Changes in uspace/drv/ohci/root_hub.c [1387692:b3f655f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
r1387692 rb3f655f 39 39 40 40 #include "root_hub.h" 41 #include "usb/classes/classes.h" 42 #include <usb/request.h> 43 #include <usb/classes/hub.h> 44 45 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = 46 { 47 .configuration_count = 1, 48 .descriptor_type = USB_DESCTYPE_DEVICE, 49 .device_class = USB_CLASS_HUB, 50 .device_protocol = 0, 51 .device_subclass = 0, 52 .device_version = 0, 53 .length = sizeof(usb_standard_device_descriptor_t), 54 /// \TODO this value is guessed 55 .max_packet_size = 8, 56 .vendor_id = 0x16db, 57 .product_id = 0x0001, 58 /// \TODO these values migt be different 59 .str_serial_number = 0, 60 .usb_spec_version = 0, 61 }; 62 63 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = 64 { 65 /// \TODO some values are default or guessed 66 .attributes = 1<<7, 67 .configuration_number = 1, 68 .descriptor_type = USB_DESCTYPE_CONFIGURATION, 69 .interface_count = 1, 70 .length = sizeof(usb_standard_configuration_descriptor_t), 71 .max_power = 100, 72 .str_configuration = 0, 73 }; 74 75 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = 76 { 77 .alternate_setting = 0, 78 .descriptor_type = USB_DESCTYPE_INTERFACE, 79 .endpoint_count = 1, 80 .interface_class = USB_CLASS_HUB, 81 /// \TODO is this correct? 82 .interface_number = 1, 83 .interface_protocol = 0, 84 .interface_subclass = 0, 85 .length = sizeof(usb_standard_interface_descriptor_t), 86 .str_interface = 0, 87 }; 88 89 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = 90 { 91 .attributes = USB_TRANSFER_INTERRUPT, 92 .descriptor_type = USB_DESCTYPE_ENDPOINT, 93 .endpoint_address = 1 + (1<<7), 94 .length = sizeof(usb_standard_endpoint_descriptor_t), 95 .max_packet_size = 8, 96 .poll_interval = 255, 97 }; 41 98 42 99 /** Root hub initialization … … 50 107 instance->device = dev; 51 108 109 52 110 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); 53 111 112 //start generic usb hub driver 113 54 114 /* TODO: implement */ 55 115 return EOK; 56 116 } 57 117 /*----------------------------------------------------------------------------*/ 118 119 120 static int process_get_port_status_request(rh_t *instance, uint16_t port, 121 usb_transfer_batch_t * request){ 122 if(port<1 || port>instance->port_count) 123 return EINVAL; 124 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 125 request->transfered_size = 4; 126 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 127 return EOK; 128 } 129 130 static int process_get_hub_status_request(rh_t *instance, 131 usb_transfer_batch_t * request){ 132 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 133 //bits, 0,1,16,17 134 request->transfered_size = 4; 135 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 136 uint32_buffer[0] = mask & instance->registers->rh_status; 137 return EOK; 138 139 } 140 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 142 size_t * out_size) { 143 //base size 144 size_t size = 7; 145 //variable size according to port count 146 size_t var_size = instance->port_count / 8 + 147 ((instance->port_count % 8 > 0) ? 1 : 0); 148 size += 2 * var_size; 149 uint8_t * result = (uint8_t*) malloc(size); 150 bzero(result,size); 151 //size 152 result[0] = size; 153 //descriptor type 154 result[1] = USB_DESCTYPE_HUB; 155 result[2] = instance->port_count; 156 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 157 result[3] = 158 ((hub_desc_reg >> 8) %2) + 159 (((hub_desc_reg >> 9) %2) << 1) + 160 (((hub_desc_reg >> 10) %2) << 2) + 161 (((hub_desc_reg >> 11) %2) << 3) + 162 (((hub_desc_reg >> 12) %2) << 4); 163 result[4] = 0; 164 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 165 result[6] = 50; 166 167 int port; 168 for (port = 1; port <= instance->port_count; ++port) { 169 result[7 + port/8] += 170 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 171 } 172 size_t i; 173 for (i = 0; i < var_size; ++i) { 174 result[7 + var_size + i] = 255; 175 } 176 (*out_result) = result; 177 (*out_size) = size; 178 } 179 180 181 static int process_get_status_request(rh_t *instance, 182 usb_transfer_batch_t * request) 183 { 184 size_t buffer_size = request->buffer_size; 185 usb_device_request_setup_packet_t * request_packet = 186 (usb_device_request_setup_packet_t*) 187 request->setup_buffer; 188 189 usb_hub_bm_request_type_t request_type = request_packet->request_type; 190 if(buffer_size<4/*request_packet->length*/){///\TODO 191 usb_log_warning("requested more data than buffer size\n"); 192 return EINVAL; 193 } 194 195 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 196 return process_get_hub_status_request(instance, request); 197 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 198 return process_get_port_status_request(instance, request_packet->index, 199 request); 200 return ENOTSUP; 201 } 202 203 static void create_interrupt_mask(rh_t *instance, void ** buffer, 204 size_t * buffer_size){ 205 int bit_count = instance->port_count + 1; 206 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 207 (*buffer) = malloc(*buffer_size); 208 uint8_t * bitmap = (uint8_t*)(*buffer); 209 uint32_t mask = (1<<16) + (1<<17); 210 bzero(bitmap,(*buffer_size)); 211 if(instance->registers->rh_status & mask){ 212 bitmap[0] = 1; 213 } 214 int port; 215 mask = 0; 216 int i; 217 for(i=16;i<=20;++i) 218 mask += 1<<i; 219 for(port = 1; port<=instance->port_count;++port){ 220 if(mask & instance->registers->rh_port_status[port-1]){ 221 bitmap[(port+1)/8] += 1<<(port%8); 222 } 223 } 224 } 225 226 227 static int process_get_descriptor_request(rh_t *instance, 228 usb_transfer_batch_t *request){ 229 /// \TODO 230 usb_device_request_setup_packet_t * setup_request = 231 (usb_device_request_setup_packet_t*)request->setup_buffer; 232 size_t size; 233 const void * result_descriptor; 234 const uint16_t setup_request_value = setup_request->value_high; 235 //(setup_request->value_low << 8); 236 bool del = false; 237 238 switch (setup_request_value) 239 { 240 case USB_DESCTYPE_HUB: { 241 uint8_t * descriptor; 242 usb_create_serialized_hub_descriptor( 243 instance, &descriptor, &size); 244 result_descriptor = descriptor; 245 break; 246 } 247 case USB_DESCTYPE_DEVICE: { 248 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 249 result_descriptor = &ohci_rh_device_descriptor; 250 size = sizeof(ohci_rh_device_descriptor); 251 break; 252 } 253 case USB_DESCTYPE_CONFIGURATION: { 254 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 255 usb_standard_configuration_descriptor_t * descriptor = 256 malloc(sizeof(usb_standard_configuration_descriptor_t)); 257 memcpy(descriptor, &ohci_rh_conf_descriptor, 258 sizeof(usb_standard_configuration_descriptor_t)); 259 /// \TODO should this include device descriptor? 260 const size_t hub_descriptor_size = 7 + 261 2* (instance->port_count / 8 + 262 ((instance->port_count % 8 > 0) ? 1 : 0)); 263 descriptor->total_length = 264 sizeof(usb_standard_configuration_descriptor_t)+ 265 sizeof(usb_standard_endpoint_descriptor_t)+ 266 sizeof(usb_standard_interface_descriptor_t)+ 267 hub_descriptor_size; 268 result_descriptor = descriptor; 269 size = sizeof(usb_standard_configuration_descriptor_t); 270 del = true; 271 break; 272 } 273 case USB_DESCTYPE_INTERFACE: { 274 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 275 result_descriptor = &ohci_rh_iface_descriptor; 276 size = sizeof(ohci_rh_iface_descriptor); 277 break; 278 } 279 case USB_DESCTYPE_ENDPOINT: { 280 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 281 result_descriptor = &ohci_rh_ep_descriptor; 282 size = sizeof(ohci_rh_ep_descriptor); 283 break; 284 } 285 default: { 286 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 287 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 288 setup_request->request_type, 289 setup_request->request, 290 setup_request_value, 291 setup_request->index, 292 setup_request->length 293 ); 294 return EINVAL; 295 } 296 } 297 #if 0 298 if(setup_request_value == USB_DESCTYPE_HUB){ 299 usb_log_debug("USB_DESCTYPE_HUB\n"); 300 //create hub descriptor 301 uint8_t * descriptor; 302 usb_create_serialized_hub_descriptor(instance, 303 &descriptor, &size); 304 result_descriptor = descriptor; 305 }else if(setup_request_value == USB_DESCTYPE_DEVICE){ 306 //create std device descriptor 307 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 308 usb_standard_device_descriptor_t * descriptor = 309 (usb_standard_device_descriptor_t*) 310 malloc(sizeof(usb_standard_device_descriptor_t)); 311 descriptor->configuration_count = 1; 312 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 313 descriptor->device_class = USB_CLASS_HUB; 314 descriptor->device_protocol = 0; 315 descriptor->device_subclass = 0; 316 descriptor->device_version = 0; 317 descriptor->length = sizeof(usb_standard_device_descriptor_t); 318 /// \TODO this value is guessed 319 descriptor->max_packet_size = 8; 320 descriptor->product_id = 0x0001; 321 /// \TODO these values migt be different 322 descriptor->str_serial_number = 0; 323 descriptor->str_serial_number = 0; 324 descriptor->usb_spec_version = 0; 325 descriptor->vendor_id = 0x16db; 326 result_descriptor = descriptor; 327 size = sizeof(usb_standard_device_descriptor_t); 328 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 329 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 330 usb_standard_configuration_descriptor_t * descriptor = 331 (usb_standard_configuration_descriptor_t*) 332 malloc(sizeof(usb_standard_configuration_descriptor_t)); 333 /// \TODO some values are default or guessed 334 descriptor->attributes = 1<<7; 335 descriptor->configuration_number = 1; 336 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 337 descriptor->interface_count = 1; 338 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 339 descriptor->max_power = 100; 340 descriptor->str_configuration = 0; 341 /// \TODO should this include device descriptor? 342 size_t hub_descriptor_size = 7 + 343 2* (instance->port_count / 8 + 344 ((instance->port_count % 8 > 0) ? 1 : 0)); 345 descriptor->total_length = 346 sizeof(usb_standard_configuration_descriptor_t)+ 347 sizeof(usb_standard_endpoint_descriptor_t)+ 348 sizeof(usb_standard_interface_descriptor_t)+ 349 hub_descriptor_size; 350 result_descriptor = descriptor; 351 size = sizeof(usb_standard_configuration_descriptor_t); 352 353 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 354 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 355 usb_standard_interface_descriptor_t * descriptor = 356 (usb_standard_interface_descriptor_t*) 357 malloc(sizeof(usb_standard_interface_descriptor_t)); 358 descriptor->alternate_setting = 0; 359 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 360 descriptor->endpoint_count = 1; 361 descriptor->interface_class = USB_CLASS_HUB; 362 /// \TODO is this correct? 363 descriptor->interface_number = 1; 364 descriptor->interface_protocol = 0; 365 descriptor->interface_subclass = 0; 366 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 367 descriptor->str_interface = 0; 368 result_descriptor = descriptor; 369 size = sizeof(usb_standard_interface_descriptor_t); 370 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 371 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 372 usb_standard_endpoint_descriptor_t * descriptor = 373 (usb_standard_endpoint_descriptor_t*) 374 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 375 descriptor->attributes = USB_TRANSFER_INTERRUPT; 376 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 377 descriptor->endpoint_address = 1 + (1<<7); 378 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 379 descriptor->max_packet_size = 8; 380 descriptor->poll_interval = 255; 381 result_descriptor = descriptor; 382 size = sizeof(usb_standard_endpoint_descriptor_t); 383 }else{ 384 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 385 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 386 setup_request->request_type, 387 setup_request->request, 388 setup_request_value, 389 setup_request->index, 390 setup_request->length 391 ); 392 return EINVAL; 393 } 394 #endif 395 if(request->buffer_size < size){ 396 size = request->buffer_size; 397 } 398 request->transfered_size = size; 399 memcpy(request->buffer,result_descriptor,size); 400 if (del) 401 free(result_descriptor); 402 return EOK; 403 } 404 405 static int process_get_configuration_request(rh_t *instance, 406 usb_transfer_batch_t *request){ 407 //set and get configuration requests do not have any meaning, only dummy 408 //values are returned 409 if(request->buffer_size != 1) 410 return EINVAL; 411 request->buffer[0] = 1; 412 request->transfered_size = 1; 413 return EOK; 414 } 415 416 static int process_hub_feature_set_request(rh_t *instance, 417 uint16_t feature, bool enable){ 418 if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT) 419 return EINVAL; 420 instance->registers->rh_status = 421 enable ? 422 (instance->registers->rh_status | (1<<feature)) 423 : 424 (instance->registers->rh_status & (~(1<<feature))); 425 /// \TODO any error? 426 return EOK; 427 } 428 429 static int process_port_feature_set_request(rh_t *instance, 430 uint16_t feature, uint16_t port, bool enable){ 431 if(feature > USB_HUB_FEATURE_C_PORT_RESET) 432 return EINVAL; 433 if(port<1 || port>instance->port_count) 434 return EINVAL; 435 instance->registers->rh_port_status[port - 1] = 436 enable ? 437 (instance->registers->rh_port_status[port - 1] | (1<<feature)) 438 : 439 (instance->registers->rh_port_status[port - 1] & (~(1<<feature))); 440 /// \TODO any error? 441 return EOK; 442 } 443 444 static int process_address_set_request(rh_t *instance, 445 uint16_t address){ 446 instance->address = address; 447 return EOK; 448 } 449 450 static int process_request_with_output(rh_t *instance, 451 usb_transfer_batch_t *request){ 452 usb_device_request_setup_packet_t * setup_request = 453 (usb_device_request_setup_packet_t*)request->setup_buffer; 454 if(setup_request->request == USB_DEVREQ_GET_STATUS){ 455 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 456 return process_get_status_request(instance, request); 457 } 458 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){ 459 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 460 return process_get_descriptor_request(instance, request); 461 } 462 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){ 463 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 464 return process_get_configuration_request(instance, request); 465 } 466 return ENOTSUP; 467 } 468 469 static int process_request_with_input(rh_t *instance, 470 usb_transfer_batch_t *request){ 471 usb_device_request_setup_packet_t * setup_request = 472 (usb_device_request_setup_packet_t*)request->setup_buffer; 473 request->transfered_size = 0; 474 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){ 475 return ENOTSUP; 476 } 477 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){ 478 //set and get configuration requests do not have any meaning, 479 //only dummy values are returned 480 return EOK; 481 } 482 return ENOTSUP; 483 } 484 485 486 static int process_request_without_data(rh_t *instance, 487 usb_transfer_batch_t *request){ 488 usb_device_request_setup_packet_t * setup_request = 489 (usb_device_request_setup_packet_t*)request->setup_buffer; 490 request->transfered_size = 0; 491 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE 492 || setup_request->request == USB_DEVREQ_SET_FEATURE){ 493 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 494 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 495 return process_hub_feature_set_request(instance, setup_request->value, 496 setup_request->request == USB_DEVREQ_SET_FEATURE); 497 } 498 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 499 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 500 return process_port_feature_set_request(instance, setup_request->value, 501 setup_request->index, 502 setup_request->request == USB_DEVREQ_SET_FEATURE); 503 } 504 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type); 505 return EINVAL; 506 } 507 if(setup_request->request == USB_DEVREQ_SET_ADDRESS){ 508 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 509 return process_address_set_request(instance, setup_request->value); 510 } 511 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type); 512 return ENOTSUP; 513 } 514 515 516 /** 517 * 518 * @param instance 519 * @param request 520 * @return 521 */ 58 522 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 59 523 { 60 524 assert(instance); 61 525 assert(request); 62 /* TODO: implement */ 63 if (request->setup_buffer) { 64 usb_log_info("Root hub got SETUP packet: %s.\n", 65 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 66 } 67 usb_log_error("Root hub request processing not implemented.\n"); 68 usb_transfer_batch_finish(request, ENOTSUP); 526 int opResult; 527 if(request->transfer_type == USB_TRANSFER_CONTROL){ 528 if (request->setup_buffer) { 529 usb_log_info("Root hub got CTRL packet: %s.\n", 530 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 531 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 532 usb_log_error("setup packet too small\n"); 533 return EINVAL; 534 } 535 usb_device_request_setup_packet_t * setup_request = 536 (usb_device_request_setup_packet_t*)request->setup_buffer; 537 if( 538 setup_request->request == USB_DEVREQ_GET_STATUS 539 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 540 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 541 ){ 542 usb_log_debug("processing request with output\n"); 543 opResult = process_request_with_output(instance,request); 544 }else if( 545 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 546 || setup_request->request == USB_DEVREQ_SET_FEATURE 547 || setup_request->request == USB_DEVREQ_SET_ADDRESS 548 ){ 549 usb_log_debug("processing request without additional data\n"); 550 opResult = process_request_without_data(instance,request); 551 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 552 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 553 ){ 554 usb_log_debug("processing request with input\n"); 555 opResult = process_request_with_input(instance,request); 556 }else{ 557 usb_log_warning("received unsuported request: %d\n", 558 setup_request->request 559 ); 560 opResult = ENOTSUP; 561 } 562 }else{ 563 usb_log_error("root hub received empty transaction?"); 564 opResult = EINVAL; 565 } 566 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 567 usb_log_info("Root hub got INTERRUPT packet\n"); 568 void * buffer; 569 create_interrupt_mask(instance, &buffer, 570 &(request->transfered_size)); 571 memcpy(request->transport_buffer,buffer, request->transfered_size); 572 opResult = EOK; 573 }else{ 574 opResult = EINVAL; 575 } 576 usb_transfer_batch_finish(request, opResult); 69 577 return EOK; 70 578 } 71 579 /*----------------------------------------------------------------------------*/ 580 581 72 582 void rh_interrupt(rh_t *instance) 73 583 {
Note:
See TracChangeset
for help on using the changeset viewer.