root_hub.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Jan Vesely
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into
00157 //USB_HUB_FEATURE_PORT_LOW_SPEED for port set feature request
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         // set port power mode to no-power-switching
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                         //will be finished later
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         //size
00314         result[0] = size;
00315         //descriptor type
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] = /*descriptor->pwr_on_2_good_time*/ 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         //bits, 0,1,16,17
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         //(setup_request->value_low << 8);
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         //set and get configuration requests do not have any meaning, only dummy
00592         //values are returned
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         //is the feature cleared directly?
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 {//the feature is cleared by writing '1'
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                 //set and get configuration requests do not have any meaning,
00762                 //only dummy values are returned
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 

Generated on Thu Jun 2 07:45:44 2011 for HelenOS/USB by  doxygen 1.4.7