Changes in / [6bfaab5:88be3a0b] in mainline
- Files:
-
- 23 added
- 11 deleted
- 75 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r6bfaab5 r88be3a0b 7 7 *.map 8 8 *.disasm 9 *.lo10 *.la11 *.so.*12 *.so013 9 _link.ld 14 10 ./*.iso … … 57 53 ./uspace/app/klog/klog 58 54 ./uspace/app/lsusb/lsusb 59 ./uspace/app/mkbd/mkbd60 55 ./uspace/app/mkfat/mkfat 61 56 ./uspace/app/netstart/netstart -
boot/Makefile.common
r6bfaab5 r88be3a0b 157 157 $(USPACE_PATH)/app/usbinfo/usbinfo \ 158 158 $(USPACE_PATH)/app/vuhid/vuh \ 159 $(USPACE_PATH)/app/mkbd/mkbd \160 159 $(USPACE_PATH)/app/websrv/websrv 161 160 -
boot/arch/amd64/Makefile.inc
r6bfaab5 r88be3a0b 49 49 usbflbk \ 50 50 usbhub \ 51 usbkbd \ 51 52 usbhid \ 52 53 usbmast \ -
kernel/generic/src/ipc/irq.c
r6bfaab5 r88be3a0b 370 370 if (AS != irq->driver_as) \ 371 371 as_switch(AS, irq->driver_as); \ 372 printf("Copying data from address: %p.\n", va); \ 372 373 memcpy_from_uspace(&target, va, (sizeof(target))); \ 373 374 if (dstarg) \ … … 380 381 if (AS != irq->driver_as) \ 381 382 as_switch(AS, irq->driver_as); \ 383 printf("Writing data to address: %p.\n", va); \ 382 384 memcpy_to_uspace(va, &val, sizeof(val)); \ 383 385 } while (0) … … 455 457 uint32_t val; 456 458 CMD_MEM_READ(val); 459 printf("mem READ value: %x.\n", val); 457 460 break; 458 461 } -
uspace/Makefile
r6bfaab5 r88be3a0b 59 59 app/websrv \ 60 60 app/sysinfo \ 61 app/mkbd \62 61 srv/clip \ 63 62 srv/devmap \ … … 123 122 drv/uhci-rhd \ 124 123 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 \ 146 147 drv/usbhid \ 147 148 drv/usbhub \ -
uspace/Makefile.common
r6bfaab5 r88be3a0b 131 131 endif 132 132 endif 133 # Build static whenever we use libusb because that library uses134 # thread local variables135 ifneq ($(findstring usb, $(LIBS)),)136 STATIC_BUILD = y137 endif138 133 139 134 ifeq ($(STATIC_BUILD), y) -
uspace/app/lsusb/main.c
r6bfaab5 r88be3a0b 45 45 #include <devmap.h> 46 46 #include <usb/dev/hub.h> 47 #include <usb/h c.h>47 #include <usb/host.h> 48 48 49 49 #define NAME "lsusb" -
uspace/app/usbinfo/main.c
r6bfaab5 r88be3a0b 43 43 #include <devman.h> 44 44 #include <devmap.h> 45 #include <usb/ hc.h>45 #include <usb/dev/hc.h> 46 46 #include <usb/dev/pipes.h> 47 #include <usb/host.h> 48 #include <usb/driver.h> 47 49 #include "usbinfo.h" 50 51 static bool try_parse_class_and_address(const char *path, 52 devman_handle_t *out_hc_handle, usb_address_t *out_device_address) 53 { 54 size_t class_index; 55 size_t address; 56 int rc; 57 char *ptr; 58 59 rc = str_size_t(path, &ptr, 10, false, &class_index); 60 if (rc != EOK) { 61 return false; 62 } 63 if ((*ptr == ':') || (*ptr == '.')) { 64 ptr++; 65 } else { 66 return false; 67 } 68 rc = str_size_t(ptr, NULL, 10, true, &address); 69 if (rc != EOK) { 70 return false; 71 } 72 rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle); 73 if (rc != EOK) { 74 return false; 75 } 76 if (out_device_address != NULL) { 77 *out_device_address = (usb_address_t) address; 78 } 79 return true; 80 } 81 82 static bool resolve_hc_handle_and_dev_addr(const char *devpath, 83 devman_handle_t *out_hc_handle, usb_address_t *out_device_address) 84 { 85 int rc; 86 87 /* Hack for QEMU to save-up on typing ;-). */ 88 if (str_cmp(devpath, "qemu") == 0) { 89 devpath = "/hw/pci0/00:01.2/uhci-rh/usb00_a1"; 90 } 91 92 /* Hack for virtual keyboard. */ 93 if (str_cmp(devpath, "virt") == 0) { 94 devpath = "/virt/usbhc/usb00_a1/usb00_a2"; 95 } 96 97 if (try_parse_class_and_address(devpath, 98 out_hc_handle, out_device_address)) { 99 return true; 100 } 101 102 char *path = str_dup(devpath); 103 if (path == NULL) { 104 return ENOMEM; 105 } 106 107 devman_handle_t hc = 0; 108 bool hc_found = false; 109 usb_address_t addr = 0; 110 bool addr_found = false; 111 112 /* Remove suffixes and hope that we will encounter device node. */ 113 while (str_length(path) > 0) { 114 /* Get device handle first. */ 115 devman_handle_t dev_handle; 116 rc = devman_device_get_handle(path, &dev_handle, 0); 117 if (rc != EOK) { 118 free(path); 119 return false; 120 } 121 122 /* Try to find its host controller. */ 123 if (!hc_found) { 124 rc = usb_hc_find(dev_handle, &hc); 125 if (rc == EOK) { 126 hc_found = true; 127 } 128 } 129 /* Try to get its address. */ 130 if (!addr_found) { 131 addr = usb_device_get_assigned_address(dev_handle); 132 if (addr >= 0) { 133 addr_found = true; 134 } 135 } 136 137 /* Speed-up. */ 138 if (hc_found && addr_found) { 139 break; 140 } 141 142 /* Remove the last suffix. */ 143 char *slash_pos = str_rchr(path, '/'); 144 if (slash_pos != NULL) { 145 *slash_pos = 0; 146 } 147 } 148 149 free(path); 150 151 if (hc_found && addr_found) { 152 if (out_hc_handle != NULL) { 153 *out_hc_handle = hc; 154 } 155 if (out_device_address != NULL) { 156 *out_device_address = addr; 157 } 158 return true; 159 } else { 160 return false; 161 } 162 } 48 163 49 164 static void print_usage(char *app_name) … … 185 300 devman_handle_t hc_handle = 0; 186 301 usb_address_t dev_addr = 0; 187 int rc = usb_resolve_device_handle(devpath,188 &hc_handle, &dev_addr , NULL);189 if ( rc != EOK) {302 bool found = resolve_hc_handle_and_dev_addr(devpath, 303 &hc_handle, &dev_addr); 304 if (!found) { 190 305 fprintf(stderr, NAME ": device `%s' not found " 191 306 "or not of USB kind, skipping.\n", -
uspace/drv/ohci/batch.c
r6bfaab5 r88be3a0b 44 44 #include "hw_struct/transfer_descriptor.h" 45 45 46 /** OHCI specific data required for USB transfer */47 46 typedef struct ohci_transfer_batch { 48 /** Endpoint descriptor of the target endpoint. */49 47 ed_t *ed; 50 /** List of TDs needed for the transfer */51 48 td_t **tds; 52 /** Number of TDs used by the transfer */53 49 size_t td_count; 54 /** Dummy TD to be left at the ED and used by the next transfer */55 50 size_t leave_td; 56 /** Data buffer, must be accessible byb the OHCI hw. */ 57 void *device_buffer; 51 char *device_buffer; 58 52 } ohci_transfer_batch_t; 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 */ 53 68 54 static void ohci_transfer_batch_dispose(void *ohci_batch) 69 55 { … … 83 69 } 84 70 /*----------------------------------------------------------------------------*/ 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 */ 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 /*----------------------------------------------------------------------------*/ 101 75 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 102 char *buffer, size_t buffer_size, 103 const char *setup_buffer, size_t setup_size, 76 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 104 77 usbhc_iface_transfer_in_callback_t func_in, 105 78 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 121 94 ohci_transfer_batch_dispose); 122 95 123 consthcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);96 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 124 97 assert(hcd_ep); 125 98 … … 130 103 data->td_count = 131 104 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER); 132 /* Control transfer need Setup and Status stage */133 105 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 134 106 data->td_count += 2; 135 107 } 136 108 137 /* We need an extra place for TDthat is currently assigned to hcd_ep*/109 /* we need one extra place for td that is currently assigned to hcd_ep*/ 138 110 data->tds = calloc(sizeof(td_t*), data->td_count + 1); 139 111 CHECK_NULL_DISPOSE_RETURN(data->tds, 140 112 "Failed to allocate transfer descriptors.\n"); 141 113 142 /* Add TD left over by the previous transfer */143 114 data->tds[0] = hcd_ep->td; 144 115 data->leave_td = 0; … … 152 123 data->ed = hcd_ep->ed; 153 124 154 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries155 * it is, however, not capable of handling buffer that occupies more156 * than two pages (the first page is computed using start pointer, the157 * other using the end pointer) */158 125 if (setup_size + buffer_size > 0) { 159 126 data->device_buffer = malloc32(setup_size + buffer_size); … … 168 135 } 169 136 /*----------------------------------------------------------------------------*/ 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 an176 * active TD. Stop with true if an error is found. Return true if the walk177 * completes with the last TD.178 */179 137 bool batch_is_complete(usb_transfer_batch_t *instance) 180 138 { … … 182 140 ohci_transfer_batch_t *data = instance->private_data; 183 141 assert(data); 142 size_t tds = data->td_count; 184 143 usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n", 185 instance, data->td_count);144 instance, tds); 186 145 usb_log_debug("ED: %x:%x:%x:%x.\n", 187 146 data->ed->status, data->ed->td_head, data->ed->td_tail, … … 189 148 size_t i = 0; 190 149 instance->transfered_size = instance->buffer_size; 191 for (; i < data->td_count; ++i) {150 for (; i < tds; ++i) { 192 151 assert(data->tds[i] != NULL); 193 152 usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i, … … 214 173 assert(hcd_ep); 215 174 hcd_ep->td = data->tds[i]; 216 assert(i > 0); 217 for (--i;i < data->td_count; ++i) 218 instance->transfered_size -= td_remain_size(data->tds[i]); 175 if (i > 0) 176 instance->transfered_size -= td_remain_size(data->tds[i - 1]); 219 177 220 178 /* Clear possible ED HALT */ 221 179 data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 222 constuint32_t pa = addr_to_phys(hcd_ep->td);180 uint32_t pa = addr_to_phys(hcd_ep->td); 223 181 assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK)); 224 182 assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK)); … … 227 185 } 228 186 /*----------------------------------------------------------------------------*/ 229 /** Starts execution of the TD list230 *231 * @param[in] instance Batch structure to use232 */233 187 void batch_commit(usb_transfer_batch_t *instance) 234 188 { … … 239 193 } 240 194 /*----------------------------------------------------------------------------*/ 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) and246 * IN(status stage).247 */248 195 void batch_control_write(usb_transfer_batch_t *instance) 249 196 { … … 256 203 } 257 204 /*----------------------------------------------------------------------------*/ 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) and263 * OUT(status stage).264 */265 205 void batch_control_read(usb_transfer_batch_t *instance) 266 206 { … … 271 211 } 272 212 /*----------------------------------------------------------------------------*/ 273 /** Prepare interrupt in transfer.274 *275 * @param[in] instance Batch structure to use.276 *277 * Data transfer.278 */279 213 void batch_interrupt_in(usb_transfer_batch_t *instance) 280 214 { … … 285 219 } 286 220 /*----------------------------------------------------------------------------*/ 287 /** Prepare interrupt out transfer.288 *289 * @param[in] instance Batch structure to use.290 *291 * Data transfer.292 */293 221 void batch_interrupt_out(usb_transfer_batch_t *instance) 294 222 { … … 301 229 } 302 230 /*----------------------------------------------------------------------------*/ 303 /** Prepare bulk in transfer.304 *305 * @param[in] instance Batch structure to use.306 *307 * Data transfer.308 */309 231 void batch_bulk_in(usb_transfer_batch_t *instance) 310 232 { … … 315 237 } 316 238 /*----------------------------------------------------------------------------*/ 317 /** Prepare bulk out transfer.318 *319 * @param[in] instance Batch structure to use.320 *321 * Data transfer.322 */323 239 void batch_bulk_out(usb_transfer_batch_t *instance) 324 240 { … … 331 247 } 332 248 /*----------------------------------------------------------------------------*/ 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 */ 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 /*----------------------------------------------------------------------------*/ 343 257 void batch_control(usb_transfer_batch_t *instance, 344 258 usb_direction_t data_dir, usb_direction_t status_dir) … … 389 303 } 390 304 /*----------------------------------------------------------------------------*/ 391 /** Prepare generic data transfer392 *393 * @param[in] instance Batch structure to use.394 *395 * Direction is supplied by the associated ep and toggle is maintained by the396 * OHCI hw in ED.397 */398 305 void batch_data(usb_transfer_batch_t *instance) 399 306 { … … 409 316 char *buffer = instance->data_buffer; 410 317 while (remain_size > 0) { 411 const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER412 ?OHCI_TD_MAX_TRANSFER : remain_size;318 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ? 319 OHCI_TD_MAX_TRANSFER : remain_size; 413 320 414 321 td_init(data->tds[td_current], instance->ep->direction, -
uspace/drv/ohci/batch.h
r6bfaab5 r88be3a0b 41 41 #include <usb/host/batch.h> 42 42 43 #include "hw_struct/endpoint_descriptor.h" 44 43 45 usb_transfer_batch_t * batch_get( 44 46 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 45 c onst char *setup_buffer, size_t setup_size,47 char *setup_buffer, size_t setup_size, 46 48 usbhc_iface_transfer_in_callback_t func_in, 47 49 usbhc_iface_transfer_out_callback_t func_out, … … 63 65 64 66 void batch_bulk_out(usb_transfer_batch_t *instance); 67 68 ed_t * batch_ed(usb_transfer_batch_t *instance); 65 69 #endif 66 70 /** -
uspace/drv/ohci/endpoint_list.c
r6bfaab5 r88be3a0b 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h>37 36 38 37 #include "endpoint_list.h" … … 44 43 * @return Error code 45 44 * 46 * Allocates memory for internal ed_t structure.45 * Allocates memory for internal qh_t structure. 47 46 */ 48 47 int endpoint_list_init(endpoint_list_t *instance, const char *name) … … 69 68 * @param[in] instance List to lead. 70 69 * @param[in] next List to append. 71 * 72 * Does not check whether this replaces an existing list. 70 * @return Error code 71 * 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 /** Add endpoint to the list and queue. 82 * 83 * @param[in] instance List to use. 84 * @param[in] endpoint Endpoint to add. 81 /** Submit transfer endpoint to the list and queue. 82 * 83 * @param[in] instance List to use. 84 * @param[in] endpoint Transfer endpoint to submit. 85 * @return Error code 85 86 * 86 87 * The endpoint is added to the end of the list and queue. … … 98 99 /* Add to the hardware queue. */ 99 100 if (list_empty(&instance->endpoint_list)) { 100 /* There are no active EDs*/101 /* There is nothing scheduled */ 101 102 last_ed = instance->list_head; 102 103 } else { 103 /* There are active EDs, get the last one*/104 /* There is something scheduled */ 104 105 hcd_endpoint_t *last = list_get_instance( 105 106 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 */115 111 ed_append_ed(last_ed, hcd_ep->ed); 116 /* Make sure ED is updated */ 117 write_barrier();118 119 /* Add to the swlist */112 113 asm volatile ("": : :"memory"); 114 115 /* Add to the driver list */ 120 116 list_append(&hcd_ep->link, &instance->endpoint_list); 121 117 … … 133 129 } 134 130 /*----------------------------------------------------------------------------*/ 135 /** Remove endpoint from the list and queue. 136 * 137 * @param[in] instance List to use. 138 * @param[in] endpoint Endpoint to remove. 131 #if 0 132 /** Create list for finished endpoints. 133 * 134 * @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. 139 186 */ 140 187 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) … … 165 212 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed)); 166 213 prev_ed->next = hcd_ep->ed->next; 167 /* Make sure ED is updated */ 168 write_barrier(); 169 214 215 asm volatile ("": : :"memory"); 170 216 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 171 217 hcd_ep, qpos, instance->name, hcd_ep->ed->next); -
uspace/drv/ohci/endpoint_list.h
r6bfaab5 r88be3a0b 41 41 #include "utils/malloc32.h" 42 42 43 /** Structure maintains both OHCI queue and software list of active endpoints.*/44 43 typedef struct endpoint_list { 45 /** Guard against add/remove races */46 44 fibril_mutex_t guard; 47 /** OHCI hw structure at the beginning of the queue */48 45 ed_t *list_head; 49 /** Physical address of the first(dummy) ED */50 46 uint32_t list_head_pa; 51 /** Assigned name, provides nicer debug output */52 47 const char *name; 53 /** Sw list of all active EDs */54 48 link_t endpoint_list; 55 49 } endpoint_list_t; … … 59 53 * @param[in] instance Memory place to use. 60 54 * 61 * Frees memory of the internal ed_t structure.55 * Frees memory for internal qh_t structure. 62 56 */ 63 57 static inline void endpoint_list_fini(endpoint_list_t *instance) … … 68 62 69 63 int endpoint_list_init(endpoint_list_t *instance, const char *name); 64 70 65 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 66 71 67 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 68 72 69 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 70 #if 0 71 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done); 72 73 void endpoint_list_abort_all(endpoint_list_t *instance); 74 #endif 73 75 #endif 74 76 /** -
uspace/drv/ohci/hc.c
r6bfaab5 r88be3a0b 51 51 static int hc_init_memory(hc_t *instance); 52 52 /*----------------------------------------------------------------------------*/ 53 /** Announce OHCI root hub to the DDF54 *55 * @param[in] instance OHCI driver intance56 * @param[in] hub_fun DDF fuction representing OHCI root hub57 * @return Error code58 */59 53 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 60 54 { … … 62 56 assert(hub_fun); 63 57 64 const usb_address_t hub_address = 58 int ret; 59 60 usb_address_t hub_address = 65 61 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 66 62 if (hub_address <= 0) { 67 usb_log_error("Failed(%d) to get OHCI root hub address.\n", 68 hub_address); 63 usb_log_error("Failed to get OHCI root hub address.\n"); 69 64 return hub_address; 70 65 } … … 73 68 &instance->manager, hub_address, hub_fun->handle); 74 69 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, 70 ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 84 71 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 85 CHECK_RET_RELEASE(ret, "Failed(%d) to add OHCI rh endpoint 0.\n", ret); 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 } 86 77 87 78 char *match_str = NULL; 88 79 /* DDF needs heap allocated string */ 89 80 ret = asprintf(&match_str, "usb&class=hub"); 90 ret = ret > 0 ? 0 : ret; 91 CHECK_RET_RELEASE(ret, "Failed(%d) to create match-id string.\n", ret); 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 } 92 87 93 88 ret = ddf_fun_add_match_id(hub_fun, match_str, 100); 94 CHECK_RET_RELEASE(ret, "Failed(%d) add root hub match-id.\n", ret); 95 89 if (ret != EOK) { 90 usb_log_error("Failed add root hub match-id.\n"); 91 } 96 92 ret = ddf_fun_bind(hub_fun); 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 */ 93 return ret; 94 } 95 /*----------------------------------------------------------------------------*/ 111 96 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts) 112 97 { … … 136 121 #undef CHECK_RET_RETURN 137 122 123 124 // hc_init_hw(instance); 125 hc_gain_control(instance); 138 126 fibril_mutex_initialize(&instance->guard); 139 hc_gain_control(instance);140 127 141 128 rh_init(&instance->rh, instance->registers); … … 150 137 } 151 138 /*----------------------------------------------------------------------------*/ 152 /** Create end register endpoint structures153 *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 code164 */165 139 int hc_add_endpoint( 166 140 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, … … 220 194 } 221 195 /*----------------------------------------------------------------------------*/ 222 /** Dequeue and delete endpoint structures223 *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 code229 */230 196 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 231 197 usb_endpoint_t endpoint, usb_direction_t direction) … … 278 244 } 279 245 /*----------------------------------------------------------------------------*/ 280 /** Get access to endpoint structures281 *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 code288 */289 246 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 290 247 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) … … 298 255 } 299 256 /*----------------------------------------------------------------------------*/ 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 */306 257 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 307 258 { … … 310 261 assert(batch->ep); 311 262 312 /* Check for root hub communication */263 /* check for root hub communication */ 313 264 if (batch->ep->address == instance->rh.address) { 314 265 return rh_request(&instance->rh, batch); … … 318 269 list_append(&batch->link, &instance->pending_batches); 319 270 batch_commit(batch); 320 321 /* Control and bulk schedules need a kick to start working */ 322 switch (batch->ep->transfer_type) 323 { 271 switch (batch->ep->transfer_type) { 324 272 case USB_TRANSFER_CONTROL: 325 273 instance->registers->command_status |= CS_CLF; … … 331 279 break; 332 280 } 281 333 282 fibril_mutex_unlock(&instance->guard); 334 283 return EOK; 335 284 } 336 285 /*----------------------------------------------------------------------------*/ 337 /** Interrupt handling routine338 *339 * @param[in] instance OHCI hc driver structure.340 * @param[in] status Value of the status register at the time of interrupt.341 */342 286 void hc_interrupt(hc_t *instance, uint32_t status) 343 287 { … … 348 292 if (status & I_RHSC) 349 293 rh_interrupt(&instance->rh); 294 350 295 351 296 if (status & I_WDH) { … … 371 316 fibril_mutex_unlock(&instance->guard); 372 317 } 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 */ 318 } 319 /*----------------------------------------------------------------------------*/ 385 320 int interrupt_emulator(hc_t *instance) 386 321 { … … 391 326 instance->registers->interrupt_status = status; 392 327 hc_interrupt(instance, status); 393 async_usleep( 10000);328 async_usleep(50000); 394 329 } 395 330 return EOK; 396 331 } 397 332 /*----------------------------------------------------------------------------*/ 398 /** Turn off any (BIOS)driver that might be in control of the device.399 *400 * @param[in] instance OHCI hc driver structure.401 */402 333 void hc_gain_control(hc_t *instance) 403 334 { … … 449 380 } 450 381 /*----------------------------------------------------------------------------*/ 451 /** OHCI hw initialization routine.452 *453 * @param[in] instance OHCI hc driver structure.454 */455 382 void hc_start_hw(hc_t *instance) 456 383 { … … 520 447 } 521 448 /*----------------------------------------------------------------------------*/ 522 /** Initialize schedule queues523 *524 * @param[in] instance OHCI hc driver structure525 * @return Error code526 */527 449 int hc_init_transfer_lists(hc_t *instance) 528 450 { 529 451 assert(instance); 452 530 453 #define SETUP_ENDPOINT_LIST(type) \ 531 454 do { \ … … 535 458 usb_log_error("Failed(%d) to setup %s endpoint list.\n", \ 536 459 ret, name); \ 537 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \460 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \ 538 461 endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \ 539 462 endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \ 540 463 endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \ 541 return ret; \542 464 } \ 543 465 } while (0) … … 554 476 } 555 477 /*----------------------------------------------------------------------------*/ 556 /** Initialize memory structures used by the OHCI hcd.557 *558 * @param[in] instance OHCI hc driver structure.559 * @return Error code.560 */561 478 int hc_init_memory(hc_t *instance) 562 479 { … … 565 482 bzero(&instance->rh, sizeof(instance->rh)); 566 483 /* Init queues */ 567 const int ret = hc_init_transfer_lists(instance); 568 if (ret != EOK) { 569 return ret; 570 } 484 hc_init_transfer_lists(instance); 571 485 572 486 /*Init HCCA */ … … 588 502 /* Init interrupt code */ 589 503 instance->interrupt_code.cmds = instance->interrupt_commands; 590 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;591 504 { 592 505 /* Read status register */ … … 608 521 instance->interrupt_commands[2].srcarg = 2; 609 522 610 /* Write -clean status register */523 /* Write clean status register */ 611 524 instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32; 612 525 instance->interrupt_commands[3].srcarg = 1; … … 616 529 /* Accept interrupt */ 617 530 instance->interrupt_commands[4].cmd = CMD_ACCEPT; 531 532 instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS; 618 533 } 619 534 -
uspace/drv/ohci/hc.h
r6bfaab5 r88be3a0b 53 53 #define OHCI_NEEDED_IRQ_COMMANDS 5 54 54 55 /** Main OHCI drier structure */56 55 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 */63 56 ohci_regs_t *registers; 64 /** Host controller communication area structure */65 57 hcca_t *hcca; 66 58 67 /** Transfer schedules */ 59 usb_address_t rh_address; 60 rh_t rh; 61 68 62 endpoint_list_t lists[4]; 69 /** List of active transfers */70 63 link_t pending_batches; 71 64 72 /** Fibril for periodic checks if interrupts can't be used */ 65 usb_device_keeper_t manager; 66 usb_endpoint_manager_t ep_manager; 73 67 fid_t interrupt_emulator; 74 75 /** Guards schedule and endpoint manipulation */76 68 fibril_mutex_t guard; 77 69 … … 81 73 /** Commands that form interrupt code */ 82 74 irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS]; 83 84 /** USB hub emulation structure */85 rh_t rh;86 75 } hc_t; 87 76 88 77 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 78 89 79 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 80 90 81 void hc_start_hw(hc_t *instance); 91 82 … … 94 85 * @param[in] instance Host controller structure to use. 95 86 */ 96 static inline void hc_fini(hc_t *instance) 97 { /* TODO: implement*/ }; 87 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 98 88 99 89 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep, 100 90 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 101 91 size_t max_packet_size, size_t size, unsigned interval); 92 102 93 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 103 94 usb_endpoint_t endpoint, usb_direction_t direction); 95 104 96 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 105 97 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw); 106 98 107 99 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 100 108 101 void hc_interrupt(hc_t *instance, uint32_t status); 109 102 … … 114 107 */ 115 108 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 116 { return fun->driver_data; }109 { return (hc_t*)fun->driver_data; } 117 110 #endif 118 111 /** -
uspace/drv/ohci/hcd_endpoint.c
r6bfaab5 r88be3a0b 35 35 #include "hcd_endpoint.h" 36 36 37 /** Callback to set toggle on ED.38 *39 * @param[in] hcd_ep hcd endpoint structure40 * @param[in] toggle new value of toggle bit41 */42 37 static void hcd_ep_toggle_set(void *hcd_ep, int toggle) 43 38 { … … 47 42 ed_toggle_set(instance->ed, toggle); 48 43 } 49 /*----------------------------------------------------------------------------*/50 /** Callback to get value of toggle bit.51 *52 * @param[in] hcd_ep hcd endpoint structure53 * @return Current value of toggle bit.54 */55 44 static int hcd_ep_toggle_get(void *hcd_ep) 56 45 { … … 60 49 return ed_toggle_get(instance->ed); 61 50 } 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 */ 51 52 68 53 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep) 69 54 { … … 93 78 } 94 79 /*----------------------------------------------------------------------------*/ 95 /** Disposes assigned hcd endpoint structure 96 * 97 * @param[in] ep USBD endpoint structure 98 */ 80 hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep) 81 { 82 assert(ep); 83 return ep->hc_data.data; 84 } 85 /*----------------------------------------------------------------------------*/ 99 86 void hcd_endpoint_clear(endpoint_t *ep) 100 87 { -
uspace/drv/ohci/hcd_endpoint.h
r6bfaab5 r88be3a0b 37 37 #include <assert.h> 38 38 #include <adt/list.h> 39 39 40 #include <usb/host/endpoint.h> 40 41 … … 42 43 #include "hw_struct/transfer_descriptor.h" 43 44 44 /** Connector structure linking ED to to prepared TD. */45 45 typedef struct hcd_endpoint { 46 /** OHCI endpoint descriptor */47 46 ed_t *ed; 48 /** Currently enqueued transfer descriptor */49 47 td_t *td; 50 /** Linked list used by driver software */51 48 link_t link; 52 49 } hcd_endpoint_t; 53 50 54 51 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep); 52 53 hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep); 54 55 55 void hcd_endpoint_clear(endpoint_t *ep); 56 57 /** Get and convert assigned hcd_endpoint_t structure58 * @param[in] ep USBD endpoint structure.59 * @return Pointer to assigned hcd endpoint structure60 */61 static inline hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep)62 {63 assert(ep);64 return ep->hc_data.data;65 }66 67 56 #endif 68 57 /** -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
r6bfaab5 r88be3a0b 44 44 assert(instance); 45 45 bzero(instance, sizeof(td_t)); 46 instance-> status = 046 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
r6bfaab5 r88be3a0b 41 41 #include "completion_codes.h" 42 42 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) 43 /* OHCI TDs can handle up to 8KB buffers */ 44 #define OHCI_TD_MAX_TRANSFER (8 * 1024) 47 45 48 46 typedef struct td { -
uspace/drv/ohci/ohci_regs.h
r6bfaab5 r88be3a0b 36 36 #include <stdint.h> 37 37 38 /** OHCI memory mapped registers structure */ 39 typedef struct ohci_regs{38 typedef struct ohci_regs 39 { 40 40 const volatile uint32_t revision; 41 41 volatile uint32_t control; -
uspace/drv/uhci-hcd/Makefile
r6bfaab5 r88be3a0b 48 48 root_hub.c \ 49 49 hw_struct/transfer_descriptor.c \ 50 utils/slab.c \ 50 51 pci.c \ 51 52 batch.c -
uspace/drv/uhci-hcd/batch.c
r6bfaab5 r88be3a0b 45 45 #define DEFAULT_ERROR_COUNT 3 46 46 47 /** UHCI specific data required for USB transfer */48 47 typedef struct uhci_transfer_batch { 49 /** Queue head50 * This QH is used to maintain UHCI schedule structure and the element51 * pointer points to the first TD of this batch.52 */53 48 qh_t *qh; 54 /** List of TDs needed for the transfer */55 49 td_t *tds; 56 /** Number of TDs used by the transfer */50 void *device_buffer; 57 51 size_t td_count; 58 /** Data buffer, must be accessible by the UHCI hw */59 void *device_buffer;60 52 } uhci_transfer_batch_t; 61 53 /*----------------------------------------------------------------------------*/ 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 62 63 static void batch_control(usb_transfer_batch_t *instance, 63 64 usb_packet_id data_stage, usb_packet_id status_stage); 64 65 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid); 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 /*----------------------------------------------------------------------------*/ 66 78 67 /** Allocate memory and initialize internal data structure. 79 68 * … … 95 84 */ 96 85 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 97 char *buffer, size_t buffer_size, 98 const char* setup_buffer, size_t setup_size, 86 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 99 87 usbhc_iface_transfer_in_callback_t func_in, 100 88 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 185 173 instance->error = td_status(&data->tds[i]); 186 174 if (instance->error != EOK) { 187 usb_log_debug("Batch(%p) found error TD(%zu):%" 188 PRIx32 ".\n",instance, i, data->tds[i].status);175 usb_log_debug("Batch(%p) found error TD(%zu):%" PRIx32 ".\n", 176 instance, i, data->tds[i].status); 189 177 td_print_status(&data->tds[i]); 190 178 … … 409 397 /*----------------------------------------------------------------------------*/ 410 398 /** Provides access to QH data structure. 411 *412 399 * @param[in] instance Batch pointer to use. 413 400 * @return Pointer to the QH used by the batch. -
uspace/drv/uhci-hcd/batch.h
r6bfaab5 r88be3a0b 35 35 #define DRV_UHCI_BATCH_H 36 36 37 #include <usbhc_iface.h> 38 #include <usb/usb.h> 39 #include <usb/host/device_keeper.h> 40 #include <usb/host/endpoint.h> 37 41 #include <usb/host/batch.h> 38 42 … … 41 45 usb_transfer_batch_t * batch_get( 42 46 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 43 c onst char *setup_buffer, size_t setup_size,47 char *setup_buffer, size_t setup_size, 44 48 usbhc_iface_transfer_in_callback_t func_in, 45 49 usbhc_iface_transfer_out_callback_t func_out, … … 51 55 52 56 void batch_control_write(usb_transfer_batch_t *instance); 57 53 58 void batch_control_read(usb_transfer_batch_t *instance); 54 59 55 60 void batch_interrupt_in(usb_transfer_batch_t *instance); 61 56 62 void batch_interrupt_out(usb_transfer_batch_t *instance); 57 63 58 64 void batch_bulk_in(usb_transfer_batch_t *instance); 65 59 66 void batch_bulk_out(usb_transfer_batch_t *instance); 60 67 -
uspace/drv/uhci-hcd/hc.c
r6bfaab5 r88be3a0b 39 39 #include <usb/debug.h> 40 40 #include <usb/usb.h> 41 #include <usb/ddfiface.h> 42 #include <usb_iface.h> 41 43 42 44 #include "hc.h" … … 55 57 static int hc_debug_checker(void *arg); 56 58 /*----------------------------------------------------------------------------*/ 57 /** Initialize UHCI hc driver structure59 /** Initialize UHCI hcd driver structure 58 60 * 59 61 * @param[in] instance Memory place to initialize. … … 83 85 /* allow access to hc control registers */ 84 86 regs_t *io; 85 ret = pio_enable(regs, reg_size, (void 87 ret = pio_enable(regs, reg_size, (void**)&io); 86 88 CHECK_RET_RETURN(ret, 87 89 "Failed(%d) to gain access to registers at %p: %s.\n", … … 141 143 } 142 144 143 constuint16_t status = pio_read_16(®isters->usbcmd);145 uint16_t status = pio_read_16(®isters->usbcmd); 144 146 if (status != 0) 145 147 usb_log_warning("Previous command value: %x.\n", status); … … 210 212 /* Init USB frame list page*/ 211 213 instance->frame_list = get_page(); 212 ret = instance ->frame_list? EOK : ENOMEM;214 ret = instance ? EOK : ENOMEM; 213 215 CHECK_RET_RETURN(ret, "Failed to get frame list page.\n"); 214 216 usb_log_debug("Initialized frame list at %p.\n", instance->frame_list); … … 275 277 &instance->transfers_control_slow); 276 278 277 /*FSBR, This feature is not needed (adds no benefit) and is supposedly 278 * buggy on certain hw, enable at your own risk. */ 279 /*FSBR*/ 279 280 #ifdef FSBR 280 281 transfer_list_set_next(&instance->transfers_bulk_full, … … 427 428 } 428 429 429 constuintptr_t frame_list =430 uintptr_t frame_list = 430 431 pio_read_32(&instance->registers->flbaseadd) & ~0xfff; 431 432 if (frame_list != addr_to_phys(instance->frame_list)) { -
uspace/drv/uhci-hcd/hc.h
r6bfaab5 r88be3a0b 37 37 38 38 #include <fibril.h> 39 #include <fibril_synch.h> 40 #include <adt/list.h> 39 41 #include <ddi.h> 40 42 43 #include <usbhc_iface.h> 41 44 #include <usb/host/device_keeper.h> 42 45 #include <usb/host/usb_endpoint_manager.h> 43 #include <usb/host/batch.h>44 46 47 #include "batch.h" 45 48 #include "transfer_list.h" 46 49 … … 92 95 #define UHCI_NEEDED_IRQ_COMMANDS 5 93 96 94 /* * Main UHCIdriver structure */97 /* Main HC driver structure */ 95 98 typedef struct hc { 96 99 /** USB bus driver, devices and addresses */ … … 151 154 */ 152 155 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 153 { 154 assert(fun); 155 return fun->driver_data; 156 } 156 { return (hc_t*)fun->driver_data; } 157 157 #endif 158 158 /** -
uspace/drv/uhci-hcd/iface.c
r6bfaab5 r88be3a0b 39 39 40 40 #include "iface.h" 41 #include "batch.h"42 41 #include "hc.h" 43 42 … … 123 122 return EOK; 124 123 } 125 /*----------------------------------------------------------------------------*/ 124 126 125 /** Find device handle by address interface function. 127 126 * … … 137 136 hc_t *hc = fun_to_hc(fun); 138 137 assert(hc); 139 constbool found =138 bool found = 140 139 usb_device_keeper_find_by_address(&hc->manager, address, handle); 141 140 return found ? EOK : ENOENT; 142 141 } 142 143 143 /*----------------------------------------------------------------------------*/ 144 144 /** Release address interface function … … 164 164 size_t max_packet_size, unsigned int interval) 165 165 { 166 assert(fun);167 166 hc_t *hc = fun_to_hc(fun); 168 167 assert(hc); … … 184 183 usb_endpoint_t endpoint, usb_direction_t direction) 185 184 { 186 assert(fun);187 185 hc_t *hc = fun_to_hc(fun); 188 186 assert(hc); … … 213 211 if (ret != EOK) 214 212 return ret; 215 assert(batch);216 assert(hc);217 213 batch_interrupt_out(batch); 218 214 ret = hc_schedule(hc, batch); … … 243 239 if (ret != EOK) 244 240 return ret; 245 assert(batch);246 assert(hc);247 241 batch_interrupt_in(batch); 248 242 ret = hc_schedule(hc, batch); … … 273 267 if (ret != EOK) 274 268 return ret; 275 assert(batch);276 assert(hc);277 269 batch_bulk_out(batch); 278 270 ret = hc_schedule(hc, batch); … … 303 295 if (ret != EOK) 304 296 return ret; 305 assert(batch);306 assert(hc);307 297 batch_bulk_in(batch); 308 298 ret = hc_schedule(hc, batch); … … 337 327 if (ret != EOK) 338 328 return ret; 339 assert(batch);340 assert(hc);341 329 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 342 330 batch_control_write(batch); … … 372 360 if (ret != EOK) 373 361 return ret; 374 assert(batch);375 assert(hc);376 362 batch_control_read(batch); 377 363 ret = hc_schedule(hc, batch); -
uspace/drv/uhci-hcd/pci.c
r6bfaab5 r88be3a0b 52 52 * @return Error code. 53 53 */ 54 int pci_get_my_registers( constddf_dev_t *dev,54 int pci_get_my_registers(ddf_dev_t *dev, 55 55 uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no) 56 56 { 57 assert(dev); 58 assert(io_reg_address); 59 assert(io_reg_size); 60 assert(irq_no); 57 assert(dev != NULL); 61 58 62 59 int parent_phone = … … 69 66 int rc = hw_res_get_resource_list(parent_phone, &hw_resources); 70 67 if (rc != EOK) { 71 async_hangup(parent_phone); 72 return rc; 68 goto leave; 73 69 } 74 70 … … 82 78 size_t i; 83 79 for (i = 0; i < hw_resources.count; i++) { 84 consthw_resource_t *res = &hw_resources.resources[i];80 hw_resource_t *res = &hw_resources.resources[i]; 85 81 switch (res->type) 86 82 { … … 103 99 } 104 100 } 105 async_hangup(parent_phone);106 101 107 if (!io_found || !irq_found) 108 return ENOENT; 102 if (!io_found || !irq_found) { 103 rc = ENOENT; 104 goto leave; 105 } 109 106 110 107 *io_reg_address = io_address; … … 112 109 *irq_no = irq; 113 110 114 return EOK; 111 rc = EOK; 112 leave: 113 async_hangup(parent_phone); 114 return rc; 115 115 } 116 116 /*----------------------------------------------------------------------------*/ … … 120 120 * @return Error code. 121 121 */ 122 int pci_enable_interrupts( constddf_dev_t *device)122 int pci_enable_interrupts(ddf_dev_t *device) 123 123 { 124 const int parent_phone = 125 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING); 126 if (parent_phone < 0) { 127 return parent_phone; 128 } 129 const bool enabled = hw_res_enable_interrupt(parent_phone); 124 int parent_phone = devman_parent_device_connect(device->handle, 125 IPC_FLAG_BLOCKING); 126 bool enabled = hw_res_enable_interrupt(parent_phone); 130 127 async_hangup(parent_phone); 131 128 return enabled ? EOK : EIO; … … 137 134 * @return Error code. 138 135 */ 139 int pci_disable_legacy( constddf_dev_t *device)136 int pci_disable_legacy(ddf_dev_t *device) 140 137 { 141 138 assert(device); 142 constint parent_phone =139 int parent_phone = 143 140 devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING); 144 141 if (parent_phone < 0) { … … 148 145 /* See UHCI design guide for these values p.45, 149 146 * write all WC bits in USB legacy register */ 150 constsysarg_t address = 0xc0;151 constsysarg_t value = 0xaf00;147 sysarg_t address = 0xc0; 148 sysarg_t value = 0xaf00; 152 149 153 constint rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),150 int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), 154 151 IPC_M_CONFIG_SPACE_WRITE_16, address, value); 155 152 async_hangup(parent_phone); -
uspace/drv/uhci-hcd/pci.h
r6bfaab5 r88be3a0b 38 38 #include <ddf/driver.h> 39 39 40 int pci_get_my_registers( constddf_dev_t *, uintptr_t *, size_t *, int *);41 int pci_enable_interrupts( constddf_dev_t *);42 int pci_disable_legacy( constddf_dev_t *);40 int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int pci_enable_interrupts(ddf_dev_t *); 42 int pci_disable_legacy(ddf_dev_t *); 43 43 44 44 #endif -
uspace/drv/uhci-hcd/root_hub.c
r6bfaab5 r88be3a0b 60 60 return ret; 61 61 } 62 assert(match_str);63 62 64 63 ret = ddf_fun_add_match_id(fun, match_str, 100); -
uspace/drv/uhci-hcd/root_hub.h
r6bfaab5 r88be3a0b 43 43 /** List of resources available to the root hub. */ 44 44 hw_resource_list_t resource_list; 45 /** The only resource in the RH resource list */45 /** The only resource in the above list */ 46 46 hw_resource_t io_regs; 47 47 } rh_t; -
uspace/drv/uhci-hcd/transfer_list.c
r6bfaab5 r88be3a0b 34 34 #include <errno.h> 35 35 #include <usb/debug.h> 36 #include <arch/barrier.h>37 38 36 39 37 #include "transfer_list.h" 40 #include "batch.h"41 38 42 39 static void transfer_list_remove_batch( … … 60 57 return ENOMEM; 61 58 } 62 constuint32_t queue_head_pa = addr_to_phys(instance->queue_head);59 uint32_t queue_head_pa = addr_to_phys(instance->queue_head); 63 60 usb_log_debug2("Transfer list %s setup with QH: %p (%#" PRIx32" ).\n", 64 61 name, instance->queue_head, queue_head_pa); … … 74 71 * @param[in] instance Memory place to use. 75 72 * 76 * Frees memory of theinternal qh_t structure.73 * Frees memory for internal qh_t structure. 77 74 */ 78 75 void transfer_list_fini(transfer_list_t *instance) … … 92 89 { 93 90 assert(instance); 94 assert(instance->queue_head);95 91 assert(next); 92 if (!instance->queue_head) 93 return; 96 94 /* Set queue_head.next to point to the follower */ 97 95 qh_set_next_qh(instance->queue_head, next->queue_head); … … 128 126 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 129 127 130 /* Make sure all data in the batch are written */131 write_barrier();132 133 128 /* keep link */ 134 129 batch_qh(batch)->next = last_qh->next; 135 130 qh_set_next_qh(last_qh, batch_qh(batch)); 136 131 137 /* Make sure the pointer is updated */ 138 write_barrier(); 139 140 /* Add to the driver's list */ 132 asm volatile ("": : :"memory"); 133 134 /* Add to the driver list */ 141 135 list_append(&batch->link, &instance->batch_list); 142 136 … … 161 155 link_t *current = instance->batch_list.next; 162 156 while (current != &instance->batch_list) { 163 link_t * constnext = current->next;157 link_t *next = current->next; 164 158 usb_transfer_batch_t *batch = 165 159 usb_transfer_batch_from_link(current); … … 183 177 fibril_mutex_lock(&instance->guard); 184 178 while (!list_empty(&instance->batch_list)) { 185 link_t * constcurrent = instance->batch_list.next;179 link_t *current = instance->batch_list.next; 186 180 usb_transfer_batch_t *batch = 187 181 usb_transfer_batch_from_link(current); … … 228 222 == addr_to_phys(batch_qh(batch))); 229 223 prev_qh->next = batch_qh(batch)->next; 230 231 /* Make sure the pointer is updated */ 232 write_barrier(); 233 224 asm volatile ("": : :"memory"); 234 225 /* Remove from the batch list */ 235 226 list_remove(&batch->link); -
uspace/drv/uhci-hcd/transfer_list.h
r6bfaab5 r88be3a0b 36 36 37 37 #include <fibril_synch.h> 38 #include <usb/host/batch.h>39 38 39 #include "batch.h" 40 40 #include "hw_struct/queue_head.h" 41 41 … … 43 43 * of currently executed transfers 44 44 */ 45 typedef struct transfer_list { 45 typedef struct transfer_list 46 { 46 47 /** Guard against multiple add/remove races */ 47 48 fibril_mutex_t guard; -
uspace/drv/uhci-hcd/uhci.c
r6bfaab5 r88be3a0b 77 77 { 78 78 assert(dev); 79 uhci_t *uhci = dev->driver_data; 80 assert(uhci); 81 hc_t *hc = &uhci->hc; 79 hc_t *hc = &((uhci_t*)dev->driver_data)->hc; 82 80 uint16_t status = IPC_GET_ARG1(*call); 83 81 assert(hc); … … 146 144 { 147 145 assert(fun); 148 rh_t *rh = fun->driver_data; 149 assert(rh); 150 return &rh->resource_list; 146 return &((rh_t*)fun->driver_data)->resource_list; 151 147 } 152 148 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/uhci.h
r6bfaab5 r88be3a0b 35 35 #ifndef DRV_UHCI_UHCI_H 36 36 #define DRV_UHCI_UHCI_H 37 #include <ddi.h> 37 38 #include <ddf/driver.h> 38 39 -
uspace/drv/uhci-hcd/utils/malloc32.h
r6bfaab5 r88be3a0b 41 41 #include <as.h> 42 42 43 #include "slab.h" 44 43 45 #define UHCI_STRCUTURES_ALIGNMENT 16 44 46 #define UHCI_REQUIRED_PAGE_SIZE 4096 … … 57 59 uintptr_t result; 58 60 const int ret = as_get_physical_mapping(addr, &result); 61 assert(ret == EOK); 62 59 63 if (ret != EOK) 60 64 return 0; … … 68 72 */ 69 73 static inline void * malloc32(size_t size) { 70 /* This works only when the host has less than 4GB of memory as 71 * physical address needs to fit into 32 bits */ 72 73 /* If we need more than one page there is no guarantee that the 74 * memory will be continuous */ 75 if (size > PAGE_SIZE) 76 return NULL; 77 /* Calculate alignment to make sure the block won't cross page 78 * boundary */ 79 size_t alignment = UHCI_STRCUTURES_ALIGNMENT; 80 while (alignment < size) 81 alignment *= 2; 82 return memalign(alignment, size); 74 if (size <= SLAB_ELEMENT_SIZE) 75 return slab_malloc_g(); 76 assert(false); 77 return memalign(UHCI_STRCUTURES_ALIGNMENT, size); 83 78 } 84 79 /*----------------------------------------------------------------------------*/ … … 90 85 if (!addr) 91 86 return; 87 if (slab_in_range_g(addr)) 88 return slab_free_g(addr); 92 89 free(addr); 93 90 } … … 100 97 { 101 98 void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE); 99 assert(free_address); /* TODO: remove this assert */ 102 100 if (free_address == 0) 103 101 return NULL; -
uspace/drv/uhci-rhd/main.c
r6bfaab5 r88be3a0b 37 37 #include <errno.h> 38 38 #include <str_error.h> 39 40 39 #include <usb_iface.h> 41 40 #include <usb/ddfiface.h> … … 46 45 #define NAME "uhci-rhd" 47 46 48 static int hc_get_my_registers( constddf_dev_t *dev,47 static int hc_get_my_registers(ddf_dev_t *dev, 49 48 uintptr_t *io_reg_address, size_t *io_reg_size); 50 49 /*----------------------------------------------------------------------------*/ … … 131 130 */ 132 131 int hc_get_my_registers( 133 constddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)132 ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size) 134 133 { 135 assert(dev );134 assert(dev != NULL); 136 135 137 constint parent_phone = devman_parent_device_connect(dev->handle,136 int parent_phone = devman_parent_device_connect(dev->handle, 138 137 IPC_FLAG_BLOCKING); 139 138 if (parent_phone < 0) { … … 142 141 143 142 hw_resource_list_t hw_resources; 144 constint ret = hw_res_get_resource_list(parent_phone, &hw_resources);143 int ret = hw_res_get_resource_list(parent_phone, &hw_resources); 145 144 if (ret != EOK) { 146 145 async_hangup(parent_phone); -
uspace/drv/uhci-rhd/port.c
r6bfaab5 r88be3a0b 36 36 #include <errno.h> 37 37 #include <str_error.h> 38 #include <time.h> 38 39 #include <async.h> 39 40 … … 81 82 * @param[in] number Port number. 82 83 * @param[in] usec Polling interval. 83 * @param[in] rh Pointer to ddf instance ofthe root hub driver.84 * @param[in] rh Pointer to ddf instance fo the root hub driver. 84 85 * @return Error code. 85 86 * … … 90 91 { 91 92 assert(port); 92 char *id_string; 93 asprintf(&id_string, "Port (%p - %u)", port, number); 94 if (id_string == NULL) { 93 asprintf(&port->id_string, "Port (%p - %u)", port, number); 94 if (port->id_string == NULL) { 95 95 return ENOMEM; 96 96 } 97 97 98 port->id_string = id_string;99 98 port->address = address; 100 99 port->number = number; … … 106 105 usb_hc_connection_initialize_from_device(&port->hc_connection, rh); 107 106 if (ret != EOK) { 108 usb_log_error("%s: failed to initialize connection to HC.", 109 port->id_string); 110 free(id_string); 107 usb_log_error("Failed to initialize connection to HC."); 111 108 return ret; 112 109 } … … 116 113 usb_log_error("%s: failed to create polling fibril.", 117 114 port->id_string); 118 free(id_string);119 115 return ENOMEM; 120 116 } … … 136 132 assert(port); 137 133 free(port->id_string); 138 / / TODO: Kill fibril here134 /* TODO: Kill fibril here */ 139 135 return; 140 136 } … … 154 150 155 151 /* Read register value */ 156 const port_status_t port_status = 157 uhci_port_read_status(instance); 152 port_status_t port_status = uhci_port_read_status(instance); 158 153 159 154 /* Print the value if it's interesting */ … … 166 161 usb_log_debug("%s: Connected change detected: %x.\n", 167 162 instance->id_string, port_status); 163 164 int rc = 165 usb_hc_connection_open(&instance->hc_connection); 166 if (rc != EOK) { 167 usb_log_error("%s: Failed to connect to HC.", 168 instance->id_string); 169 continue; 170 } 168 171 169 172 /* Remove any old device */ … … 172 175 instance->id_string); 173 176 uhci_port_remove_device(instance); 174 }175 176 int ret =177 usb_hc_connection_open(&instance->hc_connection);178 if (ret != EOK) {179 usb_log_error("%s: Failed to connect to HC.",180 instance->id_string);181 continue;182 177 } 183 178 … … 195 190 } 196 191 197 r et= usb_hc_connection_close(&instance->hc_connection);198 if (r et!= EOK) {192 rc = usb_hc_connection_close(&instance->hc_connection); 193 if (rc != EOK) { 199 194 usb_log_error("%s: Failed to disconnect.", 200 195 instance->id_string); … … 214 209 int uhci_port_reset_enable(int portno, void *arg) 215 210 { 216 uhci_port_t *port = arg; 217 assert(port); 211 uhci_port_t *port = (uhci_port_t *) arg; 218 212 219 213 usb_log_debug2("%s: new_device_enable_port.\n", port->id_string); … … 233 227 while (uhci_port_read_status(port) & STATUS_IN_RESET); 234 228 } 235 /* PIO delay, should not be longer than 3ms as the device might236 * enter suspend state. */237 229 udelay(10); 238 230 /* Enable the port. */ 239 231 uhci_port_set_enabled(port, true); 232 233 /* Reset recovery period, 234 * devices do not have to respond during this period 235 */ 236 async_usleep(10000); 240 237 return EOK; 241 238 } … … 289 286 usb_log_error("%s: Don't know how to remove device %" PRIun ".\n", 290 287 port->id_string, port->attached_device); 291 port->attached_device = 0;292 288 return ENOTSUP; 293 289 } -
uspace/drv/uhci-rhd/port.h
r6bfaab5 r88be3a0b 38 38 #include <fibril.h> 39 39 #include <ddf/driver.h> 40 #include <usb/ hc.h> /* usb_hc_connection_t */40 #include <usb/dev/hc.h> /* usb_hc_connection_t */ 41 41 42 42 typedef uint16_t port_status_t; … … 57 57 typedef struct uhci_port 58 58 { 59 c onst char *id_string;59 char *id_string; 60 60 port_status_t *address; 61 61 unsigned number; -
uspace/drv/usbhid/Makefile
r6bfaab5 r88be3a0b 57 57 generic/hiddev.c \ 58 58 mouse/mousedev.c \ 59 multimedia/multimedia.c \60 multimedia/keymap.c \59 lgtch-ultrax/lgtch-ultrax.c \ 60 lgtch-ultrax/keymap.c \ 61 61 $(STOLEN_LAYOUT_SOURCES) 62 62 -
uspace/drv/usbhid/generic/hiddev.c
r6bfaab5 r88be3a0b 62 62 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 63 63 64 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,65 size_t size, size_t *act_size, int *event_nr,unsigned int flags);64 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 65 size_t size, size_t *act_size, unsigned int flags); 66 66 67 67 static int usb_generic_hid_client_connected(ddf_fun_t *fun); 68 69 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun);70 71 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,72 size_t size, size_t *actual_size);73 68 74 69 /*----------------------------------------------------------------------------*/ … … 76 71 static usbhid_iface_t usb_generic_iface = { 77 72 .get_event = usb_generic_hid_get_event, 78 .get_event_length = usb_generic_hid_get_event_length, 79 .get_report_descriptor_length = usb_generic_get_report_descriptor_length, 80 .get_report_descriptor = usb_generic_get_report_descriptor 73 .get_event_length = usb_generic_hid_get_event_length 81 74 }; 82 75 … … 90 83 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 91 84 { 92 usb_log_debug2("Generic HID: Get event length (fun: %p, " 93 "fun->driver_data: %p.\n", fun, fun->driver_data); 94 95 if (fun == NULL || fun->driver_data == NULL) { 85 if (fun == NULL || fun->driver_data) { 96 86 return 0; 97 87 } … … 99 89 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 100 90 101 usb_log_debug2("hid_dev: %p, Max input report size (%d).\n", 102 hid_dev, hid_dev->max_input_report_size); 103 104 return hid_dev->max_input_report_size; 91 return hid_dev->input_report_size; 105 92 } 106 93 107 94 /*----------------------------------------------------------------------------*/ 108 95 109 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,110 size_t size, size_t *act_size, int *event_nr,unsigned int flags)96 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 97 size_t size, size_t *act_size, unsigned int flags) 111 98 { 112 usb_log_debug2("Generic HID: Get event.\n"); 113 114 if (fun == NULL || fun->driver_data == NULL || buffer == NULL 115 || act_size == NULL || event_nr == NULL) { 116 usb_log_debug("No function"); 99 if (fun == NULL || fun->driver_data) { 117 100 return EINVAL; 118 101 } … … 121 104 122 105 if (hid_dev->input_report_size > size) { 123 usb_log_debug("input_report_size > size (%zu, %zu)\n",124 hid_dev->input_report_size, size);125 106 return EINVAL; // TODO: other error code 126 107 } 127 108 128 109 /*! @todo This should probably be atomic. */ 129 // if (usb_hid_report_ready()) { 130 // usb_log_debug2("Report ready, size: %zu\n", 131 // hid_dev->input_report_size); 132 133 // usb_hid_report_received(); 134 // } else { 135 // memset(buffer, 0, hid_dev->input_report_size); 136 // } 137 memcpy(buffer, hid_dev->input_report, 138 hid_dev->input_report_size); 139 *act_size = hid_dev->input_report_size; 140 *event_nr = usb_hid_report_number(hid_dev); 110 if (usb_hid_report_ready()) { 111 memcpy(buffer, hid_dev->input_report, 112 hid_dev->input_report_size); 113 *act_size = hid_dev->input_report_size; 114 usb_hid_report_received(); 115 } 141 116 142 117 // clear the buffer so that it will not be received twice … … 145 120 // note that we already received this report 146 121 // report_received = true; 147 usb_log_debug2("OK\n");148 149 return EOK;150 }151 152 /*----------------------------------------------------------------------------*/153 154 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun)155 {156 usb_log_debug("Generic HID: Get report descriptor length.\n");157 158 if (fun == NULL || fun->driver_data == NULL) {159 usb_log_debug("No function");160 return EINVAL;161 }162 163 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;164 165 usb_log_debug2("hid_dev->report_desc_size = %zu\n",166 hid_dev->report_desc_size);167 168 return hid_dev->report_desc_size;169 }170 171 /*----------------------------------------------------------------------------*/172 173 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,174 size_t size, size_t *actual_size)175 {176 usb_log_debug2("Generic HID: Get report descriptor.\n");177 178 if (fun == NULL || fun->driver_data == NULL) {179 usb_log_debug("No function");180 return EINVAL;181 }182 183 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;184 185 if (hid_dev->report_desc_size > size) {186 return EINVAL; // TODO: other error code187 }188 189 memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size);190 *actual_size = hid_dev->report_desc_size;191 122 192 123 return EOK; … … 197 128 static int usb_generic_hid_client_connected(ddf_fun_t *fun) 198 129 { 199 usb_ log_debug("Generic HID: Client connected.\n");130 usb_hid_report_received(); 200 131 return EOK; 201 132 } … … 214 145 return ENOMEM; 215 146 } 216 217 fun->ops = &usb_generic_hid_ops;218 fun->driver_data = hid_dev;219 147 220 148 int rc = ddf_fun_bind(fun); … … 226 154 } 227 155 228 usb_log_debug("HID function created. Handle: %d\n", fun->handle); 156 fun->ops = &usb_generic_hid_ops; 157 fun->driver_data = hid_dev; 229 158 230 159 return EOK; … … 233 162 /*----------------------------------------------------------------------------*/ 234 163 235 int usb_generic_hid_init(usb_hid_dev_t *hid_dev , void **data)164 int usb_generic_hid_init(usb_hid_dev_t *hid_dev) 236 165 { 237 166 if (hid_dev == NULL) { … … 244 173 /*----------------------------------------------------------------------------*/ 245 174 246 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data,175 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, 247 176 uint8_t *buffer, size_t buffer_size) 248 177 { 249 usb_log_debug 2("usb_hid_polling_callback(%p, %p, %zu)\n",178 usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n", 250 179 hid_dev, buffer, buffer_size); 251 180 usb_debug_str_buffer(buffer, buffer_size, 0); -
uspace/drv/usbhid/generic/hiddev.h
r6bfaab5 r88be3a0b 48 48 /*----------------------------------------------------------------------------*/ 49 49 50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev , void **data);50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev); 51 51 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data,52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, 53 53 uint8_t *buffer, size_t buffer_size); 54 54 -
uspace/drv/usbhid/kbd/kbddev.c
r6bfaab5 r88be3a0b 252 252 sysarg_t method = IPC_GET_IMETHOD(*icall); 253 253 254 usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data; 255 if (kbd_dev == NULL) { 254 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 255 256 if (hid_dev == NULL || hid_dev->data == NULL) { 256 257 usb_log_debug("default_connection_handler: " 257 258 "Missing parameter.\n"); … … 259 260 return; 260 261 } 262 263 assert(hid_dev != NULL); 264 assert(hid_dev->data != NULL); 265 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 261 266 262 267 if (method == IPC_M_CONNECT_TO_ME) { … … 308 313 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 309 314 hid_dev->report, NULL, kbd_dev->led_path, 310 USB_HID_PATH_COMPARE_ END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,315 USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END, 311 316 USB_HID_REPORT_TYPE_OUTPUT); 312 317 313 while (field != NULL) { 314 318 while (field != NULL) { 319 315 320 if ((field->usage == USB_HID_LED_NUM_LOCK) 316 321 && (kbd_dev->mods & KM_NUM_LOCK)){ … … 329 334 330 335 field = usb_hid_report_get_sibling(hid_dev->report, field, 331 kbd_dev->led_path, 332 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 333 USB_HID_REPORT_TYPE_OUTPUT); 336 kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 337 | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT); 334 338 } 335 339 … … 658 662 * usb_hid_parse_report(). 659 663 */ 660 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev,664 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, 661 665 uint8_t *buffer, size_t actual_size) 662 666 { 663 667 assert(hid_dev->report != NULL); 664 668 assert(hid_dev != NULL); 665 assert(kbd_dev != NULL); 669 assert(hid_dev->data != NULL); 670 671 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 666 672 667 673 usb_log_debug("Calling usb_hid_parse_report() with " … … 768 774 /*----------------------------------------------------------------------------*/ 769 775 770 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev , usb_kbd_t *kbd_dev)776 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev) 771 777 { 772 778 assert(hid_dev != NULL); 773 779 assert(hid_dev->usb_dev != NULL); 774 assert(kbd_dev != NULL);775 780 776 781 /* Create the function exposed under /dev/devices. */ … … 787 792 * to the DDF function. 788 793 */ 789 fun->ops = & kbd_dev->ops;790 fun->driver_data = kbd_dev;794 fun->ops = &hid_dev->ops; 795 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 791 796 792 797 int rc = ddf_fun_bind(fun); … … 797 802 return rc; 798 803 } 799 800 usb_log_debug("%s function created. Handle: %d\n", HID_KBD_FUN_NAME,801 fun->handle);802 804 803 805 usb_log_debug("Adding DDF function to class %s...\n", … … 838 840 * @return Other value inherited from function usbhid_dev_init(). 839 841 */ 840 int usb_kbd_init(usb_hid_dev_t *hid_dev , void **data)842 int usb_kbd_init(usb_hid_dev_t *hid_dev) 841 843 { 842 844 usb_log_debug("Initializing HID/KBD structure...\n"); … … 863 865 usb_hid_report_path_set_report_id(path, 0); 864 866 865 kbd_dev->key_count = usb_hid_report_size( 866 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 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); 867 870 usb_hid_report_path_free(path); 868 871 … … 905 908 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 906 909 907 kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report, 908 0, USB_HID_REPORT_TYPE_OUTPUT); 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); 909 913 910 914 usb_log_debug("Output report size (in items): %zu\n", … … 951 955 952 956 // save the KBD device structure into the HID device structure 953 //hid_dev->data = kbd_dev; 954 *data = kbd_dev; 957 hid_dev->data = kbd_dev; 955 958 956 959 // set handler for incoming calls 957 kbd_dev->ops.default_handler = default_connection_handler;960 hid_dev->ops.default_handler = default_connection_handler; 958 961 959 962 /* … … 980 983 981 984 usb_log_debug("Creating KBD function...\n"); 982 int rc = usb_kbd_create_function(hid_dev , kbd_dev);985 int rc = usb_kbd_create_function(hid_dev); 983 986 if (rc != EOK) { 984 987 usb_kbd_free(&kbd_dev); … … 991 994 /*----------------------------------------------------------------------------*/ 992 995 993 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data,994 uint8_t *buffer,size_t buffer_size)995 { 996 if (hid_dev == NULL || buffer == NULL || data == NULL) {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) { 997 1000 // do not continue polling (???) 998 1001 return false; 999 1002 } 1000 1003 1001 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;1002 assert(kbd_dev != NULL);1003 1004 1004 // TODO: add return value from this function 1005 usb_kbd_process_data(hid_dev, kbd_dev,buffer, buffer_size);1005 usb_kbd_process_data(hid_dev, buffer, buffer_size); 1006 1006 1007 1007 return true; … … 1066 1066 /*----------------------------------------------------------------------------*/ 1067 1067 1068 void usb_kbd_deinit(usb_hid_dev_t *hid_dev , void *data)1068 void usb_kbd_deinit(usb_hid_dev_t *hid_dev) 1069 1069 { 1070 1070 if (hid_dev == NULL) { … … 1072 1072 } 1073 1073 1074 if ( data != NULL) {1075 usb_kbd_t *kbd_dev = (usb_kbd_t *) data;1074 if (hid_dev->data != NULL) { 1075 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 1076 1076 if (usb_kbd_is_initialized(kbd_dev)) { 1077 1077 usb_kbd_mark_unusable(kbd_dev); 1078 1078 } else { 1079 1079 usb_kbd_free(&kbd_dev); 1080 hid_dev->data = NULL; 1080 1081 } 1081 1082 } -
uspace/drv/usbhid/kbd/kbddev.h
r6bfaab5 r88be3a0b 83 83 int console_phone; 84 84 85 /** @todo What is this actually? */86 ddf_dev_ops_t ops;87 88 85 /** Information for auto-repeat of keys. */ 89 86 usb_kbd_repeat_t repeat; … … 120 117 /*----------------------------------------------------------------------------*/ 121 118 122 int usb_kbd_init(struct usb_hid_dev *hid_dev , void **data);119 int usb_kbd_init(struct usb_hid_dev *hid_dev); 123 120 124 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data,125 uint8_t *buffer,size_t buffer_size);121 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer, 122 size_t buffer_size); 126 123 127 124 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); … … 134 131 int type, unsigned int key); 135 132 136 void usb_kbd_deinit(struct usb_hid_dev *hid_dev , void *data);133 void usb_kbd_deinit(struct usb_hid_dev *hid_dev); 137 134 138 135 int usb_kbd_set_boot_protocol(struct usb_hid_dev *hid_dev); -
uspace/drv/usbhid/mouse/mousedev.c
r6bfaab5 r88be3a0b 122 122 sysarg_t method = IPC_GET_IMETHOD(*icall); 123 123 124 usb_ mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data;125 126 if ( mouse_dev== NULL) {124 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 125 126 if (hid_dev == NULL || hid_dev->data == NULL) { 127 127 usb_log_debug("default_connection_handler: Missing " 128 128 "parameters.\n"); … … 131 131 } 132 132 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); 133 assert(hid_dev != NULL); 134 assert(hid_dev->data != NULL); 135 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 137 136 138 137 int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) … … 146 145 "phone to mouse already set.\n"); 147 146 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", *phone);152 usb_log_debug("Console phone to mouse set ok (%d).\n", callback); 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, 227 usb_mouse_t *mouse_dev, uint8_t *buffer, 228 size_t buffer_size) 229 { 230 assert(mouse_dev != NULL); 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; 231 230 232 231 usb_log_debug2("got buffer: %s.\n", … … 234 233 235 234 if (mouse_dev->mouse_phone < 0) { 236 usb_log_ warning(NAME " No console phone.\n");237 return true;235 usb_log_error(NAME " No console phone.\n"); 236 return false; // ?? 238 237 } 239 238 … … 379 378 /*----------------------------------------------------------------------------*/ 380 379 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 380 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev) 381 { 386 382 /* Create the function exposed under /dev/devices. */ 387 383 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); … … 393 389 } 394 390 395 fun->ops = &mouse->ops; 396 fun->driver_data = mouse; // TODO: maybe change to hid_dev->data 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 397 397 398 398 int rc = ddf_fun_bind(fun); … … 431 431 * to the DDF function. 432 432 */ 433 fun->ops = & mouse->ops;434 fun->driver_data = mouse; // TODO: maybe change to hid_dev->data433 fun->ops = &hid_dev->ops; 434 fun->driver_data = hid_dev; // 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 , void **data)460 int usb_mouse_init(usb_hid_dev_t *hid_dev) 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 *data = mouse_dev;487 hid_dev->data = mouse_dev; 488 488 489 489 // set handler for incoming calls 490 // TODO: must be one for each subdriver!! 491 mouse_dev->ops.default_handler = default_connection_handler; 490 hid_dev->ops.default_handler = default_connection_handler; 492 491 493 492 // TODO: how to know if the device supports the request??? … … 495 494 // hid_dev->usb_dev->interface_no, IDLE_RATE); 496 495 497 int rc = usb_mouse_create_function(hid_dev , mouse_dev);496 int rc = usb_mouse_create_function(hid_dev); 498 497 if (rc != EOK) { 499 498 usb_mouse_free(&mouse_dev); … … 506 505 /*----------------------------------------------------------------------------*/ 507 506 508 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data,509 uint8_t *buffer,size_t buffer_size)507 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer, 508 size_t buffer_size) 510 509 { 511 510 usb_log_debug("usb_mouse_polling_callback()\n"); 512 511 usb_debug_str_buffer(buffer, buffer_size, 0); 513 512 514 if (hid_dev == NULL || data == NULL) {513 if (hid_dev == NULL) { 515 514 usb_log_error("Missing argument to the mouse polling callback." 516 515 "\n"); … … 518 517 } 519 518 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 } 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); 533 533 } 534 534 -
uspace/drv/usbhid/mouse/mousedev.h
r6bfaab5 r88be3a0b 52 52 53 53 int32_t *buttons; 54 55 ddf_dev_ops_t ops;56 54 } usb_mouse_t; 57 55 … … 65 63 /*----------------------------------------------------------------------------*/ 66 64 67 int usb_mouse_init(struct usb_hid_dev *hid_dev , void **data);65 int usb_mouse_init(struct usb_hid_dev *hid_dev); 68 66 69 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data,70 uint8_t *buffer,size_t buffer_size);67 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer, 68 size_t buffer_size); 71 69 72 void usb_mouse_deinit(struct usb_hid_dev *hid_dev , void *data);70 void usb_mouse_deinit(struct usb_hid_dev *hid_dev); 73 71 74 72 int usb_mouse_set_boot_protocol(struct usb_hid_dev *hid_dev); -
uspace/drv/usbhid/subdrivers.c
r6bfaab5 r88be3a0b 38 38 #include <usb/hid/hidpath.h> 39 39 40 #include " multimedia/multimedia.h"40 #include "lgtch-ultrax/lgtch-ultrax.h" 41 41 #include "mouse/mousedev.h" 42 #include "generic/hiddev.h"43 42 44 43 static usb_hid_subdriver_usage_t path_kbd[] = { 45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 44 {USB_HIDUT_PAGE_KEYBOARD, 0}, 47 45 {0, 0} 48 46 }; 49 47 50 static usb_hid_subdriver_usage_t path_mouse [] = {51 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_ MOUSE},48 static usb_hid_subdriver_usage_t path_mouse2[] = { 49 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_X}, 52 50 {0, 0} 53 51 }; 54 52 55 static usb_hid_subdriver_usage_t multim_key_path[] = {56 { USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL},53 static usb_hid_subdriver_usage_t lgtch_path[] = { 54 {0xc, 0}, 57 55 {0, 0} 58 56 }; 59 60 //static usb_hid_subdriver_usage_t generic_hid_key_path[] = {61 // {0, 0}62 //};63 57 64 58 const usb_hid_subdriver_mapping_t usb_hid_subdrivers[] = { 65 59 { 66 60 path_kbd, 67 0, 68 USB_HID_PATH_COMPARE_BEGIN, 61 -1, 62 USB_HID_PATH_COMPARE_END 63 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 69 64 -1, 70 65 -1, … … 78 73 }, 79 74 { 80 multim_key_path,75 lgtch_path, 81 76 1, 82 USB_HID_PATH_COMPARE_BEGIN, 83 -1, 84 -1, 77 USB_HID_PATH_COMPARE_END 78 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 79 0x046d, 80 0xc30e, 85 81 { 86 .init = usb_ multimedia_init,87 .deinit = usb_ multimedia_deinit,88 .poll = usb_ multimedia_polling_callback,82 .init = usb_lgtch_init, 83 .deinit = usb_lgtch_deinit, 84 .poll = usb_lgtch_polling_callback, 89 85 .poll_end = NULL 90 86 } 91 87 }, 92 88 { 93 path_mouse, 94 0, 95 USB_HID_PATH_COMPARE_BEGIN, 89 path_mouse2, 90 -1, 91 USB_HID_PATH_COMPARE_END 92 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 96 93 -1, 97 94 -1, … … 103 100 } 104 101 }, 105 // { 106 // generic_hid_key_path, 107 // 0, 108 // USB_HID_PATH_COMPARE_ANYWHERE, 109 // -1, 110 // -1, 111 // { 112 // .init = usb_generic_hid_init, 113 // .deinit = NULL, 114 // .poll = usb_generic_hid_polling_callback, 115 // .poll_end = NULL 116 // } 117 // }, 118 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}} 102 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}} 119 103 }; 120 104 -
uspace/drv/usbhid/usbhid.c
r6bfaab5 r88be3a0b 63 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 64 65 /** @todo What happens if this is not fibril local? */ 66 //static fibril_local bool report_number; 65 static fibril_local bool report_received; 67 66 68 67 /*----------------------------------------------------------------------------*/ … … 204 203 205 204 usb_log_debug("Compare flags: %d\n", mapping->compare); 206 // size_t size = usb_hid_report_size(hid_dev->report, 0, 207 // USB_HID_REPORT_TYPE_INPUT); 208 size_t size = 0; 209 usb_hid_report_field_t *field = usb_hid_report_get_sibling (hid_dev->report, 210 NULL, usage_path, mapping->compare, USB_HID_REPORT_TYPE_INPUT); 211 while(field != NULL) { 212 size++; 213 field = usb_hid_report_get_sibling (hid_dev->report, 214 field, usage_path, mapping->compare, 215 USB_HID_REPORT_TYPE_INPUT); 216 } 217 205 size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 206 mapping->compare); 218 207 usb_log_debug("Size of the input report: %zuB\n", size); 208 219 209 usb_hid_report_path_free(usage_path); 220 210 … … 235 225 } 236 226 237 // add one generic HID subdriver per device 238 239 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 227 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count * 240 228 sizeof(usb_hid_subdriver_t)); 241 229 if (hid_dev->subdrivers == NULL) { … … 250 238 } 251 239 252 hid_dev->subdrivers[count].init = usb_generic_hid_init; 253 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 254 hid_dev->subdrivers[count].deinit = NULL; 255 hid_dev->subdrivers[count].poll_end = NULL; 256 257 hid_dev->subdriver_count = count + 1; 240 hid_dev->subdriver_count = count; 258 241 259 242 return EOK; … … 315 298 316 299 if (matched) { 317 usb_log_debug("Subdriver matched.\n");318 300 subdrivers[count++] = &mapping->subdriver; 319 301 } … … 357 339 /*----------------------------------------------------------------------------*/ 358 340 359 static int usb_hid_init_report(usb_hid_dev_t *hid_dev)360 {361 assert(hid_dev != NULL && hid_dev->report != NULL);362 363 uint8_t report_id = 0;364 size_t size;/* = usb_hid_report_byte_size(hid_dev->report, report_id,365 USB_HID_REPORT_TYPE_INPUT);*/366 367 size_t max_size = 0;368 369 do {370 size = usb_hid_report_byte_size(hid_dev->report, report_id,371 USB_HID_REPORT_TYPE_INPUT);372 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);373 max_size = (size > max_size) ? size : max_size;374 report_id = usb_hid_get_next_report_id(hid_dev->report,375 report_id, USB_HID_REPORT_TYPE_INPUT);376 } while (report_id != 0);377 378 usb_log_debug("Max size of input report: %zu\n", max_size);379 380 hid_dev->max_input_report_size = max_size;381 assert(hid_dev->input_report == NULL);382 383 hid_dev->input_report = malloc(max_size);384 if (hid_dev->input_report == NULL) {385 return ENOMEM;386 }387 memset(hid_dev->input_report, 0, max_size);388 389 return EOK;390 }391 392 /*----------------------------------------------------------------------------*/393 394 341 usb_hid_dev_t *usb_hid_new(void) 395 342 { … … 446 393 /* Get the report descriptor and parse it. */ 447 394 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 448 hid_dev->report , &hid_dev->report_desc, &hid_dev->report_desc_size);395 hid_dev->report); 449 396 450 397 bool fallback = false; … … 510 457 if (hid_dev->subdrivers[i].init != NULL) { 511 458 usb_log_debug("Initializing subdriver %d.\n",i); 512 rc = hid_dev->subdrivers[i].init(hid_dev, 513 &hid_dev->subdrivers[i].data); 459 rc = hid_dev->subdrivers[i].init(hid_dev); 514 460 if (rc != EOK) { 515 461 usb_log_warning("Failed to initialize" … … 527 473 } 528 474 529 // save max input report size and allocate space for the report530 rc = usb_hid_init_report(hid_dev);531 if (rc != EOK) {532 usb_log_error("Failed to initialize input report buffer.\n");533 }534 535 475 return rc; 536 476 } … … 550 490 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 551 491 552 // int allocated = (hid_dev->input_report != NULL); 553 assert(hid_dev->input_report != NULL); 554 usb_log_debug("Max input report size: %zu, buffer size: %zu\n", 555 hid_dev->max_input_report_size, buffer_size); 556 assert(hid_dev->max_input_report_size >= buffer_size); 557 558 // if (/*!allocated*/ 559 // /*|| *//*hid_dev->input_report_size < buffer_size*/) { 560 // uint8_t *input_old = hid_dev->input_report; 561 // uint8_t *input_new = (uint8_t *)malloc(buffer_size); 562 563 // if (input_new == NULL) { 564 // usb_log_error("Failed to allocate space for input " 565 // "buffer. This event may not be reported\n"); 566 // memset(hid_dev->input_report, 0, 567 // hid_dev->input_report_size); 568 // } else { 569 // memcpy(input_new, input_old, 570 // hid_dev->input_report_size); 571 // hid_dev->input_report = input_new; 572 // if (allocated) { 573 // free(input_old); 574 // } 575 // usb_hid_new_report(); 576 // } 577 // } 492 int allocated = (hid_dev->input_report != NULL); 493 494 if (!allocated 495 || hid_dev->input_report_size < buffer_size) { 496 uint8_t *input_old = hid_dev->input_report; 497 uint8_t *input_new = (uint8_t *)malloc(buffer_size); 498 499 if (input_new == NULL) { 500 usb_log_error("Failed to allocate space for input " 501 "buffer. This event may not be reported\n"); 502 memset(hid_dev->input_report, 0, 503 hid_dev->input_report_size); 504 } else { 505 memcpy(input_new, input_old, 506 hid_dev->input_report_size); 507 hid_dev->input_report = input_new; 508 if (allocated) { 509 free(input_old); 510 } 511 usb_hid_new_report(); 512 } 513 } 578 514 579 515 /*! @todo This should probably be atomic. */ 580 516 memcpy(hid_dev->input_report, buffer, buffer_size); 581 517 hid_dev->input_report_size = buffer_size; 582 usb_hid_new_report(hid_dev);583 518 584 519 bool cont = false; … … 587 522 for (i = 0; i < hid_dev->subdriver_count; ++i) { 588 523 if (hid_dev->subdrivers[i].poll != NULL 589 && hid_dev->subdrivers[i].poll(hid_dev, 590 hid_dev->subdrivers[i].data, buffer,buffer_size)) {524 && hid_dev->subdrivers[i].poll(hid_dev, buffer, 525 buffer_size)) { 591 526 cont = true; 592 527 } … … 611 546 for (i = 0; i < hid_dev->subdriver_count; ++i) { 612 547 if (hid_dev->subdrivers[i].poll_end != NULL) { 613 hid_dev->subdrivers[i].poll_end(hid_dev, 614 hid_dev->subdrivers[i].data, reason); 548 hid_dev->subdrivers[i].poll_end(hid_dev, reason); 615 549 } 616 550 } … … 656 590 /*----------------------------------------------------------------------------*/ 657 591 658 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 659 { 660 ++hid_dev->report_nr; 661 } 662 663 /*----------------------------------------------------------------------------*/ 664 665 int usb_hid_report_number(usb_hid_dev_t *hid_dev) 666 { 667 return hid_dev->report_nr; 668 } 669 670 /*----------------------------------------------------------------------------*/ 671 672 //void usb_hid_report_received(void) 673 //{ 674 // ++report_number; 675 //} 676 677 /*----------------------------------------------------------------------------*/ 678 679 //bool usb_hid_report_ready(void) 680 //{ 681 // return !report_received; 682 //} 592 void usb_hid_new_report(void) 593 { 594 report_received = false; 595 } 596 597 /*----------------------------------------------------------------------------*/ 598 599 void usb_hid_report_received(void) 600 { 601 report_received = true; 602 } 603 604 /*----------------------------------------------------------------------------*/ 605 606 bool usb_hid_report_ready(void) 607 { 608 return !report_received; 609 } 683 610 684 611 /*----------------------------------------------------------------------------*/ … … 700 627 for (i = 0; i < (*hid_dev)->subdriver_count; ++i) { 701 628 if ((*hid_dev)->subdrivers[i].deinit != NULL) { 702 (*hid_dev)->subdrivers[i].deinit(*hid_dev, 703 (*hid_dev)->subdrivers[i].data); 629 (*hid_dev)->subdrivers[i].deinit(*hid_dev); 704 630 } 705 631 } -
uspace/drv/usbhid/usbhid.h
r6bfaab5 r88be3a0b 48 48 struct usb_hid_dev; 49 49 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); 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); 56 54 57 55 // TODO: add function and class name?? … … 65 63 /** Function to be called when polling ends. */ 66 64 usb_hid_driver_poll_ended poll_end; 67 /** Arbitrary data needed by the subdriver. */68 void *data;69 65 } usb_hid_subdriver_t; 70 66 … … 76 72 /** Structure holding generic USB device information. */ 77 73 usb_device_t *usb_dev; 74 75 /** @todo What is this actually? */ 76 ddf_dev_ops_t ops; 78 77 79 78 /** Index of the polling pipe in usb_hid_endpoints array. */ … … 98 97 99 98 size_t input_report_size; 100 size_t max_input_report_size;101 99 102 int report_nr; 100 /** Arbitrary data (e.g. a special structure for handling keyboard). */ 101 void *data; 103 102 } usb_hid_dev_t; 104 103 … … 130 129 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev); 131 130 132 void usb_hid_new_report( usb_hid_dev_t *hid_dev);131 void usb_hid_new_report(void); 133 132 134 int usb_hid_report_number(usb_hid_dev_t *hid_dev);133 void usb_hid_report_received(void); 135 134 136 //void usb_hid_report_received(void); 137 138 //bool usb_hid_report_ready(void); 135 bool usb_hid_report_ready(void); 139 136 140 137 void usb_hid_free(usb_hid_dev_t **hid_dev); -
uspace/lib/drv/Makefile
r6bfaab5 r88be3a0b 40 40 generic/remote_usb.c \ 41 41 generic/remote_pci.c \ 42 generic/remote_usbhc.c \ 43 generic/remote_usbhid.c 42 generic/remote_usbhc.c 44 43 45 44 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/drv/generic/dev_iface.c
r6bfaab5 r88be3a0b 46 46 #include "remote_pci.h" 47 47 48 #include <stdio.h>49 50 48 static iface_dipatch_table_t remote_ifaces = { 51 49 .ifaces = { … … 62 60 { 63 61 assert(is_valid_iface_idx(idx)); 64 65 62 return remote_ifaces.ifaces[idx]; 66 63 } -
uspace/lib/drv/generic/driver.c
r6bfaab5 r88be3a0b 405 405 /* The interface has not such method */ 406 406 printf("%s: driver_connection_gen error - " 407 "invalid interface method (%d).\n", 408 driver->name, iface_method_idx); 407 "invalid interface method.", driver->name); 409 408 async_answer_0(callid, ENOTSUP); 410 409 break; -
uspace/lib/drv/generic/remote_usbhid.c
r6bfaab5 r88be3a0b 36 36 #include <errno.h> 37 37 #include <assert.h> 38 #include <stdio.h>39 38 40 39 #include "usbhid_iface.h" … … 43 42 static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 44 43 static void remote_usbhid_get_event(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 static void remote_usbhid_get_report_descriptor_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);46 static void remote_usbhid_get_report_descriptor(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);47 44 // static void remote_usbhid_(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 48 45 … … 50 47 static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = { 51 48 remote_usbhid_get_event_length, 52 remote_usbhid_get_event, 53 remote_usbhid_get_report_descriptor_length, 54 remote_usbhid_get_report_descriptor 49 remote_usbhid_get_event 55 50 }; 56 51 … … 63 58 }; 64 59 65 //usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;60 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 66 61 67 62 … … 69 64 ipc_callid_t callid, ipc_call_t *call) 70 65 { 71 printf("remote_usbhid_get_event_length()\n");72 73 66 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface; 74 67 75 68 if (!hid_iface->get_event_length) { 76 printf("Get event length not set!\n");77 69 async_answer_0(callid, ENOTSUP); 78 70 return; 79 71 } 80 72 81 size_t len = hid_iface->get_event_length(fun); 82 // if (len == 0) { 83 // len = EEMPTY; 84 // } 85 async_answer_1(callid, EOK, len); 86 87 // if (len < 0) { 88 // async_answer_0(callid, len); 89 // } else { 90 // async_answer_1(callid, EOK, len); 91 // } 73 int len = hid_iface->get_event_length(fun); 74 if (len == 0) { 75 len = EEMPTY; 76 } 77 if (len < 0) { 78 async_answer_0(callid, len); 79 } else { 80 async_answer_1(callid, EOK, len); 81 } 92 82 } 93 83 … … 110 100 return; 111 101 } 112 ///* Check that length is even number. Truncate otherwise. */113 //if ((len % 2) == 1) {114 //len--;115 //}102 /* Check that length is even number. Truncate otherwise. */ 103 if ((len % 2) == 1) { 104 len--; 105 } 116 106 if (len == 0) { 117 107 async_answer_0(data_callid, EINVAL); 118 108 async_answer_0(callid, EINVAL); 119 return;120 109 } 121 110 122 111 int rc; 123 112 124 uint8_t *data = malloc(len); 125 if (data == NULL) { 113 size_t items = len / 2; 114 uint16_t *usage_pages_and_usages = malloc(sizeof(uint16_t) * len); 115 if (usage_pages_and_usages == NULL) { 126 116 async_answer_0(data_callid, ENOMEM); 127 117 async_answer_0(callid, ENOMEM); 128 return;129 118 } 130 119 131 size_t act_ length;132 int event_nr;133 rc = hid_iface->get_event(fun, data, len, &act_length, &event_nr, flags);120 size_t act_items; 121 int rc = hid_iface->get_event(fun, usage_pages_and_usages, 122 usage_pages_and_usages + items, items, &act_items, flags); 134 123 if (rc != EOK) { 135 free( data);124 free(usage_pages_and_usages); 136 125 async_answer_0(data_callid, rc); 137 126 async_answer_0(callid, rc); 138 return;139 127 } 140 if (act_ length >= len) {128 if (act_items >= items) { 141 129 /* This shall not happen. */ 142 130 // FIXME: how about an assert here? 143 act_ length = len;131 act_items = items; 144 132 } 145 133 146 async_data_read_finalize(data_callid, data, act_length); 134 async_data_read_finalize(data_callid, usage_pages_and_usages, 135 act_items * 2 * sizeof(uint16_t)); 147 136 148 free( data);137 free(usage_pages_and_usages); 149 138 150 async_answer_ 1(callid, EOK, event_nr);139 async_answer_0(callid, EOK); 151 140 } 152 153 void remote_usbhid_get_report_descriptor_length(ddf_fun_t *fun, void *iface,154 ipc_callid_t callid, ipc_call_t *call)155 {156 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;157 158 if (!hid_iface->get_report_descriptor_length) {159 async_answer_0(callid, ENOTSUP);160 return;161 }162 163 size_t len = hid_iface->get_report_descriptor_length(fun);164 async_answer_1(callid, EOK, (sysarg_t) len);165 }166 167 void remote_usbhid_get_report_descriptor(ddf_fun_t *fun, void *iface,168 ipc_callid_t callid, ipc_call_t *call)169 {170 usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;171 172 if (!hid_iface->get_report_descriptor) {173 async_answer_0(callid, ENOTSUP);174 return;175 }176 177 size_t len;178 ipc_callid_t data_callid;179 if (!async_data_read_receive(&data_callid, &len)) {180 async_answer_0(callid, EINVAL);181 return;182 }183 184 if (len == 0) {185 async_answer_0(data_callid, EINVAL);186 async_answer_0(callid, EINVAL);187 return;188 }189 190 uint8_t *descriptor = malloc(len);191 if (descriptor == NULL) {192 async_answer_0(data_callid, ENOMEM);193 async_answer_0(callid, ENOMEM);194 return;195 }196 197 size_t act_len = 0;198 int rc = hid_iface->get_report_descriptor(fun, descriptor, len,199 &act_len);200 if (act_len > len) {201 rc = ELIMIT;202 }203 if (rc != EOK) {204 free(descriptor);205 async_answer_0(data_callid, rc);206 async_answer_0(callid, rc);207 return;208 }209 210 async_data_read_finalize(data_callid, descriptor, act_len);211 async_answer_0(callid, EOK);212 213 free(descriptor);214 }215 216 217 141 218 142 /** -
uspace/lib/drv/include/remote_usbhid.h
r6bfaab5 r88be3a0b 36 36 #define LIBDRV_REMOTE_USBHID_H_ 37 37 38 externremote_iface_t remote_usbhid_iface;38 remote_iface_t remote_usbhid_iface; 39 39 40 40 #endif -
uspace/lib/drv/include/usbhid_iface.h
r6bfaab5 r88be3a0b 45 45 * Parameters: none 46 46 * Answer: 47 * - Size of one report in bytes. 47 * - EOK (expected always as long as device support USB HID interface) 48 * Parameters of the answer: 49 * - number of items 48 50 */ 49 51 IPC_M_USBHID_GET_EVENT_LENGTH, … … 61 63 * It is okay if the client requests less data. Extra data must 62 64 * be truncated by the driver. 63 *64 * @todo Change this comment.65 65 */ 66 IPC_M_USBHID_GET_EVENT, 67 68 /** Get the size of the report descriptor from the HID device. 69 * 70 * Parameters: 71 * - none 72 * Answer: 73 * - EOK - method is implemented (expected always) 74 * Parameters of the answer: 75 * - Size of the report in bytes. 76 */ 77 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, 78 79 /** Get the report descriptor from the HID device. 80 * 81 * Parameters: 82 * - none 83 * The call is followed by data read expecting the descriptor itself. 84 * Answer: 85 * - EOK - report descriptor returned. 86 */ 87 IPC_M_USBHID_GET_REPORT_DESCRIPTOR 66 IPC_M_USBHID_GET_EVENT 88 67 } usbhid_iface_funcs_t; 89 68 … … 96 75 * 97 76 * @param[in] fun DDF function answering the request. 98 * @return Size of the event in bytes.77 * @return Number of events or error code. 99 78 */ 100 79 size_t (*get_event_length)(ddf_fun_t *fun); … … 108 87 * @return Error code. 109 88 */ 110 int (*get_event)(ddf_fun_t *fun, uint8_t *buffer, size_t size, 111 size_t *act_size, int *event_nr, unsigned int flags); 112 113 /** Get size of the report descriptor in bytes. 114 * 115 * @param[in] fun DDF function answering the request. 116 * @return Size of the report descriptor in bytes. 117 */ 118 size_t (*get_report_descriptor_length)(ddf_fun_t *fun); 119 120 /** Get the report descriptor from the HID device. 121 * 122 * @param[in] fun DDF function answering the request. 123 * @param[out] desc Buffer with the report descriptor. 124 * @param[in] size Size of the allocated @p desc buffer. 125 * @param[out] act_size Actual size of the report descriptor returned. 126 * @return Error code. 127 */ 128 int (*get_report_descriptor)(ddf_fun_t *fun, uint8_t *desc, 129 size_t size, size_t *act_size); 89 int (*get_event)(ddf_fun_t *fun, int32_t *buffer, size_t size, 90 size_t *act_size, unsigned int flags); 130 91 } usbhid_iface_t; 131 92 -
uspace/lib/usb/Makefile
r6bfaab5 r88be3a0b 37 37 src/ddfiface.c \ 38 38 src/debug.c \ 39 src/driver.c \ 39 40 src/dump.c \ 40 src/hc.c \ 41 src/resolve.c \ 41 src/host.c \ 42 42 src/usb.c 43 43 -
uspace/lib/usb/src/ddfiface.c
r6bfaab5 r88be3a0b 37 37 #include <async.h> 38 38 #include <usb/ddfiface.h> 39 #include <usb/ hc.h>39 #include <usb/driver.h> 40 40 #include <usb/debug.h> 41 41 #include <errno.h> -
uspace/lib/usbdev/Makefile
r6bfaab5 r88be3a0b 46 46 src/pipesio.c \ 47 47 src/recognise.c \ 48 src/request.c 48 src/request.c \ 49 src/usbdevice.c 49 50 50 51 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbdev/include/usb/dev/hub.h
r6bfaab5 r88be3a0b 39 39 40 40 #include <sys/types.h> 41 #include <usb/ hc.h>41 #include <usb/dev/hc.h> 42 42 43 43 int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t, … … 63 63 const usb_hc_attached_device_t *); 64 64 int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t); 65 int usb_hc_get_handle_by_address(usb_hc_connection_t *, usb_address_t, 66 devman_handle_t *); 65 67 66 68 #endif -
uspace/lib/usbdev/include/usb/dev/pipes.h
r6bfaab5 r88be3a0b 38 38 #include <sys/types.h> 39 39 #include <usb/usb.h> 40 #include <usb/ hc.h>40 #include <usb/dev/hc.h> 41 41 #include <usb/descriptor.h> 42 42 #include <ipc/devman.h> … … 163 163 164 164 int usb_device_get_assigned_interface(ddf_dev_t *); 165 usb_address_t usb_device_get_assigned_address(devman_handle_t); 165 166 166 167 int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *, -
uspace/lib/usbdev/src/hub.c
r6bfaab5 r88be3a0b 41 41 #include <assert.h> 42 42 #include <usb/debug.h> 43 #include <time.h>44 43 45 44 /** How much time to wait between attempts to register endpoint 0:0. … … 120 119 } 121 120 121 /** Get handle of USB device with given address. 122 * 123 * @param[in] connection Opened connection to host controller. 124 * @param[in] address Address of device in question. 125 * @param[out] handle Where to write the device handle. 126 * @return Error code. 127 */ 128 int usb_hc_get_handle_by_address(usb_hc_connection_t *connection, 129 usb_address_t address, devman_handle_t *handle) 130 { 131 CHECK_CONNECTION(connection); 132 133 sysarg_t tmp; 134 int rc = async_req_2_1(connection->hc_phone, 135 DEV_IFACE_ID(USBHC_DEV_IFACE), 136 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 137 address, &tmp); 138 if ((rc == EOK) && (handle != NULL)) { 139 *handle = tmp; 140 } 141 142 return rc; 143 } 122 144 123 145 static void unregister_control_endpoint_on_default_address( … … 196 218 197 219 int rc; 198 struct timeval start_time;199 200 rc = gettimeofday(&start_time, NULL);201 if (rc != EOK) {202 return rc;203 }204 220 205 221 rc = usb_hc_connection_open(&hc_conn); … … 248 264 } 249 265 } while (rc != EOK); 250 struct timeval end_time;251 252 rc = gettimeofday(&end_time, NULL);253 if (rc != EOK) {254 goto leave_release_default_address;255 }256 257 /* According to the USB spec part 9.1.2 host allows 100ms time for258 * the insertion process to complete. According to 7.1.7.1 this is the259 * time between attach detected and port reset. However, the setup done260 * above might use much of this time so we should only wait to fill261 * up the 100ms quota*/262 suseconds_t elapsed = tv_sub(&end_time, &start_time);263 if (elapsed < 100000) {264 async_usleep(100000 - elapsed);265 }266 266 267 267 /* … … 273 273 goto leave_release_default_address; 274 274 } 275 /* USB spec 7.1.7.1: The USB System Software guarantees a minimum of276 * 10ms for reset recovery. Device response to any bus transactions277 * addressed to the default device address during the reset recovery278 * time is undefined.279 */280 async_usleep(10000);281 275 282 276 rc = usb_pipe_probe_default_control(&ctrl_pipe); -
uspace/lib/usbdev/src/pipes.c
r6bfaab5 r88be3a0b 36 36 #include <usb/dev/pipes.h> 37 37 #include <usb/debug.h> 38 #include <usb/ hc.h>38 #include <usb/driver.h> 39 39 #include <usbhc_iface.h> 40 40 #include <usb_iface.h> … … 97 97 98 98 return (int) iface_no; 99 } 100 101 /** Tell USB address assigned to given device. 102 * 103 * @param dev_handle Devman handle of the USB device in question. 104 * @return USB address or negative error code. 105 */ 106 usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle) 107 { 108 int parent_phone = devman_parent_device_connect(dev_handle, 109 IPC_FLAG_BLOCKING); 110 if (parent_phone < 0) { 111 return parent_phone; 112 } 113 114 sysarg_t address; 115 116 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 117 IPC_M_USB_GET_ADDRESS, 118 dev_handle, &address); 119 120 if (rc != EOK) { 121 return rc; 122 } 123 124 async_hangup(parent_phone); 125 126 return (usb_address_t) address; 99 127 } 100 128 -
uspace/lib/usbhid/Makefile
r6bfaab5 r88be3a0b 41 41 src/hidpath.c \ 42 42 src/hidreport.c \ 43 src/consumer.c \44 43 src/hidreq.c 45 44 -
uspace/lib/usbhid/include/usb/hid/hid_report_items.h
r6bfaab5 r88be3a0b 27 27 */ 28 28 29 /** @addtogroup libusb 29 /** @addtogroup libusbhid 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief USB HID Report descriptor item tags.33 * @brief USB HID parser. 34 34 */ 35 #ifndef LIBUSB _HID_REPORT_ITEMS_H_36 #define LIBUSB _HID_REPORT_ITEMS_H_35 #ifndef LIBUSBHID_HID_REPORT_ITEMS_H_ 36 #define LIBUSBHID_HID_REPORT_ITEMS_H_ 37 37 38 38 #include <stdint.h> 39 39 40 /*---------------------------------------------------------------------------*/ 41 /* 40 /** 42 41 * Item prefix 43 42 */ 44 45 /** Returns size of item data in bytes */46 43 #define USB_HID_ITEM_SIZE(data) ((uint8_t)(data & 0x3)) 47 48 /** Returns item tag */49 44 #define USB_HID_ITEM_TAG(data) ((uint8_t)((data & 0xF0) >> 4)) 50 51 /** Returns class of item tag */52 45 #define USB_HID_ITEM_TAG_CLASS(data) ((uint8_t)((data & 0xC) >> 2)) 53 54 /** Returns if the item is the short item or long item. Long items are not55 * supported. */56 46 #define USB_HID_ITEM_IS_LONG(data) (data == 0xFE) 57 47 58 /*---------------------------------------------------------------------------*/59 /*60 * Extended usage macros61 */62 48 63 /** Recognizes if the given usage is extended (contains also usage page). */ 64 #define USB_HID_IS_EXTENDED_USAGE(usage) ((usage & 0xFFFF0000) != 0) 65 66 /** Cuts usage page of the extended usage. */ 67 #define USB_HID_EXTENDED_USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16) 68 69 /** Cuts usage of the extended usage */ 70 #define USB_HID_EXTENDED_USAGE(usage) (usage & 0xFFFF) 71 72 /*---------------------------------------------------------------------------*/ 73 /* 49 /** 74 50 * Input/Output/Feature Item flags 75 51 */ 76 /** 77 * Indicates whether the item is data (0) or a constant (1) value. Data 78 * indicates the item is defining report fields that contain modifiable device 79 * data. Constant indicates the item is a static read-only field in a report 80 * and cannot be modified (written) by the host. 81 */ 52 /** Constant (1) / Variable (0) */ 82 53 #define USB_HID_ITEM_FLAG_CONSTANT(flags) ((flags & 0x1) == 0x1) 83 84 /** 85 * Indicates whether the item creates variable (1) or array (0) data fields in 86 * reports. 87 */ 54 /** Variable (1) / Array (0) */ 88 55 #define USB_HID_ITEM_FLAG_VARIABLE(flags) ((flags & 0x2) == 0x2) 89 90 /** 91 * Indicates whether the data is absolute (0) (based on a fixed origin) or 92 * relative (1) (indicating the change in value from the last report). Mouse 93 * devices usually provide relative data, while tablets usually provide 94 * absolute data. 95 */ 56 /** Absolute / Relative*/ 96 57 #define USB_HID_ITEM_FLAG_RELATIVE(flags) ((flags & 0x4) == 0x4) 97 98 /** Indicates whether the data “rolls over” when reaching either the extreme 99 * high or low value. For example, a dial that can spin freely 360 degrees 100 * might output values from 0 to 10. If Wrap is indicated, the next value 101 * reported after passing the 10 position in the increasing direction would be 102 * 0. 103 */ 58 /** Wrap / No Wrap */ 104 59 #define USB_HID_ITEM_FLAG_WRAP(flags) ((flags & 0x8) == 0x8) 105 106 /**107 * Indicates whether the raw data from the device has been processed in some108 * way, and no longer represents a linear relationship between what is109 * measured and the data that is reported.110 */111 60 #define USB_HID_ITEM_FLAG_LINEAR(flags) ((flags & 0x10) == 0x10) 112 113 /**114 * Indicates whether the control has a preferred state to which it will return115 * when the user is not physically interacting with the control. Push buttons116 * (as opposed to toggle buttons) and self- centering joysticks are examples.117 */118 61 #define USB_HID_ITEM_FLAG_PREFERRED(flags) ((flags & 0x20) == 0x20) 119 120 /**121 * Indicates whether the control has a state in which it is not sending122 * meaningful data. One possible use of the null state is for controls that123 * require the user to physically interact with the control in order for it to124 * report useful data.125 */126 62 #define USB_HID_ITEM_FLAG_POSITION(flags) ((flags & 0x40) == 0x40) 127 128 /**129 * Indicates whether the Feature or Output control's value should be changed130 * by the host or not. Volatile output can change with or without host131 * interaction. To avoid synchronization problems, volatile controls should be132 * relative whenever possible.133 */134 63 #define USB_HID_ITEM_FLAG_VOLATILE(flags) ((flags & 0x80) == 0x80) 135 136 /**137 * Indicates that the control emits a fixed-size stream of bytes. The contents138 * of the data field are determined by the application. The contents of the139 * buffer are not interpreted as a single numeric quantity. Report data140 * defined by a Buffered Bytes item must be aligned on an 8-bit boundary.141 */142 64 #define USB_HID_ITEM_FLAG_BUFFERED(flags) ((flags & 0x100) == 0x100) 143 65 144 /*---------------------------------------------------------------------------*/145 146 66 /* MAIN ITEMS */ 147 148 /** 149 * Main items are used to either define or group certain types of data fields 150 * within a Report descriptor. 151 */ 152 #define USB_HID_TAG_CLASS_MAIN 0x0 153 154 /** 155 * An Input item describes information about the data provided by one or more 156 * physical controls. An application can use this information to interpret the 157 * data provided by the device. All data fields defined in a single item share 158 * an identical data format. 159 */ 160 #define USB_HID_REPORT_TAG_INPUT 0x8 161 162 /** 163 * The Output item is used to define an output data field in a report. This 164 * item is similar to an Input item except it describes data sent to the 165 * device—for example, LED states. 166 */ 167 #define USB_HID_REPORT_TAG_OUTPUT 0x9 168 169 /** 170 * Feature items describe device configuration information that can be sent to 171 * the device. 172 */ 173 #define USB_HID_REPORT_TAG_FEATURE 0xB 174 175 /** 176 * A Collection item identifies a relationship between two or more data 177 * (Input, Output, or Feature.) 178 */ 67 #define USB_HID_TAG_CLASS_MAIN 0x0 68 #define USB_HID_REPORT_TAG_INPUT 0x8 69 #define USB_HID_REPORT_TAG_OUTPUT 0x9 70 #define USB_HID_REPORT_TAG_FEATURE 0xB 179 71 #define USB_HID_REPORT_TAG_COLLECTION 0xA 180 181 /**182 * While the Collection item opens a collection of data, the End Collection183 * item closes a collection.184 */185 72 #define USB_HID_REPORT_TAG_END_COLLECTION 0xC 186 73 187 /*---------------------------------------------------------------------------*/ 74 /* GLOBAL ITEMS */ 75 #define USB_HID_TAG_CLASS_GLOBAL 0x1 76 #define USB_HID_REPORT_TAG_USAGE_PAGE 0x0 77 #define USB_HID_REPORT_TAG_LOGICAL_MINIMUM 0x1 78 #define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM 0x2 79 #define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM 0x3 80 #define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM 0x4 81 #define USB_HID_REPORT_TAG_UNIT_EXPONENT 0x5 82 #define USB_HID_REPORT_TAG_UNIT 0x6 83 #define USB_HID_REPORT_TAG_REPORT_SIZE 0x7 84 #define USB_HID_REPORT_TAG_REPORT_ID 0x8 85 #define USB_HID_REPORT_TAG_REPORT_COUNT 0x9 86 #define USB_HID_REPORT_TAG_PUSH 0xA 87 #define USB_HID_REPORT_TAG_POP 0xB 188 88 189 /* GLOBAL ITEMS */190 191 /**192 * Global items describe rather than define data from a control.193 */194 #define USB_HID_TAG_CLASS_GLOBAL 0x1195 196 /**197 * Unsigned integer specifying the current Usage Page. Since a usage are 32198 * bit values, Usage Page items can be used to conserve space in a report199 * descriptor by setting the high order 16 bits of a subsequent usages. Any200 * usage that follows which is defines 16 bits or less is interpreted as a201 * Usage ID and concatenated with the Usage Page to form a 32 bit Usage.202 */203 #define USB_HID_REPORT_TAG_USAGE_PAGE 0x0204 205 /**206 * Extent value in logical units. This is the minimum value that a variable207 * or array item will report. For example, a mouse reporting x position values208 * from 0 to 128 would have a Logical Minimum of 0 and a Logical Maximum of209 * 128.210 */211 #define USB_HID_REPORT_TAG_LOGICAL_MINIMUM 0x1212 213 /**214 * Extent value in logical units. This is the maximum value that a variable215 * or array item will report.216 */217 #define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM 0x2218 219 /**220 * Minimum value for the physical extent of a variable item. This represents221 * the Logical Minimum with units applied to it.222 */223 #define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM 0x3224 225 /**226 * Maximum value for the physical extent of a variable item.227 */228 #define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM 0x4229 230 /**231 * Value of the unit exponent in base 10. See the table later in this section232 * for more information.233 */234 #define USB_HID_REPORT_TAG_UNIT_EXPONENT 0x5235 236 /**237 * Unit values.238 */239 #define USB_HID_REPORT_TAG_UNIT 0x6240 241 /**242 * Unsigned integer specifying the size of the report fields in bits. This243 * allows the parser to build an item map for the report handler to use.244 */245 #define USB_HID_REPORT_TAG_REPORT_SIZE 0x7246 247 /**248 * Unsigned value that specifies the Report ID. If a Report ID tag is used249 * anywhere in Report descriptor, all data reports for the device are preceded250 * by a single byte ID field. All items succeeding the first Report ID tag but251 * preceding a second Report ID tag are included in a report prefixed by a252 * 1-byte ID. All items succeeding the second but preceding a third Report ID253 * tag are included in a second report prefixed by a second ID, and so on.254 */255 #define USB_HID_REPORT_TAG_REPORT_ID 0x8256 257 /**258 * Unsigned integer specifying the number of data fields for the item;259 * determines how many fields are included in the report for this particular260 * item (and consequently how many bits are added to the report).261 */262 #define USB_HID_REPORT_TAG_REPORT_COUNT 0x9263 264 /**265 * Places a copy of the global item state table on the stack.266 */267 #define USB_HID_REPORT_TAG_PUSH 0xA268 269 /**270 * Replaces the item state table with the top structure from the stack.271 */272 #define USB_HID_REPORT_TAG_POP 0xB273 274 /*---------------------------------------------------------------------------*/275 89 276 90 /* LOCAL ITEMS */ 277 278 /** 279 * Local item tags define characteristics of controls. These items do not 280 * carry over to the next Main item. If a Main item defines more than one 281 * control, it may be preceded by several similar Local item tags. For 282 * example, an Input item may have several Usage tags associated with it, one 283 * for each control. 284 */ 285 #define USB_HID_TAG_CLASS_LOCAL 0x2 286 287 /** 288 * Usage index for an item usage; represents a suggested usage for the item or 289 * collection. In the case where an item represents multiple controls, a Usage 290 * tag may suggest a usage for every variable or element in an array. 291 */ 292 #define USB_HID_REPORT_TAG_USAGE 0x0 293 294 /** 295 * Defines the starting usage associated with an array or bitmap. 296 */ 297 #define USB_HID_REPORT_TAG_USAGE_MINIMUM 0x1 298 299 /** 300 * Defines the ending usage associated with an array or bitmap. 301 */ 302 #define USB_HID_REPORT_TAG_USAGE_MAXIMUM 0x2 303 304 /** 305 * Determines the body part used for a control. Index points to a designator 306 * in the Physical descriptor. 307 */ 308 #define USB_HID_REPORT_TAG_DESIGNATOR_INDEX 0x3 309 310 /** 311 * Defines the index of the starting designator associated with an array or 312 * bitmap. 313 */ 91 #define USB_HID_TAG_CLASS_LOCAL 0x2 92 #define USB_HID_REPORT_TAG_USAGE 0x0 93 #define USB_HID_REPORT_TAG_USAGE_MINIMUM 0x1 94 #define USB_HID_REPORT_TAG_USAGE_MAXIMUM 0x2 95 #define USB_HID_REPORT_TAG_DESIGNATOR_INDEX 0x3 314 96 #define USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM 0x4 315 316 /**317 * Defines the index of the ending designator associated with an array or318 * bitmap.319 */320 97 #define USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM 0x5 321 322 /** 323 * String index for a String descriptor; allows a string to be associated with 324 * a particular item or control. 325 */ 326 #define USB_HID_REPORT_TAG_STRING_INDEX 0x7 327 328 /** 329 * Specifies the first string index when assigning a group of sequential 330 * strings to controls in an array or bitmap. 331 */ 332 #define USB_HID_REPORT_TAG_STRING_MINIMUM 0x8 333 334 /** 335 * Specifies the last string index when assigning a group of sequential 336 * strings to controls in an array or bitmap. 337 */ 338 #define USB_HID_REPORT_TAG_STRING_MAXIMUM 0x9 339 340 /** 341 * Defines the beginning or end of a set of local items (1 = open set, 0 = 342 * close set). 343 * 344 * Usages other than the first (most preferred) usage defined are not 345 * accessible by system software. 346 */ 347 #define USB_HID_REPORT_TAG_DELIMITER 0xA 348 349 /*---------------------------------------------------------------------------*/ 98 #define USB_HID_REPORT_TAG_STRING_INDEX 0x7 99 #define USB_HID_REPORT_TAG_STRING_MINIMUM 0x8 100 #define USB_HID_REPORT_TAG_STRING_MAXIMUM 0x9 101 #define USB_HID_REPORT_TAG_DELIMITER 0xA 350 102 351 103 #endif -
uspace/lib/usbhid/include/usb/hid/hiddescriptor.h
r6bfaab5 r88be3a0b 27 27 */ 28 28 29 /** @addtogroup libusb 29 /** @addtogroup libusbhid 30 30 * @{ 31 31 */ … … 33 33 * USB HID report descriptor and report data parser 34 34 */ 35 #ifndef LIBUSB _HIDDESCRIPTOR_H_36 #define LIBUSB _HIDDESCRIPTOR_H_35 #ifndef LIBUSBHID_HIDDESCRIPTOR_H_ 36 #define LIBUSBHID_HIDDESCRIPTOR_H_ 37 37 38 38 #include <stdint.h> … … 42 42 #include <usb/hid/hidtypes.h> 43 43 44 45 /* 46 * Descriptor parser functions 47 */ 48 49 /** */ 44 50 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 45 51 const uint8_t *data, size_t size); 46 52 53 /** */ 47 54 void usb_hid_free_report(usb_hid_report_t *report); 48 55 56 /** */ 49 57 void usb_hid_descriptor_print(usb_hid_report_t *report); 50 58 59 51 60 int usb_hid_report_init(usb_hid_report_t *report); 61 int usb_hid_report_append_fields(usb_hid_report_t *report, 62 usb_hid_report_item_t *report_item); 52 63 53 int usb_hid_report_append_fields(usb_hid_report_t *report, 54 usb_hid_report_item_t *report_item); 55 56 usb_hid_report_description_t * usb_hid_report_find_description( 57 const usb_hid_report_t *report, uint8_t report_id, 58 usb_hid_report_type_t type); 59 60 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 61 size_t item_size, usb_hid_report_item_t *report_item, 62 usb_hid_report_path_t *usage_path); 63 64 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 65 size_t item_size, usb_hid_report_item_t *report_item, 66 usb_hid_report_path_t *usage_path); 67 68 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 69 size_t item_size, usb_hid_report_item_t *report_item, 70 usb_hid_report_path_t *usage_path); 71 72 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 73 size_t item_size, usb_hid_report_item_t *report_item, 74 usb_hid_report_path_t *usage_path); 64 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type); 65 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 66 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 67 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 68 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 69 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 70 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 71 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 72 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 75 73 76 74 void usb_hid_descriptor_print_list(link_t *head); 77 78 75 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item); 79 80 76 void usb_hid_free_report_list(link_t *head); 81 82 usb_hid_report_item_t *usb_hid_report_item_clone( 83 const usb_hid_report_item_t *item); 84 77 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item); 85 78 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 86 79 87 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t*report, 88 usb_hid_report_path_t *cmp_path); 89 90 80 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path); 91 81 #endif 92 82 /** -
uspace/lib/usbhid/include/usb/hid/hidparser.h
r6bfaab5 r88be3a0b 47 47 * Input report parser functions 48 48 */ 49 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 50 size_t size, uint8_t *report_id); 49 /** */ 50 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 51 size_t size, uint8_t *report_id); 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); 51 56 52 57 /* 53 58 * Output report parser functions 54 59 */ 60 /** Allocates output report buffer*/ 55 61 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 56 62 uint8_t report_id); 57 63 64 /** Frees output report buffer*/ 58 65 void usb_hid_report_output_free(uint8_t *output); 59 66 60 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 61 usb_hid_report_type_t type); 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); 62 70 63 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id, 64 usb_hid_report_type_t type); 71 /** Makes the output report buffer by translated given data */ 72 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 73 uint8_t *buffer, size_t size); 65 74 75 /** */ 76 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 77 usb_hid_report_field_t *field, 78 usb_hid_report_path_t *path, 79 int flags, 80 usb_hid_report_type_t type); 66 81 67 int usb_hid_report_output_translate(usb_hid_report_t *report, 68 uint8_t report_id, uint8_t *buffer, size_t size); 69 70 71 /* 72 * Report descriptor structure observing functions 73 */ 74 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 75 usb_hid_report_field_t *field, usb_hid_report_path_t *path, 76 int flags, usb_hid_report_type_t type); 77 78 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, 79 uint8_t report_id, usb_hid_report_type_t type); 82 /** */ 83 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, 84 uint8_t report_id, 85 usb_hid_report_type_t type); 80 86 81 87 #endif -
uspace/lib/usbhid/include/usb/hid/hidpath.h
r6bfaab5 r88be3a0b 27 27 */ 28 28 29 /** @addtogroup libusb 29 /** @addtogroup libusbhid 30 30 * @{ 31 31 */ … … 33 33 * USB HID report descriptor and report data parser 34 34 */ 35 #ifndef LIBUSB _HIDPATH_H_36 #define LIBUSB _HIDPATH_H_35 #ifndef LIBUSBHID_HIDPATH_H_ 36 #define LIBUSBHID_HIDPATH_H_ 37 37 38 38 #include <usb/hid/hidparser.h> … … 40 40 #include <adt/list.h> 41 41 42 43 /*---------------------------------------------------------------------------*/ 44 /* 45 * Flags of usage paths comparison modes. 46 * 42 /** 43 * Description of path of usage pages and usages in report descriptor 47 44 */ 48 /** Wanted usage path must be exactly the same as the searched one. This 49 * option cannot be combined with the others. 50 */ 45 /** Wanted usage path must be exactly the same as the searched one */ 51 46 #define USB_HID_PATH_COMPARE_STRICT 0 52 53 /** 54 * Wanted usage path must be the suffix in the searched one. 55 */ 47 /** Wanted usage path must be the suffix in the searched one */ 56 48 #define USB_HID_PATH_COMPARE_END 1 57 58 /** 59 * Only usage page are compared along the usage path. This option can be 60 * combined with others. 61 */ 49 /** */ 62 50 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 2 63 64 /** 65 * Searched usage page must be prefix of the other one. 66 */ 51 /** Searched usage page must be prefix of the other one */ 67 52 #define USB_HID_PATH_COMPARE_BEGIN 4 68 69 /** 70 * Searched couple of usage page and usage can be anywhere in usage path. 71 * This option is deprecated. 72 */ 53 /** Searched couple of usage page and usage can be anywhere in usage path */ 73 54 #define USB_HID_PATH_COMPARE_ANYWHERE 8 74 55 75 /*----------------------------------------------------------------------------*/ 76 /** 77 * Item of usage path structure. Last item of linked list describes one item 78 * in report, the others describe superior Collection tags. Usage and Usage 79 * page of report item can be changed due to data in report. 80 */ 56 57 /** Collection usage path structure */ 81 58 typedef struct { 82 /** Usage page of report item. Zero when usage page can be changed.*/59 /** */ 83 60 uint32_t usage_page; 84 /** Usage of report item. Zero when usage can be changed.*/61 /** */ 85 62 uint32_t usage; 86 63 87 /** Attribute of Collection tag in report descriptor*/88 64 uint8_t flags; 89 90 /** Linked list structure*/ 65 /** */ 91 66 link_t link; 92 67 } usb_hid_report_usage_path_t; 93 68 94 95 /*---------------------------------------------------------------------------*/ 96 /** 97 * USB HID usage path structure. 98 * */ 69 /** */ 99 70 typedef struct { 100 /** Length of usage path*/71 /** */ 101 72 int depth; 102 103 /** Report id. Zero is reserved and means that report id is not used.104 * */105 73 uint8_t report_id; 106 74 107 /** Linked list structure.*/75 /** */ 108 76 link_t link; /* list */ 109 77 110 /** Head of the list of usage path items. */ 111 link_t head; 78 link_t head; /* head of list of usage paths */ 112 79 113 80 } usb_hid_report_path_t; 114 81 115 /* ---------------------------------------------------------------------------*/82 /** */ 116 83 usb_hid_report_path_t *usb_hid_report_path(void); 117 84 85 /** */ 118 86 void usb_hid_report_path_free(usb_hid_report_path_t *path); 119 87 120 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 121 uint8_t report_id); 88 /** */ 89 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 90 uint8_t report_id); 122 91 92 /** */ 123 93 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 124 94 int32_t usage_page, int32_t usage); 125 95 96 /** */ 126 97 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 127 98 99 /** */ 128 100 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 129 101 102 /** */ 130 103 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 131 104 int32_t tag, int32_t data); 132 105 133 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 134 usb_hid_report_path_t *path, int flags); 106 /** */ 107 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 108 usb_hid_report_path_t *path, int flags); 135 109 136 usb_hid_report_path_t *usb_hid_report_path_clone( 137 110 /** */ 111 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 138 112 139 113 void usb_hid_print_usage_path(usb_hid_report_path_t *path); -
uspace/lib/usbhid/include/usb/hid/hidreport.h
r6bfaab5 r88be3a0b 44 44 * report parser. 45 45 * 46 * \param[in] dev USB device representing a HID device. 47 * \param[in/out] parser HID Report parser. 48 * \param[out] report_desc Place to save report descriptor into. 49 * \param[out] report_size 46 * \param dev USB device representing a HID device. 47 * \param parser HID Report parser. 50 48 * 51 49 * \retval EOK if successful. … … 59 57 */ 60 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 61 usb_hid_report_t *report , uint8_t **report_desc, size_t *report_size);59 usb_hid_report_t *report); 62 60 63 61 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usbhid/include/usb/hid/hidtypes.h
r6bfaab5 r88be3a0b 27 27 */ 28 28 29 /** @addtogroup libusb 29 /** @addtogroup libusbhid 30 30 * @{ 31 31 */ 32 32 /** @file 33 * Basic data structures for USB HID Report descriptor and report parser.34 */ 35 #ifndef LIBUSB _HIDTYPES_H_36 #define LIBUSB _HIDTYPES_H_33 * USB HID report descriptor and report data parser 34 */ 35 #ifndef LIBUSBHID_HIDTYPES_H_ 36 #define LIBUSBHID_HIDTYPES_H_ 37 37 38 38 #include <stdint.h> 39 39 #include <adt/list.h> 40 40 41 /*---------------------------------------------------------------------------*/ 42 43 /** 44 * Maximum amount of specified usages for one report item 45 */ 46 #define USB_HID_MAX_USAGES 0xffff 47 48 /** 49 * Converts integer from unsigned two's complement format format to signed 50 * one. 51 * 52 * @param x Number to convert 53 * @param size Length of the unsigned number in bites 54 * @return signed int 55 */ 56 #define USB_HID_UINT32_TO_INT32(x, size) \ 57 ((((x) & (1 << ((size) - 1))) != 0) ? \ 58 -(~((x) - 1) & ((1 << size) - 1)) : (x)) 59 60 /** 61 * Convert integer from signed format to unsigned. If number is negative the 62 * two's complement format is used. 63 * 64 * @param x Number to convert 65 * @param size Length of result number in bites 66 * @return unsigned int 67 */ 68 #define USB_HID_INT32_TO_UINT32(x, size) \ 69 (((x) < 0 ) ? ((1 << (size)) + (x)) : (x)) 70 71 /*---------------------------------------------------------------------------*/ 72 73 /** 74 * Enum of report types 75 */ 41 #define USB_HID_MAX_USAGES 20 42 43 #define USB_HID_UINT32_TO_INT32(x, size) ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1))) 44 #define USB_HID_INT32_TO_UINT32(x, size) (((x) < 0 ) ? ((1 << (size)) + (x)) : (x)) 45 46 76 47 typedef enum { 77 /** Input report. Data are sent from device to system */78 48 USB_HID_REPORT_TYPE_INPUT = 1, 79 80 /** Output report. Data are sent from system to device */81 49 USB_HID_REPORT_TYPE_OUTPUT = 2, 82 83 /** Feature report. Describes device configuration information that84 * can be sent to the device */85 50 USB_HID_REPORT_TYPE_FEATURE = 3 86 51 } usb_hid_report_type_t; 87 52 88 /*---------------------------------------------------------------------------*/ 89 90 /** 91 * Description of all reports described in one report descriptor. 92 */ 93 typedef struct { 94 /** Count of available reports. */ 53 54 typedef struct { 55 /** */ 95 56 int report_count; 96 97 /** Head of linked list of description of reports. */ 98 link_t reports; 99 100 /** Head of linked list of all used usage/collection paths. */ 57 link_t reports; /** list of usb_hid_report_description_t */ 58 101 59 link_t collection_paths; 102 103 /** Length of list of usage paths. */104 60 int collection_paths_count; 105 61 106 /** Flag whether report ids are used. */107 62 int use_report_ids; 108 109 /** Report id of last parsed report. */110 63 uint8_t last_report_id; 111 64 112 65 } usb_hid_report_t; 113 /*---------------------------------------------------------------------------*/ 114 115 /** 116 * Description of one concrete report 117 */ 118 typedef struct { 119 /** Report id. Zero when no report id is used. */ 66 67 typedef struct { 120 68 uint8_t report_id; 121 122 /** Type of report */123 69 usb_hid_report_type_t type; 124 70 125 /** Bit length of the report */126 71 size_t bit_length; 127 128 /** Number of items in report */129 72 size_t item_length; 130 73 131 /** Linked list of report items in report */ 132 link_t report_items; 133 134 /** Linked list of descriptions. */ 74 link_t report_items; /** list of report items (fields) */ 75 135 76 link_t link; 136 77 } usb_hid_report_description_t; 137 /*---------------------------------------------------------------------------*/ 138 139 /** 140 * Description of one field/item in report 141 */ 142 typedef struct { 143 /** Bit offset of the field */ 78 79 typedef struct { 80 144 81 int offset; 145 146 /** Bit size of the field */147 82 size_t size; 148 83 149 /** Usage page. Zero when usage page can be changed. */150 84 uint16_t usage_page; 151 152 /** Usage. Zero when usage can be changed. */153 85 uint16_t usage; 154 86 155 /** Item's attributes */156 87 uint8_t item_flags; 157 158 /** Usage/Collection path of the field. */159 88 usb_hid_report_path_t *collection_path; 160 89 161 /**162 * The lowest valid logical value (value with the device operates)163 */164 90 int32_t logical_minimum; 165 166 /**167 * The greatest valid logical value168 */169 91 int32_t logical_maximum; 170 171 /**172 * The lowest valid physical value (value with the system operates)173 */174 92 int32_t physical_minimum; 175 176 /** The greatest valid physical value */177 93 int32_t physical_maximum; 178 179 /** The lowest valid usage index */ 180 int32_t usage_minimum; 181 182 /** The greatest valid usage index */ 183 int32_t usage_maximum; 184 185 /** Unit of the value */ 94 uint32_t usage_minimum; 95 uint32_t usage_maximum; 186 96 uint32_t unit; 187 188 /** Unit exponent */189 97 uint32_t unit_exponent; 190 191 /** Array of possible usages */ 192 uint32_t *usages; 193 194 /** Size of the array of usages */ 195 size_t usages_count; 196 197 /** Parsed value */ 98 99 198 100 int32_t value; 199 101 200 /** List to another report items */201 102 link_t link; 202 103 } usb_hid_report_field_t; 203 104 204 /*---------------------------------------------------------------------------*/ 105 205 106 206 107 /** 207 * State table for report descriptor parsing108 * state table 208 109 */ 209 110 typedef struct { … … 211 112 int32_t id; 212 113 213 /** Extended usage page*/114 /** */ 214 115 uint16_t extended_usage_page; 215 216 /** Array of usages specified for this item */217 116 uint32_t usages[USB_HID_MAX_USAGES]; 218 219 /** Length of usages array */220 117 int usages_count; 221 118 222 /** Usage page*/119 /** */ 223 120 uint32_t usage_page; 224 121 225 /** Minimum valid usage index */ 226 int32_t usage_minimum; 227 228 /** Maximum valid usage index */ 229 int32_t usage_maximum; 230 231 /** Minimum valid logical value */ 122 /** */ 123 uint32_t usage_minimum; 124 /** */ 125 uint32_t usage_maximum; 126 /** */ 232 127 int32_t logical_minimum; 233 234 /** Maximum valid logical value */ 128 /** */ 235 129 int32_t logical_maximum; 236 237 /** Length of the items in bits*/ 130 /** */ 238 131 int32_t size; 239 240 /** COunt of items*/ 132 /** */ 241 133 int32_t count; 242 243 /** Bit offset of the item in report */ 134 /** */ 244 135 size_t offset; 245 246 /** Unit exponent */ 136 /** */ 247 137 int32_t unit_exponent; 248 /** Unit of the value*/138 /** */ 249 139 int32_t unit; 250 140 251 /** String index*/141 /** */ 252 142 uint32_t string_index; 253 254 /** Minimum valid string index */ 143 /** */ 255 144 uint32_t string_minimum; 256 257 /** Maximum valid string index */ 145 /** */ 258 146 uint32_t string_maximum; 259 260 /** The designator index */ 147 /** */ 261 148 uint32_t designator_index; 262 263 /** Minimum valid designator value*/ 149 /** */ 264 150 uint32_t designator_minimum; 265 266 /** Maximum valid designator value*/ 151 /** */ 267 152 uint32_t designator_maximum; 268 269 /** Minimal valid physical value*/ 153 /** */ 270 154 int32_t physical_minimum; 271 272 /** Maximal valid physical value */ 155 /** */ 273 156 int32_t physical_maximum; 274 157 275 /** Items attributes*/158 /** */ 276 159 uint8_t item_flags; 277 160 278 /** Report type */279 161 usb_hid_report_type_t type; 280 162 281 163 /** current collection path*/ 282 164 usb_hid_report_path_t *usage_path; 283 284 /** Unused*/ 165 /** */ 285 166 link_t link; 286 167 287 168 int in_delimiter; 288 169 } usb_hid_report_item_t; 289 /*---------------------------------------------------------------------------*/ 290 /** 291 * Enum of the keyboard modifiers 292 */ 170 171 /** HID parser callbacks for IN items. */ 172 typedef struct { 173 /** Callback for keyboard. 174 * 175 * @param key_codes Array of pressed key (including modifiers). 176 * @param count Length of @p key_codes. 177 * @param arg Custom argument. 178 */ 179 void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t report_id, void *arg); 180 } usb_hid_report_in_callbacks_t; 181 182 293 183 typedef enum { 294 184 USB_HID_MOD_LCTRL = 0x01, … … 314 204 USB_HID_MOD_RGUI 315 205 }; 316 /*---------------------------------------------------------------------------*/317 318 206 319 207 #endif -
uspace/lib/usbhid/include/usb/hid/iface.h
r6bfaab5 r88be3a0b 38 38 #include <sys/types.h> 39 39 40 int usbhid_dev_get_event_length(int , size_t *);41 int usbhid_dev_get_event(int, uint 8_t *, size_t, size_t *, int *,40 int usbhid_dev_get_event_length(int); 41 int usbhid_dev_get_event(int, uint16_t *, uint16_t *, size_t, size_t *, 42 42 unsigned int); 43 int usbhid_dev_get_report_descriptor_length(int, size_t *);44 int usbhid_dev_get_report_descriptor(int, uint8_t *, size_t, size_t *);45 43 46 44 #endif -
uspace/lib/usbhid/include/usb/hid/usages/core.h
r6bfaab5 r88be3a0b 67 67 } usb_hidut_usage_generic_desktop_t; 68 68 69 typedef enum {70 USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL = 171 } usb_hidut_usage_consumer_t;72 73 69 74 70 #endif -
uspace/lib/usbhid/src/hiddescriptor.c
r6bfaab5 r88be3a0b 41 41 #include <assert.h> 42 42 43 /*---------------------------------------------------------------------------*/ 44 /* 45 * Constants defining current parsing mode for correct parsing of the set of 46 * local tags (usage) enclosed in delimter tags. 47 */ 48 /** 49 * Second delimiter tag was read. The set of local items (usage) ended. 50 */ 43 51 44 #define OUTSIDE_DELIMITER_SET 0 52 53 /**54 * First delimiter tag was read. The set of local items (usage) started.55 */56 45 #define START_DELIMITER_SET 1 57 58 /**59 * Parser is in the set of local items.60 */61 46 #define INSIDE_DELIMITER_SET 2 62 63 /*---------------------------------------------------------------------------*/64 47 65 48 /** The new report item flag. Used to determine when the item is completly … … 78 61 #define USB_HID_UNKNOWN_TAG -99 79 62 80 /*---------------------------------------------------------------------------*/ 81 /** 82 * Checks if given collection path is already present in report structure and 83 * inserts it if not. 84 * 85 * @param report Report structure 86 * @param cmp_path The collection path 87 * @return Pointer to the result collection path in report structure. 88 * @retval NULL If some error occurs 89 */ 90 usb_hid_report_path_t *usb_hid_report_path_try_insert( 91 usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) { 92 93 link_t *path_it = report->collection_paths.prev->next; 63 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) 64 { 65 /* find or append current collection path to the list */ 66 link_t *path_it = report->collection_paths.next; 94 67 usb_hid_report_path_t *path = NULL; 95 96 if((report == NULL) || (cmp_path == NULL)) {97 return NULL;98 }99 100 68 while(path_it != &report->collection_paths) { 101 path = list_get_instance(path_it, usb_hid_report_path_t, 102 link); 103 104 if(usb_hid_report_compare_usage_path(path, cmp_path, 105 USB_HID_PATH_COMPARE_STRICT) == EOK){ 69 path = list_get_instance(path_it, usb_hid_report_path_t, link); 70 71 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 106 72 break; 107 73 } … … 109 75 } 110 76 if(path_it == &report->collection_paths) { 111 path = usb_hid_report_path_clone(cmp_path); 112 if(path == NULL) { 113 return NULL; 114 } 77 path = usb_hid_report_path_clone(cmp_path); 115 78 list_append(&path->link, &report->collection_paths); 116 79 report->collection_paths_count++; … … 119 82 } 120 83 else { 121 return list_get_instance(path_it, usb_hid_report_path_t, 122 link); 123 } 124 } 125 126 /*---------------------------------------------------------------------------*/ 84 return list_get_instance(path_it, usb_hid_report_path_t, link); 85 } 86 } 87 127 88 /** 128 89 * Initialize the report descriptor parser structure … … 130 91 * @param parser Report descriptor parser structure 131 92 * @return Error code 132 * @retval EINVAL If no report structure was given133 * @retval EOK If report structure was successfully initialized134 93 */ 135 94 int usb_hid_report_init(usb_hid_report_t *report) … … 147 106 } 148 107 149 /*---------------------------------------------------------------------------*/ 150 151 /** 152 * 153 * 154 * @param report Report structure in which the new report items should be 155 * stored 156 * @param report_item Current report descriptor's parsing state table 157 * @return Error code 158 * @retval EOK If all fields were successfully append to report 159 * @retval EINVAL If invalid parameters (NULL) was given 160 * @retval ENOMEM If there is no memmory to store new report description 161 * 162 */ 163 int usb_hid_report_append_fields(usb_hid_report_t *report, 164 usb_hid_report_item_t *report_item) { 165 108 109 /* 110 * 111 * 112 */ 113 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 114 { 166 115 usb_hid_report_field_t *field; 167 116 int i; 168 117 169 uint32_t *usages; 170 int usages_used=0; 171 172 if((report == NULL) || (report_item == NULL)) { 173 return EINVAL; 174 } 175 176 if(report_item->usages_count > 0){ 177 usages = malloc(sizeof(int32_t) * report_item->usages_count); 178 memcpy(usages, report_item->usages, sizeof(int32_t) * 179 report_item->usages_count); 180 } 181 else { 182 usages = NULL; 183 } 184 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 185 122 usb_hid_report_path_t *path = report_item->usage_path; 186 123 for(i=0; i<report_item->count; i++){ … … 196 133 field->physical_maximum = report_item->physical_maximum; 197 134 198 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){ 199 /* 200 Store usage array. The Correct Usage Page and Usage is 201 depending on data in report and will be filled later 202 */ 203 field->usage = 0; 204 field->usage_page = 0; //report_item->usage_page; 205 206 field->usages_count = report_item->usages_count; 207 field->usages = usages; 208 usages_used = 1; 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; 209 139 } 210 140 else { 211 212 /* Fill the correct Usage and Usage Page */ 213 int32_t usage; 214 if(i < report_item->usages_count) { 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){ 215 147 usage = report_item->usages[i]; 216 148 } 217 149 else { 218 usage = report_item->usages[ 219 report_item->usages_count- 1]; 220 } 221 222 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 223 field->usage = USB_HID_EXTENDED_USAGE(usage); 224 field->usage_page = 225 USB_HID_EXTENDED_USAGE_PAGE(usage); 150 usage = report_item->usages[report_item->usages_count - 1]; 151 } 152 153 154 if((usage & 0xFFFF0000) != 0){ 155 field->usage_page = (usage >> 16); 156 field->usage = (usage & 0xFFFF); 226 157 } 227 158 else { 228 // should not occur229 159 field->usage = usage; 230 field->usage_page = report_item->usage_page; 231 } 232 } 233 234 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, 235 field->usage_page); 236 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, 237 field->usage); 238 239 field->collection_path = 240 usb_hid_report_path_try_insert(report, path); 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; 167 } 168 169 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page); 170 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage); 171 172 field->collection_path = usb_hid_report_path_try_insert(report, path); 241 173 242 174 field->size = report_item->size; 243 175 244 size_t offset_byte = (report_item->offset + (i * 245 report_item->size)) / 8; 246 247 size_t offset_bit = 8 - ((report_item->offset + (i * 248 report_item->size)) % 8) - report_item->size; 176 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8; 177 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size; 249 178 250 179 field->offset = 8 * offset_byte + offset_bit; … … 257 186 /* find the right report list*/ 258 187 usb_hid_report_description_t *report_des; 259 report_des = usb_hid_report_find_description(report, 260 report_item->id, report_item->type); 261 188 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 262 189 if(report_des == NULL){ 263 report_des = malloc( 264 sizeof(usb_hid_report_description_t)); 265 if(report_des == NULL) { 266 return ENOMEM; 267 } 268 269 memset(report_des, 0, 270 sizeof(usb_hid_report_description_t)); 190 report_des = malloc(sizeof(usb_hid_report_description_t)); 191 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 271 192 272 193 report_des->type = report_item->type; 273 194 report_des->report_id = report_item->id; 274 if(report_des->report_id != 0) {275 /* set up the bit length by report_id field */276 report_des->bit_length = 8;277 }278 279 195 list_initialize (&report_des->link); 280 196 list_initialize (&report_des->report_items); … … 293 209 } 294 210 295 // free only when not used!!!296 if(usages && usages_used == 0) {297 free(usages);298 }299 211 300 212 return EOK; 301 213 } 302 /*---------------------------------------------------------------------------*/ 303 /** 304 * Finds description of report with given report_id and of given type in 305 * opaque report structure. 306 * 307 * @param report Opaque structure containing the parsed report descriptor 308 * @param report_id ReportId of report we are searching 309 * @param type Type of report we are searching 310 * @return Pointer to the particular report description 311 * @retval NULL If no description is founded 312 */ 313 usb_hid_report_description_t * usb_hid_report_find_description( 314 const usb_hid_report_t *report, uint8_t report_id, 315 usb_hid_report_type_t type) { 316 214 215 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 216 { 317 217 link_t *report_it = report->reports.next; 318 218 usb_hid_report_description_t *report_des = NULL; 319 219 320 220 while(report_it != &report->reports) { 321 report_des = list_get_instance(report_it, 322 usb_hid_report_description_t, link); 323 324 if((report_des->report_id == report_id) && 325 (report_des->type == type)) { 221 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 222 223 if((report_des->report_id == report_id) && (report_des->type == type)){ 326 224 return report_des; 327 225 } … … 332 230 return NULL; 333 231 } 334 /*---------------------------------------------------------------------------*/335 232 336 233 /** Parse HID report descriptor. … … 339 236 * @param data Data describing the report. 340 237 * @return Error code. 341 * @retval ENOMEM If no more memmory is available342 * @retval EINVAL If invalid data are founded343 * @retval EOK If report descriptor is successfully parsed344 238 */ 345 239 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 392 286 393 287 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 394 item_size,report_item, usage_path); 395 288 item_size,report_item, usage_path); 396 289 switch(ret){ 397 case USB_HID_NEW_REPORT_ITEM: 398 /* store report item to report and create the 399 * new one store current collection path 400 */ 401 report_item->usage_path = usage_path; 290 case USB_HID_NEW_REPORT_ITEM: 291 // store report item to report and create the new one 292 // store current collection path 293 report_item->usage_path = usage_path; 402 294 403 usb_hid_report_path_set_report_id( 404 report_item->usage_path, report_item->id); 405 406 if(report_item->id != 0){ 407 report->use_report_ids = 1; 408 } 295 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 296 if(report_item->id != 0){ 297 report->use_report_ids = 1; 298 } 409 299 410 switch(tag) { 411 case USB_HID_REPORT_TAG_INPUT: 412 report_item->type = 413 USB_HID_REPORT_TYPE_INPUT; 414 415 report_item->offset = offset_input; 416 offset_input += report_item->count * 417 report_item->size; 300 switch(tag) { 301 case USB_HID_REPORT_TAG_INPUT: 302 report_item->type = USB_HID_REPORT_TYPE_INPUT; 303 report_item->offset = offset_input; 304 offset_input += report_item->count * report_item->size; 305 break; 306 case USB_HID_REPORT_TAG_OUTPUT: 307 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 308 report_item->offset = offset_output; 309 offset_output += report_item->count * report_item->size; 310 311 break; 312 case USB_HID_REPORT_TAG_FEATURE: 313 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 314 report_item->offset = offset_feature; 315 offset_feature += report_item->count * report_item->size; 316 break; 317 default: 318 usb_log_debug("\tjump over - tag %X\n", tag); 319 break; 320 } 321 322 /* 323 * append new fields to the report 324 * structure 325 */ 326 usb_hid_report_append_fields(report, report_item); 327 328 /* reset local items */ 329 usb_hid_report_reset_local_items (report_item); 330 418 331 break; 419 420 case USB_HID_REPORT_TAG_OUTPUT: 421 report_item->type = 422 USB_HID_REPORT_TYPE_OUTPUT; 332 333 case USB_HID_RESET_OFFSET: 334 offset_input = 0; 335 offset_output = 0; 336 offset_feature = 0; 337 usb_hid_report_path_set_report_id (usage_path, report_item->id); 338 break; 339 340 case USB_HID_REPORT_TAG_PUSH: 341 // push current state to stack 342 new_report_item = usb_hid_report_item_clone(report_item); 343 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 344 new_report_item->usage_path = tmp_path; 345 346 list_prepend (&new_report_item->link, &stack); 347 break; 348 case USB_HID_REPORT_TAG_POP: 349 // restore current state from stack 350 if(list_empty (&stack)) { 351 return EINVAL; 352 } 353 free(report_item); 354 355 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 423 356 424 report_item->offset = offset_output; 425 offset_output += report_item->count * 426 report_item->size; 357 usb_hid_report_usage_path_t *tmp_usage_path; 358 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 359 360 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 361 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 362 363 usb_hid_report_path_free(report_item->usage_path); 364 list_initialize(&report_item->usage_path->link); 365 list_remove (stack.next); 366 427 367 break; 428 429 case USB_HID_REPORT_TAG_FEATURE: 430 report_item->type = 431 USB_HID_REPORT_TYPE_FEATURE; 432 433 report_item->offset = offset_feature; 434 offset_feature += report_item->count * 435 report_item->size; 368 369 default: 370 // nothing special to do 436 371 break; 437 438 default:439 usb_log_debug2(440 "\tjump over - tag %X\n", tag);441 break;442 }443 444 /*445 * append new fields to the report structure446 */447 usb_hid_report_append_fields(report,448 report_item);449 450 /* reset local items */451 usb_hid_report_reset_local_items (report_item);452 break;453 454 case USB_HID_RESET_OFFSET:455 offset_input = 0;456 offset_output = 0;457 offset_feature = 0;458 usb_hid_report_path_set_report_id (usage_path,459 report_item->id);460 break;461 462 case USB_HID_REPORT_TAG_PUSH:463 // push current state to stack464 new_report_item = usb_hid_report_item_clone(465 report_item);466 467 usb_hid_report_path_t *tmp_path =468 usb_hid_report_path_clone(usage_path);469 470 new_report_item->usage_path = tmp_path;471 472 list_prepend (&new_report_item->link, &stack);473 break;474 case USB_HID_REPORT_TAG_POP:475 // restore current state from stack476 if(list_empty (&stack)) {477 return EINVAL;478 }479 free(report_item);480 481 report_item = list_get_instance(stack.next,482 usb_hid_report_item_t, link);483 484 usb_hid_report_usage_path_t *tmp_usage_path;485 tmp_usage_path = list_get_instance(486 report_item->usage_path->link.prev,487 usb_hid_report_usage_path_t, link);488 489 usb_hid_report_set_last_item(usage_path,490 USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);491 492 usb_hid_report_set_last_item(usage_path,493 USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);494 495 usb_hid_report_path_free(report_item->usage_path);496 list_initialize(&report_item->usage_path->link);497 list_remove (stack.next);498 499 break;500 501 default:502 // nothing special to do503 break;504 372 } 505 373 … … 518 386 } 519 387 520 /*---------------------------------------------------------------------------*/521 388 522 389 /** … … 529 396 * @return Code of action to be done next 530 397 */ 531 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 532 size_t item_size, usb_hid_report_item_t *report_item, 533 usb_hid_report_path_t *usage_path) { 534 398 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 399 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 400 { 535 401 int ret; 536 402 537 403 switch(class){ 538 case USB_HID_TAG_CLASS_MAIN: 539 540 if((ret=usb_hid_report_parse_main_tag(tag, data, item_size, 541 report_item, usage_path)) == EOK) { 542 543 return USB_HID_NEW_REPORT_ITEM; 544 } 545 else { 546 return ret; 547 } 548 break; 549 550 case USB_HID_TAG_CLASS_GLOBAL: 551 return usb_hid_report_parse_global_tag(tag, data, item_size, 552 report_item, usage_path); 553 break; 554 555 case USB_HID_TAG_CLASS_LOCAL: 556 return usb_hid_report_parse_local_tag(tag, data, item_size, 557 report_item, usage_path); 558 break; 559 560 default: 561 return USB_HID_NO_ACTION; 404 case USB_HID_TAG_CLASS_MAIN: 405 406 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 407 return USB_HID_NEW_REPORT_ITEM; 408 } 409 else { 410 /*TODO process the error */ 411 return ret; 412 } 413 break; 414 415 case USB_HID_TAG_CLASS_GLOBAL: 416 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 417 break; 418 419 case USB_HID_TAG_CLASS_LOCAL: 420 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 421 break; 422 default: 423 return USB_HID_NO_ACTION; 562 424 } 563 425 } … … 573 435 */ 574 436 575 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 576 size_t item_size, usb_hid_report_item_t *report_item, 577 usb_hid_report_path_t *usage_path) 437 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 438 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 578 439 { 579 440 usb_hid_report_usage_path_t *path_item; … … 581 442 switch(tag) 582 443 { 583 case USB_HID_REPORT_TAG_INPUT:584 case USB_HID_REPORT_TAG_OUTPUT:585 case USB_HID_REPORT_TAG_FEATURE:586 report_item->item_flags = *data;587 return EOK;588 break;444 case USB_HID_REPORT_TAG_INPUT: 445 case USB_HID_REPORT_TAG_OUTPUT: 446 case USB_HID_REPORT_TAG_FEATURE: 447 report_item->item_flags = *data; 448 return EOK; 449 break; 589 450 590 case USB_HID_REPORT_TAG_COLLECTION: 591 592 /* store collection atributes */ 593 path_item = list_get_instance(usage_path->head.prev, 594 usb_hid_report_usage_path_t, link); 595 path_item->flags = *data; 451 case USB_HID_REPORT_TAG_COLLECTION: 452 // store collection atributes 453 path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 454 path_item->flags = *data; 596 455 597 /* set last item */ 598 usb_hid_report_set_last_item(usage_path, 599 USB_HID_TAG_CLASS_GLOBAL, 600 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[ 601 report_item->usages_count-1])); 602 603 usb_hid_report_set_last_item(usage_path, 604 USB_HID_TAG_CLASS_LOCAL, 605 USB_HID_EXTENDED_USAGE(report_item->usages[ 606 report_item->usages_count-1])); 456 // 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]); 607 459 608 /* append the new one which will be set by common usage/usage 609 * page */ 610 usb_hid_report_path_append_item(usage_path, 611 report_item->usage_page, 612 report_item->usages[report_item->usages_count-1]); 613 614 usb_hid_report_reset_local_items (report_item); 615 return USB_HID_NO_ACTION; 616 break; 460 // append the new one which will be set by common 461 // usage/usage page 462 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 463 usb_hid_report_reset_local_items (report_item); 464 return USB_HID_NO_ACTION; 465 break; 617 466 618 case USB_HID_REPORT_TAG_END_COLLECTION: 619 usb_hid_report_remove_last_item(usage_path); 620 return USB_HID_NO_ACTION; 621 break; 622 623 default: 624 return USB_HID_NO_ACTION; 467 case USB_HID_REPORT_TAG_END_COLLECTION: 468 usb_hid_report_remove_last_item(usage_path); 469 return USB_HID_NO_ACTION; 470 break; 471 default: 472 return USB_HID_NO_ACTION; 625 473 } 626 474 … … 637 485 * @return Error code 638 486 */ 639 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 640 size_t item_size, usb_hid_report_item_t *report_item, 641 usb_hid_report_path_t *usage_path) { 642 487 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 488 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 489 { 490 // TODO take care about the bit length of data 643 491 switch(tag) 644 492 { 645 case USB_HID_REPORT_TAG_USAGE_PAGE: 646 report_item->usage_page = 647 usb_hid_report_tag_data_uint32(data, item_size); 648 break; 649 650 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 651 report_item->logical_minimum = USB_HID_UINT32_TO_INT32( 652 usb_hid_report_tag_data_uint32(data,item_size), 653 item_size * 8); 654 break; 655 656 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 657 report_item->logical_maximum = USB_HID_UINT32_TO_INT32( 658 usb_hid_report_tag_data_uint32(data,item_size), 659 item_size * 8); 660 break; 661 662 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 663 report_item->physical_minimum = USB_HID_UINT32_TO_INT32( 664 usb_hid_report_tag_data_uint32(data,item_size), 665 item_size * 8); 666 break; 667 668 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 669 report_item->physical_maximum = USB_HID_UINT32_TO_INT32( 670 usb_hid_report_tag_data_uint32(data,item_size), 671 item_size * 8); 672 break; 673 674 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 675 report_item->unit_exponent = usb_hid_report_tag_data_uint32( 676 data,item_size); 677 break; 678 679 case USB_HID_REPORT_TAG_UNIT: 680 report_item->unit = usb_hid_report_tag_data_uint32( 681 data,item_size); 682 break; 683 684 case USB_HID_REPORT_TAG_REPORT_SIZE: 685 report_item->size = usb_hid_report_tag_data_uint32( 686 data,item_size); 687 break; 688 689 case USB_HID_REPORT_TAG_REPORT_COUNT: 690 report_item->count = usb_hid_report_tag_data_uint32( 691 data,item_size); 692 break; 693 694 case USB_HID_REPORT_TAG_REPORT_ID: 695 report_item->id = usb_hid_report_tag_data_uint32(data, 696 item_size); 697 return USB_HID_RESET_OFFSET; 698 break; 699 700 case USB_HID_REPORT_TAG_PUSH: 701 case USB_HID_REPORT_TAG_POP: 702 /* 703 * stack operations are done in top level parsing 704 * function 705 */ 706 return tag; 707 break; 493 case USB_HID_REPORT_TAG_USAGE_PAGE: 494 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 495 break; 496 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 497 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 498 break; 499 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 500 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 501 break; 502 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 503 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 504 break; 505 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 506 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 507 508 break; 509 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 510 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 511 break; 512 case USB_HID_REPORT_TAG_UNIT: 513 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 514 break; 515 case USB_HID_REPORT_TAG_REPORT_SIZE: 516 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 517 break; 518 case USB_HID_REPORT_TAG_REPORT_COUNT: 519 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 520 break; 521 case USB_HID_REPORT_TAG_REPORT_ID: 522 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 523 return USB_HID_RESET_OFFSET; 524 break; 525 case USB_HID_REPORT_TAG_PUSH: 526 case USB_HID_REPORT_TAG_POP: 527 /* 528 * stack operations are done in top level parsing 529 * function 530 */ 531 return tag; 532 break; 708 533 709 default:710 return USB_HID_NO_ACTION;534 default: 535 return USB_HID_NO_ACTION; 711 536 } 712 537 … … 723 548 * @return Error code 724 549 */ 725 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 726 size_t item_size, usb_hid_report_item_t *report_item, 727 usb_hid_report_path_t *usage_path) 728 { 729 int32_t extended_usage; 730 550 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 551 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 552 { 731 553 switch(tag) { 732 case USB_HID_REPORT_TAG_USAGE: 733 switch(report_item->in_delimiter) { 734 case INSIDE_DELIMITER_SET: 735 /* nothing to do 736 * we catch only the first one 737 */ 738 break; 739 740 case START_DELIMITER_SET: 741 report_item->in_delimiter = INSIDE_DELIMITER_SET; 742 case OUTSIDE_DELIMITER_SET: 743 extended_usage = ((report_item->usage_page) << 16); 744 extended_usage += usb_hid_report_tag_data_uint32( 745 data,item_size); 746 747 report_item->usages[report_item->usages_count] = 748 extended_usage; 749 750 report_item->usages_count++; 751 break; 752 } 753 break; 754 755 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 756 if (item_size == 3) { 757 // usage extended usages 758 report_item->extended_usage_page = 759 USB_HID_EXTENDED_USAGE_PAGE( 760 usb_hid_report_tag_data_uint32(data,item_size)); 761 762 763 report_item->usage_minimum = 764 USB_HID_EXTENDED_USAGE( 765 usb_hid_report_tag_data_uint32(data,item_size)); 766 } 767 else { 768 report_item->usage_minimum = 769 usb_hid_report_tag_data_uint32(data,item_size); 770 } 771 break; 772 773 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 774 if (item_size == 3) { 775 if(report_item->extended_usage_page != 776 USB_HID_EXTENDED_USAGE_PAGE( 777 usb_hid_report_tag_data_uint32(data,item_size))) { 778 779 return EINVAL; 780 } 781 782 // usage extended usages 783 report_item->extended_usage_page = 784 USB_HID_EXTENDED_USAGE_PAGE( 785 usb_hid_report_tag_data_uint32(data,item_size)); 786 787 report_item->usage_maximum = 788 USB_HID_EXTENDED_USAGE( 789 usb_hid_report_tag_data_uint32(data,item_size)); 790 } 791 else { 792 report_item->usage_maximum = 793 usb_hid_report_tag_data_uint32(data,item_size); 794 } 795 796 // vlozit zaznamy do pole usages 797 int32_t i; 798 for(i = report_item->usage_minimum; 799 i <= report_item->usage_maximum; i++) { 800 801 if(report_item->extended_usage_page) { 802 report_item->usages[report_item->usages_count++] = 803 (report_item->extended_usage_page << 16) + i; 804 } 805 else { 806 report_item->usages[report_item->usages_count++] = 807 (report_item->usage_page << 16) + i; 808 } 809 } 810 report_item->extended_usage_page = 0; 811 812 break; 813 814 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 815 report_item->designator_index = 816 usb_hid_report_tag_data_uint32(data,item_size); 817 break; 818 819 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 820 report_item->designator_minimum = 821 usb_hid_report_tag_data_uint32(data,item_size); 822 break; 823 824 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 825 report_item->designator_maximum = 826 usb_hid_report_tag_data_uint32(data,item_size); 827 break; 828 829 case USB_HID_REPORT_TAG_STRING_INDEX: 830 report_item->string_index = 831 usb_hid_report_tag_data_uint32(data,item_size); 832 break; 833 834 case USB_HID_REPORT_TAG_STRING_MINIMUM: 835 report_item->string_minimum = 836 usb_hid_report_tag_data_uint32(data,item_size); 837 break; 838 839 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 840 report_item->string_maximum = 841 usb_hid_report_tag_data_uint32(data,item_size); 842 break; 843 844 case USB_HID_REPORT_TAG_DELIMITER: 845 report_item->in_delimiter = 846 usb_hid_report_tag_data_uint32(data,item_size); 847 break; 848 849 default: 850 return USB_HID_NO_ACTION; 554 case USB_HID_REPORT_TAG_USAGE: 555 switch(report_item->in_delimiter) { 556 case INSIDE_DELIMITER_SET: 557 // nothing to do 558 break; 559 case START_DELIMITER_SET: 560 report_item->in_delimiter = INSIDE_DELIMITER_SET; 561 case OUTSIDE_DELIMITER_SET: 562 report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size); 563 report_item->usages_count++; 564 break; 565 } 566 break; 567 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 568 if (item_size == 3) { 569 // usage extended usages 570 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 571 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 572 } 573 else { 574 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 575 } 576 break; 577 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 578 if (item_size == 3) { 579 // usage extended usages 580 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 581 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 582 } 583 else { 584 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 585 } 586 break; 587 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 588 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 589 break; 590 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 591 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 592 break; 593 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 594 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 595 break; 596 case USB_HID_REPORT_TAG_STRING_INDEX: 597 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 598 break; 599 case USB_HID_REPORT_TAG_STRING_MINIMUM: 600 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 601 break; 602 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 603 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 604 break; 605 case USB_HID_REPORT_TAG_DELIMITER: 606 report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size); 607 break; 608 609 default: 610 return USB_HID_NO_ACTION; 851 611 } 852 612 853 613 return EOK; 854 614 } 855 /*---------------------------------------------------------------------------*/856 615 857 616 /** … … 874 633 return result; 875 634 } 876 /*---------------------------------------------------------------------------*/877 635 878 636 /** … … 895 653 for(item = head->next; item != head; item = item->next) { 896 654 897 report_item = list_get_instance(item, usb_hid_report_field_t, 898 link); 655 report_item = list_get_instance(item, usb_hid_report_field_t, link); 899 656 900 657 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 901 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 902 usb_log_debug("\t\tLOGMIN: %d\n", 903 report_item->logical_minimum); 904 usb_log_debug("\t\tLOGMAX: %d\n", 905 report_item->logical_maximum); 906 usb_log_debug("\t\tPHYMIN: %d\n", 907 report_item->physical_minimum); 908 usb_log_debug("\t\tPHYMAX: %d\n", 909 report_item->physical_maximum); 910 usb_log_debug("\t\ttUSAGEMIN: %X\n", 911 report_item->usage_minimum); 912 usb_log_debug("\t\tUSAGEMAX: %X\n", 913 report_item->usage_maximum); 914 usb_log_debug("\t\tUSAGES COUNT: %zu\n", 915 report_item->usages_count); 658 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 659 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 660 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 661 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 662 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 663 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 664 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 916 665 917 666 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 919 668 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 920 669 921 usb_hid_print_usage_path(report_item->collection_path);670 //usb_hid_print_usage_path(report_item->collection_path); 922 671 923 672 usb_log_debug("\n"); … … 925 674 } 926 675 927 } 928 /*---------------------------------------------------------------------------*/ 929 676 677 } 930 678 /** 931 679 * Prints content of given report descriptor in human readable format. … … 944 692 945 693 while(report_it != &report->reports) { 946 report_des = list_get_instance(report_it, 947 usb_hid_report_description_t, link); 694 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 948 695 usb_log_debug("Report ID: %d\n", report_des->report_id); 949 696 usb_log_debug("\tType: %d\n", report_des->type); 950 697 usb_log_debug("\tLength: %zu\n", report_des->bit_length); 951 usb_log_debug("\tB Size: %zu\n",952 usb_hid_report_byte_size(report,953 report_des->report_id,954 report_des->type));955 698 usb_log_debug("\tItems: %zu\n", report_des->item_length); 956 699 957 700 usb_hid_descriptor_print_list(&report_des->report_items); 958 701 702 703 link_t *path_it = report->collection_paths.next; 704 while(path_it != &report->collection_paths) { 705 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link)); 706 path_it = path_it->next; 707 } 708 959 709 report_it = report_it->next; 960 710 } 961 711 } 962 /*---------------------------------------------------------------------------*/963 712 964 713 /** … … 985 734 986 735 while(!list_empty(&report_item->usage_path->link)) { 987 736 usb_hid_report_remove_last_item(report_item->usage_path); 988 737 } 989 738 … … 997 746 998 747 } 999 /*---------------------------------------------------------------------------*/1000 748 1001 749 /** Frees the HID report descriptor parser structure … … 1013 761 usb_hid_report_path_t *path; 1014 762 while(!list_empty(&report->collection_paths)) { 1015 path = list_get_instance(report->collection_paths.next, 1016 usb_hid_report_path_t, link); 1017 763 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 1018 764 usb_hid_report_path_free(path); 1019 765 } … … 1023 769 usb_hid_report_field_t *field; 1024 770 while(!list_empty(&report->reports)) { 1025 report_des = list_get_instance(report->reports.next, 1026 usb_hid_report_description_t, link); 1027 771 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 1028 772 list_remove(&report_des->link); 1029 773 1030 774 while(!list_empty(&report_des->report_items)) { 1031 field = list_get_instance( 1032 report_des->report_items.next, 1033 usb_hid_report_field_t, link); 1034 775 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 1035 776 list_remove(&field->link); 1036 777 … … 1043 784 return; 1044 785 } 1045 /*---------------------------------------------------------------------------*/1046 786 1047 787 /** -
uspace/lib/usbhid/src/hidiface.c
r6bfaab5 r88be3a0b 46 46 * @return Number of usages returned or negative error code. 47 47 */ 48 int usbhid_dev_get_event_length(int dev_phone , size_t *size)48 int usbhid_dev_get_event_length(int dev_phone) 49 49 { 50 50 if (dev_phone < 0) { … … 56 56 IPC_M_USBHID_GET_EVENT_LENGTH, &len); 57 57 if (rc == EOK) { 58 if (size != NULL) {59 *size = (size_t) len;60 }58 return (int) len; 59 } else { 60 return rc; 61 61 } 62 63 return rc;64 62 } 65 63 … … 76 74 * @return Error code. 77 75 */ 78 int usbhid_dev_get_event(int dev_phone, uint 8_t *buf,79 size_t size, size_t *actual_size, int *event_nr, unsigned int flags)76 int usbhid_dev_get_event(int dev_phone, uint16_t *usage_pages, uint16_t *usages, 77 size_t usage_count, size_t *actual_usage_count, unsigned int flags) 80 78 { 81 79 if (dev_phone < 0) { 82 80 return EINVAL; 83 81 } 84 if (( buf== NULL)) {82 if ((usage_pages == NULL) || (usages == NULL)) { 85 83 return ENOMEM; 86 84 } 87 if ( size== 0) {85 if (usage_count == 0) { 88 86 return EINVAL; 89 87 } 90 91 // if (size == 0) {92 // return EOK;93 // }94 88 95 size_t buffer_size = size;96 uint 8_t *buffer = malloc(buffer_size);89 size_t buffer_size = sizeof(uint16_t) * usage_count * 2; 90 uint16_t *buffer = malloc(buffer_size); 97 91 if (buffer == NULL) { 98 92 return ENOMEM; 99 93 } 100 94 101 ipc_call_t opening_request_call;102 95 aid_t opening_request = async_send_2(dev_phone, 103 96 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT, 104 flags, &opening_request_call);97 flags, NULL); 105 98 if (opening_request == 0) { 106 99 free(buffer); … … 135 128 } 136 129 137 size_t act_size = IPC_GET_ARG2(data_request_call); 130 size_t actual_size = IPC_GET_ARG2(data_request_call); 131 size_t items = actual_size / 2; 138 132 139 133 /* Copy the individual items. */ 140 memcpy( buf, buffer, act_size);141 // memcpy(usages, buffer + items, items * sizeof(int32_t));134 memcpy(usage_pages, buffer, items * sizeof(uint16_t)); 135 memcpy(usages, buffer + items, items * sizeof(uint16_t)); 142 136 143 if (actual_size != NULL) { 144 *actual_size = act_size; 145 } 146 147 if (event_nr != NULL) { 148 *event_nr = IPC_GET_ARG1(opening_request_call); 149 } 150 151 return EOK; 152 } 153 154 155 int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size) 156 { 157 if (dev_phone < 0) { 158 return EINVAL; 159 } 160 161 sysarg_t arg_size; 162 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE), 163 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size); 164 if (rc == EOK) { 165 if (size != NULL) { 166 *size = (size_t) arg_size; 167 } 168 } 169 return rc; 170 } 171 172 int usbhid_dev_get_report_descriptor(int dev_phone, uint8_t *buf, size_t size, 173 size_t *actual_size) 174 { 175 if (dev_phone < 0) { 176 return EINVAL; 177 } 178 if ((buf == NULL)) { 179 return ENOMEM; 180 } 181 if (size == 0) { 182 return EINVAL; 183 } 184 185 aid_t opening_request = async_send_1(dev_phone, 186 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR, 187 NULL); 188 if (opening_request == 0) { 189 return ENOMEM; 190 } 191 192 ipc_call_t data_request_call; 193 aid_t data_request = async_data_read(dev_phone, buf, size, 194 &data_request_call); 195 if (data_request == 0) { 196 async_wait_for(opening_request, NULL); 197 return ENOMEM; 198 } 199 200 sysarg_t data_request_rc; 201 sysarg_t opening_request_rc; 202 async_wait_for(data_request, &data_request_rc); 203 async_wait_for(opening_request, &opening_request_rc); 204 205 if (data_request_rc != EOK) { 206 /* Prefer return code of the opening request. */ 207 if (opening_request_rc != EOK) { 208 return (int) opening_request_rc; 209 } else { 210 return (int) data_request_rc; 211 } 212 } 213 214 if (opening_request_rc != EOK) { 215 return (int) opening_request_rc; 216 } 217 218 size_t act_size = IPC_GET_ARG2(data_request_call); 219 220 if (actual_size != NULL) { 221 *actual_size = act_size; 137 if (actual_usage_count != NULL) { 138 *actual_usage_count = items; 222 139 } 223 140 -
uspace/lib/usbhid/src/hidparser.c
r6bfaab5 r88be3a0b 31 31 */ 32 32 /** @file 33 * USB HIDreport data parser implementation.33 * HID report descriptor and report data parser implementation. 34 34 */ 35 35 #include <usb/hid/hidparser.h> … … 41 41 #include <assert.h> 42 42 43 /*---------------------------------------------------------------------------*/ 43 44 44 /* 45 45 * Data translation private functions 46 46 */ 47 47 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 48 48 //inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 49 49 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data); 50 51 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 52 int32_t value); 53 50 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 54 51 int usb_pow(int a, int b); 55 52 56 /*---------------------------------------------------------------------------*/57 53 58 54 // TODO: tohle ma bejt asi jinde … … 60 56 { 61 57 switch(b) { 62 case 0: 63 return 1; 64 break; 65 case 1: 66 return a; 67 break; 68 default: 69 return a * usb_pow(a, b-1); 70 break; 71 } 72 } 73 /*---------------------------------------------------------------------------*/ 74 75 /** Returns size of report of specified report id and type in items 76 * 77 * @param parser Opaque report parser structure 78 * @param report_id 79 * @param type 80 * @return Number of items in specified report 81 */ 82 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 83 usb_hid_report_type_t type) 84 { 85 usb_hid_report_description_t *report_des; 86 87 if(report == NULL) { 88 return 0; 89 } 90 91 report_des = usb_hid_report_find_description (report, report_id, type); 92 if(report_des == NULL){ 93 return 0; 94 } 95 else { 96 return report_des->item_length; 97 } 98 } 99 100 /** Returns size of report of specified report id and type in bytes 101 * 102 * @param parser Opaque report parser structure 103 * @param report_id 104 * @param type 105 * @return Number of items in specified report 106 */ 107 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id, 108 usb_hid_report_type_t type) 109 { 110 usb_hid_report_description_t *report_des; 111 112 if(report == NULL) { 113 return 0; 114 } 115 116 report_des = usb_hid_report_find_description (report, report_id, type); 117 if(report_des == NULL){ 118 return 0; 119 } 120 else { 121 return ((report_des->bit_length + 7) / 8) ; 122 } 123 } 124 /*---------------------------------------------------------------------------*/ 58 case 0: 59 return 1; 60 break; 61 case 1: 62 return a; 63 break; 64 default: 65 return a * usb_pow(a, b-1); 66 break; 67 } 68 } 69 70 71 125 72 126 73 /** Parse and act upon a HID report. … … 132 79 * @return Error code. 133 80 */ 134 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data,135 81 int usb_hid_parse_report(const usb_hid_report_t *report, 82 const uint8_t *data, size_t size, uint8_t *report_id) 136 83 { 137 84 link_t *list_item; … … 140 87 usb_hid_report_description_t *report_des; 141 88 usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT; 142 89 143 90 if(report == NULL) { 144 91 return EINVAL; … … 154 101 155 102 report_des = usb_hid_report_find_description(report, *report_id, type); 156 if(report_des == NULL) {157 return EINVAL;158 }159 103 160 104 /* read data */ … … 162 106 while(list_item != &(report_des->report_items)) { 163 107 164 item = list_get_instance(list_item, usb_hid_report_field_t, 165 link); 108 item = list_get_instance(list_item, usb_hid_report_field_t, link); 166 109 167 110 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) { … … 170 113 171 114 // array 172 item->value = 173 usb_hid_translate_data(item, data); 174 175 item->usage = USB_HID_EXTENDED_USAGE( 176 item->usages[item->value - item->physical_minimum]); 177 178 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE( 179 item->usages[item->value - item->physical_minimum]); 180 181 usb_hid_report_set_last_item (item->collection_path, 182 USB_HID_TAG_CLASS_GLOBAL, item->usage_page); 183 184 usb_hid_report_set_last_item (item->collection_path, 185 USB_HID_TAG_CLASS_LOCAL, item->usage); 186 115 item->value = usb_hid_translate_data(item, data); 116 item->usage = (item->value - item->physical_minimum) + item->usage_minimum; 187 117 } 188 118 else { … … 193 123 list_item = list_item->next; 194 124 } 195 125 196 126 return EOK; 197 127 198 128 } 199 129 200 /*---------------------------------------------------------------------------*/201 130 /** 202 131 * Translate data from the report as specified in report descriptor item … … 204 133 * @param item Report descriptor item with definition of translation 205 134 * @param data Data to translate 135 * @param j Index of processed field in report descriptor item 206 136 * @return Translated data 207 137 */ … … 272 202 } 273 203 274 return (int)(((value - item->logical_minimum) / resolution) + 275 item->physical_minimum); 276 277 } 278 279 /*---------------------------------------------------------------------------*/ 280 /* OUTPUT API */ 204 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 205 206 } 207 208 /** 209 * Returns number of items in input report which are accessible by given usage path 210 * 211 * @param parser Opaque report descriptor structure 212 * @param path Usage path specification 213 * @param flags Usage path comparison flags 214 * @return Number of items in input report 215 */ 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 /*** OUTPUT API **/ 281 253 282 254 /** … … 288 260 * @return Returns allocated output buffer for specified output 289 261 */ 290 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 291 uint8_t report_id) 262 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 292 263 { 293 264 if(report == NULL) { … … 299 270 usb_hid_report_description_t *report_des = NULL; 300 271 while(report_it != &report->reports) { 301 report_des = list_get_instance(report_it, 302 usb_hid_report_description_t, link); 303 304 if((report_des->report_id == report_id) && 305 (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 272 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 273 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 306 274 break; 307 275 } … … 334 302 free (output); 335 303 } 304 } 305 306 /** Returns size of output for given usage path 307 * 308 * @param parser Opaque report parser structure 309 * @param path Usage path specified which items will be thought for the output 310 * @param flags Flags of usage path structure comparison 311 * @return Number of items matching the given usage path 312 */ 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 336 346 } 337 347 … … 345 355 * @return Error code 346 356 */ 347 int usb_hid_report_output_translate(usb_hid_report_t *report, 348 uint8_t report_id,uint8_t *buffer, size_t size)357 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 358 uint8_t *buffer, size_t size) 349 359 { 350 360 link_t *item; … … 362 372 } 363 373 374 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 375 364 376 usb_hid_report_description_t *report_des; 365 report_des = usb_hid_report_find_description (report, report_id, 366 USB_HID_REPORT_TYPE_OUTPUT); 367 377 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT); 368 378 if(report_des == NULL){ 369 379 return EINVAL; … … 375 385 report_item = list_get_instance(item, usb_hid_report_field_t, link); 376 386 377 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {387 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 378 388 379 // array 380 value = usb_hid_translate_data_reverse(report_item, 381 report_item->value); 382 383 offset = report_item->offset; 384 length = report_item->size; 385 } 386 else { 387 // variable item 388 value = usb_hid_translate_data_reverse(report_item, 389 report_item->value); 390 391 offset = report_item->offset; 392 length = report_item->size; 393 } 394 395 usb_log_debug("\ttranslated value: %x\n", value); 396 397 if((offset/8) == ((offset+length-1)/8)) { 398 // je to v jednom bytu 399 if(((size_t)(offset/8) >= size) || 400 ((size_t)(offset+length-1)/8) >= size) { 401 break; // TODO ErrorCode 402 } 403 size_t shift = 8 - offset%8 - length; 404 value = value << shift; 405 value = value & (((1 << length)-1) << shift); 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 405 } 406 407 size_t shift = 8 - offset%8 - length; 408 409 value = value << shift; 410 value = value & (((1 << length)-1) << shift); 406 411 407 uint8_t mask = 0; 408 mask = 0xff - (((1 << length) - 1) << shift); 409 buffer[offset/8] = (buffer[offset/8] & mask) | value; 410 } 411 else { 412 int i = 0; 413 uint8_t mask = 0; 414 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 415 if(i == (offset/8)) { 416 tmp_value = value; 417 tmp_value = tmp_value & 418 ((1 << (8-(offset%8)))-1); 419 420 tmp_value = tmp_value << (offset%8); 421 422 mask = ~(((1 << (8-(offset%8)))-1) << 423 (offset%8)); 424 425 buffer[i] = (buffer[i] & mask) | 426 tmp_value; 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 } 427 439 } 428 else if (i == ((offset + length -1)/8)) { 429 430 value = value >> (length - 431 ((offset + length) % 8)); 432 433 value = value & ((1 << (length - 434 ((offset + length) % 8))) - 1); 435 436 mask = (1 << (length - 437 ((offset + length) % 8))) - 1; 438 439 buffer[i] = (buffer[i] & mask) | value; 440 } 441 else { 442 buffer[i] = value & (0xFF << i); 443 } 444 } 445 } 440 } 441 446 442 447 443 // reset value … … 451 447 } 452 448 449 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 450 453 451 return EOK; 454 452 } 455 453 456 /*---------------------------------------------------------------------------*/457 454 /** 458 455 * Translate given data for putting them into the outoput report … … 461 458 * @return ranslated value 462 459 */ 463 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 464 int value) 460 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 465 461 { 466 462 int ret=0; … … 476 472 } 477 473 478 // variable item 479 if(item->physical_maximum == item->physical_minimum){ 480 resolution = 1; 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; 481 488 } 482 489 else { 483 resolution = (item->logical_maximum - item->logical_minimum) / 484 ((item->physical_maximum - item->physical_minimum) * 485 (usb_pow(10,(item->unit_exponent)))); 486 } 487 488 ret = ((value - item->physical_minimum) * resolution) + 489 item->logical_minimum; 490 491 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), \ 492 ret(%x)\n", value, resolution, item->physical_minimum, 493 item->logical_minimum, ret); 494 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 495 500 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 496 501 return USB_HID_INT32_TO_UINT32(ret, item->size); 497 502 } 498 return (int32_t)0 + ret; 499 } 500 501 /*---------------------------------------------------------------------------*/ 502 /** 503 * Clones given state table 504 * 505 * @param item State table to clone 506 * @return Pointer to the cloned item 507 */ 508 usb_hid_report_item_t *usb_hid_report_item_clone( 509 const usb_hid_report_item_t *item) 503 return (int32_t)ret; 504 } 505 506 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item) 510 507 { 511 508 usb_hid_report_item_t *new_report_item; … … 520 517 } 521 518 522 /*---------------------------------------------------------------------------*/ 523 /** 524 * Function for sequence walking through the report. Returns next field in the 525 * report or the first one when no field is given. 526 * 527 * @param report Searched report structure 528 * @param field Current field. If NULL is given, the first one in the report 529 * is returned. Otherwise the next one i nthe list is returned. 530 * @param path Usage path specifying which fields wa are interested in. 531 * @param flags Flags defining mode of usage paths comparison 532 * @param type Type of report we search. 533 * @retval NULL if no field is founded 534 * @retval Pointer to the founded report structure when founded 535 */ 519 536 520 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 537 usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, 538 usb_hid_report_type_t type) 539 { 540 usb_hid_report_description_t *report_des = 541 usb_hid_report_find_description(report, path->report_id, type); 542 521 usb_hid_report_field_t *field, 522 usb_hid_report_path_t *path, int flags, 523 usb_hid_report_type_t type) 524 { 525 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type); 543 526 link_t *field_it; 544 527 … … 548 531 549 532 if(field == NULL){ 533 // vezmu prvni co mathuje podle path!! 550 534 field_it = report_des->report_items.next; 551 535 } … … 555 539 556 540 while(field_it != &report_des->report_items) { 557 field = list_get_instance(field_it, usb_hid_report_field_t, 558 link); 541 field = list_get_instance(field_it, usb_hid_report_field_t, link); 559 542 560 543 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 561 usb_hid_report_path_append_item ( 562 field->collection_path, field->usage_page, 563 field->usage); 564 565 if(usb_hid_report_compare_usage_path( 566 field->collection_path, path, flags) == EOK){ 567 568 usb_hid_report_remove_last_item( 569 field->collection_path); 570 544 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 545 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){ 546 usb_hid_report_remove_last_item (field->collection_path); 571 547 return field; 572 548 } 573 usb_hid_report_remove_last_item ( 574 field->collection_path); 549 usb_hid_report_remove_last_item (field->collection_path); 575 550 } 576 551 field_it = field_it->next; … … 580 555 } 581 556 582 /*---------------------------------------------------------------------------*/ 583 /** 584 * Returns next report_id of report of specified type. If zero is given than 585 * first report_id of specified type is returned (0 is not legal value for 586 * repotr_id) 587 * 588 * @param report_id Current report_id, 0 if there is no current report_id 589 * @param type Type of searched report 590 * @param report Report structure inwhich we search 591 * @retval 0 if report structure is null or there is no specified report 592 * @retval report_id otherwise 593 */ 594 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, 595 uint8_t report_id, usb_hid_report_type_t type) 557 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 596 558 { 597 559 if(report == NULL){ … … 602 564 link_t *report_it; 603 565 604 if(report_id > 0) { 605 report_it = usb_hid_report_find_description(report, report_id, 606 type)->link.next; 566 if(report_id == 0) { 567 report_it = usb_hid_report_find_description (report, report_id, type)->link.next; 607 568 } 608 569 else { … … 611 572 612 573 while(report_it != &report->reports) { 613 report_des = list_get_instance(report_it, 614 usb_hid_report_description_t, link); 615 574 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 616 575 if(report_des->type == type){ 617 576 return report_des->report_id; … … 622 581 } 623 582 624 /*---------------------------------------------------------------------------*/625 /**626 * Reset all local items in given state table627 *628 * @param report_item State table containing current state of report629 * descriptor parsing630 *631 * @return void632 */633 583 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item) 634 584 { -
uspace/lib/usbhid/src/hidpath.c
r6bfaab5 r88be3a0b 41 41 #include <assert.h> 42 42 43 /*---------------------------------------------------------------------------*/ 44 /** 45 * Compares two usages if they are same or not or one of the usages is not 46 * set. 47 * 48 * @param usage1 49 * @param usage2 50 * @return boolean 51 */ 52 #define USB_HID_SAME_USAGE(usage1, usage2) \ 53 ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0)) 54 55 /** 56 * Compares two usage pages if they are same or not or one of them is not set. 57 * 58 * @param page1 59 * @param page2 60 * @return boolean 61 */ 62 #define USB_HID_SAME_USAGE_PAGE(page1, page2) \ 63 ((page1 == page2) || (page1 == 0) || (page2 == 0)) 64 65 /*---------------------------------------------------------------------------*/ 43 66 44 /** 67 45 * Appends one item (couple of usage_path and usage) into the usage path … … 92 70 } 93 71 94 /*---------------------------------------------------------------------------*/95 72 /** 96 73 * Removes last item from the usage path structure … … 111 88 } 112 89 113 /*---------------------------------------------------------------------------*/114 90 /** 115 91 * Nulls last item of the usage path structure. … … 123 99 124 100 if(!list_empty(&usage_path->head)){ 125 item = list_get_instance(usage_path->head.prev, 126 usb_hid_report_usage_path_t, link); 127 101 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 128 102 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 129 103 } 130 104 } 131 105 132 /*---------------------------------------------------------------------------*/133 106 /** 134 107 * Modifies last item of usage path structure by given usage page or usage … … 161 134 } 162 135 163 /*---------------------------------------------------------------------------*/ 164 /** 165 * 166 * 167 * 168 * 169 */ 136 170 137 void usb_hid_print_usage_path(usb_hid_report_path_t *path) 171 138 { … … 177 144 while(item != &path->head) { 178 145 179 path_item = list_get_instance(item, usb_hid_report_usage_path_t, 180 link); 181 146 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link); 182 147 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page); 183 148 usb_log_debug("\tUSAGE: %X\n", path_item->usage); 184 149 usb_log_debug("\tFLAGS: %d\n", path_item->flags); 185 150 186 item = item->next; 187 } 188 } 189 190 /*---------------------------------------------------------------------------*/ 151 item = item->next; 152 } 153 } 154 191 155 /** 192 156 * Compares two usage paths structures … … 225 189 226 190 switch(flags){ 227 /* path is somewhere in report_path */ 228 case USB_HID_PATH_COMPARE_ANYWHERE: 229 if(path->depth != 1){ 230 return 1; 231 } 232 233 report_link = report_path->head.next; 234 path_link = path->head.next; 235 path_item = list_get_instance(path_link, 236 usb_hid_report_usage_path_t, link); 237 238 while(report_link != &report_path->head) { 239 report_item = list_get_instance(report_link, 240 usb_hid_report_usage_path_t, link); 241 242 if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 243 path_item->usage_page)){ 244 245 if(only_page == 0){ 246 if(USB_HID_SAME_USAGE( 247 report_item->usage, 248 path_item->usage)) { 249 191 /* path is somewhere in report_path */ 192 case USB_HID_PATH_COMPARE_ANYWHERE: 193 if(path->depth != 1){ 194 return 1; 195 } 196 197 // projit skrz cestu a kdyz nekde sedi tak vratim EOK 198 // dojduli az za konec tak nnesedi 199 report_link = report_path->head.next; 200 path_link = path->head.next; 201 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 202 203 while(report_link != &report_path->head) { 204 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 205 if(report_item->usage_page == path_item->usage_page){ 206 if(only_page == 0){ 207 if(report_item->usage == path_item->usage) { 208 return EOK; 209 } 210 } 211 else { 250 212 return EOK; 251 213 } 252 214 } 215 216 report_link = report_link->next; 217 } 218 219 return 1; 220 break; 221 /* the paths must be identical */ 222 case USB_HID_PATH_COMPARE_STRICT: 223 if(report_path->depth != path->depth){ 224 return 1; 225 } 226 227 /* path is prefix of the report_path */ 228 case USB_HID_PATH_COMPARE_BEGIN: 229 230 report_link = report_path->head.next; 231 path_link = path->head.next; 232 233 while((report_link != &report_path->head) && 234 (path_link != &path->head)) { 235 236 report_item = list_get_instance(report_link, 237 usb_hid_report_usage_path_t, 238 link); 239 240 path_item = list_get_instance(path_link, 241 usb_hid_report_usage_path_t, 242 link); 243 244 if((report_item->usage_page != path_item->usage_page) || 245 ((only_page == 0) && 246 (report_item->usage != path_item->usage))) { 247 248 return 1; 249 } else { 250 report_link = report_link->next; 251 path_link = path_link->next; 252 } 253 254 } 255 256 if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) || 257 ((report_link == &report_path->head) && (path_link == &path->head))) { 258 return EOK; 259 } 253 260 else { 261 return 1; 262 } 263 break; 264 265 /* path is suffix of report_path */ 266 case USB_HID_PATH_COMPARE_END: 267 268 report_link = report_path->head.prev; 269 path_link = path->head.prev; 270 271 if(list_empty(&path->head)){ 254 272 return EOK; 255 273 } 256 }257 258 report_link = report_link->next;259 }260 261 return 1;262 break;263 264 /* the paths must be identical */265 case USB_HID_PATH_COMPARE_STRICT:266 if(report_path->depth != path->depth){267 return 1;268 }269 270 /* path is prefix of the report_path */271 case USB_HID_PATH_COMPARE_BEGIN:272 273 report_link = report_path->head.next;274 path_link = path->head.next;275 274 276 while((report_link != &report_path->head) && 277 (path_link != &path->head)) { 278 279 report_item = list_get_instance(report_link, 280 usb_hid_report_usage_path_t, link); 281 282 path_item = list_get_instance(path_link, 283 usb_hid_report_usage_path_t, link); 284 285 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 286 path_item->usage_page) || ((only_page == 0) && 287 !USB_HID_SAME_USAGE(report_item->usage, 288 path_item->usage))) { 275 while((report_link != &report_path->head) && 276 (path_link != &path->head)) { 277 278 report_item = list_get_instance(report_link, 279 usb_hid_report_usage_path_t, 280 link); 281 path_item = list_get_instance(path_link, 282 usb_hid_report_usage_path_t, 283 link); 284 285 if((report_item->usage_page != path_item->usage_page) || 286 ((only_page == 0) && 287 (report_item->usage != path_item->usage))) { 288 return 1; 289 } else { 290 report_link = report_link->prev; 291 path_link = path_link->prev; 292 } 289 293 290 return 1; 291 } 292 else { 293 report_link = report_link->next; 294 path_link = path_link->next; 295 } 294 } 295 296 if(path_link == &path->head) { 297 return EOK; 298 } 299 else { 300 return 1; 301 } 296 302 297 } 298 299 if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && 300 (path_link == &path->head)) || 301 ((report_link == &report_path->head) && 302 (path_link == &path->head))) { 303 304 return EOK; 305 } 306 else { 307 return 1; 308 } 309 break; 310 311 /* path is suffix of report_path */ 312 case USB_HID_PATH_COMPARE_END: 313 314 report_link = report_path->head.prev; 315 path_link = path->head.prev; 316 317 if(list_empty(&path->head)){ 318 return EOK; 319 } 320 321 while((report_link != &report_path->head) && 322 (path_link != &path->head)) { 323 324 report_item = list_get_instance(report_link, 325 usb_hid_report_usage_path_t, link); 326 327 path_item = list_get_instance(path_link, 328 usb_hid_report_usage_path_t, link); 329 330 if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 331 path_item->usage_page) || ((only_page == 0) && 332 !USB_HID_SAME_USAGE(report_item->usage, 333 path_item->usage))) { 334 335 return 1; 336 } else { 337 report_link = report_link->prev; 338 path_link = path_link->prev; 339 } 340 341 } 342 343 if(path_link == &path->head) { 344 return EOK; 345 } 346 else { 347 return 1; 348 } 349 350 break; 351 352 default: 353 return EINVAL; 354 } 355 } 356 357 /*---------------------------------------------------------------------------*/ 303 break; 304 305 default: 306 return EINVAL; 307 } 308 } 309 358 310 /** 359 311 * Allocates and initializes new usage path structure. … … 377 329 } 378 330 379 /*---------------------------------------------------------------------------*/380 331 /** 381 332 * Releases given usage path structure. … … 394 345 } 395 346 396 /*---------------------------------------------------------------------------*/ 347 397 348 /** 398 349 * Clone content of given usage path to the new one … … 401 352 * @return New copy of given usage path structure 402 353 */ 403 usb_hid_report_path_t *usb_hid_report_path_clone( 404 usb_hid_report_path_t *usage_path) 354 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 405 355 { 406 356 link_t *path_link; … … 421 371 path_link = usage_path->head.next; 422 372 while(path_link != &usage_path->head) { 423 path_item = list_get_instance(path_link, 424 usb_hid_report_usage_path_t, link); 425 373 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, 374 link); 426 375 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t)); 427 376 if(new_path_item == NULL) { … … 443 392 } 444 393 445 /*---------------------------------------------------------------------------*/ 394 446 395 /** 447 396 * Sets report id in usage path structure … … 451 400 * @return Error code 452 401 */ 453 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, 454 uint8_t report_id) 402 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id) 455 403 { 456 404 if(path == NULL){ -
uspace/lib/usbhid/src/hidreport.c
r6bfaab5 r88be3a0b 164 164 165 165 int usb_hid_process_report_descriptor(usb_device_t *dev, 166 usb_hid_report_t *report , uint8_t **report_desc, size_t *report_size)166 usb_hid_report_t *report) 167 167 { 168 168 if (dev == NULL || report == NULL) { … … 172 172 } 173 173 174 // uint8_t *report_desc = NULL; 175 // size_t report_size; 176 177 int rc = usb_hid_get_report_descriptor(dev, report_desc, report_size); 174 uint8_t *report_desc = NULL; 175 size_t report_size; 176 177 int rc = usb_hid_get_report_descriptor(dev, &report_desc, 178 &report_size); 178 179 179 180 if (rc != EOK) { 180 181 usb_log_error("Problem with getting Report descriptor: %s.\n", 181 182 str_error(rc)); 182 if (*report_desc != NULL) { 183 free(*report_desc); 184 *report_desc = NULL; 183 if (report_desc != NULL) { 184 free(report_desc); 185 185 } 186 186 return rc; 187 187 } 188 188 189 assert( *report_desc != NULL);190 191 rc = usb_hid_parse_report_descriptor(report, *report_desc, *report_size);189 assert(report_desc != NULL); 190 191 rc = usb_hid_parse_report_descriptor(report, report_desc, report_size); 192 192 if (rc != EOK) { 193 193 usb_log_error("Problem parsing Report descriptor: %s.\n", 194 194 str_error(rc)); 195 free(*report_desc); 196 *report_desc = NULL; 195 free(report_desc); 197 196 return rc; 198 197 } 199 198 200 199 usb_hid_descriptor_print(report); 200 free(report_desc); 201 201 202 202 return EOK; -
uspace/lib/usbhost/src/device_keeper.c
r6bfaab5 r88be3a0b 158 158 } 159 159 160 /** Find devman handle assigned to USB address. 161 * Intentionally refuse to find handle of default address. 160 /** Find devman handled assigned to USB address. 162 161 * 163 162 * @param[in] instance Device keeper structure to use. … … 171 170 assert(instance); 172 171 fibril_mutex_lock(&instance->guard); 173 if ((address < =0) || (address >= USB_ADDRESS_COUNT)) {172 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 174 173 fibril_mutex_unlock(&instance->guard); 175 174 return false;
Note:
See TracChangeset
for help on using the changeset viewer.