Changes in / [ef75332:8e423a2d] in mainline


Ignore:
Location:
uspace/lib/usb
Files:
3 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/Makefile

    ref75332 r8e423a2d  
    3434SOURCES = \
    3535        src/hcdhubd.c \
    36         src/hcdrv.c \
    37         src/hubdrv.c \
    3836        src/localdrv.c \
    3937        src/usb.c \
  • uspace/lib/usb/src/hcdhubd.c

    ref75332 r8e423a2d  
    3131 */
    3232/** @file
    33  * @brief Common stuff for both HC driver and hub driver.
     33 * @brief HC driver and hub driver (implementation).
    3434 */
    3535#include <usb/hcdhubd.h>
     
    4242#include <usb/classes/hub.h>
    4343
    44 #include "hcdhubd_private.h"
     44#define USB_HUB_DEVICE_NAME "usbhub"
     45
     46#define USB_KBD_DEVICE_NAME "hid"
     47
     48
     49
     50
     51/** List of handled host controllers. */
     52static LIST_INITIALIZE(hc_list);
     53
     54/** Our HC driver. */
     55static usb_hc_driver_t *hc_driver = NULL;
     56
     57static usbhc_iface_t usb_interface = {
     58        .interrupt_out = NULL,
     59        .interrupt_in = NULL
     60};
     61
     62static device_ops_t usb_device_ops = {
     63        .interfaces[USBHC_DEV_IFACE] = &usb_interface
     64};
     65
     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
     131static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
     132
     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}
    45151
    46152/** Callback when new device is detected and must be handled by this driver.
    47153 *
    48154 * @param dev New device.
    49  * @return Error code.
     155 * @return Error code.hub added, hurrah!\n"
    50156 */
    51157static int add_device(device_t *dev) {
     158        /*
     159         * FIXME: use some magic to determine whether hub or another HC
     160         * was connected.
     161         */
    52162        bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0;
    53163        printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name);
     
    57167                 * We are the HC itself.
    58168                 */
    59                 return usb_add_hc_device(dev);
     169                usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));
     170                list_initialize(&hc_dev->link);
     171                hc_dev->transfer_ops = NULL;
     172
     173                hc_dev->generic = dev;
     174                dev->ops = &usb_device_ops;
     175                hc_dev->generic->driver_data = hc_dev;
     176
     177                int rc = hc_driver->add_hc(hc_dev);
     178                if (rc != EOK) {
     179                        free(hc_dev);
     180                        return rc;
     181                }
     182
     183                /*
     184                 * FIXME: The following line causes devman to hang.
     185                 * Will investigate later why.
     186                 */
     187                // add_device_to_class(dev, "usbhc");
     188
     189                list_append(&hc_dev->link, &hc_list);
     190
     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);
     230                return EOK;
     231
     232
     233
    60234        } else {
     235                usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
     236                set_hub_address(hc, 5);
     237
    61238                /*
    62                  * We are some (maybe deeply nested) hub.
     239                 * We are some (probably deeply nested) hub.
    63240                 * Thus, assign our own operations and explore already
    64241                 * connected devices.
    65242                 */
    66                 return usb_add_hub_device(dev);
     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;
     269        }
     270}
     271
     272/** Sample usage of usb_hc_async functions.
     273 * This function sets hub address using standard SET_ADDRESS request.
     274 *
     275 * @warning This function shall be removed once you are familiar with
     276 * the usb_hc_ API.
     277 *
     278 * @param hc Host controller the hub belongs to.
     279 * @param address New hub address.
     280 */
     281static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
     282        printf("%s: setting hub address to %d\n", hc->generic->name, address);
     283        usb_target_t target = {0, 0};
     284        usb_handle_t handle;
     285        int rc;
     286
     287        usb_device_request_setup_packet_t setup_packet = {
     288                .request_type = 0,
     289                .request = USB_DEVREQ_SET_ADDRESS,
     290                .index = 0,
     291                .length = 0,
     292        };
     293        setup_packet.value = address;
     294
     295        rc = usb_hc_async_control_write_setup(hc, target,
     296                        &setup_packet, sizeof (setup_packet), &handle);
     297        if (rc != EOK) {
     298                return;
     299        }
     300
     301        rc = usb_hc_async_wait_for(handle);
     302        if (rc != EOK) {
     303                return;
     304        }
     305
     306        rc = usb_hc_async_control_write_status(hc, target, &handle);
     307        if (rc != EOK) {
     308                return;
     309        }
     310
     311        rc = usb_hc_async_wait_for(handle);
     312        if (rc != EOK) {
     313                return;
     314        }
     315
     316        printf("%s: hub address changed\n", hc->generic->name);
     317}
     318
     319/** Check changes on all known hubs.
     320 */
     321static void check_hub_changes(void) {
     322        /*
     323         * Iterate through all HCs.
     324         */
     325        link_t *link_hc;
     326        for (link_hc = hc_list.next;
     327                        link_hc != &hc_list;
     328                        link_hc = link_hc->next) {
     329                usb_hc_device_t *hc = list_get_instance(link_hc,
     330                                usb_hc_device_t, link);
     331                /*
     332                 * Iterate through all their hubs.
     333                 */
     334                link_t *link_hub;
     335                for (link_hub = hc->hubs.next;
     336                                link_hub != &hc->hubs;
     337                                link_hub = link_hub->next) {
     338                        usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
     339                                        usb_hcd_hub_info_t, link);
     340
     341                        /*
     342                         * Check status change pipe of this hub.
     343                         */
     344                        usb_target_t target = {
     345                                .address = hub->device->address,
     346                                .endpoint = 1
     347                        };
     348
     349                        // FIXME: count properly
     350                        size_t byte_length = (hub->port_count / 8) + 1;
     351
     352                        void *change_bitmap = malloc(byte_length);
     353                        size_t actual_size;
     354                        usb_handle_t handle;
     355
     356                        /*
     357                         * Send the request.
     358                         * FIXME: check returned value for possible errors
     359                         */
     360                        usb_hc_async_interrupt_in(hc, target,
     361                                        change_bitmap, byte_length, &actual_size,
     362                                        &handle);
     363
     364                        usb_hc_async_wait_for(handle);
     365
     366                        /*
     367                         * TODO: handle the changes.
     368                         */
     369                }
    67370        }
    68371}
     
    88391        hc_driver = hc;
    89392        hc_driver_generic.name = hc->name;
     393
     394        /*
     395         * Launch here fibril that will periodically check all
     396         * attached hubs for status change.
     397         * WARN: This call will effectively do nothing.
     398         */
     399        check_hub_changes();
    90400
    91401        /*
Note: See TracChangeset for help on using the changeset viewer.