Changeset dc4c19e in mainline for uspace/drv/ohci/root_hub.c
- Timestamp:
- 2011-04-10T12:18:09Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 60c0573
- Parents:
- a49e171 (diff), 82e8861 (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
ra49e171 rdc4c19e 47 47 * standart device descriptor for ohci root hub 48 48 */ 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, 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, 65 64 }; 66 65 … … 69 68 * for ohci root hubs 70 69 */ 71 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = 72 { 70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = { 73 71 /// \TODO some values are default or guessed 74 .attributes = 1 <<7,72 .attributes = 1 << 7, 75 73 .configuration_number = 1, 76 74 .descriptor_type = USB_DESCTYPE_CONFIGURATION, 77 75 .interface_count = 1, 78 .length = sizeof (usb_standard_configuration_descriptor_t),76 .length = sizeof (usb_standard_configuration_descriptor_t), 79 77 .max_power = 100, 80 78 .str_configuration = 0, … … 84 82 * standart ohci root hub interface descriptor 85 83 */ 86 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = 87 { 84 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = { 88 85 .alternate_setting = 0, 89 86 .descriptor_type = USB_DESCTYPE_INTERFACE, … … 94 91 .interface_protocol = 0, 95 92 .interface_subclass = 0, 96 .length = sizeof (usb_standard_interface_descriptor_t),93 .length = sizeof (usb_standard_interface_descriptor_t), 97 94 .str_interface = 0, 98 95 }; … … 101 98 * standart ohci root hub endpoint descriptor 102 99 */ 103 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = 104 { 100 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = { 105 101 .attributes = USB_TRANSFER_INTERRUPT, 106 102 .descriptor_type = USB_DESCTYPE_ENDPOINT, 107 .endpoint_address = 1 + (1 <<7),108 .length = sizeof (usb_standard_endpoint_descriptor_t),103 .endpoint_address = 1 + (1 << 7), 104 .length = sizeof (usb_standard_endpoint_descriptor_t), 109 105 .max_packet_size = 8, 110 106 .poll_interval = 255, … … 112 108 113 109 static const uint32_t hub_clear_feature_valid_mask = 114 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) +115 110 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) | 111 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 116 112 117 113 static const uint32_t hub_clear_feature_by_writing_one_mask = … … 119 115 120 116 static const uint32_t hub_set_feature_valid_mask = 121 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 122 123 117 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 118 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 119 120 124 121 static const uint32_t hub_set_feature_direct_mask = 125 122 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 126 123 127 124 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 125 (1 << USB_HUB_FEATURE_PORT_ENABLE) | 126 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 127 (1 << USB_HUB_FEATURE_PORT_RESET) | 128 (1 << USB_HUB_FEATURE_PORT_POWER); 132 129 133 130 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 131 (1 << USB_HUB_FEATURE_PORT_CONNECTION) | 132 (1 << USB_HUB_FEATURE_PORT_SUSPEND) | 133 (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) | 134 (1 << USB_HUB_FEATURE_PORT_POWER) | 135 (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) | 136 (1 << USB_HUB_FEATURE_C_PORT_ENABLE) | 137 (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) | 138 (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 139 (1 << USB_HUB_FEATURE_C_PORT_RESET); 140 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into 141 //USB_HUB_FEATURE_PORT_LOW_SPEED 142 143 static const uint32_t port_status_change_mask = 144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) | 145 (1<< USB_HUB_FEATURE_C_PORT_ENABLE) | 146 (1<< USB_HUB_FEATURE_C_PORT_OVER_CURRENT) | 147 (1<< USB_HUB_FEATURE_C_PORT_RESET) | 148 (1<< USB_HUB_FEATURE_C_PORT_SUSPEND); 149 150 151 static void usb_create_serialized_hub_descriptor(rh_t *instance, 152 uint8_t ** out_result, 153 size_t * out_size); 154 155 static void rh_init_descriptors(rh_t *instance); 156 157 static int process_get_port_status_request(rh_t *instance, uint16_t port, 158 usb_transfer_batch_t * request); 159 160 static int process_get_hub_status_request(rh_t *instance, 161 usb_transfer_batch_t * request); 162 163 static int process_get_status_request(rh_t *instance, 164 usb_transfer_batch_t * request); 165 166 static void create_interrupt_mask(rh_t *instance, void ** buffer, 167 size_t * buffer_size); 168 169 static int process_get_descriptor_request(rh_t *instance, 170 usb_transfer_batch_t *request); 171 172 static int process_get_configuration_request(rh_t *instance, 173 usb_transfer_batch_t *request); 174 175 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature); 176 177 static int process_hub_feature_clear_request(rh_t *instance, 178 uint16_t feature); 179 180 static int process_port_feature_set_request(rh_t *instance, 181 uint16_t feature, uint16_t port); 182 183 static int process_port_feature_clear_request(rh_t *instance, 184 uint16_t feature, uint16_t port); 185 186 static int process_address_set_request(rh_t *instance, 187 uint16_t address); 188 189 static int process_request_with_output(rh_t *instance, 190 usb_transfer_batch_t *request); 191 192 static int process_request_with_input(rh_t *instance, 193 usb_transfer_batch_t *request); 194 195 static int process_request_without_data(rh_t *instance, 196 usb_transfer_batch_t *request); 197 198 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 199 200 201 202 203 204 /** Root hub initialization 205 * @return Error code. 206 */ 207 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) { 208 assert(instance); 209 //instance->address = -1; 210 instance->registers = regs; 211 instance->device = dev; 212 instance->port_count = 213 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 214 rh_init_descriptors(instance); 215 // set port power mode to no-power-switching 216 instance->registers->rh_desc_a = 217 instance->registers->rh_desc_a | (1<<9); 218 219 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 220 221 //start generic usb hub driver 222 223 /* TODO: implement */ 224 return EOK; 225 } 226 /*----------------------------------------------------------------------------*/ 227 228 /** 229 * process root hub request 230 * 231 * @param instance root hub instance 232 * @param request structure containing both request and response information 233 * @return error code 234 */ 235 int rh_request(rh_t *instance, usb_transfer_batch_t *request) { 236 assert(instance); 237 assert(request); 238 int opResult; 239 if (request->transfer_type == USB_TRANSFER_CONTROL) { 240 usb_log_info("Root hub got CONTROL packet\n"); 241 opResult = process_ctrl_request(instance, request); 242 } else if (request->transfer_type == USB_TRANSFER_INTERRUPT) { 243 usb_log_info("Root hub got INTERRUPT packet\n"); 244 void * buffer; 245 create_interrupt_mask(instance, &buffer, 246 &(request->transfered_size)); 247 memcpy(request->transport_buffer, buffer, 248 request->transfered_size); 249 opResult = EOK; 250 } else { 251 opResult = EINVAL; 252 } 253 usb_transfer_batch_finish_error(request, opResult); 254 return EOK; 255 } 256 257 /*----------------------------------------------------------------------------*/ 258 259 260 void rh_interrupt(rh_t *instance) { 261 usb_log_info("Whoa whoa wait, I`m not supposed to receive any " 262 "interrupts, am I?\n"); 263 /* TODO: implement? */ 264 } 265 /*----------------------------------------------------------------------------*/ 147 266 148 267 /** … … 157 276 */ 158 277 static void usb_create_serialized_hub_descriptor(rh_t *instance, 159 160 278 uint8_t ** out_result, 279 size_t * out_size) { 161 280 //base size 162 281 size_t size = 7; 163 282 //variable size according to port count 164 283 size_t var_size = instance->port_count / 8 + 165 284 ((instance->port_count % 8 > 0) ? 1 : 0); 166 285 size += 2 * var_size; 167 286 uint8_t * result = (uint8_t*) malloc(size); 168 bzero(result, size);287 bzero(result, size); 169 288 //size 170 289 result[0] = size; … … 174 293 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 175 294 result[3] = 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);295 ((hub_desc_reg >> 8) % 2) + 296 (((hub_desc_reg >> 9) % 2) << 1) + 297 (((hub_desc_reg >> 10) % 2) << 2) + 298 (((hub_desc_reg >> 11) % 2) << 3) + 299 (((hub_desc_reg >> 12) % 2) << 4); 181 300 result[4] = 0; 182 301 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; … … 185 304 int port; 186 305 for (port = 1; port <= instance->port_count; ++port) { 187 result[7 + port/8] += 188 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 306 uint8_t is_non_removable = 307 instance->registers->rh_desc_b >> port % 2; 308 result[7 + port / 8] += 309 is_non_removable << (port % 8); 189 310 } 190 311 size_t i; … … 195 316 (*out_size) = size; 196 317 } 197 318 /*----------------------------------------------------------------------------*/ 198 319 199 320 /** initialize hub descriptors … … 203 324 * @instance root hub instance 204 325 */ 205 static void rh_init_descriptors(rh_t *instance) {326 static void rh_init_descriptors(rh_t *instance) { 206 327 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 207 sizeof (ohci_rh_device_descriptor)208 );328 sizeof (ohci_rh_device_descriptor) 329 ); 209 330 usb_standard_configuration_descriptor_t descriptor; 210 memcpy(&descriptor, &ohci_rh_conf_descriptor,211 sizeof(ohci_rh_conf_descriptor));331 memcpy(&descriptor, &ohci_rh_conf_descriptor, 332 sizeof (ohci_rh_conf_descriptor)); 212 333 uint8_t * hub_descriptor; 213 334 size_t hub_desc_size; 214 335 usb_create_serialized_hub_descriptor(instance, &hub_descriptor, 215 336 &hub_desc_size); 216 337 217 338 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 222 339 sizeof (usb_standard_configuration_descriptor_t) + 340 sizeof (usb_standard_endpoint_descriptor_t) + 341 sizeof (usb_standard_interface_descriptor_t) + 342 hub_desc_size; 343 223 344 uint8_t * full_config_descriptor = 224 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 235 345 (uint8_t*) malloc(descriptor.total_length); 346 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 347 memcpy(full_config_descriptor + sizeof (descriptor), 348 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor)); 349 memcpy(full_config_descriptor + sizeof (descriptor) + 350 sizeof (ohci_rh_iface_descriptor), 351 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor)); 352 memcpy(full_config_descriptor + sizeof (descriptor) + 353 sizeof (ohci_rh_iface_descriptor) + 354 sizeof (ohci_rh_ep_descriptor), 355 hub_descriptor, hub_desc_size); 356 236 357 instance->descriptors.configuration = full_config_descriptor; 237 358 instance->descriptors.configuration_size = descriptor.total_length; 238 359 } 239 240 /** Root hub initialization241 * @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 mode252 253 254 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);255 256 //start generic usb hub driver257 258 /* TODO: implement */259 return EOK;260 }261 360 /*----------------------------------------------------------------------------*/ 262 361 … … 272 371 */ 273 372 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;373 usb_transfer_batch_t * request) { 374 if (port < 1 || port > instance->port_count) 375 return EINVAL; 376 uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer; 278 377 request->transfered_size = 4; 279 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 280 return EOK; 281 } 378 uint32_buffer[0] = instance->registers->rh_port_status[port - 1]; 379 #if 0 380 int i; 381 for (i = 0; i < instance->port_count; ++i) { 382 usb_log_debug("port status %d,x%x\n", 383 instance->registers->rh_port_status[i], 384 instance->registers->rh_port_status[i]); 385 } 386 #endif 387 return EOK; 388 } 389 /*----------------------------------------------------------------------------*/ 282 390 283 391 /** … … 291 399 */ 292 400 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; 401 usb_transfer_batch_t * request) { 402 uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer; 403 request->transfered_size = 4; 295 404 //bits, 0,1,16,17 296 request->transfered_size = 4; 297 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 405 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 298 406 uint32_buffer[0] = mask & instance->registers->rh_status; 299 407 return EOK; 300 301 } 302 303 408 } 409 /*----------------------------------------------------------------------------*/ 304 410 305 411 /** … … 313 419 */ 314 420 static int process_get_status_request(rh_t *instance, 315 usb_transfer_batch_t * request) 316 { 421 usb_transfer_batch_t * request) { 317 422 size_t buffer_size = request->buffer_size; 318 423 usb_device_request_setup_packet_t * request_packet = 319 320 424 (usb_device_request_setup_packet_t*) 425 request->setup_buffer; 321 426 322 427 usb_hub_bm_request_type_t request_type = request_packet->request_type; 323 if (buffer_size<4/*request_packet->length*/){///\TODO428 if (buffer_size < 4/*request_packet->length*/) {///\TODO 324 429 usb_log_warning("requested more data than buffer size\n"); 325 430 return EINVAL; 326 431 } 327 432 328 if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)433 if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 329 434 return process_get_hub_status_request(instance, 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); 435 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 436 return process_get_port_status_request(instance, 437 request_packet->index, 438 request); 333 439 return ENOTSUP; 334 440 } 441 /*----------------------------------------------------------------------------*/ 335 442 336 443 /** … … 339 446 * Result contains bitmap where bit 0 indicates change on hub and 340 447 * bit i indicates change on i`th port (i>0). For more info see 341 * Hub and Port status bitmap specification in USB specification. 448 * Hub and Port status bitmap specification in USB specification 449 * (chapter 11.13.4) 342 450 * @param instance root hub instance 343 451 * @param@out buffer pointer to created interrupt mas … … 345 453 */ 346 454 static void create_interrupt_mask(rh_t *instance, void ** buffer, 347 size_t * buffer_size){455 size_t * buffer_size) { 348 456 int bit_count = instance->port_count + 1; 349 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 457 (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1); 458 350 459 (*buffer) = malloc(*buffer_size); 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){ 460 uint8_t * bitmap = (uint8_t*) (*buffer); 461 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 462 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 463 bzero(bitmap, (*buffer_size)); 464 if (instance->registers->rh_status & mask) { 355 465 bitmap[0] = 1; 356 466 } 357 467 int port; 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 468 mask = port_status_change_mask; 469 for (port = 1; port <= instance->port_count; ++port) { 470 if (mask & instance->registers->rh_port_status[port - 1]) { 471 bitmap[(port) / 8] += 1 << (port % 8); 472 } 473 } 474 } 475 /*----------------------------------------------------------------------------*/ 476 369 477 /** 370 478 * create answer to a descriptor request … … 377 485 */ 378 486 static int process_get_descriptor_request(rh_t *instance, 379 usb_transfer_batch_t *request){487 usb_transfer_batch_t *request) { 380 488 usb_device_request_setup_packet_t * setup_request = 381 (usb_device_request_setup_packet_t*)request->setup_buffer;489 (usb_device_request_setup_packet_t*) request->setup_buffer; 382 490 size_t size; 383 491 const void * result_descriptor = NULL; 384 492 const uint16_t setup_request_value = setup_request->value_high; 385 493 //(setup_request->value_low << 8); 386 494 bool del = false; 387 switch (setup_request_value) 388 {389 case USB_DESCTYPE_HUB:{495 switch (setup_request_value) { 496 case USB_DESCTYPE_HUB: 497 { 390 498 uint8_t * descriptor; 391 499 usb_create_serialized_hub_descriptor( 392 500 instance, &descriptor, &size); 393 501 result_descriptor = descriptor; 394 if (result_descriptor) del = true;502 if (result_descriptor) del = true; 395 503 break; 396 504 } 397 case USB_DESCTYPE_DEVICE: { 505 case USB_DESCTYPE_DEVICE: 506 { 398 507 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 399 508 result_descriptor = &ohci_rh_device_descriptor; 400 size = sizeof (ohci_rh_device_descriptor);509 size = sizeof (ohci_rh_device_descriptor); 401 510 break; 402 511 } 403 case USB_DESCTYPE_CONFIGURATION: { 512 case USB_DESCTYPE_CONFIGURATION: 513 { 404 514 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 405 515 result_descriptor = instance->descriptors.configuration; … … 407 517 break; 408 518 } 409 case USB_DESCTYPE_INTERFACE: { 519 case USB_DESCTYPE_INTERFACE: 520 { 410 521 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 411 522 result_descriptor = &ohci_rh_iface_descriptor; 412 size = sizeof (ohci_rh_iface_descriptor);523 size = sizeof (ohci_rh_iface_descriptor); 413 524 break; 414 525 } 415 case USB_DESCTYPE_ENDPOINT: { 526 case USB_DESCTYPE_ENDPOINT: 527 { 416 528 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 417 529 result_descriptor = &ohci_rh_ep_descriptor; 418 size = sizeof (ohci_rh_ep_descriptor);530 size = sizeof (ohci_rh_ep_descriptor); 419 531 break; 420 532 } 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 ); 533 default: 534 { 535 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 536 setup_request->value); 537 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 538 "%d\n\tindex %d\n\tlen %d\n ", 539 setup_request->request_type, 540 setup_request->request, 541 setup_request_value, 542 setup_request->index, 543 setup_request->length 544 ); 430 545 return EINVAL; 431 546 } 432 547 } 433 if (request->buffer_size < size){548 if (request->buffer_size < size) { 434 549 size = request->buffer_size; 435 550 } 436 551 request->transfered_size = 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)); 552 memcpy(request->transport_buffer, result_descriptor, size); 440 553 if (del) 441 554 free(result_descriptor); 442 555 return EOK; 443 556 } 557 /*----------------------------------------------------------------------------*/ 444 558 445 559 /** … … 451 565 * @return error code 452 566 */ 453 static int process_get_configuration_request(rh_t *instance, 454 usb_transfer_batch_t *request){567 static int process_get_configuration_request(rh_t *instance, 568 usb_transfer_batch_t *request) { 455 569 //set and get configuration requests do not have any meaning, only dummy 456 570 //values are returned 457 if (request->buffer_size != 1)571 if (request->buffer_size != 1) 458 572 return EINVAL; 459 573 request->transport_buffer[0] = 1; … … 461 575 return EOK; 462 576 } 577 /*----------------------------------------------------------------------------*/ 463 578 464 579 /** 465 580 * process feature-enabling request on hub 466 * 581 * 467 582 * @param instance root hub instance 468 583 * @param feature feature selector … … 470 585 */ 471 586 static int process_hub_feature_set_request(rh_t *instance, 472 uint16_t feature){ 473 if(! ((1<<feature) & hub_set_feature_valid_mask)) 474 return EINVAL; 587 uint16_t feature) { 588 if (!((1 << feature) & hub_set_feature_valid_mask)) 589 return EINVAL; 590 if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 591 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 475 592 instance->registers->rh_status = 476 (instance->registers->rh_status | (1<<feature)) 477 & (~ hub_clear_feature_by_writing_one_mask); 478 return EOK; 479 } 593 (instance->registers->rh_status | (1 << feature)) 594 & (~hub_clear_feature_by_writing_one_mask); 595 return EOK; 596 } 597 /*----------------------------------------------------------------------------*/ 480 598 481 599 /** … … 487 605 */ 488 606 static int process_hub_feature_clear_request(rh_t *instance, 489 uint16_t feature){490 if (! ((1<<feature) & hub_clear_feature_valid_mask))607 uint16_t feature) { 608 if (!((1 << feature) & hub_clear_feature_valid_mask)) 491 609 return EINVAL; 492 610 //is the feature cleared directly? 493 if ((1 <<feature) & hub_set_feature_direct_mask){611 if ((1 << feature) & hub_set_feature_direct_mask) { 494 612 instance->registers->rh_status = 495 (instance->registers->rh_status & (~(1 <<feature)))496 & (~ 497 } else{//the feature is cleared by writing '1'613 (instance->registers->rh_status & (~(1 << feature))) 614 & (~hub_clear_feature_by_writing_one_mask); 615 } else {//the feature is cleared by writing '1' 498 616 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 617 (instance->registers->rh_status 618 & (~hub_clear_feature_by_writing_one_mask)) 619 | (1 << feature); 620 } 621 return EOK; 622 } 623 /*----------------------------------------------------------------------------*/ 507 624 508 625 /** 509 626 * process feature-enabling request on hub 510 * 627 * 511 628 * @param instance root hub instance 512 629 * @param feature feature selector … … 516 633 */ 517 634 static int process_port_feature_set_request(rh_t *instance, 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 uint16_t feature, uint16_t port) { 636 if (!((1 << feature) & port_set_feature_valid_mask)) 637 return EINVAL; 638 if (port < 1 || port > instance->port_count) 522 639 return EINVAL; 523 640 instance->registers->rh_port_status[port - 1] = 524 (instance->registers->rh_port_status[port - 1] | (1<<feature))525 641 (instance->registers->rh_port_status[port - 1] | (1 << feature)) 642 & (~port_clear_feature_valid_mask); 526 643 /// \TODO any error? 527 644 return EOK; 528 645 } 646 /*----------------------------------------------------------------------------*/ 529 647 530 648 /** … … 538 656 */ 539 657 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)658 uint16_t feature, uint16_t port) { 659 if (!((1 << feature) & port_clear_feature_valid_mask)) 660 return EINVAL; 661 if (port < 1 || port > instance->port_count) 662 return EINVAL; 663 if (feature == USB_HUB_FEATURE_PORT_POWER) 546 664 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 547 if (feature == USB_HUB_FEATURE_PORT_SUSPEND)665 if (feature == USB_HUB_FEATURE_PORT_SUSPEND) 548 666 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 549 667 instance->registers->rh_port_status[port - 1] = 550 (instance->registers->rh_port_status[port - 1]551 552 | (1<<feature);668 (instance->registers->rh_port_status[port - 1] 669 & (~port_clear_feature_valid_mask)) 670 | (1 << feature); 553 671 /// \TODO any error? 554 672 return EOK; 555 673 } 556 674 /*----------------------------------------------------------------------------*/ 557 675 558 676 /** 559 677 * register address to this device 560 * 678 * 561 679 * @param instance root hub instance 562 680 * @param address new address … … 564 682 */ 565 683 static int process_address_set_request(rh_t *instance, 566 uint16_t address){684 uint16_t address) { 567 685 instance->address = address; 568 686 return EOK; 569 687 } 688 /*----------------------------------------------------------------------------*/ 570 689 571 690 /** … … 579 698 */ 580 699 static int process_request_with_output(rh_t *instance, 581 usb_transfer_batch_t *request){700 usb_transfer_batch_t *request) { 582 701 usb_device_request_setup_packet_t * setup_request = 583 (usb_device_request_setup_packet_t*)request->setup_buffer;584 if (setup_request->request == USB_DEVREQ_GET_STATUS){702 (usb_device_request_setup_packet_t*) request->setup_buffer; 703 if (setup_request->request == USB_DEVREQ_GET_STATUS) { 585 704 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 586 705 return process_get_status_request(instance, request); 587 706 } 588 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){707 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) { 589 708 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 590 709 return process_get_descriptor_request(instance, request); 591 710 } 592 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION){711 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) { 593 712 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 594 713 return process_get_configuration_request(instance, request); … … 596 715 return ENOTSUP; 597 716 } 717 /*----------------------------------------------------------------------------*/ 598 718 599 719 /** … … 607 727 */ 608 728 static int process_request_with_input(rh_t *instance, 609 usb_transfer_batch_t *request){729 usb_transfer_batch_t *request) { 610 730 usb_device_request_setup_packet_t * setup_request = 611 (usb_device_request_setup_packet_t*)request->setup_buffer;731 (usb_device_request_setup_packet_t*) request->setup_buffer; 612 732 request->transfered_size = 0; 613 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){733 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) { 614 734 return ENOTSUP; 615 735 } 616 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION){736 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) { 617 737 //set and get configuration requests do not have any meaning, 618 738 //only dummy values are returned … … 621 741 return ENOTSUP; 622 742 } 743 /*----------------------------------------------------------------------------*/ 623 744 624 745 /** … … 632 753 */ 633 754 static int process_request_without_data(rh_t *instance, 634 usb_transfer_batch_t *request){755 usb_transfer_batch_t *request) { 635 756 usb_device_request_setup_packet_t * setup_request = 636 (usb_device_request_setup_packet_t*)request->setup_buffer;757 (usb_device_request_setup_packet_t*) request->setup_buffer; 637 758 request->transfered_size = 0; 638 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE){639 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){759 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) { 760 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 640 761 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 641 762 return process_hub_feature_clear_request(instance, 642 643 } 644 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){763 setup_request->value); 764 } 765 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 645 766 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 646 767 return process_port_feature_clear_request(instance, 647 648 768 setup_request->value, 769 setup_request->index); 649 770 } 650 771 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 651 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){772 setup_request->request_type); 773 return EINVAL; 774 } 775 if (setup_request->request == USB_DEVREQ_SET_FEATURE) { 776 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) { 656 777 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 657 778 return process_hub_feature_set_request(instance, 658 659 } 660 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){779 setup_request->value); 780 } 781 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) { 661 782 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 662 783 return process_port_feature_set_request(instance, 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){ 784 setup_request->value, 785 setup_request->index); 786 } 787 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 788 setup_request->request_type); 789 return EINVAL; 790 } 791 if (setup_request->request == USB_DEVREQ_SET_ADDRESS) { 670 792 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 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); 793 return process_address_set_request(instance, 794 setup_request->value); 795 } 796 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 797 setup_request->request_type); 674 798 return ENOTSUP; 675 799 } 800 /*----------------------------------------------------------------------------*/ 676 801 677 802 /** … … 693 818 * @return error code 694 819 */ 695 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){ 820 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) { 821 if (!request->setup_buffer) { 822 usb_log_error("root hub received empty transaction?"); 823 return EINVAL; 824 } 696 825 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 705 (usb_device_request_setup_packet_t*)request->setup_buffer;706 if(707 setup_request->request == USB_DEVREQ_GET_STATUS708 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR709 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION710 ){826 if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) { 827 usb_log_error("setup packet too small\n"); 828 return EINVAL; 829 } 830 usb_log_info("CTRL packet: %s.\n", 831 usb_debug_str_buffer( 832 (const uint8_t *) request->setup_buffer, 8, 8)); 833 usb_device_request_setup_packet_t * setup_request = 834 (usb_device_request_setup_packet_t*) 835 request->setup_buffer; 836 switch (setup_request->request) { 837 case USB_DEVREQ_GET_STATUS: 838 case USB_DEVREQ_GET_DESCRIPTOR: 839 case USB_DEVREQ_GET_CONFIGURATION: 711 840 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 ); 841 opResult = process_request_with_output( 842 instance, request); 843 break; 844 case USB_DEVREQ_CLEAR_FEATURE: 845 case USB_DEVREQ_SET_FEATURE: 846 case USB_DEVREQ_SET_ADDRESS: 847 usb_log_debug("processing request without " 848 "additional data\n"); 849 opResult = process_request_without_data( 850 instance, request); 851 break; 852 case USB_DEVREQ_SET_DESCRIPTOR: 853 case USB_DEVREQ_SET_CONFIGURATION: 854 usb_log_debug("processing request with " 855 "input\n"); 856 opResult = process_request_with_input( 857 instance, request); 858 break; 859 default: 860 usb_log_warning("received unsuported request: " 861 "%d\n", 862 setup_request->request 863 ); 729 864 opResult = ENOTSUP; 730 }731 }else{732 usb_log_error("root hub received empty transaction?");733 opResult = EINVAL;734 865 } 735 866 return opResult; … … 737 868 738 869 /** 739 * process root hub request740 *741 * @param instance root hub instance742 * @param request structure containing both request and response information743 * @return error code744 */745 int rh_request(rh_t *instance, usb_transfer_batch_t *request)746 {747 assert(instance);748 assert(request);749 int opResult;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 }774 /**775 870 * @} 776 871 */
Note:
See TracChangeset
for help on using the changeset viewer.