Changeset a822cd8 in mainline
- Timestamp:
- 2010-12-12T14:16:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- 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. - Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/virtusbkbd/Makefile
ra59cdd2 ra822cd8 33 33 34 34 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include 36 36 37 37 SOURCES = \ -
uspace/drv/usbkbd/main.c
ra59cdd2 ra822cd8 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 static const usb_endpoint_t CONTROL_EP = 0; 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->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 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->default_ep 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 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 240 static 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 259 static int usbkbd_add_device(device_t *dev) 79 260 { 80 261 /* For now, fail immediately. */ 81 return ENOTSUP;262 //return ENOTSUP; 82 263 83 264 /* 84 265 * 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); 101 289 102 290 /* … … 107 295 108 296 static driver_ops_t kbd_driver_ops = { 109 .add_device = add_kbd_device,297 .add_device = usbkbd_add_device, 110 298 }; 111 299 112 300 static driver_t kbd_driver = { 113 .name = "usbkbd",301 .name = NAME, 114 302 .driver_ops = &kbd_driver_ops 115 303 }; -
uspace/lib/usb/include/usb/classes/hid.h
ra59cdd2 ra822cd8 36 36 #define LIBUSB_HID_H_ 37 37 38 #include <usb/usb.h> 39 #include <driver.h> 40 #include <usb/classes/hidparser.h> 41 38 42 /** USB/HID device requests. */ 39 43 typedef enum { … … 54 58 } usb_hid_protocol_t; 55 59 60 /** Part of standard USB HID descriptor specifying one class descriptor. 61 * 62 * (See HID Specification, p.22) 63 */ 64 typedef 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 */ 78 typedef 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 */ 99 typedef 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 56 106 #endif 57 107 /** -
uspace/lib/usb/include/usb/classes/hidparser.h
ra59cdd2 ra822cd8 50 50 * @param arg Custom argument. 51 51 */ 52 void (*keyboard)(const uint 32_t *key_codes, size_t count, void *arg);52 void (*keyboard)(const uint16_t *key_codes, size_t count, void *arg); 53 53 } usb_hid_report_in_callbacks_t; 54 54 55 55 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 56 const uint8_t *data );56 const uint8_t *data, size_t size); 57 57 58 58 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 59 const uint8_t *data, 59 const uint8_t *data, size_t size, 60 60 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 61 61 -
uspace/lib/usb/src/hidparser.c
ra59cdd2 ra822cd8 40 40 * @param parser Opaque HID report parser structure. 41 41 * @param data Data describing the report. 42 * @param size Size of the descriptor in bytes. 42 43 * @return Error code. 43 44 */ 44 45 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 45 const uint8_t *data )46 const uint8_t *data, size_t size) 46 47 { 47 48 return ENOTSUP; … … 54 55 * @param parser Opaque HID report parser structure. 55 56 * @param data Data for the report. 57 * @param size Size of the data in bytes. 56 58 * @param callbacks Callbacks for report actions. 57 59 * @param arg Custom argument (passed through to the callbacks). … … 59 61 */ 60 62 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 61 const uint8_t *data, 63 const uint8_t *data, size_t size, 62 64 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 63 65 { 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; 65 79 } 66 80 -
uspace/lib/usb/src/usbdrvreq.c
ra59cdd2 ra822cd8 162 162 .request = USB_DEVREQ_GET_DESCRIPTOR, 163 163 .index = 0, 164 .length = sizeof(usb_standard_ device_descriptor_t)164 .length = sizeof(usb_standard_configuration_descriptor_t) 165 165 }; 166 166 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; … … 225 225 .request = USB_DEVREQ_GET_DESCRIPTOR, 226 226 .index = 0, 227 .length = sizeof(usb_standard_device_descriptor_t)227 .length = buffer_size 228 228 }; 229 229 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
Note:
See TracChangeset
for help on using the changeset viewer.