Ignore:
File:
1 edited

Legend:

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

    re4dbfda rda55d5b  
    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>
     42#include <usb/classes/hub.h>
    4143
    4244#define USB_HUB_DEVICE_NAME "usbhub"
     45
     46#define USB_KBD_DEVICE_NAME "hid"
     47
     48
     49
    4350
    4451/** List of handled host controllers. */
     
    5764};
    5865
     66size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
     67
     68uint8_t USB_HUB_DESCRIPTOR_TYPE = 0x29;
     69
     70//*********************************************
     71//
     72//  various utils
     73//
     74//*********************************************
     75
     76void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     77        //base size
     78        size_t size = 7;
     79        //variable size according to port count
     80        size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8 > 0) ? 1 : 0);
     81        size += 2 * var_size;
     82        uint8_t * result = (uint8_t*) malloc(size);
     83        //size
     84        result[0] = size;
     85        //descriptor type
     86        result[1] = USB_DESCTYPE_HUB;
     87        result[2] = descriptor->ports_count;
     88        /// @fixme handling of endianness??
     89        result[3] = descriptor->hub_characteristics / 256;
     90        result[4] = descriptor->hub_characteristics % 256;
     91        result[5] = descriptor->pwr_on_2_good_time;
     92        result[6] = descriptor->current_requirement;
     93
     94        size_t i;
     95        for (i = 0; i < var_size; ++i) {
     96                result[7 + i] = descriptor->devices_removable[i];
     97        }
     98        for (i = 0; i < var_size; ++i) {
     99                result[7 + var_size + i] = 255;
     100        }
     101        return result;
     102}
     103
     104usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
     105        uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
     106        if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL;
     107        usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t));
     108        //uint8_t size = sdescriptor[0];
     109        result->ports_count = sdescriptor[2];
     110        /// @fixme handling of endianness??
     111        result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
     112        result->pwr_on_2_good_time = sdescriptor[5];
     113        result->current_requirement = sdescriptor[6];
     114        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
     115        result->devices_removable = (uint8_t*) malloc(var_size);
     116
     117        size_t i;
     118        for (i = 0; i < var_size; ++i) {
     119                result->devices_removable[i] = sdescriptor[7 + i];
     120        }
     121        return result;
     122}
     123
     124
     125//*********************************************
     126//
     127//  hub driver code
     128//
     129//*********************************************
     130
    59131static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
    60132
     133usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
     134        usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
     135        //get parent device
     136        /// @TODO this code is not correct
     137        device_t * my_hcd = device;
     138        while (my_hcd->parent)
     139                my_hcd = my_hcd->parent;
     140        //dev->
     141        printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     142        //we add the hub into the first hc
     143        //link_t *link_hc = hc_list.next;
     144        //usb_hc_device_t *hc = list_get_instance(link_hc,
     145        //              usb_hc_device_t, link);
     146        //must get generic device info
     147
     148
     149        return result;
     150}
     151
    61152/** Callback when new device is detected and must be handled by this driver.
    62153 *
    63154 * @param dev New device.
    64  * @return Error code.
    65  */
    66 static int add_device(device_t *dev)
    67 {
     155 * @return Error code.hub added, hurrah!\n"
     156 */
     157static int add_device(device_t *dev) {
    68158        /*
    69159         * FIXME: use some magic to determine whether hub or another HC
     
    77167                 * We are the HC itself.
    78168                 */
    79                 usb_hc_device_t *hc_dev = malloc(sizeof(usb_hc_device_t));
     169                usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));
    80170                list_initialize(&hc_dev->link);
    81171                hc_dev->transfer_ops = NULL;
     
    99189                list_append(&hc_dev->link, &hc_list);
    100190
     191                //add keyboard
     192                /// @TODO this is not correct code
     193               
     194                /*
     195                 * Announce presence of child device.
     196                 */
     197                device_t *kbd = NULL;
     198                match_id_t *match_id = NULL;
     199
     200                kbd = create_device();
     201                if (kbd == NULL) {
     202                        printf("ERROR: enomem\n");
     203                }
     204                kbd->name = USB_KBD_DEVICE_NAME;
     205
     206                match_id = create_match_id();
     207                if (match_id == NULL) {
     208                        printf("ERROR: enomem\n");
     209                }
     210
     211                char *id;
     212                rc = asprintf(&id, USB_KBD_DEVICE_NAME);
     213                if (rc <= 0) {
     214                        printf("ERROR: enomem\n");
     215                        return rc;
     216                }
     217
     218                match_id->id = id;
     219                match_id->score = 30;
     220
     221                add_match_id(&kbd->match_ids, match_id);
     222
     223                rc = child_device_register(kbd, dev);
     224                if (rc != EOK) {
     225                        printf("ERROR: cannot register kbd\n");
     226                        return rc;
     227                }
     228
     229                printf("%s: registered root hub\n", dev->name);
    101230                return EOK;
     231
     232
     233
    102234        } else {
    103235                usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
     
    109241                 * connected devices.
    110242                 */
    111 
    112                 return ENOTSUP;
     243                //insert hub into list
     244                //find owner hcd
     245                device_t * my_hcd = dev;
     246                while (my_hcd->parent)
     247                        my_hcd = my_hcd->parent;
     248                //dev->
     249                printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     250                my_hcd = dev;
     251                while (my_hcd->parent)
     252                        my_hcd = my_hcd->parent;
     253                //dev->
     254
     255                printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     256               
     257                //create the hub structure
     258                usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
     259
     260
     261                //append into the list
     262                //we add the hub into the first hc
     263                list_append(&hub_info->link, &hc->hubs);
     264
     265
     266
     267                return EOK;
     268                //return ENOTSUP;
    113269        }
    114270}
     
    123279 * @param address New hub address.
    124280 */
    125 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address)
    126 {
     281static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
    127282        printf("%s: setting hub address to %d\n", hc->generic->name, address);
    128283        usb_target_t target = {0, 0};
     
    139294
    140295        rc = usb_hc_async_control_write_setup(hc, target,
    141             &setup_packet, sizeof(setup_packet), &handle);
     296                        &setup_packet, sizeof (setup_packet), &handle);
    142297        if (rc != EOK) {
    143298                return;
     
    164319/** Check changes on all known hubs.
    165320 */
    166 static void check_hub_changes(void)
    167 {
     321static void check_hub_changes(void) {
    168322        /*
    169323         * Iterate through all HCs.
     
    171325        link_t *link_hc;
    172326        for (link_hc = hc_list.next;
    173             link_hc != &hc_list;
    174             link_hc = link_hc->next) {
     327                        link_hc != &hc_list;
     328                        link_hc = link_hc->next) {
    175329                usb_hc_device_t *hc = list_get_instance(link_hc,
    176                     usb_hc_device_t, link);
     330                                usb_hc_device_t, link);
    177331                /*
    178332                 * Iterate through all their hubs.
     
    180334                link_t *link_hub;
    181335                for (link_hub = hc->hubs.next;
    182                     link_hub != &hc->hubs;
    183                     link_hub = link_hub->next) {
     336                                link_hub != &hc->hubs;
     337                                link_hub = link_hub->next) {
    184338                        usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
    185                             usb_hcd_hub_info_t, link);
     339                                        usb_hcd_hub_info_t, link);
    186340
    187341                        /*
     
    205359                         */
    206360                        usb_hc_async_interrupt_in(hc, target,
    207                             change_bitmap, byte_length, &actual_size,
    208                             &handle);
     361                                        change_bitmap, byte_length, &actual_size,
     362                                        &handle);
    209363
    210364                        usb_hc_async_wait_for(handle);
     
    234388 * @return Error code.
    235389 */
    236 int usb_hcd_main(usb_hc_driver_t *hc)
    237 {
     390int usb_hcd_main(usb_hc_driver_t *hc) {
    238391        hc_driver = hc;
    239392        hc_driver_generic.name = hc->name;
     
    261414 * @return Error code.
    262415 */
    263 int usb_hcd_add_root_hub(usb_hc_device_t *dev)
    264 {
    265         char *id;
    266         int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name);
    267         if (rc <= 0) {
    268                 return rc;
    269         }
    270 
    271         rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id);
    272         if (rc != EOK) {
    273                 free(id);
    274         }
    275 
    276         return rc;
    277 }
    278 
    279 /** Info about child device. */
    280 struct child_device_info {
    281         device_t *parent;
    282         const char *name;
    283         const char *match_id;
    284 };
    285 
    286 /** Adds a child device fibril worker. */
    287 static int fibril_add_child_device(void *arg)
    288 {
    289         struct child_device_info *child_info
    290             = (struct child_device_info *) arg;
     416int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
    291417        int rc;
    292418
    293         device_t *child = create_device();
     419        /*
     420         * Announce presence of child device.
     421         */
     422        device_t *hub = NULL;
    294423        match_id_t *match_id = NULL;
    295424
    296         if (child == NULL) {
     425        hub = create_device();
     426        if (hub == NULL) {
    297427                rc = ENOMEM;
    298428                goto failure;
    299429        }
    300         child->name = child_info->name;
     430        hub->name = USB_HUB_DEVICE_NAME;
    301431
    302432        match_id = create_match_id();
     
    305435                goto failure;
    306436        }
    307         match_id->id = child_info->match_id;
    308         match_id->score = 10;
    309         printf("adding child device with match \"%s\"\n", match_id->id);
    310         add_match_id(&child->match_ids, match_id);
    311 
    312         rc = child_device_register(child, child_info->parent);
     437
     438        char *id;
     439        rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name);
     440        if (rc <= 0) {
     441                rc = ENOMEM;
     442                goto failure;
     443        }
     444
     445        match_id->id = id;
     446        match_id->score = 30;
     447
     448        add_match_id(&hub->match_ids, match_id);
     449
     450        rc = child_device_register(hub, dev->generic);
    313451        if (rc != EOK) {
    314452                goto failure;
    315453        }
    316454
    317         goto leave;
     455        printf("%s: registered root hub\n", dev->generic->name);
     456        return EOK;
    318457
    319458failure:
    320         if (child != NULL) {
    321                 child->name = NULL;
    322                 delete_device(child);
    323         }
    324 
    325         if (match_id != NULL) {
    326                 match_id->id = NULL;
    327                 delete_match_id(match_id);
    328         }
    329 
    330 leave:
    331         free(arg);
     459        if (hub != NULL) {
     460                hub->name = NULL;
     461                delete_device(hub);
     462        }
     463        delete_match_id(match_id);
     464
    332465        return rc;
    333 }
    334 
    335 /** Adds a child.
    336  * Due to deadlock in devman when parent registers child that oughts to be
    337  * driven by the same task, the child adding is done in separate fibril.
    338  * Not optimal, but it works.
    339  *
    340  * @param parent Parent device.
    341  * @param name Device name.
    342  * @param match_id Match id.
    343  * @return Error code.
    344  */
    345 int usb_hc_add_child_device(device_t *parent, const char *name,
    346     const char *match_id)
    347 {
    348         struct child_device_info *child_info
    349             = malloc(sizeof(struct child_device_info));
    350 
    351         child_info->parent = parent;
    352         child_info->name = name;
    353         child_info->match_id = match_id;
    354 
    355         fid_t fibril = fibril_create(fibril_add_child_device, child_info);
    356         if (!fibril) {
    357                 return ENOMEM;
    358         }
    359         fibril_add_ready(fibril);
    360 
    361         return EOK;
    362466}
    363467
Note: See TracChangeset for help on using the changeset viewer.