Changeset 28f660d in mainline


Ignore:
Timestamp:
2010-12-31T15:53:35Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
92f924c8
Parents:
2972e21
Message:

moved logic to port structure

Location:
uspace/drv/uhci/root_hub
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci/root_hub/root_hub.c

    r2972e21 r28f660d  
    1 #include <bool.h>
     1#include <async.h>
    22#include <ddi.h>
    3 #include <devman.h>
    4 #include <async.h>
    53#include <errno.h>
    64#include <stdint.h>
    75#include <stdio.h>
    86
    9 #include "../name.h"
    10 #include "../uhci.h"
    11 #include "../debug.h"
    12 #include "port_status.h"
     7#include "debug.h"
    138#include "root_hub.h"
    149
    1510#define ROOT_HUB_WAIT_USEC 10000000 /* 10 second */
    1611
    17 struct usb_match {
    18         int id_score;
    19         const char *id_string;
    20 };
    21 
    22 static int uhci_root_hub_check_ports( void *hc );
    23 static int uhci_root_hub_new_device( device_t *hc, unsigned port );
    24 static usb_address_t uhci_root_hub_assign_address( device_t *hc );
    25 static int uhci_root_hub_report_new_device(
    26   device_t *hc, usb_address_t address, int port, devman_handle_t *handle );
    27 static int uhci_root_hub_port_set_enabled(
    28   uhci_root_hub_t *instance, unsigned port, bool enabled );
    29 
    30 /*----------------------------------------------------------------------------*/
    3112int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr )
    3213{
     
    3415
    3516        /* allow access to root hub registers */
    36         port_regs_t *regs;
    37         const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
     17        uhci_port_reg_t *regs;
     18        const int ret = pio_enable(
     19          addr, sizeof(uhci_port_reg_t) * UHCI_ROOT_HUB_PORT_COUNT, (void**)&regs);
     20
    3821        if (ret < 0) {
    39                 uhci_print_error(
    40                   ": Failed to gain access to port registers at %p\n", regs );
     22                uhci_print_error(": Failed to gain access to port registers at %p\n", regs);
    4123                return ret;
    4224        }
    43         hub->registers = regs;
    4425
    45         /* add fibril for periodic checks */
    46         hub->checker = fibril_create( uhci_root_hub_check_ports, hc );
    47         if (hub->checker == 0) {
    48                 uhci_print_error( ": failed to launch root hub fibril." );
    49                 return ENOMEM;
     26        /* add fibrils for periodic port checks */
     27        unsigned i = 0;
     28        for (; i< UHCI_ROOT_HUB_PORT_COUNT; ++i) {
     29                /* mind pointer arithmetics */
     30                uhci_port_init(
     31                  &hub->ports[i], regs + i, hc, i, ROOT_HUB_WAIT_USEC);
     32
     33                hub->checker[i] = fibril_create(uhci_port_check, &hub->ports[i]);
     34                if (hub->checker[i] == 0) {
     35                        uhci_print_error(": failed to launch root hub fibril.");
     36                        return ENOMEM;
     37                }
     38                fibril_add_ready(hub->checker[i]);
    5039        }
    51         fibril_add_ready( hub->checker );
    5240
    5341        return EOK;
     
    6351}
    6452/*----------------------------------------------------------------------------*/
    65 static int uhci_root_hub_port_set_enabled( uhci_root_hub_t *instance,
    66   unsigned port, bool enabled )
    67 {
    68         assert( instance );
    69         assert( instance->registers );
    70         assert( port < UHCI_ROOT_HUB_PORT_COUNT );
    71 
    72         volatile uint16_t * address =
    73                 &(instance->registers->portsc[port]);
    74 
    75         /* read register value */
    76         port_status_t port_status;
    77         port_status.raw_value = pio_read_16( address );
    78 
    79         /* enable port: register write */
    80         port_status.status.enabled_change = 0;
    81         port_status.status.enabled = (bool)enabled;
    82         pio_write_16( address, port_status.raw_value );
    83 
    84         uhci_print_info( "Enabled port %d.\n", port );
    85         return EOK;
    86 }
    87 /*----------------------------------------------------------------------------*/
    88 static int uhci_root_hub_check_ports( void * device )
    89 {
    90         assert( device );
    91         uhci_t *uhci_instance = ((device_t*)device)->driver_data;
    92 
    93         while (1) {
    94                 int i = 0;
    95                 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    96                         volatile uint16_t * address =
    97                                 &(uhci_instance->root_hub.registers->portsc[i]);
    98 
    99                         uhci_print_info( "Port(%d) status address %p:\n", i, address );
    100 
    101                         /* read register value */
    102                         port_status_t port_status;
    103                         port_status.raw_value = pio_read_16( address );
    104 
    105                         /* debug print */
    106                         uhci_print_info( "Port(%d) status %#x:\n", i, port_status.raw_value );
    107                         print_port_status( &port_status );
    108 
    109                         if (port_status.status.connect_change) {
    110                                 if (port_status.status.connected) {
    111                                         /* assign address and report new device */
    112                                         uhci_root_hub_new_device( (device_t*)device, i );
    113                                 } else {
    114                                         /* TODO */
    115                                         /* remove device here */
    116                                 }
    117                         }
    118                 }
    119                 async_usleep( ROOT_HUB_WAIT_USEC );
    120         }
    121         return ENOTSUP;
    122 }
    123 /*----------------------------------------------------------------------------*/
    124 int uhci_root_hub_new_device( device_t *hc, unsigned port )
    125 {
    126         assert( hc );
    127         assert( hc->driver_data );
    128         assert( port < UHCI_ROOT_HUB_PORT_COUNT );
    129 
    130         uhci_print_info( "Adding new device on port %d.\n", port );
    131 
    132         uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
    133 
    134         /* get default address */
    135         usb_address_keeping_reserve_default( &uhci_instance->address_manager );
    136 
    137         /* enable port */
    138         uhci_root_hub_port_set_enabled( &uhci_instance->root_hub, port, true );
    139 
    140         /* assign address to device */
    141         usb_address_t address = uhci_root_hub_assign_address( hc );
    142 
    143         /* release default address */
    144         usb_address_keeping_release_default( &uhci_instance->address_manager );
    145 
    146         if (address <= 0) { /* address assigning went wrong */
    147                 uhci_root_hub_port_set_enabled( &uhci_instance->root_hub, port, false );
    148                 uhci_print_error( "Failed to assign address to the device" );
    149                 return ENOMEM;
    150         }
    151 
    152         /* report to devman */
    153         devman_handle_t child = 0;
    154         uhci_root_hub_report_new_device( hc, address, port, &child );
    155 
    156         /* bind address */
    157         usb_address_keeping_devman_bind( &uhci_instance->address_manager,
    158           address, child );
    159 
    160 
    161         return EOK;
    162 }
    163 /*----------------------------------------------------------------------------*/
    164 static usb_address_t uhci_root_hub_assign_address( device_t *hc )
    165 {
    166         assert( hc );
    167         assert( hc->driver_data );
    168 
    169         uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
    170         /* get new address */
    171         const usb_address_t usb_address =
    172           usb_address_keeping_request( &uhci_instance->address_manager );
    173 
    174         /* assign new address */
    175         /* TODO send new address to the device*/
    176         uhci_print_error( "Assigned address %#x.\n", usb_address );
    177 
    178         return usb_address;
    179 }
    180 /*----------------------------------------------------------------------------*/
    181 static int uhci_root_hub_report_new_device(
    182   device_t *hc, usb_address_t address, int hub_port, devman_handle_t *handle )
    183 {
    184         assert( hc );
    185         assert( address > 0 );
    186         assert( address <= USB11_ADDRESS_MAX );
    187 
    188         device_t *child = create_device();
    189         if (child == NULL)
    190                 { return ENOMEM; }
    191 
    192         char *name;
    193         int ret;
    194 
    195         ret = asprintf( &name, "usbdevice on hc%p/%d/%#x", hc, hub_port, address );
    196         if (ret < 0) {
    197                 uhci_print_error( "Failed to create device name.\n" );
    198                 delete_device( child );
    199                 return ret;
    200         }
    201         child->name = name;
    202 
    203         /* TODO get and parse device descriptor */
    204         const int vendor = 1;
    205         const int product = 1;
    206         const char* release = "unknown";
    207         const char* class = "unknown";
    208 
    209         /* create match ids TODO fix class printf*/
    210         static const struct usb_match usb_matches[] = {
    211           { 100, "usb&vendor=%d&product=%d&release=%s" },
    212           {  90, "usb&vendor=%d&product=%d" },
    213           {  50, "usb&class=%d" },
    214           {   1, "usb&fallback" }
    215         };
    216 
    217         unsigned i = 0;
    218         for (;i < sizeof( usb_matches )/ sizeof( struct usb_match ); ++i ) {
    219                 char *match_str;
    220                 const int ret = asprintf(
    221                   &match_str, usb_matches[i].id_string, vendor, product, release, class );
    222                 if (ret < 0 ) {
    223                         uhci_print_error( "Failed to create matchid string.\n" );
    224                         delete_device( child );
    225                         return ret;
    226                 }
    227                 uhci_print_info( "Adding match id rule:%s\n", match_str );
    228 
    229                 match_id_t *id = create_match_id();
    230                 if (id == NULL) {
    231                         uhci_print_error( "Failed to create matchid.\n" );
    232                         delete_device( child );
    233                         free( match_str );
    234                         return ENOMEM;
    235                 }
    236                 id->id = match_str;
    237                 id->score = usb_matches[i].id_score;
    238                 add_match_id( &child->match_ids, id );
    239 
    240                 uhci_print_info( "Added match id, score: %d, string %s\n",
    241                   id->score, id->id );
    242         }
    243 
    244         ret = child_device_register( child, hc );
    245         if (ret < 0) {
    246                 uhci_print_error( "Failed to create device name.\n" );
    247                 delete_device( child );
    248                 return ret;
    249         }
    250 
    251         if (handle != NULL)
    252                 { *handle = child->handle; }
    253 
    254         return EOK;
    255 }
  • uspace/drv/uhci/root_hub/root_hub.h

    r2972e21 r28f660d  
    3232 * @brief UHCI driver
    3333 */
    34 #ifndef DRV_UHCI_TD_ROOT_HUB_H
    35 #define DRV_UHCI_TD_ROOT_HUB_H
     34#ifndef DRV_UHCI_ROOT_HUB_H
     35#define DRV_UHCI_ROOT_HUB_H
    3636
    3737#include <fibril.h>
    3838#include <driver.h>
    3939
     40#include "port.h"
     41
    4042#define UHCI_ROOT_HUB_PORT_COUNT 2
    4143#define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
    4244
    43 typedef struct port_regs {
    44         uint16_t portsc[UHCI_ROOT_HUB_PORT_COUNT];
    45 } port_regs_t;
    46 
    4745typedef struct root_hub {
    48         port_regs_t *registers;
    49         fid_t checker;
     46        uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
     47        fid_t checker[UHCI_ROOT_HUB_PORT_COUNT];
    5048} uhci_root_hub_t;
    5149
    5250int uhci_root_hub_init(
    53   uhci_root_hub_t *instance, device_t *device, void *addr );
     51  uhci_root_hub_t *instance, device_t *device, void *addr);
    5452
    55 int uhci_root_hub_fini( uhci_root_hub_t* instance );
    56 
    57 //int uhci_root_hub_check_ports( void * device );
    58 
     53int uhci_root_hub_fini(uhci_root_hub_t* instance);
    5954#endif
    6055/**
Note: See TracChangeset for help on using the changeset viewer.