Changeset 293de44 in mainline
- Timestamp:
- 2011-05-20T11:18:53Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c7c2443
- Parents:
- 160b75e (diff), 7941bd6 (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:
-
- 2 added
- 11 deleted
- 43 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r160b75e r293de44 53 53 ./uspace/app/klog/klog 54 54 ./uspace/app/lsusb/lsusb 55 ./uspace/app/mkbd/mkbd 55 56 ./uspace/app/mkfat/mkfat 56 57 ./uspace/app/netstart/netstart -
boot/Makefile.common
r160b75e r293de44 157 157 $(USPACE_PATH)/app/usbinfo/usbinfo \ 158 158 $(USPACE_PATH)/app/vuhid/vuh \ 159 $(USPACE_PATH)/app/mkbd/mkbd \ 159 160 $(USPACE_PATH)/app/websrv/websrv 160 161 -
boot/arch/amd64/Makefile.inc
r160b75e r293de44 49 49 usbflbk \ 50 50 usbhub \ 51 usbkbd \52 51 usbhid \ 53 52 usbmast \ -
kernel/generic/src/ipc/irq.c
r160b75e r293de44 370 370 if (AS != irq->driver_as) \ 371 371 as_switch(AS, irq->driver_as); \ 372 printf("Copying data from address: %p.\n", va); \373 372 memcpy_from_uspace(&target, va, (sizeof(target))); \ 374 373 if (dstarg) \ … … 381 380 if (AS != irq->driver_as) \ 382 381 as_switch(AS, irq->driver_as); \ 383 printf("Writing data to address: %p.\n", va); \384 382 memcpy_to_uspace(va, &val, sizeof(val)); \ 385 383 } while (0) … … 457 455 uint32_t val; 458 456 CMD_MEM_READ(val); 459 printf("mem READ value: %x.\n", val);460 457 break; 461 458 } -
uspace/Makefile
r160b75e r293de44 59 59 app/websrv \ 60 60 app/sysinfo \ 61 app/mkbd \ 61 62 srv/clip \ 62 63 srv/devmap \ … … 122 123 drv/uhci-rhd \ 123 124 drv/usbflbk \ 124 drv/usbkbd \125 125 drv/usbhid \ 126 126 drv/usbhub \ … … 144 144 drv/uhci-rhd \ 145 145 drv/usbflbk \ 146 drv/usbkbd \147 146 drv/usbhid \ 148 147 drv/usbhub \ -
uspace/app/mkbd/Makefile
r160b75e r293de44 1 1 # 2 # Copyright (c) 201 0-2011 Vojtech Horky2 # Copyright (c) 2011 Vojtech Horky 3 3 # All rights reserved. 4 4 # … … 28 28 29 29 USPACE_PREFIX = ../.. 30 BINARY = mkbd 30 31 31 32 LIBS = \ 32 $(LIBUSBHID_PREFIX)/libusbhid.a \33 33 $(LIBUSBDEV_PREFIX)/libusbdev.a \ 34 34 $(LIBUSB_PREFIX)/libusb.a \ 35 35 $(LIBDRV_PREFIX)/libdrv.a 36 EXTRA_CFLAGS += \ 37 -I. \ 36 EXTRA_CFLAGS = \ 38 37 -I$(LIBUSB_PREFIX)/include \ 39 38 -I$(LIBUSBDEV_PREFIX)/include \ 40 -I$(LIBUSBHID_PREFIX)/include \41 39 -I$(LIBDRV_PREFIX)/include 42 40 43 BINARY = usbkbd44 45 STOLEN_LAYOUT_SOURCES = \46 layout/us_qwerty.c \47 layout/us_dvorak.c \48 layout/cz.c49 50 41 SOURCES = \ 51 main.c \ 52 conv.c \ 53 kbddev.c \ 54 kbdrepeat.c \ 55 $(STOLEN_LAYOUT_SOURCES) 56 57 EXTRA_CLEAN = $(STOLEN_LAYOUT_SOURCES) 58 59 SRV_KBD = $(USPACE_PREFIX)/srv/hid/kbd 42 main.c 60 43 61 44 include $(USPACE_PREFIX)/Makefile.common 62 63 layout/%.c: $(SRV_KBD)/layout/%.c64 ln -sfn ../$< $@ -
uspace/drv/ohci/batch.c
r160b75e r293de44 44 44 #include "hw_struct/transfer_descriptor.h" 45 45 46 /** OHCI specific data required for USB transfer */ 46 47 typedef struct ohci_transfer_batch { 48 /** Endpoint descriptor of the target endpoint. */ 47 49 ed_t *ed; 50 /** List of TDs needed for the transfer */ 48 51 td_t **tds; 52 /** Number of TDs used by the transfer */ 49 53 size_t td_count; 54 /** Dummy TD to be left at the ED and used by the next transfer */ 50 55 size_t leave_td; 51 char *device_buffer; 56 /** Data buffer, must be accessible byb the OHCI hw. */ 57 void *device_buffer; 52 58 } ohci_transfer_batch_t; 53 59 /*----------------------------------------------------------------------------*/ 60 static void batch_control(usb_transfer_batch_t *instance, 61 usb_direction_t data_dir, usb_direction_t status_dir); 62 static void batch_data(usb_transfer_batch_t *instance); 63 /*----------------------------------------------------------------------------*/ 64 /** Safely destructs ohci_transfer_batch_t structure 65 * 66 * @param[in] ohci_batch Instance to destroy. 67 */ 54 68 static void ohci_transfer_batch_dispose(void *ohci_batch) 55 69 { … … 69 83 } 70 84 /*----------------------------------------------------------------------------*/ 71 static void batch_control(usb_transfer_batch_t *instance, 72 usb_direction_t data_dir, usb_direction_t status_dir); 73 static void batch_data(usb_transfer_batch_t *instance); 74 /*----------------------------------------------------------------------------*/ 85 /** Allocate memory initialize internal structures 86 * 87 * @param[in] fun DDF function to pass to callback. 88 * @param[in] ep Communication target 89 * @param[in] buffer Data source/destination. 90 * @param[in] buffer_size Size of the buffer. 91 * @param[in] setup_buffer Setup data source (if not NULL) 92 * @param[in] setup_size Size of setup_buffer (should be always 8) 93 * @param[in] func_in function to call on inbound transfer completion 94 * @param[in] func_out function to call on outbound transfer completion 95 * @param[in] arg additional parameter to func_in or func_out 96 * @return Valid pointer if all structures were successfully created, 97 * NULL otherwise. 98 * 99 * Allocates and initializes structures needed by the OHCI hw for the transfer. 100 */ 75 101 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 76 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 102 char *buffer, size_t buffer_size, 103 const char *setup_buffer, size_t setup_size, 77 104 usbhc_iface_transfer_in_callback_t func_in, 78 105 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 94 121 ohci_transfer_batch_dispose); 95 122 96 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);123 const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 97 124 assert(hcd_ep); 98 125 … … 103 130 data->td_count = 104 131 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER); 132 /* Control transfer need Setup and Status stage */ 105 133 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 106 134 data->td_count += 2; 107 135 } 108 136 109 /* we need one extra place for tdthat is currently assigned to hcd_ep*/137 /* We need an extra place for TD that is currently assigned to hcd_ep*/ 110 138 data->tds = calloc(sizeof(td_t*), data->td_count + 1); 111 139 CHECK_NULL_DISPOSE_RETURN(data->tds, 112 140 "Failed to allocate transfer descriptors.\n"); 113 141 142 /* Add TD left over by the previous transfer */ 114 143 data->tds[0] = hcd_ep->td; 115 144 data->leave_td = 0; … … 123 152 data->ed = hcd_ep->ed; 124 153 154 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries 155 * it is, however, not capable of handling buffer that occupies more 156 * than two pages (the first page is computed using start pointer, the 157 * other using the end pointer) */ 125 158 if (setup_size + buffer_size > 0) { 126 159 data->device_buffer = malloc32(setup_size + buffer_size); … … 135 168 } 136 169 /*----------------------------------------------------------------------------*/ 170 /** Check batch TDs' status. 171 * 172 * @param[in] instance Batch structure to use. 173 * @return False, if there is an active TD, true otherwise. 174 * 175 * Walk all TDs (usually there is just one). Stop with false if there is an 176 * active TD. Stop with true if an error is found. Return true if the walk 177 * completes with the last TD. 178 */ 137 179 bool batch_is_complete(usb_transfer_batch_t *instance) 138 180 { … … 140 182 ohci_transfer_batch_t *data = instance->private_data; 141 183 assert(data); 142 size_t tds = data->td_count;143 184 usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n", 144 instance, tds);185 instance, data->td_count); 145 186 usb_log_debug("ED: %x:%x:%x:%x.\n", 146 187 data->ed->status, data->ed->td_head, data->ed->td_tail, … … 148 189 size_t i = 0; 149 190 instance->transfered_size = instance->buffer_size; 150 for (; i < tds; ++i) {191 for (; i < data->td_count; ++i) { 151 192 assert(data->tds[i] != NULL); 152 193 usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i, … … 173 214 assert(hcd_ep); 174 215 hcd_ep->td = data->tds[i]; 175 if (i > 0) 176 instance->transfered_size -= td_remain_size(data->tds[i - 1]); 216 assert(i > 0); 217 for (--i;i < data->td_count; ++i) 218 instance->transfered_size -= td_remain_size(data->tds[i]); 177 219 178 220 /* Clear possible ED HALT */ 179 221 data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 180 uint32_t pa = addr_to_phys(hcd_ep->td);222 const uint32_t pa = addr_to_phys(hcd_ep->td); 181 223 assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK)); 182 224 assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK)); … … 185 227 } 186 228 /*----------------------------------------------------------------------------*/ 229 /** Starts execution of the TD list 230 * 231 * @param[in] instance Batch structure to use 232 */ 187 233 void batch_commit(usb_transfer_batch_t *instance) 188 234 { … … 193 239 } 194 240 /*----------------------------------------------------------------------------*/ 241 /** Prepares control write transfer. 242 * 243 * @param[in] instance Batch structure to use. 244 * 245 * Uses generic control transfer using direction OUT(data stage) and 246 * IN(status stage). 247 */ 195 248 void batch_control_write(usb_transfer_batch_t *instance) 196 249 { … … 203 256 } 204 257 /*----------------------------------------------------------------------------*/ 258 /** Prepares control read transfer. 259 * 260 * @param[in] instance Batch structure to use. 261 * 262 * Uses generic control transfer using direction IN(data stage) and 263 * OUT(status stage). 264 */ 205 265 void batch_control_read(usb_transfer_batch_t *instance) 206 266 { … … 211 271 } 212 272 /*----------------------------------------------------------------------------*/ 273 /** Prepare interrupt in transfer. 274 * 275 * @param[in] instance Batch structure to use. 276 * 277 * Data transfer. 278 */ 213 279 void batch_interrupt_in(usb_transfer_batch_t *instance) 214 280 { … … 219 285 } 220 286 /*----------------------------------------------------------------------------*/ 287 /** Prepare interrupt out transfer. 288 * 289 * @param[in] instance Batch structure to use. 290 * 291 * Data transfer. 292 */ 221 293 void batch_interrupt_out(usb_transfer_batch_t *instance) 222 294 { … … 229 301 } 230 302 /*----------------------------------------------------------------------------*/ 303 /** Prepare bulk in transfer. 304 * 305 * @param[in] instance Batch structure to use. 306 * 307 * Data transfer. 308 */ 231 309 void batch_bulk_in(usb_transfer_batch_t *instance) 232 310 { … … 237 315 } 238 316 /*----------------------------------------------------------------------------*/ 317 /** Prepare bulk out transfer. 318 * 319 * @param[in] instance Batch structure to use. 320 * 321 * Data transfer. 322 */ 239 323 void batch_bulk_out(usb_transfer_batch_t *instance) 240 324 { … … 247 331 } 248 332 /*----------------------------------------------------------------------------*/ 249 ed_t * batch_ed(usb_transfer_batch_t *instance) 250 { 251 assert(instance); 252 ohci_transfer_batch_t *data = instance->private_data; 253 assert(data); 254 return data->ed; 255 } 256 /*----------------------------------------------------------------------------*/ 333 /** Prepare generic control transfer 334 * 335 * @param[in] instance Batch structure to use. 336 * @param[in] data_dir Direction to use for data stage. 337 * @param[in] status_dir Direction to use for status stage. 338 * 339 * Setup stage with toggle 0 and direction BOTH(SETUP_PID) 340 * Data stage with alternating toggle and direction supplied by parameter. 341 * Status stage with toggle 1 and direction supplied by parameter. 342 */ 257 343 void batch_control(usb_transfer_batch_t *instance, 258 344 usb_direction_t data_dir, usb_direction_t status_dir) … … 303 389 } 304 390 /*----------------------------------------------------------------------------*/ 391 /** Prepare generic data transfer 392 * 393 * @param[in] instance Batch structure to use. 394 * 395 * Direction is supplied by the associated ep and toggle is maintained by the 396 * OHCI hw in ED. 397 */ 305 398 void batch_data(usb_transfer_batch_t *instance) 306 399 { … … 316 409 char *buffer = instance->data_buffer; 317 410 while (remain_size > 0) { 318 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?319 OHCI_TD_MAX_TRANSFER : remain_size;411 const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER 412 ? OHCI_TD_MAX_TRANSFER : remain_size; 320 413 321 414 td_init(data->tds[td_current], instance->ep->direction, -
uspace/drv/ohci/batch.h
r160b75e r293de44 41 41 #include <usb/host/batch.h> 42 42 43 #include "hw_struct/endpoint_descriptor.h"44 45 43 usb_transfer_batch_t * batch_get( 46 44 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 47 c har *setup_buffer, size_t setup_size,45 const char *setup_buffer, size_t setup_size, 48 46 usbhc_iface_transfer_in_callback_t func_in, 49 47 usbhc_iface_transfer_out_callback_t func_out, … … 65 63 66 64 void batch_bulk_out(usb_transfer_batch_t *instance); 67 68 ed_t * batch_ed(usb_transfer_batch_t *instance);69 65 #endif 70 66 /** -
uspace/drv/ohci/endpoint_list.c
r160b75e r293de44 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h> 36 37 37 38 #include "endpoint_list.h" … … 43 44 * @return Error code 44 45 * 45 * Allocates memory for internal qh_t structure.46 * Allocates memory for internal ed_t structure. 46 47 */ 47 48 int endpoint_list_init(endpoint_list_t *instance, const char *name) … … 68 69 * @param[in] instance List to lead. 69 70 * @param[in] next List to append. 70 * @return Error code71 71 * 72 * Does not check whether this replaces an existing list 72 * Does not check whether this replaces an existing list. 73 73 */ 74 74 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next) … … 79 79 } 80 80 /*----------------------------------------------------------------------------*/ 81 /** Submit transferendpoint to the list and queue.81 /** Add endpoint to the list and queue. 82 82 * 83 83 * @param[in] instance List to use. 84 * @param[in] endpoint Transfer endpoint to submit. 85 * @return Error code 84 * @param[in] endpoint Endpoint to add. 86 85 * 87 86 * The endpoint is added to the end of the list and queue. … … 99 98 /* Add to the hardware queue. */ 100 99 if (list_empty(&instance->endpoint_list)) { 101 /* There is nothing scheduled*/100 /* There are no active EDs */ 102 101 last_ed = instance->list_head; 103 102 } else { 104 /* There is something scheduled*/103 /* There are active EDs, get the last one */ 105 104 hcd_endpoint_t *last = list_get_instance( 106 105 instance->endpoint_list.prev, hcd_endpoint_t, link); 106 assert(last); 107 107 last_ed = last->ed; 108 108 } 109 /* keep link */109 /* Keep link */ 110 110 hcd_ep->ed->next = last_ed->next; 111 /* Make sure ED is written to the memory */ 112 write_barrier(); 113 114 /* Add ed to the hw queue */ 111 115 ed_append_ed(last_ed, hcd_ep->ed); 116 /* Make sure ED is updated */ 117 write_barrier(); 112 118 113 asm volatile ("": : :"memory"); 114 115 /* Add to the driver list */ 119 /* Add to the sw list */ 116 120 list_append(&hcd_ep->link, &instance->endpoint_list); 117 121 … … 129 133 } 130 134 /*----------------------------------------------------------------------------*/ 131 #if 0 132 /** Create list for finished endpoints. 135 /** Remove endpoint from the list and queue. 133 136 * 134 137 * @param[in] instance List to use. 135 * @param[in] done list to fill 136 */ 137 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done) 138 { 139 assert(instance); 140 assert(done); 141 142 fibril_mutex_lock(&instance->guard); 143 usb_log_debug2("Checking list %s for completed endpointes(%d).\n", 144 instance->name, list_count(&instance->endpoint_list)); 145 link_t *current = instance->endpoint_list.next; 146 while (current != &instance->endpoint_list) { 147 link_t *next = current->next; 148 hcd_endpoint_t *endpoint = 149 list_get_instance(current, hcd_endpoint_t, link); 150 151 if (endpoint_is_complete(endpoint)) { 152 /* Save for post-processing */ 153 endpoint_list_remove_endpoint(instance, endpoint); 154 list_append(current, done); 155 } 156 current = next; 157 } 158 fibril_mutex_unlock(&instance->guard); 159 } 160 /*----------------------------------------------------------------------------*/ 161 /** Walk the list and abort all endpointes. 162 * 163 * @param[in] instance List to use. 164 */ 165 void endpoint_list_abort_all(endpoint_list_t *instance) 166 { 167 fibril_mutex_lock(&instance->guard); 168 while (!list_empty(&instance->endpoint_list)) { 169 link_t *current = instance->endpoint_list.next; 170 hcd_endpoint_t *endpoint = 171 list_get_instance(current, hcd_endpoint_t, link); 172 endpoint_list_remove_endpoint(instance, endpoint); 173 hcd_endpoint_finish_error(endpoint, EIO); 174 } 175 fibril_mutex_unlock(&instance->guard); 176 } 177 #endif 178 /*----------------------------------------------------------------------------*/ 179 /** Remove a transfer endpoint from the list and queue. 180 * 181 * @param[in] instance List to use. 182 * @param[in] endpoint Transfer endpoint to remove. 183 * @return Error code 184 * 185 * Does not lock the transfer list, caller is responsible for that. 138 * @param[in] endpoint Endpoint to remove. 186 139 */ 187 140 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) … … 212 165 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed)); 213 166 prev_ed->next = hcd_ep->ed->next; 167 /* Make sure ED is updated */ 168 write_barrier(); 214 169 215 asm volatile ("": : :"memory");216 170 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 217 171 hcd_ep, qpos, instance->name, hcd_ep->ed->next); -
uspace/drv/ohci/endpoint_list.h
r160b75e r293de44 41 41 #include "utils/malloc32.h" 42 42 43 /** Structure maintains both OHCI queue and software list of active endpoints.*/ 43 44 typedef struct endpoint_list { 45 /** Guard against add/remove races */ 44 46 fibril_mutex_t guard; 47 /** OHCI hw structure at the beginning of the queue */ 45 48 ed_t *list_head; 49 /** Physical address of the first(dummy) ED */ 46 50 uint32_t list_head_pa; 51 /** Assigned name, provides nicer debug output */ 47 52 const char *name; 53 /** Sw list of all active EDs */ 48 54 link_t endpoint_list; 49 55 } endpoint_list_t; … … 53 59 * @param[in] instance Memory place to use. 54 60 * 55 * Frees memory for internal qh_t structure.61 * Frees memory of the internal ed_t structure. 56 62 */ 57 63 static inline void endpoint_list_fini(endpoint_list_t *instance) … … 62 68 63 69 int endpoint_list_init(endpoint_list_t *instance, const char *name); 64 65 70 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 66 67 71 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 68 69 72 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 70 #if 071 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done);72 73 void endpoint_list_abort_all(endpoint_list_t *instance);74 #endif75 73 #endif 76 74 /** -
uspace/drv/ohci/hc.c
r160b75e r293de44 51 51 static int hc_init_memory(hc_t *instance); 52 52 /*----------------------------------------------------------------------------*/ 53 /** Announce OHCI root hub to the DDF 54 * 55 * @param[in] instance OHCI driver intance 56 * @param[in] hub_fun DDF fuction representing OHCI root hub 57 * @return Error code 58 */ 53 59 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 54 60 { … … 56 62 assert(hub_fun); 57 63 58 int ret; 59 60 usb_address_t hub_address = 64 const usb_address_t hub_address = 61 65 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 62 66 if (hub_address <= 0) { 63 usb_log_error("Failed to get OHCI root hub address.\n"); 67 usb_log_error("Failed(%d) to get OHCI root hub address.\n", 68 hub_address); 64 69 return hub_address; 65 70 } … … 68 73 &instance->manager, hub_address, hub_fun->handle); 69 74 70 ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 75 #define CHECK_RET_RELEASE(ret, message...) \ 76 if (ret != EOK) { \ 77 usb_log_error(message); \ 78 hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \ 79 usb_device_keeper_release(&instance->manager, hub_address); \ 80 return ret; \ 81 } else (void)0 82 83 int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 71 84 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 72 if (ret != EOK) { 73 usb_log_error("Failed to add OHCI rh endpoint 0.\n"); 74 usb_device_keeper_release(&instance->manager, hub_address); 75 return ret; 76 } 85 CHECK_RET_RELEASE(ret, "Failed(%d) to add OHCI rh endpoint 0.\n", ret); 77 86 78 87 char *match_str = NULL; 79 88 /* DDF needs heap allocated string */ 80 89 ret = asprintf(&match_str, "usb&class=hub"); 81 if (ret < 0) { 82 usb_log_error( 83 "Failed(%d) to create root hub match-id string.\n", ret); 84 usb_device_keeper_release(&instance->manager, hub_address); 85 return ret; 86 } 90 ret = ret > 0 ? 0 : ret; 91 CHECK_RET_RELEASE(ret, "Failed(%d) to create match-id string.\n", ret); 87 92 88 93 ret = ddf_fun_add_match_id(hub_fun, match_str, 100); 89 if (ret != EOK) { 90 usb_log_error("Failed add root hub match-id.\n"); 91 } 94 CHECK_RET_RELEASE(ret, "Failed(%d) add root hub match-id.\n", ret); 95 92 96 ret = ddf_fun_bind(hub_fun); 93 return ret; 94 } 95 /*----------------------------------------------------------------------------*/ 97 CHECK_RET_RELEASE(ret, "Failed(%d) to bind root hub function.\n", ret); 98 99 return EOK; 100 #undef CHECK_RET_RELEASE 101 } 102 /*----------------------------------------------------------------------------*/ 103 /** Initialize OHCI hc driver structure 104 * 105 * @param[in] instance Memory place for the structure. 106 * @param[in] regs Address of the memory mapped I/O registers. 107 * @param[in] reg_size Size of the memory mapped area. 108 * @param[in] interrupts True if w interrupts should be used 109 * @return Error code 110 */ 96 111 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 97 112 { … … 121 136 #undef CHECK_RET_RETURN 122 137 123 124 // hc_init_hw(instance); 138 fibril_mutex_initialize(&instance->guard); 125 139 hc_gain_control(instance); 126 fibril_mutex_initialize(&instance->guard);127 140 128 141 rh_init(&instance->rh, instance->registers); … … 137 150 } 138 151 /*----------------------------------------------------------------------------*/ 152 /** Create end register endpoint structures 153 * 154 * @param[in] instance OHCI driver structure. 155 * @param[in] address USB address of the device. 156 * @param[in] endpoint USB endpoint number. 157 * @param[in] speed Communication speeed of the device. 158 * @param[in] type Endpoint's transfer type. 159 * @param[in] direction Endpoint's direction. 160 * @param[in] mps Maximum packet size the endpoint accepts. 161 * @param[in] size Maximum allowed buffer size. 162 * @param[in] interval Time between transfers(interrupt transfers only). 163 * @return Error code 164 */ 139 165 int hc_add_endpoint( 140 166 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, … … 194 220 } 195 221 /*----------------------------------------------------------------------------*/ 222 /** Dequeue and delete endpoint structures 223 * 224 * @param[in] instance OHCI hc driver structure. 225 * @param[in] address USB address of the device. 226 * @param[in] endpoint USB endpoint number. 227 * @param[in] direction Direction of the endpoint. 228 * @return Error code 229 */ 196 230 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 197 231 usb_endpoint_t endpoint, usb_direction_t direction) … … 244 278 } 245 279 /*----------------------------------------------------------------------------*/ 280 /** Get access to endpoint structures 281 * 282 * @param[in] instance OHCI hc driver structure. 283 * @param[in] address USB address of the device. 284 * @param[in] endpoint USB endpoint number. 285 * @param[in] direction Direction of the endpoint. 286 * @param[out] bw Reserved bandwidth. 287 * @return Error code 288 */ 246 289 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 247 290 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) … … 255 298 } 256 299 /*----------------------------------------------------------------------------*/ 300 /** Add USB transfer to the schedule. 301 * 302 * @param[in] instance OHCI hc driver structure. 303 * @param[in] batch Batch representing the transfer. 304 * @return Error code. 305 */ 257 306 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 258 307 { … … 261 310 assert(batch->ep); 262 311 263 /* check for root hub communication */312 /* Check for root hub communication */ 264 313 if (batch->ep->address == instance->rh.address) { 265 314 return rh_request(&instance->rh, batch); … … 269 318 list_append(&batch->link, &instance->pending_batches); 270 319 batch_commit(batch); 271 switch (batch->ep->transfer_type) { 320 321 /* Control and bulk schedules need a kick to start working */ 322 switch (batch->ep->transfer_type) 323 { 272 324 case USB_TRANSFER_CONTROL: 273 325 instance->registers->command_status |= CS_CLF; … … 279 331 break; 280 332 } 281 282 333 fibril_mutex_unlock(&instance->guard); 283 334 return EOK; 284 335 } 285 336 /*----------------------------------------------------------------------------*/ 337 /** Interrupt handling routine 338 * 339 * @param[in] instance OHCI hc driver structure. 340 * @param[in] status Value of the status register at the time of interrupt. 341 */ 286 342 void hc_interrupt(hc_t *instance, uint32_t status) 287 343 { … … 292 348 if (status & I_RHSC) 293 349 rh_interrupt(&instance->rh); 294 295 350 296 351 if (status & I_WDH) { … … 316 371 fibril_mutex_unlock(&instance->guard); 317 372 } 318 } 319 /*----------------------------------------------------------------------------*/ 373 374 if (status & I_UE) { 375 hc_start_hw(instance); 376 } 377 378 } 379 /*----------------------------------------------------------------------------*/ 380 /** Check status register regularly 381 * 382 * @param[in] instance OHCI hc driver structure. 383 * @return Error code 384 */ 320 385 int interrupt_emulator(hc_t *instance) 321 386 { … … 326 391 instance->registers->interrupt_status = status; 327 392 hc_interrupt(instance, status); 328 async_usleep( 50000);393 async_usleep(10000); 329 394 } 330 395 return EOK; 331 396 } 332 397 /*----------------------------------------------------------------------------*/ 398 /** Turn off any (BIOS)driver that might be in control of the device. 399 * 400 * @param[in] instance OHCI hc driver structure. 401 */ 333 402 void hc_gain_control(hc_t *instance) 334 403 { … … 380 449 } 381 450 /*----------------------------------------------------------------------------*/ 451 /** OHCI hw initialization routine. 452 * 453 * @param[in] instance OHCI hc driver structure. 454 */ 382 455 void hc_start_hw(hc_t *instance) 383 456 { … … 447 520 } 448 521 /*----------------------------------------------------------------------------*/ 522 /** Initialize schedule queues 523 * 524 * @param[in] instance OHCI hc driver structure 525 * @return Error code 526 */ 449 527 int hc_init_transfer_lists(hc_t *instance) 450 528 { 451 529 assert(instance); 452 453 530 #define SETUP_ENDPOINT_LIST(type) \ 454 531 do { \ … … 458 535 usb_log_error("Failed(%d) to setup %s endpoint list.\n", \ 459 536 ret, name); \ 460 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); 537 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]);\ 461 538 endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \ 462 539 endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \ 463 540 endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \ 541 return ret; \ 464 542 } \ 465 543 } while (0) … … 476 554 } 477 555 /*----------------------------------------------------------------------------*/ 556 /** Initialize memory structures used by the OHCI hcd. 557 * 558 * @param[in] instance OHCI hc driver structure. 559 * @return Error code. 560 */ 478 561 int hc_init_memory(hc_t *instance) 479 562 { … … 502 585 /* Init interrupt code */ 503 586 instance->interrupt_code.cmds = instance->interrupt_commands; 587 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS; 504 588 { 505 589 /* Read status register */ … … 521 605 instance->interrupt_commands[2].srcarg = 2; 522 606 523 /* Write 607 /* Write-clean status register */ 524 608 instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32; 525 609 instance->interrupt_commands[3].srcarg = 1; … … 529 613 /* Accept interrupt */ 530 614 instance->interrupt_commands[4].cmd = CMD_ACCEPT; 531 532 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;533 615 } 534 616 -
uspace/drv/ohci/hc.h
r160b75e r293de44 53 53 #define OHCI_NEEDED_IRQ_COMMANDS 5 54 54 55 /** Main OHCI drier structure */ 55 56 typedef struct hc { 57 /** USB bus driver, devices and addresses */ 58 usb_device_keeper_t manager; 59 /** USB bus driver, endpoints */ 60 usb_endpoint_manager_t ep_manager; 61 62 /** Memory mapped I/O registers area */ 56 63 ohci_regs_t *registers; 64 /** Host controller communication area structure */ 57 65 hcca_t *hcca; 58 66 59 usb_address_t rh_address; 60 rh_t rh; 61 67 /** Transfer schedules */ 62 68 endpoint_list_t lists[4]; 69 /** List of active transfers */ 63 70 link_t pending_batches; 64 71 65 usb_device_keeper_t manager; 66 usb_endpoint_manager_t ep_manager; 72 /** Fibril for periodic checks if interrupts can't be used */ 67 73 fid_t interrupt_emulator; 74 75 /** Guards schedule and endpoint manipulation */ 68 76 fibril_mutex_t guard; 69 77 … … 73 81 /** Commands that form interrupt code */ 74 82 irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS]; 83 84 /** USB hub emulation structure */ 85 rh_t rh; 75 86 } hc_t; 76 87 77 88 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 78 79 89 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 80 81 90 void hc_start_hw(hc_t *instance); 82 91 … … 85 94 * @param[in] instance Host controller structure to use. 86 95 */ 87 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 96 static inline void hc_fini(hc_t *instance) 97 { /* TODO: implement*/ }; 88 98 89 99 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep, 90 100 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 91 101 size_t max_packet_size, size_t size, unsigned interval); 92 93 102 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 94 103 usb_endpoint_t endpoint, usb_direction_t direction); 95 96 104 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 97 105 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw); 98 106 99 107 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 100 101 108 void hc_interrupt(hc_t *instance, uint32_t status); 102 109 … … 107 114 */ 108 115 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 109 { return (hc_t*)fun->driver_data; }116 { return fun->driver_data; } 110 117 #endif 111 118 /** -
uspace/drv/ohci/hcd_endpoint.c
r160b75e r293de44 35 35 #include "hcd_endpoint.h" 36 36 37 /** Callback to set toggle on ED. 38 * 39 * @param[in] hcd_ep hcd endpoint structure 40 * @param[in] toggle new value of toggle bit 41 */ 37 42 static void hcd_ep_toggle_set(void *hcd_ep, int toggle) 38 43 { … … 42 47 ed_toggle_set(instance->ed, toggle); 43 48 } 49 /*----------------------------------------------------------------------------*/ 50 /** Callback to get value of toggle bit. 51 * 52 * @param[in] hcd_ep hcd endpoint structure 53 * @return Current value of toggle bit. 54 */ 44 55 static int hcd_ep_toggle_get(void *hcd_ep) 45 56 { … … 49 60 return ed_toggle_get(instance->ed); 50 61 } 51 52 62 /*----------------------------------------------------------------------------*/ 63 /** Creates new hcd endpoint representation. 64 * 65 * @param[in] ep USBD endpoint structure 66 * @return pointer to a new hcd endpoint structure, NULL on failure. 67 */ 53 68 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep) 54 69 { … … 78 93 } 79 94 /*----------------------------------------------------------------------------*/ 80 hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep) 81 { 82 assert(ep); 83 return ep->hc_data.data; 84 } 85 /*----------------------------------------------------------------------------*/ 95 /** Disposes assigned hcd endpoint structure 96 * 97 * @param[in] ep USBD endpoint structure 98 */ 86 99 void hcd_endpoint_clear(endpoint_t *ep) 87 100 { -
uspace/drv/ohci/hcd_endpoint.h
r160b75e r293de44 37 37 #include <assert.h> 38 38 #include <adt/list.h> 39 40 39 #include <usb/host/endpoint.h> 41 40 … … 43 42 #include "hw_struct/transfer_descriptor.h" 44 43 44 /** Connector structure linking ED to to prepared TD. */ 45 45 typedef struct hcd_endpoint { 46 /** OHCI endpoint descriptor */ 46 47 ed_t *ed; 48 /** Currently enqueued transfer descriptor */ 47 49 td_t *td; 50 /** Linked list used by driver software */ 48 51 link_t link; 49 52 } hcd_endpoint_t; 50 53 51 54 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep); 55 void hcd_endpoint_clear(endpoint_t *ep); 52 56 53 hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep); 57 /** Get and convert assigned hcd_endpoint_t structure 58 * @param[in] ep USBD endpoint structure. 59 * @return Pointer to assigned hcd endpoint structure 60 */ 61 static inline hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep) 62 { 63 assert(ep); 64 return ep->hc_data.data; 65 } 54 66 55 void hcd_endpoint_clear(endpoint_t *ep);56 67 #endif 57 68 /** -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
r160b75e r293de44 44 44 assert(instance); 45 45 bzero(instance, sizeof(td_t)); 46 instance-> 46 instance->status = 0 47 47 | ((dp[dir] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT) 48 48 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT); -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
r160b75e r293de44 41 41 #include "completion_codes.h" 42 42 43 /* OHCI TDs can handle up to 8KB buffers */ 44 #define OHCI_TD_MAX_TRANSFER (8 * 1024) 43 /* OHCI TDs can handle up to 8KB buffers, however, it can use max 2 pages. 44 * Using 4KB buffers guarantees the page count condition. 45 * (OHCI assumes 4KB pages) */ 46 #define OHCI_TD_MAX_TRANSFER (4 * 1024) 45 47 46 48 typedef struct td { -
uspace/drv/ohci/ohci_regs.h
r160b75e r293de44 36 36 #include <stdint.h> 37 37 38 typedef struct ohci_regs 39 {38 /** OHCI memory mapped registers structure */ 39 typedef struct ohci_regs { 40 40 const volatile uint32_t revision; 41 41 volatile uint32_t control; -
uspace/drv/uhci-hcd/batch.c
r160b75e r293de44 45 45 #define DEFAULT_ERROR_COUNT 3 46 46 47 /** UHCI specific data required for USB transfer */ 47 48 typedef struct uhci_transfer_batch { 49 /** Queue head 50 * This QH is used to maintain UHCI schedule structure and the element 51 * pointer points to the first TD of this batch. 52 */ 48 53 qh_t *qh; 54 /** List of TDs needed for the transfer */ 49 55 td_t *tds; 56 /** Number of TDs used by the transfer */ 57 size_t td_count; 58 /** Data buffer, must be accessible by the UHCI hw */ 50 59 void *device_buffer; 51 size_t td_count;52 60 } uhci_transfer_batch_t; 53 61 /*----------------------------------------------------------------------------*/ 54 static void uhci_transfer_batch_dispose(void *uhci_batch)55 {56 uhci_transfer_batch_t *instance = uhci_batch;57 assert(instance);58 free32(instance->device_buffer);59 free(instance);60 }61 /*----------------------------------------------------------------------------*/62 63 62 static void batch_control(usb_transfer_batch_t *instance, 64 63 usb_packet_id data_stage, usb_packet_id status_stage); 65 64 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid); 66 65 /*----------------------------------------------------------------------------*/ 66 /** Safely destructs uhci_transfer_batch_t structure 67 * 68 * @param[in] uhci_batch Instance to destroy. 69 */ 70 static void uhci_transfer_batch_dispose(void *uhci_batch) 71 { 72 uhci_transfer_batch_t *instance = uhci_batch; 73 assert(instance); 74 free32(instance->device_buffer); 75 free(instance); 76 } 77 /*----------------------------------------------------------------------------*/ 67 78 /** Allocate memory and initialize internal data structure. 68 79 * … … 84 95 */ 85 96 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 86 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 97 char *buffer, size_t buffer_size, 98 const char* setup_buffer, size_t setup_size, 87 99 usbhc_iface_transfer_in_callback_t func_in, 88 100 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 173 185 instance->error = td_status(&data->tds[i]); 174 186 if (instance->error != EOK) { 175 usb_log_debug("Batch(%p) found error TD(%zu):%" PRIx32 ".\n",176 instance, i, data->tds[i].status);187 usb_log_debug("Batch(%p) found error TD(%zu):%" 188 PRIx32 ".\n", instance, i, data->tds[i].status); 177 189 td_print_status(&data->tds[i]); 178 190 … … 397 409 /*----------------------------------------------------------------------------*/ 398 410 /** Provides access to QH data structure. 411 * 399 412 * @param[in] instance Batch pointer to use. 400 413 * @return Pointer to the QH used by the batch. -
uspace/drv/uhci-hcd/batch.h
r160b75e r293de44 45 45 usb_transfer_batch_t * batch_get( 46 46 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 47 c har *setup_buffer, size_t setup_size,47 const char *setup_buffer, size_t setup_size, 48 48 usbhc_iface_transfer_in_callback_t func_in, 49 49 usbhc_iface_transfer_out_callback_t func_out, … … 55 55 56 56 void batch_control_write(usb_transfer_batch_t *instance); 57 58 57 void batch_control_read(usb_transfer_batch_t *instance); 59 58 60 59 void batch_interrupt_in(usb_transfer_batch_t *instance); 61 62 60 void batch_interrupt_out(usb_transfer_batch_t *instance); 63 61 64 62 void batch_bulk_in(usb_transfer_batch_t *instance); 65 66 63 void batch_bulk_out(usb_transfer_batch_t *instance); 67 64 -
uspace/drv/uhci-hcd/hc.c
r160b75e r293de44 57 57 static int hc_debug_checker(void *arg); 58 58 /*----------------------------------------------------------------------------*/ 59 /** Initialize UHCI hc ddriver structure59 /** Initialize UHCI hc driver structure 60 60 * 61 61 * @param[in] instance Memory place to initialize. -
uspace/drv/uhci-hcd/hc.h
r160b75e r293de44 95 95 #define UHCI_NEEDED_IRQ_COMMANDS 5 96 96 97 /* Main HCdriver structure */97 /** Main UHCI driver structure */ 98 98 typedef struct hc { 99 99 /** USB bus driver, devices and addresses */ -
uspace/drv/uhci-hcd/transfer_list.c
r160b75e r293de44 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h> 36 37 37 38 #include "transfer_list.h" … … 71 72 * @param[in] instance Memory place to use. 72 73 * 73 * Frees memory forinternal qh_t structure.74 * Frees memory of the internal qh_t structure. 74 75 */ 75 76 void transfer_list_fini(transfer_list_t *instance) … … 126 127 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 127 128 129 /* Make sure all data in the batch are written */ 130 write_barrier(); 131 128 132 /* keep link */ 129 133 batch_qh(batch)->next = last_qh->next; 130 134 qh_set_next_qh(last_qh, batch_qh(batch)); 131 135 132 asm volatile ("": : :"memory"); 136 /* Make sure the pointer is updated */ 137 write_barrier(); 133 138 134 139 /* Add to the driver list */ … … 222 227 == addr_to_phys(batch_qh(batch))); 223 228 prev_qh->next = batch_qh(batch)->next; 224 asm volatile ("": : :"memory"); 229 230 /* Make sure the pointer is updated */ 231 write_barrier(); 232 225 233 /* Remove from the batch list */ 226 234 list_remove(&batch->link); -
uspace/drv/uhci-hcd/transfer_list.h
r160b75e r293de44 43 43 * of currently executed transfers 44 44 */ 45 typedef struct transfer_list 46 { 45 typedef struct transfer_list { 47 46 /** Guard against multiple add/remove races */ 48 47 fibril_mutex_t guard; -
uspace/drv/uhci-hcd/utils/malloc32.h
r160b75e r293de44 74 74 if (size <= SLAB_ELEMENT_SIZE) 75 75 return slab_malloc_g(); 76 assert(false); 76 usb_log_warning("Requested %zu bytes, current allocator can't handle " 77 "that amount, pray that the standard malloc will suffice.", size); 77 78 return memalign(UHCI_STRCUTURES_ALIGNMENT, size); 78 79 } -
uspace/drv/uhci-rhd/port.c
r160b75e r293de44 227 227 while (uhci_port_read_status(port) & STATUS_IN_RESET); 228 228 } 229 /* PIO delay, should not be longer than 3ms as the device might 230 * enter suspend state. */ 229 231 udelay(10); 230 232 /* Enable the port. */ 231 233 uhci_port_set_enabled(port, true); 232 233 /* Reset recovery period,234 * devices do not have to respond during this period235 */236 async_usleep(10000);237 234 return EOK; 238 235 } -
uspace/drv/usbhid/Makefile
r160b75e r293de44 57 57 generic/hiddev.c \ 58 58 mouse/mousedev.c \ 59 lgtch-ultrax/lgtch-ultrax.c \60 lgtch-ultrax/keymap.c \59 multimedia/multimedia.c \ 60 multimedia/keymap.c \ 61 61 $(STOLEN_LAYOUT_SOURCES) 62 62 -
uspace/drv/usbhid/generic/hiddev.c
r160b75e r293de44 162 162 /*----------------------------------------------------------------------------*/ 163 163 164 int usb_generic_hid_init(usb_hid_dev_t *hid_dev )164 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 165 165 { 166 166 if (hid_dev == NULL) { … … 173 173 /*----------------------------------------------------------------------------*/ 174 174 175 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, 175 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data, 176 176 uint8_t *buffer, size_t buffer_size) 177 177 { -
uspace/drv/usbhid/generic/hiddev.h
r160b75e r293de44 48 48 /*----------------------------------------------------------------------------*/ 49 49 50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev );50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data); 51 51 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data, 53 53 uint8_t *buffer, size_t buffer_size); 54 54 -
uspace/drv/usbhid/kbd/kbddev.c
r160b75e r293de44 252 252 sysarg_t method = IPC_GET_IMETHOD(*icall); 253 253 254 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 255 256 if (hid_dev == NULL || hid_dev->data == NULL) { 254 usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data; 255 if (kbd_dev == NULL) { 257 256 usb_log_debug("default_connection_handler: " 258 257 "Missing parameter.\n"); … … 260 259 return; 261 260 } 262 263 assert(hid_dev != NULL);264 assert(hid_dev->data != NULL);265 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;266 261 267 262 if (method == IPC_M_CONNECT_TO_ME) { … … 313 308 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 314 309 hid_dev->report, NULL, kbd_dev->led_path, 315 USB_HID_PATH_COMPARE_ USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END,310 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 316 311 USB_HID_REPORT_TYPE_OUTPUT); 317 312 318 while (field != NULL) { 319 313 while (field != NULL) { 314 320 315 if ((field->usage == USB_HID_LED_NUM_LOCK) 321 316 && (kbd_dev->mods & KM_NUM_LOCK)){ … … 334 329 335 330 field = usb_hid_report_get_sibling(hid_dev->report, field, 336 kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 337 | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT); 331 kbd_dev->led_path, 332 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 333 USB_HID_REPORT_TYPE_OUTPUT); 338 334 } 339 335 … … 662 658 * usb_hid_parse_report(). 663 659 */ 664 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, 660 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, 665 661 uint8_t *buffer, size_t actual_size) 666 662 { 667 663 assert(hid_dev->report != NULL); 668 664 assert(hid_dev != NULL); 669 assert(hid_dev->data != NULL); 670 671 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 665 assert(kbd_dev != NULL); 672 666 673 667 usb_log_debug("Calling usb_hid_parse_report() with " … … 774 768 /*----------------------------------------------------------------------------*/ 775 769 776 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev )770 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 777 771 { 778 772 assert(hid_dev != NULL); 779 773 assert(hid_dev->usb_dev != NULL); 774 assert(kbd_dev != NULL); 780 775 781 776 /* Create the function exposed under /dev/devices. */ … … 792 787 * to the DDF function. 793 788 */ 794 fun->ops = & hid_dev->ops;795 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data789 fun->ops = &kbd_dev->ops; 790 fun->driver_data = kbd_dev; 796 791 797 792 int rc = ddf_fun_bind(fun); … … 840 835 * @return Other value inherited from function usbhid_dev_init(). 841 836 */ 842 int usb_kbd_init(usb_hid_dev_t *hid_dev )837 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data) 843 838 { 844 839 usb_log_debug("Initializing HID/KBD structure...\n"); … … 865 860 usb_hid_report_path_set_report_id(path, 0); 866 861 867 kbd_dev->key_count = usb_hid_report_input_length( 868 hid_dev->report, path, 869 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 862 kbd_dev->key_count = usb_hid_report_size( 863 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 870 864 usb_hid_report_path_free(path); 871 865 … … 908 902 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 909 903 910 kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report, 911 kbd_dev->led_path, 912 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 904 kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report, 905 0, USB_HID_REPORT_TYPE_OUTPUT); 913 906 914 907 usb_log_debug("Output report size (in items): %zu\n", … … 955 948 956 949 // save the KBD device structure into the HID device structure 957 hid_dev->data = kbd_dev; 950 //hid_dev->data = kbd_dev; 951 *data = kbd_dev; 958 952 959 953 // set handler for incoming calls 960 hid_dev->ops.default_handler = default_connection_handler;954 kbd_dev->ops.default_handler = default_connection_handler; 961 955 962 956 /* … … 983 977 984 978 usb_log_debug("Creating KBD function...\n"); 985 int rc = usb_kbd_create_function(hid_dev );979 int rc = usb_kbd_create_function(hid_dev, kbd_dev); 986 980 if (rc != EOK) { 987 981 usb_kbd_free(&kbd_dev); … … 994 988 /*----------------------------------------------------------------------------*/ 995 989 996 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,997 size_t buffer_size)998 { 999 if (hid_dev == NULL || buffer == NULL ) {990 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data, 991 uint8_t *buffer, size_t buffer_size) 992 { 993 if (hid_dev == NULL || buffer == NULL || data == NULL) { 1000 994 // do not continue polling (???) 1001 995 return false; 1002 996 } 1003 997 998 usb_kbd_t *kbd_dev = (usb_kbd_t *)data; 999 assert(kbd_dev != NULL); 1000 1004 1001 // TODO: add return value from this function 1005 usb_kbd_process_data(hid_dev, buffer, buffer_size);1002 usb_kbd_process_data(hid_dev, kbd_dev, buffer, buffer_size); 1006 1003 1007 1004 return true; … … 1066 1063 /*----------------------------------------------------------------------------*/ 1067 1064 1068 void usb_kbd_deinit(usb_hid_dev_t *hid_dev )1065 void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data) 1069 1066 { 1070 1067 if (hid_dev == NULL) { … … 1072 1069 } 1073 1070 1074 if ( hid_dev->data != NULL) {1075 usb_kbd_t *kbd_dev = (usb_kbd_t *) hid_dev->data;1071 if (data != NULL) { 1072 usb_kbd_t *kbd_dev = (usb_kbd_t *)data; 1076 1073 if (usb_kbd_is_initialized(kbd_dev)) { 1077 1074 usb_kbd_mark_unusable(kbd_dev); 1078 1075 } else { 1079 1076 usb_kbd_free(&kbd_dev); 1080 hid_dev->data = NULL;1081 1077 } 1082 1078 } -
uspace/drv/usbhid/kbd/kbddev.h
r160b75e r293de44 83 83 int console_phone; 84 84 85 /** @todo What is this actually? */ 86 ddf_dev_ops_t ops; 87 85 88 /** Information for auto-repeat of keys. */ 86 89 usb_kbd_repeat_t repeat; … … 117 120 /*----------------------------------------------------------------------------*/ 118 121 119 int usb_kbd_init(struct usb_hid_dev *hid_dev );122 int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data); 120 123 121 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,122 size_t buffer_size);124 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data, 125 uint8_t *buffer, size_t buffer_size); 123 126 124 127 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); … … 131 134 int type, unsigned int key); 132 135 133 void usb_kbd_deinit(struct usb_hid_dev *hid_dev );136 void usb_kbd_deinit(struct usb_hid_dev *hid_dev, void *data); 134 137 135 138 int usb_kbd_set_boot_protocol(struct usb_hid_dev *hid_dev); -
uspace/drv/usbhid/mouse/mousedev.c
r160b75e r293de44 122 122 sysarg_t method = IPC_GET_IMETHOD(*icall); 123 123 124 usb_ hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;125 126 if ( hid_dev == NULL || hid_dev->data== NULL) {124 usb_mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data; 125 126 if (mouse_dev == NULL) { 127 127 usb_log_debug("default_connection_handler: Missing " 128 128 "parameters.\n"); … … 131 131 } 132 132 133 assert(hid_dev != NULL); 134 assert(hid_dev->data != NULL); 135 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 133 usb_log_debug("default_connection_handler: fun->name: %s\n", 134 fun->name); 135 usb_log_debug("default_connection_handler: mouse_phone: %d, wheel " 136 "phone: %d\n", mouse_dev->mouse_phone, mouse_dev->wheel_phone); 136 137 137 138 int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) … … 145 146 "phone to mouse already set.\n"); 146 147 async_answer_0(icallid, ELIMIT); 147 //async_answer_0(icallid, EOK);148 148 return; 149 149 } 150 150 151 151 *phone = callback; 152 usb_log_debug("Console phone to mouse set ok (%d).\n", callback);152 usb_log_debug("Console phone to mouse set ok (%d).\n", *phone); 153 153 async_answer_0(icallid, EOK); 154 154 return; … … 224 224 /*----------------------------------------------------------------------------*/ 225 225 226 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, uint8_t *buffer, 227 size_t buffer_size) 228 { 229 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 226 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, 227 usb_mouse_t *mouse_dev, uint8_t *buffer, 228 size_t buffer_size) 229 { 230 assert(mouse_dev != NULL); 230 231 231 232 usb_log_debug2("got buffer: %s.\n", … … 378 379 /*----------------------------------------------------------------------------*/ 379 380 380 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev) 381 { 381 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse) 382 { 383 assert(hid_dev != NULL); 384 assert(mouse != NULL); 385 382 386 /* Create the function exposed under /dev/devices. */ 383 387 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); … … 389 393 } 390 394 391 /* 392 * Store the initialized HID device and HID ops 393 * to the DDF function. 394 */ 395 fun->ops = &hid_dev->ops; 396 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 395 fun->ops = &mouse->ops; 396 fun->driver_data = mouse; // TODO: maybe change to hid_dev->data 397 397 398 398 int rc = ddf_fun_bind(fun); … … 431 431 * to the DDF function. 432 432 */ 433 fun->ops = & hid_dev->ops;434 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data433 fun->ops = &mouse->ops; 434 fun->driver_data = mouse; // TODO: maybe change to hid_dev->data 435 435 436 436 rc = ddf_fun_bind(fun); … … 458 458 /*----------------------------------------------------------------------------*/ 459 459 460 int usb_mouse_init(usb_hid_dev_t *hid_dev )460 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 461 461 { 462 462 usb_log_debug("Initializing HID/Mouse structure...\n"); … … 485 485 486 486 // save the Mouse device structure into the HID device structure 487 hid_dev->data = mouse_dev;487 *data = mouse_dev; 488 488 489 489 // set handler for incoming calls 490 hid_dev->ops.default_handler = default_connection_handler; 490 // TODO: must be one for each subdriver!! 491 mouse_dev->ops.default_handler = default_connection_handler; 491 492 492 493 // TODO: how to know if the device supports the request??? … … 494 495 // hid_dev->usb_dev->interface_no, IDLE_RATE); 495 496 496 int rc = usb_mouse_create_function(hid_dev );497 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 497 498 if (rc != EOK) { 498 499 usb_mouse_free(&mouse_dev); … … 505 506 /*----------------------------------------------------------------------------*/ 506 507 507 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,508 size_t buffer_size)508 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data, 509 uint8_t *buffer, size_t buffer_size) 509 510 { 510 511 usb_log_debug("usb_mouse_polling_callback()\n"); 511 512 usb_debug_str_buffer(buffer, buffer_size, 0); 512 513 513 if (hid_dev == NULL ) {514 if (hid_dev == NULL || data == NULL) { 514 515 usb_log_error("Missing argument to the mouse polling callback." 515 516 "\n"); … … 517 518 } 518 519 519 if (hid_dev->data == NULL) { 520 usb_log_error("Wrong argument to the mouse polling callback." 521 "\n"); 522 return false; 523 } 524 525 return usb_mouse_process_report(hid_dev, buffer, buffer_size); 526 } 527 528 /*----------------------------------------------------------------------------*/ 529 530 void usb_mouse_deinit(usb_hid_dev_t *hid_dev) 531 { 532 usb_mouse_free((usb_mouse_t **)&hid_dev->data); 520 usb_mouse_t *mouse_dev = (usb_mouse_t *)data; 521 522 return usb_mouse_process_report(hid_dev, mouse_dev, buffer, 523 buffer_size); 524 } 525 526 /*----------------------------------------------------------------------------*/ 527 528 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data) 529 { 530 if (data != NULL) { 531 usb_mouse_free((usb_mouse_t **)&data); 532 } 533 533 } 534 534 -
uspace/drv/usbhid/mouse/mousedev.h
r160b75e r293de44 52 52 53 53 int32_t *buttons; 54 55 ddf_dev_ops_t ops; 54 56 } usb_mouse_t; 55 57 … … 63 65 /*----------------------------------------------------------------------------*/ 64 66 65 int usb_mouse_init(struct usb_hid_dev *hid_dev );67 int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data); 66 68 67 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,68 size_t buffer_size);69 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data, 70 uint8_t *buffer, size_t buffer_size); 69 71 70 void usb_mouse_deinit(struct usb_hid_dev *hid_dev );72 void usb_mouse_deinit(struct usb_hid_dev *hid_dev, void *data); 71 73 72 74 int usb_mouse_set_boot_protocol(struct usb_hid_dev *hid_dev); -
uspace/drv/usbhid/multimedia/keymap.h
r160b75e r293de44 34 34 */ 35 35 36 #ifndef USB_HID_ LGTCH_ULTRAX_KEYMAP_H_37 #define USB_HID_ LGTCH_ULTRAX_KEYMAP_H_36 #ifndef USB_HID_MULTIMEDIA_KEYMAP_H_ 37 #define USB_HID_MULTIMEDIA_KEYMAP_H_ 38 38 39 unsigned int usb_ lgtch_map_usage(int usage);39 unsigned int usb_multimedia_map_usage(int usage); 40 40 41 #endif /* USB_HID_LGTCH_ULTRAX_KEYMAP_H_ */ 41 const char *usb_multimedia_usage_to_str(int usage); 42 43 #endif /* USB_HID_MULTIMEDIA_KEYMAP_H_ */ 42 44 43 45 /** -
uspace/drv/usbhid/multimedia/multimedia.c
r160b75e r293de44 32 32 /** 33 33 * @file 34 * USB Logitech UltraX Keyboard sampledriver.35 */ 36 37 38 #include " lgtch-ultrax.h"34 * USB Keyboard multimedia keys subdriver. 35 */ 36 37 38 #include "multimedia.h" 39 39 #include "../usbhid.h" 40 40 #include "keymap.h" … … 50 50 #include <io/console.h> 51 51 52 #define NAME "lgtch-ultrax" 53 54 typedef enum usb_lgtch_flags { 55 USB_LGTCH_STATUS_UNINITIALIZED = 0, 56 USB_LGTCH_STATUS_INITIALIZED = 1, 57 USB_LGTCH_STATUS_TO_DESTROY = -1 58 } usb_lgtch_flags; 52 #define NAME "multimedia-keys" 59 53 60 54 /*----------------------------------------------------------------------------*/ … … 62 56 * Logitech UltraX device type. 63 57 */ 64 typedef struct usb_ lgtch_ultrax_t {58 typedef struct usb_multimedia_t { 65 59 /** Previously pressed keys (not translated to key codes). */ 66 60 int32_t *keys_old; … … 68 62 int32_t *keys; 69 63 /** Count of stored keys (i.e. number of keys in the report). */ 70 size_t key_count; 71 64 size_t key_count; 72 65 /** IPC phone to the console device (for sending key events). */ 73 66 int console_phone; 74 75 /** Information for auto-repeat of keys. */ 76 // usb_kbd_repeat_t repeat; 77 78 /** Mutex for accessing the information about auto-repeat. */ 79 // fibril_mutex_t *repeat_mtx; 80 81 /** State of the structure (for checking before use). 82 * 83 * 0 - not initialized 84 * 1 - initialized 85 * -1 - ready for destroying 86 */ 87 int initialized; 88 } usb_lgtch_ultrax_t; 67 } usb_multimedia_t; 89 68 90 69 … … 108 87 sysarg_t method = IPC_GET_IMETHOD(*icall); 109 88 110 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 111 112 if (hid_dev == NULL || hid_dev->data == NULL) { 89 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 90 //usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 91 92 if (multim_dev == NULL) { 113 93 async_answer_0(icallid, EINVAL); 114 94 return; 115 95 } 116 117 assert(hid_dev != NULL);118 assert(hid_dev->data != NULL);119 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data;120 96 121 97 if (method == IPC_M_CONNECT_TO_ME) { 122 98 int callback = IPC_GET_ARG5(*icall); 123 99 124 if ( lgtch_dev->console_phone != -1) {100 if (multim_dev->console_phone != -1) { 125 101 async_answer_0(icallid, ELIMIT); 126 102 return; 127 103 } 128 104 129 lgtch_dev->console_phone = callback;105 multim_dev->console_phone = callback; 130 106 usb_log_debug(NAME " Saved phone to console: %d\n", callback); 131 107 async_answer_0(icallid, EOK); … … 138 114 /*----------------------------------------------------------------------------*/ 139 115 140 static ddf_dev_ops_t lgtch_ultrax_ops = {116 static ddf_dev_ops_t multimedia_ops = { 141 117 .default_handler = default_connection_handler 142 118 }; 143 144 /*----------------------------------------------------------------------------*/145 146 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,147 // uint8_t report_id, void *arg);148 149 //static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = {150 // .keyboard = usb_lgtch_process_keycodes151 //};152 153 ///*----------------------------------------------------------------------------*/154 155 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,156 // uint8_t report_id, void *arg)157 //{158 // // TODO: checks159 160 // usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n",161 // report_id, usb_debug_str_buffer(key_codes, count, 0));162 //}163 119 164 120 /*----------------------------------------------------------------------------*/ … … 180 136 * @param key Key code of the key according to HID Usage Tables. 181 137 */ 182 static void usb_ lgtch_push_ev(usb_hid_dev_t *hid_dev, int type,183 u nsigned int key)138 static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev, 139 usb_multimedia_t *multim_dev, int type, unsigned int key) 184 140 { 185 141 assert(hid_dev != NULL); 186 assert( hid_dev->data!= NULL);187 188 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data;142 assert(multim_dev != NULL); 143 144 // usb_multimedia_t *multim_dev = (usb_multimedia_t *)hid_dev->data; 189 145 190 146 console_event_t ev; … … 193 149 ev.key = key; 194 150 ev.mods = 0; 195 196 151 ev.c = 0; 197 152 198 153 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); 199 if ( lgtch_dev->console_phone < 0) {154 if (multim_dev->console_phone < 0) { 200 155 usb_log_warning( 201 156 "Connection to console not ready, key discarded.\n"); … … 203 158 } 204 159 205 async_msg_4( lgtch_dev->console_phone, KBD_EVENT, ev.type, ev.key,160 async_msg_4(multim_dev->console_phone, KBD_EVENT, ev.type, ev.key, 206 161 ev.mods, ev.c); 207 162 } … … 209 164 /*----------------------------------------------------------------------------*/ 210 165 211 static void usb_ lgtch_free(usb_lgtch_ultrax_t **lgtch_dev)212 { 213 if ( lgtch_dev == NULL || *lgtch_dev == NULL) {166 static void usb_multimedia_free(usb_multimedia_t **multim_dev) 167 { 168 if (multim_dev == NULL || *multim_dev == NULL) { 214 169 return; 215 170 } 216 171 217 172 // hangup phone to the console 218 async_hangup((*lgtch_dev)->console_phone); 219 220 // if ((*lgtch_dev)->repeat_mtx != NULL) { 221 // /* TODO: replace by some check and wait */ 222 // assert(!fibril_mutex_is_locked((*lgtch_dev)->repeat_mtx)); 223 // free((*lgtch_dev)->repeat_mtx); 224 // } 173 async_hangup((*multim_dev)->console_phone); 225 174 226 175 // free all buffers 227 if ((*lgtch_dev)->keys != NULL) { 228 free((*lgtch_dev)->keys); 229 } 230 if ((*lgtch_dev)->keys_old != NULL) { 231 free((*lgtch_dev)->keys_old); 232 } 233 234 free(*lgtch_dev); 235 *lgtch_dev = NULL; 236 } 237 238 /*----------------------------------------------------------------------------*/ 239 240 static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev) 176 if ((*multim_dev)->keys != NULL) { 177 free((*multim_dev)->keys); 178 } 179 if ((*multim_dev)->keys_old != NULL) { 180 free((*multim_dev)->keys_old); 181 } 182 183 free(*multim_dev); 184 *multim_dev = NULL; 185 } 186 187 /*----------------------------------------------------------------------------*/ 188 189 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev, 190 usb_multimedia_t *multim_dev) 241 191 { 242 192 /* Create the function exposed under /dev/devices. */ … … 248 198 } 249 199 250 /* 251 * Store the initialized HID device and HID ops 252 * to the DDF function. 253 */ 254 fun->ops = &lgtch_ultrax_ops; 255 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 200 fun->ops = &multimedia_ops; 201 fun->driver_data = multim_dev; // TODO: maybe change to hid_dev->data 256 202 257 203 int rc = ddf_fun_bind(fun); … … 279 225 /*----------------------------------------------------------------------------*/ 280 226 281 int usb_ lgtch_init(struct usb_hid_dev *hid_dev)227 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 282 228 { 283 229 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { … … 285 231 } 286 232 287 usb_log_debug(NAME " Initializing HID/ lgtch_ultraxstructure...\n");288 289 usb_ lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(290 sizeof(usb_ lgtch_ultrax_t));291 if ( lgtch_dev == NULL) {233 usb_log_debug(NAME " Initializing HID/multimedia structure...\n"); 234 235 usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc( 236 sizeof(usb_multimedia_t)); 237 if (multim_dev == NULL) { 292 238 return ENOMEM; 293 239 } 294 240 295 lgtch_dev->console_phone = -1;241 multim_dev->console_phone = -1; 296 242 297 243 usb_hid_report_path_t *path = usb_hid_report_path(); … … 300 246 usb_hid_report_path_set_report_id(path, 1); 301 247 302 lgtch_dev->key_count = usb_hid_report_input_length(303 hid_dev->report, path,304 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 248 multim_dev->key_count = usb_hid_report_size( 249 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 250 305 251 usb_hid_report_path_free(path); 306 252 307 253 usb_log_debug(NAME " Size of the input report: %zu\n", 308 lgtch_dev->key_count);309 310 lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,254 multim_dev->key_count); 255 256 multim_dev->keys = (int32_t *)calloc(multim_dev->key_count, 311 257 sizeof(int32_t)); 312 258 313 if ( lgtch_dev->keys == NULL) {259 if (multim_dev->keys == NULL) { 314 260 usb_log_fatal("No memory!\n"); 315 free( lgtch_dev);261 free(multim_dev); 316 262 return ENOMEM; 317 263 } 318 264 319 lgtch_dev->keys_old =320 (int32_t *)calloc( lgtch_dev->key_count, sizeof(int32_t));321 322 if ( lgtch_dev->keys_old == NULL) {265 multim_dev->keys_old = 266 (int32_t *)calloc(multim_dev->key_count, sizeof(int32_t)); 267 268 if (multim_dev->keys_old == NULL) { 323 269 usb_log_fatal("No memory!\n"); 324 free( lgtch_dev->keys);325 free( lgtch_dev);270 free(multim_dev->keys); 271 free(multim_dev); 326 272 return ENOMEM; 327 273 } … … 330 276 331 277 // save the KBD device structure into the HID device structure 332 hid_dev->data = lgtch_dev; 333 334 lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED; 335 usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n"); 336 337 int rc = usb_lgtch_create_function(hid_dev); 278 *data = multim_dev; 279 280 usb_log_debug(NAME " HID/multimedia device structure initialized.\n"); 281 282 int rc = usb_multimedia_create_function(hid_dev, multim_dev); 338 283 if (rc != EOK) { 339 usb_ lgtch_free(&lgtch_dev);284 usb_multimedia_free(&multim_dev); 340 285 return rc; 341 286 } 342 287 343 usb_log_debug(NAME " HID/ lgtch_ultraxstructure initialized.\n");288 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 344 289 345 290 return EOK; … … 348 293 /*----------------------------------------------------------------------------*/ 349 294 350 void usb_ lgtch_deinit(struct usb_hid_dev *hid_dev)295 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data) 351 296 { 352 297 if (hid_dev == NULL) { … … 354 299 } 355 300 356 if (hid_dev->data != NULL) { 357 usb_lgtch_ultrax_t *lgtch_dev = 358 (usb_lgtch_ultrax_t *)hid_dev->data; 359 // if (usb_kbd_is_initialized(kbd_dev)) { 360 // usb_kbd_mark_unusable(kbd_dev); 361 // } else { 362 usb_lgtch_free(&lgtch_dev); 363 hid_dev->data = NULL; 364 // } 365 } 366 } 367 368 /*----------------------------------------------------------------------------*/ 369 370 bool usb_lgtch_polling_callback(struct usb_hid_dev *hid_dev, 301 if (data != NULL) { 302 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 303 usb_multimedia_free(&multim_dev); 304 } 305 } 306 307 /*----------------------------------------------------------------------------*/ 308 309 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data, 371 310 uint8_t *buffer, size_t buffer_size) 372 311 { … … 375 314 usb_log_debug(NAME " usb_lgtch_polling_callback(%p, %p, %zu)\n", 376 315 hid_dev, buffer, buffer_size); 316 317 if (data == NULL) { 318 return EINVAL; // TODO: other error code? 319 } 320 321 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 377 322 378 323 usb_log_debug(NAME " Calling usb_hid_parse_report() with " … … 380 325 381 326 usb_hid_report_path_t *path = usb_hid_report_path(); 382 usb_hid_report_path_append_item(path, 0xc, 0);327 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 383 328 384 329 uint8_t report_id; … … 400 345 USB_HID_REPORT_TYPE_INPUT); 401 346 402 unsigned int key;347 // unsigned int key; 403 348 404 349 /*! @todo Is this iterating OK if done multiple times? … … 406 351 */ 407 352 while (field != NULL) { 408 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", field->value, 409 field->usage); 410 411 key = usb_lgtch_map_usage(field->usage); 412 usb_lgtch_push_ev(hid_dev, KEY_PRESS, key); 353 if(field->value != 0) { 354 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 355 field->value, field->usage); 356 unsigned int key = 357 usb_multimedia_map_usage(field->usage); 358 const char *key_str = 359 usb_multimedia_usage_to_str(field->usage); 360 usb_log_info("Pressed key: %s\n", key_str); 361 usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, 362 key); 363 } 413 364 414 365 field = usb_hid_report_get_sibling( -
uspace/drv/usbhid/multimedia/multimedia.h
r160b75e r293de44 31 31 */ 32 32 /** @file 33 * USB Logitech UltraX Keyboard sampledriver.33 * USB Keyboard multimedia keys subdriver. 34 34 */ 35 35 36 #ifndef USB_HID_ LGTCH_ULTRAX_H_37 #define USB_HID_ LGTCH_ULTRAX_H_36 #ifndef USB_HID_MULTIMEDIA_H_ 37 #define USB_HID_MULTIMEDIA_H_ 38 38 39 39 #include <usb/dev/driver.h> … … 43 43 /*----------------------------------------------------------------------------*/ 44 44 45 int usb_ lgtch_init(struct usb_hid_dev *hid_dev);45 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data); 46 46 47 void usb_ lgtch_deinit(struct usb_hid_dev *hid_dev);47 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data); 48 48 49 bool usb_ lgtch_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,50 size_t buffer_size);49 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data, 50 uint8_t *buffer, size_t buffer_size); 51 51 52 52 /*----------------------------------------------------------------------------*/ 53 53 54 #endif // USB_HID_ LGTCH_ULTRAX_H_54 #endif // USB_HID_MULTIMEDIA_H_ 55 55 56 56 /** -
uspace/drv/usbhid/subdrivers.c
r160b75e r293de44 38 38 #include <usb/hid/hidpath.h> 39 39 40 #include "lgtch-ultrax/lgtch-ultrax.h" 40 //#include "lgtch-ultrax/lgtch-ultrax.h" 41 #include "multimedia/multimedia.h" 41 42 #include "mouse/mousedev.h" 42 43 43 44 static usb_hid_subdriver_usage_t path_kbd[] = { 44 {USB_HIDUT_PAGE_KEYBOARD, 0}, 45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 45 47 {0, 0} 46 48 }; 47 49 48 static usb_hid_subdriver_usage_t path_mouse 2[] = {49 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_ X},50 static usb_hid_subdriver_usage_t path_mouse[] = { 51 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE}, 50 52 {0, 0} 51 53 }; 52 54 53 static usb_hid_subdriver_usage_t lgtch_path[] = {54 { 0xc, 0},55 static usb_hid_subdriver_usage_t multim_key_path[] = { 56 {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL}, 55 57 {0, 0} 56 58 }; … … 60 62 path_kbd, 61 63 -1, 62 USB_HID_PATH_COMPARE_END 63 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 64 USB_HID_PATH_COMPARE_BEGIN, 64 65 -1, 65 66 -1, … … 73 74 }, 74 75 { 75 lgtch_path,76 multim_key_path, 76 77 1, 77 USB_HID_PATH_COMPARE_END 78 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 79 0x046d, 80 0xc30e, 78 USB_HID_PATH_COMPARE_BEGIN, 79 -1, 80 -1, 81 81 { 82 .init = usb_ lgtch_init,83 .deinit = usb_ lgtch_deinit,84 .poll = usb_ lgtch_polling_callback,82 .init = usb_multimedia_init, 83 .deinit = usb_multimedia_deinit, 84 .poll = usb_multimedia_polling_callback, 85 85 .poll_end = NULL 86 86 } 87 87 }, 88 88 { 89 path_mouse 2,89 path_mouse, 90 90 -1, 91 USB_HID_PATH_COMPARE_END 92 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 91 USB_HID_PATH_COMPARE_BEGIN, 93 92 -1, 94 93 -1, … … 100 99 } 101 100 }, 102 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL }}101 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}} 103 102 }; 104 103 -
uspace/drv/usbhid/usbhid.c
r160b75e r293de44 203 203 204 204 usb_log_debug("Compare flags: %d\n", mapping->compare); 205 size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 206 mapping->compare); 205 // size_t size = usb_hid_report_size(hid_dev->report, 0, 206 // USB_HID_REPORT_TYPE_INPUT); 207 size_t size = 0; 208 usb_hid_report_field_t *field = usb_hid_report_get_sibling (hid_dev->report, 209 NULL, usage_path, mapping->compare, USB_HID_REPORT_TYPE_INPUT); 210 while(field != NULL) { 211 size++; 212 field = usb_hid_report_get_sibling (hid_dev->report, 213 field, usage_path, mapping->compare, 214 USB_HID_REPORT_TYPE_INPUT); 215 } 216 207 217 usb_log_debug("Size of the input report: %zuB\n", size); 208 209 218 usb_hid_report_path_free(usage_path); 210 219 … … 457 466 if (hid_dev->subdrivers[i].init != NULL) { 458 467 usb_log_debug("Initializing subdriver %d.\n",i); 459 rc = hid_dev->subdrivers[i].init(hid_dev); 468 rc = hid_dev->subdrivers[i].init(hid_dev, 469 &hid_dev->subdrivers[i].data); 460 470 if (rc != EOK) { 461 471 usb_log_warning("Failed to initialize" … … 522 532 for (i = 0; i < hid_dev->subdriver_count; ++i) { 523 533 if (hid_dev->subdrivers[i].poll != NULL 524 && hid_dev->subdrivers[i].poll(hid_dev, buffer,525 buffer_size)) {534 && hid_dev->subdrivers[i].poll(hid_dev, 535 hid_dev->subdrivers[i].data, buffer, buffer_size)) { 526 536 cont = true; 527 537 } … … 546 556 for (i = 0; i < hid_dev->subdriver_count; ++i) { 547 557 if (hid_dev->subdrivers[i].poll_end != NULL) { 548 hid_dev->subdrivers[i].poll_end(hid_dev, reason); 558 hid_dev->subdrivers[i].poll_end(hid_dev, 559 hid_dev->subdrivers[i].data, reason); 549 560 } 550 561 } … … 627 638 for (i = 0; i < (*hid_dev)->subdriver_count; ++i) { 628 639 if ((*hid_dev)->subdrivers[i].deinit != NULL) { 629 (*hid_dev)->subdrivers[i].deinit(*hid_dev); 640 (*hid_dev)->subdrivers[i].deinit(*hid_dev, 641 (*hid_dev)->subdrivers[i].data); 630 642 } 631 643 } -
uspace/drv/usbhid/usbhid.h
r160b75e r293de44 48 48 struct usb_hid_dev; 49 49 50 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *); 51 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *); 52 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, uint8_t *, size_t); 53 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, bool reason); 50 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *, void **data); 51 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *, void *data); 52 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, void *data, uint8_t *, 53 size_t); 54 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, void *data, 55 bool reason); 54 56 55 57 // TODO: add function and class name?? … … 63 65 /** Function to be called when polling ends. */ 64 66 usb_hid_driver_poll_ended poll_end; 67 /** Arbitrary data needed by the subdriver. */ 68 void *data; 65 69 } usb_hid_subdriver_t; 66 70 … … 72 76 /** Structure holding generic USB device information. */ 73 77 usb_device_t *usb_dev; 74 75 /** @todo What is this actually? */76 ddf_dev_ops_t ops;77 78 78 79 /** Index of the polling pipe in usb_hid_endpoints array. */ … … 97 98 98 99 size_t input_report_size; 99 100 /** Arbitrary data (e.g. a special structure for handling keyboard). */101 void *data;102 100 } usb_hid_dev_t; 103 101 -
uspace/lib/usbdev/src/hub.c
r160b75e r293de44 41 41 #include <assert.h> 42 42 #include <usb/debug.h> 43 #include <time.h> 43 44 44 45 /** How much time to wait between attempts to register endpoint 0:0. … … 218 219 219 220 int rc; 221 struct timeval start_time; 222 223 rc = gettimeofday(&start_time, NULL); 224 if (rc != EOK) { 225 return rc; 226 } 220 227 221 228 rc = usb_hc_connection_open(&hc_conn); … … 264 271 } 265 272 } while (rc != EOK); 273 struct timeval end_time; 274 275 rc = gettimeofday(&end_time, NULL); 276 if (rc != EOK) { 277 goto leave_release_default_address; 278 } 279 280 /* According to the USB spec part 9.1.2 host allows 100ms time for 281 * the insertion process to complete. According to 7.1.7.1 this is the 282 * time between attach detected and port reset. However, the setup done 283 * above might use much of this time so we should only wait to fill 284 * up the 100ms quota*/ 285 suseconds_t elapsed = tv_sub(&end_time, &start_time); 286 if (elapsed < 100000) { 287 async_usleep(100000 - elapsed); 288 } 266 289 267 290 /* … … 273 296 goto leave_release_default_address; 274 297 } 298 /* USB spec 7.1.7.1: The USB System Software guarantees a minimum of 299 * 10ms for reset recovery. Device response to any bus transactions 300 * addressed to the default device address during the reset recovery 301 * time is undefined. 302 */ 303 async_usleep(10000); 275 304 276 305 rc = usb_pipe_probe_default_control(&ctrl_pipe); -
uspace/lib/usbhid/include/usb/hid/hid_report_items.h
r160b75e r293de44 46 46 #define USB_HID_ITEM_IS_LONG(data) (data == 0xFE) 47 47 48 49 /** 50 * Extended usage macros 51 */ 52 #define USB_HID_IS_EXTENDED_USAGE(usage) ((usage & 0xFFFF0000) != 0) 53 #define USB_HID_EXTENDED_USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16) 54 #define USB_HID_EXTENDED_USAGE(usage) (usage & 0xFFFF) 48 55 49 56 /** -
uspace/lib/usbhid/include/usb/hid/hidparser.h
r160b75e r293de44 51 51 size_t size, uint8_t *report_id); 52 52 53 /** */54 size_t usb_hid_report_input_length(const usb_hid_report_t *report,55 usb_hid_report_path_t *path, int flags);56 57 53 /* 58 54 * Output report parser functions … … 65 61 void usb_hid_report_output_free(uint8_t *output); 66 62 67 /** Returns size of output for given usage path*/68 size_t usb_hid_report_ output_size(usb_hid_report_t *report,69 usb_hid_report_path_t *path, int flags);63 /** Returns size of report in items */ 64 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 65 usb_hid_report_type_t type); 70 66 71 67 /** Makes the output report buffer by translated given data */ -
uspace/lib/usbhid/include/usb/hid/hidtypes.h
r160b75e r293de44 39 39 #include <adt/list.h> 40 40 41 #define USB_HID_MAX_USAGES 2041 #define USB_HID_MAX_USAGES 0xffff 42 42 43 43 #define USB_HID_UINT32_TO_INT32(x, size) ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1))) … … 92 92 int32_t physical_minimum; 93 93 int32_t physical_maximum; 94 uint32_t usage_minimum;95 uint32_t usage_maximum;94 int32_t usage_minimum; 95 int32_t usage_maximum; 96 96 uint32_t unit; 97 97 uint32_t unit_exponent; 98 98 99 uint32_t *usages; 100 size_t usages_count; 99 101 100 102 int32_t value; … … 121 123 122 124 /** */ 123 uint32_t usage_minimum;124 /** */ 125 uint32_t usage_maximum;125 int32_t usage_minimum; 126 /** */ 127 int32_t usage_maximum; 126 128 /** */ 127 129 int32_t logical_minimum; -
uspace/lib/usbhid/include/usb/hid/usages/core.h
r160b75e r293de44 67 67 } usb_hidut_usage_generic_desktop_t; 68 68 69 typedef enum { 70 USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL = 1 71 } usb_hidut_usage_consumer_t; 72 69 73 70 74 #endif -
uspace/lib/usbhid/src/hiddescriptor.c
r160b75e r293de44 64 64 { 65 65 /* find or append current collection path to the list */ 66 link_t *path_it = report->collection_paths.next; 66 //link_t *path_it = report->collection_paths.next; 67 link_t *path_it = report->collection_paths.prev->next; 67 68 usb_hid_report_path_t *path = NULL; 69 70 68 71 while(path_it != &report->collection_paths) { 69 72 path = list_get_instance(path_it, usb_hid_report_path_t, link); … … 116 119 int i; 117 120 118 for(i=0; i<report_item->usages_count; i++){ 119 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]); 120 } 121 121 uint32_t *usages; 122 int usages_used=0; 123 if(report_item->usages_count > 0){ 124 usages = malloc(sizeof(int32_t) * report_item->usages_count); 125 memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count); 126 } 127 else { 128 usages = NULL; 129 } 130 122 131 usb_hid_report_path_t *path = report_item->usage_path; 123 132 for(i=0; i<report_item->count; i++){ … … 133 142 field->physical_maximum = report_item->physical_maximum; 134 143 135 field->usage_minimum = report_item->usage_minimum; 136 field->usage_maximum = report_item->usage_maximum; 137 if(report_item->extended_usage_page != 0){ 138 field->usage_page = report_item->extended_usage_page; 144 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){ 145 /* 146 Store usage array. The Correct Usage Page and Usage is depending 147 on data in report and will be filled later 148 */ 149 field->usage = 0; 150 field->usage_page = 0; //report_item->usage_page; 151 152 field->usages_count = report_item->usages_count; 153 field->usages = usages; 154 usages_used = 1; 139 155 } 140 156 else { 141 field->usage_page = report_item->usage_page; 142 } 143 144 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 145 uint32_t usage; 146 if(i < report_item->usages_count){ 157 158 /* Fill the correct Usage and Usage Page */ 159 int32_t usage; 160 if(i < report_item->usages_count) { 147 161 usage = report_item->usages[i]; 148 162 } … … 151 165 } 152 166 153 154 if((usage & 0xFFFF0000) != 0){ 155 field->usage_page = (usage >> 16); 156 field->usage = (usage & 0xFFFF); 167 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 168 field->usage = USB_HID_EXTENDED_USAGE(usage); 169 field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage); 157 170 } 158 171 else { 172 // should not occur 159 173 field->usage = usage; 160 } 161 162 163 } 164 165 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) { 166 field->usage = report_item->usage_minimum + i; 174 field->usage_page = report_item->usage_page; 175 } 167 176 } 168 177 … … 209 218 } 210 219 220 // free only when not used!!! 221 if(usages && usages_used == 0) { 222 free(usages); 223 } 211 224 212 225 return EOK; … … 450 463 451 464 case USB_HID_REPORT_TAG_COLLECTION: 465 452 466 // store collection atributes 453 467 path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); … … 455 469 456 470 // set last item 457 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page); 458 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]); 471 usb_hid_report_set_last_item(usage_path, 472 USB_HID_TAG_CLASS_GLOBAL, 473 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1])); 474 usb_hid_report_set_last_item(usage_path, 475 USB_HID_TAG_CLASS_LOCAL, 476 USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1])); 459 477 460 478 // append the new one which will be set by common … … 551 569 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 552 570 { 571 int32_t extended_usage; 572 553 573 switch(tag) { 554 574 case USB_HID_REPORT_TAG_USAGE: … … 560 580 report_item->in_delimiter = INSIDE_DELIMITER_SET; 561 581 case OUTSIDE_DELIMITER_SET: 562 report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size); 582 extended_usage = ((report_item->usage_page) << 16); 583 extended_usage += usb_hid_report_tag_data_uint32(data,item_size); 584 report_item->usages[report_item->usages_count] = extended_usage; 563 585 report_item->usages_count++; 564 586 break; 565 587 } 566 588 break; 567 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 589 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 568 590 if (item_size == 3) { 569 591 // usage extended usages … … 577 599 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 578 600 if (item_size == 3) { 601 602 if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) { 603 return EINVAL; 604 } 605 579 606 // usage extended usages 580 607 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; … … 584 611 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 585 612 } 613 614 // vlozit zaznamy do pole usages 615 int32_t i; 616 for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) { 617 if(report_item->extended_usage_page) { 618 report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i; 619 } 620 else { 621 622 report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i; 623 } 624 } 625 report_item->extended_usage_page = 0; 626 586 627 break; 587 628 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: … … 663 704 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 664 705 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 706 usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count); 665 707 666 708 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 668 710 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 669 711 670 //usb_hid_print_usage_path(report_item->collection_path);712 usb_hid_print_usage_path(report_item->collection_path); 671 713 672 714 usb_log_debug("\n"); … … 700 742 usb_hid_descriptor_print_list(&report_des->report_items); 701 743 702 744 /* 703 745 link_t *path_it = report->collection_paths.next; 704 746 while(path_it != &report->collection_paths) { … … 706 748 path_it = path_it->next; 707 749 } 708 750 */ 709 751 report_it = report_it->next; 710 752 } -
uspace/lib/usbhid/src/hidparser.c
r160b75e r293de44 69 69 70 70 71 /** Returns size of report of specified report id and type in items 72 * 73 * @param parser Opaque report parser structure 74 * @param report_id 75 * @param type 76 * @return Number of items in specified report 77 */ 78 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 79 usb_hid_report_type_t type) 80 { 81 usb_hid_report_description_t *report_des; 82 83 if(report == NULL) { 84 return 0; 85 } 86 87 report_des = usb_hid_report_find_description (report, report_id, type); 88 if(report_des == NULL){ 89 return 0; 90 } 91 else { 92 return report_des->item_length; 93 } 94 } 71 95 72 96 … … 87 111 usb_hid_report_description_t *report_des; 88 112 usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT; 89 113 90 114 if(report == NULL) { 91 115 return EINVAL; … … 114 138 // array 115 139 item->value = usb_hid_translate_data(item, data); 116 item->usage = (item->value - item->physical_minimum) + item->usage_minimum; 140 141 item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]); 142 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]); 143 144 usb_hid_report_set_last_item (item->collection_path, 145 USB_HID_TAG_CLASS_GLOBAL, 146 item->usage_page); 147 usb_hid_report_set_last_item (item->collection_path, 148 USB_HID_TAG_CLASS_LOCAL, 149 item->usage); 150 117 151 } 118 152 else { … … 123 157 list_item = list_item->next; 124 158 } 125 159 126 160 return EOK; 127 161 … … 206 240 } 207 241 208 /**209 * Returns number of items in input report which are accessible by given usage path210 *211 * @param parser Opaque report descriptor structure212 * @param path Usage path specification213 * @param flags Usage path comparison flags214 * @return Number of items in input report215 */216 size_t usb_hid_report_input_length(const usb_hid_report_t *report,217 usb_hid_report_path_t *path, int flags)218 {219 220 size_t ret = 0;221 222 if(report == NULL) {223 return 0;224 }225 226 usb_hid_report_description_t *report_des;227 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);228 if(report_des == NULL) {229 return 0;230 }231 232 link_t *field_it = report_des->report_items.next;233 usb_hid_report_field_t *field;234 while(field_it != &report_des->report_items) {235 236 field = list_get_instance(field_it, usb_hid_report_field_t, link);237 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {238 239 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);240 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {241 ret++;242 }243 usb_hid_report_remove_last_item (field->collection_path);244 }245 246 field_it = field_it->next;247 }248 249 return ret;250 }251 252 242 /*** OUTPUT API **/ 253 243 … … 304 294 } 305 295 306 /** Returns size of output for given usage path307 *308 * @param parser Opaque report parser structure309 * @param path Usage path specified which items will be thought for the output310 * @param flags Flags of usage path structure comparison311 * @return Number of items matching the given usage path312 */313 size_t usb_hid_report_output_size(usb_hid_report_t *report,314 usb_hid_report_path_t *path, int flags)315 {316 size_t ret = 0;317 usb_hid_report_description_t *report_des;318 319 if(report == NULL) {320 return 0;321 }322 323 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);324 if(report_des == NULL){325 return 0;326 }327 328 link_t *field_it = report_des->report_items.next;329 usb_hid_report_field_t *field;330 while(field_it != &report_des->report_items) {331 332 field = list_get_instance(field_it, usb_hid_report_field_t, link);333 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){334 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);335 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {336 ret++;337 }338 usb_hid_report_remove_last_item (field->collection_path);339 }340 341 field_it = field_it->next;342 }343 344 return ret;345 346 }347 348 296 /** Makes the output report buffer for data given in the report structure 349 297 * … … 385 333 report_item = list_get_instance(item, usb_hid_report_field_t, link); 386 334 387 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 335 usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value); 336 337 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 388 338 389 // array 390 value = usb_hid_translate_data_reverse(report_item, report_item->value); 391 offset = report_item->offset; 392 length = report_item->size; 393 } 394 else { 395 // variable item 396 value = usb_hid_translate_data_reverse(report_item, report_item->value); 397 offset = report_item->offset; 398 length = report_item->size; 399 } 400 401 if((offset/8) == ((offset+length-1)/8)) { 402 // je to v jednom bytu 403 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) { 404 break; // TODO ErrorCode 339 // array 340 value = usb_hid_translate_data_reverse(report_item, report_item->value); 341 offset = report_item->offset; 342 length = report_item->size; 343 } 344 else { 345 // variable item 346 value = usb_hid_translate_data_reverse(report_item, report_item->value); 347 offset = report_item->offset; 348 length = report_item->size; 349 } 350 351 usb_log_debug("\ttranslated value: %x\n", value); 352 353 if((offset/8) == ((offset+length-1)/8)) { 354 // je to v jednom bytu 355 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) { 356 break; // TODO ErrorCode 357 } 358 size_t shift = 8 - offset%8 - length; 359 value = value << shift; 360 value = value & (((1 << length)-1) << shift); 361 362 uint8_t mask = 0; 363 mask = 0xff - (((1 << length) - 1) << shift); 364 buffer[offset/8] = (buffer[offset/8] & mask) | value; 365 } 366 else { 367 int i = 0; 368 uint8_t mask = 0; 369 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 370 if(i == (offset/8)) { 371 tmp_value = value; 372 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 373 tmp_value = tmp_value << (offset%8); 374 375 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 376 buffer[i] = (buffer[i] & mask) | tmp_value; 405 377 } 406 407 size_t shift = 8 - offset%8 - length; 408 409 value = value << shift; 410 value = value & (((1 << length)-1) << shift); 378 else if (i == ((offset + length -1)/8)) { 379 380 value = value >> (length - ((offset + length) % 8)); 381 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 411 382 412 uint8_t mask = 0; 413 mask = 0xff - (((1 << length) - 1) << shift); 414 buffer[offset/8] = (buffer[offset/8] & mask) | value; 415 } 416 else { 417 int i = 0; 418 uint8_t mask = 0; 419 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 420 if(i == (offset/8)) { 421 tmp_value = value; 422 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 423 tmp_value = tmp_value << (offset%8); 424 425 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 426 buffer[i] = (buffer[i] & mask) | tmp_value; 427 } 428 else if (i == ((offset + length -1)/8)) { 429 430 value = value >> (length - ((offset + length) % 8)); 431 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 432 433 mask = (1 << (length - ((offset + length) % 8))) - 1; 434 buffer[i] = (buffer[i] & mask) | value; 435 } 436 else { 437 buffer[i] = value & (0xFF << i); 438 } 383 mask = (1 << (length - ((offset + length) % 8))) - 1; 384 buffer[i] = (buffer[i] & mask) | value; 439 385 } 440 } 441 386 else { 387 buffer[i] = value & (0xFF << i); 388 } 389 } 390 } 442 391 443 392 // reset value … … 472 421 } 473 422 474 475 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) { 476 477 // variable item 478 if(item->physical_maximum == item->physical_minimum){ 479 resolution = 1; 480 } 481 else { 482 resolution = (item->logical_maximum - item->logical_minimum) / 483 ((item->physical_maximum - item->physical_minimum) * 484 (usb_pow(10,(item->unit_exponent)))); 485 } 486 487 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum; 488 } 489 else { 490 // bitmapa 491 if(value == 0) { 492 ret = 0; 493 } 494 else { 495 size_t bitmap_idx = (value - item->usage_minimum); 496 ret = 1 << bitmap_idx; 497 } 498 } 499 423 // variable item 424 if(item->physical_maximum == item->physical_minimum){ 425 resolution = 1; 426 } 427 else { 428 resolution = (item->logical_maximum - item->logical_minimum) / 429 ((item->physical_maximum - item->physical_minimum) * 430 (usb_pow(10,(item->unit_exponent)))); 431 } 432 433 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum; 434 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret); 435 500 436 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 501 437 return USB_HID_INT32_TO_UINT32(ret, item->size); 502 438 } 503 return (int32_t) ret;439 return (int32_t)0 + ret; 504 440 } 505 441 -
uspace/lib/usbhid/src/hidpath.c
r160b75e r293de44 42 42 43 43 44 #define USB_HID_SAME_USAGE(usage1, usage2) ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0)) 45 #define USB_HID_SAME_USAGE_PAGE(page1, page2) ((page1 == page2) || (page1 == 0) || (page2 == 0)) 46 44 47 /** 45 48 * Appends one item (couple of usage_path and usage) into the usage path … … 203 206 while(report_link != &report_path->head) { 204 207 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 205 if( report_item->usage_page == path_item->usage_page){208 if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page)){ 206 209 if(only_page == 0){ 207 if( report_item->usage == path_item->usage) {210 if(USB_HID_SAME_USAGE(report_item->usage, path_item->usage)) { 208 211 return EOK; 209 212 } … … 242 245 link); 243 246 244 if( (report_item->usage_page !=path_item->usage_page) ||247 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) || 245 248 ((only_page == 0) && 246 (report_item->usage !=path_item->usage))) {249 !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) { 247 250 248 251 return 1; … … 282 285 usb_hid_report_usage_path_t, 283 286 link); 284 285 if( (report_item->usage_page !=path_item->usage_page) ||287 288 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) || 286 289 ((only_page == 0) && 287 (report_item->usage !=path_item->usage))) {288 290 !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) { 291 return 1; 289 292 } else { 290 293 report_link = report_link->prev; -
uspace/lib/usbhost/src/device_keeper.c
r160b75e r293de44 158 158 } 159 159 160 /** Find devman handled assigned to USB address. 160 /** Find devman handle assigned to USB address. 161 * Intentionally refuse to find handle of default address. 161 162 * 162 163 * @param[in] instance Device keeper structure to use. … … 170 171 assert(instance); 171 172 fibril_mutex_lock(&instance->guard); 172 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {173 if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) { 173 174 fibril_mutex_unlock(&instance->guard); 174 175 return false;
Note:
See TracChangeset
for help on using the changeset viewer.