Changes in / [a4e18e1:a82889e] in mainline
- Location:
- uspace/drv
- Files:
-
- 2 added
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
ra4e18e1 ra82889e 47 47 * standart device descriptor for ohci root hub 48 48 */ 49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = { 50 .configuration_count = 1, 51 .descriptor_type = USB_DESCTYPE_DEVICE, 52 .device_class = USB_CLASS_HUB, 53 .device_protocol = 0, 54 .device_subclass = 0, 55 .device_version = 0, 56 .length = sizeof (usb_standard_device_descriptor_t), 57 /// \TODO this value is guessed 58 .max_packet_size = 8, 59 .vendor_id = 0x16db, 60 .product_id = 0x0001, 61 /// \TODO these values migt be different 62 .str_serial_number = 0, 63 .usb_spec_version = 0x110, 49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = 50 { 51 .configuration_count = 1, 52 .descriptor_type = USB_DESCTYPE_DEVICE, 53 .device_class = USB_CLASS_HUB, 54 .device_protocol = 0, 55 .device_subclass = 0, 56 .device_version = 0, 57 .length = sizeof(usb_standard_device_descriptor_t), 58 /// \TODO this value is guessed 59 .max_packet_size = 8, 60 .vendor_id = 0x16db, 61 .product_id = 0x0001, 62 /// \TODO these values migt be different 63 .str_serial_number = 0, 64 .usb_spec_version = 0x110, 64 65 }; 65 66 … … 68 69 * for ohci root hubs 69 70 */ 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = { 71 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = 72 { 71 73 /// \TODO some values are default or guessed 72 .attributes = 1 <<7,74 .attributes = 1<<7, 73 75 .configuration_number = 1, 74 76 .descriptor_type = USB_DESCTYPE_CONFIGURATION, 75 77 .interface_count = 1, 76 .length = sizeof 78 .length = sizeof(usb_standard_configuration_descriptor_t), 77 79 .max_power = 100, 78 80 .str_configuration = 0, … … 82 84 * standart ohci root hub interface descriptor 83 85 */ 84 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = { 86 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = 87 { 85 88 .alternate_setting = 0, 86 89 .descriptor_type = USB_DESCTYPE_INTERFACE, … … 91 94 .interface_protocol = 0, 92 95 .interface_subclass = 0, 93 .length = sizeof 96 .length = sizeof(usb_standard_interface_descriptor_t), 94 97 .str_interface = 0, 95 98 }; … … 98 101 * standart ohci root hub endpoint descriptor 99 102 */ 100 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = { 103 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = 104 { 101 105 .attributes = USB_TRANSFER_INTERRUPT, 102 106 .descriptor_type = USB_DESCTYPE_ENDPOINT, 103 .endpoint_address = 1 + (1 <<7),104 .length = sizeof 107 .endpoint_address = 1 + (1<<7), 108 .length = sizeof(usb_standard_endpoint_descriptor_t), 105 109 .max_packet_size = 8, 106 110 .poll_interval = 255, … … 108 112 109 113 static const uint32_t hub_clear_feature_valid_mask = 110 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |111 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);114 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) + 115 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 112 116 113 117 static const uint32_t hub_clear_feature_by_writing_one_mask = … … 117 121 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 118 122 119 123 120 124 static const uint32_t hub_set_feature_direct_mask = 121 125 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 122 126 123 127 static const uint32_t port_set_feature_valid_mask = 124 (1 << USB_HUB_FEATURE_PORT_ENABLE) |125 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 126 (1 << USB_HUB_FEATURE_PORT_RESET) | 127 (1 << USB_HUB_FEATURE_PORT_POWER);128 (1 << USB_HUB_FEATURE_PORT_ENABLE) + 129 (1 << USB_HUB_FEATURE_PORT_SUSPEND) + 130 (1 << USB_HUB_FEATURE_PORT_RESET) + 131 (1 << USB_HUB_FEATURE_PORT_POWER); 128 132 129 133 static const uint32_t port_clear_feature_valid_mask = 130 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 131 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 132 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | 133 (1 << USB_HUB_FEATURE_PORT_POWER) | 134 (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) | 135 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) | 136 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) | 137 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 138 (1 << USB_HUB_FEATURE_C_PORT_RESET); 139 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into 140 //USB_HUB_FEATURE_PORT_LOW_SPEED 141 142 static const uint32_t port_status_change_mask = 143 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) | 144 (1<< USB_HUB_FEATURE_C_PORT_ENABLE) | 145 (1<< USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 146 (1<< USB_HUB_FEATURE_C_PORT_RESET) | 147 (1<< USB_HUB_FEATURE_C_PORT_SUSPEND); 148 149 150 static void usb_create_serialized_hub_descriptor(rh_t *instance, 151 uint8_t ** out_result, 152 size_t * out_size); 153 154 static void rh_init_descriptors(rh_t *instance); 155 156 static int process_get_port_status_request(rh_t *instance, uint16_t port, 157 usb_transfer_batch_t * request); 158 159 static int process_get_hub_status_request(rh_t *instance, 160 usb_transfer_batch_t * request); 161 162 static int process_get_status_request(rh_t *instance, 163 usb_transfer_batch_t * request); 164 165 static void create_interrupt_mask(rh_t *instance, void ** buffer, 166 size_t * buffer_size); 167 168 static int process_get_descriptor_request(rh_t *instance, 169 usb_transfer_batch_t *request); 170 171 static int process_get_configuration_request(rh_t *instance, 172 usb_transfer_batch_t *request); 173 174 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 175 176 static int process_hub_feature_clear_request(rh_t *instance, 177 uint16_t feature); 178 179 static int process_port_feature_set_request(rh_t *instance, 180 uint16_t feature, uint16_t port); 181 182 static int process_port_feature_clear_request(rh_t *instance, 183 uint16_t feature, uint16_t port); 184 185 static int process_address_set_request(rh_t *instance, 186 uint16_t address); 187 188 static int process_request_with_output(rh_t *instance, 189 usb_transfer_batch_t *request); 190 191 static int process_request_with_input(rh_t *instance, 192 usb_transfer_batch_t *request); 193 194 static int process_request_without_data(rh_t *instance, 195 usb_transfer_batch_t *request); 196 197 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 198 199 200 201 202 203 /** Root hub initialization 204 * @return Error code. 205 */ 206 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) { 207 assert(instance); 208 //instance->address = -1; 209 instance->registers = regs; 210 instance->device = dev; 211 instance->port_count = instance->registers->rh_desc_a & 0xff; 212 rh_init_descriptors(instance); 213 // set port power mode to no-power-switching 214 instance->registers->rh_desc_a = 215 instance->registers->rh_desc_a | (1<<9); 216 217 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 218 219 //start generic usb hub driver 220 221 /* TODO: implement */ 222 return EOK; 223 } 224 /*----------------------------------------------------------------------------*/ 225 226 /** 227 * process root hub request 228 * 229 * @param instance root hub instance 230 * @param request structure containing both request and response information 231 * @return error code 232 */ 233 int rh_request(rh_t *instance, usb_transfer_batch_t *request) { 234 assert(instance); 235 assert(request); 236 int opResult; 237 if (request->transfer_type == USB_TRANSFER_CONTROL) { 238 usb_log_info("Root hub got CONTROL packet\n"); 239 opResult = process_ctrl_request(instance, request); 240 } else if (request->transfer_type == USB_TRANSFER_INTERRUPT) { 241 usb_log_info("Root hub got INTERRUPT packet\n"); 242 void * buffer; 243 create_interrupt_mask(instance, &buffer, 244 &(request->transfered_size)); 245 memcpy(request->transport_buffer, buffer, 246 request->transfered_size); 247 opResult = EOK; 248 } else { 249 opResult = EINVAL; 250 } 251 usb_transfer_batch_finish(request, opResult); 252 return EOK; 253 } 254 255 /*----------------------------------------------------------------------------*/ 256 257 258 void rh_interrupt(rh_t *instance) { 259 usb_log_info("Whoa whoa wait, I`m not supposed to receive any " 260 "interrupts, am I?\n"); 261 /* TODO: implement? */ 262 } 263 /*----------------------------------------------------------------------------*/ 134 (1 << USB_HUB_FEATURE_PORT_CONNECTION) + 135 (1 << USB_HUB_FEATURE_PORT_SUSPEND) + 136 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) + 137 (1 << USB_HUB_FEATURE_PORT_POWER) + 138 (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) + 139 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) + 140 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) + 141 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) + 142 (1 << USB_HUB_FEATURE_C_PORT_RESET); 143 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into USB_HUB_FEATURE_PORT_LOW_SPEED 144 145 146 264 147 265 148 /** … … 274 157 */ 275 158 static void usb_create_serialized_hub_descriptor(rh_t *instance, 276 uint8_t ** out_result,277 size_t * out_size) {159 uint8_t ** out_result, 160 size_t * out_size) { 278 161 //base size 279 162 size_t size = 7; 280 163 //variable size according to port count 281 164 size_t var_size = instance->port_count / 8 + 282 ((instance->port_count % 8 > 0) ? 1 : 0);165 ((instance->port_count % 8 > 0) ? 1 : 0); 283 166 size += 2 * var_size; 284 167 uint8_t * result = (uint8_t*) malloc(size); 285 bzero(result, 168 bzero(result,size); 286 169 //size 287 170 result[0] = size; … … 291 174 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 292 175 result[3] = 293 ((hub_desc_reg >> 8) %2) +294 (((hub_desc_reg >> 9) %2) << 1) +295 (((hub_desc_reg >> 10) %2) << 2) +296 (((hub_desc_reg >> 11) %2) << 3) +297 (((hub_desc_reg >> 12) %2) << 4);176 ((hub_desc_reg >> 8) %2) + 177 (((hub_desc_reg >> 9) %2) << 1) + 178 (((hub_desc_reg >> 10) %2) << 2) + 179 (((hub_desc_reg >> 11) %2) << 3) + 180 (((hub_desc_reg >> 12) %2) << 4); 298 181 result[4] = 0; 299 182 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; … … 302 185 int port; 303 186 for (port = 1; port <= instance->port_count; ++port) { 304 uint8_t is_non_removable = 305 instance->registers->rh_desc_b >> port % 2; 306 result[7 + port / 8] += 307 is_non_removable << (port % 8); 187 result[7 + port/8] += 188 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 308 189 } 309 190 size_t i; … … 314 195 (*out_size) = size; 315 196 } 316 /*----------------------------------------------------------------------------*/ 197 317 198 318 199 /** initialize hub descriptors … … 322 203 * @instance root hub instance 323 204 */ 324 static void rh_init_descriptors(rh_t *instance) 205 static void rh_init_descriptors(rh_t *instance){ 325 206 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 326 sizeof 327 207 sizeof(ohci_rh_device_descriptor) 208 ); 328 209 usb_standard_configuration_descriptor_t descriptor; 329 memcpy(&descriptor, 330 sizeof(ohci_rh_conf_descriptor));210 memcpy(&descriptor,&ohci_rh_conf_descriptor, 211 sizeof(ohci_rh_conf_descriptor)); 331 212 uint8_t * hub_descriptor; 332 213 size_t hub_desc_size; 333 214 usb_create_serialized_hub_descriptor(instance, &hub_descriptor, 334 &hub_desc_size);215 &hub_desc_size); 335 216 336 217 descriptor.total_length = 337 sizeof (usb_standard_configuration_descriptor_t)+338 sizeof (usb_standard_endpoint_descriptor_t)+339 sizeof (usb_standard_interface_descriptor_t)+340 hub_desc_size;341 218 sizeof(usb_standard_configuration_descriptor_t)+ 219 sizeof(usb_standard_endpoint_descriptor_t)+ 220 sizeof(usb_standard_interface_descriptor_t)+ 221 hub_desc_size; 222 342 223 uint8_t * full_config_descriptor = 343 (uint8_t*) malloc(descriptor.total_length);344 memcpy(full_config_descriptor, &descriptor, sizeof 345 memcpy(full_config_descriptor + sizeof 346 &ohci_rh_iface_descriptor, sizeof(ohci_rh_iface_descriptor));347 memcpy(full_config_descriptor + sizeof 348 sizeof(ohci_rh_iface_descriptor),349 &ohci_rh_ep_descriptor, sizeof(ohci_rh_ep_descriptor));350 memcpy(full_config_descriptor + sizeof 351 sizeof(ohci_rh_iface_descriptor) +352 sizeof(ohci_rh_ep_descriptor),353 hub_descriptor, hub_desc_size);354 224 (uint8_t*) malloc(descriptor.total_length); 225 memcpy(full_config_descriptor, &descriptor, sizeof(descriptor)); 226 memcpy(full_config_descriptor + sizeof(descriptor), 227 &ohci_rh_iface_descriptor, sizeof(ohci_rh_iface_descriptor)); 228 memcpy(full_config_descriptor + sizeof(descriptor) + 229 sizeof(ohci_rh_iface_descriptor), 230 &ohci_rh_ep_descriptor, sizeof(ohci_rh_ep_descriptor)); 231 memcpy(full_config_descriptor + sizeof(descriptor) + 232 sizeof(ohci_rh_iface_descriptor) + 233 sizeof(ohci_rh_ep_descriptor), 234 hub_descriptor, hub_desc_size); 235 355 236 instance->descriptors.configuration = full_config_descriptor; 356 237 instance->descriptors.configuration_size = descriptor.total_length; 357 238 } 239 240 /** Root hub initialization 241 * @return Error code. 242 */ 243 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) 244 { 245 assert(instance); 246 instance->address = -1; 247 instance->registers = regs; 248 instance->device = dev; 249 instance->port_count = instance->registers->rh_desc_a & 0xff; 250 rh_init_descriptors(instance); 251 /// \TODO set port power mode 252 253 254 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 255 256 //start generic usb hub driver 257 258 /* TODO: implement */ 259 return EOK; 260 } 358 261 /*----------------------------------------------------------------------------*/ 359 262 … … 369 272 */ 370 273 static int process_get_port_status_request(rh_t *instance, uint16_t port, 371 usb_transfer_batch_t * request){372 if (port < 1 || port >instance->port_count)373 return EINVAL; 374 uint32_t * uint32_buffer = (uint32_t*) 274 usb_transfer_batch_t * request){ 275 if(port<1 || port>instance->port_count) 276 return EINVAL; 277 uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer; 375 278 request->transfered_size = 4; 376 uint32_buffer[0] = instance->registers->rh_port_status[port - 1]; 377 #if 0 378 int i; 379 for (i = 0; i < instance->port_count; ++i) { 380 usb_log_debug("port status %d,x%x\n", 381 instance->registers->rh_port_status[i], 382 instance->registers->rh_port_status[i]); 383 } 384 #endif 385 return EOK; 386 } 387 /*----------------------------------------------------------------------------*/ 279 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 280 return EOK; 281 } 388 282 389 283 /** … … 397 291 */ 398 292 static int process_get_hub_status_request(rh_t *instance, 399 usb_transfer_batch_t * request) { 400 uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer; 293 usb_transfer_batch_t * request){ 294 uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer; 295 //bits, 0,1,16,17 401 296 request->transfered_size = 4; 402 //bits, 0,1,16,17 403 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 297 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 404 298 uint32_buffer[0] = mask & instance->registers->rh_status; 405 299 return EOK; 406 } 407 /*----------------------------------------------------------------------------*/ 300 301 } 302 303 408 304 409 305 /** … … 417 313 */ 418 314 static int process_get_status_request(rh_t *instance, 419 usb_transfer_batch_t * request) { 315 usb_transfer_batch_t * request) 316 { 420 317 size_t buffer_size = request->buffer_size; 421 318 usb_device_request_setup_packet_t * request_packet = 422 (usb_device_request_setup_packet_t*)423 request->setup_buffer;319 (usb_device_request_setup_packet_t*) 320 request->setup_buffer; 424 321 425 322 usb_hub_bm_request_type_t request_type = request_packet->request_type; 426 if (buffer_size < 4/*request_packet->length*/){///\TODO323 if(buffer_size<4/*request_packet->length*/){///\TODO 427 324 usb_log_warning("requested more data than buffer size\n"); 428 325 return EINVAL; 429 326 } 430 327 431 if 328 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 432 329 return process_get_hub_status_request(instance, request); 433 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 434 return process_get_port_status_request(instance, 435 request_packet->index, 436 request); 330 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 331 return process_get_port_status_request(instance, request_packet->index, 332 request); 437 333 return ENOTSUP; 438 334 } 439 /*----------------------------------------------------------------------------*/440 335 441 336 /** … … 444 339 * Result contains bitmap where bit 0 indicates change on hub and 445 340 * bit i indicates change on i`th port (i>0). For more info see 446 * Hub and Port status bitmap specification in USB specification 447 * (chapter 11.13.4) 341 * Hub and Port status bitmap specification in USB specification. 448 342 * @param instance root hub instance 449 343 * @param@out buffer pointer to created interrupt mas … … 451 345 */ 452 346 static void create_interrupt_mask(rh_t *instance, void ** buffer, 453 size_t * buffer_size){347 size_t * buffer_size){ 454 348 int bit_count = instance->port_count + 1; 455 (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1); 456 349 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 457 350 (*buffer) = malloc(*buffer_size); 458 uint8_t * bitmap = (uint8_t*) (*buffer); 459 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 460 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 461 bzero(bitmap, (*buffer_size)); 462 if (instance->registers->rh_status & mask) { 351 uint8_t * bitmap = (uint8_t*)(*buffer); 352 uint32_t mask = (1<<16) + (1<<17); 353 bzero(bitmap,(*buffer_size)); 354 if(instance->registers->rh_status & mask){ 463 355 bitmap[0] = 1; 464 356 } 465 357 int port; 466 mask = port_status_change_mask; 467 for (port = 1; port <= instance->port_count; ++port) { 468 if (mask & instance->registers->rh_port_status[port - 1]) { 469 bitmap[(port) / 8] += 1 << (port % 8); 470 } 471 } 472 } 473 /*----------------------------------------------------------------------------*/ 474 358 mask = 0; 359 int i; 360 for(i=16;i<=20;++i) 361 mask += 1<<i; 362 for(port = 1; port<=instance->port_count;++port){ 363 if(mask & instance->registers->rh_port_status[port-1]){ 364 bitmap[(port+1)/8] += 1<<(port%8); 365 } 366 } 367 } 368 475 369 /** 476 370 * create answer to a descriptor request … … 483 377 */ 484 378 static int process_get_descriptor_request(rh_t *instance, 485 usb_transfer_batch_t *request){379 usb_transfer_batch_t *request){ 486 380 usb_device_request_setup_packet_t * setup_request = 487 (usb_device_request_setup_packet_t*)request->setup_buffer;381 (usb_device_request_setup_packet_t*)request->setup_buffer; 488 382 size_t size; 489 383 const void * result_descriptor = NULL; 490 384 const uint16_t setup_request_value = setup_request->value_high; 491 //(setup_request->value_low << 8);385 //(setup_request->value_low << 8); 492 386 bool del = false; 493 switch (setup_request_value) {494 case USB_DESCTYPE_HUB:495 {387 switch (setup_request_value) 388 { 389 case USB_DESCTYPE_HUB: { 496 390 uint8_t * descriptor; 497 391 usb_create_serialized_hub_descriptor( 498 392 instance, &descriptor, &size); 499 393 result_descriptor = descriptor; 500 if 394 if(result_descriptor) del = true; 501 395 break; 502 396 } 503 case USB_DESCTYPE_DEVICE: 504 { 397 case USB_DESCTYPE_DEVICE: { 505 398 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 506 399 result_descriptor = &ohci_rh_device_descriptor; 507 size = sizeof 400 size = sizeof(ohci_rh_device_descriptor); 508 401 break; 509 402 } 510 case USB_DESCTYPE_CONFIGURATION: 511 { 403 case USB_DESCTYPE_CONFIGURATION: { 512 404 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 513 405 result_descriptor = instance->descriptors.configuration; … … 515 407 break; 516 408 } 517 case USB_DESCTYPE_INTERFACE: 518 { 409 case USB_DESCTYPE_INTERFACE: { 519 410 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 520 411 result_descriptor = &ohci_rh_iface_descriptor; 521 size = sizeof 412 size = sizeof(ohci_rh_iface_descriptor); 522 413 break; 523 414 } 524 case USB_DESCTYPE_ENDPOINT: 525 { 415 case USB_DESCTYPE_ENDPOINT: { 526 416 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 527 417 result_descriptor = &ohci_rh_ep_descriptor; 528 size = sizeof 418 size = sizeof(ohci_rh_ep_descriptor); 529 419 break; 530 420 } 531 default: 532 { 533 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 534 setup_request->value); 535 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 536 "%d\n\tindex %d\n\tlen %d\n ", 537 setup_request->request_type, 538 setup_request->request, 539 setup_request_value, 540 setup_request->index, 541 setup_request->length 542 ); 421 default: { 422 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 423 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 424 setup_request->request_type, 425 setup_request->request, 426 setup_request_value, 427 setup_request->index, 428 setup_request->length 429 ); 543 430 return EINVAL; 544 431 } 545 432 } 546 if (request->buffer_size < size){433 if(request->buffer_size < size){ 547 434 size = request->buffer_size; 548 435 } 549 436 request->transfered_size = size; 550 memcpy(request->transport_buffer, result_descriptor, size); 437 memcpy(request->transport_buffer,result_descriptor,size); 438 usb_log_debug("sent desctiptor: %s\n", 439 usb_debug_str_buffer((uint8_t*)request->transport_buffer,size,size)); 551 440 if (del) 552 441 free(result_descriptor); 553 442 return EOK; 554 443 } 555 /*----------------------------------------------------------------------------*/556 444 557 445 /** … … 563 451 * @return error code 564 452 */ 565 static int process_get_configuration_request(rh_t *instance, 566 usb_transfer_batch_t *request){453 static int process_get_configuration_request(rh_t *instance, 454 usb_transfer_batch_t *request){ 567 455 //set and get configuration requests do not have any meaning, only dummy 568 456 //values are returned 569 if 457 if(request->buffer_size != 1) 570 458 return EINVAL; 571 459 request->transport_buffer[0] = 1; … … 573 461 return EOK; 574 462 } 575 /*----------------------------------------------------------------------------*/576 463 577 464 /** 578 465 * process feature-enabling request on hub 579 * 466 * 580 467 * @param instance root hub instance 581 468 * @param feature feature selector … … 583 470 */ 584 471 static int process_hub_feature_set_request(rh_t *instance, 585 uint16_t feature){586 if (!((1 <<feature) & hub_set_feature_valid_mask))472 uint16_t feature){ 473 if(! ((1<<feature) & hub_set_feature_valid_mask)) 587 474 return EINVAL; 588 475 instance->registers->rh_status = 589 (instance->registers->rh_status | (1 << feature)) 590 & (~hub_clear_feature_by_writing_one_mask); 591 return EOK; 592 } 593 /*----------------------------------------------------------------------------*/ 476 (instance->registers->rh_status | (1<<feature)) 477 & (~ hub_clear_feature_by_writing_one_mask); 478 return EOK; 479 } 594 480 595 481 /** … … 601 487 */ 602 488 static int process_hub_feature_clear_request(rh_t *instance, 603 uint16_t feature){604 if (!((1 <<feature) & hub_clear_feature_valid_mask))489 uint16_t feature){ 490 if(! ((1<<feature) & hub_clear_feature_valid_mask)) 605 491 return EINVAL; 606 492 //is the feature cleared directly? 607 if ((1 << feature) & hub_set_feature_direct_mask){493 if ((1<<feature) & hub_set_feature_direct_mask){ 608 494 instance->registers->rh_status = 609 (instance->registers->rh_status & (~(1 <<feature)))610 & (~ hub_clear_feature_by_writing_one_mask);611 } else{//the feature is cleared by writing '1'495 (instance->registers->rh_status & (~(1<<feature))) 496 & (~ hub_clear_feature_by_writing_one_mask); 497 }else{//the feature is cleared by writing '1' 612 498 instance->registers->rh_status = 613 (instance->registers->rh_status 614 & (~hub_clear_feature_by_writing_one_mask)) 615 | (1 << feature); 616 } 617 return EOK; 618 } 619 /*----------------------------------------------------------------------------*/ 499 (instance->registers->rh_status 500 & (~ hub_clear_feature_by_writing_one_mask)) 501 | (1<<feature); 502 } 503 return EOK; 504 } 505 506 620 507 621 508 /** 622 509 * process feature-enabling request on hub 623 * 510 * 624 511 * @param instance root hub instance 625 512 * @param feature feature selector … … 629 516 */ 630 517 static int process_port_feature_set_request(rh_t *instance, 631 uint16_t feature, uint16_t port){632 if (!((1 <<feature) & port_set_feature_valid_mask))633 return EINVAL; 634 if (port < 1 || port >instance->port_count)518 uint16_t feature, uint16_t port){ 519 if(!((1<<feature) & port_set_feature_valid_mask)) 520 return EINVAL; 521 if(port<1 || port>instance->port_count) 635 522 return EINVAL; 636 523 instance->registers->rh_port_status[port - 1] = 637 (instance->registers->rh_port_status[port - 1] | (1 <<feature))638 & (~port_clear_feature_valid_mask);524 (instance->registers->rh_port_status[port - 1] | (1<<feature)) 525 & (~port_clear_feature_valid_mask); 639 526 /// \TODO any error? 640 527 return EOK; 641 528 } 642 /*----------------------------------------------------------------------------*/643 529 644 530 /** … … 652 538 */ 653 539 static int process_port_feature_clear_request(rh_t *instance, 654 uint16_t feature, uint16_t port){655 if (!((1 <<feature) & port_clear_feature_valid_mask))656 return EINVAL; 657 if (port < 1 || port >instance->port_count)658 return EINVAL; 659 if 540 uint16_t feature, uint16_t port){ 541 if(!((1<<feature) & port_clear_feature_valid_mask)) 542 return EINVAL; 543 if(port<1 || port>instance->port_count) 544 return EINVAL; 545 if(feature == USB_HUB_FEATURE_PORT_POWER) 660 546 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 661 if 547 if(feature == USB_HUB_FEATURE_PORT_SUSPEND) 662 548 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 663 549 instance->registers->rh_port_status[port - 1] = 664 (instance->registers->rh_port_status[port - 1]665 & (~port_clear_feature_valid_mask))666 | (1 <<feature);550 (instance->registers->rh_port_status[port - 1] 551 & (~port_clear_feature_valid_mask)) 552 | (1<<feature); 667 553 /// \TODO any error? 668 554 return EOK; 669 555 } 670 /*----------------------------------------------------------------------------*/ 556 671 557 672 558 /** 673 559 * register address to this device 674 * 560 * 675 561 * @param instance root hub instance 676 562 * @param address new address … … 678 564 */ 679 565 static int process_address_set_request(rh_t *instance, 680 uint16_t address){566 uint16_t address){ 681 567 instance->address = address; 682 568 return EOK; 683 569 } 684 /*----------------------------------------------------------------------------*/685 570 686 571 /** … … 694 579 */ 695 580 static int process_request_with_output(rh_t *instance, 696 usb_transfer_batch_t *request){581 usb_transfer_batch_t *request){ 697 582 usb_device_request_setup_packet_t * setup_request = 698 (usb_device_request_setup_packet_t*)request->setup_buffer;699 if (setup_request->request == USB_DEVREQ_GET_STATUS){583 (usb_device_request_setup_packet_t*)request->setup_buffer; 584 if(setup_request->request == USB_DEVREQ_GET_STATUS){ 700 585 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 701 586 return process_get_status_request(instance, request); 702 587 } 703 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){588 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){ 704 589 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 705 590 return process_get_descriptor_request(instance, request); 706 591 } 707 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION){592 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){ 708 593 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 709 594 return process_get_configuration_request(instance, request); … … 711 596 return ENOTSUP; 712 597 } 713 /*----------------------------------------------------------------------------*/714 598 715 599 /** … … 723 607 */ 724 608 static int process_request_with_input(rh_t *instance, 725 usb_transfer_batch_t *request){609 usb_transfer_batch_t *request){ 726 610 usb_device_request_setup_packet_t * setup_request = 727 (usb_device_request_setup_packet_t*)request->setup_buffer;611 (usb_device_request_setup_packet_t*)request->setup_buffer; 728 612 request->transfered_size = 0; 729 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){613 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){ 730 614 return ENOTSUP; 731 615 } 732 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION){616 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){ 733 617 //set and get configuration requests do not have any meaning, 734 618 //only dummy values are returned … … 737 621 return ENOTSUP; 738 622 } 739 /*----------------------------------------------------------------------------*/740 623 741 624 /** … … 749 632 */ 750 633 static int process_request_without_data(rh_t *instance, 751 usb_transfer_batch_t *request){634 usb_transfer_batch_t *request){ 752 635 usb_device_request_setup_packet_t * setup_request = 753 (usb_device_request_setup_packet_t*)request->setup_buffer;636 (usb_device_request_setup_packet_t*)request->setup_buffer; 754 637 request->transfered_size = 0; 755 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE){756 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){638 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE){ 639 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 757 640 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 758 641 return process_hub_feature_clear_request(instance, 759 setup_request->value);760 } 761 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){642 setup_request->value); 643 } 644 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 762 645 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 763 646 return process_port_feature_clear_request(instance, 764 setup_request->value,765 setup_request->index);647 setup_request->value, 648 setup_request->index); 766 649 } 767 650 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 768 setup_request->request_type);769 return EINVAL; 770 } 771 if (setup_request->request == USB_DEVREQ_SET_FEATURE){772 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){651 setup_request->request_type); 652 return EINVAL; 653 } 654 if(setup_request->request == USB_DEVREQ_SET_FEATURE){ 655 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 773 656 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 774 657 return process_hub_feature_set_request(instance, 775 setup_request->value);776 } 777 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){658 setup_request->value); 659 } 660 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 778 661 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 779 662 return process_port_feature_set_request(instance, 780 setup_request->value, 781 setup_request->index); 782 } 783 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 784 setup_request->request_type); 785 return EINVAL; 786 } 787 if (setup_request->request == USB_DEVREQ_SET_ADDRESS) { 663 setup_request->value, 664 setup_request->index); 665 } 666 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type); 667 return EINVAL; 668 } 669 if(setup_request->request == USB_DEVREQ_SET_ADDRESS){ 788 670 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 789 return process_address_set_request(instance, 790 setup_request->value); 791 } 792 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 793 setup_request->request_type); 671 return process_address_set_request(instance, setup_request->value); 672 } 673 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type); 794 674 return ENOTSUP; 795 675 } 796 /*----------------------------------------------------------------------------*/797 676 798 677 /** … … 814 693 * @return error code 815 694 */ 816 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) { 817 if (!request->setup_buffer) { 695 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){ 696 int opResult; 697 if (request->setup_buffer) { 698 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 699 usb_log_error("setup packet too small\n"); 700 return EINVAL; 701 } 702 usb_log_info("CTRL packet: %s.\n", 703 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 704 usb_device_request_setup_packet_t * setup_request = 705 (usb_device_request_setup_packet_t*)request->setup_buffer; 706 if( 707 setup_request->request == USB_DEVREQ_GET_STATUS 708 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 709 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 710 ){ 711 usb_log_debug("processing request with output\n"); 712 opResult = process_request_with_output(instance,request); 713 }else if( 714 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 715 || setup_request->request == USB_DEVREQ_SET_FEATURE 716 || setup_request->request == USB_DEVREQ_SET_ADDRESS 717 ){ 718 usb_log_debug("processing request without additional data\n"); 719 opResult = process_request_without_data(instance,request); 720 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 721 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 722 ){ 723 usb_log_debug("processing request with input\n"); 724 opResult = process_request_with_input(instance,request); 725 }else{ 726 usb_log_warning("received unsuported request: %d\n", 727 setup_request->request 728 ); 729 opResult = ENOTSUP; 730 } 731 }else{ 818 732 usb_log_error("root hub received empty transaction?"); 819 return EINVAL; 820 } 733 opResult = EINVAL; 734 } 735 return opResult; 736 } 737 738 /** 739 * process root hub request 740 * 741 * @param instance root hub instance 742 * @param request structure containing both request and response information 743 * @return error code 744 */ 745 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 746 { 747 assert(instance); 748 assert(request); 821 749 int opResult; 822 if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) { 823 usb_log_error("setup packet too small\n"); 824 return EINVAL; 825 } 826 usb_log_info("CTRL packet: %s.\n", 827 usb_debug_str_buffer( 828 (const uint8_t *) request->setup_buffer, 8, 8)); 829 usb_device_request_setup_packet_t * setup_request = 830 (usb_device_request_setup_packet_t*) 831 request->setup_buffer; 832 switch (setup_request->request) { 833 case USB_DEVREQ_GET_STATUS: 834 case USB_DEVREQ_GET_DESCRIPTOR: 835 case USB_DEVREQ_GET_CONFIGURATION: 836 usb_log_debug("processing request with output\n"); 837 opResult = process_request_with_output( 838 instance, request); 839 break; 840 case USB_DEVREQ_CLEAR_FEATURE: 841 case USB_DEVREQ_SET_FEATURE: 842 case USB_DEVREQ_SET_ADDRESS: 843 usb_log_debug("processing request without " 844 "additional data\n"); 845 opResult = process_request_without_data( 846 instance, request); 847 break; 848 case USB_DEVREQ_SET_DESCRIPTOR: 849 case USB_DEVREQ_SET_CONFIGURATION: 850 usb_log_debug("processing request with " 851 "input\n"); 852 opResult = process_request_with_input( 853 instance, request); 854 break; 855 default: 856 usb_log_warning("received unsuported request: " 857 "%d\n", 858 setup_request->request 859 ); 860 opResult = ENOTSUP; 861 } 862 return opResult; 863 } 864 865 866 867 750 if(request->transfer_type == USB_TRANSFER_CONTROL){ 751 usb_log_info("Root hub got CONTROL packet\n"); 752 opResult = process_ctrl_request(instance,request); 753 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 754 usb_log_info("Root hub got INTERRUPT packet\n"); 755 void * buffer; 756 create_interrupt_mask(instance, &buffer, 757 &(request->transfered_size)); 758 memcpy(request->transport_buffer,buffer, request->transfered_size); 759 opResult = EOK; 760 }else{ 761 opResult = EINVAL; 762 } 763 usb_transfer_batch_finish(request, opResult); 764 return EOK; 765 } 766 /*----------------------------------------------------------------------------*/ 767 768 769 void rh_interrupt(rh_t *instance) 770 { 771 usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n"); 772 /* TODO: implement? */ 773 } 868 774 /** 869 775 * @} -
uspace/drv/usbhub/Makefile
ra4e18e1 ra82889e 34 34 SOURCES = \ 35 35 main.c \ 36 ports.c \ 36 37 utils.c \ 37 usbhub.c \ 38 usblist.c 38 usbhub.c 39 39 40 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/usbhub/port_status.h
ra4e18e1 ra82889e 49 49 50 50 /** 51 * structure holding hub status and changes flags.52 * should not be accessed directly, use supplied getter/setter methods.53 *54 * For more information refer to table 11.16.2.5 in55 * "Universal Serial Bus Specification Revision 1.1"56 *57 */58 typedef uint32_t usb_hub_status_t;59 60 /**61 51 * set values in request to be it a port status request 62 52 * @param request … … 64 54 */ 65 55 static inline void usb_hub_set_port_status_request( 66 67 ){56 usb_device_request_setup_packet_t * request, uint16_t port 57 ){ 68 58 request->index = port; 69 59 request->request_type = USB_HUB_REQ_TYPE_GET_PORT_STATUS; … … 73 63 } 74 64 75 /**76 * set values in request to be it a port status request77 * @param request78 * @param port79 */80 static inline void usb_hub_set_hub_status_request(81 usb_device_request_setup_packet_t * request82 ) {83 request->index = 0;84 request->request_type = USB_HUB_REQ_TYPE_GET_HUB_STATUS;85 request->request = USB_HUB_REQUEST_GET_STATUS;86 request->value = 0;87 request->length = 4;88 }89 65 90 66 /** … … 94 70 */ 95 71 static inline usb_device_request_setup_packet_t * 96 usb_hub_create_port_status_request(uint16_t port) 72 usb_hub_create_port_status_request(uint16_t port){ 97 73 usb_device_request_setup_packet_t * result = 98 74 usb_new(usb_device_request_setup_packet_t); 99 usb_hub_set_port_status_request(result, 75 usb_hub_set_port_status_request(result,port); 100 76 return result; 101 77 } 102 78 79 103 80 /** 104 81 * set the device request to be a port feature enable request … … 108 85 */ 109 86 static inline void usb_hub_set_enable_port_feature_request( 110 111 uint16_t feature_selector112 ){87 usb_device_request_setup_packet_t * request, uint16_t port, 88 uint16_t feature_selector 89 ){ 113 90 request->index = port; 114 91 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 125 102 */ 126 103 static inline void usb_hub_set_disable_port_feature_request( 127 128 uint16_t feature_selector129 ){104 usb_device_request_setup_packet_t * request, uint16_t port, 105 uint16_t feature_selector 106 ){ 130 107 request->index = port; 131 108 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 141 118 */ 142 119 static inline void usb_hub_set_enable_port_request( 143 144 ){120 usb_device_request_setup_packet_t * request, uint16_t port 121 ){ 145 122 request->index = port; 146 123 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 156 133 */ 157 134 static inline usb_device_request_setup_packet_t * 158 usb_hub_create_enable_port_request(uint16_t port) 135 usb_hub_create_enable_port_request(uint16_t port){ 159 136 usb_device_request_setup_packet_t * result = 160 137 usb_new(usb_device_request_setup_packet_t); 161 usb_hub_set_enable_port_request(result, 138 usb_hub_set_enable_port_request(result,port); 162 139 return result; 163 140 } … … 169 146 */ 170 147 static inline void usb_hub_set_disable_port_request( 171 172 ){148 usb_device_request_setup_packet_t * request, uint16_t port 149 ){ 173 150 request->index = port; 174 151 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 184 161 */ 185 162 static inline usb_device_request_setup_packet_t * 186 usb_hub_create_disable_port_request(uint16_t port) 163 usb_hub_create_disable_port_request(uint16_t port){ 187 164 usb_device_request_setup_packet_t * result = 188 165 usb_new(usb_device_request_setup_packet_t); 189 usb_hub_set_disable_port_request(result, 166 usb_hub_set_disable_port_request(result,port); 190 167 return result; 191 168 } … … 197 174 */ 198 175 static inline void usb_hub_set_reset_port_request( 199 200 ){176 usb_device_request_setup_packet_t * request, uint16_t port 177 ){ 201 178 request->index = port; 202 179 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 212 189 */ 213 190 static inline usb_device_request_setup_packet_t * 214 usb_hub_create_reset_port_request(uint16_t port) 191 usb_hub_create_reset_port_request(uint16_t port){ 215 192 usb_device_request_setup_packet_t * result = 216 193 usb_new(usb_device_request_setup_packet_t); 217 usb_hub_set_reset_port_request(result, 194 usb_hub_set_reset_port_request(result,port); 218 195 return result; 219 196 } … … 225 202 */ 226 203 static inline void usb_hub_set_power_port_request( 227 228 ){204 usb_device_request_setup_packet_t * request, uint16_t port 205 ){ 229 206 request->index = port; 230 207 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 240 217 */ 241 218 static inline void usb_hub_unset_power_port_request( 242 243 ){219 usb_device_request_setup_packet_t * request, uint16_t port 220 ){ 244 221 request->index = port; 245 222 request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE; … … 249 226 } 250 227 251 /** 252 * get i`th bit of port status 253 * 254 * @param status 255 * @param idx 256 * @return 257 */ 258 static inline bool usb_port_get_bit(usb_port_status_t * status, int idx) { 259 return ((*status)&(1 << idx))!=0; 260 } 261 262 /** 263 * set i`th bit of port status 264 * 265 * @param status 266 * @param idx 267 * @param value 268 */ 228 229 /** get i`th bit of port status */ 230 static inline bool usb_port_get_bit(usb_port_status_t * status, int idx) 231 { 232 return (((*status)>>(idx))%2); 233 } 234 235 /** set i`th bit of port status */ 269 236 static inline void usb_port_set_bit( 270 usb_port_status_t * status, int idx, bool value) { 271 (*status) = value ? 272 ((*status) | (1 << (idx))) : 273 ((*status)&(~(1 << (idx)))); 274 } 275 276 /** 277 * get i`th bit of hub status 278 * 279 * @param status 280 * @param idx 281 * @return 282 */ 283 static inline bool usb_hub_get_bit(usb_hub_status_t * status, int idx) { 284 return (*status)&(1 << idx); 285 } 286 287 /** 288 * set i`th bit of hub status 289 * 290 * @param status 291 * @param idx 292 * @param value 293 */ 294 static inline void usb_hub_set_bit( 295 usb_hub_status_t * status, int idx, bool value) { 296 (*status) = value ? 297 ((*status) | (1 << (idx))) : 298 ((*status)&(~(1 << (idx)))); 299 } 300 301 /** 302 * connection status geter for port status 303 * 304 * @param status 305 * @return true if there is something connected 306 */ 307 static inline bool usb_port_dev_connected(usb_port_status_t * status) { 308 return usb_port_get_bit(status, 0); 309 } 310 311 static inline void usb_port_set_dev_connected(usb_port_status_t * status, bool connected) { 312 usb_port_set_bit(status, 0, connected); 237 usb_port_status_t * status, int idx, bool value) 238 { 239 (*status) = value? 240 ((*status)|(1<<(idx))): 241 ((*status)&(~(1<<(idx)))); 242 } 243 244 //device connnected on port 245 static inline bool usb_port_dev_connected(usb_port_status_t * status){ 246 return usb_port_get_bit(status,0); 247 } 248 249 static inline void usb_port_set_dev_connected(usb_port_status_t * status,bool connected){ 250 usb_port_set_bit(status,0,connected); 313 251 } 314 252 315 253 //port enabled 316 317 /** 318 * port enabled getter for port status 319 * 320 * @param status 321 * @return true if the port is enabled 322 */ 323 static inline bool usb_port_enabled(usb_port_status_t * status) { 324 return usb_port_get_bit(status, 1); 325 } 326 327 static inline void usb_port_set_enabled(usb_port_status_t * status, bool enabled) { 328 usb_port_set_bit(status, 1, enabled); 254 static inline bool usb_port_enabled(usb_port_status_t * status){ 255 return usb_port_get_bit(status,1); 256 } 257 258 static inline void usb_port_set_enabled(usb_port_status_t * status,bool enabled){ 259 usb_port_set_bit(status,1,enabled); 329 260 } 330 261 331 262 //port suspended 332 /** 333 * port suspended getter for port status 334 * 335 * @param status 336 * @return true if port is suspended 337 */ 338 static inline bool usb_port_suspended(usb_port_status_t * status) { 339 return usb_port_get_bit(status, 2); 340 } 341 342 static inline void usb_port_set_suspended(usb_port_status_t * status, bool suspended) { 343 usb_port_set_bit(status, 2, suspended); 263 static inline bool usb_port_suspended(usb_port_status_t * status){ 264 return usb_port_get_bit(status,2); 265 } 266 267 static inline void usb_port_set_suspended(usb_port_status_t * status,bool suspended){ 268 usb_port_set_bit(status,2,suspended); 344 269 } 345 270 346 271 //over currect 347 /** 348 * over current condition indicator getter for port status 349 * 350 * @param status 351 * @return true if there is opver-current condition on the hub 352 */ 353 static inline bool usb_port_over_current(usb_port_status_t * status) { 354 return usb_port_get_bit(status, 3); 355 } 356 357 static inline void usb_port_set_over_current(usb_port_status_t * status, bool value) { 358 usb_port_set_bit(status, 3, value); 272 static inline bool usb_port_over_current(usb_port_status_t * status){ 273 return usb_port_get_bit(status,3); 274 } 275 276 static inline void usb_port_set_over_current(usb_port_status_t * status,bool value){ 277 usb_port_set_bit(status,3,value); 359 278 } 360 279 361 280 //port reset 362 /** 363 * port reset indicator getter for port status 364 * 365 * @param status 366 * @return true if port is reset 367 */ 368 static inline bool usb_port_reset(usb_port_status_t * status) { 369 return usb_port_get_bit(status, 4); 370 } 371 372 static inline void usb_port_set_reset(usb_port_status_t * status, bool value) { 373 usb_port_set_bit(status, 4, value); 281 static inline bool usb_port_reset(usb_port_status_t * status){ 282 return usb_port_get_bit(status,4); 283 } 284 285 static inline void usb_port_set_reset(usb_port_status_t * status,bool value){ 286 usb_port_set_bit(status,4,value); 374 287 } 375 288 376 289 //powered 377 /** 378 * power state getter for port status 379 * 380 * @param status 381 * @return true if port is powered 382 */ 383 static inline bool usb_port_powered(usb_port_status_t * status) { 384 return usb_port_get_bit(status, 8); 385 } 386 387 static inline void usb_port_set_powered(usb_port_status_t * status, bool powered) { 388 usb_port_set_bit(status, 8, powered); 290 static inline bool usb_port_powered(usb_port_status_t * status){ 291 return usb_port_get_bit(status,8); 292 } 293 294 static inline void usb_port_set_powered(usb_port_status_t * status,bool powered){ 295 usb_port_set_bit(status,8,powered); 389 296 } 390 297 391 298 //low speed device attached 392 /** 393 * low speed device on the port indicator 394 * 395 * @param status 396 * @return true if low speed device is attached 397 */ 398 static inline bool usb_port_low_speed(usb_port_status_t * status) { 399 return usb_port_get_bit(status, 9); 400 } 401 402 static inline void usb_port_set_low_speed(usb_port_status_t * status, bool low_speed) { 403 usb_port_set_bit(status, 9, low_speed); 404 } 405 406 //high speed device attached 407 /** 408 * high speed device on the port indicator 409 * 410 * @param status 411 * @return true if high speed device is on port 412 */ 413 static inline bool usb_port_high_speed(usb_port_status_t * status) { 414 return usb_port_get_bit(status, 10); 415 } 416 417 static inline void usb_port_set_high_speed(usb_port_status_t * status, bool high_speed) { 418 usb_port_set_bit(status, 10, high_speed); 419 } 420 421 /** 422 * speed getter for port status 423 * 424 * @param status 425 * @return speed of usb device (for more see usb specification) 426 */ 427 static inline usb_speed_t usb_port_speed(usb_port_status_t * status) { 428 if (usb_port_low_speed(status)) 299 static inline bool usb_port_low_speed(usb_port_status_t * status){ 300 return usb_port_get_bit(status,9); 301 } 302 303 static inline void usb_port_set_low_speed(usb_port_status_t * status,bool low_speed){ 304 usb_port_set_bit(status,9,low_speed); 305 } 306 307 //low speed device attached 308 static inline bool usb_port_high_speed(usb_port_status_t * status){ 309 return usb_port_get_bit(status,10); 310 } 311 312 static inline void usb_port_set_high_speed(usb_port_status_t * status,bool high_speed){ 313 usb_port_set_bit(status,10,high_speed); 314 } 315 316 static inline usb_speed_t usb_port_speed(usb_port_status_t * status){ 317 if(usb_port_low_speed(status)) 429 318 return USB_SPEED_LOW; 430 if 319 if(usb_port_high_speed(status)) 431 320 return USB_SPEED_HIGH; 432 321 return USB_SPEED_FULL; … … 435 324 436 325 //connect change 437 /** 438 * port connect change indicator 439 * 440 * @param status 441 * @return true if connection has changed 442 */ 443 static inline bool usb_port_connect_change(usb_port_status_t * status) { 444 return usb_port_get_bit(status, 16); 445 } 446 447 static inline void usb_port_set_connect_change(usb_port_status_t * status, bool change) { 448 usb_port_set_bit(status, 16, change); 326 static inline bool usb_port_connect_change(usb_port_status_t * status){ 327 return usb_port_get_bit(status,16); 328 } 329 330 static inline void usb_port_set_connect_change(usb_port_status_t * status,bool change){ 331 usb_port_set_bit(status,16,change); 449 332 } 450 333 451 334 //port enable change 452 /** 453 * port enable change for port status 454 * 455 * @param status 456 * @return true if the port has been enabled/disabled 457 */ 458 static inline bool usb_port_enabled_change(usb_port_status_t * status) { 459 return usb_port_get_bit(status, 17); 460 } 461 462 static inline void usb_port_set_enabled_change(usb_port_status_t * status, bool change) { 463 usb_port_set_bit(status, 17, change); 335 static inline bool usb_port_enabled_change(usb_port_status_t * status){ 336 return usb_port_get_bit(status,17); 337 } 338 339 static inline void usb_port_set_enabled_change(usb_port_status_t * status,bool change){ 340 usb_port_set_bit(status,17,change); 464 341 } 465 342 466 343 //suspend change 467 /** 468 * port suspend change for port status 469 * 470 * @param status 471 * @return ture if suspend status has changed 472 */ 473 static inline bool usb_port_suspend_change(usb_port_status_t * status) { 474 return usb_port_get_bit(status, 18); 475 } 476 477 static inline void usb_port_set_suspend_change(usb_port_status_t * status, bool change) { 478 usb_port_set_bit(status, 18, change); 344 static inline bool usb_port_suspend_change(usb_port_status_t * status){ 345 return usb_port_get_bit(status,18); 346 } 347 348 static inline void usb_port_set_suspend_change(usb_port_status_t * status,bool change){ 349 usb_port_set_bit(status,18,change); 479 350 } 480 351 481 352 //over current change 482 /** 483 * over current change indicator 484 * 485 * @param status 486 * @return true if over-current condition on port has changed 487 */ 488 static inline bool usb_port_overcurrent_change(usb_port_status_t * status) { 489 return usb_port_get_bit(status, 19); 490 } 491 492 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status, bool change) { 493 usb_port_set_bit(status, 19, change); 353 static inline bool usb_port_overcurrent_change(usb_port_status_t * status){ 354 return usb_port_get_bit(status,19); 355 } 356 357 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status,bool change){ 358 usb_port_set_bit(status,19,change); 494 359 } 495 360 496 361 //reset change 497 /** 498 * port reset change indicator 499 * @param status 500 * @return true if port has been reset 501 */ 502 static inline bool usb_port_reset_completed(usb_port_status_t * status) { 503 return usb_port_get_bit(status, 20); 504 } 505 506 static inline void usb_port_set_reset_completed(usb_port_status_t * status, bool completed) { 507 usb_port_set_bit(status, 20, completed); 508 } 509 510 //local power status 511 /** 512 * local power lost indicator for hub status 513 * 514 * @param status 515 * @return true if hub is not powered 516 */ 517 static inline bool usb_hub_local_power_lost(usb_hub_status_t * status) { 518 return usb_hub_get_bit(status, 0); 519 } 520 521 static inline void usb_hub_set_local_power_lost(usb_port_status_t * status, 522 bool power_lost) { 523 usb_hub_set_bit(status, 0, power_lost); 524 } 525 526 //over current ocndition 527 /** 528 * hub over-current indicator 529 * 530 * @param status 531 * @return true if over-current condition occurred on hub 532 */ 533 static inline bool usb_hub_over_current(usb_hub_status_t * status) { 534 return usb_hub_get_bit(status, 1); 535 } 536 537 static inline void usb_hub_set_over_current(usb_port_status_t * status, 538 bool over_current) { 539 usb_hub_set_bit(status, 1, over_current); 540 } 541 542 //local power change 543 /** 544 * hub power change indicator 545 * 546 * @param status 547 * @return true if local power status has been changed - power has been 548 * dropped or re-established 549 */ 550 static inline bool usb_hub_local_power_change(usb_hub_status_t * status) { 551 return usb_hub_get_bit(status, 16); 552 } 553 554 static inline void usb_hub_set_local_power_change(usb_port_status_t * status, 555 bool change) { 556 usb_hub_set_bit(status, 16, change); 557 } 558 559 //local power status 560 /** 561 * hub over-current condition change indicator 562 * 563 * @param status 564 * @return true if over-current condition has changed 565 */ 566 static inline bool usb_hub_over_current_change(usb_hub_status_t * status) { 567 return usb_hub_get_bit(status, 17); 568 } 569 570 static inline void usb_hub_set_over_current_change(usb_port_status_t * status, 571 bool change) { 572 usb_hub_set_bit(status, 17, change); 573 } 362 static inline bool usb_port_reset_completed(usb_port_status_t * status){ 363 return usb_port_get_bit(status,20); 364 } 365 366 static inline void usb_port_set_reset_completed(usb_port_status_t * status,bool completed){ 367 usb_port_set_bit(status,20,completed); 368 } 369 574 370 575 371 -
uspace/drv/usbhub/usbhub.c
ra4e18e1 ra82889e 53 53 #include "usb/classes/classes.h" 54 54 55 56 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,57 usb_speed_t speed);58 59 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);60 61 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);62 63 static int usb_hub_set_configuration(usb_hub_info_t * hub_info);64 65 static int usb_hub_release_default_address(usb_hub_info_t * hub);66 67 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,68 usb_speed_t speed);69 70 static void usb_hub_finalize_add_device(usb_hub_info_t * hub,71 uint16_t port, usb_speed_t speed);72 73 static void usb_hub_removed_device(74 usb_hub_info_t * hub, uint16_t port);75 76 static void usb_hub_port_over_current(usb_hub_info_t * hub,77 uint16_t port, uint32_t status);78 79 static void usb_hub_process_interrupt(usb_hub_info_t * hub,80 uint16_t port);81 82 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,83 usb_hub_status_t status);84 85 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,86 usb_hub_status_t status);87 88 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);89 90 //static int initialize_non_removable(usb_hub_info_t * hub_info,91 // unsigned int port);92 93 55 static int usb_hub_trigger_connecting_non_removable_devices( 94 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 95 96 97 /** 98 * control loop running in hub`s fibril 99 * 100 * Hub`s fibril periodically asks for changes on hub and if needded calls 101 * change handling routine. 102 * @warning currently hub driver asks for changes once a second 103 * @param hub_info_param hub representation pointer 104 * @return zero 105 */ 106 int usb_hub_control_loop(void * hub_info_param) { 107 usb_hub_info_t * hub_info = (usb_hub_info_t*) hub_info_param; 108 int errorCode = EOK; 109 110 while (errorCode == EOK) { 111 async_usleep(1000 * 1000 * 10); /// \TODO proper number once 112 errorCode = usb_hub_check_hub_changes(hub_info); 113 } 114 usb_log_error("something in ctrl loop went wrong, errno %d\n", 115 errorCode); 116 117 return 0; 118 } 119 /// \TODO malloc checking 56 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 57 120 58 121 59 //********************************************* … … 125 63 //********************************************* 126 64 127 128 129 /**130 * Initialize hub device driver fibril131 *132 * Creates hub representation and fibril that periodically checks hub`s status.133 * Hub representation is passed to the fibril.134 * @param usb_dev generic usb device information135 * @return error code136 */137 int usb_hub_add_device(usb_device_t * usb_dev) {138 if (!usb_dev) return EINVAL;139 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);140 //create hc connection141 usb_log_debug("Initializing USB wire abstraction.\n");142 int opResult = usb_hc_connection_initialize_from_device(143 &hub_info->connection,144 hub_info->usb_device->ddf_dev);145 if (opResult != EOK) {146 usb_log_error("could not initialize connection to device, "147 "errno %d\n",148 opResult);149 free(hub_info);150 return opResult;151 }152 153 usb_pipe_start_session(hub_info->control_pipe);154 //set hub configuration155 opResult = usb_hub_set_configuration(hub_info);156 if (opResult != EOK) {157 usb_log_error("could not set hub configuration, errno %d\n",158 opResult);159 free(hub_info);160 return opResult;161 }162 //get port count and create attached_devs163 opResult = usb_hub_process_hub_specific_info(hub_info);164 if (opResult != EOK) {165 usb_log_error("could not set hub configuration, errno %d\n",166 opResult);167 free(hub_info);168 return opResult;169 }170 usb_pipe_end_session(hub_info->control_pipe);171 172 173 /// \TODO what is this?174 usb_log_debug("Creating `hub' function.\n");175 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,176 fun_exposed, "hub");177 assert(hub_fun != NULL);178 hub_fun->ops = NULL;179 180 int rc = ddf_fun_bind(hub_fun);181 assert(rc == EOK);182 rc = ddf_fun_add_to_class(hub_fun, "hub");183 assert(rc == EOK);184 185 //create fibril for the hub control loop186 fid_t fid = fibril_create(usb_hub_control_loop, hub_info);187 if (fid == 0) {188 usb_log_error("failed to start monitoring fibril for new"189 " hub.\n");190 return ENOMEM;191 }192 fibril_add_ready(fid);193 usb_log_debug("Hub fibril created.\n");194 195 usb_log_info("Controlling hub `%s' (%d ports).\n",196 hub_info->usb_device->ddf_dev->name, hub_info->port_count);197 return EOK;198 }199 200 201 //*********************************************202 //203 // hub driver code, main loop and port handling204 //205 //*********************************************206 207 /**208 * check changes on hub209 *210 * Handles changes on each port with a status change.211 * @param hub_info hub representation212 * @return error code213 */214 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {215 int opResult;216 opResult = usb_pipe_start_session(217 hub_info->status_change_pipe);218 //this might not be necessary - if all non-removables are ok, it is219 //not needed here220 opResult = usb_pipe_start_session(hub_info->control_pipe);221 if (opResult != EOK) {222 usb_log_error("could not initialize communication for hub; %d\n",223 opResult);224 return opResult;225 }226 227 size_t port_count = hub_info->port_count;228 //first check non-removable devices229 /*230 {231 unsigned int port;232 for (port = 0; port < port_count; ++port) {233 bool is_non_removable =234 hub_info->not_initialized_non_removables[port/8]235 & (1 << (port-1 % 8));236 if (is_non_removable) {237 opResult = initialize_non_removable(hub_info,238 port+1);239 }240 }241 }242 */243 244 /// FIXME: count properly245 size_t byte_length = ((port_count + 1) / 8) + 1;246 void *change_bitmap = malloc(byte_length);247 size_t actual_size;248 249 /*250 * Send the request.251 */252 opResult = usb_pipe_read(253 hub_info->status_change_pipe,254 change_bitmap, byte_length, &actual_size255 );256 257 if (opResult != EOK) {258 free(change_bitmap);259 usb_log_warning("something went wrong while getting the"260 "status of hub\n");261 usb_pipe_end_session(hub_info->status_change_pipe);262 return opResult;263 }264 unsigned int port;265 266 if (opResult != EOK) {267 usb_log_error("could not start control pipe session %d\n",268 opResult);269 usb_pipe_end_session(hub_info->status_change_pipe);270 return opResult;271 }272 opResult = usb_hc_connection_open(&hub_info->connection);273 if (opResult != EOK) {274 usb_log_error("could not start host controller session %d\n",275 opResult);276 usb_pipe_end_session(hub_info->control_pipe);277 usb_pipe_end_session(hub_info->status_change_pipe);278 return opResult;279 }280 281 ///todo, opresult check, pre obe konekce282 bool interrupt;283 interrupt = ((uint8_t*)change_bitmap)[0] & 1;284 if(interrupt){285 usb_hub_process_global_interrupt(hub_info);286 }287 for (port = 1; port < port_count + 1; ++port) {288 interrupt =289 ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));290 if (interrupt) {291 usb_hub_process_interrupt(292 hub_info, port);293 }294 }295 /// \todo check hub status296 usb_hc_connection_close(&hub_info->connection);297 usb_pipe_end_session(hub_info->control_pipe);298 usb_pipe_end_session(hub_info->status_change_pipe);299 free(change_bitmap);300 return EOK;301 }302 303 //*********************************************304 //305 // support functions306 //307 //*********************************************308 309 65 /** 310 66 * create usb_hub_info_t structure … … 316 72 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) { 317 73 usb_hub_info_t * result = usb_new(usb_hub_info_t); 318 if 74 if(!result) return NULL; 319 75 result->usb_device = usb_dev; 320 76 result->status_change_pipe = usb_dev->pipes[0].pipe; … … 323 79 return result; 324 80 } 325 326 81 327 82 /** … … 335 90 * @return error code 336 91 */ 337 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) 92 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){ 338 93 // get hub descriptor 339 94 usb_log_debug("creating serialized descriptor\n"); 340 95 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 341 96 usb_hub_descriptor_t * descriptor; 342 int opResult;343 97 344 98 /* this was one fix of some bug, should not be needed anymore 345 99 * these lines allow to reset hub once more, it can be used as 346 100 * brute-force initialization for non-removable devices 347 * 348 opResult = usb_request_set_configuration(hub_info->control_pipe, 349 1); 101 int opResult = usb_request_set_configuration(&result->endpoints.control, 1); 102 if(opResult!=EOK){ 103 usb_log_error("could not set default configuration, errno %d",opResult); 104 return opResult; 105 } 106 */ 107 size_t received_size; 108 int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe, 109 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 110 USB_DESCTYPE_HUB, 111 0, 0, serialized_descriptor, 112 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 113 350 114 if (opResult != EOK) { 351 usb_log_error("could not set default configuration, errno %d", 352 opResult); 353 return opResult; 354 }*/ 355 356 357 size_t received_size; 358 opResult = usb_request_get_descriptor(hub_info->control_pipe, 359 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 360 USB_DESCTYPE_HUB, 361 0, 0, serialized_descriptor, 362 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 363 364 if (opResult != EOK) { 365 usb_log_error("failed when receiving hub descriptor, " 366 "badcode = %d\n", 367 opResult); 115 usb_log_error("failed when receiving hub descriptor, badcode = %d\n", 116 opResult); 368 117 free(serialized_descriptor); 369 118 return opResult; … … 371 120 usb_log_debug2("deserializing descriptor\n"); 372 121 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 373 if (descriptor == NULL){122 if(descriptor==NULL){ 374 123 usb_log_warning("could not deserialize descriptor \n"); 375 124 return opResult; 376 125 } 377 usb_log_debug("setting port count to %d\n", 126 usb_log_debug("setting port count to %d\n",descriptor->ports_count); 378 127 hub_info->port_count = descriptor->ports_count; 379 /// \TODO check attached_devices array: this is not semantically correct 380 hub_info->attached_devs = (usb_hc_attached_device_t*) 381 malloc((hub_info->port_count + 1) * 382 sizeof (usb_hc_attached_device_t) 383 ); 384 int i; 385 for (i = 1; i <= hub_info->port_count; ++i) { 386 hub_info->attached_devs[i].handle = 0; 387 hub_info->attached_devs[i].address = 0; 388 usb_log_info("powering port %d\n",i); 389 opResult = usb_hub_set_port_feature( 390 hub_info->control_pipe, 391 i, 392 USB_HUB_FEATURE_PORT_POWER); 393 if(opResult!=EOK) 394 usb_log_warning("could not power port %d\n",i); 395 128 hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1)); 129 size_t port; 130 for (port = 0; port < hub_info->port_count + 1; port++) { 131 usb_hub_port_init(&hub_info->ports[port]); 396 132 } 397 133 //handle non-removable devices … … 399 135 usb_log_debug2("freeing data\n"); 400 136 free(serialized_descriptor); 401 hub_info->descriptor = descriptor; 402 hub_info->not_initialized_non_removables = 403 (uint8_t*) malloc((hub_info->port_count + 8) / 8); 404 memcpy(hub_info->not_initialized_non_removables, 405 descriptor->devices_removable, 406 (hub_info->port_count + 8) / 8 407 ); 408 409 //free(descriptor->devices_removable); 410 //free(descriptor); 137 free(descriptor->devices_removable); 138 free(descriptor); 411 139 return EOK; 412 140 } 413 414 141 /** 415 142 * Set configuration of hub … … 420 147 * @return error code 421 148 */ 422 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) 149 static int usb_hub_set_configuration(usb_hub_info_t * hub_info){ 423 150 //device descriptor 424 151 usb_standard_device_descriptor_t *std_descriptor 425 152 = &hub_info->usb_device->descriptors.device; 426 153 usb_log_debug("hub has %d configurations\n", 427 428 if (std_descriptor->configuration_count < 1){154 std_descriptor->configuration_count); 155 if(std_descriptor->configuration_count<1){ 429 156 usb_log_error("there are no configurations available\n"); 430 157 return EINVAL; … … 432 159 433 160 usb_standard_configuration_descriptor_t *config_descriptor 434 435 161 = (usb_standard_configuration_descriptor_t *) 162 hub_info->usb_device->descriptors.configuration; 436 163 437 164 /* Set configuration. */ 438 165 int opResult = usb_request_set_configuration( 439 440 166 &hub_info->usb_device->ctrl_pipe, 167 config_descriptor->configuration_number); 441 168 442 169 if (opResult != EOK) { 443 170 usb_log_error("Failed to set hub configuration: %s.\n", 444 171 str_error(opResult)); 445 172 return opResult; 446 173 } 447 174 usb_log_debug("\tused configuration %d\n", 448 config_descriptor->configuration_number);175 config_descriptor->configuration_number); 449 176 450 177 return EOK; … … 452 179 453 180 /** 454 * release default address used by given hub455 * 456 * Also unsets hub->is_default_address_used. Convenience wrapper function.457 * @note hub->connection MUST be open for communication458 * @param hub hub representation181 * Initialize hub device driver fibril 182 * 183 * Creates hub representation and fibril that periodically checks hub`s status. 184 * Hub representation is passed to the fibril. 185 * @param usb_dev generic usb device information 459 186 * @return error code 460 187 */ 461 static int usb_hub_release_default_address(usb_hub_info_t * hub) { 462 int opResult = usb_hc_release_default_address(&hub->connection); 463 if (opResult != EOK) { 464 usb_log_error("could not release default address, errno %d\n", 465 opResult); 466 return opResult; 467 } 468 hub->is_default_address_used = false; 188 int usb_hub_add_device(usb_device_t * usb_dev){ 189 if(!usb_dev) return EINVAL; 190 usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev); 191 //create hc connection 192 usb_log_debug("Initializing USB wire abstraction.\n"); 193 int opResult = usb_hc_connection_initialize_from_device( 194 &hub_info->connection, 195 hub_info->usb_device->ddf_dev); 196 if(opResult != EOK){ 197 usb_log_error("could not initialize connection to device, errno %d\n", 198 opResult); 199 free(hub_info); 200 return opResult; 201 } 202 203 usb_pipe_start_session(hub_info->control_pipe); 204 //set hub configuration 205 opResult = usb_hub_set_configuration(hub_info); 206 if(opResult!=EOK){ 207 usb_log_error("could not set hub configuration, errno %d\n",opResult); 208 free(hub_info); 209 return opResult; 210 } 211 //get port count and create attached_devs 212 opResult = usb_hub_process_hub_specific_info(hub_info); 213 if(opResult!=EOK){ 214 usb_log_error("could not set hub configuration, errno %d\n",opResult); 215 free(hub_info); 216 return opResult; 217 } 218 usb_pipe_end_session(hub_info->control_pipe); 219 220 221 /// \TODO what is this? 222 usb_log_debug("Creating `hub' function.\n"); 223 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev, 224 fun_exposed, "hub"); 225 assert(hub_fun != NULL); 226 hub_fun->ops = NULL; 227 228 int rc = ddf_fun_bind(hub_fun); 229 assert(rc == EOK); 230 rc = ddf_fun_add_to_class(hub_fun, "hub"); 231 assert(rc == EOK); 232 233 /* 234 * The processing will require opened control pipe and connection 235 * to the host controller. 236 * It is waste of resources but let's hope there will be less 237 * hubs than the phone limit. 238 * FIXME: with some proper locking over pipes and session 239 * auto destruction, this could work better. 240 */ 241 rc = usb_pipe_start_session(&usb_dev->ctrl_pipe); 242 if (rc != EOK) { 243 usb_log_error("Failed to start session on control pipe: %s.\n", 244 str_error(rc)); 245 goto leave; 246 } 247 rc = usb_hc_connection_open(&hub_info->connection); 248 if (rc != EOK) { 249 usb_pipe_end_session(&usb_dev->ctrl_pipe); 250 usb_log_error("Failed to open connection to HC: %s.\n", 251 str_error(rc)); 252 goto leave; 253 } 254 255 rc = usb_device_auto_poll(hub_info->usb_device, 0, 256 hub_port_changes_callback, ((hub_info->port_count+1) / 8) + 1, 257 NULL, hub_info); 258 if (rc != EOK) { 259 usb_log_error("Failed to create polling fibril: %s.\n", 260 str_error(rc)); 261 free(hub_info); 262 return rc; 263 } 264 265 usb_log_info("Controlling hub `%s' (%d ports).\n", 266 hub_info->usb_device->ddf_dev->name, hub_info->port_count); 469 267 return EOK; 470 } 471 472 /** 473 * Reset the port with new device and reserve the default address. 474 * @param hub hub representation 475 * @param port port number, starting from 1 476 * @param speed transfer speed of attached device, one of low, full or high 477 * @return error code 478 */ 479 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port, 480 usb_speed_t speed) { 481 //if this hub already uses default address, it cannot request it once more 482 if (hub->is_default_address_used) { 483 usb_log_info("default address used, another time\n"); 484 return EREFUSED; 485 } 486 usb_log_debug("some connection changed\n"); 487 assert(hub->control_pipe->hc_phone); 488 int opResult = usb_hub_clear_port_feature(hub->control_pipe, 489 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 490 if (opResult != EOK) { 491 usb_log_warning("could not clear port-change-connection flag\n"); 492 } 493 usb_device_request_setup_packet_t request; 494 495 //get default address 496 opResult = usb_hc_reserve_default_address(&hub->connection, speed); 497 498 if (opResult != EOK) { 499 usb_log_warning("cannot assign default address, it is probably " 500 "used %d\n", 501 opResult); 502 return opResult; 503 } 504 hub->is_default_address_used = true; 505 //reset port 506 usb_hub_set_reset_port_request(&request, port); 507 opResult = usb_pipe_control_write( 508 hub->control_pipe, 509 &request, sizeof (usb_device_request_setup_packet_t), 510 NULL, 0 511 ); 512 if (opResult != EOK) { 513 usb_log_error("something went wrong when reseting a port %d\n", 514 opResult); 515 usb_hub_release_default_address(hub); 516 } 517 return opResult; 518 } 519 520 /** 521 * Finalize adding new device after port reset 522 * 523 * Set device`s address and start it`s driver. 524 * @param hub hub representation 525 * @param port port number, starting from 1 526 * @param speed transfer speed of attached device, one of low, full or high 527 */ 528 static void usb_hub_finalize_add_device(usb_hub_info_t * hub, 529 uint16_t port, usb_speed_t speed) { 530 531 int opResult; 532 usb_log_debug("finalizing add device\n"); 533 opResult = usb_hub_clear_port_feature(hub->control_pipe, 534 port, USB_HUB_FEATURE_C_PORT_RESET); 535 536 if (opResult != EOK) { 537 usb_log_error("failed to clear port reset feature\n"); 538 usb_hub_release_default_address(hub); 539 return; 540 } 541 //create connection to device 542 usb_pipe_t new_device_pipe; 543 usb_device_connection_t new_device_connection; 544 usb_device_connection_initialize_on_default_address( 545 &new_device_connection, 546 &hub->connection 547 ); 548 usb_pipe_initialize_default_control( 549 &new_device_pipe, 550 &new_device_connection); 551 usb_pipe_probe_default_control(&new_device_pipe); 552 553 /* Request address from host controller. */ 554 usb_address_t new_device_address = usb_hc_request_address( 555 &hub->connection, 556 speed 557 ); 558 if (new_device_address < 0) { 559 usb_log_error("failed to get free USB address\n"); 560 opResult = new_device_address; 561 usb_hub_release_default_address(hub); 562 return; 563 } 564 usb_log_debug("setting new address %d\n", new_device_address); 565 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 566 // new_device_address); 567 usb_pipe_start_session(&new_device_pipe); 568 opResult = usb_request_set_address(&new_device_pipe, 569 new_device_address); 570 usb_pipe_end_session(&new_device_pipe); 571 if (opResult != EOK) { 572 usb_log_error("could not set address for new device %d\n", 573 opResult); 574 usb_hub_release_default_address(hub); 575 return; 576 } 577 578 //opResult = usb_hub_release_default_address(hc); 579 opResult = usb_hub_release_default_address(hub); 580 if (opResult != EOK) { 581 return; 582 } 583 584 devman_handle_t child_handle; 585 //?? 586 opResult = usb_device_register_child_in_devman(new_device_address, 587 hub->connection.hc_handle, hub->usb_device->ddf_dev, 588 &child_handle, 589 NULL, NULL, NULL); 590 591 if (opResult != EOK) { 592 usb_log_error("could not start driver for new device %d\n", 593 opResult); 594 return; 595 } 596 hub->attached_devs[port].handle = child_handle; 597 hub->attached_devs[port].address = new_device_address; 598 599 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle); 600 opResult = usb_hc_register_device( 601 &hub->connection, 602 &hub->attached_devs[port]); 603 if (opResult != EOK) { 604 usb_log_error("could not assign address of device in hcd %d\n", 605 opResult); 606 return; 607 } 608 usb_log_info("Detected new device on `%s' (port %d), " \ 609 "address %d (handle %llu).\n", 610 hub->usb_device->ddf_dev->name, (int) port, 611 new_device_address, child_handle); 612 } 613 614 /** 615 * routine called when a device on port has been removed 616 * 617 * If the device on port had default address, it releases default address. 618 * Otherwise does not do anything, because DDF does not allow to remove device 619 * from it`s device tree. 620 * @param hub hub representation 621 * @param port port number, starting from 1 622 */ 623 static void usb_hub_removed_device( 624 usb_hub_info_t * hub, uint16_t port) { 625 626 int opResult = usb_hub_clear_port_feature(hub->control_pipe, 627 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 628 if (opResult != EOK) { 629 usb_log_warning("could not clear port-change-connection flag\n"); 630 } 631 /** \TODO remove device from device manager - not yet implemented in 632 * devide manager 633 */ 634 635 //close address 636 if (hub->attached_devs[port].address != 0) { 637 /*uncomment this code to use it when DDF allows device removal 638 opResult = usb_hc_unregister_device( 639 &hub->connection, 640 hub->attached_devs[port].address); 641 if(opResult != EOK) { 642 dprintf(USB_LOG_LEVEL_WARNING, "could not release " 643 "address of " 644 "removed device: %d", opResult); 645 } 646 hub->attached_devs[port].address = 0; 647 hub->attached_devs[port].handle = 0; 648 */ 649 } else { 650 usb_log_warning("this is strange, disconnected device had " 651 "no address\n"); 652 //device was disconnected before it`s port was reset - 653 //return default address 654 usb_hub_release_default_address(hub); 655 } 656 } 657 658 /** 659 * Process over current condition on port. 660 * 661 * Turn off the power on the port. 662 * 663 * @param hub hub representation 664 * @param port port number, starting from 1 665 */ 666 static void usb_hub_port_over_current(usb_hub_info_t * hub, 667 uint16_t port, uint32_t status) { 668 int opResult; 669 if(usb_port_over_current(&status)){ 670 opResult = usb_hub_clear_port_feature(hub->control_pipe, 671 port, USB_HUB_FEATURE_PORT_POWER); 672 if (opResult != EOK) { 673 usb_log_error("cannot power off port %d; %d\n", 674 port, opResult); 675 } 676 }else{ 677 opResult = usb_hub_set_port_feature(hub->control_pipe, 678 port, USB_HUB_FEATURE_PORT_POWER); 679 if (opResult != EOK) { 680 usb_log_error("cannot power on port %d; %d\n", 681 port, opResult); 682 } 683 } 684 } 685 686 /** 687 * Process interrupts on given hub port 688 * 689 * Accepts connection, over current and port reset change. 690 * @param hub hub representation 691 * @param port port number, starting from 1 692 */ 693 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 694 uint16_t port) { 695 usb_log_debug("interrupt at port %d\n", port); 696 //determine type of change 697 usb_pipe_t *pipe = hub->control_pipe; 698 699 int opResult; 700 701 usb_port_status_t status; 702 size_t rcvd_size; 703 usb_device_request_setup_packet_t request; 704 //int opResult; 705 usb_hub_set_port_status_request(&request, port); 706 //endpoint 0 707 708 opResult = usb_pipe_control_read( 709 pipe, 710 &request, sizeof (usb_device_request_setup_packet_t), 711 &status, 4, &rcvd_size 712 ); 713 if (opResult != EOK) { 714 usb_log_error("could not get port status\n"); 715 return; 716 } 717 if (rcvd_size != sizeof (usb_port_status_t)) { 718 usb_log_error("received status has incorrect size\n"); 719 return; 720 } 721 //something connected/disconnected 722 if (usb_port_connect_change(&status)) { 723 usb_log_debug("connection change on port\n"); 724 if (usb_port_dev_connected(&status)) { 725 usb_hub_init_add_device(hub, port, 726 usb_port_speed(&status)); 727 } else { 728 usb_hub_removed_device(hub, port); 729 } 730 } 731 //over current 732 if (usb_port_overcurrent_change(&status)) { 733 //check if it was not auto-resolved 734 usb_log_debug("overcurrent change on port\n"); 735 usb_hub_port_over_current(hub, port, status); 736 } 737 //port reset 738 if (usb_port_reset_completed(&status)) { 739 usb_log_debug("port reset complete\n"); 740 if (usb_port_enabled(&status)) { 741 usb_hub_finalize_add_device(hub, port, 742 usb_port_speed(&status)); 743 } else { 744 usb_log_warning("port reset, but port still not " 745 "enabled\n"); 746 } 747 } 748 usb_log_debug("status x%x : %d\n ", status, status); 749 750 usb_port_set_connect_change(&status, false); 751 usb_port_set_reset(&status, false); 752 usb_port_set_reset_completed(&status, false); 753 usb_port_set_dev_connected(&status, false); 754 usb_port_set_overcurrent_change(&status,false); 755 /// \TODO what about port power change? 756 if (status >> 16) { 757 usb_log_info("there was unsupported change on port %d: %X\n", 758 port, status); 759 760 } 761 } 762 763 /** 764 * process hub over current change 765 * 766 * This means either to power off the hub or power it on. 767 * @param hub_info hub instance 768 * @param status hub status bitmask 769 * @return error code 770 */ 771 static int usb_process_hub_over_current(usb_hub_info_t * hub_info, 772 usb_hub_status_t status) 773 { 774 int opResult; 775 if(usb_hub_over_current(&status)){ 776 opResult = usb_hub_clear_feature(hub_info->control_pipe, 777 USB_HUB_FEATURE_PORT_POWER); 778 if (opResult != EOK) { 779 usb_log_error("cannot power off hub: %d\n", 780 opResult); 781 } 782 }else{ 783 opResult = usb_hub_set_feature(hub_info->control_pipe, 784 USB_HUB_FEATURE_PORT_POWER); 785 if (opResult != EOK) { 786 usb_log_error("cannot power on hub: %d\n", 787 opResult); 788 } 789 } 790 return opResult; 791 } 792 793 /** 794 * process hub power change 795 * 796 * If the power has been lost, reestablish it. 797 * If it was reestablished, re-power all ports. 798 * @param hub_info hub instance 799 * @param status hub status bitmask 800 * @return error code 801 */ 802 static int usb_process_hub_power_change(usb_hub_info_t * hub_info, 803 usb_hub_status_t status) 804 { 805 int opResult; 806 if(usb_hub_local_power_lost(&status)){ 807 //restart power on hub 808 opResult = usb_hub_set_feature(hub_info->control_pipe, 809 USB_HUB_FEATURE_PORT_POWER); 810 if (opResult != EOK) { 811 usb_log_error("cannot power on hub: %d\n", 812 opResult); 813 } 814 }else{//power reestablished on hub- restart ports 815 int port; 816 for(port=0;port<hub_info->port_count;++port){ 817 opResult = usb_hub_set_port_feature( 818 hub_info->control_pipe, 819 port, USB_HUB_FEATURE_PORT_POWER); 820 if (opResult != EOK) { 821 usb_log_error("cannot power on port %d; %d\n", 822 port, opResult); 823 } 824 } 825 } 826 return opResult; 827 } 828 829 /** 830 * process hub interrupts 831 * 832 * The change can be either in the over-current condition or 833 * local-power lost condition. 834 * @param hub_info hub instance 835 */ 836 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info){ 837 usb_log_debug("global interrupt on a hub\n"); 838 usb_pipe_t *pipe = hub_info->control_pipe; 839 int opResult; 840 841 usb_port_status_t status; 842 size_t rcvd_size; 843 usb_device_request_setup_packet_t request; 844 //int opResult; 845 usb_hub_set_hub_status_request(&request); 846 //endpoint 0 847 848 opResult = usb_pipe_control_read( 849 pipe, 850 &request, sizeof (usb_device_request_setup_packet_t), 851 &status, 4, &rcvd_size 852 ); 853 if (opResult != EOK) { 854 usb_log_error("could not get hub status\n"); 855 return; 856 } 857 if (rcvd_size != sizeof (usb_port_status_t)) { 858 usb_log_error("received status has incorrect size\n"); 859 return; 860 } 861 //port reset 862 if (usb_hub_over_current_change(&status)) { 863 usb_process_hub_over_current(hub_info,status); 864 } 865 if (usb_hub_local_power_change(&status)) { 866 usb_process_hub_power_change(hub_info,status); 867 } 868 } 869 870 //-----------attempts to solve non-removable------------------------ 871 //-----------attempts to solve non-removable------------------------ 872 //-----------attempts to solve non-removable------------------------ 873 //-----------attempts to solve non-removable------------------------ 874 875 /** 876 * this is an attempt to initialize non-removable devices in the hub 877 * 878 * @param hub_info hub instance 879 * @param port port number, counting from 1 880 * @return error code 881 */ 882 #if 0 883 static int initialize_non_removable(usb_hub_info_t * hub_info, 884 unsigned int port) { 885 int opResult; 886 usb_log_debug("there is not pluged in non-removable device on " 887 "port %d\n", port 888 ); 889 //usb_hub_init_add_device(hub_info, port, usb_port_speed(&status)); 890 usb_port_status_t status; 891 size_t rcvd_size; 892 usb_device_request_setup_packet_t request; 893 //int opResult; 894 usb_hub_set_port_status_request(&request, port); 895 //endpoint 0 896 897 opResult = usb_pipe_control_read( 898 hub_info->control_pipe, 899 &request, sizeof (usb_device_request_setup_packet_t), 900 &status, 4, &rcvd_size 901 ); 902 if (opResult != EOK) { 903 usb_log_error("could not get port status %d\n", opResult); 904 return opResult; 905 } 906 if (rcvd_size != sizeof (usb_port_status_t)) { 907 usb_log_error("received status has incorrect size\n"); 908 return opResult; 909 } 910 usb_log_debug("port status %d, x%x\n", status, status); 911 if (usb_port_dev_connected(&status)) { 912 usb_log_debug("there is connected device on this port\n"); 913 opResult = usb_hub_init_add_device(hub_info, port, 914 usb_port_speed(&status)); 915 }else{ 916 usb_log_debug("the non-removable device is not connected\n"); 917 opResult = EINVAL; 918 } 919 920 return opResult; 921 } 922 #endif 268 269 leave: 270 free(hub_info); 271 272 return rc; 273 } 274 275 276 //********************************************* 277 // 278 // hub driver code, main loop and port handling 279 // 280 //********************************************* 281 923 282 /** 924 283 * triggers actions to connect non0removable devices … … 930 289 * @return error code 931 290 */ 932 static int usb_hub_trigger_connecting_non_removable_devices( 933 usb_hub_info_t * hub,934 usb_hub_descriptor_t * descriptor){291 static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub, 292 usb_hub_descriptor_t * descriptor) 293 { 935 294 usb_log_info("attaching non-removable devices(if any)\n"); 936 //usb_device_request_setup_packet_t request;295 usb_device_request_setup_packet_t request; 937 296 int opResult; 938 //size_t rcvd_size;939 //usb_port_status_t status;297 size_t rcvd_size; 298 usb_port_status_t status; 940 299 uint8_t * non_removable_dev_bitmap = descriptor->devices_removable; 941 300 int port; 942 #if 0 943 opResult = usb_request_set_configuration(hub->control_pipe, 944 1); 945 if (opResult != EOK) { 946 usb_log_error("could not set default configuration, errno %d", 947 opResult); 948 return opResult; 949 } 950 951 for (port = 1; port <= descriptor->ports_count; ++port) { 301 for(port=1;port<=descriptor->ports_count;++port){ 952 302 bool is_non_removable = 953 ((non_removable_dev_bitmap[port / 8]) >> (port % 8)) %2;954 if (is_non_removable){955 usb_log_debug("non-removable device on port %d\n", 303 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2; 304 if(is_non_removable){ 305 usb_log_debug("non-removable device on port %d\n",port); 956 306 usb_hub_set_port_status_request(&request, port); 957 307 opResult = usb_pipe_control_read( 958 hub->control_pipe, 959 &request, 960 sizeof (usb_device_request_setup_packet_t), 961 &status, 4, &rcvd_size 962 ); 308 hub->control_pipe, 309 &request, sizeof(usb_device_request_setup_packet_t), 310 &status, 4, &rcvd_size 311 ); 963 312 if (opResult != EOK) { 964 usb_log_error("could not get port status of " 965 "port %d errno:%d\n", 966 port, opResult); 313 usb_log_error("could not get port status of port %d errno:%d\n", 314 port, opResult); 967 315 return opResult; 968 316 } 969 //try to reset port 970 if (usb_port_dev_connected(&status) || true) { 971 usb_hub_set_enable_port_feature_request( 972 &request, port, 973 USB_HUB_FEATURE_PORT_RESET); 317 //set the status change bit, so it will be noticed in driver loop 318 if(usb_port_dev_connected(&status)){ 319 usb_hub_set_disable_port_feature_request(&request, port, 320 USB_HUB_FEATURE_PORT_CONNECTION); 974 321 opResult = usb_pipe_control_read( 975 hub->control_pipe, 976 &request, 977 sizeof (usb_device_request_setup_packet_t), 978 &status, 4, &rcvd_size 979 ); 322 hub->control_pipe, 323 &request, sizeof(usb_device_request_setup_packet_t), 324 &status, 4, &rcvd_size 325 ); 980 326 if (opResult != EOK) { 981 327 usb_log_warning( 982 "could not reset port %d " 983 "errno:%d\n", 984 port, opResult); 328 "could not clear port connection on port %d errno:%d\n", 329 port, opResult); 985 330 } 986 usb_log_debug("port reset, should look like " 987 "%d,x%x\n", 988 (1 << USB_HUB_FEATURE_PORT_RESET), 989 (1 << USB_HUB_FEATURE_PORT_RESET) 990 ); 991 } 992 //set the status change bit, so it will be noticed 993 //in driver loop 994 if (usb_port_dev_connected(&status) && false) { 995 usb_hub_set_disable_port_feature_request( 996 &request, port, 997 USB_HUB_FEATURE_PORT_CONNECTION); 331 usb_log_debug("cleared port connection\n"); 332 usb_hub_set_enable_port_feature_request(&request, port, 333 USB_HUB_FEATURE_PORT_ENABLE); 998 334 opResult = usb_pipe_control_read( 999 hub->control_pipe, 1000 &request, 1001 sizeof (usb_device_request_setup_packet_t), 1002 &status, 4, &rcvd_size 1003 ); 335 hub->control_pipe, 336 &request, sizeof(usb_device_request_setup_packet_t), 337 &status, 4, &rcvd_size 338 ); 1004 339 if (opResult != EOK) { 1005 340 usb_log_warning( 1006 "could not clear port " 1007 "connection on port %d " 1008 "errno:%d\n", 1009 port, opResult); 341 "could not set port enabled on port %d errno:%d\n", 342 port, opResult); 1010 343 } 1011 usb_log_debug("cleared port connection\n"); 1012 usb_hub_set_enable_port_feature_request(&request, 1013 port, 1014 USB_HUB_FEATURE_PORT_ENABLE); 1015 opResult = usb_pipe_control_read( 1016 hub->control_pipe, 1017 &request, 1018 sizeof (usb_device_request_setup_packet_t), 1019 &status, 4, &rcvd_size 1020 ); 1021 if (opResult != EOK) { 1022 usb_log_warning( 1023 "could not set port enabled " 1024 "on port %d errno:%d\n", 1025 port, opResult); 1026 } 1027 usb_log_debug("port set to enabled - " 1028 "should lead to connection change\n"); 344 usb_log_debug("port set to enabled - should lead to connection change\n"); 1029 345 } 1030 346 } 1031 347 } 1032 #endif1033 1034 348 /// \TODO this is just a debug code 1035 for (port = 1; port <= descriptor->ports_count; ++port){349 for(port=1;port<=descriptor->ports_count;++port){ 1036 350 bool is_non_removable = 1037 ((non_removable_dev_bitmap[(port-1) / 8]) >> ((port-1) % 8)) % 2; 1038 if (is_non_removable) { 1039 usb_log_debug("CHECKING port %d is non-removable\n", 1040 port); 351 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2; 352 if(is_non_removable){ 353 usb_log_debug("port %d is non-removable\n",port); 1041 354 usb_port_status_t status; 1042 355 size_t rcvd_size; … … 1046 359 //endpoint 0 1047 360 opResult = usb_pipe_control_read( 1048 hub->control_pipe, 1049 &request, 1050 sizeof (usb_device_request_setup_packet_t), 1051 &status, 4, &rcvd_size 1052 ); 361 hub->control_pipe, 362 &request, sizeof(usb_device_request_setup_packet_t), 363 &status, 4, &rcvd_size 364 ); 1053 365 if (opResult != EOK) { 1054 usb_log_error("could not get port status %d\n", 1055 opResult); 366 usb_log_error("could not get port status %d\n",opResult); 1056 367 } 1057 368 if (rcvd_size != sizeof (usb_port_status_t)) { 1058 usb_log_error("received status has incorrect" 1059 " size\n"); 369 usb_log_error("received status has incorrect size\n"); 1060 370 } 1061 371 //something connected/disconnected … … 1063 373 usb_log_debug("some connection changed\n"); 1064 374 } 1065 if(usb_port_dev_connected(&status)){ 1066 usb_log_debug("device connected on port\n"); 1067 } 1068 usb_log_debug("status: %s\n", usb_debug_str_buffer( 1069 (uint8_t *) & status, 4, 4)); 375 usb_log_debug("status: %s\n",usb_debug_str_buffer( 376 (uint8_t *)&status,4,4)); 1070 377 } 1071 378 } 1072 async_usleep(1000*1000*10);1073 379 return EOK; 1074 380 } … … 1076 382 1077 383 /** 384 * release default address used by given hub 385 * 386 * Also unsets hub->is_default_address_used. Convenience wrapper function. 387 * @note hub->connection MUST be open for communication 388 * @param hub hub representation 389 * @return error code 390 */ 391 static int usb_hub_release_default_address(usb_hub_info_t * hub){ 392 int opResult = usb_hc_release_default_address(&hub->connection); 393 if(opResult!=EOK){ 394 usb_log_error("could not release default address, errno %d\n",opResult); 395 return opResult; 396 } 397 hub->is_default_address_used = false; 398 return EOK; 399 } 400 401 /** 402 * routine called when a device on port has been removed 403 * 404 * If the device on port had default address, it releases default address. 405 * Otherwise does not do anything, because DDF does not allow to remove device 406 * from it`s device tree. 407 * @param hub hub representation 408 * @param port port number, starting from 1 409 */ 410 void usb_hub_removed_device( 411 usb_hub_info_t * hub,uint16_t port) { 412 413 int opResult = usb_hub_clear_port_feature(hub->control_pipe, 414 port, USB_HUB_FEATURE_C_PORT_CONNECTION); 415 if(opResult != EOK){ 416 usb_log_warning("could not clear port-change-connection flag\n"); 417 } 418 /** \TODO remove device from device manager - not yet implemented in 419 * devide manager 420 */ 421 422 //close address 423 if(hub->ports[port].attached_device.address >= 0){ 424 /*uncomment this code to use it when DDF allows device removal 425 opResult = usb_hc_unregister_device( 426 &hub->connection, hub->attached_devs[port].address); 427 if(opResult != EOK) { 428 dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \ 429 "removed device: %d", opResult); 430 } 431 hub->attached_devs[port].address = 0; 432 hub->attached_devs[port].handle = 0; 433 */ 434 }else{ 435 usb_log_warning("this is strange, disconnected device had no address\n"); 436 //device was disconnected before it`s port was reset - return default address 437 usb_hub_release_default_address(hub); 438 } 439 } 440 441 442 /** 443 * Process over current condition on port. 444 * 445 * Turn off the power on the port. 446 * 447 * @param hub hub representation 448 * @param port port number, starting from 1 449 */ 450 void usb_hub_over_current( usb_hub_info_t * hub, 451 uint16_t port){ 452 int opResult; 453 opResult = usb_hub_clear_port_feature(hub->control_pipe, 454 port, USB_HUB_FEATURE_PORT_POWER); 455 if(opResult!=EOK){ 456 usb_log_error("cannot power off port %d; %d\n", 457 port, opResult); 458 } 459 } 460 461 462 /** 1078 463 * @} 1079 464 */ -
uspace/drv/usbhub/usbhub.h
ra4e18e1 ra82889e 43 43 44 44 #include <usb/hub.h> 45 #include <usb/classes/hub.h>46 45 47 46 #include <usb/pipes.h> 48 47 #include <usb/devdrv.h> 49 48 49 #include "ports.h" 50 51 52 50 53 /** Information about attached hub. */ 51 54 typedef struct { 52 55 /** Number of ports. */ 53 int port_count;56 size_t port_count; 54 57 55 /** attached device handles, for each port one*/56 usb_h c_attached_device_t * attached_devs;57 58 /** Ports. */ 59 usb_hub_port_t *ports; 60 58 61 /** connection to hcd */ 59 62 usb_hc_connection_t connection; … … 84 87 /** generic usb device data*/ 85 88 usb_device_t * usb_device; 86 87 /** usb hub specific descriptor */88 usb_hub_descriptor_t * descriptor;89 90 /** not yet initialized non-removable devices */91 uint8_t * not_initialized_non_removables;92 93 89 } usb_hub_info_t; 94 90 … … 98 94 */ 99 95 int usb_hub_control_loop(void * hub_info_param); 100 101 int usb_hub_add_device(usb_device_t * usb_dev);102 96 103 97 /** … … 109 103 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param); 110 104 105 void usb_hub_removed_device(usb_hub_info_t *, uint16_t); 106 void usb_hub_over_current(usb_hub_info_t *, uint16_t); 107 108 int usb_hub_add_device(usb_device_t * usb_dev); 111 109 112 110 #endif -
uspace/drv/usbhub/usbhub_private.h
ra4e18e1 ra82889e 38 38 39 39 #include "usbhub.h" 40 #include "usblist.h"41 40 42 41 #include <adt/list.h> … … 111 110 112 111 /** 113 * Clear feature on hub port.114 *115 * @param hc Host controller telephone116 * @param address Hub address117 * @param port_index Port118 * @param feature Feature selector119 * @return Operation result120 */121 static inline int usb_hub_set_port_feature(usb_pipe_t *pipe,122 int port_index,123 usb_hub_class_feature_t feature) {124 125 usb_device_request_setup_packet_t clear_request = {126 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,127 .request = USB_DEVREQ_SET_FEATURE,128 .length = 0,129 .index = port_index130 };131 clear_request.value = feature;132 return usb_pipe_control_write(pipe, &clear_request,133 sizeof(clear_request), NULL, 0);134 }135 136 137 /**138 * Clear feature on hub port.139 *140 * @param pipe pipe to hub control endpoint141 * @param feature Feature selector142 * @return Operation result143 */144 static inline int usb_hub_clear_feature(usb_pipe_t *pipe,145 usb_hub_class_feature_t feature) {146 147 usb_device_request_setup_packet_t clear_request = {148 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,149 .request = USB_DEVREQ_CLEAR_FEATURE,150 .length = 0,151 .index = 0152 };153 clear_request.value = feature;154 return usb_pipe_control_write(pipe, &clear_request,155 sizeof(clear_request), NULL, 0);156 }157 158 /**159 * Clear feature on hub port.160 *161 * @param pipe pipe to hub control endpoint162 * @param feature Feature selector163 * @return Operation result164 */165 static inline int usb_hub_set_feature(usb_pipe_t *pipe,166 usb_hub_class_feature_t feature) {167 168 usb_device_request_setup_packet_t clear_request = {169 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,170 .request = USB_DEVREQ_SET_FEATURE,171 .length = 0,172 .index = 0173 };174 clear_request.value = feature;175 return usb_pipe_control_write(pipe, &clear_request,176 sizeof(clear_request), NULL, 0);177 }178 179 /**180 112 * create uint8_t array with serialized descriptor 181 113 *
Note:
See TracChangeset
for help on using the changeset viewer.