Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/usbhub.c

    r0f21c0c r15b0432  
    5050#include "usb/usb.h"
    5151#include "usb/pipes.h"
     52#include "usb/classes/classes.h"
    5253
    5354static device_ops_t hub_device_ops = {
    5455        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    5556};
     57
     58/** Hub status-change endpoint description */
     59static usb_endpoint_description_t status_change_endpoint_description = {
     60        .transfer_type = USB_TRANSFER_INTERRUPT,
     61        .direction = USB_DIRECTION_IN,
     62        .interface_class = USB_CLASS_HUB,
     63        .flags = 0
     64};
     65
    5666
    5767//*********************************************
     
    6171//*********************************************
    6272
     73/**
     74 * Initialize connnections to host controller, device, and device
     75 * control endpoint
     76 * @param hub
     77 * @param device
     78 * @return
     79 */
     80static int usb_hub_init_communication(usb_hub_info_t * hub){
     81        int opResult;
     82        opResult = usb_device_connection_initialize_from_device(
     83                        &hub->device_connection,
     84                        hub->device);
     85        if(opResult != EOK){
     86                dprintf(USB_LOG_LEVEL_ERROR,
     87                                "could not initialize connection to hc, errno %d",opResult);
     88                return opResult;
     89        }
     90        opResult = usb_hc_connection_initialize_from_device(&hub->connection,
     91                        hub->device);
     92        if(opResult != EOK){
     93                dprintf(USB_LOG_LEVEL_ERROR,
     94                                "could not initialize connection to device, errno %d",opResult);
     95                return opResult;
     96        }
     97        opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
     98            &hub->device_connection);
     99        if(opResult != EOK){
     100                dprintf(USB_LOG_LEVEL_ERROR,
     101                                "could not initialize connection to device endpoint, errno %d",opResult);
     102        }
     103        return opResult;
     104}
     105
     106/**
     107 * When entering this function, hub->endpoints.control should be active.
     108 * @param hub
     109 * @return
     110 */
     111static int usb_hub_process_configuration_descriptors(
     112        usb_hub_info_t * hub){
     113        if(hub==NULL) {
     114                return EINVAL;
     115        }
     116        int opResult;
     117       
     118        //device descriptor
     119        usb_standard_device_descriptor_t std_descriptor;
     120        opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
     121            &std_descriptor);
     122        if(opResult!=EOK){
     123                dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
     124                return opResult;
     125        }
     126        dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",
     127                        std_descriptor.configuration_count);
     128        if(std_descriptor.configuration_count<1){
     129                dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
     130                //shouldn`t I return?
     131        }
     132
     133        //configuration descriptor
     134        /// \TODO check other configurations
     135        usb_standard_configuration_descriptor_t config_descriptor;
     136        opResult = usb_request_get_bare_configuration_descriptor(
     137            &hub->endpoints.control, 0,
     138        &config_descriptor);
     139        if(opResult!=EOK){
     140                dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     141                return opResult;
     142        }
     143        //set configuration
     144        opResult = usb_request_set_configuration(&hub->endpoints.control,
     145                config_descriptor.configuration_number);
     146
     147        if (opResult != EOK) {
     148                dprintf(USB_LOG_LEVEL_ERROR,
     149                                "something went wrong when setting hub`s configuration, %d",
     150                                opResult);
     151                return opResult;
     152        }
     153        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
     154                        config_descriptor.configuration_number);
     155
     156        //full configuration descriptor
     157        size_t transferred = 0;
     158        uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
     159        if (descriptors == NULL) {
     160                dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
     161                return ENOMEM;
     162        }
     163        opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
     164            0, descriptors,
     165            config_descriptor.total_length, &transferred);
     166        if(opResult!=EOK){
     167                free(descriptors);
     168                dprintf(USB_LOG_LEVEL_ERROR,
     169                                "could not get full configuration descriptor, %d",opResult);
     170                return opResult;
     171        }
     172        if (transferred != config_descriptor.total_length) {
     173                dprintf(USB_LOG_LEVEL_ERROR,
     174                                "received incorrect full configuration descriptor");
     175                return ELIMIT;
     176        }
     177
     178        /**
     179         * Initialize the interrupt in endpoint.
     180         * \TODO this code should be checked...
     181         */
     182        usb_endpoint_mapping_t endpoint_mapping[1] = {
     183                {
     184                        .pipe = &hub->endpoints.status_change,
     185                        .description = &status_change_endpoint_description,
     186                        .interface_no =
     187                            usb_device_get_assigned_interface(hub->device)
     188                }
     189        };
     190        opResult = usb_endpoint_pipe_initialize_from_configuration(
     191            endpoint_mapping, 1,
     192            descriptors, config_descriptor.total_length,
     193            &hub->device_connection);
     194        if (opResult != EOK) {
     195                dprintf(USB_LOG_LEVEL_ERROR,
     196                                "Failed to initialize status change pipe: %s",
     197                    str_error(opResult));
     198                return opResult;
     199        }
     200        if (!endpoint_mapping[0].present) {
     201                dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \
     202                    "cannot understand what is happenning");
     203                return EREFUSED;
     204        }
     205
     206        free(descriptors);
     207        return EOK;
     208       
     209
     210        // Initialize the interrupt(=status change) endpoint.
     211        /*usb_endpoint_pipe_initialize(
     212                &result->endpoints->status_change,
     213                &result->device_connection, );USB_TRANSFER_INTERRUPT
     214        USB_DIRECTION_IN*/
     215
     216}
     217
     218
     219/**
     220 * Create hub representation from device information.
     221 * @param device
     222 * @return pointer to created structure or NULL in case of error
     223 */
    63224usb_hub_info_t * usb_create_hub_info(device_t * device) {
    64225        usb_hub_info_t* result = usb_new(usb_hub_info_t);
    65         usb_device_connection_initialize_from_device(&result->device_connection,
    66                         device);
    67         usb_hc_connection_initialize_from_device(&result->connection,
    68                         device);
    69         usb_endpoint_pipe_initialize_default_control(&result->endpoints.control,
    70             &result->device_connection);
    71        
     226        result->device = device;
     227        int opResult;
     228        opResult = usb_hub_init_communication(result);
     229        if(opResult != EOK){
     230                free(result);
     231                return NULL;
     232        }
    72233
    73234        //result->device = device;
    74235        result->port_count = -1;
    75         /// \TODO is this correct? is the device stored?
    76236        result->device = device;
    77237
    78238        //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
    79        
     239        size_t received_size;
     240
    80241        // get hub descriptor
    81 
    82242        dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
    83243        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    84244        usb_hub_descriptor_t * descriptor;
    85         size_t received_size;
    86         int opResult;
    87245        dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
    88246        usb_endpoint_pipe_start_session(&result->endpoints.control);
     
    93251        usb_endpoint_pipe_end_session(&result->endpoints.control);
    94252
    95         /* Initialize the interrupt endpoint.
    96         usb_endpoint_pipe_initalize(
    97                 &hub_data->endpoints->status_change,
    98                 &endpiont_descriptor, &hub_data->connection);
    99 
    100          */ /// \TODO add this call
    101 
    102253        if (opResult != EOK) {
    103254                dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
     
    112263                return result;
    113264        }
     265
     266       
    114267        dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
    115268        result->port_count = descriptor->ports_count;
     
    133286}
    134287
     288/**
     289 * Create hub representation and add it into hub list
     290 * @param dev
     291 * @return
     292 */
    135293int usb_add_hub_device(device_t *dev) {
    136294        dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
    137295
    138         /*
    139          * We are some (probably deeply nested) hub.
    140          * Thus, assign our own operations and explore already
    141          * connected devices.
    142          */
    143296        dev->ops = &hub_device_ops;
    144297
    145 
    146298        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     299
     300        int opResult;
     301
     302        //perform final configurations
    147303        usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
    148 
     304        // process descriptors
     305        opResult = usb_hub_process_configuration_descriptors(hub_info);
     306        if(opResult != EOK){
     307                dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
     308                                opResult);
     309                return opResult;
     310        }
     311        //power ports
     312        usb_device_request_setup_packet_t request;
    149313        int port;
    150         int opResult;
    151         //usb_target_t target;
    152         //target.address = hub_info->usb_device->address;
    153         //target.endpoint = 0;
    154 
    155         //get configuration descriptor
    156         // this is not fully correct - there are more configurations
    157         // and all should be checked
    158         usb_standard_device_descriptor_t std_descriptor;
    159         opResult = usb_request_get_device_descriptor(&hub_info->endpoints.control,
    160             &std_descriptor);
    161         if(opResult!=EOK){
    162                 dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
    163                 return opResult;
    164         }
    165         dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",std_descriptor.configuration_count);
    166         if(std_descriptor.configuration_count<1){
    167                 dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
    168                 //shouldn`t I return?
    169         }
    170         /// \TODO check other configurations
    171         usb_standard_configuration_descriptor_t config_descriptor;
    172         opResult = usb_request_get_bare_configuration_descriptor(
    173             &hub_info->endpoints.control, 0,
    174         &config_descriptor);
    175         if(opResult!=EOK){
    176                 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
    177                 return opResult;
    178         }
    179         //set configuration
    180         opResult = usb_request_set_configuration(&hub_info->endpoints.control,
    181     config_descriptor.configuration_number);
    182 
    183         if (opResult != EOK) {
    184                 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when setting hub`s configuration, %d", opResult);
    185         }
    186 
    187         usb_device_request_setup_packet_t request;
    188314        for (port = 1; port < hub_info->port_count+1; ++port) {
    189315                usb_hub_set_power_port_request(&request, port);
     
    196322        }
    197323        //ports powered, hub seems to be enabled
    198 
    199324        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
    200         //async_hangup(hc);
    201325
    202326        //add the hub to list
     
    208332        //(void)hub_info;
    209333        usb_hub_check_hub_changes();
    210 
    211334       
    212 
    213335        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
    214336        //address is lost...
     
    216338                        //hub_info->endpoints.control.,
    217339                        hub_info->port_count);
    218         dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",config_descriptor.configuration_number);
    219340
    220341        return EOK;
Note: See TracChangeset for help on using the changeset viewer.