Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/hcdhubd.c

    re4dbfda rdac43be  
    3131 */
    3232/** @file
    33  * @brief HC driver and hub driver (implementation).
     33 * @brief Common stuff for both HC driver and hub driver.
    3434 */
    3535#include <usb/hcdhubd.h>
    3636#include <usb/devreq.h>
    3737#include <usbhc_iface.h>
     38#include <usb/descriptor.h>
    3839#include <driver.h>
    3940#include <bool.h>
    4041#include <errno.h>
    41 
    42 #define USB_HUB_DEVICE_NAME "usbhub"
    43 
    44 /** List of handled host controllers. */
    45 static LIST_INITIALIZE(hc_list);
    46 
    47 /** Our HC driver. */
    48 static usb_hc_driver_t *hc_driver = NULL;
    49 
    50 static usbhc_iface_t usb_interface = {
    51         .interrupt_out = NULL,
    52         .interrupt_in = NULL
    53 };
    54 
    55 static device_ops_t usb_device_ops = {
    56         .interfaces[USBHC_DEV_IFACE] = &usb_interface
    57 };
    58 
    59 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
     42#include <usb/classes/hub.h>
     43
     44#include "hcdhubd_private.h"
    6045
    6146/** Callback when new device is detected and must be handled by this driver.
     
    6449 * @return Error code.
    6550 */
    66 static int add_device(device_t *dev)
    67 {
    68         /*
    69          * FIXME: use some magic to determine whether hub or another HC
    70          * was connected.
    71          */
     51static int add_device(device_t *dev) {
    7252        bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0;
    7353        printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name);
     
    7757                 * We are the HC itself.
    7858                 */
    79                 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t));
    80                 list_initialize(&hc_dev->link);
    81                 hc_dev->transfer_ops = NULL;
    82 
    83                 hc_dev->generic = dev;
    84                 dev->ops = &usb_device_ops;
    85                 hc_dev->generic->driver_data = hc_dev;
    86 
    87                 int rc = hc_driver->add_hc(hc_dev);
    88                 if (rc != EOK) {
    89                         free(hc_dev);
    90                         return rc;
    91                 }
    92 
     59                return usb_add_hc_device(dev);
     60        } else {
    9361                /*
    94                  * FIXME: The following line causes devman to hang.
    95                  * Will investigate later why.
    96                  */
    97                 // add_device_to_class(dev, "usbhc");
    98 
    99                 list_append(&hc_dev->link, &hc_list);
    100 
    101                 return EOK;
    102         } else {
    103                 usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
    104                 set_hub_address(hc, 5);
    105 
    106                 /*
    107                  * We are some (probably deeply nested) hub.
     62                 * We are some (maybe deeply nested) hub.
    10863                 * Thus, assign our own operations and explore already
    10964                 * connected devices.
    11065                 */
    111 
    112                 return ENOTSUP;
    113         }
    114 }
    115 
    116 /** Sample usage of usb_hc_async functions.
    117  * This function sets hub address using standard SET_ADDRESS request.
    118  *
    119  * @warning This function shall be removed once you are familiar with
    120  * the usb_hc_ API.
    121  *
    122  * @param hc Host controller the hub belongs to.
    123  * @param address New hub address.
    124  */
    125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address)
    126 {
    127         printf("%s: setting hub address to %d\n", hc->generic->name, address);
    128         usb_target_t target = {0, 0};
    129         usb_handle_t handle;
    130         int rc;
    131 
    132         usb_device_request_setup_packet_t setup_packet = {
    133                 .request_type = 0,
    134                 .request = USB_DEVREQ_SET_ADDRESS,
    135                 .index = 0,
    136                 .length = 0,
    137         };
    138         setup_packet.value = address;
    139 
    140         rc = usb_hc_async_control_write_setup(hc, target,
    141             &setup_packet, sizeof(setup_packet), &handle);
    142         if (rc != EOK) {
    143                 return;
    144         }
    145 
    146         rc = usb_hc_async_wait_for(handle);
    147         if (rc != EOK) {
    148                 return;
    149         }
    150 
    151         rc = usb_hc_async_control_write_status(hc, target, &handle);
    152         if (rc != EOK) {
    153                 return;
    154         }
    155 
    156         rc = usb_hc_async_wait_for(handle);
    157         if (rc != EOK) {
    158                 return;
    159         }
    160 
    161         printf("%s: hub address changed\n", hc->generic->name);
    162 }
    163 
    164 /** Check changes on all known hubs.
    165  */
    166 static void check_hub_changes(void)
    167 {
    168         /*
    169          * Iterate through all HCs.
    170          */
    171         link_t *link_hc;
    172         for (link_hc = hc_list.next;
    173             link_hc != &hc_list;
    174             link_hc = link_hc->next) {
    175                 usb_hc_device_t *hc = list_get_instance(link_hc,
    176                     usb_hc_device_t, link);
    177                 /*
    178                  * Iterate through all their hubs.
    179                  */
    180                 link_t *link_hub;
    181                 for (link_hub = hc->hubs.next;
    182                     link_hub != &hc->hubs;
    183                     link_hub = link_hub->next) {
    184                         usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
    185                             usb_hcd_hub_info_t, link);
    186 
    187                         /*
    188                          * Check status change pipe of this hub.
    189                          */
    190                         usb_target_t target = {
    191                                 .address = hub->device->address,
    192                                 .endpoint = 1
    193                         };
    194 
    195                         // FIXME: count properly
    196                         size_t byte_length = (hub->port_count / 8) + 1;
    197 
    198                         void *change_bitmap = malloc(byte_length);
    199                         size_t actual_size;
    200                         usb_handle_t handle;
    201 
    202                         /*
    203                          * Send the request.
    204                          * FIXME: check returned value for possible errors
    205                          */
    206                         usb_hc_async_interrupt_in(hc, target,
    207                             change_bitmap, byte_length, &actual_size,
    208                             &handle);
    209 
    210                         usb_hc_async_wait_for(handle);
    211 
    212                         /*
    213                          * TODO: handle the changes.
    214                          */
    215                 }
     66                return usb_add_hub_device(dev);
    21667        }
    21768}
     
    23485 * @return Error code.
    23586 */
    236 int usb_hcd_main(usb_hc_driver_t *hc)
    237 {
     87int usb_hcd_main(usb_hc_driver_t *hc) {
    23888        hc_driver = hc;
    23989        hc_driver_generic.name = hc->name;
    240 
    241         /*
    242          * Launch here fibril that will periodically check all
    243          * attached hubs for status change.
    244          * WARN: This call will effectively do nothing.
    245          */
    246         check_hub_changes();
    24790
    24891        /*
Note: See TracChangeset for help on using the changeset viewer.