Changes in uspace/drv/usbkbd/main.c [f9a0cef:0e126be7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/main.c
rf9a0cef r0e126be7 28 28 #include <usb/usbdrv.h> 29 29 #include <driver.h> 30 #include <ipc/driver.h>31 30 #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>37 31 38 32 #define BUFFER_SIZE 32 39 #define NAME "usbkbd"40 33 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. */ 35 static void poll_keyboard(device_t *dev) 191 36 { 192 37 int rc; 193 38 usb_handle_t handle; 194 uint8_tbuffer[BUFFER_SIZE];39 char buffer[BUFFER_SIZE]; 195 40 size_t actual_size; 196 //usb_endpoint_t poll_endpoint = 1;41 usb_endpoint_t poll_endpoint = 1; 197 42 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 } 203 48 204 49 usb_target_t poll_target = { 205 .address = kbd_dev->address,206 .endpoint = kbd_dev->poll_endpoint50 .address = my_address, 51 .endpoint = poll_endpoint 207 52 }; 208 53 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; 235 58 } 236 59 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 */ 239 76 } 240 77 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) 78 static int add_kbd_device(device_t *dev) 261 79 { 262 80 /* For now, fail immediately. */ 263 //return ENOTSUP;81 return ENOTSUP; 264 82 265 83 /* 266 84 * When everything is okay, connect to "our" HC. 267 *268 * Not supported yet, skip..269 85 */ 270 //int phone = usb_drv_hc_connect(dev, 0);271 //if (phone < 0) {272 ///*273 //* Connecting to HC failed, roll-back and announce274 //* 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 } 278 94 279 //dev->parent_phone = phone;95 dev->parent_phone = phone; 280 96 281 97 /* 282 * Create new fibril for handling this keyboard98 * Just for fun ;-). 283 99 */ 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); 290 101 291 102 /* … … 296 107 297 108 static driver_ops_t kbd_driver_ops = { 298 .add_device = usbkbd_add_device,109 .add_device = add_kbd_device, 299 110 }; 300 111 301 112 static driver_t kbd_driver = { 302 .name = NAME,113 .name = "usbkbd", 303 114 .driver_ops = &kbd_driver_ops 304 115 };
Note:
See TracChangeset
for help on using the changeset viewer.