Changeset 28f660d in mainline
- Timestamp:
- 2010-12-31T15:53:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 92f924c8
- Parents:
- 2972e21
- 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> 2 2 #include <ddi.h> 3 #include <devman.h>4 #include <async.h>5 3 #include <errno.h> 6 4 #include <stdint.h> 7 5 #include <stdio.h> 8 6 9 #include "../name.h" 10 #include "../uhci.h" 11 #include "../debug.h" 12 #include "port_status.h" 7 #include "debug.h" 13 8 #include "root_hub.h" 14 9 15 10 #define ROOT_HUB_WAIT_USEC 10000000 /* 10 second */ 16 11 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 /*----------------------------------------------------------------------------*/31 12 int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr ) 32 13 { … … 34 15 35 16 /* allow access to root hub registers */ 36 port_regs_t *regs; 37 const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)®s); 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**)®s); 20 38 21 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); 41 23 return ret; 42 24 } 43 hub->registers = regs;44 25 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]); 50 39 } 51 fibril_add_ready( hub->checker );52 40 53 41 return EOK; … … 63 51 } 64 52 /*----------------------------------------------------------------------------*/ 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 32 32 * @brief UHCI driver 33 33 */ 34 #ifndef DRV_UHCI_ TD_ROOT_HUB_H35 #define DRV_UHCI_ TD_ROOT_HUB_H34 #ifndef DRV_UHCI_ROOT_HUB_H 35 #define DRV_UHCI_ROOT_HUB_H 36 36 37 37 #include <fibril.h> 38 38 #include <driver.h> 39 39 40 #include "port.h" 41 40 42 #define UHCI_ROOT_HUB_PORT_COUNT 2 41 43 #define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10 42 44 43 typedef struct port_regs {44 uint16_t portsc[UHCI_ROOT_HUB_PORT_COUNT];45 } port_regs_t;46 47 45 typedef 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]; 50 48 } uhci_root_hub_t; 51 49 52 50 int 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); 54 52 55 int uhci_root_hub_fini( uhci_root_hub_t* instance ); 56 57 //int uhci_root_hub_check_ports( void * device ); 58 53 int uhci_root_hub_fini(uhci_root_hub_t* instance); 59 54 #endif 60 55 /**
Note:
See TracChangeset
for help on using the changeset viewer.