Changeset 61257f4 in mainline
- Timestamp:
- 2011-04-07T20:19:24Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f8e8738
- Parents:
- fd9ba204
- Location:
- uspace/drv/usbhid
- Files:
-
- 12 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/Makefile
rfd9ba204 r61257f4 32 32 BINARY = usbhid 33 33 34 STOLEN_LAYOUT_SOURCES = \ 35 kbd/layout/us_qwerty.c \ 36 kbd/layout/us_dvorak.c \ 37 kbd/layout/cz.c 38 34 39 SOURCES = \ 35 40 main.c \ 36 usbhid.c 41 usbhid.c \ 42 kbd/conv.c \ 43 kbd/kbddev.c \ 44 kbd/kbdrepeat.c \ 45 generic/hidd.c \ 46 $(STOLEN_LAYOUT_SOURCES) 47 48 EXTRA_CLEAN = $(STOLEN_LAYOUT_SOURCES) 49 50 SRV_KBD = $(USPACE_PREFIX)/srv/hid/kbd 37 51 38 52 include $(USPACE_PREFIX)/Makefile.common 39 53 54 kbd/layout/%.c: $(SRV_KBD)/layout/%.c 55 ln -sfn ../../$< $@ -
uspace/drv/usbhid/main.c
rfd9ba204 r61257f4 71 71 * @return Other error code inherited from one of functions usb_kbd_init(), 72 72 * ddf_fun_bind() and ddf_fun_add_to_class(). 73 *74 * @sa usb_kbd_fibril(), usb_kbd_repeat_fibril()75 73 */ 76 74 static int usb_hid_try_add_device(usb_device_t *dev) 77 75 { 76 /* 77 * Initialize device (get and process descriptors, get address, etc.) 78 */ 79 usb_log_debug("Initializing USB/HID device...\n"); 80 81 usb_hid_dev_t *hid_dev = usb_hid_new(); 82 if (hid_dev == NULL) { 83 usb_log_error("Error while creating USB/HID device " 84 "structure.\n"); 85 return ENOMEM; 86 } 87 88 int rc = usb_hid_init(hid_dev, dev); 89 90 if (rc != EOK) { 91 usb_log_error("Failed to initialize USB/HID device.\n"); 92 usb_hid_free(&hid_dev); 93 return rc; 94 } 95 96 usb_log_debug("USB/HID device structure initialized.\n"); 97 78 98 /* Create the function exposed under /dev/devices. */ 79 99 ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 80 "hid");100 usb_hid_get_function_name(hid_dev->device_type)); 81 101 if (hid_fun == NULL) { 82 102 usb_log_error("Could not create DDF function node.\n"); 103 usb_hid_free(&hid_dev); 83 104 return ENOMEM; 84 105 } 85 106 86 /*87 * Initialize device (get and process descriptors, get address, etc.)88 */89 usb_log_debug("Initializing USB/HID device...\n");90 91 // usb_kbd_t *kbd_dev = usb_kbd_new();92 // if (kbd_dev == NULL) {93 // usb_log_error("Error while creating USB/HID KBD device "94 // "structure.\n");95 // ddf_fun_destroy(hid_fun);96 // return ENOMEM; // TODO: some other code??97 // }98 99 // int rc = usb_kbd_init(kbd_dev, dev);100 101 // if (rc != EOK) {102 // usb_log_error("Failed to initialize USB/HID KBD device.\n");103 // ddf_fun_destroy(hid_fun);104 // usb_kbd_free(&kbd_dev);105 // return rc;106 // }107 108 // usb_log_debug("USB/HID KBD device structure initialized.\n");109 110 107 /* 111 * Store the initialized keyboard device and keyboardops108 * Store the initialized HID device and HID ops 112 109 * to the DDF function. 113 110 */ 114 //kbd_fun->driver_data = kbd_dev;115 hid_fun-> ops = &hid_ops;116 117 intrc = ddf_fun_bind(hid_fun);111 hid_fun->ops = &hid_dev->ops; 112 hid_fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 113 114 rc = ddf_fun_bind(hid_fun); 118 115 if (rc != EOK) { 119 116 usb_log_error("Could not bind DDF function: %s.\n", … … 121 118 // TODO: Can / should I destroy the DDF function? 122 119 ddf_fun_destroy(hid_fun); 123 return rc; 124 } 125 126 rc = ddf_fun_add_to_class(hid_fun, "hid"); 120 usb_hid_free(&hid_dev); 121 return rc; 122 } 123 124 rc = ddf_fun_add_to_class(hid_fun, 125 usb_hid_get_class_name(hid_dev->device_type)); 127 126 if (rc != EOK) { 128 127 usb_log_error( … … 131 130 // TODO: Can / should I destroy the DDF function? 132 131 ddf_fun_destroy(hid_fun); 133 return rc;134 }135 136 132 usb_hid_free(&hid_dev); 133 return rc; 134 } 135 137 136 /* Start automated polling function. 138 137 * This will create a separate fibril that will query the device … … 141 140 rc = usb_device_auto_poll(dev, 142 141 /* Index of the polling pipe. */ 143 USB_HID_POLL_EP_NO,142 hid_dev->poll_pipe_index, 144 143 /* Callback when data arrives. */ 145 usb_hid_polling_callback,144 hid_dev->poll_callback, 146 145 /* How much data to request. */ 147 dev->pipes[ USB_HID_POLL_EP_NO].pipe->max_packet_size,146 dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size, 148 147 /* Callback when the polling ends. */ 149 148 usb_hid_polling_ended_callback, 150 149 /* Custom argument. */ 151 NULL);150 hid_dev); 152 151 153 152 … … 157 156 return rc; 158 157 } 159 160 (void)hid_ops;161 158 162 159 /* … … 183 180 if (dev->interface_no < 0) { 184 181 usb_log_warning("Device is not a supported HID device.\n"); 185 usb_log_error("Failed to add HID device: endpoint not found."182 usb_log_error("Failed to add HID device: endpoints not found." 186 183 "\n"); 187 184 return ENOTSUP; -
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 -
uspace/drv/usbhid/usbhid.h
rfd9ba204 r61257f4 42 42 43 43 //#include <usb/classes/hid.h> 44 //#include <usb/classes/hidparser.h>44 #include <usb/classes/hidparser.h> 45 45 #include <ddf/driver.h> 46 46 #include <usb/pipes.h> 47 47 #include <usb/devdrv.h> 48 #include <usb/classes/hid.h> 48 49 49 50 /*----------------------------------------------------------------------------*/ 50 ///** 51 // * USB/HID keyboard device type. 52 // * 53 // * Holds a reference to generic USB/HID device structure and keyboard-specific 54 // * data, such as currently pressed keys, modifiers and lock keys. 55 // * 56 // * Also holds a IPC phone to the console (since there is now no other way to 57 // * communicate with it). 58 // * 59 // * @note Storing active lock keys in this structure results in their setting 60 // * being device-specific. 61 // */ 62 //typedef struct usb_kbd_t { 63 // /** Structure holding generic USB device information. */ 64 // //usbhid_dev_t *hid_dev; 65 // usb_device_t *usb_dev; 51 /** 52 * Structure for holding general HID device data. 53 */ 54 typedef struct usb_hid_dev_t { 55 /** Structure holding generic USB device information. */ 56 usb_device_t *usb_dev; 66 57 67 // /** Currently pressed keys (not translated to key codes). */ 68 // uint8_t *keys; 69 // /** Count of stored keys (i.e. number of keys in the report). */ 70 // size_t key_count; 71 // /** Currently pressed modifiers (bitmap). */ 72 // uint8_t modifiers; 58 /** @todo What is this actually? */ 59 ddf_dev_ops_t ops; 73 60 74 // /** Currently active modifiers including locks. Sent to the console. */75 // unsigned mods;61 /** Index of the polling pipe in usb_hid_endpoints array. */ 62 int poll_pipe_index; 76 63 77 // /** Currently active lock keys. */78 // unsigned lock_keys;64 /** Function to be called when data arrives from the device. */ 65 usb_polling_callback_t poll_callback; 79 66 80 // /** IPC phone to the console device (for sending key events). */ 81 // int console_phone; 67 /** Report descriptor. */ 68 uint8_t *report_desc; 69 70 /** Report descriptor size. */ 71 size_t report_desc_size; 82 72 83 // /** Information for auto-repeat of keys. */84 // usb_kbd_repeat_t repeat;73 /** HID Report parser. */ 74 usb_hid_report_parser_t *parser; 85 75 86 // /** Mutex for accessing the information about auto-repeat. */87 // fibril_mutex_t *repeat_mtx;76 /** Arbitrary data (e.g. a special structure for handling keyboard). */ 77 void *data; 88 78 89 // /** Report descriptor. */ 90 // uint8_t *report_desc; 91 92 // /** Report descriptor size. */ 93 // size_t report_desc_size; 94 95 // uint8_t *output_buffer; 96 97 // size_t output_size; 98 99 // size_t led_output_size; 100 101 // usb_hid_report_path_t *led_path; 102 103 // int32_t *led_data; 104 105 // /** HID Report parser. */ 106 // usb_hid_report_parser_t *parser; 107 108 // /** State of the structure (for checking before use). 109 // * 110 // * 0 - not initialized 111 // * 1 - initialized 112 // * -1 - ready for destroying 113 // */ 114 // int initialized; 115 //} usb_kbd_t; 79 /** Type of the device (keyboard, mouse, generic HID device). */ 80 usb_hid_iface_protocol_t device_type; 81 } usb_hid_dev_t; 116 82 117 83 /*----------------------------------------------------------------------------*/ 118 84 119 85 enum { 120 USB_HID_POLL_EP_NO = 0, 121 USB_HID_POLL_EP_COUNT = 1 86 USB_HID_KBD_POLL_EP_NO = 0, 87 USB_HID_MOUSE_POLL_EP_NO = 1, 88 USB_HID_GENERIC_POLL_EP_NO = 2, 89 USB_HID_POLL_EP_COUNT = 3 122 90 }; 123 91 124 92 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1]; 125 93 126 ddf_dev_ops_t hid_ops;127 128 94 /*----------------------------------------------------------------------------*/ 129 95 130 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 131 size_t buffer_size, void *arg); 96 usb_hid_dev_t *usb_hid_new(void); 132 97 133 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 98 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev); 99 100 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 134 101 void *arg); 135 102 136 #endif /* USB_KBDDEV_H_ */ 103 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type); 104 105 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type); 106 107 /** @todo Maybe not needed in the API. */ 108 void usb_hid_free(usb_hid_dev_t **hid_dev); 109 110 #endif /* USB_USBHID_H_ */ 137 111 138 112 /** -
uspace/drv/usbhid/usbhid.ma
rfd9ba204 r61257f4 1 100 usb&interface&class=HID 1 1000 usb&interface&class=HID&subclass=0x01&protocol=0x02 2 1000 usb&interface&class=HID
Note:
See TracChangeset
for help on using the changeset viewer.