Changeset 61257f4 in mainline for uspace/drv/usbhid/usbhid.c
- Timestamp:
- 2011-04-07T20:19:24Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f8e8738
- Parents:
- fd9ba204
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/usbhid.c
rfd9ba204 r61257f4 37 37 #include <usb/debug.h> 38 38 #include <usb/classes/classes.h> 39 #include <usb/classes/hid.h> 40 #include <usb/classes/hidparser.h> 41 #include <usb/classes/hidreport.h> 42 #include <errno.h> 39 43 40 44 #include "usbhid.h" 41 45 42 /*----------------------------------------------------------------------------*/ 43 44 /** HID device polling endpoint description. */ 45 static usb_endpoint_description_t poll_endpoint_description = { 46 #include "kbd/kbddev.h" 47 #include "generic/hidd.h" 48 49 /*----------------------------------------------------------------------------*/ 50 51 /** Generic HID device polling endpoint description. */ 52 //static usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = { 53 // .transfer_type = USB_TRANSFER_INTERRUPT, 54 // .direction = USB_DIRECTION_IN, 55 // .interface_class = USB_CLASS_HID, 56 // .flags = 0 57 //}; 58 59 ///** Keyboard polling endpoint description for boot protocol class. */ 60 //static usb_endpoint_description_t ush_hid_kbd_poll_endpoint_description = { 61 // .transfer_type = USB_TRANSFER_INTERRUPT, 62 // .direction = USB_DIRECTION_IN, 63 // .interface_class = USB_CLASS_HID, 64 // .interface_subclass = USB_HID_SUBCLASS_BOOT, 65 // .interface_protocol = USB_HID_PROTOCOL_KEYBOARD, 66 // .flags = 0 67 //}; 68 69 /** Mouse polling endpoint description for boot protocol class. */ 70 static usb_endpoint_description_t ush_hid_mouse_poll_endpoint_description = { 46 71 .transfer_type = USB_TRANSFER_INTERRUPT, 47 72 .direction = USB_DIRECTION_IN, 48 73 .interface_class = USB_CLASS_HID, 74 .interface_subclass = USB_HID_SUBCLASS_BOOT, 75 .interface_protocol = USB_HID_PROTOCOL_MOUSE, 49 76 .flags = 0 50 77 }; … … 53 80 usb_endpoint_description_t 54 81 *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = { 55 &poll_endpoint_description, 82 &ush_hid_kbd_poll_endpoint_description, 83 &ush_hid_mouse_poll_endpoint_description, 84 &usb_hid_generic_poll_endpoint_description, 56 85 NULL 57 86 }; 58 87 59 /*----------------------------------------------------------------------------*/ 60 61 ddf_dev_ops_t hid_ops = { 62 .default_handler = NULL 63 }; 64 65 /*----------------------------------------------------------------------------*/ 66 67 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 88 static const char *HID_MOUSE_FUN_NAME = "mouse"; 89 static const char *HID_MOUSE_CLASS_NAME = "mouse"; 90 91 /*----------------------------------------------------------------------------*/ 92 93 usb_hid_dev_t *usb_hid_new(void) 94 { 95 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1, 96 sizeof(usb_hid_dev_t)); 97 98 if (hid_dev == NULL) { 99 usb_log_fatal("No memory!\n"); 100 return NULL; 101 } 102 103 hid_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 104 usb_hid_report_parser_t))); 105 if (hid_dev->parser == NULL) { 106 usb_log_fatal("No memory!\n"); 107 free(hid_dev); 108 return NULL; 109 } 110 111 return hid_dev; 112 } 113 114 /*----------------------------------------------------------------------------*/ 115 116 static bool usb_dummy_polling_callback(usb_device_t *dev, uint8_t *buffer, 68 117 size_t buffer_size, void *arg) 69 118 { 70 usb_debug_str_buffer(buffer, buffer_size, 0); 71 return true; 72 } 73 74 /*----------------------------------------------------------------------------*/ 75 76 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 77 void *arg) 78 { 79 119 return false; 120 } 121 122 /*----------------------------------------------------------------------------*/ 123 124 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 125 { 126 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 127 usb_log_debug("Found keyboard endpoint.\n"); 128 129 // save the pipe index and device type 130 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 131 hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD; 132 133 // set the polling callback 134 hid_dev->poll_callback = usb_kbd_polling_callback; 135 136 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 137 usb_log_debug("Found mouse endpoint.\n"); 138 139 // save the pipe index and device type 140 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 141 hid_dev->device_type = USB_HID_PROTOCOL_MOUSE; 142 143 // set the polling callback 144 hid_dev->poll_callback = usb_dummy_polling_callback; 145 146 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 147 usb_log_debug("Found generic HID endpoint.\n"); 148 149 // save the pipe index and device type 150 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 151 hid_dev->device_type = USB_HID_PROTOCOL_NONE; 152 153 // set the polling callback 154 hid_dev->poll_callback = usb_hid_polling_callback; 155 156 } else { 157 usb_log_warning("None of supported endpoints found - probably" 158 " not a supported device.\n"); 159 return ENOTSUP; 160 } 161 162 return EOK; 163 } 164 165 /*----------------------------------------------------------------------------*/ 166 167 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev) 168 { 169 /* Initialize the report parser. */ 170 int rc = usb_hid_parser_init(hid_dev->parser); 171 if (rc != EOK) { 172 usb_log_error("Failed to initialize report parser.\n"); 173 return rc; 174 } 175 176 /* Get the report descriptor and parse it. */ 177 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 178 hid_dev->parser); 179 if (rc != EOK) { 180 usb_log_warning("Could not process report descriptor.\n"); 181 182 if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) { 183 usb_log_warning("Falling back to boot protocol.\n"); 184 185 rc = usb_kbd_set_boot_protocol(hid_dev); 186 187 } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) { 188 usb_log_warning("No boot protocol for mouse yet.\n"); 189 rc = ENOTSUP; 190 } 191 } 192 193 return rc; 194 } 195 196 /*----------------------------------------------------------------------------*/ 197 198 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 199 { 200 int rc; 201 202 usb_log_debug("Initializing HID structure...\n"); 203 204 if (hid_dev == NULL) { 205 usb_log_error("Failed to init HID structure: no structure given" 206 ".\n"); 207 return EINVAL; 208 } 209 210 if (dev == NULL) { 211 usb_log_error("Failed to init HID structure: no USB device" 212 " given.\n"); 213 return EINVAL; 214 } 215 216 /* The USB device should already be initialized, save it in structure */ 217 hid_dev->usb_dev = dev; 218 219 rc = usb_hid_check_pipes(hid_dev, dev); 220 if (rc != EOK) { 221 return rc; 222 } 223 224 rc = usb_hid_init_parser(hid_dev); 225 if (rc != EOK) { 226 usb_log_error("Failed to initialize HID parser.\n"); 227 return rc; 228 } 229 230 switch (hid_dev->device_type) { 231 case USB_HID_PROTOCOL_KEYBOARD: 232 // initialize the keyboard structure 233 rc = usb_kbd_init(hid_dev); 234 if (rc != EOK) { 235 usb_log_warning("Failed to initialize KBD structure." 236 "\n"); 237 } 238 break; 239 case USB_HID_PROTOCOL_MOUSE: 240 break; 241 default: 242 break; 243 } 244 245 return rc; 246 } 247 248 /*----------------------------------------------------------------------------*/ 249 250 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 251 void *arg) 252 { 253 if (dev == NULL || arg == NULL) { 254 return; 255 } 256 257 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 258 259 usb_hid_free(&hid_dev); 260 } 261 262 /*----------------------------------------------------------------------------*/ 263 264 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type) 265 { 266 switch (device_type) { 267 case USB_HID_PROTOCOL_KEYBOARD: 268 return HID_KBD_FUN_NAME; 269 break; 270 case USB_HID_PROTOCOL_MOUSE: 271 return HID_MOUSE_FUN_NAME; 272 break; 273 default: 274 return HID_GENERIC_FUN_NAME; 275 } 276 } 277 278 /*----------------------------------------------------------------------------*/ 279 280 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type) 281 { 282 switch (device_type) { 283 case USB_HID_PROTOCOL_KEYBOARD: 284 return HID_KBD_CLASS_NAME; 285 break; 286 case USB_HID_PROTOCOL_MOUSE: 287 return HID_MOUSE_CLASS_NAME; 288 break; 289 default: 290 return HID_GENERIC_CLASS_NAME; 291 } 292 } 293 294 /*----------------------------------------------------------------------------*/ 295 296 void usb_hid_free(usb_hid_dev_t **hid_dev) 297 { 298 if (hid_dev == NULL || *hid_dev == NULL) { 299 return; 300 } 301 302 switch ((*hid_dev)->device_type) { 303 case USB_HID_PROTOCOL_KEYBOARD: 304 usb_kbd_deinit(*hid_dev); 305 break; 306 case USB_HID_PROTOCOL_MOUSE: 307 break; 308 default: 309 break; 310 } 311 312 // destroy the parser 313 if ((*hid_dev)->parser != NULL) { 314 usb_hid_free_report_parser((*hid_dev)->parser); 315 } 316 317 if ((*hid_dev)->report_desc != NULL) { 318 free((*hid_dev)->report_desc); 319 } 320 321 free(*hid_dev); 322 *hid_dev = NULL; 80 323 } 81 324
Note:
See TracChangeset
for help on using the changeset viewer.