Changes in uspace/drv/usbhub/usbhub.c [ad4562c2:5097bed4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
rad4562c2 r5097bed4 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbhub28 /** @addtogroup usb hub driver 29 29 * @{ 30 30 */ … … 33 33 */ 34 34 35 #include <d df/driver.h>35 #include <driver.h> 36 36 #include <bool.h> 37 37 #include <errno.h> 38 #include <str_error.h>39 38 40 39 #include <usb_iface.h> 41 #include <usb/ ddfiface.h>40 #include <usb/usbdrv.h> 42 41 #include <usb/descriptor.h> 43 #include <usb/recognise.h> 44 #include <usb/request.h> 42 #include <usb/devreq.h> 45 43 #include <usb/classes/hub.h> 46 #include <stdio.h>47 44 48 45 #include "usbhub.h" 49 46 #include "usbhub_private.h" 50 47 #include "port_status.h" 51 #include "usb/usb.h" 52 #include "usb/pipes.h" 53 #include "usb/classes/classes.h" 54 55 static ddf_dev_ops_t hub_device_ops = { 56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 48 49 static usb_iface_t hub_usb_iface = { 50 .get_hc_handle = usb_drv_find_hc 57 51 }; 58 52 59 /** Hub status-change endpoint description 60 * 61 * For more see usb hub specification in 11.15.1 of 62 */ 63 static usb_endpoint_description_t status_change_endpoint_description = { 64 .transfer_type = USB_TRANSFER_INTERRUPT, 65 .direction = USB_DIRECTION_IN, 66 .interface_class = USB_CLASS_HUB, 67 .interface_subclass = 0, 68 .interface_protocol = 0, 69 .flags = 0 53 static device_ops_t hub_device_ops = { 54 .interfaces[USB_DEV_IFACE] = &hub_usb_iface 70 55 }; 71 72 int usb_hub_control_loop(void * hub_info_param){73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;74 while(true){75 usb_hub_check_hub_changes(hub_info);76 async_usleep(1000 * 1000 );/// \TODO proper number once77 }78 return 0;79 }80 81 56 82 57 //********************************************* … … 86 61 //********************************************* 87 62 88 /** 89 * Initialize connnections to host controller, device, and device 90 * control endpoint 91 * @param hub 92 * @param device 93 * @return 94 */ 95 static int usb_hub_init_communication(usb_hub_info_t * hub){ 96 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle); 97 int opResult; 98 opResult = usb_device_connection_initialize_from_device( 99 &hub->device_connection, 100 hub->device); 101 if(opResult != EOK){ 102 dprintf(USB_LOG_LEVEL_ERROR, 103 "could not initialize connection to hc, errno %d",opResult); 104 return opResult; 105 } 106 usb_log_debug("Initializing USB wire abstraction.\n"); 107 opResult = usb_hc_connection_initialize_from_device(&hub->connection, 108 hub->device); 109 if(opResult != EOK){ 110 dprintf(USB_LOG_LEVEL_ERROR, 111 "could not initialize connection to device, errno %d",opResult); 112 return opResult; 113 } 114 usb_log_debug("Initializing default control pipe.\n"); 115 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control, 116 &hub->device_connection); 117 if(opResult != EOK){ 118 dprintf(USB_LOG_LEVEL_ERROR, 119 "could not initialize connection to device endpoint, errno %d",opResult); 120 } 121 return opResult; 122 } 123 124 /** 125 * When entering this function, hub->endpoints.control should be active. 126 * @param hub 127 * @return 128 */ 129 static int usb_hub_process_configuration_descriptors( 130 usb_hub_info_t * hub){ 131 if(hub==NULL) { 132 return EINVAL; 133 } 134 int opResult; 135 136 //device descriptor 137 usb_standard_device_descriptor_t std_descriptor; 138 opResult = usb_request_get_device_descriptor(&hub->endpoints.control, 139 &std_descriptor); 140 if(opResult!=EOK){ 141 dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult); 142 return opResult; 143 } 144 dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations", 145 std_descriptor.configuration_count); 146 if(std_descriptor.configuration_count<1){ 147 dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE"); 148 //shouldn`t I return? 149 } 150 151 //configuration descriptor 152 /// \TODO check other configurations? 153 usb_standard_configuration_descriptor_t config_descriptor; 154 opResult = usb_request_get_bare_configuration_descriptor( 155 &hub->endpoints.control, 0, 156 &config_descriptor); 157 if(opResult!=EOK){ 158 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult); 159 return opResult; 160 } 161 //set configuration 162 opResult = usb_request_set_configuration(&hub->endpoints.control, 163 config_descriptor.configuration_number); 164 165 if (opResult != EOK) { 166 dprintf(USB_LOG_LEVEL_ERROR, 167 "something went wrong when setting hub`s configuration, %d", 168 opResult); 169 return opResult; 170 } 171 dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d", 172 config_descriptor.configuration_number); 173 174 //full configuration descriptor 175 size_t transferred = 0; 176 uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length); 177 if (descriptors == NULL) { 178 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory"); 179 return ENOMEM; 180 } 181 opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control, 182 0, descriptors, 183 config_descriptor.total_length, &transferred); 184 if(opResult!=EOK){ 185 free(descriptors); 186 dprintf(USB_LOG_LEVEL_ERROR, 187 "could not get full configuration descriptor, %d",opResult); 188 return opResult; 189 } 190 if (transferred != config_descriptor.total_length) { 191 dprintf(USB_LOG_LEVEL_ERROR, 192 "received incorrect full configuration descriptor"); 193 return ELIMIT; 194 } 195 196 usb_endpoint_mapping_t endpoint_mapping[1] = { 197 { 198 .pipe = &hub->endpoints.status_change, 199 .description = &status_change_endpoint_description, 200 .interface_no = 201 usb_device_get_assigned_interface(hub->device) 202 } 203 }; 204 opResult = usb_endpoint_pipe_initialize_from_configuration( 205 endpoint_mapping, 1, 206 descriptors, config_descriptor.total_length, 207 &hub->device_connection); 208 if (opResult != EOK) { 209 dprintf(USB_LOG_LEVEL_ERROR, 210 "Failed to initialize status change pipe: %s", 211 str_error(opResult)); 212 return opResult; 213 } 214 if (!endpoint_mapping[0].present) { 215 dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \ 216 "cannot understand what is happenning"); 217 return EREFUSED; 218 } 219 220 free(descriptors); 221 return EOK; 222 223 } 224 225 226 /** 227 * Create hub representation from device information. 228 * @param device 229 * @return pointer to created structure or NULL in case of error 230 */ 231 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) { 63 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 232 64 usb_hub_info_t* result = usb_new(usb_hub_info_t); 233 result->device = device;234 int opResult;235 opResult = usb_hub_init_communication(result);236 if(opResult != EOK){237 free(result);238 return NULL;239 }240 241 65 //result->device = device; 242 66 result->port_count = -1; 67 /// \TODO is this correct? is the device stored? 243 68 result->device = device; 244 69 245 //result->usb_device = usb_new(usb_hcd_attached_device_info_t); 246 size_t received_size; 70 71 //printf("[usb_hub] phone to hc = %d\n", hc); 72 if (hc < 0) { 73 return result; 74 } 75 //get some hub info 76 usb_address_t addr = usb_drv_get_my_address(hc, device); 77 dprintf(1,"[usb_hub] address of newly created hub = %d", addr); 78 /*if(addr<0){ 79 //return result; 80 81 }*/ 82 83 result->usb_device = usb_new(usb_hcd_attached_device_info_t); 84 result->usb_device->address = addr; 247 85 248 86 // get hub descriptor 249 dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton"); 87 usb_target_t target; 88 target.address = addr; 89 target.endpoint = 0; 90 usb_device_request_setup_packet_t request; 91 //printf("[usb_hub] creating descriptor request\n"); 92 usb_hub_set_descriptor_request(&request); 93 94 //printf("[usb_hub] creating serialized descriptor\n"); 250 95 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 251 96 usb_hub_descriptor_t * descriptor; 252 dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction"); 253 usb_endpoint_pipe_start_session(&result->endpoints.control); 254 opResult = usb_request_get_descriptor(&result->endpoints.control, 255 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 256 USB_DESCTYPE_HUB, 257 0, 0, serialized_descriptor, 97 size_t received_size; 98 int opResult; 99 //printf("[usb_hub] starting control transaction\n"); 100 opResult = usb_drv_sync_control_read( 101 hc, target, &request, serialized_descriptor, 258 102 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 259 usb_endpoint_pipe_end_session(&result->endpoints.control); 260 261 if (opResult != EOK) { 262 dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult); 103 if (opResult != EOK) { 104 dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult); 263 105 free(serialized_descriptor); 264 106 return result; 265 107 } 266 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");108 //printf("[usb_hub] deserializing descriptor\n"); 267 109 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 268 110 if(descriptor==NULL){ 269 dprintf( USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");111 dprintf(1,"[usb_hub] could not deserialize descriptor "); 270 112 result->port_count = 1;///\TODO this code is only for debug!!! 271 113 return result; 272 114 } 273 274 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 115 //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count); 275 116 result->port_count = descriptor->ports_count; 276 result->attached_devs = (usb_h c_attached_device_t*)277 malloc((result->port_count+1) * sizeof(usb_h c_attached_device_t));117 result->attached_devs = (usb_hub_attached_device_t*) 118 malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t)); 278 119 int i; 279 120 for(i=0;i<result->port_count+1;++i){ 280 result->attached_devs[i]. handle=0;121 result->attached_devs[i].devman_handle=0; 281 122 result->attached_devs[i].address=0; 282 123 } 283 dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");124 //printf("[usb_hub] freeing data\n"); 284 125 free(serialized_descriptor); 285 126 free(descriptor->devices_removable); … … 288 129 //finish 289 130 290 dprintf( USB_LOG_LEVEL_INFO, "hub info created");131 dprintf(1,"[usb_hub] hub info created"); 291 132 292 133 return result; 293 134 } 294 135 295 /** 296 * Create hub representation and add it into hub list 297 * @param dev 298 * @return 299 */ 300 int usb_add_hub_device(ddf_dev_t *dev) { 301 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 302 303 //dev->ops = &hub_device_ops; 304 (void) hub_device_ops; 305 306 usb_hub_info_t * hub_info = usb_create_hub_info(dev); 307 308 int opResult; 309 310 //perform final configurations 311 usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 312 // process descriptors 313 opResult = usb_hub_process_configuration_descriptors(hub_info); 314 if(opResult != EOK){ 315 dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d", 316 opResult); 136 int usb_add_hub_device(device_t *dev) { 137 dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle); 138 dprintf(1,"[usb_hub] hub device"); 139 140 /* 141 * We are some (probably deeply nested) hub. 142 * Thus, assign our own operations and explore already 143 * connected devices. 144 */ 145 dev->ops = &hub_device_ops; 146 147 //create the hub structure 148 //get hc connection 149 int hc = usb_drv_hc_connect_auto(dev, 0); 150 if (hc < 0) { 151 return hc; 152 } 153 154 usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc); 155 int port; 156 int opResult; 157 usb_device_request_setup_packet_t request; 158 usb_target_t target; 159 target.address = hub_info->usb_device->address; 160 target.endpoint = 0; 161 162 //get configuration descriptor 163 // this is not fully correct - there are more configurations 164 // and all should be checked 165 usb_standard_device_descriptor_t std_descriptor; 166 opResult = usb_drv_req_get_device_descriptor(hc, target.address, 167 &std_descriptor); 168 if(opResult!=EOK){ 169 dprintf(1,"[usb_hub] could not get device descriptor, %d",opResult); 317 170 return opResult; 318 171 } 319 //power ports 320 usb_device_request_setup_packet_t request; 321 int port; 172 dprintf(1,"[usb_hub] hub has %d configurations",std_descriptor.configuration_count); 173 if(std_descriptor.configuration_count<1){ 174 dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE"); 175 } 176 /// \TODO check other configurations 177 usb_standard_configuration_descriptor_t config_descriptor; 178 opResult = usb_drv_req_get_bare_configuration_descriptor(hc, 179 target.address, 0, 180 &config_descriptor); 181 if(opResult!=EOK){ 182 dprintf(1,"[usb_hub] could not get configuration descriptor, %d",opResult); 183 return opResult; 184 } 185 //set configuration 186 request.request_type = 0; 187 request.request = USB_DEVREQ_SET_CONFIGURATION; 188 request.index=0; 189 request.length=0; 190 request.value_high=0; 191 request.value_low = config_descriptor.configuration_number; 192 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 193 if (opResult != EOK) { 194 dprintf(1,"[usb_hub]something went wrong when setting hub`s configuration, %d", opResult); 195 } 196 322 197 for (port = 1; port < hub_info->port_count+1; ++port) { 323 198 usb_hub_set_power_port_request(&request, port); 324 opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control, 325 &request,sizeof(usb_device_request_setup_packet_t), NULL, 0); 326 dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port); 199 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 200 dprintf(1,"[usb_hub] powering port %d",port); 327 201 if (opResult != EOK) { 328 dprintf( USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);202 dprintf(1,"[usb_hub]something went wrong when setting hub`s %dth port", port); 329 203 } 330 204 } 331 205 //ports powered, hub seems to be enabled 332 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 206 207 ipc_hangup(hc); 333 208 334 209 //add the hub to list 335 //is this needed now? 336 fibril_mutex_lock(&usb_hub_list_lock); 210 futex_down(&usb_hub_list_lock); 337 211 usb_lst_append(&usb_hub_list, hub_info); 338 fibril_mutex_unlock(&usb_hub_list_lock); 339 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list"); 340 341 dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf"); 342 ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub"); 343 assert(hub_fun != NULL); 344 hub_fun->ops = NULL; 345 346 int rc = ddf_fun_bind(hub_fun); 347 assert(rc == EOK); 348 rc = ddf_fun_add_to_class(hub_fun, "hub"); 349 assert(rc == EOK); 350 351 fid_t fid = fibril_create(usb_hub_control_loop, hub_info); 352 if (fid == 0) { 353 dprintf(USB_LOG_LEVEL_ERROR, 354 ": failed to start monitoring fibril for new hub"); 355 return ENOMEM; 356 } 357 fibril_add_ready(fid); 358 359 dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created"); 212 futex_up(&usb_hub_list_lock); 213 214 dprintf(1,"[usb_hub] hub info added to list"); 360 215 //(void)hub_info; 361 //usb_hub_check_hub_changes(); 216 usb_hub_check_hub_changes(); 217 362 218 363 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); 364 //address is lost...365 dprintf( USB_LOG_LEVEL_DEBUG,"\taddress %d, has %d ports ",366 //hub_info->endpoints.control.,219 220 dprintf(1,"[usb_hub] hub dev added"); 221 dprintf(1,"\taddress %d, has %d ports ", 222 hub_info->usb_device->address, 367 223 hub_info->port_count); 224 dprintf(1,"\tused configuration %d",config_descriptor.configuration_number); 368 225 369 226 return EOK; 370 227 //return ENOTSUP; 371 228 } 229 372 230 373 231 … … 379 237 380 238 /** 381 * Reset the port with new device and reserve the default address. 239 * convenience function for releasing default address and writing debug info 240 * (these few lines are used too often to be written again and again) 241 * @param hc 242 * @return 243 */ 244 inline static int usb_hub_release_default_address(int hc){ 245 int opResult; 246 dprintf(1,"[usb_hub] releasing default address"); 247 opResult = usb_drv_release_default_address(hc); 248 if (opResult != EOK) { 249 dprintf(1,"[usb_hub] failed to release default address"); 250 } 251 return opResult; 252 } 253 254 /** 255 * reset the port with new device and reserve the default address 382 256 * @param hc 383 257 * @param port 384 258 * @param target 385 259 */ 386 static void usb_hub_init_add_device( usb_hub_info_t * hub, uint16_t port) {260 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) { 387 261 usb_device_request_setup_packet_t request; 388 262 int opResult; 389 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 390 assert(hub->endpoints.control.hc_phone); 263 dprintf(1,"[usb_hub] some connection changed"); 391 264 //get default address 392 //opResult = usb_drv_reserve_default_address(hc); 393 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 394 395 if (opResult != EOK) { 396 dprintf(USB_LOG_LEVEL_WARNING, 397 "cannot assign default address, it is probably used %d",opResult); 265 opResult = usb_drv_reserve_default_address(hc); 266 if (opResult != EOK) { 267 dprintf(1,"[usb_hub] cannot assign default address, it is probably used"); 398 268 return; 399 269 } 400 270 //reset port 401 271 usb_hub_set_reset_port_request(&request, port); 402 opResult = usb_ endpoint_pipe_control_write(403 &hub->endpoints.control,404 &request, sizeof(usb_device_request_setup_packet_t),272 opResult = usb_drv_sync_control_write( 273 hc, target, 274 &request, 405 275 NULL, 0 406 276 ); 407 277 if (opResult != EOK) { 408 dprintf(USB_LOG_LEVEL_ERROR, 409 "something went wrong when reseting a port %d",opResult); 410 //usb_hub_release_default_address(hc); 411 usb_hc_release_default_address(&hub->connection); 278 dprintf(1,"[usb_hub] something went wrong when reseting a port"); 279 usb_hub_release_default_address(hc); 412 280 } 413 281 } 414 282 415 283 /** 416 * Finalize adding new device after port reset284 * finalize adding new device after port reset 417 285 * @param hc 418 286 * @param port … … 420 288 */ 421 289 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 422 uint16_t port, bool isLowSpeed) {423 424 int opResult; 425 dprintf( USB_LOG_LEVEL_INFO, "finalizing add device");426 opResult = usb_hub_clear_port_feature( &hub->endpoints.control,290 int hc, uint16_t port, usb_target_t target) { 291 292 int opResult; 293 dprintf(1,"[usb_hub] finalizing add device"); 294 opResult = usb_hub_clear_port_feature(hc, target.address, 427 295 port, USB_HUB_FEATURE_C_PORT_RESET); 428 429 if (opResult != EOK) { 430 dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature"); 431 usb_hc_release_default_address(&hub->connection); 432 return; 433 } 434 //create connection to device 435 usb_endpoint_pipe_t new_device_pipe; 436 usb_device_connection_t new_device_connection; 437 usb_device_connection_initialize_on_default_address( 438 &new_device_connection, 439 &hub->connection 440 ); 441 usb_endpoint_pipe_initialize_default_control( 442 &new_device_pipe, 443 &new_device_connection); 444 /// \TODO get highspeed info 445 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 446 447 448 /* Request address from host controller. */ 449 usb_address_t new_device_address = usb_hc_request_address( 450 &hub->connection, 451 speed/// \TODO fullspeed?? 452 ); 296 if (opResult != EOK) { 297 dprintf(1,"[usb_hub] failed to clear port reset feature"); 298 usb_hub_release_default_address(hc); 299 return; 300 } 301 302 /* Request address at from host controller. */ 303 usb_address_t new_device_address = usb_drv_request_address(hc); 453 304 if (new_device_address < 0) { 454 dprintf( USB_LOG_LEVEL_ERROR, "failed to get free USB address");305 dprintf(1,"[usb_hub] failed to get free USB address"); 455 306 opResult = new_device_address; 456 usb_hc_release_default_address(&hub->connection); 457 return; 458 } 459 dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address); 460 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 461 // new_device_address); 462 usb_endpoint_pipe_start_session(&new_device_pipe); 463 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 464 usb_endpoint_pipe_end_session(&new_device_pipe); 465 if (opResult != EOK) { 466 dprintf(USB_LOG_LEVEL_ERROR, 467 "could not set address for new device %d",opResult); 468 usb_hc_release_default_address(&hub->connection); 469 return; 470 } 471 472 473 //opResult = usb_hub_release_default_address(hc); 474 opResult = usb_hc_release_default_address(&hub->connection); 307 usb_hub_release_default_address(hc); 308 return; 309 } 310 dprintf(1,"[usb_hub] setting new address"); 311 opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 312 new_device_address); 313 314 if (opResult != EOK) { 315 dprintf(1,"[usb_hub] could not set address for new device"); 316 usb_hub_release_default_address(hc); 317 return; 318 } 319 320 321 opResult = usb_hub_release_default_address(hc); 475 322 if(opResult!=EOK){ 476 323 return; … … 478 325 479 326 devman_handle_t child_handle; 480 //?? 481 opResult = usb_device_register_child_in_devman(new_device_address, 482 hub->connection.hc_handle, hub->device, &child_handle, 483 NULL, NULL, NULL); 484 485 if (opResult != EOK) { 486 dprintf(USB_LOG_LEVEL_ERROR, 487 "could not start driver for new device %d",opResult); 488 return; 489 } 490 hub->attached_devs[port].handle = child_handle; 327 opResult = usb_drv_register_child_in_devman(hc, hub->device, 328 new_device_address, &child_handle); 329 if (opResult != EOK) { 330 dprintf(1,"[usb_hub] could not start driver for new device"); 331 return; 332 } 333 hub->attached_devs[port].devman_handle = child_handle; 491 334 hub->attached_devs[port].address = new_device_address; 492 335 493 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 494 opResult = usb_hc_register_device( 495 &hub->connection, 496 &hub->attached_devs[port]); 497 if (opResult != EOK) { 498 dprintf(USB_LOG_LEVEL_ERROR, 499 "could not assign address of device in hcd %d",opResult); 500 return; 501 } 502 dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu", 336 opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 337 if (opResult != EOK) { 338 dprintf(1,"[usb_hub] could not assign address of device in hcd"); 339 return; 340 } 341 dprintf(1,"[usb_hub] new device address %d, handle %zu", 503 342 new_device_address, child_handle); 504 343 … … 506 345 507 346 /** 508 * Unregister device address in hc347 * unregister device address in hc 509 348 * @param hc 510 349 * @param port … … 512 351 */ 513 352 static void usb_hub_removed_device( 514 usb_hub_info_t * hub, uint16_t port) {353 usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) { 515 354 //usb_device_request_setup_packet_t request; 516 355 int opResult; 517 356 518 /** \TODO remove device from device manager - not yet implemented in 519 * devide manager 520 */ 521 357 /// \TODO remove device 358 359 hub->attached_devs[port].devman_handle=0; 522 360 //close address 523 361 if(hub->attached_devs[port].address!=0){ 524 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 525 opResult = usb_hc_unregister_device( 526 &hub->connection, hub->attached_devs[port].address); 362 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 527 363 if(opResult != EOK) { 528 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 529 "removed device: %d", opResult); 364 dprintf(1, 365 "[usb_hub] could not release address of removed device: %d" 366 ,opResult); 530 367 } 531 368 hub->attached_devs[port].address = 0; 532 hub->attached_devs[port].handle = 0;533 369 }else{ 534 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); 370 dprintf(1, 371 "[usb_hub] this is strange, disconnected device had no address"); 535 372 //device was disconnected before it`s port was reset - return default address 536 //usb_drv_release_default_address(hc); 537 usb_hc_release_default_address(&hub->connection); 538 } 539 } 540 373 usb_drv_release_default_address(hc); 374 } 375 } 541 376 542 377 /** 543 *Process over current condition on port. 544 * 545 * Turn off the power on the port. 546 * 547 * @param hub 548 * @param port 549 */ 550 static void usb_hub_over_current( usb_hub_info_t * hub, 551 uint16_t port){ 552 int opResult; 553 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 554 port, USB_HUB_FEATURE_PORT_POWER); 555 if(opResult!=EOK){ 556 dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d; %d", 557 port, opResult); 558 } 559 } 560 561 /** 562 * Process interrupts on given hub port 378 * process interrupts on given hub port 563 379 * @param hc 564 380 * @param port 565 381 * @param target 566 382 */ 567 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 568 uint16_t port ) {569 dprintf( USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port);383 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc, 384 uint16_t port, usb_address_t address) { 385 dprintf(1,"[usb_hub] interrupt at port %d", port); 570 386 //determine type of change 571 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 572 573 int opResult; 574 387 usb_target_t target; 388 target.address=address; 389 target.endpoint=0; 575 390 usb_port_status_t status; 576 391 size_t rcvd_size; 577 392 usb_device_request_setup_packet_t request; 578 //int opResult;393 int opResult; 579 394 usb_hub_set_port_status_request(&request, port); 580 395 //endpoint 0 581 396 582 opResult = usb_ endpoint_pipe_control_read(583 pipe,584 &request, sizeof(usb_device_request_setup_packet_t),397 opResult = usb_drv_sync_control_read( 398 hc, target, 399 &request, 585 400 &status, 4, &rcvd_size 586 401 ); 587 402 if (opResult != EOK) { 588 dprintf( USB_LOG_LEVEL_ERROR, "could not get port status");403 dprintf(1,"[usb_hub] ERROR: could not get port status"); 589 404 return; 590 405 } 591 406 if (rcvd_size != sizeof (usb_port_status_t)) { 592 dprintf( USB_LOG_LEVEL_ERROR, "received status has incorrect size");407 dprintf(1,"[usb_hub] ERROR: received status has incorrect size"); 593 408 return; 594 409 } 595 410 //something connected/disconnected 596 411 if (usb_port_connect_change(&status)) { 597 opResult = usb_hub_clear_port_feature( pipe,412 opResult = usb_hub_clear_port_feature(hc, target.address, 598 413 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 599 414 // TODO: check opResult 600 415 if (usb_port_dev_connected(&status)) { 601 dprintf( USB_LOG_LEVEL_INFO, "some connection changed");602 usb_hub_init_add_device(h ub, port);416 dprintf(1,"[usb_hub] some connection changed"); 417 usb_hub_init_add_device(hc, port, target); 603 418 } else { 604 usb_hub_removed_device(hub, port); 605 } 606 } 607 //over current 608 if (usb_port_overcurrent_change(&status)) { 609 //check if it was not auto-resolved 610 if(usb_port_over_current(&status)){ 611 usb_hub_over_current(hub,port); 612 }else{ 613 dprintf(USB_LOG_LEVEL_INFO, 614 "over current condition was auto-resolved on port %d",port); 419 usb_hub_removed_device(hub, hc, port, target); 615 420 } 616 421 } 617 422 //port reset 618 423 if (usb_port_reset_completed(&status)) { 619 dprintf( USB_LOG_LEVEL_INFO, "port reset complete");424 dprintf(1,"[usb_hub] port reset complete"); 620 425 if (usb_port_enabled(&status)) { 621 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));426 usb_hub_finalize_add_device(hub, hc, port, target); 622 427 } else { 623 dprintf( USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");428 dprintf(1,"[usb_hub] ERROR: port reset, but port still not enabled"); 624 429 } 625 430 } … … 629 434 usb_port_set_reset_completed(&status, false); 630 435 usb_port_set_dev_connected(&status, false); 631 if (status>>16) { 632 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status); 633 436 if (status) { 437 dprintf(1,"[usb_hub]there was some unsupported change on port %d",port); 634 438 } 635 439 /// \TODO handle other changes 636 } 637 638 /** 639 * Check changes on particular hub 640 * @param hub_info_param 641 */ 642 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 643 int opResult; 644 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 645 if(opResult != EOK){ 646 dprintf(USB_LOG_LEVEL_ERROR, 647 "could not initialize communication for hub; %d", opResult); 648 return; 649 } 650 651 size_t port_count = hub_info->port_count; 652 653 /// FIXME: count properly 654 size_t byte_length = ((port_count+1) / 8) + 1; 440 /// \TODO debug log for various situations 441 442 } 443 444 /* Check changes on all known hubs. 445 */ 446 void usb_hub_check_hub_changes(void) { 447 /* 448 * Iterate through all hubs. 449 */ 450 usb_general_list_t * lst_item; 451 futex_down(&usb_hub_list_lock); 452 for (lst_item = usb_hub_list.next; 453 lst_item != &usb_hub_list; 454 lst_item = lst_item->next) { 455 futex_up(&usb_hub_list_lock); 456 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 457 /* 458 * Check status change pipe of this hub. 459 */ 460 461 usb_target_t target; 462 target.address = hub_info->usb_device->address; 463 target.endpoint = 1;/// \TODO get from endpoint descriptor 464 dprintf(1,"[usb_hub] checking changes for hub at addr %d", 465 target.address); 466 467 size_t port_count = hub_info->port_count; 468 469 /* 470 * Connect to respective HC. 471 */ 472 int hc = usb_drv_hc_connect_auto(hub_info->device, 0); 473 if (hc < 0) { 474 continue; 475 } 476 477 /// FIXME: count properly 478 size_t byte_length = ((port_count+1) / 8) + 1; 479 655 480 void *change_bitmap = malloc(byte_length); 656 size_t actual_size; 657 658 /* 659 * Send the request. 660 */ 661 opResult = usb_endpoint_pipe_read( 662 &hub_info->endpoints.status_change, 663 change_bitmap, byte_length, &actual_size 664 ); 665 666 if (opResult != EOK) { 481 size_t actual_size; 482 usb_handle_t handle; 483 484 /* 485 * Send the request. 486 */ 487 int opResult = usb_drv_async_interrupt_in(hc, target, 488 change_bitmap, byte_length, &actual_size, 489 &handle); 490 491 usb_drv_async_wait_for(handle); 492 493 if (opResult != EOK) { 494 dprintf(1,"[usb_hub] something went wrong while getting status of hub"); 495 continue; 496 } 497 unsigned int port; 498 for (port = 1; port < port_count+1; ++port) { 499 bool interrupt = 500 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 501 if (interrupt) { 502 usb_hub_process_interrupt( 503 hub_info, hc, port, hub_info->usb_device->address); 504 } 505 } 667 506 free(change_bitmap); 668 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 669 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 670 return; 671 } 672 unsigned int port; 673 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 674 if(opResult!=EOK){ 675 dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d", 676 opResult); 677 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 678 return; 679 } 680 opResult = usb_hc_connection_open(&hub_info->connection); 681 if(opResult!=EOK){ 682 dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d", 683 opResult); 684 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 685 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 686 return; 687 } 688 689 ///todo, opresult check, pre obe konekce 690 for (port = 1; port < port_count+1; ++port) { 691 bool interrupt = 692 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 693 if (interrupt) { 694 usb_hub_process_interrupt( 695 hub_info, port); 696 } 697 } 698 usb_hc_connection_close(&hub_info->connection); 699 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 700 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 701 free(change_bitmap); 702 } 507 508 ipc_hangup(hc); 509 futex_down(&usb_hub_list_lock); 510 } 511 futex_up(&usb_hub_list_lock); 512 } 513 514 703 515 704 516
Note:
See TracChangeset
for help on using the changeset viewer.