Changes in uspace/drv/ohci/root_hub.c [be11749:ccbcd895] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
rbe11749 rccbcd895 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 = … … 115 119 116 120 static const uint32_t hub_set_feature_valid_mask = 117 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) | 118 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 119 120 121 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 122 123 121 124 static const uint32_t hub_set_feature_direct_mask = 122 125 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT); 123 126 124 127 static const uint32_t port_set_feature_valid_mask = 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);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); 129 132 130 133 static const uint32_t port_clear_feature_valid_mask = 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 static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request, 201 void * change_buffer, size_t buffe_size); 202 203 static bool is_zeros(void * buffer, size_t size); 204 205 206 207 /** Root hub initialization 208 * @return Error code. 209 */ 210 int rh_init(rh_t *instance, ohci_regs_t *regs) { 211 assert(instance); 212 instance->registers = regs; 213 instance->port_count = 214 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 215 rh_init_descriptors(instance); 216 // set port power mode to no-power-switching 217 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 218 instance->unfinished_interrupt_transfer = NULL; 219 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 220 return EOK; 221 } 222 /*----------------------------------------------------------------------------*/ 223 224 /** 225 * process root hub request 226 * 227 * @param instance root hub instance 228 * @param request structure containing both request and response information 229 * @return error code 230 */ 231 int rh_request(rh_t *instance, usb_transfer_batch_t *request) { 232 assert(instance); 233 assert(request); 234 int opResult; 235 if (request->ep->transfer_type == USB_TRANSFER_CONTROL) { 236 usb_log_info("Root hub got CONTROL packet\n"); 237 opResult = process_ctrl_request(instance, request); 238 usb_transfer_batch_finish_error(request, opResult); 239 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) { 240 usb_log_info("Root hub got INTERRUPT packet\n"); 241 void * buffer; 242 size_t buffer_size; 243 create_interrupt_mask(instance, &buffer, 244 &buffer_size); 245 if(is_zeros(buffer,buffer_size)){ 246 usb_log_debug("no changes.."); 247 instance->unfinished_interrupt_transfer= 248 request; 249 //will be finished later 250 }else{ 251 usb_log_debug("processing changes.."); 252 process_interrupt(instance, request, 253 buffer, buffer_size); 254 } 255 free(buffer); 256 opResult = EOK; 257 } else { 258 opResult = EINVAL; 259 usb_transfer_batch_finish_error(request, opResult); 260 } 261 return EOK; 262 } 263 264 /*----------------------------------------------------------------------------*/ 265 266 267 void rh_interrupt(rh_t *instance) { 268 //usb_log_info("Whoa whoa wait, I`m not supposed to receive any " 269 // "interrupts, am I?\n"); 270 if(!instance->unfinished_interrupt_transfer){ 271 return; 272 } 273 size_t size; 274 void * buffer; 275 create_interrupt_mask(instance, &buffer, 276 &size); 277 process_interrupt(instance,instance->unfinished_interrupt_transfer, 278 buffer,size); 279 free(buffer); 280 } 281 /*----------------------------------------------------------------------------*/ 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 282 147 283 148 /** … … 292 157 */ 293 158 static void usb_create_serialized_hub_descriptor(rh_t *instance, 294 uint8_t ** out_result,295 size_t * out_size) {159 uint8_t ** out_result, 160 size_t * out_size) { 296 161 //base size 297 162 size_t size = 7; 298 163 //variable size according to port count 299 164 size_t var_size = instance->port_count / 8 + 300 ((instance->port_count % 8 > 0) ? 1 : 0);165 ((instance->port_count % 8 > 0) ? 1 : 0); 301 166 size += 2 * var_size; 302 167 uint8_t * result = (uint8_t*) malloc(size); 303 bzero(result, 168 bzero(result,size); 304 169 //size 305 170 result[0] = size; … … 309 174 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 310 175 result[3] = 311 ((hub_desc_reg >> 8) %2) +312 (((hub_desc_reg >> 9) %2) << 1) +313 (((hub_desc_reg >> 10) %2) << 2) +314 (((hub_desc_reg >> 11) %2) << 3) +315 (((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); 316 181 result[4] = 0; 317 182 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; … … 320 185 int port; 321 186 for (port = 1; port <= instance->port_count; ++port) { 322 uint8_t is_non_removable = 323 instance->registers->rh_desc_b >> port % 2; 324 result[7 + port / 8] += 325 is_non_removable << (port % 8); 187 result[7 + port/8] += 188 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 326 189 } 327 190 size_t i; … … 332 195 (*out_size) = size; 333 196 } 334 /*----------------------------------------------------------------------------*/ 197 335 198 336 199 /** initialize hub descriptors … … 340 203 * @instance root hub instance 341 204 */ 342 static void rh_init_descriptors(rh_t *instance) 205 static void rh_init_descriptors(rh_t *instance){ 343 206 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 344 sizeof 345 207 sizeof(ohci_rh_device_descriptor) 208 ); 346 209 usb_standard_configuration_descriptor_t descriptor; 347 memcpy(&descriptor, 348 sizeof(ohci_rh_conf_descriptor));210 memcpy(&descriptor,&ohci_rh_conf_descriptor, 211 sizeof(ohci_rh_conf_descriptor)); 349 212 uint8_t * hub_descriptor; 350 213 size_t hub_desc_size; 351 214 usb_create_serialized_hub_descriptor(instance, &hub_descriptor, 352 &hub_desc_size);215 &hub_desc_size); 353 216 354 217 descriptor.total_length = 355 sizeof (usb_standard_configuration_descriptor_t)+356 sizeof (usb_standard_endpoint_descriptor_t)+357 sizeof (usb_standard_interface_descriptor_t)+358 hub_desc_size;359 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 360 223 uint8_t * full_config_descriptor = 361 (uint8_t*) malloc(descriptor.total_length);362 memcpy(full_config_descriptor, &descriptor, sizeof 363 memcpy(full_config_descriptor + sizeof 364 &ohci_rh_iface_descriptor, sizeof(ohci_rh_iface_descriptor));365 memcpy(full_config_descriptor + sizeof 366 sizeof(ohci_rh_iface_descriptor),367 &ohci_rh_ep_descriptor, sizeof(ohci_rh_ep_descriptor));368 memcpy(full_config_descriptor + sizeof 369 sizeof(ohci_rh_iface_descriptor) +370 sizeof(ohci_rh_ep_descriptor),371 hub_descriptor, hub_desc_size);372 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 373 236 instance->descriptors.configuration = full_config_descriptor; 374 237 instance->descriptors.configuration_size = descriptor.total_length; 375 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 } 376 261 /*----------------------------------------------------------------------------*/ 377 262 … … 387 272 */ 388 273 static int process_get_port_status_request(rh_t *instance, uint16_t port, 389 usb_transfer_batch_t * request){390 if (port < 1 || port >instance->port_count)391 return EINVAL; 392 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer;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; 393 278 request->transfered_size = 4; 394 uint32_buffer[0] = instance->registers->rh_port_status[port - 1]; 395 #if 0 396 int i; 397 for (i = 0; i < instance->port_count; ++i) { 398 usb_log_debug("port status %d,x%x\n", 399 instance->registers->rh_port_status[i], 400 instance->registers->rh_port_status[i]); 401 } 402 #endif 403 return EOK; 404 } 405 /*----------------------------------------------------------------------------*/ 279 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 280 return EOK; 281 } 406 282 407 283 /** … … 415 291 */ 416 292 static int process_get_hub_status_request(rh_t *instance, 417 usb_transfer_batch_t * request) { 418 uint32_t * uint32_buffer = (uint32_t*) request->data_buffer; 293 usb_transfer_batch_t * request){ 294 uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer; 295 //bits, 0,1,16,17 419 296 request->transfered_size = 4; 420 //bits, 0,1,16,17 421 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17); 297 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 422 298 uint32_buffer[0] = mask & instance->registers->rh_status; 423 299 return EOK; 424 } 425 /*----------------------------------------------------------------------------*/ 300 301 } 302 303 426 304 427 305 /** … … 435 313 */ 436 314 static int process_get_status_request(rh_t *instance, 437 usb_transfer_batch_t * request) { 315 usb_transfer_batch_t * request) 316 { 438 317 size_t buffer_size = request->buffer_size; 439 318 usb_device_request_setup_packet_t * request_packet = 440 (usb_device_request_setup_packet_t*)441 request->setup_buffer;319 (usb_device_request_setup_packet_t*) 320 request->setup_buffer; 442 321 443 322 usb_hub_bm_request_type_t request_type = request_packet->request_type; 444 if (buffer_size < 4/*request_packet->length*/){///\TODO323 if(buffer_size<4/*request_packet->length*/){///\TODO 445 324 usb_log_warning("requested more data than buffer size\n"); 446 325 return EINVAL; 447 326 } 448 327 449 if 328 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 450 329 return process_get_hub_status_request(instance, request); 451 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 452 return process_get_port_status_request(instance, 453 request_packet->index, 454 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); 455 333 return ENOTSUP; 456 334 } 457 /*----------------------------------------------------------------------------*/458 335 459 336 /** … … 462 339 * Result contains bitmap where bit 0 indicates change on hub and 463 340 * bit i indicates change on i`th port (i>0). For more info see 464 * Hub and Port status bitmap specification in USB specification 465 * (chapter 11.13.4) 341 * Hub and Port status bitmap specification in USB specification. 466 342 * @param instance root hub instance 467 343 * @param@out buffer pointer to created interrupt mas … … 469 345 */ 470 346 static void create_interrupt_mask(rh_t *instance, void ** buffer, 471 size_t * buffer_size){347 size_t * buffer_size){ 472 348 int bit_count = instance->port_count + 1; 473 (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1); 474 349 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 475 350 (*buffer) = malloc(*buffer_size); 476 uint8_t * bitmap = (uint8_t*) (*buffer); 477 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 478 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 479 bzero(bitmap, (*buffer_size)); 480 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){ 481 355 bitmap[0] = 1; 482 356 } 483 357 int port; 484 mask = port_status_change_mask; 485 for (port = 1; port <= instance->port_count; ++port) { 486 if (mask & instance->registers->rh_port_status[port - 1]) { 487 bitmap[(port) / 8] += 1 << (port % 8); 488 } 489 } 490 } 491 /*----------------------------------------------------------------------------*/ 492 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 493 369 /** 494 370 * create answer to a descriptor request … … 501 377 */ 502 378 static int process_get_descriptor_request(rh_t *instance, 503 usb_transfer_batch_t *request){379 usb_transfer_batch_t *request){ 504 380 usb_device_request_setup_packet_t * setup_request = 505 (usb_device_request_setup_packet_t*)request->setup_buffer;381 (usb_device_request_setup_packet_t*)request->setup_buffer; 506 382 size_t size; 507 383 const void * result_descriptor = NULL; 508 384 const uint16_t setup_request_value = setup_request->value_high; 509 //(setup_request->value_low << 8);385 //(setup_request->value_low << 8); 510 386 bool del = false; 511 switch (setup_request_value) {512 case USB_DESCTYPE_HUB:513 {387 switch (setup_request_value) 388 { 389 case USB_DESCTYPE_HUB: { 514 390 uint8_t * descriptor; 515 391 usb_create_serialized_hub_descriptor( 516 392 instance, &descriptor, &size); 517 393 result_descriptor = descriptor; 518 if 394 if(result_descriptor) del = true; 519 395 break; 520 396 } 521 case USB_DESCTYPE_DEVICE: 522 { 397 case USB_DESCTYPE_DEVICE: { 523 398 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 524 399 result_descriptor = &ohci_rh_device_descriptor; 525 size = sizeof 400 size = sizeof(ohci_rh_device_descriptor); 526 401 break; 527 402 } 528 case USB_DESCTYPE_CONFIGURATION: 529 { 403 case USB_DESCTYPE_CONFIGURATION: { 530 404 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 531 405 result_descriptor = instance->descriptors.configuration; … … 533 407 break; 534 408 } 535 case USB_DESCTYPE_INTERFACE: 536 { 409 case USB_DESCTYPE_INTERFACE: { 537 410 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 538 411 result_descriptor = &ohci_rh_iface_descriptor; 539 size = sizeof 412 size = sizeof(ohci_rh_iface_descriptor); 540 413 break; 541 414 } 542 case USB_DESCTYPE_ENDPOINT: 543 { 415 case USB_DESCTYPE_ENDPOINT: { 544 416 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 545 417 result_descriptor = &ohci_rh_ep_descriptor; 546 size = sizeof 418 size = sizeof(ohci_rh_ep_descriptor); 547 419 break; 548 420 } 549 default: 550 { 551 usb_log_debug("USB_DESCTYPE_EINVAL %d \n", 552 setup_request->value); 553 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue " 554 "%d\n\tindex %d\n\tlen %d\n ", 555 setup_request->request_type, 556 setup_request->request, 557 setup_request_value, 558 setup_request->index, 559 setup_request->length 560 ); 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 ); 561 430 return EINVAL; 562 431 } 563 432 } 564 if (request->buffer_size < size){433 if(request->buffer_size < size){ 565 434 size = request->buffer_size; 566 435 } 567 436 request->transfered_size = size; 568 memcpy(request->data_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)); 569 440 if (del) 570 441 free(result_descriptor); 571 442 return EOK; 572 443 } 573 /*----------------------------------------------------------------------------*/574 444 575 445 /** … … 581 451 * @return error code 582 452 */ 583 static int process_get_configuration_request(rh_t *instance, 584 usb_transfer_batch_t *request){453 static int process_get_configuration_request(rh_t *instance, 454 usb_transfer_batch_t *request){ 585 455 //set and get configuration requests do not have any meaning, only dummy 586 456 //values are returned 587 if 588 return EINVAL; 589 request-> data_buffer[0] = 1;457 if(request->buffer_size != 1) 458 return EINVAL; 459 request->transport_buffer[0] = 1; 590 460 request->transfered_size = 1; 591 461 return EOK; 592 462 } 593 /*----------------------------------------------------------------------------*/594 463 595 464 /** 596 465 * process feature-enabling request on hub 597 * 466 * 598 467 * @param instance root hub instance 599 468 * @param feature feature selector … … 601 470 */ 602 471 static int process_hub_feature_set_request(rh_t *instance, 603 uint16_t feature) { 604 if (!((1 << feature) & hub_set_feature_valid_mask)) 605 return EINVAL; 606 if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER) 607 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16; 472 uint16_t feature){ 473 if(! ((1<<feature) & hub_set_feature_valid_mask)) 474 return EINVAL; 608 475 instance->registers->rh_status = 609 (instance->registers->rh_status | (1 << feature)) 610 & (~hub_clear_feature_by_writing_one_mask); 611 return EOK; 612 } 613 /*----------------------------------------------------------------------------*/ 476 (instance->registers->rh_status | (1<<feature)) 477 & (~ hub_clear_feature_by_writing_one_mask); 478 return EOK; 479 } 614 480 615 481 /** … … 621 487 */ 622 488 static int process_hub_feature_clear_request(rh_t *instance, 623 uint16_t feature){624 if (!((1 <<feature) & hub_clear_feature_valid_mask))489 uint16_t feature){ 490 if(! ((1<<feature) & hub_clear_feature_valid_mask)) 625 491 return EINVAL; 626 492 //is the feature cleared directly? 627 if ((1 << feature) & hub_set_feature_direct_mask){493 if ((1<<feature) & hub_set_feature_direct_mask){ 628 494 instance->registers->rh_status = 629 (instance->registers->rh_status & (~(1 <<feature)))630 & (~ hub_clear_feature_by_writing_one_mask);631 } 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' 632 498 instance->registers->rh_status = 633 (instance->registers->rh_status 634 & (~hub_clear_feature_by_writing_one_mask)) 635 | (1 << feature); 636 } 637 return EOK; 638 } 639 /*----------------------------------------------------------------------------*/ 499 (instance->registers->rh_status 500 & (~ hub_clear_feature_by_writing_one_mask)) 501 | (1<<feature); 502 } 503 return EOK; 504 } 505 506 640 507 641 508 /** 642 509 * process feature-enabling request on hub 643 * 510 * 644 511 * @param instance root hub instance 645 512 * @param feature feature selector … … 649 516 */ 650 517 static int process_port_feature_set_request(rh_t *instance, 651 uint16_t feature, uint16_t port){652 if (!((1 <<feature) & port_set_feature_valid_mask))653 return EINVAL; 654 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) 655 522 return EINVAL; 656 523 instance->registers->rh_port_status[port - 1] = 657 (instance->registers->rh_port_status[port - 1] | (1 <<feature))658 & (~port_clear_feature_valid_mask);524 (instance->registers->rh_port_status[port - 1] | (1<<feature)) 525 & (~port_clear_feature_valid_mask); 659 526 /// \TODO any error? 660 527 return EOK; 661 528 } 662 /*----------------------------------------------------------------------------*/663 529 664 530 /** … … 672 538 */ 673 539 static int process_port_feature_clear_request(rh_t *instance, 674 uint16_t feature, uint16_t port){675 if (!((1 <<feature) & port_clear_feature_valid_mask))676 return EINVAL; 677 if (port < 1 || port >instance->port_count)678 return EINVAL; 679 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) 680 546 feature = USB_HUB_FEATURE_PORT_LOW_SPEED; 681 if 547 if(feature == USB_HUB_FEATURE_PORT_SUSPEND) 682 548 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT; 683 549 instance->registers->rh_port_status[port - 1] = 684 (instance->registers->rh_port_status[port - 1]685 & (~port_clear_feature_valid_mask))686 | (1 <<feature);550 (instance->registers->rh_port_status[port - 1] 551 & (~port_clear_feature_valid_mask)) 552 | (1<<feature); 687 553 /// \TODO any error? 688 554 return EOK; 689 555 } 690 /*----------------------------------------------------------------------------*/ 556 691 557 692 558 /** 693 559 * register address to this device 694 * 560 * 695 561 * @param instance root hub instance 696 562 * @param address new address … … 698 564 */ 699 565 static int process_address_set_request(rh_t *instance, 700 uint16_t address){566 uint16_t address){ 701 567 instance->address = address; 702 568 return EOK; 703 569 } 704 /*----------------------------------------------------------------------------*/705 570 706 571 /** … … 714 579 */ 715 580 static int process_request_with_output(rh_t *instance, 716 usb_transfer_batch_t *request){581 usb_transfer_batch_t *request){ 717 582 usb_device_request_setup_packet_t * setup_request = 718 (usb_device_request_setup_packet_t*)request->setup_buffer;719 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){ 720 585 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 721 586 return process_get_status_request(instance, request); 722 587 } 723 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){588 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){ 724 589 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 725 590 return process_get_descriptor_request(instance, request); 726 591 } 727 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION){592 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){ 728 593 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 729 594 return process_get_configuration_request(instance, request); … … 731 596 return ENOTSUP; 732 597 } 733 /*----------------------------------------------------------------------------*/734 598 735 599 /** … … 743 607 */ 744 608 static int process_request_with_input(rh_t *instance, 745 usb_transfer_batch_t *request){609 usb_transfer_batch_t *request){ 746 610 usb_device_request_setup_packet_t * setup_request = 747 (usb_device_request_setup_packet_t*)request->setup_buffer;611 (usb_device_request_setup_packet_t*)request->setup_buffer; 748 612 request->transfered_size = 0; 749 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){613 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){ 750 614 return ENOTSUP; 751 615 } 752 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION){616 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){ 753 617 //set and get configuration requests do not have any meaning, 754 618 //only dummy values are returned … … 757 621 return ENOTSUP; 758 622 } 759 /*----------------------------------------------------------------------------*/760 623 761 624 /** … … 769 632 */ 770 633 static int process_request_without_data(rh_t *instance, 771 usb_transfer_batch_t *request){634 usb_transfer_batch_t *request){ 772 635 usb_device_request_setup_packet_t * setup_request = 773 (usb_device_request_setup_packet_t*)request->setup_buffer;636 (usb_device_request_setup_packet_t*)request->setup_buffer; 774 637 request->transfered_size = 0; 775 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE){776 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){ 777 640 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 778 641 return process_hub_feature_clear_request(instance, 779 setup_request->value);780 } 781 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){ 782 645 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 783 646 return process_port_feature_clear_request(instance, 784 setup_request->value,785 setup_request->index);647 setup_request->value, 648 setup_request->index); 786 649 } 787 650 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_FEATURE){792 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){ 793 656 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 794 657 return process_hub_feature_set_request(instance, 795 setup_request->value);796 } 797 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){ 798 661 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 799 662 return process_port_feature_set_request(instance, 800 setup_request->value, 801 setup_request->index); 802 } 803 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n", 804 setup_request->request_type); 805 return EINVAL; 806 } 807 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){ 808 670 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 809 return process_address_set_request(instance, 810 setup_request->value); 811 } 812 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n", 813 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); 814 674 return ENOTSUP; 815 675 } 816 /*----------------------------------------------------------------------------*/817 676 818 677 /** … … 834 693 * @return error code 835 694 */ 836 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) { 837 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{ 838 732 usb_log_error("root hub received empty transaction?"); 839 return EINVAL; 840 } 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); 841 749 int opResult; 842 if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) { 843 usb_log_error("setup packet too small\n"); 844 return EINVAL; 845 } 846 usb_log_info("CTRL packet: %s.\n", 847 usb_debug_str_buffer( 848 (const uint8_t *) request->setup_buffer, 8, 8)); 849 usb_device_request_setup_packet_t * setup_request = 850 (usb_device_request_setup_packet_t*) 851 request->setup_buffer; 852 switch (setup_request->request) { 853 case USB_DEVREQ_GET_STATUS: 854 case USB_DEVREQ_GET_DESCRIPTOR: 855 case USB_DEVREQ_GET_CONFIGURATION: 856 usb_log_debug("processing request with output\n"); 857 opResult = process_request_with_output( 858 instance, request); 859 break; 860 case USB_DEVREQ_CLEAR_FEATURE: 861 case USB_DEVREQ_SET_FEATURE: 862 case USB_DEVREQ_SET_ADDRESS: 863 usb_log_debug("processing request without " 864 "additional data\n"); 865 opResult = process_request_without_data( 866 instance, request); 867 break; 868 case USB_DEVREQ_SET_DESCRIPTOR: 869 case USB_DEVREQ_SET_CONFIGURATION: 870 usb_log_debug("processing request with " 871 "input\n"); 872 opResult = process_request_with_input( 873 instance, request); 874 break; 875 default: 876 usb_log_warning("received unsuported request: " 877 "%d\n", 878 setup_request->request 879 ); 880 opResult = ENOTSUP; 881 } 882 return 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; 883 765 } 884 766 /*----------------------------------------------------------------------------*/ 885 767 886 /** 887 * process hanging interrupt request 888 * 889 * If an interrupt transfer has been received and there was no change, 890 * the driver stores the transfer information and waits for change to occcur. 891 * This routine is called when that happens and it finalizes the interrupt 892 * transfer. 893 * 894 * @param instance hub instance 895 * @param request batch request to be processed 896 * @param change_buffer chages on hub 897 * @param buffer_size size of change buffer 898 * 899 * @return 900 */ 901 static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request, 902 void * change_buffer, size_t buffe_size){ 903 create_interrupt_mask(instance, &change_buffer, 904 &(request->transfered_size)); 905 memcpy(request->data_buffer, change_buffer,request->transfered_size); 906 instance->unfinished_interrupt_transfer = NULL; 907 usb_transfer_batch_finish_error(request, EOK); 908 return EOK; 909 } 910 911 /*----------------------------------------------------------------------------*/ 912 913 /** 914 * return whether the buffer is full of zeros 915 * 916 * Convenience function. 917 * @param buffer 918 * @param size 919 * @return 920 */ 921 static bool is_zeros(void * buffer, size_t size){ 922 if(!buffer) return true; 923 if(!size) return true; 924 size_t i; 925 for(i=0;i<size;++i){ 926 if(((char*)buffer)[i]) 927 return false; 928 } 929 return true; 930 } 931 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 } 932 774 /** 933 775 * @}
Note:
See TracChangeset
for help on using the changeset viewer.