Changes in / [cd4ae1e:a146aa33] in mainline
- Location:
- uspace/drv
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
rcd4ae1e ra146aa33 149 149 150 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); 151 static int create_serialized_hub_descriptor(rh_t *instance); 152 153 static int rh_init_descriptors(rh_t *instance); 156 154 157 155 static int process_get_port_status_request(rh_t *instance, uint16_t port, … … 164 162 usb_transfer_batch_t * request); 165 163 166 static void create_interrupt_mask(rh_t *instance, void ** buffer, 167 size_t * buffer_size); 164 static void create_interrupt_mask_in_instance(rh_t *instance); 168 165 169 166 static int process_get_descriptor_request(rh_t *instance, … … 198 195 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 199 196 200 static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request, 201 void * change_buffer, size_t buffe_size); 197 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request); 202 198 203 199 static bool is_zeros(void * buffer, size_t size); … … 213 209 instance->port_count = 214 210 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 215 rh_init_descriptors(instance); 211 int opResult = rh_init_descriptors(instance); 212 if(opResult != EOK){ 213 return opResult; 214 } 216 215 // set port power mode to no-power-switching 217 216 instance->registers->rh_desc_a |= RHDA_NPS_FLAG; 218 217 instance->unfinished_interrupt_transfer = NULL; 219 instance->interrupt_buffer = malloc((instance->port_count + 8)/8); 218 instance->interrupt_mask_size = (instance->port_count + 8)/8; 219 instance->interrupt_buffer = malloc(instance->interrupt_mask_size); 220 if(!instance->interrupt_buffer) 221 return ENOMEM; 222 223 220 224 usb_log_info("OHCI root hub with %d ports.\n", instance->port_count); 221 225 return EOK; … … 240 244 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) { 241 245 usb_log_info("Root hub got INTERRUPT packet\n"); 242 void * buffer; 243 size_t buffer_size; 244 create_interrupt_mask(instance, &buffer, 245 &buffer_size); 246 if(is_zeros(buffer,buffer_size)){ 247 usb_log_debug("no changes.."); 248 instance->unfinished_interrupt_transfer= 249 request; 246 create_interrupt_mask_in_instance(instance); 247 if(is_zeros(instance->interrupt_buffer, 248 instance->interrupt_mask_size)){ 249 usb_log_debug("no changes..\n"); 250 instance->unfinished_interrupt_transfer = request; 250 251 //will be finished later 251 252 }else{ 252 usb_log_debug("processing changes.."); 253 process_interrupt(instance, request, 254 buffer, buffer_size); 255 } 256 free(buffer); 253 usb_log_debug("processing changes..\n"); 254 process_interrupt_mask_in_instance(instance, request); 255 } 257 256 opResult = EOK; 258 257 } else { … … 265 264 /*----------------------------------------------------------------------------*/ 266 265 267 266 /** 267 * process interrupt on a hub 268 * 269 * If there is no pending interrupt transfer, nothing happens. 270 * @param instance 271 */ 268 272 void rh_interrupt(rh_t *instance) { 269 //usb_log_info("Whoa whoa wait, I`m not supposed to receive any "270 // "interrupts, am I?\n");271 273 if(!instance->unfinished_interrupt_transfer){ 272 274 return; 273 275 } 274 size_t size; 275 void * buffer; 276 create_interrupt_mask(instance, &buffer, 277 &size); 278 process_interrupt(instance,instance->unfinished_interrupt_transfer, 279 buffer,size); 280 free(buffer); 276 usb_log_debug("finalizing interrupt transfer\n"); 277 create_interrupt_mask_in_instance(instance); 278 process_interrupt_mask_in_instance(instance, 279 instance->unfinished_interrupt_transfer); 281 280 } 282 281 /*----------------------------------------------------------------------------*/ … … 289 288 * 290 289 * @param instance root hub instance 291 * @param@out out_result pointer to resultant serialized descriptor 292 * @param@out out_size size of serialized descriptor 293 */ 294 static void usb_create_serialized_hub_descriptor(rh_t *instance, 295 uint8_t ** out_result, 296 size_t * out_size) { 297 //base size 298 size_t size = 7; 299 //variable size according to port count 300 size_t var_size = instance->port_count / 8 + 301 ((instance->port_count % 8 > 0) ? 1 : 0); 302 size += 2 * var_size; 290 * @return error code 291 */ 292 static int create_serialized_hub_descriptor(rh_t *instance) { 293 size_t size = 7 + 294 ((instance->port_count +7 )/ 8) * 2; 295 size_t var_size = (instance->port_count +7 )/ 8; 303 296 uint8_t * result = (uint8_t*) malloc(size); 297 if(!result) return ENOMEM; 298 304 299 bzero(result, size); 305 300 //size … … 330 325 result[7 + var_size + i] = 255; 331 326 } 332 (*out_result) = result; 333 (*out_size) = size; 327 instance->hub_descriptor = result; 328 instance->descriptor_size = size; 329 return EOK; 334 330 } 335 331 /*----------------------------------------------------------------------------*/ … … 340 336 * be initialized only once per hub. 341 337 * @instance root hub instance 342 */ 343 static void rh_init_descriptors(rh_t *instance) { 338 * @return error code 339 */ 340 static int rh_init_descriptors(rh_t *instance) { 344 341 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor, 345 342 sizeof (ohci_rh_device_descriptor) … … 348 345 memcpy(&descriptor, &ohci_rh_conf_descriptor, 349 346 sizeof (ohci_rh_conf_descriptor)); 350 uint8_t * hub_descriptor; 351 size_t hub_desc_size;352 usb_create_serialized_hub_descriptor(instance, &hub_descriptor,353 &hub_desc_size);354 347 348 int opResult = create_serialized_hub_descriptor(instance); 349 if(opResult != EOK){ 350 return opResult; 351 } 355 352 descriptor.total_length = 356 353 sizeof (usb_standard_configuration_descriptor_t) + 357 354 sizeof (usb_standard_endpoint_descriptor_t) + 358 355 sizeof (usb_standard_interface_descriptor_t) + 359 hub_desc_size;356 instance->descriptor_size; 360 357 361 358 uint8_t * full_config_descriptor = 362 359 (uint8_t*) malloc(descriptor.total_length); 360 if(!full_config_descriptor){ 361 return ENOMEM; 362 } 363 363 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor)); 364 364 memcpy(full_config_descriptor + sizeof (descriptor), … … 370 370 sizeof (ohci_rh_iface_descriptor) + 371 371 sizeof (ohci_rh_ep_descriptor), 372 hub_descriptor, hub_desc_size);373 372 instance->hub_descriptor, instance->descriptor_size); 373 374 374 instance->descriptors.configuration = full_config_descriptor; 375 375 instance->descriptors.configuration_size = descriptor.total_length; 376 return EOK; 376 377 } 377 378 /*----------------------------------------------------------------------------*/ … … 464 465 * bit i indicates change on i`th port (i>0). For more info see 465 466 * Hub and Port status bitmap specification in USB specification 466 * (chapter 11.13.4) 467 * @param instance root hub instance 468 * @param@out buffer pointer to created interrupt mas 469 * @param@out buffer_size size of created interrupt mask 470 */ 471 static void create_interrupt_mask(rh_t *instance, void ** buffer, 472 size_t * buffer_size) { 473 int bit_count = instance->port_count + 1; 474 (*buffer_size) = (bit_count+7 / 8); 475 476 (*buffer) = instance->interrupt_buffer;//malloc(*buffer_size); 477 uint8_t * bitmap = (uint8_t*) (*buffer); 467 * (chapter 11.13.4). 468 * Uses instance`s interrupt buffer to store the interrupt information. 469 * @param instance root hub instance 470 */ 471 static void create_interrupt_mask_in_instance(rh_t * instance) { 472 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer); 478 473 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16)) 479 474 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16)); 480 bzero(bitmap, (*buffer_size));475 bzero(bitmap, instance->interrupt_mask_size); 481 476 if (instance->registers->rh_status & mask) { 482 477 bitmap[0] = 1; … … 509 504 const uint16_t setup_request_value = setup_request->value_high; 510 505 //(setup_request->value_low << 8); 511 bool del = false;512 506 switch (setup_request_value) { 513 507 case USB_DESCTYPE_HUB: 514 508 { 515 uint8_t * descriptor; 516 usb_create_serialized_hub_descriptor( 517 instance, &descriptor, &size); 518 result_descriptor = descriptor; 519 if (result_descriptor) del = true; 509 usb_log_debug("USB_DESCTYPE_HUB\n"); 510 result_descriptor = instance->hub_descriptor; 511 size = instance->descriptor_size; 520 512 break; 521 513 } … … 568 560 request->transfered_size = size; 569 561 memcpy(request->data_buffer, result_descriptor, size); 570 if (del)571 free(result_descriptor);572 562 return EOK; 573 563 } … … 895 885 * @param instance hub instance 896 886 * @param request batch request to be processed 897 * @param change_buffer chages on hub898 * @param buffer_size size of change buffer899 887 * 900 888 * @return 901 889 */ 902 static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request, 903 void * change_buffer, size_t buffe_size){ 904 create_interrupt_mask(instance, &change_buffer, 905 &(request->transfered_size)); 906 memcpy(request->data_buffer, change_buffer,request->transfered_size); 890 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request){ 891 memcpy(request->data_buffer, instance->interrupt_buffer, 892 instance->interrupt_mask_size); 893 request->transfered_size = instance->interrupt_mask_size; 907 894 instance->unfinished_interrupt_transfer = NULL; 908 895 usb_transfer_batch_finish_error(request, EOK); -
uspace/drv/ohci/root_hub.h
rcd4ae1e ra146aa33 59 59 * 60 60 * This is allocated when initializing instance, so that memory 61 * allocation is not needed when processing request. 61 * allocation is not needed when processing request. Buffer is used for 62 * interrupt bitmask. 62 63 */ 63 64 uint8_t * interrupt_buffer; 65 /** size of interrupt buffer */ 66 size_t interrupt_mask_size; 67 /** instance`s descriptor*/ 68 uint8_t * hub_descriptor; 69 /** size of hub descriptor */ 70 size_t descriptor_size; 71 72 64 73 } rh_t; 65 74 -
uspace/drv/usbhub/main.c
rcd4ae1e ra146aa33 55 55 }; 56 56 57 57 /** 58 * usb hub driver operations 59 * 60 * The most important one is add_device, which is set to usb_hub_add_device. 61 */ 58 62 static usb_driver_ops_t usb_hub_driver_ops = { 59 63 .add_device = usb_hub_add_device 60 64 }; 61 65 66 /** 67 * hub endpoints, excluding control endpoint 68 */ 62 69 static usb_endpoint_description_t *usb_hub_endpoints[] = { 63 70 &hub_status_change_endpoint_description, … … 65 72 }; 66 73 74 /** 75 * static usb hub driver information 76 */ 67 77 static usb_driver_t usb_hub_driver = { 68 78 .name = NAME, -
uspace/drv/usbhub/ports.c
rcd4ae1e ra146aa33 167 167 168 168 //close address 169 //if (hub->attached_devs[port].address != 0) {170 169 if(hub->ports[port].attached_device.address >= 0){ 171 170 /*uncomment this code to use it when DDF allows device removal … … 182 181 */ 183 182 } else { 184 // TODO: is this really reason to print a warning?185 183 usb_log_warning("Device removed before being registered.\n"); 186 184 -
uspace/drv/usbhub/usbhub.c
rcd4ae1e ra146aa33 73 73 74 74 75 /// \TODO malloc checking76 77 75 //********************************************* 78 76 // … … 248 246 hub_info->ports = malloc( 249 247 sizeof (usb_hub_port_t) * (hub_info->port_count + 1)); 248 if(!hub_info->ports){ 249 return ENOMEM; 250 } 250 251 size_t port; 251 252 for (port = 0; port < hub_info->port_count + 1; ++port) { … … 255 256 usb_log_debug("is_power_switched\n"); 256 257 258 if(!has_individual_port_powering){ 259 usb_log_debug("!has_individual_port_powering\n"); 260 opResult = usb_hub_set_feature(hub_info->control_pipe, 261 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 262 if (opResult != EOK) { 263 usb_log_error("cannot power hub: %s\n", 264 str_error(opResult)); 265 } 266 } 267 257 268 for (port = 1; port <= hub_info->port_count; ++port) { 258 269 usb_log_debug("Powering port %zu.\n",port); … … 264 275 } 265 276 } 266 if(!has_individual_port_powering){ 267 usb_log_debug("!has_individual_port_powering\n"); 268 opResult = usb_hub_set_feature(hub_info->control_pipe, 269 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 270 if (opResult != EOK) { 271 usb_log_error("cannot power hub: %s\n", 272 str_error(opResult)); 273 } 274 } 277 275 278 }else{ 276 usb_log_debug("!is_power_switched \n");279 usb_log_debug("!is_power_switched, not going to be powered\n"); 277 280 } 278 281 usb_log_debug2("freeing data\n");
Note:
See TracChangeset
for help on using the changeset viewer.