Changes in uspace/drv/ohci/root_hub.c [d8421c4:1387692] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/root_hub.c
rd8421c4 r1387692 39 39 40 40 #include "root_hub.h" 41 #include "usb/classes/classes.h"42 #include <usb/request.h>43 #include <usb/classes/hub.h>44 45 41 46 42 /** Root hub initialization … … 54 50 instance->device = dev; 55 51 56 57 52 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); 58 53 59 //start generic usb hub driver60 61 54 /* TODO: implement */ 62 55 return EOK; 63 56 } 64 57 /*----------------------------------------------------------------------------*/ 65 66 67 static int process_get_port_status_request(rh_t *instance, uint16_t port,68 usb_transfer_batch_t * request){69 if(port<1 || port>instance->port_count)70 return EINVAL;71 uint32_t * uint32_buffer = (uint32_t*)request->buffer;72 request->transfered_size = 4;73 uint32_buffer[0] = instance->registers->rh_port_status[port -1];74 return EOK;75 }76 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;80 //bits, 0,1,16,1781 request->transfered_size = 4;82 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);83 uint32_buffer[0] = mask & instance->registers->rh_status;84 return EOK;85 86 }87 88 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,89 size_t * out_size) {90 //base size91 size_t size = 7;92 //variable size according to port count93 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 //size99 result[0] = size;100 //descriptor type101 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*/){///\TODO138 usb_log_warning("requested more data than buffer size\n");139 return EINVAL;140 }141 142 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)143 return process_get_hub_status_request(instance, request);144 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)145 return process_get_port_status_request(instance, request_packet->index,146 request);147 return ENOTSUP;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 173 174 static int process_get_descriptor_request(rh_t *instance,175 usb_transfer_batch_t *request){176 /// \TODO177 usb_device_request_setup_packet_t * setup_request =178 (usb_device_request_setup_packet_t*)request->setup_buffer;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");185 //create hub descriptor186 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){191 //create std device descriptor192 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 guessed204 descriptor->max_packet_size = 8;205 descriptor->product_id = 0x0001;206 /// \TODO these values migt be different207 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 guessed219 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);268 }else{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->length276 );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){290 //set and get configuration requests do not have any meaning, only dummy291 //values are returned292 if(request->buffer_size != 1)293 return EINVAL;294 request->buffer[0] = 1;295 request->transfered_size = 1;296 return EOK;297 }298 299 static int process_hub_feature_set_request(rh_t *instance,300 uint16_t feature, bool enable){301 if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)302 return EINVAL;303 instance->registers->rh_status =304 enable ?305 (instance->registers->rh_status | (1<<feature))306 :307 (instance->registers->rh_status & (~(1<<feature)));308 /// \TODO any error?309 return EOK;310 }311 312 static int process_port_feature_set_request(rh_t *instance,313 uint16_t feature, uint16_t port, bool enable){314 if(feature > USB_HUB_FEATURE_C_PORT_RESET)315 return EINVAL;316 if(port<1 || port>instance->port_count)317 return EINVAL;318 instance->registers->rh_port_status[port - 1] =319 enable ?320 (instance->registers->rh_port_status[port - 1] | (1<<feature))321 :322 (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));323 /// \TODO any error?324 return EOK;325 }326 327 static int process_address_set_request(rh_t *instance,328 uint16_t address){329 instance->address = address;330 return EOK;331 }332 333 static int process_request_with_output(rh_t *instance,334 usb_transfer_batch_t *request){335 usb_device_request_setup_packet_t * setup_request =336 (usb_device_request_setup_packet_t*)request->setup_buffer;337 if(setup_request->request == USB_DEVREQ_GET_STATUS){338 usb_log_debug("USB_DEVREQ_GET_STATUS\n");339 return process_get_status_request(instance, request);340 }341 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){342 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");343 return process_get_descriptor_request(instance, request);344 }345 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){346 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");347 return process_get_configuration_request(instance, request);348 }349 return ENOTSUP;350 }351 352 static int process_request_with_input(rh_t *instance,353 usb_transfer_batch_t *request){354 usb_device_request_setup_packet_t * setup_request =355 (usb_device_request_setup_packet_t*)request->setup_buffer;356 request->transfered_size = 0;357 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){358 return ENOTSUP;359 }360 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){361 //set and get configuration requests do not have any meaning,362 //only dummy values are returned363 return EOK;364 }365 return ENOTSUP;366 }367 368 369 static int process_request_without_data(rh_t *instance,370 usb_transfer_batch_t *request){371 usb_device_request_setup_packet_t * setup_request =372 (usb_device_request_setup_packet_t*)request->setup_buffer;373 request->transfered_size = 0;374 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE375 || 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);395 return ENOTSUP;396 }397 398 399 /**400 *401 * @param instance402 * @param request403 * @return404 */405 58 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 406 59 { 407 60 assert(instance); 408 61 assert(request); 409 int opResult; 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; 448 } 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; 456 }else{ 457 opResult = EINVAL; 62 /* TODO: implement */ 63 if (request->setup_buffer) { 64 usb_log_info("Root hub got SETUP packet: %s.\n", 65 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 458 66 } 459 usb_transfer_batch_finish(request, opResult); 67 usb_log_error("Root hub request processing not implemented.\n"); 68 usb_transfer_batch_finish(request, ENOTSUP); 460 69 return EOK; 461 70 } 462 71 /*----------------------------------------------------------------------------*/ 463 464 465 72 void rh_interrupt(rh_t *instance) 466 73 {
Note:
See TracChangeset
for help on using the changeset viewer.