00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00034 #include <assert.h>
00035 #include <errno.h>
00036 #include <str_error.h>
00037
00038 #include <usb/debug.h>
00039
00040 #include "root_hub.h"
00041 #include <usb/classes/classes.h>
00042 #include <usb/dev/driver.h>
00043 #include "ohci_regs.h"
00044
00045 #include <usb/dev/request.h>
00046 #include <usb/classes/hub.h>
00047
00051 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = {
00052 .configuration_count = 1,
00053 .descriptor_type = USB_DESCTYPE_DEVICE,
00054 .device_class = USB_CLASS_HUB,
00055 .device_protocol = 0,
00056 .device_subclass = 0,
00057 .device_version = 0,
00058 .length = sizeof (usb_standard_device_descriptor_t),
00059 .max_packet_size = 8,
00060 .vendor_id = 0x16db,
00061 .product_id = 0x0001,
00062 .str_serial_number = 0,
00063 .usb_spec_version = 0x110,
00064 };
00065
00070 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = {
00071 .attributes = 1 << 7,
00072 .configuration_number = 1,
00073 .descriptor_type = USB_DESCTYPE_CONFIGURATION,
00074 .interface_count = 1,
00075 .length = sizeof (usb_standard_configuration_descriptor_t),
00076 .max_power = 100,
00077 .str_configuration = 0,
00078 };
00079
00083 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = {
00084 .alternate_setting = 0,
00085 .descriptor_type = USB_DESCTYPE_INTERFACE,
00086 .endpoint_count = 1,
00087 .interface_class = USB_CLASS_HUB,
00088 .interface_number = 1,
00089 .interface_protocol = 0,
00090 .interface_subclass = 0,
00091 .length = sizeof (usb_standard_interface_descriptor_t),
00092 .str_interface = 0,
00093 };
00094
00098 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = {
00099 .attributes = USB_TRANSFER_INTERRUPT,
00100 .descriptor_type = USB_DESCTYPE_ENDPOINT,
00101 .endpoint_address = 1 + (1 << 7),
00102 .length = sizeof (usb_standard_endpoint_descriptor_t),
00103 .max_packet_size = 8,
00104 .poll_interval = 255,
00105 };
00106
00110 static const uint32_t hub_clear_feature_valid_mask =
00111 RHS_OCIC_FLAG |
00112 RHS_CLEAR_PORT_POWER;
00113
00117 static const uint32_t hub_clear_feature_by_writing_one_mask =
00118 RHS_CLEAR_PORT_POWER;
00119
00123 static const uint32_t hub_set_feature_valid_mask =
00124 RHS_LPSC_FLAG |
00125 RHS_OCIC_FLAG;
00126
00130 static const uint32_t hub_set_feature_direct_mask =
00131 RHS_SET_PORT_POWER;
00132
00136 static const uint32_t port_set_feature_valid_mask =
00137 RHPS_SET_PORT_ENABLE |
00138 RHPS_SET_PORT_SUSPEND |
00139 RHPS_SET_PORT_RESET |
00140 RHPS_SET_PORT_POWER;
00141
00145 static const uint32_t port_clear_feature_valid_mask =
00146 RHPS_CCS_FLAG |
00147 RHPS_SET_PORT_SUSPEND |
00148 RHPS_POCI_FLAG |
00149 RHPS_SET_PORT_POWER |
00150 RHPS_CSC_FLAG |
00151 RHPS_PESC_FLAG |
00152 RHPS_PSSC_FLAG |
00153 RHPS_OCIC_FLAG |
00154 RHPS_PRSC_FLAG;
00155
00156
00157
00158
00162 static const uint32_t port_status_change_mask = RHPS_CHANGE_WC_MASK;
00163
00164 static int create_serialized_hub_descriptor(rh_t *instance);
00165
00166 static int rh_init_descriptors(rh_t *instance);
00167
00168 static int process_get_port_status_request(rh_t *instance, uint16_t port,
00169 usb_transfer_batch_t * request);
00170
00171 static int process_get_hub_status_request(rh_t *instance,
00172 usb_transfer_batch_t * request);
00173
00174 static int process_get_status_request(rh_t *instance,
00175 usb_transfer_batch_t * request);
00176
00177 static void create_interrupt_mask_in_instance(rh_t *instance);
00178
00179 static int process_get_descriptor_request(rh_t *instance,
00180 usb_transfer_batch_t *request);
00181
00182 static int process_get_configuration_request(rh_t *instance,
00183 usb_transfer_batch_t *request);
00184
00185 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature);
00186
00187 static int process_hub_feature_clear_request(rh_t *instance,
00188 uint16_t feature);
00189
00190 static int process_port_feature_set_request(rh_t *instance,
00191 uint16_t feature, uint16_t port);
00192
00193 static int process_port_feature_clear_request(rh_t *instance,
00194 uint16_t feature, uint16_t port);
00195
00196 static int process_address_set_request(rh_t *instance,
00197 uint16_t address);
00198
00199 static int process_request_with_output(rh_t *instance,
00200 usb_transfer_batch_t *request);
00201
00202 static int process_request_with_input(rh_t *instance,
00203 usb_transfer_batch_t *request);
00204
00205 static int process_request_without_data(rh_t *instance,
00206 usb_transfer_batch_t *request);
00207
00208 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
00209
00210 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request);
00211
00212 static bool is_zeros(void * buffer, size_t size);
00213
00217 int rh_init(rh_t *instance, ohci_regs_t *regs) {
00218 assert(instance);
00219 instance->registers = regs;
00220 instance->port_count =
00221 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
00222 int opResult = rh_init_descriptors(instance);
00223 if (opResult != EOK) {
00224 return opResult;
00225 }
00226
00227 instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
00228 instance->unfinished_interrupt_transfer = NULL;
00229 instance->interrupt_mask_size = (instance->port_count + 8) / 8;
00230 instance->interrupt_buffer = malloc(instance->interrupt_mask_size);
00231 if (!instance->interrupt_buffer)
00232 return ENOMEM;
00233
00234 usb_log_info("OHCI root hub with %zu ports initialized.\n",
00235 instance->port_count);
00236
00237 return EOK;
00238 }
00239
00240
00248 int rh_request(rh_t *instance, usb_transfer_batch_t *request) {
00249 assert(instance);
00250 assert(request);
00251 int opResult;
00252 if (request->ep->transfer_type == USB_TRANSFER_CONTROL) {
00253 usb_log_debug("Root hub got CONTROL packet\n");
00254 opResult = process_ctrl_request(instance, request);
00255 usb_transfer_batch_finish_error(request, opResult);
00256 } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) {
00257 usb_log_debug("Root hub got INTERRUPT packet\n");
00258 create_interrupt_mask_in_instance(instance);
00259 if (is_zeros(instance->interrupt_buffer,
00260 instance->interrupt_mask_size)) {
00261 usb_log_debug("No changes..\n");
00262 instance->unfinished_interrupt_transfer = request;
00263
00264 } else {
00265 usb_log_debug("Processing changes..\n");
00266 process_interrupt_mask_in_instance(instance, request);
00267 }
00268 opResult = EOK;
00269 } else {
00270
00271 opResult = EINVAL;
00272 usb_transfer_batch_finish_error(request, opResult);
00273 }
00274 return EOK;
00275 }
00276
00277
00278
00285 void rh_interrupt(rh_t *instance) {
00286 if (!instance->unfinished_interrupt_transfer) {
00287 return;
00288 }
00289 usb_log_debug("Finalizing interrupt transfer\n");
00290 create_interrupt_mask_in_instance(instance);
00291 process_interrupt_mask_in_instance(instance,
00292 instance->unfinished_interrupt_transfer);
00293 }
00294
00295
00305 static int create_serialized_hub_descriptor(rh_t *instance) {
00306 size_t size = 7 +
00307 ((instance->port_count + 7) / 8) * 2;
00308 size_t var_size = (instance->port_count + 7) / 8;
00309 uint8_t * result = (uint8_t*) malloc(size);
00310 if (!result) return ENOMEM;
00311
00312 bzero(result, size);
00313
00314 result[0] = size;
00315
00316 result[1] = USB_DESCTYPE_HUB;
00317 result[2] = instance->port_count;
00318 uint32_t hub_desc_reg = instance->registers->rh_desc_a;
00319 result[3] =
00320 ((hub_desc_reg >> 8) % 2) +
00321 (((hub_desc_reg >> 9) % 2) << 1) +
00322 (((hub_desc_reg >> 10) % 2) << 2) +
00323 (((hub_desc_reg >> 11) % 2) << 3) +
00324 (((hub_desc_reg >> 12) % 2) << 4);
00325 result[4] = 0;
00326 result[5] = 50;
00327 result[6] = 50;
00328
00329 size_t port;
00330 for (port = 1; port <= instance->port_count; ++port) {
00331 uint8_t is_non_removable =
00332 instance->registers->rh_desc_b >> port % 2;
00333 result[7 + port / 8] +=
00334 is_non_removable << (port % 8);
00335 }
00336 size_t i;
00337 for (i = 0; i < var_size; ++i) {
00338 result[7 + var_size + i] = 255;
00339 }
00340 instance->hub_descriptor = result;
00341 instance->descriptor_size = size;
00342
00343 return EOK;
00344 }
00345
00346
00354 static int rh_init_descriptors(rh_t *instance) {
00355 memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor,
00356 sizeof (ohci_rh_device_descriptor)
00357 );
00358 usb_standard_configuration_descriptor_t descriptor;
00359 memcpy(&descriptor, &ohci_rh_conf_descriptor,
00360 sizeof (ohci_rh_conf_descriptor));
00361
00362 int opResult = create_serialized_hub_descriptor(instance);
00363 if (opResult != EOK) {
00364 return opResult;
00365 }
00366 descriptor.total_length =
00367 sizeof (usb_standard_configuration_descriptor_t) +
00368 sizeof (usb_standard_endpoint_descriptor_t) +
00369 sizeof (usb_standard_interface_descriptor_t) +
00370 instance->descriptor_size;
00371
00372 uint8_t * full_config_descriptor =
00373 (uint8_t*) malloc(descriptor.total_length);
00374 if (!full_config_descriptor) {
00375 return ENOMEM;
00376 }
00377 memcpy(full_config_descriptor, &descriptor, sizeof (descriptor));
00378 memcpy(full_config_descriptor + sizeof (descriptor),
00379 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));
00380 memcpy(full_config_descriptor + sizeof (descriptor) +
00381 sizeof (ohci_rh_iface_descriptor),
00382 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));
00383 memcpy(full_config_descriptor + sizeof (descriptor) +
00384 sizeof (ohci_rh_iface_descriptor) +
00385 sizeof (ohci_rh_ep_descriptor),
00386 instance->hub_descriptor, instance->descriptor_size);
00387
00388 instance->descriptors.configuration = full_config_descriptor;
00389 instance->descriptors.configuration_size = descriptor.total_length;
00390
00391 return EOK;
00392 }
00393
00394
00407 static int process_get_port_status_request(rh_t *instance, uint16_t port,
00408 usb_transfer_batch_t * request) {
00409 if (port < 1 || port > instance->port_count)
00410 return EINVAL;
00411 request->transfered_size = 4;
00412 uint32_t data = instance->registers->rh_port_status[port - 1];
00413 memcpy(request->data_buffer, &data, 4);
00414 return EOK;
00415 }
00416
00417
00429 static int process_get_hub_status_request(rh_t *instance,
00430 usb_transfer_batch_t * request) {
00431 request->transfered_size = 4;
00432
00433 uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17);
00434 uint32_t data = mask & instance->registers->rh_status;
00435 memcpy(request->data_buffer, &data, 4);
00436
00437 return EOK;
00438 }
00439
00440
00450 static int process_get_status_request(rh_t *instance,
00451 usb_transfer_batch_t * request) {
00452 size_t buffer_size = request->buffer_size;
00453 usb_device_request_setup_packet_t * request_packet =
00454 (usb_device_request_setup_packet_t*)
00455 request->setup_buffer;
00456
00457 usb_hub_bm_request_type_t request_type = request_packet->request_type;
00458 if (buffer_size < 4) {
00459 usb_log_warning("Requested more data than buffer size\n");
00460 return EINVAL;
00461 }
00462
00463 if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
00464 return process_get_hub_status_request(instance, request);
00465 if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
00466 return process_get_port_status_request(instance,
00467 request_packet->index,
00468 request);
00469
00470 return ENOTSUP;
00471 }
00472
00473
00484 static void create_interrupt_mask_in_instance(rh_t * instance) {
00485 uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer);
00486 uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
00487 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16));
00488 bzero(bitmap, instance->interrupt_mask_size);
00489 if ((instance->registers->rh_status & mask) != 0) {
00490 bitmap[0] = 1;
00491 }
00492 size_t port;
00493 mask = port_status_change_mask;
00494 for (port = 1; port <= instance->port_count; ++port) {
00495 if ((mask & instance->registers->rh_port_status[port - 1]) != 0) {
00496
00497 bitmap[(port) / 8] += 1 << (port % 8);
00498 }
00499 }
00500 }
00501
00502
00512 static int process_get_descriptor_request(rh_t *instance,
00513 usb_transfer_batch_t *request) {
00514 usb_device_request_setup_packet_t * setup_request =
00515 (usb_device_request_setup_packet_t*) request->setup_buffer;
00516 size_t size;
00517 const void * result_descriptor = NULL;
00518 const uint16_t setup_request_value = setup_request->value_high;
00519
00520 switch (setup_request_value) {
00521 case USB_DESCTYPE_HUB:
00522 {
00523 usb_log_debug("USB_DESCTYPE_HUB\n");
00524 result_descriptor = instance->hub_descriptor;
00525 size = instance->descriptor_size;
00526 break;
00527 }
00528 case USB_DESCTYPE_DEVICE:
00529 {
00530 usb_log_debug("USB_DESCTYPE_DEVICE\n");
00531 result_descriptor = &ohci_rh_device_descriptor;
00532 size = sizeof (ohci_rh_device_descriptor);
00533 break;
00534 }
00535 case USB_DESCTYPE_CONFIGURATION:
00536 {
00537 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
00538 result_descriptor = instance->descriptors.configuration;
00539 size = instance->descriptors.configuration_size;
00540 break;
00541 }
00542 case USB_DESCTYPE_INTERFACE:
00543 {
00544 usb_log_debug("USB_DESCTYPE_INTERFACE\n");
00545 result_descriptor = &ohci_rh_iface_descriptor;
00546 size = sizeof (ohci_rh_iface_descriptor);
00547 break;
00548 }
00549 case USB_DESCTYPE_ENDPOINT:
00550 {
00551 usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
00552 result_descriptor = &ohci_rh_ep_descriptor;
00553 size = sizeof (ohci_rh_ep_descriptor);
00554 break;
00555 }
00556 default:
00557 {
00558 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",
00559 setup_request->value);
00560 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue "
00561 "%d\n\tindex %d\n\tlen %d\n ",
00562 setup_request->request_type,
00563 setup_request->request,
00564 setup_request_value,
00565 setup_request->index,
00566 setup_request->length
00567 );
00568 return EINVAL;
00569 }
00570 }
00571 if (request->buffer_size < size) {
00572 size = request->buffer_size;
00573 }
00574 request->transfered_size = size;
00575 memcpy(request->data_buffer, result_descriptor, size);
00576
00577 return EOK;
00578 }
00579
00580
00589 static int process_get_configuration_request(rh_t *instance,
00590 usb_transfer_batch_t *request) {
00591
00592
00593 if (request->buffer_size != 1)
00594 return EINVAL;
00595 request->data_buffer[0] = 1;
00596 request->transfered_size = 1;
00597
00598 return EOK;
00599 }
00600
00601
00609 static int process_hub_feature_set_request(rh_t *instance,
00610 uint16_t feature) {
00611 if (!((1 << feature) & hub_set_feature_valid_mask))
00612 return EINVAL;
00613 if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)
00614 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16;
00615 instance->registers->rh_status =
00616 (instance->registers->rh_status | (1 << feature))
00617 & (~hub_clear_feature_by_writing_one_mask);
00618
00619 return EOK;
00620 }
00621
00622
00630 static int process_hub_feature_clear_request(rh_t *instance,
00631 uint16_t feature) {
00632 if (!((1 << feature) & hub_clear_feature_valid_mask))
00633 return EINVAL;
00634
00635 if ((1 << feature) & hub_set_feature_direct_mask) {
00636 instance->registers->rh_status =
00637 (instance->registers->rh_status & (~(1 << feature)))
00638 & (~hub_clear_feature_by_writing_one_mask);
00639 } else {
00640
00641 instance->registers->rh_status =
00642 (instance->registers->rh_status
00643 & (~hub_clear_feature_by_writing_one_mask))
00644 | (1 << feature);
00645 }
00646 return EOK;
00647 }
00648
00649
00659 static int process_port_feature_set_request(rh_t *instance,
00660 uint16_t feature, uint16_t port) {
00661 if (!((1 << feature) & port_set_feature_valid_mask))
00662 return EINVAL;
00663 if (port < 1 || port > instance->port_count)
00664 return EINVAL;
00665 instance->registers->rh_port_status[port - 1] =
00666 (instance->registers->rh_port_status[port - 1] | (1 << feature))
00667 & (~port_clear_feature_valid_mask);
00668 return EOK;
00669 }
00670
00671
00681 static int process_port_feature_clear_request(rh_t *instance,
00682 uint16_t feature, uint16_t port) {
00683 if (!((1 << feature) & port_clear_feature_valid_mask))
00684 return EINVAL;
00685 if (port < 1 || port > instance->port_count)
00686 return EINVAL;
00687 if (feature == USB_HUB_FEATURE_PORT_POWER)
00688 feature = USB_HUB_FEATURE_PORT_LOW_SPEED;
00689 if (feature == USB_HUB_FEATURE_PORT_SUSPEND)
00690 feature = USB_HUB_FEATURE_PORT_OVER_CURRENT;
00691 instance->registers->rh_port_status[port - 1] =
00692 (instance->registers->rh_port_status[port - 1]
00693 & (~port_clear_feature_valid_mask))
00694 | (1 << feature);
00695
00696 return EOK;
00697 }
00698
00699
00707 static int process_address_set_request(rh_t *instance,
00708 uint16_t address) {
00709 return ENOTSUP;
00710 }
00711
00712
00722 static int process_request_with_output(rh_t *instance,
00723 usb_transfer_batch_t *request) {
00724 usb_device_request_setup_packet_t * setup_request =
00725 (usb_device_request_setup_packet_t*) request->setup_buffer;
00726 if (setup_request->request == USB_DEVREQ_GET_STATUS) {
00727 usb_log_debug("USB_DEVREQ_GET_STATUS\n");
00728 return process_get_status_request(instance, request);
00729 }
00730 if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) {
00731 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
00732 return process_get_descriptor_request(instance, request);
00733 }
00734 if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) {
00735 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
00736
00737 return process_get_configuration_request(instance, request);
00738 }
00739 return ENOTSUP;
00740 }
00741
00742
00752 static int process_request_with_input(rh_t *instance,
00753 usb_transfer_batch_t *request) {
00754 usb_device_request_setup_packet_t * setup_request =
00755 (usb_device_request_setup_packet_t*) request->setup_buffer;
00756 request->transfered_size = 0;
00757 if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) {
00758 return ENOTSUP;
00759 }
00760 if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) {
00761
00762
00763
00764 return EOK;
00765 }
00766 return ENOTSUP;
00767 }
00768
00769
00779 static int process_request_without_data(rh_t *instance,
00780 usb_transfer_batch_t *request) {
00781 usb_device_request_setup_packet_t * setup_request =
00782 (usb_device_request_setup_packet_t*) request->setup_buffer;
00783 request->transfered_size = 0;
00784 if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) {
00785 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {
00786 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
00787 return process_hub_feature_clear_request(instance,
00788 setup_request->value);
00789 }
00790 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
00791 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
00792 return process_port_feature_clear_request(instance,
00793 setup_request->value,
00794 setup_request->index);
00795 }
00796 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
00797 setup_request->request_type);
00798 return EINVAL;
00799 }
00800 if (setup_request->request == USB_DEVREQ_SET_FEATURE) {
00801 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {
00802 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
00803 return process_hub_feature_set_request(instance,
00804 setup_request->value);
00805 }
00806 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
00807 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
00808 return process_port_feature_set_request(instance,
00809 setup_request->value,
00810 setup_request->index);
00811 }
00812 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
00813 setup_request->request_type);
00814 return EINVAL;
00815 }
00816 if (setup_request->request == USB_DEVREQ_SET_ADDRESS) {
00817 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
00818 return process_address_set_request(instance,
00819 setup_request->value);
00820 }
00821 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",
00822 setup_request->request_type);
00823
00824 return ENOTSUP;
00825 }
00826
00827
00846 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) {
00847 if (!request->setup_buffer) {
00848 usb_log_error("root hub received empty transaction?");
00849 return EINVAL;
00850 }
00851 int opResult;
00852 if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) {
00853 usb_log_error("Setup packet too small\n");
00854 return EINVAL;
00855 }
00856 usb_log_info("CTRL packet: %s.\n",
00857 usb_debug_str_buffer(
00858 (const uint8_t *) request->setup_buffer, 8, 8));
00859 usb_device_request_setup_packet_t * setup_request =
00860 (usb_device_request_setup_packet_t*)
00861 request->setup_buffer;
00862 switch (setup_request->request) {
00863 case USB_DEVREQ_GET_STATUS:
00864 case USB_DEVREQ_GET_DESCRIPTOR:
00865 case USB_DEVREQ_GET_CONFIGURATION:
00866 usb_log_debug("Processing request with output\n");
00867 opResult = process_request_with_output(
00868 instance, request);
00869 break;
00870 case USB_DEVREQ_CLEAR_FEATURE:
00871 case USB_DEVREQ_SET_FEATURE:
00872 case USB_DEVREQ_SET_ADDRESS:
00873 usb_log_debug("Processing request without "
00874 "additional data\n");
00875 opResult = process_request_without_data(
00876 instance, request);
00877 break;
00878 case USB_DEVREQ_SET_DESCRIPTOR:
00879 case USB_DEVREQ_SET_CONFIGURATION:
00880 usb_log_debug("Processing request with "
00881 "input\n");
00882 opResult = process_request_with_input(
00883 instance, request);
00884
00885 break;
00886 default:
00887 usb_log_warning("Received unsuported request: "
00888 "%d\n",
00889 setup_request->request
00890 );
00891 opResult = ENOTSUP;
00892 }
00893 return opResult;
00894 }
00895
00896
00910 static int process_interrupt_mask_in_instance(rh_t *instance,
00911 usb_transfer_batch_t * request) {
00912 memcpy(request->data_buffer, instance->interrupt_buffer,
00913 instance->interrupt_mask_size);
00914 request->transfered_size = instance->interrupt_mask_size;
00915 instance->unfinished_interrupt_transfer = NULL;
00916 usb_transfer_batch_finish_error(request, EOK);
00917
00918 return EOK;
00919 }
00920
00921
00922
00931 static bool is_zeros(void *buffer, size_t size) {
00932 if (!buffer) return true;
00933 if (!size) return true;
00934 size_t i;
00935 for (i = 0; i < size; ++i) {
00936 if (((char*) buffer)[i])
00937 return false;
00938 }
00939 return true;
00940 }
00941