Changeset c593b21 in mainline for uspace/drv/ohci/root_hub.c
- Timestamp:
- 2011-04-03T18:06:29Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c4e0b47
- Parents:
- 0b4e7ca (diff), 0cec844 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
r0b4e7ca rc593b21 40 40 #include "root_hub.h" 41 41 #include "usb/classes/classes.h" 42 #include "usb/devdrv.h" 42 43 #include <usb/request.h> 43 44 #include <usb/classes/hub.h> … … 61 62 /// \TODO these values migt be different 62 63 .str_serial_number = 0, 63 .usb_spec_version = 0 ,64 .usb_spec_version = 0x110, 64 65 }; 65 66 … … 110 111 }; 111 112 112 /** Root hub initialization 113 * @return Error code. 114 */ 115 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) 116 { 117 assert(instance); 118 instance->address = -1; 119 instance->registers = regs; 120 instance->device = dev; 121 122 123 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); 124 125 //start generic usb hub driver 113 static const uint32_t hub_clear_feature_valid_mask = 114 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) + 115 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 116 117 static const uint32_t hub_clear_feature_by_writing_one_mask = 118 1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER; 119 120 static const uint32_t hub_set_feature_valid_mask = 121 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 122 126 123 127 /* TODO: implement */ 128 return EOK; 129 } 130 /*----------------------------------------------------------------------------*/ 131 132 /** 133 * create answer to port status_request 134 * 135 * Copy content of corresponding port status register to answer buffer. 136 * 137 * @param instance root hub instance 138 * @param port port number, counted from 1 139 * @param request structure containing both request and response information 140 * @return error code 141 */ 142 static int process_get_port_status_request(rh_t *instance, uint16_t port, 143 usb_transfer_batch_t * request){ 144 if(port<1 || port>instance->port_count) 145 return EINVAL; 146 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 147 request->transfered_size = 4; 148 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 149 return EOK; 150 } 151 152 /** 153 * create answer to port status_request 154 * 155 * Copy content of hub status register to answer buffer. 156 * 157 * @param instance root hub instance 158 * @param request structure containing both request and response information 159 * @return error code 160 */ 161 static int process_get_hub_status_request(rh_t *instance, 162 usb_transfer_batch_t * request){ 163 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 164 //bits, 0,1,16,17 165 request->transfered_size = 4; 166 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 167 uint32_buffer[0] = mask & instance->registers->rh_status; 168 return EOK; 169 170 } 124 static const uint32_t hub_set_feature_direct_mask = 125 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 126 127 static const uint32_t port_set_feature_valid_mask = 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); 132 133 static const uint32_t port_clear_feature_valid_mask = 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 171 147 172 148 /** 173 149 * Create hub descriptor used in hub-driver <-> hub communication 174 * 150 * 175 151 * This means creating byt array from data in root hub registers. For more 176 152 * info see usb hub specification. … … 197 173 result[2] = instance->port_count; 198 174 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 199 result[3] = 175 result[3] = 200 176 ((hub_desc_reg >> 8) %2) + 201 177 (((hub_desc_reg >> 9) %2) << 1) + … … 219 195 (*out_size) = size; 220 196 } 197 198 199 /** initialize hub descriptors 200 * 201 * Initialized are device and full configuration descriptor. These need to 202 * be initialized only once per hub. 203 * @instance root hub instance 204 */ 205 static void rh_init_descriptors(rh_t *instance){ 206 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 207 sizeof(ohci_rh_device_descriptor) 208 ); 209 usb_standard_configuration_descriptor_t descriptor; 210 memcpy(&descriptor,&ohci_rh_conf_descriptor, 211 sizeof(ohci_rh_conf_descriptor)); 212 uint8_t * hub_descriptor; 213 size_t hub_desc_size; 214 usb_create_serialized_hub_descriptor(instance, &hub_descriptor, 215 &hub_desc_size); 216 217 descriptor.total_length = 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 223 uint8_t * full_config_descriptor = 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 236 instance->descriptors.configuration = full_config_descriptor; 237 instance->descriptors.configuration_size = descriptor.total_length; 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 } 261 /*----------------------------------------------------------------------------*/ 262 263 /** 264 * create answer to port status_request 265 * 266 * Copy content of corresponding port status register to answer buffer. 267 * 268 * @param instance root hub instance 269 * @param port port number, counted from 1 270 * @param request structure containing both request and response information 271 * @return error code 272 */ 273 static int process_get_port_status_request(rh_t *instance, uint16_t port, 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; 278 request->transfered_size = 4; 279 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 280 return EOK; 281 } 282 283 /** 284 * create answer to port status_request 285 * 286 * Copy content of hub status register to answer buffer. 287 * 288 * @param instance root hub instance 289 * @param request structure containing both request and response information 290 * @return error code 291 */ 292 static int process_get_hub_status_request(rh_t *instance, 293 usb_transfer_batch_t * request){ 294 uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer; 295 //bits, 0,1,16,17 296 request->transfered_size = 4; 297 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 298 uint32_buffer[0] = mask & instance->registers->rh_status; 299 return EOK; 300 301 } 302 221 303 222 304 … … 284 366 } 285 367 } 286 287 /** 288 * create standart configuration descriptor for the root hub instance 289 * @param instance root hub instance 290 * @return newly allocated descriptor 291 */ 292 static usb_standard_configuration_descriptor_t * 293 usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){ 294 usb_standard_configuration_descriptor_t * descriptor = 295 malloc(sizeof(usb_standard_configuration_descriptor_t)); 296 memcpy(descriptor, &ohci_rh_conf_descriptor, 297 sizeof(usb_standard_configuration_descriptor_t)); 298 /// \TODO should this include device descriptor? 299 const size_t hub_descriptor_size = 7 + 300 2* (instance->port_count / 8 + 301 ((instance->port_count % 8 > 0) ? 1 : 0)); 302 descriptor->total_length = 303 sizeof(usb_standard_configuration_descriptor_t)+ 304 sizeof(usb_standard_endpoint_descriptor_t)+ 305 sizeof(usb_standard_interface_descriptor_t)+ 306 hub_descriptor_size; 307 return descriptor; 308 } 309 368 310 369 /** 311 370 * create answer to a descriptor request … … 344 403 case USB_DESCTYPE_CONFIGURATION: { 345 404 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 346 usb_standard_configuration_descriptor_t * descriptor = 347 usb_ohci_rh_create_standart_configuration_descriptor( 348 instance); 349 result_descriptor = descriptor; 350 size = sizeof(usb_standard_configuration_descriptor_t); 351 del = true; 405 result_descriptor = instance->descriptors.configuration; 406 size = instance->descriptors.configuration_size; 352 407 break; 353 408 } … … 380 435 } 381 436 request->transfered_size = size; 382 memcpy(request->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)); 383 440 if (del) 384 441 free(result_descriptor); … … 400 457 if(request->buffer_size != 1) 401 458 return EINVAL; 402 request-> buffer[0] = 1;459 request->transport_buffer[0] = 1; 403 460 request->transfered_size = 1; 404 461 return EOK; … … 406 463 407 464 /** 408 * process feature-enabling /disablingrequest on hub465 * process feature-enabling request on hub 409 466 * 410 467 * @param instance root hub instance 411 468 * @param feature feature selector 412 * @param enable enable or disable specified feature413 469 * @return error code 414 470 */ 415 471 static int process_hub_feature_set_request(rh_t *instance, 416 uint16_t feature , bool enable){417 if( feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)472 uint16_t feature){ 473 if(! ((1<<feature) & hub_set_feature_valid_mask)) 418 474 return EINVAL; 419 475 instance->registers->rh_status = 420 enable ?421 476 (instance->registers->rh_status | (1<<feature)) 422 : 423 (instance->registers->rh_status & (~(1<<feature))); 424 /// \TODO any error? 425 return EOK; 426 } 427 428 /** 429 * process feature-enabling/disabling request on hub 477 & (~ hub_clear_feature_by_writing_one_mask); 478 return EOK; 479 } 480 481 /** 482 * process feature-disabling request on hub 483 * 484 * @param instance root hub instance 485 * @param feature feature selector 486 * @return error code 487 */ 488 static int process_hub_feature_clear_request(rh_t *instance, 489 uint16_t feature){ 490 if(! ((1<<feature) & hub_clear_feature_valid_mask)) 491 return EINVAL; 492 //is the feature cleared directly? 493 if ((1<<feature) & hub_set_feature_direct_mask){ 494 instance->registers->rh_status = 495 (instance->registers->rh_status & (~(1<<feature))) 496 & (~ hub_clear_feature_by_writing_one_mask); 497 }else{//the feature is cleared by writing '1' 498 instance->registers->rh_status = 499 (instance->registers->rh_status 500 & (~ hub_clear_feature_by_writing_one_mask)) 501 | (1<<feature); 502 } 503 return EOK; 504 } 505 506 507 508 /** 509 * process feature-enabling request on hub 430 510 * 431 511 * @param instance root hub instance … … 436 516 */ 437 517 static int process_port_feature_set_request(rh_t *instance, 438 uint16_t feature, uint16_t port , bool enable){439 if( feature > USB_HUB_FEATURE_C_PORT_RESET)518 uint16_t feature, uint16_t port){ 519 if(!((1<<feature) & port_set_feature_valid_mask)) 440 520 return EINVAL; 441 521 if(port<1 || port>instance->port_count) 442 522 return EINVAL; 443 523 instance->registers->rh_port_status[port - 1] = 444 enable ?445 524 (instance->registers->rh_port_status[port - 1] | (1<<feature)) 446 : 447 (instance->registers->rh_port_status[port - 1] & (~(1<<feature))); 525 & (~port_clear_feature_valid_mask); 448 526 /// \TODO any error? 449 527 return EOK; 450 528 } 529 530 /** 531 * process feature-disabling request on hub 532 * 533 * @param instance root hub instance 534 * @param feature feature selector 535 * @param port port number, counted from 1 536 * @param enable enable or disable the specified feature 537 * @return error code 538 */ 539 static int process_port_feature_clear_request(rh_t *instance, 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) 546 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 547 if(feature == USB_HUB_FEATURE_PORT_SUSPEND) 548 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 549 instance->registers->rh_port_status[port - 1] = 550 (instance->registers->rh_port_status[port - 1] 551 & (~port_clear_feature_valid_mask)) 552 | (1<<feature); 553 /// \TODO any error? 554 return EOK; 555 } 556 451 557 452 558 /** … … 530 636 (usb_device_request_setup_packet_t*)request->setup_buffer; 531 637 request->transfered_size = 0; 532 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE 533 || setup_request->request == USB_DEVREQ_SET_FEATURE){ 638 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE){ 534 639 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 535 640 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 536 return process_hub_feature_ set_request(instance, setup_request->value,537 setup_request-> request == USB_DEVREQ_SET_FEATURE);641 return process_hub_feature_clear_request(instance, 642 setup_request->value); 538 643 } 539 644 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 540 645 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 541 return process_port_feature_set_request(instance, setup_request->value, 542 setup_request->index, 543 setup_request->request == USB_DEVREQ_SET_FEATURE); 646 return process_port_feature_clear_request(instance, 647 setup_request->value, 648 setup_request->index); 649 } 650 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 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){ 656 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 657 return process_hub_feature_set_request(instance, 658 setup_request->value); 659 } 660 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 661 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 662 return process_port_feature_set_request(instance, 663 setup_request->value, 664 setup_request->index); 544 665 } 545 666 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
Note:
See TracChangeset
for help on using the changeset viewer.