Changeset f3da9b2 in mainline
- Timestamp:
- 2011-03-26T16:51:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- aee6c73
- Parents:
- e6223239
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
re6223239 rf3da9b2 64 64 /*----------------------------------------------------------------------------*/ 65 65 66 66 /** 67 * create answer to port status_request 68 * 69 * Copy content of corresponding port status register to answer buffer. 70 * 71 * @param instance root hub instance 72 * @param port port number, counted from 1 73 * @param request structure containing both request and response information 74 * @return error code 75 */ 67 76 static int process_get_port_status_request(rh_t *instance, uint16_t port, 68 77 usb_transfer_batch_t * request){ … … 75 84 } 76 85 86 /** 87 * create answer to port status_request 88 * 89 * Copy content of hub status register to answer buffer. 90 * 91 * @param instance root hub instance 92 * @param request structure containing both request and response information 93 * @return error code 94 */ 77 95 static int process_get_hub_status_request(rh_t *instance, 78 96 usb_transfer_batch_t * request){ … … 86 104 } 87 105 88 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 106 /** 107 * Create hub descriptor used in hub-driver <-> hub communication 108 * 109 * This means creating byt array from data in root hub registers. For more 110 * info see usb hub specification. 111 * 112 * @param instance root hub instance 113 * @param@out out_result pointer to resultant serialized descriptor 114 * @param@out out_size size of serialized descriptor 115 */ 116 static void usb_create_serialized_hub_descriptor(rh_t *instance, 117 uint8_t ** out_result, 89 118 size_t * out_size) { 90 119 //base size … … 126 155 127 156 157 /** 158 * create answer to status request 159 * 160 * This might be either hub status or port status request. If neither, 161 * ENOTSUP is returned. 162 * @param instance root hub instance 163 * @param request structure containing both request and response information 164 * @return error code 165 */ 128 166 static int process_get_status_request(rh_t *instance, 129 167 usb_transfer_batch_t * request) … … 148 186 } 149 187 188 /** 189 * create answer to status interrupt consisting of change bitmap 190 * 191 * Result contains bitmap where bit 0 indicates change on hub and 192 * bit i indicates change on i`th port (i>0). For more info see 193 * Hub and Port status bitmap specification in USB specification. 194 * @param instance root hub instance 195 * @param@out buffer pointer to created interrupt mas 196 * @param@out buffer_size size of created interrupt mask 197 */ 150 198 static void create_interrupt_mask(rh_t *instance, void ** buffer, 151 199 size_t * buffer_size){ … … 171 219 } 172 220 173 221 /** 222 * create standard device descriptor for a hub 223 * @return newly allocated descriptor 224 */ 225 static usb_standard_device_descriptor_t * 226 usb_ohci_rh_create_standard_device_descriptor(){ 227 usb_standard_device_descriptor_t * descriptor = 228 (usb_standard_device_descriptor_t*) 229 malloc(sizeof(usb_standard_device_descriptor_t)); 230 descriptor->configuration_count = 1; 231 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 232 descriptor->device_class = USB_CLASS_HUB; 233 descriptor->device_protocol = 0; 234 descriptor->device_subclass = 0; 235 descriptor->device_version = 0; 236 descriptor->length = sizeof(usb_standard_device_descriptor_t); 237 /// \TODO this value is guessed 238 descriptor->max_packet_size = 8; 239 descriptor->product_id = 0x0001; 240 /// \TODO these values migt be different 241 descriptor->str_serial_number = 0; 242 descriptor->str_serial_number = 0; 243 descriptor->usb_spec_version = 0; 244 descriptor->vendor_id = 0x16db; 245 return descriptor; 246 } 247 248 /** 249 * create standart configuration descriptor for the root hub instance 250 * @param instance root hub instance 251 * @return newly allocated descriptor 252 */ 253 static usb_standard_configuration_descriptor_t * 254 usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){ 255 usb_standard_configuration_descriptor_t * descriptor = 256 (usb_standard_configuration_descriptor_t*) 257 malloc(sizeof(usb_standard_configuration_descriptor_t)); 258 /// \TODO some values are default or guessed 259 descriptor->attributes = 1<<7; 260 descriptor->configuration_number = 1; 261 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 262 descriptor->interface_count = 1; 263 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 264 descriptor->max_power = 100; 265 descriptor->str_configuration = 0; 266 /// \TODO should this include device descriptor? 267 size_t hub_descriptor_size = 7 + 268 2* (instance->port_count / 8 + 269 ((instance->port_count % 8 > 0) ? 1 : 0)); 270 descriptor->total_length = 271 sizeof(usb_standard_configuration_descriptor_t)+ 272 sizeof(usb_standard_endpoint_descriptor_t)+ 273 sizeof(usb_standard_interface_descriptor_t)+ 274 hub_descriptor_size; 275 return descriptor; 276 } 277 278 /** 279 * create standard interface descriptor for a root hub 280 * @return newly allocated descriptor 281 */ 282 static usb_standard_interface_descriptor_t * 283 usb_ohci_rh_create_standard_interface_descriptor(){ 284 usb_standard_interface_descriptor_t * descriptor = 285 (usb_standard_interface_descriptor_t*) 286 malloc(sizeof(usb_standard_interface_descriptor_t)); 287 descriptor->alternate_setting = 0; 288 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 289 descriptor->endpoint_count = 1; 290 descriptor->interface_class = USB_CLASS_HUB; 291 /// \TODO is this correct? 292 descriptor->interface_number = 1; 293 descriptor->interface_protocol = 0; 294 descriptor->interface_subclass = 0; 295 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 296 descriptor->str_interface = 0; 297 return descriptor; 298 } 299 300 /** 301 * create standard endpoint descriptor for a root hub 302 * @return newly allocated descriptor 303 */ 304 static usb_standard_endpoint_descriptor_t * 305 usb_ohci_rh_create_standard_endpoint_descriptor(){ 306 usb_standard_endpoint_descriptor_t * descriptor = 307 (usb_standard_endpoint_descriptor_t*) 308 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 309 descriptor->attributes = USB_TRANSFER_INTERRUPT; 310 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 311 descriptor->endpoint_address = 1 + (1<<7); 312 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 313 descriptor->max_packet_size = 8; 314 descriptor->poll_interval = 255; 315 return descriptor; 316 } 317 318 /** 319 * create answer to a descriptor request 320 * 321 * This might be a request for standard (configuration, device, endpoint or 322 * interface) or device specific (hub) descriptor. 323 * @param instance root hub instance 324 * @param request structure containing both request and response information 325 * @return error code 326 */ 174 327 static int process_get_descriptor_request(rh_t *instance, 175 328 usb_transfer_batch_t *request){ 176 /// \TODO177 329 usb_device_request_setup_packet_t * setup_request = 178 330 (usb_device_request_setup_packet_t*)request->setup_buffer; … … 191 343 //create std device descriptor 192 344 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 193 usb_standard_device_descriptor_t * descriptor = 194 (usb_standard_device_descriptor_t*) 195 malloc(sizeof(usb_standard_device_descriptor_t)); 196 descriptor->configuration_count = 1; 197 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 198 descriptor->device_class = USB_CLASS_HUB; 199 descriptor->device_protocol = 0; 200 descriptor->device_subclass = 0; 201 descriptor->device_version = 0; 202 descriptor->length = sizeof(usb_standard_device_descriptor_t); 203 /// \TODO this value is guessed 204 descriptor->max_packet_size = 8; 205 descriptor->product_id = 0x0001; 206 /// \TODO these values migt be different 207 descriptor->str_serial_number = 0; 208 descriptor->str_serial_number = 0; 209 descriptor->usb_spec_version = 0; 210 descriptor->vendor_id = 0x16db; 211 result_descriptor = descriptor; 345 result_descriptor = 346 usb_ohci_rh_create_standard_device_descriptor(); 212 347 size = sizeof(usb_standard_device_descriptor_t); 213 348 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 214 349 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 215 usb_standard_configuration_descriptor_t * descriptor = 216 (usb_standard_configuration_descriptor_t*) 217 malloc(sizeof(usb_standard_configuration_descriptor_t)); 218 /// \TODO some values are default or guessed 219 descriptor->attributes = 1<<7; 220 descriptor->configuration_number = 1; 221 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 222 descriptor->interface_count = 1; 223 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 224 descriptor->max_power = 100; 225 descriptor->str_configuration = 0; 226 /// \TODO should this include device descriptor? 227 size_t hub_descriptor_size = 7 + 228 2* (instance->port_count / 8 + 229 ((instance->port_count % 8 > 0) ? 1 : 0)); 230 descriptor->total_length = 231 sizeof(usb_standard_configuration_descriptor_t)+ 232 sizeof(usb_standard_endpoint_descriptor_t)+ 233 sizeof(usb_standard_interface_descriptor_t)+ 234 hub_descriptor_size; 235 result_descriptor = descriptor; 350 result_descriptor = 351 usb_ohci_rh_create_standart_configuration_descriptor(instance); 236 352 size = sizeof(usb_standard_configuration_descriptor_t); 237 353 238 354 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 239 355 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 240 usb_standard_interface_descriptor_t * descriptor = 241 (usb_standard_interface_descriptor_t*) 242 malloc(sizeof(usb_standard_interface_descriptor_t)); 243 descriptor->alternate_setting = 0; 244 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 245 descriptor->endpoint_count = 1; 246 descriptor->interface_class = USB_CLASS_HUB; 247 /// \TODO is this correct? 248 descriptor->interface_number = 1; 249 descriptor->interface_protocol = 0; 250 descriptor->interface_subclass = 0; 251 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 252 descriptor->str_interface = 0; 253 result_descriptor = descriptor; 356 result_descriptor = 357 usb_ohci_rh_create_standard_interface_descriptor(); 254 358 size = sizeof(usb_standard_interface_descriptor_t); 255 359 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 256 360 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 257 usb_standard_endpoint_descriptor_t * descriptor = 258 (usb_standard_endpoint_descriptor_t*) 259 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 260 descriptor->attributes = USB_TRANSFER_INTERRUPT; 261 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 262 descriptor->endpoint_address = 1 + (1<<7); 263 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 264 descriptor->max_packet_size = 8; 265 descriptor->poll_interval = 255; 266 result_descriptor = descriptor; 361 result_descriptor = 362 usb_ohci_rh_create_standard_endpoint_descriptor(); 267 363 size = sizeof(usb_standard_endpoint_descriptor_t); 268 364 }else{ … … 286 382 } 287 383 384 /** 385 * answer to get configuration request 386 * 387 * Root hub works independently on the configuration. 388 * @param instance root hub instance 389 * @param request structure containing both request and response information 390 * @return error code 391 */ 288 392 static int process_get_configuration_request(rh_t *instance, 289 393 usb_transfer_batch_t *request){ … … 297 401 } 298 402 403 /** 404 * process feature-enabling/disabling request on hub 405 * 406 * @param instance root hub instance 407 * @param feature feature selector 408 * @param enable enable or disable specified feature 409 * @return error code 410 */ 299 411 static int process_hub_feature_set_request(rh_t *instance, 300 412 uint16_t feature, bool enable){ … … 310 422 } 311 423 424 /** 425 * process feature-enabling/disabling request on hub 426 * 427 * @param instance root hub instance 428 * @param feature feature selector 429 * @param port port number, counted from 1 430 * @param enable enable or disable the specified feature 431 * @return error code 432 */ 312 433 static int process_port_feature_set_request(rh_t *instance, 313 434 uint16_t feature, uint16_t port, bool enable){ … … 325 446 } 326 447 448 /** 449 * register address to this device 450 * 451 * @param instance root hub instance 452 * @param address new address 453 * @return error code 454 */ 327 455 static int process_address_set_request(rh_t *instance, 328 456 uint16_t address){ … … 331 459 } 332 460 461 /** 462 * process one of requests that requere output data 463 * 464 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or 465 * USB_DEVREQ_GET_CONFIGURATION. 466 * @param instance root hub instance 467 * @param request structure containing both request and response information 468 * @return error code 469 */ 333 470 static int process_request_with_output(rh_t *instance, 334 471 usb_transfer_batch_t *request){ … … 350 487 } 351 488 489 /** 490 * process one of requests that carry input data 491 * 492 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or 493 * USB_DEVREQ_SET_CONFIGURATION. 494 * @param instance root hub instance 495 * @param request structure containing both request and response information 496 * @return error code 497 */ 352 498 static int process_request_with_input(rh_t *instance, 353 499 usb_transfer_batch_t *request){ … … 366 512 } 367 513 368 514 /** 515 * process one of requests that do not request nor carry additional data 516 * 517 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or 518 * USB_DEVREQ_SET_ADDRESS. 519 * @param instance root hub instance 520 * @param request structure containing both request and response information 521 * @return error code 522 */ 369 523 static int process_request_without_data(rh_t *instance, 370 524 usb_transfer_batch_t *request){ … … 396 550 } 397 551 398 399 /** 400 * 401 * @param instance 402 * @param request 403 * @return 552 /** 553 * process hub control request 554 * 555 * If needed, writes answer into the request structure. 556 * Request can be one of 557 * USB_DEVREQ_GET_STATUS, 558 * USB_DEVREQ_GET_DESCRIPTOR, 559 * USB_DEVREQ_GET_CONFIGURATION, 560 * USB_DEVREQ_CLEAR_FEATURE, 561 * USB_DEVREQ_SET_FEATURE, 562 * USB_DEVREQ_SET_ADDRESS, 563 * USB_DEVREQ_SET_DESCRIPTOR or 564 * USB_DEVREQ_SET_CONFIGURATION. 565 * 566 * @param instance root hub instance 567 * @param request structure containing both request and response information 568 * @return error code 569 */ 570 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){ 571 int opResult; 572 if (request->setup_buffer) { 573 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 574 usb_log_error("setup packet too small\n"); 575 return EINVAL; 576 } 577 usb_log_info("CTRL packet: %s.\n", 578 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 579 usb_device_request_setup_packet_t * setup_request = 580 (usb_device_request_setup_packet_t*)request->setup_buffer; 581 if( 582 setup_request->request == USB_DEVREQ_GET_STATUS 583 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 584 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 585 ){ 586 usb_log_debug("processing request with output\n"); 587 opResult = process_request_with_output(instance,request); 588 }else if( 589 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 590 || setup_request->request == USB_DEVREQ_SET_FEATURE 591 || setup_request->request == USB_DEVREQ_SET_ADDRESS 592 ){ 593 usb_log_debug("processing request without additional data\n"); 594 opResult = process_request_without_data(instance,request); 595 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 596 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 597 ){ 598 usb_log_debug("processing request with input\n"); 599 opResult = process_request_with_input(instance,request); 600 }else{ 601 usb_log_warning("received unsuported request: %d\n", 602 setup_request->request 603 ); 604 opResult = ENOTSUP; 605 } 606 }else{ 607 usb_log_error("root hub received empty transaction?"); 608 opResult = EINVAL; 609 } 610 return opResult; 611 } 612 613 /** 614 * process root hub request 615 * 616 * @param instance root hub instance 617 * @param request structure containing both request and response information 618 * @return error code 404 619 */ 405 620 int rh_request(rh_t *instance, usb_transfer_batch_t *request) … … 409 624 int opResult; 410 625 if(request->transfer_type == USB_TRANSFER_CONTROL){ 411 if (request->setup_buffer) { 412 usb_log_info("Root hub got CTRL packet: %s.\n", 413 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 414 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 415 usb_log_error("setup packet too small\n"); 416 return EINVAL; 417 } 418 usb_device_request_setup_packet_t * setup_request = 419 (usb_device_request_setup_packet_t*)request->setup_buffer; 420 if( 421 setup_request->request == USB_DEVREQ_GET_STATUS 422 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 423 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 424 ){ 425 usb_log_debug("processing request with output\n"); 426 opResult = process_request_with_output(instance,request); 427 }else if( 428 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 429 || setup_request->request == USB_DEVREQ_SET_FEATURE 430 || setup_request->request == USB_DEVREQ_SET_ADDRESS 431 ){ 432 usb_log_debug("processing request without additional data\n"); 433 opResult = process_request_without_data(instance,request); 434 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 435 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 436 ){ 437 usb_log_debug("processing request with input\n"); 438 opResult = process_request_with_input(instance,request); 439 }else{ 440 usb_log_warning("received unsuported request: %d\n", 441 setup_request->request 442 ); 443 opResult = ENOTSUP; 444 } 445 }else{ 446 usb_log_error("root hub received empty transaction?"); 447 opResult = EINVAL; 448 } 626 usb_log_info("Root hub got CONTROL packet\n"); 627 opResult = process_ctrl_request(instance,request); 449 628 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 450 629 usb_log_info("Root hub got INTERRUPT packet\n"); … … 465 644 void rh_interrupt(rh_t *instance) 466 645 { 467 usb_log_ error("Root hub interrupt not implemented.\n");468 /* TODO: implement */646 usb_log_info("Whoa whoa wait, I`m not supposed to receive interrupts, am I?\n"); 647 /* TODO: implement? */ 469 648 } 470 649 /**
Note:
See TracChangeset
for help on using the changeset viewer.