Changeset d8421c4 in mainline
- Timestamp:
- 2011-03-25T16:18:12Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f97717d9
- Parents:
- 4d0c40b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
r4d0c40b rd8421c4 39 39 40 40 #include "root_hub.h" 41 #include "usb/classes/classes.h" 41 42 #include <usb/request.h> 42 43 #include <usb/classes/hub.h> … … 65 66 66 67 static int process_get_port_status_request(rh_t *instance, uint16_t port, 67 char * buffer){68 usb_transfer_batch_t * request){ 68 69 if(port<1 || port>instance->port_count) 69 70 return EINVAL; 70 uint32_t * uint32_buffer = (uint32_t*)buffer; 71 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 72 request->transfered_size = 4; 71 73 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 72 74 return EOK; 73 75 } 74 76 75 static int process_get_hub_status_request(rh_t *instance,char * buffer){ 76 uint32_t * uint32_buffer = (uint32_t*)buffer; 77 static int process_get_hub_status_request(rh_t *instance, 78 usb_transfer_batch_t * request){ 79 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 77 80 //bits, 0,1,16,17 81 request->transfered_size = 4; 78 82 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 79 83 uint32_buffer[0] = mask & instance->registers->rh_status; … … 82 86 } 83 87 84 85 static int process_get_status_request(rh_t *instance,char * buffer, 86 size_t buffer_size, usb_device_request_setup_packet_t * request){ 87 88 usb_hub_bm_request_type_t request_type = request->request_type; 89 if(buffer_size!=4) return EINVAL; 88 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 89 size_t * out_size) { 90 //base size 91 size_t size = 7; 92 //variable size according to port count 93 size_t var_size = instance->port_count / 8 + 94 ((instance->port_count % 8 > 0) ? 1 : 0); 95 size += 2 * var_size; 96 uint8_t * result = (uint8_t*) malloc(size); 97 bzero(result,size); 98 //size 99 result[0] = size; 100 //descriptor type 101 result[1] = USB_DESCTYPE_HUB; 102 result[2] = instance->port_count; 103 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 104 result[3] = 105 ((hub_desc_reg >> 8) %2) + 106 (((hub_desc_reg >> 9) %2) << 1) + 107 (((hub_desc_reg >> 10) %2) << 2) + 108 (((hub_desc_reg >> 11) %2) << 3) + 109 (((hub_desc_reg >> 12) %2) << 4); 110 result[4] = 0; 111 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 112 result[6] = 50; 113 114 int port; 115 for (port = 1; port <= instance->port_count; ++port) { 116 result[7 + port/8] += 117 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 118 } 119 size_t i; 120 for (i = 0; i < var_size; ++i) { 121 result[7 + var_size + i] = 255; 122 } 123 (*out_result) = result; 124 (*out_size) = size; 125 } 126 127 128 static int process_get_status_request(rh_t *instance, 129 usb_transfer_batch_t * request) 130 { 131 size_t buffer_size = request->buffer_size; 132 usb_device_request_setup_packet_t * request_packet = 133 (usb_device_request_setup_packet_t*) 134 request->setup_buffer; 135 136 usb_hub_bm_request_type_t request_type = request_packet->request_type; 137 if(buffer_size<4/*request_packet->length*/){///\TODO 138 usb_log_warning("requested more data than buffer size\n"); 139 return EINVAL; 140 } 141 90 142 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 91 return process_get_hub_status_request(instance, buffer);143 return process_get_hub_status_request(instance, request); 92 144 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 93 return process_get_port_status_request(instance, request ->index,94 buffer);145 return process_get_port_status_request(instance, request_packet->index, 146 request); 95 147 return ENOTSUP; 96 148 } 149 150 static void create_interrupt_mask(rh_t *instance, void ** buffer, 151 size_t * buffer_size){ 152 int bit_count = instance->port_count + 1; 153 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 154 (*buffer) = malloc(*buffer_size); 155 uint8_t * bitmap = (uint8_t*)(*buffer); 156 uint32_t mask = (1<<16) + (1<<17); 157 bzero(bitmap,(*buffer_size)); 158 if(instance->registers->rh_status & mask){ 159 bitmap[0] = 1; 160 } 161 int port; 162 mask = 0; 163 int i; 164 for(i=16;i<=20;++i) 165 mask += 1<<i; 166 for(port = 1; port<=instance->port_count;++port){ 167 if(mask & instance->registers->rh_port_status[port-1]){ 168 bitmap[(port+1)/8] += 1<<(port%8); 169 } 170 } 171 } 172 97 173 98 174 static int process_get_descriptor_request(rh_t *instance, … … 101 177 usb_device_request_setup_packet_t * setup_request = 102 178 (usb_device_request_setup_packet_t*)request->setup_buffer; 103 if(setup_request->value == USB_DESCTYPE_HUB){ 179 size_t size; 180 void * result_descriptor; 181 uint16_t setup_request_value = setup_request->value_high; 182 //(setup_request->value_low << 8); 183 if(setup_request_value == USB_DESCTYPE_HUB){ 184 usb_log_debug("USB_DESCTYPE_HUB\n"); 104 185 //create hub descriptor 105 }else if(setup_request->value == USB_DESCTYPE_HUB){ 186 uint8_t * descriptor; 187 usb_create_serialized_hub_descriptor(instance, 188 &descriptor, &size); 189 result_descriptor = descriptor; 190 }else if(setup_request_value == USB_DESCTYPE_DEVICE){ 106 191 //create std device descriptor 192 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 193 usb_standard_device_descriptor_t * descriptor = 194 (usb_standard_device_descriptor_t*) 195 malloc(sizeof(usb_standard_device_descriptor_t)); 196 descriptor->configuration_count = 1; 197 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 198 descriptor->device_class = USB_CLASS_HUB; 199 descriptor->device_protocol = 0; 200 descriptor->device_subclass = 0; 201 descriptor->device_version = 0; 202 descriptor->length = sizeof(usb_standard_device_descriptor_t); 203 /// \TODO this value is guessed 204 descriptor->max_packet_size = 8; 205 descriptor->product_id = 0x0001; 206 /// \TODO these values migt be different 207 descriptor->str_serial_number = 0; 208 descriptor->str_serial_number = 0; 209 descriptor->usb_spec_version = 0; 210 descriptor->vendor_id = 0x16db; 211 result_descriptor = descriptor; 212 size = sizeof(usb_standard_device_descriptor_t); 213 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 214 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 215 usb_standard_configuration_descriptor_t * descriptor = 216 (usb_standard_configuration_descriptor_t*) 217 malloc(sizeof(usb_standard_configuration_descriptor_t)); 218 /// \TODO some values are default or guessed 219 descriptor->attributes = 1<<7; 220 descriptor->configuration_number = 1; 221 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 222 descriptor->interface_count = 1; 223 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 224 descriptor->max_power = 100; 225 descriptor->str_configuration = 0; 226 /// \TODO should this include device descriptor? 227 size_t hub_descriptor_size = 7 + 228 2* (instance->port_count / 8 + 229 ((instance->port_count % 8 > 0) ? 1 : 0)); 230 descriptor->total_length = 231 sizeof(usb_standard_configuration_descriptor_t)+ 232 sizeof(usb_standard_endpoint_descriptor_t)+ 233 sizeof(usb_standard_interface_descriptor_t)+ 234 hub_descriptor_size; 235 result_descriptor = descriptor; 236 size = sizeof(usb_standard_configuration_descriptor_t); 237 238 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 239 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 240 usb_standard_interface_descriptor_t * descriptor = 241 (usb_standard_interface_descriptor_t*) 242 malloc(sizeof(usb_standard_interface_descriptor_t)); 243 descriptor->alternate_setting = 0; 244 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 245 descriptor->endpoint_count = 1; 246 descriptor->interface_class = USB_CLASS_HUB; 247 /// \TODO is this correct? 248 descriptor->interface_number = 1; 249 descriptor->interface_protocol = 0; 250 descriptor->interface_subclass = 0; 251 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 252 descriptor->str_interface = 0; 253 result_descriptor = descriptor; 254 size = sizeof(usb_standard_interface_descriptor_t); 255 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 256 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 257 usb_standard_endpoint_descriptor_t * descriptor = 258 (usb_standard_endpoint_descriptor_t*) 259 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 260 descriptor->attributes = USB_TRANSFER_INTERRUPT; 261 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 262 descriptor->endpoint_address = 1 + (1<<7); 263 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 264 descriptor->max_packet_size = 8; 265 descriptor->poll_interval = 255; 266 result_descriptor = descriptor; 267 size = sizeof(usb_standard_endpoint_descriptor_t); 107 268 }else{ 108 return EINVAL; 109 } 110 return EOK; 111 } 112 113 static int process_get_configuration_request(rh_t *instance, char * buffer, 114 size_t buffer_size 115 ){ 269 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 270 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 271 setup_request->request_type, 272 setup_request->request, 273 setup_request_value, 274 setup_request->index, 275 setup_request->length 276 ); 277 return EINVAL; 278 } 279 if(request->buffer_size < size){ 280 size = request->buffer_size; 281 } 282 request->transfered_size = size; 283 memcpy(request->buffer,result_descriptor,size); 284 free(result_descriptor); 285 return EOK; 286 } 287 288 static int process_get_configuration_request(rh_t *instance, 289 usb_transfer_batch_t *request){ 116 290 //set and get configuration requests do not have any meaning, only dummy 117 291 //values are returned 118 if(buffer_size != 1) 119 return EINVAL; 120 buffer[0] = 1; 292 if(request->buffer_size != 1) 293 return EINVAL; 294 request->buffer[0] = 1; 295 request->transfered_size = 1; 121 296 return EOK; 122 297 } … … 148 323 /// \TODO any error? 149 324 return EOK; 150 325 } 326 327 static int process_address_set_request(rh_t *instance, 328 uint16_t address){ 329 instance->address = address; 330 return EOK; 151 331 } 152 332 … … 156 336 (usb_device_request_setup_packet_t*)request->setup_buffer; 157 337 if(setup_request->request == USB_DEVREQ_GET_STATUS){ 158 return process_get_status_request(instance, request->buffer, 159 request->buffer_size, 160 setup_request); 338 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 339 return process_get_status_request(instance, request); 161 340 } 162 341 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){ 342 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 163 343 return process_get_descriptor_request(instance, request); 164 344 } 165 345 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){ 166 return process_get_configuration_request(instance, request->buffer,167 request->buffer_size);346 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 347 return process_get_configuration_request(instance, request); 168 348 } 169 349 return ENOTSUP; … … 174 354 usb_device_request_setup_packet_t * setup_request = 175 355 (usb_device_request_setup_packet_t*)request->setup_buffer; 356 request->transfered_size = 0; 176 357 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){ 177 358 return ENOTSUP; … … 190 371 usb_device_request_setup_packet_t * setup_request = 191 372 (usb_device_request_setup_packet_t*)request->setup_buffer; 192 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 193 return process_hub_feature_set_request(instance, setup_request->value, 194 setup_request->request == USB_DEVREQ_SET_FEATURE); 195 } 196 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 197 return process_port_feature_set_request(instance, setup_request->value, 198 setup_request->index, 199 setup_request->request == USB_DEVREQ_SET_FEATURE); 200 } 373 request->transfered_size = 0; 374 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE 375 || setup_request->request == USB_DEVREQ_SET_FEATURE){ 376 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 377 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 378 return process_hub_feature_set_request(instance, setup_request->value, 379 setup_request->request == USB_DEVREQ_SET_FEATURE); 380 } 381 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 382 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 383 return process_port_feature_set_request(instance, setup_request->value, 384 setup_request->index, 385 setup_request->request == USB_DEVREQ_SET_FEATURE); 386 } 387 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type); 388 return EINVAL; 389 } 390 if(setup_request->request == USB_DEVREQ_SET_ADDRESS){ 391 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 392 return process_address_set_request(instance, setup_request->value); 393 } 394 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type); 201 395 return ENOTSUP; 202 396 } … … 214 408 assert(request); 215 409 int opResult; 216 if (request->setup_buffer) { 217 usb_log_info("Root hub got SETUP packet: %s.\n", 218 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 219 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 220 usb_log_error("setup packet too small\n"); 221 return EINVAL; 410 if(request->transfer_type == USB_TRANSFER_CONTROL){ 411 if (request->setup_buffer) { 412 usb_log_info("Root hub got CTRL packet: %s.\n", 413 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 414 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 415 usb_log_error("setup packet too small\n"); 416 return EINVAL; 417 } 418 usb_device_request_setup_packet_t * setup_request = 419 (usb_device_request_setup_packet_t*)request->setup_buffer; 420 if( 421 setup_request->request == USB_DEVREQ_GET_STATUS 422 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 423 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 424 ){ 425 usb_log_debug("processing request with output\n"); 426 opResult = process_request_with_output(instance,request); 427 }else if( 428 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 429 || setup_request->request == USB_DEVREQ_SET_FEATURE 430 || setup_request->request == USB_DEVREQ_SET_ADDRESS 431 ){ 432 usb_log_debug("processing request without additional data\n"); 433 opResult = process_request_without_data(instance,request); 434 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 435 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 436 ){ 437 usb_log_debug("processing request with input\n"); 438 opResult = process_request_with_input(instance,request); 439 }else{ 440 usb_log_warning("received unsuported request: %d\n", 441 setup_request->request 442 ); 443 opResult = ENOTSUP; 444 } 445 }else{ 446 usb_log_error("root hub received empty transaction?"); 447 opResult = EINVAL; 222 448 } 223 usb_device_request_setup_packet_t * setup_request = 224 (usb_device_request_setup_packet_t*)request->setup_buffer; 225 if( 226 setup_request->request == USB_DEVREQ_GET_STATUS 227 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 228 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 229 ){ 230 usb_log_debug("processing request with output\n"); 231 opResult = process_request_with_output(instance,request); 232 }else if( 233 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 234 || setup_request->request == USB_DEVREQ_SET_FEATURE 235 ){ 236 usb_log_debug("processing request without additional data\n"); 237 opResult = process_request_without_data(instance,request); 238 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 239 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 240 ){ 241 usb_log_debug("processing request with input\n"); 242 opResult = process_request_with_input(instance,request); 243 }else{ 244 usb_log_warning("received unsuported request: %d\n", 245 setup_request->request 246 ); 247 opResult = ENOTSUP; 248 } 449 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 450 usb_log_info("Root hub got INTERRUPT packet\n"); 451 void * buffer; 452 create_interrupt_mask(instance, &buffer, 453 &(request->transfered_size)); 454 memcpy(request->transport_buffer,buffer, request->transfered_size); 455 opResult = EOK; 249 456 }else{ 250 usb_log_error("root hub received empty transaction?");251 457 opResult = EINVAL; 252 458 } … … 255 461 } 256 462 /*----------------------------------------------------------------------------*/ 257 //is this status change? 463 464 258 465 void rh_interrupt(rh_t *instance) 259 466 {
Note:
See TracChangeset
for help on using the changeset viewer.