Changeset 291b8bc in mainline
- Timestamp:
- 2011-03-26T13:28:43Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f62468c
- Parents:
- 889e8e3 (diff), c9f5e238 (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. - Files:
-
- 5 added
- 3 deleted
- 28 edited
- 14 moved
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/amd64/Makefile.inc
r889e8e3 r291b8bc 49 49 usbflbk \ 50 50 usbhub \ 51 usb hid \51 usbkbd \ 52 52 usbmid \ 53 53 usbmouse \ -
kernel/generic/src/console/console.c
r889e8e3 r291b8bc 53 53 #include <str.h> 54 54 55 /* 56 * devman produces a lot of output and by giving so many pages 57 * we to allow /app/klog to catch-up. 58 */ 59 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH 60 #define KLOG_PAGES 64 61 #else 55 62 #define KLOG_PAGES 4 63 #endif 64 56 65 #define KLOG_LENGTH (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t)) 57 66 #define KLOG_LATENCY 8 -
kernel/generic/src/mm/as.c
r889e8e3 r291b8bc 1949 1949 sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags) 1950 1950 { 1951 if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,1951 if (as_area_create(AS, flags, size, address, 1952 1952 AS_AREA_ATTR_NONE, &anon_backend, NULL)) 1953 1953 return (sysarg_t) address; -
uspace/Makefile
r889e8e3 r291b8bc 122 122 drv/uhci-rhd \ 123 123 drv/usbflbk \ 124 drv/usb hid \124 drv/usbkbd \ 125 125 drv/usbhub \ 126 126 drv/usbmid \ … … 142 142 drv/uhci-rhd \ 143 143 drv/usbflbk \ 144 drv/usb hid \144 drv/usbkbd \ 145 145 drv/usbhub \ 146 146 drv/usbmid \ -
uspace/app/init/init.c
r889e8e3 r291b8bc 288 288 289 289 spawn("/srv/clip"); 290 291 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH292 spawn("/srv/devman");293 #endif294 290 295 291 /* … … 318 314 getterm("term/vc6", "/app/klog", false); 319 315 320 #ifndef CONFIG_DEVMAN_EARLY_LAUNCH 316 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH 317 spawn("/srv/devman"); 318 #else 321 319 getterm("term/vc7", "/srv/devman", false); 322 320 #endif -
uspace/drv/ohci/Makefile
r889e8e3 r291b8bc 37 37 main.c \ 38 38 hc.c \ 39 ohci.c \ 39 40 root_hub.c \ 40 41 pci.c -
uspace/drv/ohci/batch.c
r889e8e3 r291b8bc 118 118 instance->next_step = batch_call_in_and_dispose; 119 119 /* TODO: implement */ 120 usb_log_debug("Batch(%p) CONTROL WRITEinitialized.\n", instance);120 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 121 121 } 122 122 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/hc.c
r889e8e3 r291b8bc 39 39 #include <usb/debug.h> 40 40 #include <usb/usb.h> 41 #include <usb/hub.h>42 41 #include <usb/ddfiface.h> 43 42 #include <usb/usbdevice.h> … … 45 44 #include "hc.h" 46 45 47 static int dummy_reset(int foo, void *arg);48 46 static int interrupt_emulator(hc_t *instance); 47 /*----------------------------------------------------------------------------*/ 48 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 49 { 50 assert(instance); 51 assert(hub_fun); 52 53 usb_address_t hub_address = 54 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 55 instance->rh.address = hub_address; 56 usb_device_keeper_bind( 57 &instance->manager, hub_address, hub_fun->handle); 58 59 char *match_str = NULL; 60 int ret = asprintf(&match_str, "usb&mid"); 61 ret = (match_str == NULL) ? ret : EOK; 62 if (ret < 0) { 63 usb_log_error("Failed to create root hub match-id string.\n"); 64 return ret; 65 } 66 67 ret = ddf_fun_add_match_id(hub_fun, match_str, 100); 68 if (ret != EOK) { 69 usb_log_error("Failed add create root hub match-id.\n"); 70 } 71 return ret; 72 } 49 73 /*----------------------------------------------------------------------------*/ 50 74 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, … … 68 92 } 69 93 94 rh_init(&instance->rh, dev, instance->registers); 70 95 71 rh_init(&instance->rh, dev, instance->registers);72 96 /* TODO: implement */ 73 return EOK;74 }75 /*----------------------------------------------------------------------------*/76 int hc_register_hub(hc_t *instance)77 {78 async_usleep(1000000);79 #define CHECK_RET_RETURN(ret, msg...) \80 if (ret != EOK) { \81 usb_log_error(msg); \82 return ret; \83 } else (void)084 assert(instance);85 assert(instance->ddf_instance);86 assert(instance->ddf_instance->handle);87 ddf_dev_t *dev = instance->rh.device;88 int ret = EOK;89 90 usb_hc_connection_t conn;91 ret =92 usb_hc_connection_initialize(&conn, instance->ddf_instance->handle);93 CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n");94 95 ret = usb_hc_connection_open(&conn);96 CHECK_RET_RETURN(ret, "Failed to open hc connection.\n");97 98 usb_address_t address;99 devman_handle_t handle;100 ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset,101 0, instance, &address, &handle, NULL, NULL, NULL);102 if (ret != EOK) {103 usb_log_error("Failed to add rh device.\n");104 instance->rh.address = -1;105 return ret;106 }107 108 ret = usb_hc_connection_close(&conn);109 CHECK_RET_RETURN(ret, "Failed to close hc connection.\n");110 97 return EOK; 111 98 } … … 134 121 } 135 122 /*----------------------------------------------------------------------------*/ 136 static int dummy_reset(int foo, void *arg) 137 { 138 hc_t *hc = (hc_t*)arg; 139 assert(hc); 140 hc->rh.address = 0; 141 return EOK; 142 } 143 /*----------------------------------------------------------------------------*/ 144 static int interrupt_emulator(hc_t *instance) 123 int interrupt_emulator(hc_t *instance) 145 124 { 146 125 assert(instance); -
uspace/drv/ohci/hc.h
r889e8e3 r291b8bc 57 57 } hc_t; 58 58 59 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 60 59 61 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev, 60 62 uintptr_t regs, size_t reg_size, bool interrupts); 61 62 int hc_register_hub(hc_t *instance);63 63 64 64 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); -
uspace/drv/ohci/iface.h
r889e8e3 r291b8bc 33 33 * Common OHCI definitions. 34 34 */ 35 #ifndef DRV_OHCI_ OHCI_H36 #define DRV_OHCI_ OHCI_H35 #ifndef DRV_OHCI_IFACE_H 36 #define DRV_OHCI_IFACE_H 37 37 38 38 #include <usbhc_iface.h> 39 40 #define NAME "ohci"41 39 42 40 extern usbhc_iface_t hc_iface; -
uspace/drv/ohci/main.c
r889e8e3 r291b8bc 34 34 */ 35 35 #include <ddf/driver.h> 36 #include <ddf/interrupt.h>37 #include <device/hw_res.h>38 36 #include <errno.h> 39 37 #include <str_error.h> 40 38 41 #include <usb_iface.h>42 #include <usb/ddfiface.h>43 39 #include <usb/debug.h> 44 40 45 #include " pci.h"46 #include "iface.h" 47 # include "hc.h"41 #include "ohci.h" 42 43 #define NAME "ohci" 48 44 49 45 static int ohci_add_device(ddf_dev_t *device); 50 static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)51 {52 assert(handle);53 assert(fun != NULL);54 55 *handle = fun->handle;56 return EOK;57 }58 /*----------------------------------------------------------------------------*/59 static int get_address(60 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)61 {62 assert(fun);63 usb_device_keeper_t *manager = &fun_to_hc(fun)->manager;64 usb_address_t addr = usb_device_keeper_find(manager, handle);65 if (addr < 0) {66 return addr;67 }68 69 if (address != NULL) {70 *address = addr;71 }72 73 return EOK;74 }75 /*----------------------------------------------------------------------------*/76 /** IRQ handling callback, identifies device77 *78 * @param[in] dev DDF instance of the device to use.79 * @param[in] iid (Unused).80 * @param[in] call Pointer to the call that represents interrupt.81 */82 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)83 {84 assert(dev);85 hc_t *hc = (hc_t*)dev->driver_data;86 assert(hc);87 hc_interrupt(hc, 0);88 }89 46 /*----------------------------------------------------------------------------*/ 90 47 static driver_ops_t ohci_driver_ops = { … … 97 54 }; 98 55 /*----------------------------------------------------------------------------*/ 99 static usb_iface_t hc_usb_iface = {100 .get_address = get_address,101 .get_hc_handle = get_hc_handle,102 };103 /*----------------------------------------------------------------------------*/104 static ddf_dev_ops_t hc_ops = {105 .interfaces[USB_DEV_IFACE] = &hc_usb_iface,106 .interfaces[USBHC_DEV_IFACE] = &hc_iface,107 };108 /*----------------------------------------------------------------------------*/109 56 /** Initializes a new ddf driver instance of OHCI hcd. 110 57 * … … 112 59 * @return Error code. 113 60 */ 114 staticint ohci_add_device(ddf_dev_t *device)61 int ohci_add_device(ddf_dev_t *device) 115 62 { 63 usb_log_debug("ohci_add_device() called\n"); 116 64 assert(device); 117 #define CHECK_RET_RETURN(ret, message...) \ 118 if (ret != EOK) { \ 119 usb_log_error(message); \ 120 return ret; \ 121 } 122 123 uintptr_t mem_reg_base = 0; 124 size_t mem_reg_size = 0; 125 int irq = 0; 126 127 int ret = 128 pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq); 129 CHECK_RET_RETURN(ret, 130 "Failed(%d) to get memory addresses:.\n", ret, device->handle); 131 usb_log_info("Memory mapped regs at 0x%X (size %zu), IRQ %d.\n", 132 mem_reg_base, mem_reg_size, irq); 133 134 ret = pci_disable_legacy(device); 135 CHECK_RET_RETURN(ret, 136 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 137 138 hc_t *hcd = malloc(sizeof(hc_t)); 139 if (hcd == NULL) { 65 ohci_t *ohci = malloc(sizeof(ohci_t)); 66 if (ohci == NULL) { 140 67 usb_log_error("Failed to allocate OHCI driver.\n"); 141 68 return ENOMEM; 142 69 } 143 70 144 ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc"); 145 if (hc_fun == NULL) { 146 usb_log_error("Failed to create OHCI function.\n"); 147 free(hcd); 148 return ENOMEM; 149 } 150 151 152 bool interrupts = false; 153 #ifdef CONFIG_USBHC_NO_INTERRUPTS 154 usb_log_warning("Interrupts disabled in OS config, " \ 155 "falling back to polling.\n"); 156 #else 157 ret = pci_enable_interrupts(device); 71 int ret = ohci_init(ohci, device); 158 72 if (ret != EOK) { 159 usb_log_ warning("Failed to enable interrupts: %s.\n",73 usb_log_error("Failed to initialize OHCI driver: %s.\n", 160 74 str_error(ret)); 161 usb_log_info("HW interrupts not available, " \162 "falling back to polling.\n");163 } else {164 usb_log_debug("Hw interrupts enabled.\n");165 interrupts = true;166 }167 #endif168 169 ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);170 if (ret != EOK) {171 usb_log_error("Failed to initialize OHCI driver.\n");172 free(hcd);173 75 return ret; 174 76 } 77 device->driver_data = ohci; 175 78 176 ret = register_interrupt_handler(device, irq, irq_handler, NULL); 177 178 hc_fun->ops = &hc_ops; 179 ret = ddf_fun_bind(hc_fun); 180 if (ret != EOK) { 181 usb_log_error("Failed to bind OHCI function.\n"); 182 ddf_fun_destroy(hc_fun); 183 free(hcd); 184 return ret; 185 } 186 hc_fun->driver_data = hcd; 187 188 fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd); 189 fibril_add_ready(later); 190 191 usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n", 192 device->name, device->handle); 79 usb_log_info("Controlling new OHCI device `%s'.\n", device->name); 193 80 194 81 return EOK; 195 #undef CHECK_RET_RETURN196 82 } 197 83 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/ohci.h
r889e8e3 r291b8bc 1 1 /* 2 * Copyright (c) 2011 Lubos Slovak2 * Copyright (c) 2011 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup drvusb hid29 /** @addtogroup drvusbohci 30 30 * @{ 31 31 */ 32 32 /** @file 33 * USB HID keyboard autorepeat facilities33 * @brief OHCI driver main structure for both host controller and root-hub. 34 34 */ 35 #ifndef DRV_OHCI_OHCI_H 36 #define DRV_OHCI_OHCI_H 37 #include <ddi.h> 38 #include <ddf/driver.h> 35 39 36 #i fndef USBHID_KBDREPEAT_H_37 # define USBHID_KBDREPEAT_H_40 #include "hc.h" 41 #include "root_hub.h" 38 42 39 #include "kbddev.h" 43 typedef struct ohci { 44 ddf_fun_t *hc_fun; 45 ddf_fun_t *rh_fun; 40 46 41 /*----------------------------------------------------------------------------*/ 47 hc_t hc; 48 rh_t rh; 49 } ohci_t; 42 50 43 int usbhid_kbd_repeat_fibril(void *arg);51 int ohci_init(ohci_t *instance, ddf_dev_t *device); 44 52 45 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key); 46 47 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key); 48 49 #endif /* USBHID_KBDREPEAT_H_ */ 50 53 #endif 51 54 /** 52 55 * @} -
uspace/drv/ohci/root_hub.c
r889e8e3 r291b8bc 39 39 40 40 #include "root_hub.h" 41 #include "usb/classes/classes.h" 42 #include <usb/request.h> 43 #include <usb/classes/hub.h> 44 45 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = 46 { 47 .configuration_count = 1, 48 .descriptor_type = USB_DESCTYPE_DEVICE, 49 .device_class = USB_CLASS_HUB, 50 .device_protocol = 0, 51 .device_subclass = 0, 52 .device_version = 0, 53 .length = sizeof(usb_standard_device_descriptor_t), 54 /// \TODO this value is guessed 55 .max_packet_size = 8, 56 .vendor_id = 0x16db, 57 .product_id = 0x0001, 58 /// \TODO these values migt be different 59 .str_serial_number = 0, 60 .usb_spec_version = 0, 61 }; 62 63 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = 64 { 65 /// \TODO some values are default or guessed 66 .attributes = 1<<7, 67 .configuration_number = 1, 68 .descriptor_type = USB_DESCTYPE_CONFIGURATION, 69 .interface_count = 1, 70 .length = sizeof(usb_standard_configuration_descriptor_t), 71 .max_power = 100, 72 .str_configuration = 0, 73 }; 74 75 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = 76 { 77 .alternate_setting = 0, 78 .descriptor_type = USB_DESCTYPE_INTERFACE, 79 .endpoint_count = 1, 80 .interface_class = USB_CLASS_HUB, 81 /// \TODO is this correct? 82 .interface_number = 1, 83 .interface_protocol = 0, 84 .interface_subclass = 0, 85 .length = sizeof(usb_standard_interface_descriptor_t), 86 .str_interface = 0, 87 }; 88 89 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = 90 { 91 .attributes = USB_TRANSFER_INTERRUPT, 92 .descriptor_type = USB_DESCTYPE_ENDPOINT, 93 .endpoint_address = 1 + (1<<7), 94 .length = sizeof(usb_standard_endpoint_descriptor_t), 95 .max_packet_size = 8, 96 .poll_interval = 255, 97 }; 41 98 42 99 /** Root hub initialization … … 50 107 instance->device = dev; 51 108 109 52 110 usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff); 53 111 112 //start generic usb hub driver 113 54 114 /* TODO: implement */ 55 115 return EOK; 56 116 } 57 117 /*----------------------------------------------------------------------------*/ 118 119 120 static int process_get_port_status_request(rh_t *instance, uint16_t port, 121 usb_transfer_batch_t * request){ 122 if(port<1 || port>instance->port_count) 123 return EINVAL; 124 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 125 request->transfered_size = 4; 126 uint32_buffer[0] = instance->registers->rh_port_status[port -1]; 127 return EOK; 128 } 129 130 static int process_get_hub_status_request(rh_t *instance, 131 usb_transfer_batch_t * request){ 132 uint32_t * uint32_buffer = (uint32_t*)request->buffer; 133 //bits, 0,1,16,17 134 request->transfered_size = 4; 135 uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17); 136 uint32_buffer[0] = mask & instance->registers->rh_status; 137 return EOK; 138 139 } 140 141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result, 142 size_t * out_size) { 143 //base size 144 size_t size = 7; 145 //variable size according to port count 146 size_t var_size = instance->port_count / 8 + 147 ((instance->port_count % 8 > 0) ? 1 : 0); 148 size += 2 * var_size; 149 uint8_t * result = (uint8_t*) malloc(size); 150 bzero(result,size); 151 //size 152 result[0] = size; 153 //descriptor type 154 result[1] = USB_DESCTYPE_HUB; 155 result[2] = instance->port_count; 156 uint32_t hub_desc_reg = instance->registers->rh_desc_a; 157 result[3] = 158 ((hub_desc_reg >> 8) %2) + 159 (((hub_desc_reg >> 9) %2) << 1) + 160 (((hub_desc_reg >> 10) %2) << 2) + 161 (((hub_desc_reg >> 11) %2) << 3) + 162 (((hub_desc_reg >> 12) %2) << 4); 163 result[4] = 0; 164 result[5] = /*descriptor->pwr_on_2_good_time*/ 50; 165 result[6] = 50; 166 167 int port; 168 for (port = 1; port <= instance->port_count; ++port) { 169 result[7 + port/8] += 170 ((instance->registers->rh_desc_b >> port)%2) << (port%8); 171 } 172 size_t i; 173 for (i = 0; i < var_size; ++i) { 174 result[7 + var_size + i] = 255; 175 } 176 (*out_result) = result; 177 (*out_size) = size; 178 } 179 180 181 static int process_get_status_request(rh_t *instance, 182 usb_transfer_batch_t * request) 183 { 184 size_t buffer_size = request->buffer_size; 185 usb_device_request_setup_packet_t * request_packet = 186 (usb_device_request_setup_packet_t*) 187 request->setup_buffer; 188 189 usb_hub_bm_request_type_t request_type = request_packet->request_type; 190 if(buffer_size<4/*request_packet->length*/){///\TODO 191 usb_log_warning("requested more data than buffer size\n"); 192 return EINVAL; 193 } 194 195 if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS) 196 return process_get_hub_status_request(instance, request); 197 if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS) 198 return process_get_port_status_request(instance, request_packet->index, 199 request); 200 return ENOTSUP; 201 } 202 203 static void create_interrupt_mask(rh_t *instance, void ** buffer, 204 size_t * buffer_size){ 205 int bit_count = instance->port_count + 1; 206 (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1; 207 (*buffer) = malloc(*buffer_size); 208 uint8_t * bitmap = (uint8_t*)(*buffer); 209 uint32_t mask = (1<<16) + (1<<17); 210 bzero(bitmap,(*buffer_size)); 211 if(instance->registers->rh_status & mask){ 212 bitmap[0] = 1; 213 } 214 int port; 215 mask = 0; 216 int i; 217 for(i=16;i<=20;++i) 218 mask += 1<<i; 219 for(port = 1; port<=instance->port_count;++port){ 220 if(mask & instance->registers->rh_port_status[port-1]){ 221 bitmap[(port+1)/8] += 1<<(port%8); 222 } 223 } 224 } 225 226 227 static int process_get_descriptor_request(rh_t *instance, 228 usb_transfer_batch_t *request){ 229 /// \TODO 230 usb_device_request_setup_packet_t * setup_request = 231 (usb_device_request_setup_packet_t*)request->setup_buffer; 232 size_t size; 233 const void * result_descriptor; 234 const uint16_t setup_request_value = setup_request->value_high; 235 //(setup_request->value_low << 8); 236 bool del = false; 237 238 switch (setup_request_value) 239 { 240 case USB_DESCTYPE_HUB: { 241 uint8_t * descriptor; 242 usb_create_serialized_hub_descriptor( 243 instance, &descriptor, &size); 244 result_descriptor = descriptor; 245 break; 246 } 247 case USB_DESCTYPE_DEVICE: { 248 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 249 result_descriptor = &ohci_rh_device_descriptor; 250 size = sizeof(ohci_rh_device_descriptor); 251 break; 252 } 253 case USB_DESCTYPE_CONFIGURATION: { 254 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 255 usb_standard_configuration_descriptor_t * descriptor = 256 malloc(sizeof(usb_standard_configuration_descriptor_t)); 257 memcpy(descriptor, &ohci_rh_conf_descriptor, 258 sizeof(usb_standard_configuration_descriptor_t)); 259 /// \TODO should this include device descriptor? 260 const size_t hub_descriptor_size = 7 + 261 2* (instance->port_count / 8 + 262 ((instance->port_count % 8 > 0) ? 1 : 0)); 263 descriptor->total_length = 264 sizeof(usb_standard_configuration_descriptor_t)+ 265 sizeof(usb_standard_endpoint_descriptor_t)+ 266 sizeof(usb_standard_interface_descriptor_t)+ 267 hub_descriptor_size; 268 result_descriptor = descriptor; 269 size = sizeof(usb_standard_configuration_descriptor_t); 270 del = true; 271 break; 272 } 273 case USB_DESCTYPE_INTERFACE: { 274 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 275 result_descriptor = &ohci_rh_iface_descriptor; 276 size = sizeof(ohci_rh_iface_descriptor); 277 break; 278 } 279 case USB_DESCTYPE_ENDPOINT: { 280 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 281 result_descriptor = &ohci_rh_ep_descriptor; 282 size = sizeof(ohci_rh_ep_descriptor); 283 break; 284 } 285 default: { 286 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 287 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 288 setup_request->request_type, 289 setup_request->request, 290 setup_request_value, 291 setup_request->index, 292 setup_request->length 293 ); 294 return EINVAL; 295 } 296 } 297 #if 0 298 if(setup_request_value == USB_DESCTYPE_HUB){ 299 usb_log_debug("USB_DESCTYPE_HUB\n"); 300 //create hub descriptor 301 uint8_t * descriptor; 302 usb_create_serialized_hub_descriptor(instance, 303 &descriptor, &size); 304 result_descriptor = descriptor; 305 }else if(setup_request_value == USB_DESCTYPE_DEVICE){ 306 //create std device descriptor 307 usb_log_debug("USB_DESCTYPE_DEVICE\n"); 308 usb_standard_device_descriptor_t * descriptor = 309 (usb_standard_device_descriptor_t*) 310 malloc(sizeof(usb_standard_device_descriptor_t)); 311 descriptor->configuration_count = 1; 312 descriptor->descriptor_type = USB_DESCTYPE_DEVICE; 313 descriptor->device_class = USB_CLASS_HUB; 314 descriptor->device_protocol = 0; 315 descriptor->device_subclass = 0; 316 descriptor->device_version = 0; 317 descriptor->length = sizeof(usb_standard_device_descriptor_t); 318 /// \TODO this value is guessed 319 descriptor->max_packet_size = 8; 320 descriptor->product_id = 0x0001; 321 /// \TODO these values migt be different 322 descriptor->str_serial_number = 0; 323 descriptor->str_serial_number = 0; 324 descriptor->usb_spec_version = 0; 325 descriptor->vendor_id = 0x16db; 326 result_descriptor = descriptor; 327 size = sizeof(usb_standard_device_descriptor_t); 328 }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){ 329 usb_log_debug("USB_DESCTYPE_CONFIGURATION\n"); 330 usb_standard_configuration_descriptor_t * descriptor = 331 (usb_standard_configuration_descriptor_t*) 332 malloc(sizeof(usb_standard_configuration_descriptor_t)); 333 /// \TODO some values are default or guessed 334 descriptor->attributes = 1<<7; 335 descriptor->configuration_number = 1; 336 descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION; 337 descriptor->interface_count = 1; 338 descriptor->length = sizeof(usb_standard_configuration_descriptor_t); 339 descriptor->max_power = 100; 340 descriptor->str_configuration = 0; 341 /// \TODO should this include device descriptor? 342 size_t hub_descriptor_size = 7 + 343 2* (instance->port_count / 8 + 344 ((instance->port_count % 8 > 0) ? 1 : 0)); 345 descriptor->total_length = 346 sizeof(usb_standard_configuration_descriptor_t)+ 347 sizeof(usb_standard_endpoint_descriptor_t)+ 348 sizeof(usb_standard_interface_descriptor_t)+ 349 hub_descriptor_size; 350 result_descriptor = descriptor; 351 size = sizeof(usb_standard_configuration_descriptor_t); 352 353 }else if(setup_request_value == USB_DESCTYPE_INTERFACE){ 354 usb_log_debug("USB_DESCTYPE_INTERFACE\n"); 355 usb_standard_interface_descriptor_t * descriptor = 356 (usb_standard_interface_descriptor_t*) 357 malloc(sizeof(usb_standard_interface_descriptor_t)); 358 descriptor->alternate_setting = 0; 359 descriptor->descriptor_type = USB_DESCTYPE_INTERFACE; 360 descriptor->endpoint_count = 1; 361 descriptor->interface_class = USB_CLASS_HUB; 362 /// \TODO is this correct? 363 descriptor->interface_number = 1; 364 descriptor->interface_protocol = 0; 365 descriptor->interface_subclass = 0; 366 descriptor->length = sizeof(usb_standard_interface_descriptor_t); 367 descriptor->str_interface = 0; 368 result_descriptor = descriptor; 369 size = sizeof(usb_standard_interface_descriptor_t); 370 }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){ 371 usb_log_debug("USB_DESCTYPE_ENDPOINT\n"); 372 usb_standard_endpoint_descriptor_t * descriptor = 373 (usb_standard_endpoint_descriptor_t*) 374 malloc(sizeof(usb_standard_endpoint_descriptor_t)); 375 descriptor->attributes = USB_TRANSFER_INTERRUPT; 376 descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT; 377 descriptor->endpoint_address = 1 + (1<<7); 378 descriptor->length = sizeof(usb_standard_endpoint_descriptor_t); 379 descriptor->max_packet_size = 8; 380 descriptor->poll_interval = 255; 381 result_descriptor = descriptor; 382 size = sizeof(usb_standard_endpoint_descriptor_t); 383 }else{ 384 usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value); 385 usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ", 386 setup_request->request_type, 387 setup_request->request, 388 setup_request_value, 389 setup_request->index, 390 setup_request->length 391 ); 392 return EINVAL; 393 } 394 #endif 395 if(request->buffer_size < size){ 396 size = request->buffer_size; 397 } 398 request->transfered_size = size; 399 memcpy(request->buffer,result_descriptor,size); 400 if (del) 401 free(result_descriptor); 402 return EOK; 403 } 404 405 static int process_get_configuration_request(rh_t *instance, 406 usb_transfer_batch_t *request){ 407 //set and get configuration requests do not have any meaning, only dummy 408 //values are returned 409 if(request->buffer_size != 1) 410 return EINVAL; 411 request->buffer[0] = 1; 412 request->transfered_size = 1; 413 return EOK; 414 } 415 416 static int process_hub_feature_set_request(rh_t *instance, 417 uint16_t feature, bool enable){ 418 if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT) 419 return EINVAL; 420 instance->registers->rh_status = 421 enable ? 422 (instance->registers->rh_status | (1<<feature)) 423 : 424 (instance->registers->rh_status & (~(1<<feature))); 425 /// \TODO any error? 426 return EOK; 427 } 428 429 static int process_port_feature_set_request(rh_t *instance, 430 uint16_t feature, uint16_t port, bool enable){ 431 if(feature > USB_HUB_FEATURE_C_PORT_RESET) 432 return EINVAL; 433 if(port<1 || port>instance->port_count) 434 return EINVAL; 435 instance->registers->rh_port_status[port - 1] = 436 enable ? 437 (instance->registers->rh_port_status[port - 1] | (1<<feature)) 438 : 439 (instance->registers->rh_port_status[port - 1] & (~(1<<feature))); 440 /// \TODO any error? 441 return EOK; 442 } 443 444 static int process_address_set_request(rh_t *instance, 445 uint16_t address){ 446 instance->address = address; 447 return EOK; 448 } 449 450 static int process_request_with_output(rh_t *instance, 451 usb_transfer_batch_t *request){ 452 usb_device_request_setup_packet_t * setup_request = 453 (usb_device_request_setup_packet_t*)request->setup_buffer; 454 if(setup_request->request == USB_DEVREQ_GET_STATUS){ 455 usb_log_debug("USB_DEVREQ_GET_STATUS\n"); 456 return process_get_status_request(instance, request); 457 } 458 if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){ 459 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n"); 460 return process_get_descriptor_request(instance, request); 461 } 462 if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){ 463 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n"); 464 return process_get_configuration_request(instance, request); 465 } 466 return ENOTSUP; 467 } 468 469 static int process_request_with_input(rh_t *instance, 470 usb_transfer_batch_t *request){ 471 usb_device_request_setup_packet_t * setup_request = 472 (usb_device_request_setup_packet_t*)request->setup_buffer; 473 request->transfered_size = 0; 474 if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){ 475 return ENOTSUP; 476 } 477 if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){ 478 //set and get configuration requests do not have any meaning, 479 //only dummy values are returned 480 return EOK; 481 } 482 return ENOTSUP; 483 } 484 485 486 static int process_request_without_data(rh_t *instance, 487 usb_transfer_batch_t *request){ 488 usb_device_request_setup_packet_t * setup_request = 489 (usb_device_request_setup_packet_t*)request->setup_buffer; 490 request->transfered_size = 0; 491 if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE 492 || setup_request->request == USB_DEVREQ_SET_FEATURE){ 493 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){ 494 usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n"); 495 return process_hub_feature_set_request(instance, setup_request->value, 496 setup_request->request == USB_DEVREQ_SET_FEATURE); 497 } 498 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){ 499 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 500 return process_port_feature_set_request(instance, setup_request->value, 501 setup_request->index, 502 setup_request->request == USB_DEVREQ_SET_FEATURE); 503 } 504 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type); 505 return EINVAL; 506 } 507 if(setup_request->request == USB_DEVREQ_SET_ADDRESS){ 508 usb_log_debug("USB_DEVREQ_SET_ADDRESS\n"); 509 return process_address_set_request(instance, setup_request->value); 510 } 511 usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type); 512 return ENOTSUP; 513 } 514 515 516 /** 517 * 518 * @param instance 519 * @param request 520 * @return 521 */ 58 522 int rh_request(rh_t *instance, usb_transfer_batch_t *request) 59 523 { 60 524 assert(instance); 61 525 assert(request); 62 /* TODO: implement */ 63 if (request->setup_buffer) { 64 usb_log_info("Root hub got SETUP packet: %s.\n", 65 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 66 } 67 usb_log_error("Root hub request processing not implemented.\n"); 68 usb_transfer_batch_finish(request, ENOTSUP); 526 int opResult; 527 if(request->transfer_type == USB_TRANSFER_CONTROL){ 528 if (request->setup_buffer) { 529 usb_log_info("Root hub got CTRL packet: %s.\n", 530 usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8)); 531 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){ 532 usb_log_error("setup packet too small\n"); 533 return EINVAL; 534 } 535 usb_device_request_setup_packet_t * setup_request = 536 (usb_device_request_setup_packet_t*)request->setup_buffer; 537 if( 538 setup_request->request == USB_DEVREQ_GET_STATUS 539 || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR 540 || setup_request->request == USB_DEVREQ_GET_CONFIGURATION 541 ){ 542 usb_log_debug("processing request with output\n"); 543 opResult = process_request_with_output(instance,request); 544 }else if( 545 setup_request->request == USB_DEVREQ_CLEAR_FEATURE 546 || setup_request->request == USB_DEVREQ_SET_FEATURE 547 || setup_request->request == USB_DEVREQ_SET_ADDRESS 548 ){ 549 usb_log_debug("processing request without additional data\n"); 550 opResult = process_request_without_data(instance,request); 551 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR 552 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION 553 ){ 554 usb_log_debug("processing request with input\n"); 555 opResult = process_request_with_input(instance,request); 556 }else{ 557 usb_log_warning("received unsuported request: %d\n", 558 setup_request->request 559 ); 560 opResult = ENOTSUP; 561 } 562 }else{ 563 usb_log_error("root hub received empty transaction?"); 564 opResult = EINVAL; 565 } 566 }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){ 567 usb_log_info("Root hub got INTERRUPT packet\n"); 568 void * buffer; 569 create_interrupt_mask(instance, &buffer, 570 &(request->transfered_size)); 571 memcpy(request->transport_buffer,buffer, request->transfered_size); 572 opResult = EOK; 573 }else{ 574 opResult = EINVAL; 575 } 576 usb_transfer_batch_finish(request, opResult); 69 577 return EOK; 70 578 } 71 579 /*----------------------------------------------------------------------------*/ 580 581 72 582 void rh_interrupt(rh_t *instance) 73 583 { -
uspace/drv/ohci/root_hub.h
r889e8e3 r291b8bc 45 45 usb_address_t address; 46 46 ddf_dev_t *device; 47 int port_count; 47 48 } rh_t; 48 49 -
uspace/drv/uhci-hcd/Makefile
r889e8e3 r291b8bc 40 40 root_hub.c \ 41 41 hw_struct/transfer_descriptor.c \ 42 utils/slab.c \ 42 43 pci.c \ 43 44 batch.c -
uspace/drv/uhci-hcd/hc.c
r889e8e3 r291b8bc 223 223 ret = instance ? EOK : ENOMEM; 224 224 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n"); 225 usb_log_debug("Initialized frame list .\n");225 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); 226 226 227 227 /* Set all frames to point to the first queue head */ … … 336 336 instance->transfers[batch->speed][batch->transfer_type]; 337 337 assert(list); 338 if (batch->transfer_type == USB_TRANSFER_CONTROL) { 339 usb_device_keeper_use_control( 340 &instance->manager, batch->target.address); 341 } 338 342 transfer_list_add_batch(list, batch); 339 343 … … 357 361 /* Lower 2 bits are transaction error and transaction complete */ 358 362 if (status & 0x3) { 359 transfer_list_remove_finished(&instance->transfers_interrupt); 360 transfer_list_remove_finished(&instance->transfers_control_slow); 361 transfer_list_remove_finished(&instance->transfers_control_full); 362 transfer_list_remove_finished(&instance->transfers_bulk_full); 363 LIST_INITIALIZE(done); 364 transfer_list_remove_finished( 365 &instance->transfers_interrupt, &done); 366 transfer_list_remove_finished( 367 &instance->transfers_control_slow, &done); 368 transfer_list_remove_finished( 369 &instance->transfers_control_full, &done); 370 transfer_list_remove_finished( 371 &instance->transfers_bulk_full, &done); 372 373 while (!list_empty(&done)) { 374 link_t *item = done.next; 375 list_remove(item); 376 usb_transfer_batch_t *batch = 377 list_get_instance(item, usb_transfer_batch_t, link); 378 if (batch->transfer_type == USB_TRANSFER_CONTROL) { 379 usb_device_keeper_release_control( 380 &instance->manager, batch->target.address); 381 } 382 batch->next_step(batch); 383 } 363 384 } 364 385 /* bits 4 and 5 indicate hc error */ -
uspace/drv/uhci-hcd/root_hub.c
r889e8e3 r291b8bc 48 48 * @return Error code. 49 49 */ 50 int rh_init( 51 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 50 int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 52 51 { 53 52 assert(fun); -
uspace/drv/uhci-hcd/transfer_list.c
r889e8e3 r291b8bc 58 58 } 59 59 instance->queue_head_pa = addr_to_phys(instance->queue_head); 60 usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n", 61 name, instance->queue_head, instance->queue_head_pa); 60 62 61 63 qh_init(instance->queue_head); … … 118 120 qh_set_next_qh(last_qh, pa); 119 121 122 asm volatile ("": : :"memory"); 123 120 124 /* Add to the driver list */ 121 125 list_append(&batch->link, &instance->batch_list); … … 137 141 * this transfer list leading to the deadlock if its done inline. 138 142 */ 139 void transfer_list_remove_finished(transfer_list_t *instance) 140 { 141 assert(instance); 142 143 LIST_INITIALIZE(done); 143 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done) 144 { 145 assert(instance); 146 assert(done); 144 147 145 148 fibril_mutex_lock(&instance->guard); … … 153 156 /* Save for post-processing */ 154 157 transfer_list_remove_batch(instance, batch); 155 list_append(current, &done);158 list_append(current, done); 156 159 } 157 160 current = next; … … 159 162 fibril_mutex_unlock(&instance->guard); 160 163 161 while (!list_empty(&done)) {162 link_t *item = done.next;163 list_remove(item);164 usb_transfer_batch_t *batch =165 list_get_instance(item, usb_transfer_batch_t, link);166 batch->next_step(batch);167 }168 164 } 169 165 /*----------------------------------------------------------------------------*/ … … 222 218 qpos = "NOT FIRST"; 223 219 } 220 asm volatile ("": : :"memory"); 224 221 /* Remove from the batch list */ 225 222 list_remove(&batch->link); -
uspace/drv/uhci-hcd/transfer_list.h
r889e8e3 r291b8bc 67 67 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch); 68 68 69 void transfer_list_remove_finished(transfer_list_t *instance );69 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done); 70 70 71 71 void transfer_list_abort_all(transfer_list_t *instance); -
uspace/drv/uhci-hcd/uhci.c
r889e8e3 r291b8bc 44 44 #include "pci.h" 45 45 46 47 46 /** IRQ handling callback, identifies device 48 47 * … … 108 107 /*----------------------------------------------------------------------------*/ 109 108 static ddf_dev_ops_t hc_ops = { 110 .interfaces[USB_DEV_IFACE] = &usb_iface,109 // .interfaces[USB_DEV_IFACE] = &usb_iface, 111 110 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 112 111 }; -
uspace/drv/uhci-hcd/utils/malloc32.h
r889e8e3 r291b8bc 40 40 #include <as.h> 41 41 42 #include "slab.h" 43 42 44 #define UHCI_STRCUTURES_ALIGNMENT 16 43 45 #define UHCI_REQUIRED_PAGE_SIZE 4096 46 44 47 45 48 /** Get physical address translation … … 54 57 55 58 uintptr_t result; 56 int ret = as_get_physical_mapping(addr, &result); 59 const int ret = as_get_physical_mapping(addr, &result); 60 assert(ret == EOK); 57 61 58 62 if (ret != EOK) … … 66 70 * @return Address of the alligned and big enough memory place, NULL on failure. 67 71 */ 68 static inline void * malloc32(size_t size) 69 { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); } 72 static inline void * malloc32(size_t size) { 73 if (size <= SLAB_ELEMENT_SIZE) 74 return slab_malloc_g(); 75 assert(false); 76 return memalign(UHCI_STRCUTURES_ALIGNMENT, size); 77 } 70 78 /*----------------------------------------------------------------------------*/ 71 79 /** Physical mallocator simulator … … 73 81 * @param[in] addr Address of the place allocated by malloc32 74 82 */ 75 static inline void free32(void *addr) 76 { if (addr) free(addr); } 83 static inline void free32(void *addr) { 84 if (!addr) 85 return; 86 if (slab_in_range_g(addr)) 87 return slab_free_g(addr); 88 free(addr); 89 } 77 90 /*----------------------------------------------------------------------------*/ 78 91 /** Create 4KB page mapping … … 82 95 static inline void * get_page(void) 83 96 { 84 void * 85 assert(free_address); 97 void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE); 98 assert(free_address); /* TODO: remove this assert */ 86 99 if (free_address == 0) 87 100 return NULL; 88 void* ret = 89 as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 101 void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 90 102 AS_AREA_READ | AS_AREA_WRITE); 91 103 if (ret != free_address) -
uspace/drv/uhci-hcd/utils/slab.h
r889e8e3 r291b8bc 1 1 /* 2 * Copyright (c) 201 0 Lubos Slovak2 * Copyright (c) 2011 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup drvusbhid 28 /** @addtogroup usb 30 29 * @{ 31 30 */ 32 31 /** @file 33 * Descriptor dumping.32 * @brief UHCI driver 34 33 */ 34 #ifndef DRV_UHCI_SLAB_H 35 #define DRV_UHCI_SLAB_H 35 36 36 #ifndef USBHID_DESCDUMP_H_ 37 #define USBHID_DESCDUMP_H_ 37 #include <bool.h> 38 38 39 #include <usb/descriptor.h> 40 #include <usb/classes/hid.h> 39 #define SLAB_ELEMENT_SIZE 1024 41 40 42 void dump_standard_configuration_descriptor( 43 int index, const usb_standard_configuration_descriptor_t *d); 41 void * slab_malloc_g(void); 44 42 45 void dump_standard_interface_descriptor( 46 const usb_standard_interface_descriptor_t *d); 43 void slab_free_g(void *addr); 47 44 48 void dump_standard_endpoint_descriptor( 49 const usb_standard_endpoint_descriptor_t *d); 45 bool slab_in_range_g(void *addr); 50 46 51 void dump_standard_hid_descriptor_header( 52 const usb_standard_hid_descriptor_t *d); 53 54 void dump_standard_hid_class_descriptor_info( 55 const usb_standard_hid_class_descriptor_info_t *d); 56 57 void dump_hid_class_descriptor(int index, uint8_t type, 58 const uint8_t *d, size_t size); 59 60 #endif /* USBHID_DESCDUMP_H_ */ 61 47 #endif 62 48 /** 63 49 * @} -
uspace/drv/usbhub/port_status.h
r889e8e3 r291b8bc 30 30 */ 31 31 32 #ifndef PORT_STATUS_H33 #define PORT_STATUS_H32 #ifndef HUB_PORT_STATUS_H 33 #define HUB_PORT_STATUS_H 34 34 35 35 #include <bool.h> … … 335 335 336 336 337 #endif /* PORT_STATUS_H */337 #endif /* HUB_PORT_STATUS_H */ 338 338 339 339 /** -
uspace/drv/usbhub/usbhub.c
r889e8e3 r291b8bc 162 162 std_descriptor->configuration_count); 163 163 if(std_descriptor->configuration_count<1){ 164 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n"); 165 //shouldn`t I return? 166 //definitely 164 usb_log_error("there are no configurations available\n"); 167 165 return EINVAL; 168 166 } -
uspace/drv/usbkbd/Makefile
r889e8e3 r291b8bc 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 32 BINARY = usb hid32 BINARY = usbkbd 33 33 34 34 STOLEN_LAYOUT_SOURCES = \ … … 40 40 main.c \ 41 41 conv.c \ 42 hidreq.c \43 42 kbddev.c \ 44 43 kbdrepeat.c \ 45 hiddev.c \46 44 $(STOLEN_LAYOUT_SOURCES) 47 45 -
uspace/drv/usbkbd/conv.h
r889e8e3 r291b8bc 34 34 */ 35 35 36 #ifndef USB HID_CONV_H_37 #define USB HID_CONV_H_36 #ifndef USB_KBD_CONV_H_ 37 #define USB_KBD_CONV_H_ 38 38 39 39 unsigned int usbhid_parse_scancode(int scancode); 40 40 41 #endif /* USB HID_CONV_H_ */41 #endif /* USB_KBD_CONV_H_ */ 42 42 43 43 /** -
uspace/drv/usbkbd/kbddev.c
r889e8e3 r291b8bc 46 46 47 47 #include <usb/usb.h> 48 #include <usb/dp.h> 49 #include <usb/request.h> 48 50 #include <usb/classes/hid.h> 49 51 #include <usb/pipes.h> … … 52 54 #include <usb/classes/classes.h> 53 55 #include <usb/classes/hidut.h> 56 #include <usb/classes/hidreq.h> 57 #include <usb/classes/hidreport.h> 58 59 #include <usb/devdrv.h> 54 60 55 61 #include "kbddev.h" 56 #include "hiddev.h" 57 #include "hidreq.h" 62 58 63 #include "layout.h" 59 64 #include "conv.h" … … 85 90 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000; 86 91 92 /*----------------------------------------------------------------------------*/ 93 87 94 /** Keyboard polling endpoint description for boot protocol class. */ 88 static usb_endpoint_description_t poll_endpoint_description = {95 static usb_endpoint_description_t boot_poll_endpoint_description = { 89 96 .transfer_type = USB_TRANSFER_INTERRUPT, 90 97 .direction = USB_DIRECTION_IN, … … 95 102 }; 96 103 97 typedef enum usbhid_kbd_flags { 98 USBHID_KBD_STATUS_UNINITIALIZED = 0, 99 USBHID_KBD_STATUS_INITIALIZED = 1, 100 USBHID_KBD_STATUS_TO_DESTROY = -1 101 } usbhid_kbd_flags; 104 /* Array of endpoints expected on the device, NULL terminated. */ 105 usb_endpoint_description_t 106 *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1] = { 107 &boot_poll_endpoint_description, 108 NULL 109 }; 110 111 /*----------------------------------------------------------------------------*/ 112 113 enum { 114 BOOT_REPORT_DESCRIPTOR_SIZE = 63 115 }; 116 117 static const uint8_t BOOT_REPORT_DESCRIPTOR[BOOT_REPORT_DESCRIPTOR_SIZE] = { 118 0x05, 0x01, // Usage Page (Generic Desktop), 119 0x09, 0x06, // Usage (Keyboard), 120 0xA1, 0x01, // Collection (Application), 121 0x75, 0x01, // Report Size (1), 122 0x95, 0x08, // Report Count (8), 123 0x05, 0x07, // Usage Page (Key Codes); 124 0x19, 0xE0, // Usage Minimum (224), 125 0x29, 0xE7, // Usage Maximum (231), 126 0x15, 0x00, // Logical Minimum (0), 127 0x25, 0x01, // Logical Maximum (1), 128 0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte 129 0x95, 0x01, // Report Count (1), 130 0x75, 0x08, // Report Size (8), 131 0x81, 0x01, // Input (Constant), ; Reserved byte 132 0x95, 0x05, // Report Count (5), 133 0x75, 0x01, // Report Size (1), 134 0x05, 0x08, // Usage Page (Page# for LEDs), 135 0x19, 0x01, // Usage Minimum (1), 136 0x29, 0x05, // Usage Maxmimum (5), 137 0x91, 0x02, // Output (Data, Variable, Absolute), ; LED report 138 0x95, 0x01, // Report Count (1), 139 0x75, 0x03, // Report Size (3), 140 0x91, 0x01, // Output (Constant), ; LED report padding 141 0x95, 0x06, // Report Count (6), 142 0x75, 0x08, // Report Size (8), 143 0x15, 0x00, // Logical Minimum (0), 144 0x25, 0xff, // Logical Maximum (255), 145 0x05, 0x07, // Usage Page (Key Codes), 146 0x19, 0x00, // Usage Minimum (0), 147 0x29, 0xff, // Usage Maximum (255), 148 0x81, 0x00, // Input (Data, Array), ; Key arrays (6 bytes) 149 0xC0 // End Collection 150 151 }; 152 153 /*----------------------------------------------------------------------------*/ 154 155 typedef enum usb_kbd_flags { 156 USB_KBD_STATUS_UNINITIALIZED = 0, 157 USB_KBD_STATUS_INITIALIZED = 1, 158 USB_KBD_STATUS_TO_DESTROY = -1 159 } usb_kbd_flags; 102 160 103 161 /*----------------------------------------------------------------------------*/ … … 132 190 133 191 typedef enum usbhid_lock_code { 134 USB HID_LOCK_NUM = 0x53,135 USB HID_LOCK_CAPS = 0x39,136 USB HID_LOCK_SCROLL = 0x47,137 USB HID_LOCK_COUNT = 3192 USB_KBD_LOCK_NUM = 0x53, 193 USB_KBD_LOCK_CAPS = 0x39, 194 USB_KBD_LOCK_SCROLL = 0x47, 195 USB_KBD_LOCK_COUNT = 3 138 196 } usbhid_lock_code; 139 197 140 static const usbhid_lock_code usbhid_lock_codes[USB HID_LOCK_COUNT] = {141 USB HID_LOCK_NUM,142 USB HID_LOCK_CAPS,143 USB HID_LOCK_SCROLL198 static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = { 199 USB_KBD_LOCK_NUM, 200 USB_KBD_LOCK_CAPS, 201 USB_KBD_LOCK_SCROLL 144 202 }; 145 203 … … 149 207 150 208 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 151 staticddf_dev_ops_t keyboard_ops = {209 ddf_dev_ops_t keyboard_ops = { 152 210 .default_handler = default_connection_handler 153 211 }; … … 169 227 sysarg_t method = IPC_GET_IMETHOD(*icall); 170 228 171 usb hid_kbd_t *kbd_dev = (usbhid_kbd_t *)fun->driver_data;229 usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data; 172 230 assert(kbd_dev != NULL); 173 231 … … 203 261 * @param kbd_dev Keyboard device structure. 204 262 */ 205 static void usb hid_kbd_set_led(usbhid_kbd_t *kbd_dev)263 static void usb_kbd_set_led(usb_kbd_t *kbd_dev) 206 264 { 207 265 uint8_t buffer[BOOTP_BUFFER_OUT_SIZE]; … … 237 295 usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0)); 238 296 239 assert(kbd_dev->hid_dev != NULL); 240 assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 241 usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT, 297 assert(kbd_dev->usb_dev != NULL); 298 299 usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe, 300 kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 242 301 buffer, BOOTP_BUFFER_OUT_SIZE); 243 302 } … … 260 319 * @param key Key code of the key according to HID Usage Tables. 261 320 */ 262 void usb hid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)321 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key) 263 322 { 264 323 console_event_t ev; … … 310 369 /* Update keyboard lock indicator lights. */ 311 370 if (kbd_dev->lock_keys != locks_old) { 312 usb hid_kbd_set_led(kbd_dev);371 usb_kbd_set_led(kbd_dev); 313 372 } 314 373 } else { … … 358 417 359 418 /*----------------------------------------------------------------------------*/ 360 /** 361 * Checks if modifiers were pressed or released and generates key events. 362 * 363 * @param kbd_dev Keyboard device structure. 364 * @param modifiers Bitmap of modifiers. 365 * 366 * @sa usbhid_kbd_push_ev() 367 */ 368 //static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev, 369 // const uint8_t *key_codes, size_t count) 370 //{ 371 // /* 372 // * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK 373 // * both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes??? 374 // * 375 // * modifiers should be sent as normal keys to usbhid_parse_scancode()!! 376 // * so maybe it would be better if I received it from report parser in 377 // * that way 378 // */ 379 380 // int i; 381 // for (i = 0; i < count; ++i) { 382 // if ((modifiers & usb_hid_modifiers_consts[i]) && 383 // !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) { 384 // // modifier pressed 385 // if (usbhid_modifiers_keycodes[i] != 0) { 386 // usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, 387 // usbhid_modifiers_keycodes[i]); 388 // } 389 // } else if (!(modifiers & usb_hid_modifiers_consts[i]) && 390 // (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) { 391 // // modifier released 392 // if (usbhid_modifiers_keycodes[i] != 0) { 393 // usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, 394 // usbhid_modifiers_keycodes[i]); 395 // } 396 // } // no change 397 // } 398 399 // kbd_dev->modifiers = modifiers; 400 //} 401 402 /*----------------------------------------------------------------------------*/ 403 404 static inline int usbhid_kbd_is_lock(unsigned int key_code) 419 420 static inline int usb_kbd_is_lock(unsigned int key_code) 405 421 { 406 422 return (key_code == KC_NUM_LOCK … … 414 430 * 415 431 * An event is created only when key is pressed or released. Besides handling 416 * the events (usb hid_kbd_push_ev()), the auto-repeat fibril is notified about417 * key presses and releases (see usb hid_kbd_repeat_start() and418 * usb hid_kbd_repeat_stop()).432 * the events (usb_kbd_push_ev()), the auto-repeat fibril is notified about 433 * key presses and releases (see usb_kbd_repeat_start() and 434 * usb_kbd_repeat_stop()). 419 435 * 420 436 * @param kbd_dev Keyboard device structure. … … 423 439 * @param count Number of key codes in report (size of the report). 424 440 * 425 * @sa usb hid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()426 */ 427 static void usb hid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,441 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop() 442 */ 443 static void usb_kbd_check_key_changes(usb_kbd_t *kbd_dev, 428 444 const uint8_t *key_codes, size_t count) 429 445 { … … 434 450 * First of all, check if the kbd have reported phantom state. 435 451 * 436 * TODO:this must be changed as we don't know which keys are modifiers452 * this must be changed as we don't know which keys are modifiers 437 453 * and which are regular keys. 438 454 */ … … 466 482 // not found, i.e. the key was released 467 483 key = usbhid_parse_scancode(kbd_dev->keys[j]); 468 if (!usb hid_kbd_is_lock(key)) {469 usb hid_kbd_repeat_stop(kbd_dev, key);484 if (!usb_kbd_is_lock(key)) { 485 usb_kbd_repeat_stop(kbd_dev, key); 470 486 } 471 usb hid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);487 usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 472 488 usb_log_debug2("Key released: %d\n", key); 473 489 } else { … … 491 507 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 492 508 key_codes[i]); 493 usb hid_kbd_push_ev(kbd_dev, KEY_PRESS, key);494 if (!usb hid_kbd_is_lock(key)) {495 usb hid_kbd_repeat_start(kbd_dev, key);509 usb_kbd_push_ev(kbd_dev, KEY_PRESS, key); 510 if (!usb_kbd_is_lock(key)) { 511 usb_kbd_repeat_start(kbd_dev, key); 496 512 } 497 513 } else { … … 523 539 * structure representing the keyboard. 524 540 * 525 * @sa usb hid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()526 */ 527 static void usb hid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,541 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes() 542 */ 543 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 528 544 uint8_t modifiers, void *arg) 529 545 { … … 534 550 } 535 551 536 usb hid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;552 usb_kbd_t *kbd_dev = (usb_kbd_t *)arg; 537 553 assert(kbd_dev != NULL); 538 554 … … 546 562 } 547 563 548 ///usb hid_kbd_check_modifier_changes(kbd_dev, key_codes, count);549 usb hid_kbd_check_key_changes(kbd_dev, key_codes, count);564 ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count); 565 usb_kbd_check_key_changes(kbd_dev, key_codes, count); 550 566 } 551 567 … … 558 574 * This function uses the HID report parser to translate the data received from 559 575 * the device into generic USB HID key codes and into generic modifiers bitmap. 560 * The parser then calls the given callback (usb hid_kbd_process_keycodes()).576 * The parser then calls the given callback (usb_kbd_process_keycodes()). 561 577 * 562 578 * @note Currently, only the boot protocol is supported. … … 566 582 * @param actual_size Size of the data from keyboard (report size) in bytes. 567 583 * 568 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(). 569 */ 570 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev, 584 * @sa usb_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(), 585 * usb_hid_parse_report(). 586 */ 587 static void usb_kbd_process_data(usb_kbd_t *kbd_dev, 571 588 uint8_t *buffer, size_t actual_size) 572 589 { 573 assert(kbd_dev->initialized == USB HID_KBD_STATUS_INITIALIZED);574 assert(kbd_dev-> hid_dev->parser != NULL);590 assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 591 assert(kbd_dev->parser != NULL); 575 592 576 593 usb_hid_report_in_callbacks_t *callbacks = … … 578 595 sizeof(usb_hid_report_in_callbacks_t)); 579 596 580 callbacks->keyboard = usb hid_kbd_process_keycodes;597 callbacks->keyboard = usb_kbd_process_keycodes; 581 598 582 599 usb_log_debug("Calling usb_hid_parse_report() with " … … 585 602 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 586 603 // callbacks, kbd_dev); 587 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 588 actual_size, callbacks, kbd_dev); 604 usb_hid_report_path_t *path = usb_hid_report_path(); 605 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 606 607 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, 608 actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev); 609 610 usb_hid_report_path_free (path); 589 611 590 612 if (rc != EOK) { … … 597 619 /* HID/KBD structure manipulation */ 598 620 /*----------------------------------------------------------------------------*/ 621 622 static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev) 623 { 624 kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY; 625 } 626 627 628 /*----------------------------------------------------------------------------*/ 629 /* API functions */ 630 /*----------------------------------------------------------------------------*/ 599 631 /** 600 632 * Creates a new USB/HID keyboard structure. 601 633 * 602 634 * The structure returned by this function is not initialized. Use 603 * usb hid_kbd_init() to initialize it prior to polling.635 * usb_kbd_init() to initialize it prior to polling. 604 636 * 605 637 * @return New uninitialized structure for representing a USB/HID keyboard or 606 638 * NULL if not successful (memory error). 607 639 */ 608 static usbhid_kbd_t *usbhid_kbd_new(void)609 { 610 usb hid_kbd_t *kbd_dev =611 (usb hid_kbd_t *)malloc(sizeof(usbhid_kbd_t));640 usb_kbd_t *usb_kbd_new(void) 641 { 642 usb_kbd_t *kbd_dev = 643 (usb_kbd_t *)malloc(sizeof(usb_kbd_t)); 612 644 613 645 if (kbd_dev == NULL) { … … 616 648 } 617 649 618 memset(kbd_dev, 0, sizeof(usbhid_kbd_t)); 619 620 kbd_dev->hid_dev = usbhid_dev_new(); 621 if (kbd_dev->hid_dev == NULL) { 622 usb_log_fatal("Could not create HID device structure.\n"); 650 memset(kbd_dev, 0, sizeof(usb_kbd_t)); 651 652 kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 653 usb_hid_report_parser_t))); 654 if (kbd_dev->parser == NULL) { 655 usb_log_fatal("No memory!\n"); 656 free(kbd_dev); 623 657 return NULL; 624 658 } 625 659 626 660 kbd_dev->console_phone = -1; 627 kbd_dev->initialized = USB HID_KBD_STATUS_UNINITIALIZED;661 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 628 662 629 663 return kbd_dev; 630 }631 632 /*----------------------------------------------------------------------------*/633 634 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)635 {636 kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;637 664 } 638 665 … … 658 685 * @return Other value inherited from function usbhid_dev_init(). 659 686 */ 660 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)687 int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev) 661 688 { 662 689 int rc; … … 671 698 672 699 if (dev == NULL) { 673 usb_log_error("Failed to init keyboard structure: no device"700 usb_log_error("Failed to init keyboard structure: no USB device" 674 701 " given.\n"); 675 702 return EINVAL; 676 703 } 677 704 678 if (kbd_dev->initialized == USB HID_KBD_STATUS_INITIALIZED) {705 if (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED) { 679 706 usb_log_warning("Keyboard structure already initialized.\n"); 680 707 return EINVAL; 681 708 } 682 709 683 rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description); 684 710 /* TODO: does not work! */ 711 if (!dev->pipes[USB_KBD_POLL_EP_NO].present) { 712 usb_log_warning("Required endpoint not found - probably not " 713 "a supported device.\n"); 714 return ENOTSUP; 715 } 716 717 /* The USB device should already be initialized, save it in structure */ 718 kbd_dev->usb_dev = dev; 719 720 /* Initialize the report parser. */ 721 rc = usb_hid_parser_init(kbd_dev->parser); 685 722 if (rc != EOK) { 686 usb_log_error("Failed to initialize HID device structure: %s\n", 687 str_error(rc)); 723 usb_log_error("Failed to initialize report parser.\n"); 688 724 return rc; 689 725 } 690 726 691 assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 692 693 // save the size of the report (boot protocol report by default) 694 // kbd_dev->key_count = BOOTP_REPORT_SIZE; 695 696 usb_hid_report_path_t path; 697 path.usage_page = USB_HIDUT_PAGE_KEYBOARD; 727 /* Get the report descriptor and parse it. */ 728 rc = usb_hid_process_report_descriptor(kbd_dev->usb_dev, 729 kbd_dev->parser); 730 if (rc != EOK) { 731 usb_log_warning("Could not process report descriptor, " 732 "falling back to boot protocol.\n"); 733 rc = usb_hid_parse_report_descriptor(kbd_dev->parser, 734 BOOT_REPORT_DESCRIPTOR, BOOT_REPORT_DESCRIPTOR_SIZE); 735 if (rc != EOK) { 736 usb_log_error("Failed to parse boot report descriptor:" 737 " %s.\n", str_error(rc)); 738 return rc; 739 } 740 741 rc = usbhid_req_set_protocol(&kbd_dev->usb_dev->ctrl_pipe, 742 kbd_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 743 744 if (rc != EOK) { 745 usb_log_warning("Failed to set boot protocol to the " 746 "device: %s\n", str_error(rc)); 747 return rc; 748 } 749 } 750 751 /* 752 * TODO: make more general 753 */ 754 usb_hid_report_path_t *path = usb_hid_report_path(); 755 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 698 756 kbd_dev->key_count = usb_hid_report_input_length( 699 kbd_dev->hid_dev->parser, &path); 757 kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT); 758 usb_hid_report_path_free (path); 700 759 701 760 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); … … 729 788 730 789 /* 731 * Set boot protocol.732 790 * Set LEDs according to initial setup. 733 791 * Set Idle rate 734 792 */ 735 assert(kbd_dev->hid_dev != NULL); 736 assert(kbd_dev->hid_dev->initialized); 737 //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT); 738 739 usbhid_kbd_set_led(kbd_dev); 740 741 usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE); 742 743 kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED; 793 usb_kbd_set_led(kbd_dev); 794 795 usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe, 796 kbd_dev->usb_dev->interface_no, IDLE_RATE); 797 798 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 744 799 usb_log_debug("HID/KBD device structure initialized.\n"); 745 800 … … 748 803 749 804 /*----------------------------------------------------------------------------*/ 750 /* HID/KBD polling */ 751 /*----------------------------------------------------------------------------*/ 752 /** 753 * Main keyboard polling function. 754 * 755 * This function uses the Interrupt In pipe of the keyboard to poll for events. 756 * The keyboard is initialized in a way that it reports only when a key is 757 * pressed or released, so there is no actual need for any sleeping between 758 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()). 759 * 760 * @param kbd_dev Initialized keyboard structure representing the device to 761 * poll. 762 * 763 * @sa usbhid_kbd_process_data() 764 */ 765 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev) 766 { 767 int rc, sess_rc; 768 uint8_t buffer[BOOTP_BUFFER_SIZE]; 769 size_t actual_size; 770 771 usb_log_debug("Polling keyboard...\n"); 772 773 if (!kbd_dev->initialized) { 774 usb_log_error("HID/KBD device not initialized!\n"); 775 return; 776 } 777 778 assert(kbd_dev->hid_dev != NULL); 779 assert(kbd_dev->hid_dev->initialized); 780 781 while (true) { 782 sess_rc = usb_pipe_start_session( 783 &kbd_dev->hid_dev->poll_pipe); 784 if (sess_rc != EOK) { 785 usb_log_warning("Failed to start a session: %s.\n", 786 str_error(sess_rc)); 787 break; 788 } 789 790 rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe, 791 buffer, BOOTP_BUFFER_SIZE, &actual_size); 792 793 sess_rc = usb_pipe_end_session( 794 &kbd_dev->hid_dev->poll_pipe); 795 796 if (rc != EOK) { 797 usb_log_warning("Error polling the keyboard: %s.\n", 798 str_error(rc)); 799 break; 800 } 801 802 if (sess_rc != EOK) { 803 usb_log_warning("Error closing session: %s.\n", 804 str_error(sess_rc)); 805 break; 806 } 807 808 /* 809 * If the keyboard answered with NAK, it returned no data. 810 * This implies that no change happened since last query. 811 */ 812 if (actual_size == 0) { 813 usb_log_debug("Keyboard returned NAK\n"); 814 continue; 815 } 816 817 /* 818 * TODO: Process pressed keys. 819 */ 820 usb_log_debug("Calling usbhid_kbd_process_data()\n"); 821 usbhid_kbd_process_data(kbd_dev, buffer, actual_size); 822 823 // disabled for now, no reason to sleep 824 //async_usleep(kbd_dev->hid_dev->poll_interval); 825 } 826 } 827 828 /*----------------------------------------------------------------------------*/ 829 /** 830 * Function executed by the main driver fibril. 831 * 832 * Just starts polling the keyboard for events. 833 * 834 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t) 835 * representing the device. 836 * 837 * @retval EOK if the fibril finished polling the device. 838 * @retval EINVAL if no device was given in the argument. 839 * 840 * @sa usbhid_kbd_poll() 841 * 842 * @todo Change return value - only case when the fibril finishes is in case 843 * of some error, so the error should probably be propagated from function 844 * usbhid_kbd_poll() to here and up. 845 */ 846 static int usbhid_kbd_fibril(void *arg) 847 { 848 if (arg == NULL) { 849 usb_log_error("No device!\n"); 850 return EINVAL; 851 } 852 853 usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg; 854 855 usbhid_kbd_poll(kbd_dev); 856 857 // as there is another fibril using this device, so we must leave the 858 // structure to it, but mark it for destroying. 859 usbhid_kbd_mark_unusable(kbd_dev); 860 // at the end, properly destroy the KBD structure 861 // usbhid_kbd_free(&kbd_dev); 862 // assert(kbd_dev == NULL); 863 864 return EOK; 865 } 866 867 /*----------------------------------------------------------------------------*/ 868 /* API functions */ 869 /*----------------------------------------------------------------------------*/ 870 /** 871 * Function for adding a new device of type USB/HID/keyboard. 872 * 873 * This functions initializes required structures from the device's descriptors 874 * and starts new fibril for polling the keyboard for events and another one for 875 * handling auto-repeat of keys. 876 * 877 * During initialization, the keyboard is switched into boot protocol, the idle 878 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 879 * when a key is pressed or released. Finally, the LED lights are turned on 880 * according to the default setup of lock keys. 881 * 882 * @note By default, the keyboards is initialized with Num Lock turned on and 883 * other locks turned off. 884 * @note Currently supports only boot-protocol keyboards. 885 * 886 * @param dev Device to add. 887 * 888 * @retval EOK if successful. 889 * @retval ENOMEM if there 890 * @return Other error code inherited from one of functions usbhid_kbd_init(), 891 * ddf_fun_bind() and ddf_fun_add_to_class(). 892 * 893 * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril() 894 */ 895 int usbhid_kbd_try_add_device(ddf_dev_t *dev) 896 { 897 /* 898 * Create default function. 899 */ 900 ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard"); 901 if (kbd_fun == NULL) { 902 usb_log_error("Could not create DDF function node.\n"); 903 return ENOMEM; 904 } 905 906 /* 907 * Initialize device (get and process descriptors, get address, etc.) 908 */ 909 usb_log_debug("Initializing USB/HID KBD device...\n"); 910 911 usbhid_kbd_t *kbd_dev = usbhid_kbd_new(); 912 if (kbd_dev == NULL) { 913 usb_log_error("Error while creating USB/HID KBD device " 914 "structure.\n"); 915 ddf_fun_destroy(kbd_fun); 916 return ENOMEM; // TODO: some other code?? 917 } 918 919 int rc = usbhid_kbd_init(kbd_dev, dev); 920 921 if (rc != EOK) { 922 usb_log_error("Failed to initialize USB/HID KBD device.\n"); 923 ddf_fun_destroy(kbd_fun); 924 usbhid_kbd_free(&kbd_dev); 925 return rc; 926 } 927 928 usb_log_debug("USB/HID KBD device structure initialized.\n"); 929 930 /* 931 * Store the initialized keyboard device and keyboard ops 932 * to the DDF function. 933 */ 934 kbd_fun->driver_data = kbd_dev; 935 kbd_fun->ops = &keyboard_ops; 936 937 rc = ddf_fun_bind(kbd_fun); 938 if (rc != EOK) { 939 usb_log_error("Could not bind DDF function: %s.\n", 940 str_error(rc)); 941 // TODO: Can / should I destroy the DDF function? 942 ddf_fun_destroy(kbd_fun); 943 usbhid_kbd_free(&kbd_dev); 944 return rc; 945 } 946 947 rc = ddf_fun_add_to_class(kbd_fun, "keyboard"); 948 if (rc != EOK) { 949 usb_log_error( 950 "Could not add DDF function to class 'keyboard': %s.\n", 951 str_error(rc)); 952 // TODO: Can / should I destroy the DDF function? 953 ddf_fun_destroy(kbd_fun); 954 usbhid_kbd_free(&kbd_dev); 955 return rc; 956 } 957 958 /* 959 * Create new fibril for handling this keyboard 960 */ 961 fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev); 962 if (fid == 0) { 963 usb_log_error("Failed to start fibril for `%s' device.\n", 964 dev->name); 965 return ENOMEM; 966 } 967 fibril_add_ready(fid); 968 969 /* 970 * Create new fibril for auto-repeat 971 */ 972 fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev); 973 if (fid == 0) { 974 usb_log_error("Failed to start fibril for KBD auto-repeat"); 975 return ENOMEM; 976 } 977 fibril_add_ready(fid); 978 979 (void)keyboard_ops; 980 981 /* 982 * Hurrah, device is initialized. 983 */ 984 return EOK; 985 } 986 987 /*----------------------------------------------------------------------------*/ 988 989 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev) 990 { 991 return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 805 806 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 807 size_t buffer_size, void *arg) 808 { 809 if (dev == NULL || buffer == NULL || arg == NULL) { 810 // do not continue polling (???) 811 return false; 812 } 813 814 usb_kbd_t *kbd_dev = (usb_kbd_t *)arg; 815 816 // TODO: add return value from this function 817 usb_kbd_process_data(kbd_dev, buffer, buffer_size); 818 819 return true; 820 } 821 822 /*----------------------------------------------------------------------------*/ 823 824 void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason, 825 void *arg) 826 { 827 if (dev == NULL || arg == NULL) { 828 return; 829 } 830 831 usb_kbd_t *kbd = (usb_kbd_t *)arg; 832 833 usb_kbd_mark_unusable(kbd); 834 } 835 836 /*----------------------------------------------------------------------------*/ 837 838 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev) 839 { 840 return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 841 } 842 843 /*----------------------------------------------------------------------------*/ 844 845 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev) 846 { 847 return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY); 992 848 } 993 849 … … 998 854 * @param kbd_dev Pointer to the structure to be destroyed. 999 855 */ 1000 void usb hid_kbd_free(usbhid_kbd_t **kbd_dev)856 void usb_kbd_free(usb_kbd_t **kbd_dev) 1001 857 { 1002 858 if (kbd_dev == NULL || *kbd_dev == NULL) { … … 1007 863 async_hangup((*kbd_dev)->console_phone); 1008 864 1009 if ((*kbd_dev)->hid_dev != NULL) {1010 usbhid_dev_free(&(*kbd_dev)->hid_dev);1011 assert((*kbd_dev)->hid_dev == NULL);1012 }865 // if ((*kbd_dev)->hid_dev != NULL) { 866 // usbhid_dev_free(&(*kbd_dev)->hid_dev); 867 // assert((*kbd_dev)->hid_dev == NULL); 868 // } 1013 869 1014 870 if ((*kbd_dev)->repeat_mtx != NULL) { … … 1017 873 free((*kbd_dev)->repeat_mtx); 1018 874 } 875 876 // destroy the parser 877 if ((*kbd_dev)->parser != NULL) { 878 usb_hid_free_report_parser((*kbd_dev)->parser); 879 } 880 881 /* TODO: what about the USB device structure?? */ 1019 882 1020 883 free(*kbd_dev); -
uspace/drv/usbkbd/kbddev.h
r889e8e3 r291b8bc 34 34 */ 35 35 36 #ifndef USB HID_KBDDEV_H_37 #define USB HID_KBDDEV_H_36 #ifndef USB_KBDDEV_H_ 37 #define USB_KBDDEV_H_ 38 38 39 39 #include <stdint.h> … … 45 45 #include <ddf/driver.h> 46 46 #include <usb/pipes.h> 47 #include <usb/devdrv.h> 47 48 48 #include " hiddev.h"49 #include "kbdrepeat.h" 49 50 50 51 /*----------------------------------------------------------------------------*/ 51 /**52 * Structure for keeping information needed for auto-repeat of keys.53 */54 typedef struct {55 /** Last pressed key. */56 unsigned int key_new;57 /** Key to be repeated. */58 unsigned int key_repeated;59 /** Delay before first repeat in microseconds. */60 unsigned int delay_before;61 /** Delay between repeats in microseconds. */62 unsigned int delay_between;63 } usbhid_kbd_repeat_t;64 65 52 /** 66 53 * USB/HID keyboard device type. … … 75 62 * being device-specific. 76 63 */ 77 typedef struct { 78 /** Structure holding generic USB/HID device information. */ 79 usbhid_dev_t *hid_dev; 64 typedef struct usb_kbd_t { 65 /** Structure holding generic USB device information. */ 66 //usbhid_dev_t *hid_dev; 67 usb_device_t *usb_dev; 80 68 81 69 /** Currently pressed keys (not translated to key codes). */ … … 96 84 97 85 /** Information for auto-repeat of keys. */ 98 usb hid_kbd_repeat_t repeat;86 usb_kbd_repeat_t repeat; 99 87 100 88 /** Mutex for accessing the information about auto-repeat. */ 101 89 fibril_mutex_t *repeat_mtx; 90 91 /** Report descriptor. */ 92 uint8_t *report_desc; 93 94 /** Report descriptor size. */ 95 size_t report_desc_size; 96 97 /** HID Report parser. */ 98 usb_hid_report_parser_t *parser; 102 99 103 100 /** State of the structure (for checking before use). … … 108 105 */ 109 106 int initialized; 110 } usb hid_kbd_t;107 } usb_kbd_t; 111 108 112 109 /*----------------------------------------------------------------------------*/ 113 110 114 int usbhid_kbd_try_add_device(ddf_dev_t *dev); 111 enum { 112 USB_KBD_POLL_EP_NO = 0, 113 USB_KBD_POLL_EP_COUNT = 1 114 }; 115 115 116 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);116 usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1]; 117 117 118 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);118 ddf_dev_ops_t keyboard_ops; 119 119 120 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key); 120 /*----------------------------------------------------------------------------*/ 121 121 122 #endif /* USBHID_KBDDEV_H_ */ 122 usb_kbd_t *usb_kbd_new(void); 123 124 int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev); 125 126 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 127 size_t buffer_size, void *arg); 128 129 void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason, 130 void *arg); 131 132 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); 133 134 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev); 135 136 void usb_kbd_free(usb_kbd_t **kbd_dev); 137 138 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key); 139 140 #endif /* USB_KBDDEV_H_ */ 123 141 124 142 /** -
uspace/drv/usbkbd/kbdrepeat.c
r889e8e3 r291b8bc 62 62 * 63 63 * If the currently repeated key is not pressed any more ( 64 * usb hid_kbd_repeat_stop() was called), it stops repeating it and starts64 * usb_kbd_repeat_stop() was called), it stops repeating it and starts 65 65 * checking again. 66 66 * … … 70 70 * @param kbd Keyboard device structure. 71 71 */ 72 static void usb hid_kbd_repeat_loop(usbhid_kbd_t *kbd)72 static void usb_kbd_repeat_loop(usb_kbd_t *kbd) 73 73 { 74 74 unsigned int delay = 0; … … 78 78 while (true) { 79 79 // check if the kbd structure is usable 80 if (!usbhid_kbd_is_usable(kbd)) { 81 usbhid_kbd_free(&kbd); 82 assert(kbd == NULL); 80 if (!usb_kbd_is_initialized(kbd)) { 81 if (usb_kbd_is_ready_to_destroy(kbd)) { 82 usb_kbd_free(&kbd); 83 assert(kbd == NULL); 84 } 83 85 return; 84 86 } … … 90 92 usb_log_debug2("Repeating key: %u.\n", 91 93 kbd->repeat.key_repeated); 92 usb hid_kbd_push_ev(kbd, KEY_PRESS,94 usb_kbd_push_ev(kbd, KEY_PRESS, 93 95 kbd->repeat.key_repeated); 94 96 delay = kbd->repeat.delay_between; … … 125 127 * @retval EINVAL if no argument is supplied. 126 128 */ 127 int usb hid_kbd_repeat_fibril(void *arg)129 int usb_kbd_repeat_fibril(void *arg) 128 130 { 129 131 usb_log_debug("Autorepeat fibril spawned.\n"); … … 134 136 } 135 137 136 usb hid_kbd_t *kbd = (usbhid_kbd_t *)arg;138 usb_kbd_t *kbd = (usb_kbd_t *)arg; 137 139 138 usb hid_kbd_repeat_loop(kbd);140 usb_kbd_repeat_loop(kbd); 139 141 140 142 return EOK; … … 152 154 * @param key Key to start repeating. 153 155 */ 154 void usb hid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key)156 void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key) 155 157 { 156 158 fibril_mutex_lock(kbd->repeat_mtx); … … 170 172 * @param key Key to stop repeating. 171 173 */ 172 void usb hid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key)174 void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key) 173 175 { 174 176 fibril_mutex_lock(kbd->repeat_mtx); -
uspace/drv/usbkbd/kbdrepeat.h
r889e8e3 r291b8bc 1 1 /* 2 * Copyright (c) 2010 Vojtech Horky3 2 * Copyright (c) 2011 Lubos Slovak 4 3 * All rights reserved. … … 31 30 * @{ 32 31 */ 33 /** 34 * @file 35 * Main routines of USB HID driver. 32 /** @file 33 * USB HID keyboard autorepeat facilities 36 34 */ 37 35 38 #include <ddf/driver.h> 39 #include <usb/debug.h> 40 #include <errno.h> 41 #include <str_error.h> 36 #ifndef USB_KBDREPEAT_H_ 37 #define USB_KBDREPEAT_H_ 42 38 43 #include "kbddev.h" 39 struct usb_kbd_t; 40 41 /*----------------------------------------------------------------------------*/ 42 /** 43 * Structure for keeping information needed for auto-repeat of keys. 44 */ 45 typedef struct { 46 /** Last pressed key. */ 47 unsigned int key_new; 48 /** Key to be repeated. */ 49 unsigned int key_repeated; 50 /** Delay before first repeat in microseconds. */ 51 unsigned int delay_before; 52 /** Delay between repeats in microseconds. */ 53 unsigned int delay_between; 54 } usb_kbd_repeat_t; 44 55 45 56 /*----------------------------------------------------------------------------*/ 46 57 47 #define NAME "usbhid" 58 int usb_kbd_repeat_fibril(void *arg); 48 59 49 /*----------------------------------------------------------------------------*/ 50 /** 51 * Callback for passing a new device to the driver. 52 * 53 * @note Currently, only boot-protocol keyboards are supported by this driver. 54 * 55 * @param dev Structure representing the new device. 56 * 57 * @retval EOK if successful. 58 * @retval EREFUSED if the device is not supported. 59 */ 60 static int usbhid_add_device(ddf_dev_t *dev) 61 { 62 usb_log_debug("usbhid_add_device()\n"); 63 64 int rc = usbhid_kbd_try_add_device(dev); 65 66 if (rc != EOK) { 67 usb_log_warning("Device is not a supported keyboard.\n"); 68 usb_log_error("Failed to add HID device: %s.\n", 69 str_error(rc)); 70 return rc; 71 } 72 73 usb_log_info("Keyboard `%s' ready to use.\n", dev->name); 60 void usb_kbd_repeat_start(struct usb_kbd_t *kbd, unsigned int key); 74 61 75 return EOK; 76 } 62 void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key); 77 63 78 /*----------------------------------------------------------------------------*/ 79 80 static driver_ops_t kbd_driver_ops = { 81 .add_device = usbhid_add_device, 82 }; 83 84 /*----------------------------------------------------------------------------*/ 85 86 static driver_t kbd_driver = { 87 .name = NAME, 88 .driver_ops = &kbd_driver_ops 89 }; 90 91 /*----------------------------------------------------------------------------*/ 92 93 int main(int argc, char *argv[]) 94 { 95 printf(NAME ": HelenOS USB HID driver.\n"); 96 97 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 98 99 return ddf_driver_main(&kbd_driver); 100 } 64 #endif /* USB_KBDREPEAT_H_ */ 101 65 102 66 /** -
uspace/drv/usbkbd/layout.h
r889e8e3 r291b8bc 36 36 */ 37 37 38 #ifndef USB HID_LAYOUT_H_39 #define USB HID_LAYOUT_H_38 #ifndef USB_KBD_LAYOUT_H_ 39 #define USB_KBD_LAYOUT_H_ 40 40 41 41 #include <sys/types.h> -
uspace/lib/c/generic/malloc.c
r889e8e3 r291b8bc 240 240 size_t asize = ALIGN_UP(size, PAGE_SIZE); 241 241 242 astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ );242 astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE); 243 243 if (astart == (void *) -1) 244 244 return false; -
uspace/lib/usb/Makefile
r889e8e3 r291b8bc 50 50 src/usb.c \ 51 51 src/usbdevice.c \ 52 src/hidreq.c \ 53 src/hidreport.c \ 52 54 src/host/device_keeper.c \ 53 55 src/host/batch.c -
uspace/lib/usb/include/usb/classes/hidparser.h
r889e8e3 r291b8bc 70 70 * Description of path of usage pages and usages in report descriptor 71 71 */ 72 #define USB_HID_PATH_COMPARE_STRICT 0 73 #define USB_HID_PATH_COMPARE_END 1 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 72 76 typedef struct { 73 77 int32_t usage_page; 78 int32_t usage; 79 80 link_t link; 81 } usb_hid_report_usage_path_t; 82 83 typedef struct { 84 int depth; 85 link_t link; 74 86 } usb_hid_report_path_t; 75 87 … … 79 91 typedef struct { 80 92 int32_t id; 81 int32_t usage_page;82 int32_t usage;83 93 int32_t usage_minimum; 84 94 int32_t usage_maximum; … … 107 117 uint8_t item_flags; 108 118 119 usb_hid_report_path_t *usage_path; 109 120 link_t link; 110 121 } usb_hid_report_item_t; … … 117 128 link_t feature; 118 129 } usb_hid_report_parser_t; 119 120 130 121 131 … … 194 204 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 195 205 const uint8_t *data, size_t size, 206 usb_hid_report_path_t *path, int flags, 196 207 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 197 208 198 209 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 199 const usb_hid_report_path_t *path);210 usb_hid_report_path_t *path, int flags); 200 211 201 212 … … 204 215 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 205 216 217 /* usage path functions */ 218 usb_hid_report_path_t *usb_hid_report_path(void); 219 void usb_hid_report_path_free(usb_hid_report_path_t *path); 220 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage); 221 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 222 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 223 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data); 224 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags); 225 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path); 226 227 228 // output 229 // - funkce co vrati cesty poli v output reportu 230 // - funkce co pro danou cestu nastavi data 231 // - finalize 232 206 233 #endif 207 234 /** -
uspace/lib/usb/include/usb/classes/hidreq.h
r889e8e3 r291b8bc 27 27 */ 28 28 29 /** @addtogroup drvusbhid29 /** @addtogroup libusb 30 30 * @{ 31 31 */ … … 34 34 */ 35 35 36 #ifndef USB HID_HIDREQ_H_37 #define USB HID_HIDREQ_H_36 #ifndef USB_KBD_HIDREQ_H_ 37 #define USB_KBD_HIDREQ_H_ 38 38 39 39 #include <stdint.h> 40 40 41 41 #include <usb/classes/hid.h> 42 43 #include "hiddev.h" 42 #include <usb/pipes.h> 44 43 45 44 /*----------------------------------------------------------------------------*/ 46 45 47 int usbhid_req_set_report(usb hid_dev_t *hid_dev,46 int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no, 48 47 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size); 49 48 50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol); 49 int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 50 usb_hid_protocol_t protocol); 51 51 52 int usbhid_req_set_idle(usb hid_dev_t *hid_dev, uint8_t duration);52 int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration); 53 53 54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 55 uint8_t *buffer, size_t buf_size, size_t *actual_size); 54 int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 55 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 56 size_t *actual_size); 56 57 57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol); 58 int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 59 usb_hid_protocol_t *protocol); 58 60 59 int usbhid_req_get_idle(usb hid_dev_t *hid_dev, uint8_t *duration);61 int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration); 60 62 61 63 /*----------------------------------------------------------------------------*/ 62 64 63 #endif /* USB HID_HIDREQ_H_ */65 #endif /* USB_KBD_HIDREQ_H_ */ 64 66 65 67 /** -
uspace/lib/usb/include/usb/host/device_keeper.h
r889e8e3 r291b8bc 51 51 usb_speed_t speed; 52 52 bool occupied; 53 bool control_used; 53 54 uint16_t toggle_status[2]; 54 55 devman_handle_t handle; … … 61 62 struct usb_device_info devices[USB_ADDRESS_COUNT]; 62 63 fibril_mutex_t guard; 63 fibril_condvar_t default_address_occupied;64 fibril_condvar_t change; 64 65 usb_address_t last_address; 65 66 } usb_device_keeper_t; … … 97 98 usb_address_t address); 98 99 100 void usb_device_keeper_use_control(usb_device_keeper_t *instance, 101 usb_address_t address); 102 103 void usb_device_keeper_release_control(usb_device_keeper_t *instance, 104 usb_address_t address); 105 99 106 #endif 100 107 /** -
uspace/lib/usb/src/hidparser.c
r889e8e3 r291b8bc 47 47 48 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 usb_hid_report_item_t *report_item );49 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 50 50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 51 usb_hid_report_item_t *report_item );51 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 52 52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 53 usb_hid_report_item_t *report_item );53 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 54 54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 55 usb_hid_report_item_t *report_item );55 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 56 56 57 57 void usb_hid_descriptor_print_list(link_t *head); … … 63 63 int usb_pow(int a, int b); 64 64 65 65 66 int usb_pow(int a, int b) 66 67 { … … 84 85 { 85 86 if(parser == NULL) { 86 return -1;87 return EINVAL; 87 88 } 88 89 … … 110 111 int ret; 111 112 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 113 usb_hid_report_item_t *new_report_item; 114 usb_hid_report_path_t *usage_path; 115 usb_hid_report_path_t *tmp_usage_path; 113 116 114 117 size_t offset_input=0; … … 117 120 118 121 122 /* parser structure initialization*/ 123 if(usb_hid_parser_init(parser) != EOK) { 124 return EINVAL; 125 } 126 127 128 /*report item initialization*/ 119 129 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 130 return ENOMEM; 121 131 } 122 132 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 133 list_initialize(&(report_item->link)); 134 135 /* usage path context initialization */ 136 if(!(usage_path=usb_hid_report_path())){ 137 return ENOMEM; 138 } 139 126 140 while(i<size){ 127 141 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 142 129 143 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE144 return EINVAL; // TODO ERROR CODE 131 145 } 132 146 … … 141 155 142 156 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item);157 item_size,report_item, usage_path); 144 158 usb_log_debug2("ret: %u\n", ret); 145 159 switch(ret){ 146 160 case USB_HID_NEW_REPORT_ITEM: 147 161 // store report item to report and create the new one 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 162 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 163 164 // store current usage path 165 report_item->usage_path = usage_path; 166 167 // new current usage path 168 tmp_usage_path = usb_hid_report_path(); 169 170 // copy old path to the new one 171 usb_hid_report_path_clone(tmp_usage_path, usage_path); 172 173 // swap 174 usage_path = tmp_usage_path; 175 tmp_usage_path = NULL; 176 149 177 150 178 switch(tag) { … … 184 212 link_initialize(&(new_report_item->link)); 185 213 report_item = new_report_item; 186 214 187 215 break; 188 216 case USB_HID_REPORT_TAG_PUSH: … … 284 312 */ 285 313 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 286 usb_hid_report_item_t *report_item )314 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 287 315 { 288 316 int ret; … … 291 319 case USB_HID_TAG_CLASS_MAIN: 292 320 293 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item )) == EOK) {321 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 294 322 return USB_HID_NEW_REPORT_ITEM; 295 323 } … … 301 329 302 330 case USB_HID_TAG_CLASS_GLOBAL: 303 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item );331 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 304 332 break; 305 333 306 334 case USB_HID_TAG_CLASS_LOCAL: 307 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item );335 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 308 336 break; 309 337 default: … … 323 351 324 352 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 325 usb_hid_report_item_t *report_item )326 { 353 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 354 { 327 355 switch(tag) 328 356 { … … 335 363 336 364 case USB_HID_REPORT_TAG_COLLECTION: 337 // TODO 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 338 367 return USB_HID_NO_ACTION; 339 368 break; 340 369 341 370 case USB_HID_REPORT_TAG_END_COLLECTION: 342 /* should be ignored */ 371 // TODO 372 // znici posledni uroven ve vsech usage paths 373 // otazka jestli nema nicit dve, respektive novou posledni vynulovat? 374 usb_hid_report_remove_last_item(usage_path); 343 375 return USB_HID_NO_ACTION; 344 376 break; … … 361 393 362 394 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 363 usb_hid_report_item_t *report_item )395 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 364 396 { 365 397 // TODO take care about the bit length of data … … 367 399 { 368 400 case USB_HID_REPORT_TAG_USAGE_PAGE: 369 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 401 // zmeni to jenom v poslednim poli aktualni usage path 402 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 403 usb_hid_report_tag_data_int32(data,item_size)); 370 404 break; 371 405 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 418 452 */ 419 453 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 420 usb_hid_report_item_t *report_item )454 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 421 455 { 422 456 switch(tag) 423 457 { 424 458 case USB_HID_REPORT_TAG_USAGE: 425 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 459 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 460 usb_hid_report_tag_data_int32(data,item_size)); 426 461 break; 427 462 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 491 526 { 492 527 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item; 529 link_t *path; 493 530 link_t *item; 494 531 … … 507 544 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 508 545 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 509 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 510 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 546 usb_log_debug("\tUSAGE PATH:\n"); 547 548 path = report_item->usage_path->link.next; 549 while(path != &report_item->usage_path->link) { 550 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 551 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 552 path = path->next; 553 } 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 511 558 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 512 559 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 530 577 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 531 578 { 579 if(parser == NULL) { 580 return; 581 } 582 532 583 usb_log_debug("INPUT:\n"); 533 584 usb_hid_descriptor_print_list(&parser->input); … … 561 612 562 613 report_item = list_get_instance(next, usb_hid_report_item_t, link); 614 615 while(!list_empty(&report_item->usage_path->link)) { 616 usb_hid_report_remove_last_item(report_item->usage_path); 617 } 618 619 563 620 next = next->next; 564 621 … … 600 657 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 601 658 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags, 602 660 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 603 661 { … … 615 673 size_t j=0; 616 674 675 if(parser == NULL) { 676 return EINVAL; 677 } 678 679 617 680 // get the size of result keycodes array 618 usb_hid_report_path_t path; 619 path.usage_page = BAD_HACK_USAGE_PAGE; 620 key_count = usb_hid_report_input_length(parser, &path); 681 key_count = usb_hid_report_input_length(parser, path, flags); 621 682 622 683 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 629 690 630 691 item = list_get_instance(list_item, usb_hid_report_item_t, link); 631 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 632 ( item->usage_page == path.usage_page)) {692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 633 694 for(j=0; j<(size_t)(item->count); j++) { 634 695 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 640 701 // bitmapa 641 702 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 642 keys[i++] = j+ item->usage_minimum;703 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 643 704 } 644 705 else { … … 736 797 737 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 738 const usb_hid_report_path_t *path)739 { 799 usb_hid_report_path_t *path, int flags) 800 { 740 801 int ret = 0; 741 802 link_t *item; 742 803 usb_hid_report_item_t *report_item; 743 804 805 if(parser == NULL) { 806 return EINVAL; 807 } 808 744 809 item = (&parser->input)->next; 745 810 while(&parser->input != item) { 746 811 report_item = list_get_instance(item, usb_hid_report_item_t, link); 747 812 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 748 ( report_item->usage_page == path->usage_page)) {813 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 749 814 ret += report_item->count; 750 815 } … … 757 822 758 823 824 /** 825 * 826 */ 827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 828 int32_t usage_page, int32_t usage) 829 { 830 usb_hid_report_usage_path_t *item; 831 832 if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) { 833 return ENOMEM; 834 } 835 list_initialize(&item->link); 836 837 item->usage = usage; 838 item->usage_page = usage_page; 839 840 list_append (&usage_path->link, &item->link); 841 usage_path->depth++; 842 return EOK; 843 } 844 845 /** 846 * 847 */ 848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) 849 { 850 usb_hid_report_usage_path_t *item; 851 852 if(!list_empty(&usage_path->link)){ 853 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 854 list_remove(usage_path->link.prev); 855 usage_path->depth--; 856 free(item); 857 } 858 } 859 860 /** 861 * 862 */ 863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) 864 { 865 usb_hid_report_usage_path_t *item; 866 867 if(!list_empty(&usage_path->link)){ 868 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 869 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 870 } 871 } 872 873 /** 874 * 875 */ 876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) 877 { 878 usb_hid_report_usage_path_t *item; 879 880 if(!list_empty(&usage_path->link)){ 881 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 882 883 switch(tag) { 884 case USB_HID_TAG_CLASS_GLOBAL: 885 item->usage_page = data; 886 break; 887 case USB_HID_TAG_CLASS_LOCAL: 888 item->usage = data; 889 break; 890 } 891 } 892 893 } 894 895 /** 896 * 897 */ 898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 899 usb_hid_report_path_t *path, 900 int flags) 901 { 902 usb_hid_report_usage_path_t *report_item; 903 usb_hid_report_usage_path_t *path_item; 904 905 link_t *report_link; 906 link_t *path_link; 907 908 int only_page; 909 910 if(path->depth == 0){ 911 return EOK; 912 } 913 914 915 if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){ 916 flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY; 917 } 918 919 switch(flags){ 920 /* path must be completly identical */ 921 case USB_HID_PATH_COMPARE_STRICT: 922 if(report_path->depth != path->depth){ 923 return 1; 924 } 925 926 report_link = report_path->link.next; 927 path_link = path->link.next; 928 929 while((report_link != &report_path->link) && (path_link != &path->link)) { 930 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 931 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 932 933 if((report_item->usage_page != path_item->usage_page) || 934 ((only_page == 0) && (report_item->usage != path_item->usage))) { 935 return 1; 936 } else { 937 report_link = report_link->next; 938 path_link = path_link->next; 939 } 940 941 } 942 943 if((report_link == &report_path->link) && (path_link == &path->link)) { 944 return EOK; 945 } 946 else { 947 return 1; 948 } 949 break; 950 951 /* given path must be the end of the report one*/ 952 case USB_HID_PATH_COMPARE_END: 953 report_link = report_path->link.prev; 954 path_link = path->link.prev; 955 956 if(list_empty(&path->link)){ 957 return EOK; 958 } 959 960 while((report_link != &report_path->link) && (path_link != &path->link)) { 961 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 962 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 963 964 if((report_item->usage_page != path_item->usage_page) || 965 ((only_page == 0) && (report_item->usage != path_item->usage))) { 966 return 1; 967 } else { 968 report_link = report_link->prev; 969 path_link = path_link->prev; 970 } 971 972 } 973 974 if(path_link == &path->link) { 975 return EOK; 976 } 977 else { 978 return 1; 979 } 980 981 break; 982 983 default: 984 return EINVAL; 985 } 986 987 988 989 990 } 991 992 /** 993 * 994 */ 995 usb_hid_report_path_t *usb_hid_report_path(void) 996 { 997 usb_hid_report_path_t *path; 998 path = malloc(sizeof(usb_hid_report_path_t)); 999 if(!path){ 1000 return NULL; 1001 } 1002 else { 1003 path->depth = 0; 1004 list_initialize(&path->link); 1005 return path; 1006 } 1007 } 1008 1009 /** 1010 * 1011 */ 1012 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1013 { 1014 while(!list_empty(&path->link)){ 1015 usb_hid_report_remove_last_item(path); 1016 } 1017 } 1018 1019 1020 /** 1021 * 1022 */ 1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path) 1024 { 1025 usb_hid_report_usage_path_t *path_item; 1026 link_t *path_link; 1027 1028 1029 if(list_empty(&usage_path->link)){ 1030 return EOK; 1031 } 1032 1033 path_link = usage_path->link.next; 1034 while(path_link != &usage_path->link) { 1035 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1036 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1037 1038 path_link = path_link->next; 1039 } 1040 1041 return EOK; 1042 } 1043 759 1044 760 1045 /** -
uspace/lib/usb/src/hidreq.c
r889e8e3 r291b8bc 41 41 #include <usb/debug.h> 42 42 #include <usb/request.h> 43 44 #include "hidreq.h" 45 #include "hiddev.h"43 #include <usb/pipes.h> 44 45 #include <usb/classes/hidreq.h> 46 46 47 47 /*----------------------------------------------------------------------------*/ … … 60 60 * usb_control_request_set(). 61 61 */ 62 int usbhid_req_set_report(usb hid_dev_t *hid_dev,62 int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no, 63 63 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size) 64 64 { 65 if (hid_dev == NULL) { 66 usb_log_error("usbhid_req_set_report(): no HID device structure" 67 " given.\n"); 68 return EINVAL; 69 } 70 71 /* 72 * No need for checking other parameters, as they are checked in 73 * the called function (usb_control_request_set()). 74 */ 75 76 int rc, sess_rc; 77 78 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 65 if (ctrl_pipe == NULL) { 66 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 67 return EINVAL; 68 } 69 70 if (iface_no < 0) { 71 usb_log_warning("usbhid_req_set_report(): no interface given." 72 "\n"); 73 return EINVAL; 74 } 75 76 /* 77 * No need for checking other parameters, as they are checked in 78 * the called function (usb_control_request_set()). 79 */ 80 81 int rc, sess_rc; 82 83 sess_rc = usb_pipe_start_session(ctrl_pipe); 79 84 if (sess_rc != EOK) { 80 85 usb_log_warning("Failed to start a session: %s.\n", … … 88 93 usb_log_debug("Sending Set_Report request to the device.\n"); 89 94 90 rc = usb_control_request_set( &hid_dev->ctrl_pipe,91 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 92 USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);93 94 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);95 rc = usb_control_request_set(ctrl_pipe, 96 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 97 USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size); 98 99 sess_rc = usb_pipe_end_session(ctrl_pipe); 95 100 96 101 if (rc != EOK) { … … 122 127 * usb_control_request_set(). 123 128 */ 124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol) 125 { 126 if (hid_dev == NULL) { 127 usb_log_error("usbhid_req_set_protocol(): no HID device " 128 "structure given.\n"); 129 return EINVAL; 130 } 131 132 /* 133 * No need for checking other parameters, as they are checked in 134 * the called function (usb_control_request_set()). 135 */ 136 137 int rc, sess_rc; 138 139 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 129 int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 130 usb_hid_protocol_t protocol) 131 { 132 if (ctrl_pipe == NULL) { 133 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 134 return EINVAL; 135 } 136 137 if (iface_no < 0) { 138 usb_log_warning("usbhid_req_set_report(): no interface given." 139 "\n"); 140 return EINVAL; 141 } 142 143 /* 144 * No need for checking other parameters, as they are checked in 145 * the called function (usb_control_request_set()). 146 */ 147 148 int rc, sess_rc; 149 150 sess_rc = usb_pipe_start_session(ctrl_pipe); 140 151 if (sess_rc != EOK) { 141 152 usb_log_warning("Failed to start a session: %s.\n", … … 145 156 146 157 usb_log_debug("Sending Set_Protocol request to the device (" 147 "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);148 149 rc = usb_control_request_set( &hid_dev->ctrl_pipe,150 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 151 USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);152 153 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);158 "protocol: %d, iface: %d).\n", protocol, iface_no); 159 160 rc = usb_control_request_set(ctrl_pipe, 161 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 162 USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0); 163 164 sess_rc = usb_pipe_end_session(ctrl_pipe); 154 165 155 166 if (rc != EOK) { … … 182 193 * usb_control_request_set(). 183 194 */ 184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration) 185 { 186 if (hid_dev == NULL) { 187 usb_log_error("usbhid_req_set_idle(): no HID device " 188 "structure given.\n"); 189 return EINVAL; 190 } 191 192 /* 193 * No need for checking other parameters, as they are checked in 194 * the called function (usb_control_request_set()). 195 */ 196 197 int rc, sess_rc; 198 199 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 195 int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration) 196 { 197 if (ctrl_pipe == NULL) { 198 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 199 return EINVAL; 200 } 201 202 if (iface_no < 0) { 203 usb_log_warning("usbhid_req_set_report(): no interface given." 204 "\n"); 205 return EINVAL; 206 } 207 208 /* 209 * No need for checking other parameters, as they are checked in 210 * the called function (usb_control_request_set()). 211 */ 212 213 int rc, sess_rc; 214 215 sess_rc = usb_pipe_start_session(ctrl_pipe); 200 216 if (sess_rc != EOK) { 201 217 usb_log_warning("Failed to start a session: %s.\n", … … 205 221 206 222 usb_log_debug("Sending Set_Idle request to the device (" 207 "duration: %u, iface: %d).\n", duration, hid_dev->iface);223 "duration: %u, iface: %d).\n", duration, iface_no); 208 224 209 225 uint16_t value = duration << 8; 210 226 211 rc = usb_control_request_set( &hid_dev->ctrl_pipe,212 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 213 USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);214 215 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);227 rc = usb_control_request_set(ctrl_pipe, 228 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 229 USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0); 230 231 sess_rc = usb_pipe_end_session(ctrl_pipe); 216 232 217 233 if (rc != EOK) { … … 247 263 * usb_control_request_set(). 248 264 */ 249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 250 uint8_t *buffer, size_t buf_size, size_t *actual_size) 251 { 252 if (hid_dev == NULL) { 253 usb_log_error("usbhid_req_set_report(): no HID device structure" 254 " given.\n"); 255 return EINVAL; 256 } 257 258 /* 259 * No need for checking other parameters, as they are checked in 260 * the called function (usb_control_request_set()). 261 */ 262 263 int rc, sess_rc; 264 265 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 265 int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 266 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 267 size_t *actual_size) 268 { 269 if (ctrl_pipe == NULL) { 270 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 271 return EINVAL; 272 } 273 274 if (iface_no < 0) { 275 usb_log_warning("usbhid_req_set_report(): no interface given." 276 "\n"); 277 return EINVAL; 278 } 279 280 /* 281 * No need for checking other parameters, as they are checked in 282 * the called function (usb_control_request_set()). 283 */ 284 285 int rc, sess_rc; 286 287 sess_rc = usb_pipe_start_session(ctrl_pipe); 266 288 if (sess_rc != EOK) { 267 289 usb_log_warning("Failed to start a session: %s.\n", … … 275 297 usb_log_debug("Sending Get_Report request to the device.\n"); 276 298 277 rc = usb_control_request_get( &hid_dev->ctrl_pipe,278 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 279 USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,299 rc = usb_control_request_get(ctrl_pipe, 300 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 301 USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size, 280 302 actual_size); 281 303 282 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);304 sess_rc = usb_pipe_end_session(ctrl_pipe); 283 305 284 306 if (rc != EOK) { … … 310 332 * usb_control_request_set(). 311 333 */ 312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol) 313 { 314 if (hid_dev == NULL) { 315 usb_log_error("usbhid_req_set_protocol(): no HID device " 316 "structure given.\n"); 317 return EINVAL; 318 } 319 320 /* 321 * No need for checking other parameters, as they are checked in 322 * the called function (usb_control_request_set()). 323 */ 324 325 int rc, sess_rc; 326 327 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 334 int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 335 usb_hid_protocol_t *protocol) 336 { 337 if (ctrl_pipe == NULL) { 338 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 339 return EINVAL; 340 } 341 342 if (iface_no < 0) { 343 usb_log_warning("usbhid_req_set_report(): no interface given." 344 "\n"); 345 return EINVAL; 346 } 347 348 /* 349 * No need for checking other parameters, as they are checked in 350 * the called function (usb_control_request_set()). 351 */ 352 353 int rc, sess_rc; 354 355 sess_rc = usb_pipe_start_session(ctrl_pipe); 328 356 if (sess_rc != EOK) { 329 357 usb_log_warning("Failed to start a session: %s.\n", … … 333 361 334 362 usb_log_debug("Sending Get_Protocol request to the device (" 335 "iface: %d).\n", hid_dev->iface);363 "iface: %d).\n", iface_no); 336 364 337 365 uint8_t buffer[1]; 338 366 size_t actual_size = 0; 339 367 340 rc = usb_control_request_get( &hid_dev->ctrl_pipe,341 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 342 USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);343 344 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);368 rc = usb_control_request_get(ctrl_pipe, 369 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 370 USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size); 371 372 sess_rc = usb_pipe_end_session(ctrl_pipe); 345 373 346 374 if (rc != EOK) { … … 381 409 * usb_control_request_set(). 382 410 */ 383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration) 384 { 385 if (hid_dev == NULL) { 386 usb_log_error("usbhid_req_set_idle(): no HID device " 387 "structure given.\n"); 388 return EINVAL; 389 } 390 391 /* 392 * No need for checking other parameters, as they are checked in 393 * the called function (usb_control_request_set()). 394 */ 395 396 int rc, sess_rc; 397 398 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 411 int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration) 412 { 413 if (ctrl_pipe == NULL) { 414 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 415 return EINVAL; 416 } 417 418 if (iface_no < 0) { 419 usb_log_warning("usbhid_req_set_report(): no interface given." 420 "\n"); 421 return EINVAL; 422 } 423 424 /* 425 * No need for checking other parameters, as they are checked in 426 * the called function (usb_control_request_set()). 427 */ 428 429 int rc, sess_rc; 430 431 sess_rc = usb_pipe_start_session(ctrl_pipe); 399 432 if (sess_rc != EOK) { 400 433 usb_log_warning("Failed to start a session: %s.\n", … … 404 437 405 438 usb_log_debug("Sending Get_Idle request to the device (" 406 "iface: %d).\n", hid_dev->iface);439 "iface: %d).\n", iface_no); 407 440 408 441 uint16_t value = 0; … … 410 443 size_t actual_size = 0; 411 444 412 rc = usb_control_request_get( &hid_dev->ctrl_pipe,413 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 414 USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,445 rc = usb_control_request_get(ctrl_pipe, 446 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 447 USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1, 415 448 &actual_size); 416 449 417 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);450 sess_rc = usb_pipe_end_session(ctrl_pipe); 418 451 419 452 if (rc != EOK) { -
uspace/lib/usb/src/host/device_keeper.c
r889e8e3 r291b8bc 49 49 assert(instance); 50 50 fibril_mutex_initialize(&instance->guard); 51 fibril_condvar_initialize(&instance-> default_address_occupied);51 fibril_condvar_initialize(&instance->change); 52 52 instance->last_address = 0; 53 53 unsigned i = 0; 54 54 for (; i < USB_ADDRESS_COUNT; ++i) { 55 55 instance->devices[i].occupied = false; 56 instance->devices[i].control_used = false; 56 57 instance->devices[i].handle = 0; 57 58 instance->devices[i].toggle_status[0] = 0; … … 71 72 fibril_mutex_lock(&instance->guard); 72 73 while (instance->devices[USB_ADDRESS_DEFAULT].occupied) { 73 fibril_condvar_wait(&instance->default_address_occupied, 74 &instance->guard); 74 fibril_condvar_wait(&instance->change, &instance->guard); 75 75 } 76 76 instance->devices[USB_ADDRESS_DEFAULT].occupied = true; … … 90 90 instance->devices[USB_ADDRESS_DEFAULT].occupied = false; 91 91 fibril_mutex_unlock(&instance->guard); 92 fibril_condvar_signal(&instance-> default_address_occupied);92 fibril_condvar_signal(&instance->change); 93 93 } 94 94 /*----------------------------------------------------------------------------*/ … … 309 309 return instance->devices[address].speed; 310 310 } 311 311 /*----------------------------------------------------------------------------*/ 312 void usb_device_keeper_use_control(usb_device_keeper_t *instance, 313 usb_address_t address) 314 { 315 assert(instance); 316 fibril_mutex_lock(&instance->guard); 317 while (instance->devices[address].control_used) { 318 fibril_condvar_wait(&instance->change, &instance->guard); 319 } 320 instance->devices[address].control_used = true; 321 fibril_mutex_unlock(&instance->guard); 322 } 323 /*----------------------------------------------------------------------------*/ 324 void usb_device_keeper_release_control(usb_device_keeper_t *instance, 325 usb_address_t address) 326 { 327 assert(instance); 328 fibril_mutex_lock(&instance->guard); 329 instance->devices[address].control_used = false; 330 fibril_mutex_unlock(&instance->guard); 331 fibril_condvar_signal(&instance->change); 332 } 312 333 /** 313 334 * @}
Note:
See TracChangeset
for help on using the changeset viewer.