Changes in uspace/drv/usbhub/usbhub.c [5097bed4:ad4562c2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r5097bed4 rad4562c2 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb hub driver28 /** @addtogroup drvusbhub 29 29 * @{ 30 30 */ … … 33 33 */ 34 34 35 #include <d river.h>35 #include <ddf/driver.h> 36 36 #include <bool.h> 37 37 #include <errno.h> 38 #include <str_error.h> 38 39 39 40 #include <usb_iface.h> 40 #include <usb/ usbdrv.h>41 #include <usb/ddfiface.h> 41 42 #include <usb/descriptor.h> 42 #include <usb/devreq.h> 43 #include <usb/recognise.h> 44 #include <usb/request.h> 43 45 #include <usb/classes/hub.h> 46 #include <stdio.h> 44 47 45 48 #include "usbhub.h" 46 49 #include "usbhub_private.h" 47 50 #include "port_status.h" 48 49 static usb_iface_t hub_usb_iface = { 50 .get_hc_handle = usb_drv_find_hc 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 51 57 }; 52 58 53 static device_ops_t hub_device_ops = { 54 .interfaces[USB_DEV_IFACE] = &hub_usb_iface 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 55 70 }; 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 once 77 } 78 return 0; 79 } 80 56 81 57 82 //********************************************* … … 61 86 //********************************************* 62 87 63 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 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) { 64 232 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 65 241 //result->device = device; 66 242 result->port_count = -1; 67 /// \TODO is this correct? is the device stored?68 243 result->device = device; 69 244 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; 245 //result->usb_device = usb_new(usb_hcd_attached_device_info_t); 246 size_t received_size; 85 247 86 248 // get hub descriptor 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"); 249 dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton"); 95 250 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 96 251 usb_hub_descriptor_t * 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, 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, 102 258 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 103 if (opResult != EOK) { 104 dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult); 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); 105 263 free(serialized_descriptor); 106 264 return result; 107 265 } 108 //printf("[usb_hub] deserializing descriptor\n");266 dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor"); 109 267 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 110 268 if(descriptor==NULL){ 111 dprintf( 1,"[usb_hub]could not deserialize descriptor ");269 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor "); 112 270 result->port_count = 1;///\TODO this code is only for debug!!! 113 271 return result; 114 272 } 115 //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count); 273 274 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 116 275 result->port_count = descriptor->ports_count; 117 result->attached_devs = (usb_h ub_attached_device_t*)118 malloc((result->port_count+1) * sizeof(usb_h ub_attached_device_t));276 result->attached_devs = (usb_hc_attached_device_t*) 277 malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t)); 119 278 int i; 120 279 for(i=0;i<result->port_count+1;++i){ 121 result->attached_devs[i]. devman_handle=0;280 result->attached_devs[i].handle=0; 122 281 result->attached_devs[i].address=0; 123 282 } 124 //printf("[usb_hub] freeing data\n");283 dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data"); 125 284 free(serialized_descriptor); 126 285 free(descriptor->devices_removable); … … 129 288 //finish 130 289 131 dprintf( 1,"[usb_hub]hub info created");290 dprintf(USB_LOG_LEVEL_INFO, "hub info created"); 132 291 133 292 return result; 134 293 } 135 294 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); 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); 317 return opResult; 318 } 319 //power ports 320 usb_device_request_setup_packet_t request; 155 321 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 descriptor163 // this is not fully correct - there are more configurations164 // and all should be checked165 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);170 return opResult;171 }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 configurations177 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 configuration186 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 197 322 for (port = 1; port < hub_info->port_count+1; ++port) { 198 323 usb_hub_set_power_port_request(&request, port); 199 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 200 dprintf(1,"[usb_hub] powering port %d",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); 201 327 if (opResult != EOK) { 202 dprintf( 1,"[usb_hub]something went wrong when setting hub`s %dth port", port);328 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port); 203 329 } 204 330 } 205 331 //ports powered, hub seems to be enabled 206 207 ipc_hangup(hc); 332 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 208 333 209 334 //add the hub to list 210 futex_down(&usb_hub_list_lock); 335 //is this needed now? 336 fibril_mutex_lock(&usb_hub_list_lock); 211 337 usb_lst_append(&usb_hub_list, hub_info); 212 futex_up(&usb_hub_list_lock); 213 214 dprintf(1,"[usb_hub] hub info added to list"); 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"); 215 360 //(void)hub_info; 216 usb_hub_check_hub_changes(); 217 361 //usb_hub_check_hub_changes(); 218 362 219 220 dprintf(1,"[usb_hub] hub dev added");221 dprintf( 1,"\taddress %d, has %d ports ",222 hub_info->usb_device->address,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., 223 367 hub_info->port_count); 224 dprintf(1,"\tused configuration %d",config_descriptor.configuration_number);225 368 226 369 return EOK; 227 370 //return ENOTSUP; 228 371 } 229 230 372 231 373 … … 237 379 238 380 /** 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 381 * Reset the port with new device and reserve the default address. 256 382 * @param hc 257 383 * @param port 258 384 * @param target 259 385 */ 260 static void usb_hub_init_add_device( int hc, uint16_t port, usb_target_t target) {386 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) { 261 387 usb_device_request_setup_packet_t request; 262 388 int opResult; 263 dprintf(1,"[usb_hub] some connection changed"); 389 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 390 assert(hub->endpoints.control.hc_phone); 264 391 //get default address 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"); 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); 268 398 return; 269 399 } 270 400 //reset port 271 401 usb_hub_set_reset_port_request(&request, port); 272 opResult = usb_ drv_sync_control_write(273 hc, target,274 &request, 402 opResult = usb_endpoint_pipe_control_write( 403 &hub->endpoints.control, 404 &request,sizeof(usb_device_request_setup_packet_t), 275 405 NULL, 0 276 406 ); 277 407 if (opResult != EOK) { 278 dprintf(1,"[usb_hub] something went wrong when reseting a port"); 279 usb_hub_release_default_address(hc); 280 } 281 } 282 283 /** 284 * finalize adding new device after port reset 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); 412 } 413 } 414 415 /** 416 * Finalize adding new device after port reset 285 417 * @param hc 286 418 * @param port … … 288 420 */ 289 421 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 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,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, 295 427 port, USB_HUB_FEATURE_C_PORT_RESET); 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); 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 ); 304 453 if (new_device_address < 0) { 305 dprintf( 1,"[usb_hub]failed to get free USB address");454 dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address"); 306 455 opResult = new_device_address; 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); 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); 322 475 if(opResult!=EOK){ 323 476 return; … … 325 478 326 479 devman_handle_t 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; 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; 334 491 hub->attached_devs[port].address = new_device_address; 335 492 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", 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", 342 503 new_device_address, child_handle); 343 504 … … 345 506 346 507 /** 347 * unregister device address in hc508 * Unregister device address in hc 348 509 * @param hc 349 510 * @param port … … 351 512 */ 352 513 static void usb_hub_removed_device( 353 usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {514 usb_hub_info_t * hub,uint16_t port) { 354 515 //usb_device_request_setup_packet_t request; 355 516 int opResult; 356 517 357 /// \TODO remove device 358 359 hub->attached_devs[port].devman_handle=0; 518 /** \TODO remove device from device manager - not yet implemented in 519 * devide manager 520 */ 521 360 522 //close address 361 523 if(hub->attached_devs[port].address!=0){ 362 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 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); 363 527 if(opResult != EOK) { 364 dprintf(1, 365 "[usb_hub] could not release address of removed device: %d" 366 ,opResult); 528 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 529 "removed device: %d", opResult); 367 530 } 368 531 hub->attached_devs[port].address = 0; 532 hub->attached_devs[port].handle = 0; 369 533 }else{ 370 dprintf(1, 371 "[usb_hub] this is strange, disconnected device had no address"); 534 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); 372 535 //device was disconnected before it`s port was reset - return default address 373 usb_drv_release_default_address(hc); 374 } 375 } 376 377 /** 378 * process interrupts on given hub port 536 //usb_drv_release_default_address(hc); 537 usb_hc_release_default_address(&hub->connection); 538 } 539 } 540 541 542 /** 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 379 563 * @param hc 380 564 * @param port 381 565 * @param target 382 566 */ 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);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); 386 570 //determine type of change 387 usb_target_t target; 388 target.address=address; 389 target.endpoint=0; 571 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 572 573 int opResult; 574 390 575 usb_port_status_t status; 391 576 size_t rcvd_size; 392 577 usb_device_request_setup_packet_t request; 393 int opResult;578 //int opResult; 394 579 usb_hub_set_port_status_request(&request, port); 395 580 //endpoint 0 396 581 397 opResult = usb_ drv_sync_control_read(398 hc, target,399 &request, 582 opResult = usb_endpoint_pipe_control_read( 583 pipe, 584 &request, sizeof(usb_device_request_setup_packet_t), 400 585 &status, 4, &rcvd_size 401 586 ); 402 587 if (opResult != EOK) { 403 dprintf( 1,"[usb_hub] ERROR:could not get port status");588 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 404 589 return; 405 590 } 406 591 if (rcvd_size != sizeof (usb_port_status_t)) { 407 dprintf( 1,"[usb_hub] ERROR:received status has incorrect size");592 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 408 593 return; 409 594 } 410 595 //something connected/disconnected 411 596 if (usb_port_connect_change(&status)) { 412 opResult = usb_hub_clear_port_feature( hc, target.address,597 opResult = usb_hub_clear_port_feature(pipe, 413 598 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 414 599 // TODO: check opResult 415 600 if (usb_port_dev_connected(&status)) { 416 dprintf( 1,"[usb_hub]some connection changed");417 usb_hub_init_add_device(h c, port, target);601 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 602 usb_hub_init_add_device(hub, port); 418 603 } else { 419 usb_hub_removed_device(hub, hc, port, target); 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); 420 615 } 421 616 } 422 617 //port reset 423 618 if (usb_port_reset_completed(&status)) { 424 dprintf( 1,"[usb_hub]port reset complete");619 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 425 620 if (usb_port_enabled(&status)) { 426 usb_hub_finalize_add_device(hub, hc, port, target);621 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 427 622 } else { 428 dprintf( 1,"[usb_hub] ERROR:port reset, but port still not enabled");623 dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled"); 429 624 } 430 625 } … … 434 629 usb_port_set_reset_completed(&status, false); 435 630 usb_port_set_dev_connected(&status, false); 436 if (status) { 437 dprintf(1,"[usb_hub]there was some unsupported change on port %d",port); 631 if (status>>16) { 632 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status); 633 438 634 } 439 635 /// \TODO handle other changes 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) { 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; 655 void *change_bitmap = malloc(byte_length); 656 size_t actual_size; 657 447 658 /* 448 * Iterate through all hubs.659 * Send the request. 449 660 */ 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; 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) { 667 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); 475 696 } 476 477 /// FIXME: count properly 478 size_t byte_length = ((port_count+1) / 8) + 1; 479 480 void *change_bitmap = malloc(byte_length); 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 } 506 free(change_bitmap); 507 508 ipc_hangup(hc); 509 futex_down(&usb_hub_list_lock); 510 } 511 futex_up(&usb_hub_list_lock); 512 } 513 514 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 } 515 703 516 704
Note:
See TracChangeset
for help on using the changeset viewer.