Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbkbd/main.c

    rf9a0cef r0e126be7  
    2828#include <usb/usbdrv.h>
    2929#include <driver.h>
    30 #include <ipc/driver.h>
    3130#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>
    3731
    3832#define BUFFER_SIZE 32
    39 #define NAME "usbkbd"
    4033
    41 #define GUESSED_POLL_ENDPOINT 1
    42 
    43 /*
    44  * Callbacks for parser
    45  */
    46 static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
    47                                     void *arg)
    48 {
    49 
    50 }
    51 
    52 /*
    53  * Kbd functions
    54  */
    55 static 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 
    93 static 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 
    130 static 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->poll_endpoint = GUESSED_POLL_ENDPOINT;
    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 
    173 static 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 
    190 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
     34/* Call this periodically to check keyboard status changes. */
     35static void poll_keyboard(device_t *dev)
    19136{
    19237        int rc;
    19338        usb_handle_t handle;
    194         uint8_t buffer[BUFFER_SIZE];
     39        char buffer[BUFFER_SIZE];
    19540        size_t actual_size;
    196         //usb_endpoint_t poll_endpoint = 1;
     41        usb_endpoint_t poll_endpoint = 1;
    19742
    198 //      usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
    199 //          dev);
    200 //      if (my_address < 0) {
    201 //              return;
    202 //      }
     43        usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
     44            dev);
     45        if (my_address < 0) {
     46                return;
     47        }
    20348
    20449        usb_target_t poll_target = {
    205                 .address = kbd_dev->address,
    206                 .endpoint = kbd_dev->poll_endpoint
     50                .address = my_address,
     51                .endpoint = poll_endpoint
    20752        };
    20853
    209         while (true) {
    210                 async_usleep(1000 * 1000);
    211                 rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
    212                     poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
    213 
    214                 if (rc != EOK) {
    215                         continue;
    216                 }
    217 
    218                 rc = usb_drv_async_wait_for(handle);
    219                 if (rc != EOK) {
    220                         continue;
    221                 }
    222 
    223                 /*
    224                  * If the keyboard answered with NAK, it returned no data.
    225                  * This implies that no change happened since last query.
    226                  */
    227                 if (actual_size == 0) {
    228                         continue;
    229                 }
    230 
    231                 /*
    232                  * TODO: Process pressed keys.
    233                  */
    234                 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
     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;
    23558        }
    23659
    237         // not reached
    238         assert(0);
     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         */
    23976}
    24077
    241 static int usbkbd_fibril_device(void *arg)
    242 {
    243         printf("!!! USB device fibril\n");
    244 
    245         if (arg == NULL) {
    246                 printf("No device!\n");
    247                 return -1;
    248         }
    249 
    250         device_t *dev = (device_t *)arg;
    251 
    252         // initialize device (get and process descriptors, get address, etc.)
    253         usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
    254 
    255         usbkbd_poll_keyboard(kbd_dev);
    256 
    257         return EOK;
    258 }
    259 
    260 static int usbkbd_add_device(device_t *dev)
     78static int add_kbd_device(device_t *dev)
    26179{
    26280        /* For now, fail immediately. */
    263         //return ENOTSUP;
     81        return ENOTSUP;
    26482
    26583        /*
    26684         * When everything is okay, connect to "our" HC.
    267          *
    268          * Not supported yet, skip..
    26985         */
    270 //      int phone = usb_drv_hc_connect(dev, 0);
    271 //      if (phone < 0) {
    272 //              /*
    273 //               * Connecting to HC failed, roll-back and announce
    274 //               * failure.
    275 //               */
    276 //              return phone;
    277 //      }
     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        }
    27894
    279 //      dev->parent_phone = phone;
     95        dev->parent_phone = phone;
    28096
    28197        /*
    282          * Create new fibril for handling this keyboard
     98         * Just for fun ;-).
    28399         */
    284         fid_t fid = fibril_create(usbkbd_fibril_device, dev);
    285         if (fid == 0) {
    286                 printf("%s: failed to start fibril for HID device\n", NAME);
    287                 return ENOMEM;
    288         }
    289         fibril_add_ready(fid);
     100        poll_keyboard(dev);
    290101
    291102        /*
     
    296107
    297108static driver_ops_t kbd_driver_ops = {
    298         .add_device = usbkbd_add_device,
     109        .add_device = add_kbd_device,
    299110};
    300111
    301112static driver_t kbd_driver = {
    302         .name = NAME,
     113        .name = "usbkbd",
    303114        .driver_ops = &kbd_driver_ops
    304115};
Note: See TracChangeset for help on using the changeset viewer.