Changes in uspace/drv/usbkbd/main.c [0e126be7:f9a0cef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/main.c
r0e126be7 rf9a0cef 28 28 #include <usb/usbdrv.h> 29 29 #include <driver.h> 30 #include <ipc/driver.h> 30 31 #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> 31 37 32 38 #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 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) 36 191 { 37 192 int rc; 38 193 usb_handle_t handle; 39 charbuffer[BUFFER_SIZE];194 uint8_t buffer[BUFFER_SIZE]; 40 195 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 // } 48 203 49 204 usb_target_t poll_target = { 50 .address = my_address,51 .endpoint = poll_endpoint205 .address = kbd_dev->address, 206 .endpoint = kbd_dev->poll_endpoint 52 207 }; 53 208 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 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); 235 } 236 237 // not reached 238 assert(0); 239 } 240 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) 79 261 { 80 262 /* For now, fail immediately. */ 81 return ENOTSUP;263 //return ENOTSUP; 82 264 83 265 /* 84 266 * 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); 267 * 268 * Not supported yet, skip.. 269 */ 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 // } 278 279 // dev->parent_phone = phone; 280 281 /* 282 * Create new fibril for handling this keyboard 283 */ 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); 101 290 102 291 /* … … 107 296 108 297 static driver_ops_t kbd_driver_ops = { 109 .add_device = add_kbd_device,298 .add_device = usbkbd_add_device, 110 299 }; 111 300 112 301 static driver_t kbd_driver = { 113 .name = "usbkbd",302 .name = NAME, 114 303 .driver_ops = &kbd_driver_ops 115 304 };
Note:
See TracChangeset
for help on using the changeset viewer.