Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a822cd8 in mainline


Ignore:
Timestamp:
2010-12-12T14:16:57Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
1f3158c, c9113d2
Parents:
a59cdd2 (diff), 0c05496 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development changes/

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/virtusbkbd/Makefile

    ra59cdd2 ra822cd8  
    3333
    3434LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
    35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX)
     35EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include
    3636
    3737SOURCES = \
  • uspace/drv/usbkbd/main.c

    ra59cdd2 ra822cd8  
    2828#include <usb/usbdrv.h>
    2929#include <driver.h>
     30#include <ipc/driver.h>
    3031#include <errno.h>
     32#include <fibril.h>
     33#include <usb/classes/hid.h>
     34#include <usb/classes/hidparser.h>
     35#include <usb/devreq.h>
     36#include <usb/descriptor.h>
    3137
    3238#define BUFFER_SIZE 32
    33 
    34 /* Call this periodically to check keyboard status changes. */
    35 static void poll_keyboard(device_t *dev)
     39#define NAME "usbkbd"
     40
     41static const usb_endpoint_t CONTROL_EP = 0;
     42
     43/*
     44 * Callbacks for parser
     45 */
     46static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
     47                                    void *arg)
     48{
     49
     50}
     51
     52/*
     53 * Kbd functions
     54 */
     55static int usbkbd_parse_descriptors(usb_hid_dev_kbd_t *kbd_dev,
     56                                    const uint8_t *data, size_t size)
     57{
     58//      const uint8_t *pos = data;
     59       
     60//      // get the configuration descriptor (should be first)
     61//      if (*pos != sizeof(usb_standard_configuration_descriptor_t)
     62//          || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) {
     63//              fprintf(stderr, "Wrong format of configuration descriptor");
     64//              return EINVAL;
     65//      }
     66       
     67//      usb_standard_configuration_descriptor_t config_descriptor;
     68//      memcpy(&config_descriptor, pos,
     69//          sizeof(usb_standard_configuration_descriptor_t));
     70//      pos += sizeof(usb_standard_configuration_descriptor_t);
     71       
     72//      // parse other descriptors
     73//      while (pos - data < size) {
     74//              //uint8_t desc_size = *pos;
     75//              uint8_t desc_type = *(pos + 1);
     76//              switch (desc_type) {
     77//              case USB_DESCTYPE_INTERFACE:
     78//                      break;
     79//              case USB_DESCTYPE_ENDPOINT:
     80//                      break;
     81//              case USB_DESCTYPE_HID:
     82//                      break;
     83//              case USB_DESCTYPE_HID_REPORT:
     84//                      break;
     85//              case USB_DESCTYPE_HID_PHYSICAL:
     86//                      break;
     87//              }
     88//      }
     89       
     90        return EOK;
     91}
     92
     93static int usbkbd_get_descriptors(usb_hid_dev_kbd_t *kbd_dev)
     94{
     95        // get the first configuration descriptor (TODO: or some other??)
     96        usb_standard_configuration_descriptor_t config_desc;
     97       
     98        int rc = usb_drv_req_get_bare_configuration_descriptor(
     99            kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
     100       
     101        if (rc != EOK) {
     102                return rc;
     103        }
     104       
     105        // prepare space for all underlying descriptors
     106        uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
     107        if (descriptors == NULL) {
     108                return ENOMEM;
     109        }
     110       
     111        size_t transferred = 0;
     112        // get full configuration descriptor
     113        rc = usb_drv_req_get_full_configuration_descriptor(
     114            kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
     115            config_desc.total_length, &transferred);
     116       
     117        if (rc != EOK) {
     118                return rc;
     119        }
     120        if (transferred != config_desc.total_length) {
     121                return ELIMIT;
     122        }
     123       
     124        rc = usbkbd_parse_descriptors(kbd_dev, descriptors, transferred);
     125        free(descriptors);
     126       
     127        return rc;
     128}
     129
     130static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
     131{
     132        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
     133                        sizeof(usb_hid_dev_kbd_t));
     134
     135        if (kbd_dev == NULL) {
     136                fprintf(stderr, NAME ": No memory!\n");
     137                return NULL;
     138        }
     139
     140        kbd_dev->device = dev;
     141
     142        // get phone to my HC and save it as my parent's phone
     143        // TODO: maybe not a good idea if DDF will use parent_phone
     144        kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
     145
     146        kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
     147            dev);
     148
     149        // doesn't matter now that we have no address
     150//      if (kbd_dev->address < 0) {
     151//              fprintf(stderr, NAME ": No device address!\n");
     152//              free(kbd_dev);
     153//              return NULL;
     154//      }
     155
     156        // default endpoint
     157        kbd_dev->default_ep = CONTROL_EP;
     158       
     159        /*
     160         * will need all descriptors:
     161         * 1) choose one configuration from configuration descriptors
     162         *    (set it to the device)
     163         * 2) set endpoints from endpoint descriptors
     164         */
     165
     166        // TODO: get descriptors
     167        usbkbd_get_descriptors(kbd_dev);
     168        // TODO: parse descriptors and save endpoints
     169
     170        return kbd_dev;
     171}
     172
     173static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
     174                                        uint8_t *buffer, size_t actual_size)
     175{
     176        /*
     177         * here, the parser will be called, probably with some callbacks
     178         * now only take last 6 bytes and process, i.e. send to kbd
     179         */
     180
     181        usb_hid_report_in_callbacks_t *callbacks =
     182            (usb_hid_report_in_callbacks_t *)malloc(
     183                sizeof(usb_hid_report_in_callbacks_t));
     184        callbacks->keyboard = usbkbd_process_keycodes;
     185
     186        usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
     187            NULL);
     188}
     189
     190static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    36191{
    37192        int rc;
    38193        usb_handle_t handle;
    39         char buffer[BUFFER_SIZE];
     194        uint8_t buffer[BUFFER_SIZE];
    40195        size_t actual_size;
    41         usb_endpoint_t poll_endpoint = 1;
    42 
    43         usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
    44             dev);
    45         if (my_address < 0) {
    46                 return;
    47         }
     196        //usb_endpoint_t poll_endpoint = 1;
     197
     198//      usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
     199//          dev);
     200//      if (my_address < 0) {
     201//              return;
     202//      }
    48203
    49204        usb_target_t poll_target = {
    50                 .address = my_address,
    51                 .endpoint = poll_endpoint
     205                .address = kbd_dev->address,
     206                .endpoint = kbd_dev->default_ep
    52207        };
    53208
    54         rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
    55             buffer, BUFFER_SIZE, &actual_size, &handle);
    56         if (rc != EOK) {
    57                 return;
    58         }
    59 
    60         rc = usb_drv_async_wait_for(handle);
    61         if (rc != EOK) {
    62                 return;
    63         }
    64 
    65         /*
    66          * If the keyboard answered with NAK, it returned no data.
    67          * This implies that no change happened since last query.
    68          */
    69         if (actual_size == 0) {
    70                 return;
    71         }
    72 
    73         /*
    74          * Process pressed keys.
    75          */
    76 }
    77 
    78 static int add_kbd_device(device_t *dev)
     209        while (true) {
     210                rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
     211                    poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
     212
     213                if (rc != EOK) {
     214                        continue;
     215                }
     216
     217                rc = usb_drv_async_wait_for(handle);
     218                if (rc != EOK) {
     219                        continue;
     220                }
     221
     222                /*
     223                 * If the keyboard answered with NAK, it returned no data.
     224                 * This implies that no change happened since last query.
     225                 */
     226                if (actual_size == 0) {
     227                        continue;
     228                }
     229
     230                /*
     231                 * TODO: Process pressed keys.
     232                 */
     233                usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
     234        }
     235
     236        // not reached
     237        assert(0);
     238}
     239
     240static int usbkbd_fibril_device(void *arg)
     241{
     242        printf("!!! USB device fibril\n");
     243
     244        if (arg == NULL) {
     245                printf("No device!\n");
     246                return -1;
     247        }
     248
     249        device_t *dev = (device_t *)arg;
     250
     251        // initialize device (get and process descriptors, get address, etc.)
     252        usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
     253
     254        usbkbd_poll_keyboard(kbd_dev);
     255
     256        return EOK;
     257}
     258
     259static int usbkbd_add_device(device_t *dev)
    79260{
    80261        /* For now, fail immediately. */
    81         return ENOTSUP;
     262        //return ENOTSUP;
    82263
    83264        /*
    84265         * When everything is okay, connect to "our" HC.
    85          */
    86         int phone = usb_drv_hc_connect(dev, 0);
    87         if (phone < 0) {
    88                 /*
    89                  * Connecting to HC failed, roll-back and announce
    90                  * failure.
    91                  */
    92                 return phone;
    93         }
    94 
    95         dev->parent_phone = phone;
    96 
    97         /*
    98          * Just for fun ;-).
    99          */
    100         poll_keyboard(dev);
     266         *
     267         * Not supported yet, skip..
     268         */
     269//      int phone = usb_drv_hc_connect(dev, 0);
     270//      if (phone < 0) {
     271//              /*
     272//               * Connecting to HC failed, roll-back and announce
     273//               * failure.
     274//               */
     275//              return phone;
     276//      }
     277
     278//      dev->parent_phone = phone;
     279
     280        /*
     281         * Create new fibril for handling this keyboard
     282         */
     283        fid_t fid = fibril_create(usbkbd_fibril_device, dev);
     284        if (fid == 0) {
     285                printf("%s: failed to start fibril for HID device\n", NAME);
     286                return ENOMEM;
     287        }
     288        fibril_add_ready(fid);
    101289
    102290        /*
     
    107295
    108296static driver_ops_t kbd_driver_ops = {
    109         .add_device = add_kbd_device,
     297        .add_device = usbkbd_add_device,
    110298};
    111299
    112300static driver_t kbd_driver = {
    113         .name = "usbkbd",
     301        .name = NAME,
    114302        .driver_ops = &kbd_driver_ops
    115303};
  • uspace/lib/usb/include/usb/classes/hid.h

    ra59cdd2 ra822cd8  
    3636#define LIBUSB_HID_H_
    3737
     38#include <usb/usb.h>
     39#include <driver.h>
     40#include <usb/classes/hidparser.h>
     41
    3842/** USB/HID device requests. */
    3943typedef enum {
     
    5458} usb_hid_protocol_t;
    5559
     60/** Part of standard USB HID descriptor specifying one class descriptor.
     61 *
     62 * (See HID Specification, p.22)
     63 */
     64typedef struct {
     65        /** Type of class descriptor (Report or Physical). */
     66        uint8_t class_descriptor_type;
     67        /** Length of class descriptor. */
     68        uint16_t class_descriptor_length;
     69} __attribute__ ((packed)) usb_standard_hid_descriptor_class_item_t;
     70
     71/** Standard USB HID descriptor.
     72 *
     73 * (See HID Specification, p.22)
     74 *
     75 * It is actually only the "header" of the descriptor, as it may have arbitrary
     76 * length if more than one class descritor is provided.
     77 */
     78typedef struct {
     79        /** Size of this descriptor in bytes. */
     80        uint8_t length;
     81        /** Descriptor type (USB_DESCTYPE_HID). */
     82        uint8_t descriptor_type;
     83        /** HID Class Specification release. */
     84        uint16_t spec_release;
     85        /** Country code of localized hardware. */
     86        uint8_t country_code;
     87        /** Total number of class (i.e. Report and Physical) descriptors. */
     88        uint8_t class_count;
     89        /** First mandatory class descriptor info. */
     90        usb_standard_hid_descriptor_class_item_t class_descriptor;
     91} __attribute__ ((packed)) usb_standard_hid_descriptor_t;
     92
     93
     94/**
     95 * @brief USB/HID keyboard device type.
     96 *
     97 * Quite dummy right now.
     98 */
     99typedef struct {
     100        device_t *device;
     101        usb_address_t address;
     102        usb_endpoint_t default_ep;
     103        usb_hid_report_parser_t *parser;
     104} usb_hid_dev_kbd_t;
     105
    56106#endif
    57107/**
  • uspace/lib/usb/include/usb/classes/hidparser.h

    ra59cdd2 ra822cd8  
    5050         * @param arg Custom argument.
    5151         */
    52         void (*keyboard)(const uint32_t *key_codes, size_t count, void *arg);
     52        void (*keyboard)(const uint16_t *key_codes, size_t count, void *arg);
    5353} usb_hid_report_in_callbacks_t;
    5454
    5555int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    56     const uint8_t *data);
     56    const uint8_t *data, size_t size);
    5757
    5858int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    59     const uint8_t *data,
     59    const uint8_t *data, size_t size,
    6060    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    6161
  • uspace/lib/usb/src/hidparser.c

    ra59cdd2 ra822cd8  
    4040 * @param parser Opaque HID report parser structure.
    4141 * @param data Data describing the report.
     42 * @param size Size of the descriptor in bytes.
    4243 * @return Error code.
    4344 */
    4445int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    45     const uint8_t *data)
     46    const uint8_t *data, size_t size)
    4647{
    4748        return ENOTSUP;
     
    5455 * @param parser Opaque HID report parser structure.
    5556 * @param data Data for the report.
     57 * @param size Size of the data in bytes.
    5658 * @param callbacks Callbacks for report actions.
    5759 * @param arg Custom argument (passed through to the callbacks).
     
    5961 */
    6062int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    61     const uint8_t *data,
     63    const uint8_t *data, size_t size,
    6264    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    6365{
    64         return ENOTSUP;
     66        int i;
     67       
     68        // TODO: parse report
     69       
     70        uint16_t keys[6];
     71       
     72        for (i = 0; i < 6; ++i) {
     73                keys[i] = data[i];
     74        }
     75       
     76        callbacks->keyboard(keys, 6, arg);
     77       
     78        return EOK;
    6579}
    6680
  • uspace/lib/usb/src/usbdrvreq.c

    ra59cdd2 ra822cd8  
    162162                .request = USB_DEVREQ_GET_DESCRIPTOR,
    163163                .index = 0,
    164                 .length = sizeof(usb_standard_device_descriptor_t)
     164                .length = sizeof(usb_standard_configuration_descriptor_t)
    165165        };
    166166        setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
     
    225225                .request = USB_DEVREQ_GET_DESCRIPTOR,
    226226                .index = 0,
    227                 .length = sizeof(usb_standard_device_descriptor_t)
     227                .length = buffer_size
    228228        };
    229229        setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
Note: See TracChangeset for help on using the changeset viewer.