Changeset e1dbcbc in mainline for uspace/lib
- Timestamp:
- 2011-04-29T13:43:01Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a81a1d09
- Parents:
- 380e0364 (diff), f19f1b7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 9 added
- 4 deleted
- 51 edited
- 1 moved
-
c/arch/mips32/include/atomic.h (modified) (1 diff)
-
c/generic/adt/measured_strings.c (modified) (1 diff)
-
c/generic/async.c (modified) (2 diffs)
-
c/generic/vfs/vfs.c (modified) (2 diffs)
-
c/include/async.h (modified) (2 diffs)
-
c/include/errno.h (modified) (1 diff)
-
c/include/ipc/dev_iface.h (modified) (1 diff)
-
drv/generic/dev_iface.c (modified) (2 diffs)
-
drv/generic/driver.c (modified) (4 diffs)
-
drv/generic/remote_usbhid.c (added)
-
drv/include/remote_usbhid.h (added)
-
drv/include/usbhid_iface.h (added)
-
net/generic/generic.c (modified) (4 diffs)
-
net/generic/net_checksum.c (modified) (6 diffs)
-
net/generic/packet_client.c (modified) (2 diffs)
-
net/il/ip_client.c (modified) (4 diffs)
-
net/tl/icmp_client.c (modified) (1 diff)
-
net/tl/socket_core.c (modified) (21 diffs)
-
net/tl/tl_common.c (modified) (6 diffs)
-
packet/generic/packet_server.c (modified) (2 diffs)
-
softint/generic/multiplication.c (modified) (1 diff)
-
usb/Makefile (modified) (1 diff)
-
usb/include/usb/classes/hid.h (modified) (1 diff)
-
usb/include/usb/classes/hid/iface.h (added)
-
usb/include/usb/classes/hidparser.h (modified) (11 diffs)
-
usb/include/usb/classes/hidreport.h (modified) (1 diff)
-
usb/include/usb/classes/hidut.h (modified) (1 diff)
-
usb/include/usb/classes/hub.h (modified) (1 diff)
-
usb/include/usb/debug.h (modified) (2 diffs)
-
usb/include/usb/devdrv.h (modified) (1 diff)
-
usb/include/usb/devpoll.h (added)
-
usb/include/usb/host/batch.h (modified) (3 diffs)
-
usb/include/usb/host/device_keeper.h (modified) (2 diffs)
-
usb/include/usb/host/endpoint.h (modified) (2 diffs)
-
usb/include/usb/host/usb_endpoint_manager.h (modified) (2 diffs)
-
usb/include/usb/pipes.h (modified) (2 diffs)
-
usb/include/usb/usb.h (modified) (1 diff)
-
usb/src/debug.c (modified) (6 diffs)
-
usb/src/devdrv.c (modified) (1 diff)
-
usb/src/devpoll.c (modified) (10 diffs)
-
usb/src/hidiface.c (added)
-
usb/src/hidparser.c (modified) (57 diffs)
-
usb/src/hidreport.c (modified) (6 diffs)
-
usb/src/hidreq.c (modified) (17 diffs)
-
usb/src/host/batch.c (modified) (5 diffs)
-
usb/src/host/device_keeper.c (modified) (7 diffs)
-
usb/src/host/endpoint.c (modified) (5 diffs)
-
usb/src/host/usb_endpoint_manager.c (modified) (1 diff)
-
usb/src/pipepriv.c (modified) (3 diffs)
-
usb/src/pipepriv.h (modified) (2 diffs)
-
usb/src/pipes.c (modified) (2 diffs)
-
usb/src/pipesinit.c (modified) (3 diffs)
-
usb/src/pipesio.c (modified) (8 diffs)
-
usbvirt/Makefile (modified) (2 diffs)
-
usbvirt/include/usbvirt/device.h (modified) (3 diffs)
-
usbvirt/include/usbvirt/ipc.h (moved) (moved from uspace/lib/usbvirt/include/usbvirt/hub.h ) (1 diff)
-
usbvirt/src/callback.c (deleted)
-
usbvirt/src/ctrlpipe.c (deleted)
-
usbvirt/src/ctrltransfer.c (added)
-
usbvirt/src/ipc.c (added)
-
usbvirt/src/main.c (deleted)
-
usbvirt/src/private.h (modified) (1 diff)
-
usbvirt/src/stdreq.c (modified) (7 diffs)
-
usbvirt/src/transaction.c (deleted)
-
usbvirt/src/transfer.c (added)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/mips32/include/atomic.h
r380e0364 re1dbcbc 70 70 " sc %0, %1\n" 71 71 " beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ 72 /* nop */ /* nop is inserted automatically by compiler */73 72 " nop\n" 74 73 : "=&r" (tmp), -
uspace/lib/c/generic/adt/measured_strings.c
r380e0364 re1dbcbc 74 74 new->length = length; 75 75 new->value = ((uint8_t *) new) + sizeof(measured_string_t); 76 / / append terminating zero explicitly - to be safe76 /* Append terminating zero explicitly - to be safe */ 77 77 memcpy(new->value, string, new->length); 78 78 new->value[new->length] = '\0'; -
uspace/lib/c/generic/async.c
r380e0364 re1dbcbc 1586 1586 * @param dst Address of the beginning of the destination buffer. 1587 1587 * @param size Size of the destination buffer. 1588 * @param flags Flags to control the data transfer. 1588 1589 * 1589 1590 * @return Zero on success or a negative error code from errno.h. 1590 1591 * 1591 1592 */ 1592 int async_data_read_start(int phoneid, void *dst, size_t size) 1593 { 1594 return async_req_2_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 1595 (sysarg_t) size); 1593 int 1594 async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags) 1595 { 1596 return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 1597 (sysarg_t) size, (sysarg_t) flags); 1596 1598 } 1597 1599 … … 1683 1685 * @param src Address of the beginning of the source buffer. 1684 1686 * @param size Size of the source buffer. 1687 * @param flags Flags to control the data transfer. 1685 1688 * 1686 1689 * @return Zero on success or a negative error code from errno.h. 1687 1690 * 1688 1691 */ 1689 int async_data_write_start(int phoneid, const void *src, size_t size) 1690 { 1691 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src, 1692 (sysarg_t) size); 1692 int 1693 async_data_write_start_generic(int phoneid, const void *src, size_t size, 1694 int flags) 1695 { 1696 return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src, 1697 (sysarg_t) size, (sysarg_t) flags); 1693 1698 } 1694 1699 -
uspace/lib/c/generic/vfs/vfs.c
r380e0364 re1dbcbc 378 378 379 379 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 380 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte); 380 rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte, 381 IPC_XF_RESTRICT); 381 382 if (rc != EOK) { 382 383 vfs_exchange_end(vfs_phone); … … 407 408 408 409 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 409 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte); 410 rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte, 411 IPC_XF_RESTRICT); 410 412 if (rc != EOK) { 411 413 vfs_exchange_end(vfs_phone); -
uspace/lib/c/include/async.h
r380e0364 re1dbcbc 341 341 342 342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *); 343 extern int async_data_read_start(int, void *, size_t); 343 #define async_data_read_start(p, buf, len) \ 344 async_data_read_start_generic((p), (buf), (len), IPC_XF_NONE) 345 346 extern int async_data_read_start_generic(int, void *, size_t, int); 344 347 extern bool async_data_read_receive(ipc_callid_t *, size_t *); 345 348 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); … … 380 383 (arg4), (answer)) 381 384 382 extern int async_data_write_start(int, const void *, size_t); 385 #define async_data_write_start(p, buf, len) \ 386 async_data_write_start_generic((p), (buf), (len), IPC_XF_NONE) 387 388 extern int async_data_write_start_generic(int, const void *, size_t, int); 383 389 extern bool async_data_write_receive(ipc_callid_t *, size_t *); 384 390 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); -
uspace/lib/c/include/errno.h
r380e0364 re1dbcbc 65 65 #define EEMPTY (-302) 66 66 67 /** Negative acknowledgment. */ 68 #define ENAK (-303) 69 67 70 /** An API function is called while another blocking function is in progress. */ 68 71 #define EINPROGRESS (-10036) -
uspace/lib/c/include/ipc/dev_iface.h
r380e0364 re1dbcbc 45 45 /** Interface provided by USB host controller. */ 46 46 USBHC_DEV_IFACE, 47 /** Interface provided by USB HID devices. */ 48 USBHID_DEV_IFACE, 47 49 48 50 DEV_IFACE_MAX -
uspace/lib/drv/generic/dev_iface.c
r380e0364 re1dbcbc 43 43 #include "remote_usb.h" 44 44 #include "remote_usbhc.h" 45 #include "remote_usbhid.h" 45 46 #include "remote_pci.h" 46 47 … … 51 52 &remote_pci_iface, 52 53 &remote_usb_iface, 53 &remote_usbhc_iface 54 &remote_usbhc_iface, 55 &remote_usbhid_iface 54 56 } 55 57 }; -
uspace/lib/drv/generic/driver.c
r380e0364 re1dbcbc 47 47 #include <stdlib.h> 48 48 #include <str.h> 49 #include <str_error.h> 49 50 #include <ctype.h> 50 51 #include <errno.h> … … 402 403 get_remote_method(rem_iface, iface_method_idx); 403 404 if (iface_method_ptr == NULL) { 404 / / the interface has not such method405 /* The interface has not such method */ 405 406 printf("%s: driver_connection_gen error - " 406 407 "invalid interface method.", driver->name); … … 655 656 int ddf_driver_main(driver_t *drv) 656 657 { 658 int rc; 659 657 660 /* 658 661 * Remember the driver structure - driver_ops will be called by generic … … 668 671 669 672 /* 670 * Register driver by device manager with generic handler for incoming671 * connections.673 * Register driver with device manager using generic handler for 674 * incoming connections. 672 675 */ 673 devman_driver_register(driver->name, driver_connection); 674 676 rc = devman_driver_register(driver->name, driver_connection); 677 if (rc != EOK) { 678 printf("Error: Failed to register driver with device manager " 679 "(%s).\n", (rc == EEXISTS) ? "driver already started" : 680 str_error(rc)); 681 682 return 1; 683 } 684 685 /* Return success from the task since server has started. */ 686 rc = task_retval(0); 687 if (rc != EOK) 688 return 1; 689 675 690 async_manager(); 676 691 -
uspace/lib/net/generic/generic.c
r380e0364 re1dbcbc 106 106 return EBADMEM; 107 107 108 / / request the address108 /* Request the address */ 109 109 message_id = async_send_1(phone, (sysarg_t) message, 110 110 (sysarg_t) device_id, NULL); … … 112 112 async_wait_for(message_id, &result); 113 113 114 / / if not successful114 /* If not successful */ 115 115 if ((string == EOK) && (result != EOK)) { 116 / / clear the data116 /* Clear the data */ 117 117 free(*address); 118 118 free(*data); … … 242 242 return EBADMEM; 243 243 244 / / request the translation244 /* Request the translation */ 245 245 message_id = async_send_3(phone, (sysarg_t) message, 246 246 (sysarg_t) device_id, (sysarg_t) count, (sysarg_t) service, NULL); … … 249 249 async_wait_for(message_id, &result); 250 250 251 / / if not successful251 /* If not successful */ 252 252 if ((string == EOK) && (result != EOK)) { 253 / / clear the data253 /* Clear the data */ 254 254 free(*translation); 255 255 free(*data); -
uspace/lib/net/generic/net_checksum.c
r380e0364 re1dbcbc 52 52 uint16_t compact_checksum(uint32_t sum) 53 53 { 54 / / shorten to the 16 bits54 /* Shorten to the 16 bits */ 55 55 while (sum >> 16) 56 56 sum = (sum & 0xffff) + (sum >> 16); … … 72 72 size_t index; 73 73 74 / / sum all the 16 bit fields74 /* Sum all the 16 bit fields */ 75 75 for (index = 0; index + 1 < length; index += 2) 76 76 seed += (data[index] << 8) + data[index + 1]; 77 77 78 / / last odd byte with zero padding78 /* Last odd byte with zero padding */ 79 79 if (index + 1 == length) 80 80 seed += data[index] << 8; … … 94 94 size_t index; 95 95 96 / / process full bytes96 /* Process full bytes */ 97 97 while (length >= 8) { 98 / / add the data98 /* Add the data */ 99 99 seed ^= (*data) << 24; 100 100 101 / / for each added bit101 /* For each added bit */ 102 102 for (index = 0; index < 8; ++index) { 103 / / if the first bit is set103 /* If the first bit is set */ 104 104 if (seed & 0x80000000) { 105 / / shift and divide the checksum105 /* Shift and divide the checksum */ 106 106 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 107 107 } else { 108 / / shift otherwise108 /* Shift otherwise */ 109 109 seed <<= 1; 110 110 } 111 111 } 112 112 113 / / move to the next byte113 /* Move to the next byte */ 114 114 ++data; 115 115 length -= 8; 116 116 } 117 117 118 / / process the odd bits118 /* Process the odd bits */ 119 119 if (length > 0) { 120 / / add the data with zero padding120 /* Add the data with zero padding */ 121 121 seed ^= ((*data) & (0xff << (8 - length))) << 24; 122 122 123 / / for each added bit123 /* For each added bit */ 124 124 for (index = 0; index < length; ++index) { 125 / / if the first bit is set125 /* If the first bit is set */ 126 126 if (seed & 0x80000000) { 127 / / shift and divide the checksum127 /* Shift and divide the checksum */ 128 128 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 129 129 } else { 130 / / shift otherwise130 /* Shift otherwise */ 131 131 seed <<= 1; 132 132 } … … 148 148 size_t index; 149 149 150 / / process full bytes150 /* Process full bytes */ 151 151 while (length >= 8) { 152 / / add the data152 /* Add the data */ 153 153 seed ^= (*data); 154 154 155 / / for each added bit155 /* For each added bit */ 156 156 for (index = 0; index < 8; ++index) { 157 / / if the last bit is set157 /* If the last bit is set */ 158 158 if (seed & 1) { 159 / / shift and divide the checksum159 /* Shift and divide the checksum */ 160 160 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 161 161 } else { 162 / / shift otherwise162 /* Shift otherwise */ 163 163 seed >>= 1; 164 164 } 165 165 } 166 166 167 / / move to the next byte167 /* Move to the next byte */ 168 168 ++data; 169 169 length -= 8; 170 170 } 171 171 172 / / process the odd bits172 /* Process the odd bits */ 173 173 if (length > 0) { 174 / / add the data with zero padding174 /* Add the data with zero padding */ 175 175 seed ^= (*data) >> (8 - length); 176 176 177 177 for (index = 0; index < length; ++index) { 178 / / if the last bit is set178 /* If the last bit is set */ 179 179 if (seed & 1) { 180 / / shift and divide the checksum180 /* Shift and divide the checksum */ 181 181 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 182 182 } else { 183 / / shift otherwise183 /* Shift otherwise */ 184 184 seed >>= 1; 185 185 } … … 198 198 uint16_t flip_checksum(uint16_t checksum) 199 199 { 200 / / flip, zero is returned as 0xFFFF (not flipped)200 /* Flip, zero is returned as 0xFFFF (not flipped) */ 201 201 checksum = ~checksum; 202 202 return checksum ? checksum : IP_CHECKSUM_ZERO; … … 216 216 uint16_t ip_checksum(uint8_t *data, size_t length) 217 217 { 218 / / compute, compact and flip the data checksum218 /* Compute, compact and flip the data checksum */ 219 219 return flip_checksum(compact_checksum(compute_checksum(0, data, 220 220 length))); -
uspace/lib/net/generic/packet_client.c
r380e0364 re1dbcbc 267 267 return NULL; 268 268 269 / / get a new packet269 /* Get a new packet */ 270 270 copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet), 271 271 PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix, … … 274 274 return NULL; 275 275 276 / / get addresses276 /* Get addresses */ 277 277 addrlen = packet_get_addr(packet, &src, &dest); 278 / / copy data278 /* Copy data */ 279 279 if ((packet_copy_data(copy, packet_get_data(packet), 280 280 PACKET_DATA_LENGTH(packet)) == EOK) && 281 / / copy addresses if present281 /* Copy addresses if present */ 282 282 ((addrlen <= 0) || 283 283 (packet_set_addr(copy, src, dest, addrlen) == EOK))) { -
uspace/lib/net/il/ip_client.c
r380e0364 re1dbcbc 124 124 125 125 // TODO IPv6 126 /* case AF_INET6: 126 #if 0 127 case AF_INET6: 127 128 if (addrlen != sizeof(struct sockaddr_in6)) 128 129 return EINVAL; … … 130 131 address_in6 = (struct sockaddr_in6 *) addr; 131 132 return EOK; 132 */ 133 #endif 133 134 134 135 default: … … 159 160 size_t padding; 160 161 161 // compute the padding if IP options are set 162 // multiple of 4 bytes 162 /* 163 * Compute the padding if IP options are set 164 * multiple of 4 bytes 165 */ 163 166 padding = ipopt_length % 4; 164 167 if (padding) { … … 167 170 } 168 171 169 / / prefix the header172 /* Prefix the header */ 170 173 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 171 174 if (!data) 172 175 return ENOMEM; 173 176 174 / / add the padding177 /* Add the padding */ 175 178 while (padding--) 176 179 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 177 180 178 / / set the header181 /* Set the header */ 179 182 header = (ip_header_t *) data; 180 183 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + -
uspace/lib/net/tl/icmp_client.c
r380e0364 re1dbcbc 81 81 *mtu = header->un.frag.mtu; 82 82 83 / / remove debug dump83 /* Remove debug dump */ 84 84 #ifdef CONFIG_DEBUG 85 85 printf("ICMP error %d (%d) in packet %d\n", header->type, header->code, -
uspace/lib/net/tl/socket_core.c
r380e0364 re1dbcbc 91 91 int packet_id; 92 92 93 / / if bound93 /* If bound */ 94 94 if (socket->port) { 95 / / release the port95 /* Release the port */ 96 96 socket_port_release(global_sockets, socket); 97 97 } 98 98 99 / / release all received packets99 /* Release all received packets */ 100 100 while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0) 101 101 pq_release_remote(packet_phone, packet_id); … … 166 166 int rc; 167 167 168 / / create a wrapper168 /* Create a wrapper */ 169 169 socket_ref = malloc(sizeof(*socket_ref)); 170 170 if (!socket_ref) … … 172 172 173 173 *socket_ref = socket; 174 / / add the wrapper174 /* Add the wrapper */ 175 175 rc = socket_port_map_add(&socket_port->map, key, key_length, 176 176 socket_ref); … … 206 206 int rc; 207 207 208 / / create a wrapper208 /* Create a wrapper */ 209 209 socket_port = malloc(sizeof(*socket_port)); 210 210 if (!socket_port) … … 221 221 goto fail; 222 222 223 / / register the incomming port223 /* Register the incoming port */ 224 224 rc = socket_ports_add(global_sockets, port, socket_port); 225 225 if (rc < 0) … … 277 277 278 278 address_in = (struct sockaddr_in *) addr; 279 / / find the socket279 /* Find the socket */ 280 280 socket = socket_cores_find(local_sockets, socket_id); 281 281 if (!socket) 282 282 return ENOTSOCK; 283 283 284 / / bind a free port?284 /* Bind a free port? */ 285 285 if (address_in->sin_port <= 0) 286 286 return socket_bind_free_port(global_sockets, socket, 287 287 free_ports_start, free_ports_end, last_used_port); 288 288 289 / / try to find the port289 /* Try to find the port */ 290 290 socket_port = socket_ports_find(global_sockets, 291 291 ntohs(address_in->sin_port)); 292 292 if (socket_port) { 293 / / already used293 /* Already used */ 294 294 return EADDRINUSE; 295 295 } 296 296 297 / / if bound297 /* If bound */ 298 298 if (socket->port) { 299 / / release the port299 /* Release the port */ 300 300 socket_port_release(global_sockets, socket); 301 301 } … … 333 333 int index; 334 334 335 / / from the last used one335 /* From the last used one */ 336 336 index = last_used_port; 337 337 … … 339 339 ++index; 340 340 341 / / til the range end341 /* Till the range end */ 342 342 if (index >= free_ports_end) { 343 / / start from the range beginning343 /* Start from the range beginning */ 344 344 index = free_ports_start - 1; 345 345 do { 346 346 ++index; 347 / / til the last used one347 /* Till the last used one */ 348 348 if (index >= last_used_port) { 349 / / none found349 /* None found */ 350 350 return ENOTCONN; 351 351 } 352 352 } while (socket_ports_find(global_sockets, index)); 353 353 354 / / found, break immediately354 /* Found, break immediately */ 355 355 break; 356 356 } … … 376 376 377 377 count = 0; 378 // socket_id = socket_globals.last_id; 378 #if 0 379 socket_id = socket_globals.last_id; 380 #endif 379 381 do { 380 382 if (count < SOCKET_ID_TRIES) { … … 384 386 socket_id = 1; 385 387 ++count; 386 / / only this branch for last_id388 /* Only this branch for last_id */ 387 389 } else { 388 390 if (socket_id < INT_MAX) { 389 391 ++ socket_id; 390 /* } else if(socket_globals.last_id) { 391 * socket_globals.last_id = 0; 392 * socket_id = 1; 393 */ } else { 392 #if 0 393 } else if(socket_globals.last_id) { 394 socket_globals.last_id = 0; 395 socket_id = 1; 396 #endif 397 } else { 394 398 return ELIMIT; 395 399 } … … 425 429 return EINVAL; 426 430 427 / / store the socket431 /* Store the socket */ 428 432 if (*socket_id <= 0) { 429 433 positive = (*socket_id == 0); … … 441 445 return ENOMEM; 442 446 443 / / initialize447 /* Initialize */ 444 448 socket->phone = app_phone; 445 449 socket->port = -1; … … 493 497 int accepted_id; 494 498 495 / / find the socket499 /* Find the socket */ 496 500 socket = socket_cores_find(local_sockets, socket_id); 497 501 if (!socket) 498 502 return ENOTSOCK; 499 503 500 / / destroy all accepted sockets504 /* Destroy all accepted sockets */ 501 505 while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0) 502 506 socket_destroy(packet_phone, accepted_id, local_sockets, … … 535 539 next_packet = pq_next(packet); 536 540 if (!next_packet) { 537 / / write all if only one fragment541 /* Write all if only one fragment */ 538 542 rc = data_reply(packet_get_data(packet), 539 543 packet_get_data_length(packet)); 540 544 if (rc != EOK) 541 545 return rc; 542 / / store the total length546 /* Store the total length */ 543 547 *length = packet_get_data_length(packet); 544 548 } else { 545 / / count the packet fragments549 /* Count the packet fragments */ 546 550 fragments = 1; 547 551 next_packet = pq_next(packet); … … 549 553 ++fragments; 550 554 551 / / compute and store the fragment lengths555 /* Compute and store the fragment lengths */ 552 556 lengths = (size_t *) malloc(sizeof(size_t) * fragments + 553 557 sizeof(size_t)); … … 565 569 } 566 570 567 / / write the fragment lengths571 /* Write the fragment lengths */ 568 572 rc = data_reply(lengths, sizeof(int) * (fragments + 1)); 569 573 if (rc != EOK) { … … 573 577 next_packet = packet; 574 578 575 / / write the fragments579 /* Write the fragments */ 576 580 for (index = 0; index < fragments; ++index) { 577 581 rc = data_reply(packet_get_data(next_packet), … … 584 588 } 585 589 586 / / store the total length590 /* Store the total length */ 587 591 *length = lengths[fragments]; 588 592 free(lengths); … … 636 640 return; 637 641 638 / / find ports642 /* Find ports */ 639 643 socket_port = socket_ports_find(global_sockets, socket->port); 640 644 if (socket_port) { 641 / / find the socket645 /* Find the socket */ 642 646 socket_ref = socket_port_map_find(&socket_port->map, 643 647 socket->key, socket->key_length); … … 646 650 --socket_port->count; 647 651 648 / / release if empty652 /* Release if empty */ 649 653 if (socket_port->count <= 0) { 650 / / destroy the map654 /* Destroy the map */ 651 655 socket_port_map_destroy(&socket_port->map, free); 652 / / release the port656 /* Release the port */ 653 657 socket_ports_exclude(global_sockets, 654 658 socket->port, free); 655 659 } else { 656 / / remove660 /* Remove */ 657 661 socket_port_map_exclude(&socket_port->map, 658 662 socket->key, socket->key_length, free); … … 685 689 int rc; 686 690 687 / / find ports691 /* Find ports */ 688 692 socket_port = socket_ports_find(global_sockets, port); 689 693 if (!socket_port) 690 694 return ENOENT; 691 695 692 / / add the socket696 /* Add the socket */ 693 697 rc = socket_port_add_core(socket_port, socket, key, key_length); 694 698 if (rc != EOK) -
uspace/lib/net/tl/tl_common.c
r380e0364 re1dbcbc 255 255 int length; 256 256 257 / / detach the first packet and release the others257 /* Detach the first packet and release the others */ 258 258 next = pq_detach(packet); 259 259 if (next) … … 262 262 length = packet_get_addr(packet, &src, NULL); 263 263 if ((length > 0) && (!error) && (icmp_phone >= 0) && 264 // set both addresses to the source one (avoids the source address 265 // deletion before setting the destination one) 264 /* 265 * Set both addresses to the source one (avoids the source address 266 * deletion before setting the destination one) 267 */ 266 268 (packet_set_addr(packet, src, src, (size_t) length) == EOK)) { 267 269 return EOK; … … 299 301 return EINVAL; 300 302 301 / / get the data length303 /* Get the data length */ 302 304 if (!async_data_write_receive(&callid, &length)) 303 305 return EINVAL; 304 306 305 / / get a new packet307 /* Get a new packet */ 306 308 *packet = packet_get_4_remote(packet_phone, length, dimension->addr_len, 307 309 prefix + dimension->prefix, dimension->suffix); … … 309 311 return ENOMEM; 310 312 311 / / allocate space in the packet313 /* Allocate space in the packet */ 312 314 data = packet_suffix(*packet, length); 313 315 if (!data) { … … 316 318 } 317 319 318 / / read the data into the packet320 /* Read the data into the packet */ 319 321 rc = async_data_write_finalize(callid, data, length); 320 322 if (rc != EOK) { … … 323 325 } 324 326 325 / / set the packet destination address327 /* Set the packet destination address */ 326 328 rc = packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen); 327 329 if (rc != EOK) { -
uspace/lib/packet/generic/packet_server.c
r380e0364 re1dbcbc 112 112 size_t max_content, size_t max_suffix) 113 113 { 114 / / clear the packet content114 /* Clear the packet content */ 115 115 bzero(((void *) packet) + sizeof(packet_t), 116 116 packet->length - sizeof(packet_t)); 117 117 118 / / clear the packet header118 /* Clear the packet header */ 119 119 packet->order = 0; 120 120 packet->metric = 0; … … 151 151 assert(fibril_mutex_is_locked(&ps_globals.lock)); 152 152 153 / / already locked153 /* Already locked */ 154 154 packet = (packet_t *) mmap(NULL, length, PROTO_READ | PROTO_WRITE, 155 155 MAP_SHARED | MAP_ANONYMOUS, 0, 0); -
uspace/lib/softint/generic/multiplication.c
r380e0364 re1dbcbc 109 109 * result does not fit in signed one */ 110 110 if (SOFTINT_CHECK_OF && ((t2 < t1) || (t2 & (1ull << 63)))) { 111 / / error, overflow111 /* Error, overflow */ 112 112 return (neg ? INT64_MIN : INT64_MAX); 113 113 } -
uspace/lib/usb/Makefile
r380e0364 re1dbcbc 42 42 src/dp.c \ 43 43 src/dump.c \ 44 src/hidiface.c \ 44 45 src/hidparser.c \ 45 46 src/hub.c \ -
uspace/lib/usb/include/usb/classes/hid.h
r380e0364 re1dbcbc 50 50 USB_HIDREQ_SET_PROTOCOL = 11 51 51 } usb_hid_request_t; 52 53 typedef enum {54 USB_HID_REPORT_TYPE_INPUT = 1,55 USB_HID_REPORT_TYPE_OUTPUT = 2,56 USB_HID_REPORT_TYPE_FEATURE = 357 } usb_hid_report_type_t;58 52 59 53 typedef enum { -
uspace/lib/usb/include/usb/classes/hidparser.h
r380e0364 re1dbcbc 73 73 #define USB_HID_PATH_COMPARE_END 1 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 76 /** */ 77 typedef struct { 78 /** */ 79 int32_t usage_page; 80 /** */ 81 int32_t usage; 75 #define USB_HID_PATH_COMPARE_COLLECTION_ONLY 2 /* porovnava jenom cestu z Kolekci */ 76 77 78 #define USB_HID_MAX_USAGES 20 79 80 typedef enum { 81 USB_HID_REPORT_TYPE_INPUT = 1, 82 USB_HID_REPORT_TYPE_OUTPUT = 2, 83 USB_HID_REPORT_TYPE_FEATURE = 3 84 } usb_hid_report_type_t; 85 86 /** Collection usage path structure */ 87 typedef struct { 88 /** */ 89 uint32_t usage_page; 90 /** */ 91 uint32_t usage; 92 93 uint8_t flags; 82 94 /** */ 83 95 link_t link; … … 91 103 92 104 /** */ 105 link_t link; /* list */ 106 107 link_t head; /* head of list of usage paths */ 108 109 } usb_hid_report_path_t; 110 111 112 typedef struct { 113 /** */ 114 int report_count; 115 link_t reports; /** list of usb_hid_report_description_t */ 116 117 link_t collection_paths; 118 int collection_paths_count; 119 120 int use_report_ids; 121 uint8_t last_report_id; 122 123 } usb_hid_report_t; 124 125 typedef struct { 126 uint8_t report_id; 127 usb_hid_report_type_t type; 128 129 size_t bit_length; 130 size_t item_length; 131 132 link_t report_items; /** list of report items (fields) */ 133 93 134 link_t link; 94 95 } usb_hid_report_path_t; 96 97 /** 98 * Description of report items 99 */ 100 typedef struct { 101 /** */ 135 } usb_hid_report_description_t; 136 137 typedef struct { 138 139 int offset; 140 size_t size; 141 142 uint16_t usage_page; 143 uint16_t usage; 144 145 uint8_t item_flags; 146 usb_hid_report_path_t *collection_path; 147 148 int32_t logical_minimum; 149 int32_t logical_maximum; 150 int32_t physical_minimum; 151 int32_t physical_maximum; 152 uint32_t usage_minimum; 153 uint32_t usage_maximum; 154 uint32_t unit; 155 uint32_t unit_exponent; 156 157 158 int32_t value; 159 160 link_t link; 161 } usb_hid_report_field_t; 162 163 164 165 /** 166 * state table 167 */ 168 typedef struct { 169 /** report id */ 102 170 int32_t id; 103 /** */ 104 int32_t usage_minimum; 105 /** */ 106 int32_t usage_maximum; 171 172 /** */ 173 uint16_t extended_usage_page; 174 uint32_t usages[USB_HID_MAX_USAGES]; 175 int usages_count; 176 177 /** */ 178 uint32_t usage_page; 179 180 /** */ 181 uint32_t usage_minimum; 182 /** */ 183 uint32_t usage_maximum; 107 184 /** */ 108 185 int32_t logical_minimum; … … 116 193 size_t offset; 117 194 /** */ 118 int32_t delimiter;119 /** */120 195 int32_t unit_exponent; 121 196 /** */ … … 123 198 124 199 /** */ 125 int32_t string_index;126 /** */ 127 int32_t string_minimum;128 /** */ 129 int32_t string_maximum;130 /** */ 131 int32_t designator_index;132 /** */ 133 int32_t designator_minimum;134 /** */ 135 int32_t designator_maximum;200 uint32_t string_index; 201 /** */ 202 uint32_t string_minimum; 203 /** */ 204 uint32_t string_maximum; 205 /** */ 206 uint32_t designator_index; 207 /** */ 208 uint32_t designator_minimum; 209 /** */ 210 uint32_t designator_maximum; 136 211 /** */ 137 212 int32_t physical_minimum; … … 142 217 uint8_t item_flags; 143 218 144 /** */ 219 usb_hid_report_type_t type; 220 221 /** current collection path*/ 145 222 usb_hid_report_path_t *usage_path; 146 223 /** */ 147 224 link_t link; 148 225 } usb_hid_report_item_t; 149 150 151 /** HID report parser structure. */152 typedef struct {153 /** */154 link_t input;155 /** */156 link_t output;157 /** */158 link_t feature;159 160 int use_report_id;161 162 /** */163 link_t stack;164 } usb_hid_report_parser_t;165 166 226 167 227 /** HID parser callbacks for IN items. */ … … 189 249 } usb_hid_modifiers_t; 190 250 191 //typedef enum {192 // USB_HID_LED_NUM_LOCK = 0x1,193 // USB_HID_LED_CAPS_LOCK = 0x2,194 // USB_HID_LED_SCROLL_LOCK = 0x4,195 // USB_HID_LED_COMPOSE = 0x8,196 // USB_HID_LED_KANA = 0x10,197 // USB_HID_LED_COUNT = 5198 //} usb_hid_led_t;199 200 251 static const usb_hid_modifiers_t 201 252 usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { … … 210 261 }; 211 262 212 //static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {213 // USB_HID_LED_NUM_LOCK,214 // USB_HID_LED_CAPS_LOCK,215 // USB_HID_LED_SCROLL_LOCK,216 // USB_HID_LED_COMPOSE,217 // USB_HID_LED_KANA218 //};219 220 //#define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01221 //#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02222 //#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04223 //#define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08224 //#define USB_HID_BOOT_KEYBOARD_KANA 0x10225 226 263 /* 227 264 * Descriptor parser functions 228 265 */ 229 /** */ 230 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 231 232 /** */ 233 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 266 267 /** */ 268 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 234 269 const uint8_t *data, size_t size); 235 270 236 271 /** */ 237 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 238 239 /** */ 240 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 241 242 /* 243 * Boot protocol functions 244 */ 245 /** */ 246 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 247 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 248 249 /** */ 250 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 272 void usb_hid_free_report(usb_hid_report_t *report); 273 274 /** */ 275 void usb_hid_descriptor_print(usb_hid_report_t *report); 251 276 252 277 … … 255 280 */ 256 281 /** */ 257 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 258 const uint8_t *data, size_t size, 259 usb_hid_report_path_t *path, int flags, 260 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 261 262 /** */ 263 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 282 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size, uint8_t *report_id); 283 284 /** */ 285 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 264 286 usb_hid_report_path_t *path, int flags); 265 287 … … 296 318 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 297 319 320 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, usb_hid_report_type_t type); 321 322 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type); 323 298 324 299 325 /* … … 301 327 */ 302 328 /** Allocates output report buffer*/ 303 uint8_t *usb_hid_report_output(usb_hid_report_ parser_t *parser, size_t *size);329 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id); 304 330 305 331 /** Frees output report buffer*/ … … 307 333 308 334 /** Returns size of output for given usage path */ 309 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,335 size_t usb_hid_report_output_size(usb_hid_report_t *report, 310 336 usb_hid_report_path_t *path, int flags); 311 337 312 /** Updates the output report buffer by translated given data */ 313 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 314 usb_hid_report_path_t *path, int flags, 315 uint8_t *buffer, size_t size, 316 int32_t *data, size_t data_size); 338 /** Sets data in report structure */ 339 int usb_hid_report_output_set_data(usb_hid_report_t *report, 340 usb_hid_report_path_t *path, int flags, 341 int *data, size_t data_size); 342 343 /** Makes the output report buffer by translated given data */ 344 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size); 317 345 #endif 318 346 /** -
uspace/lib/usb/include/usb/classes/hidreport.h
r380e0364 re1dbcbc 57 57 */ 58 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_ parser_t *parser);59 usb_hid_report_t *report); 60 60 61 61 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usb/include/usb/classes/hidut.h
r380e0364 re1dbcbc 46 46 USB_HIDUT_PAGE_KEYBOARD = 7, 47 47 USB_HIDUT_PAGE_LED = 8, 48 USB_HIDUT_PAGE_BUTTON = 9 49 /* USB_HIDUT_PAGE_ = , */ 48 USB_HIDUT_PAGE_BUTTON = 9, 49 USB_HIDUT_PAGE_ORDINAL = 0x0a, 50 USB_HIDUT_PAGE_TELEPHONY_DEVICE = 0x0b, 51 USB_HIDUT_PAGE_CONSUMER = 0x0c 50 52 } usb_hidut_usage_page_t; 51 53 -
uspace/lib/usb/include/usb/classes/hub.h
r380e0364 re1dbcbc 152 152 maximum of 255 ports). 153 153 */ 154 uint8_t * devices_removable;154 uint8_t devices_removable[32]; 155 155 156 156 /** -
uspace/lib/usb/include/usb/debug.h
r380e0364 re1dbcbc 36 36 #define LIBUSB_DEBUG_H_ 37 37 #include <stdio.h> 38 #include <inttypes.h> 38 39 #include <usb/usb.h> 39 40 #include <assert.h> … … 85 86 void usb_log_enable(usb_log_level_t, const char *); 86 87 87 void usb_log_printf(usb_log_level_t, const char *, ...); 88 void usb_log_printf(usb_log_level_t, const char *, ...) 89 PRINTF_ATTRIBUTE(2, 3); 88 90 89 91 /** Log fatal error. */ -
uspace/lib/usb/include/usb/devdrv.h
r380e0364 re1dbcbc 162 162 usb_endpoint_description_t **); 163 163 164 typedef bool (*usb_polling_callback_t)(usb_device_t *,165 uint8_t *, size_t, void *);166 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);167 168 int usb_device_auto_poll(usb_device_t *, size_t,169 usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);170 171 164 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *); 172 165 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *, -
uspace/lib/usb/include/usb/host/batch.h
r380e0364 re1dbcbc 43 43 typedef struct usb_transfer_batch usb_transfer_batch_t; 44 44 struct usb_transfer_batch { 45 endpoint_t *ep; 45 46 link_t link; 46 usb_target_t target;47 usb_transfer_type_t transfer_type;48 usb_speed_t speed;49 usb_direction_t direction;50 47 usbhc_iface_transfer_in_callback_t callback_in; 51 48 usbhc_iface_transfer_out_callback_t callback_out; 49 void *arg; 52 50 char *buffer; 53 char * transport_buffer;51 char *data_buffer; 54 52 size_t buffer_size; 55 53 char *setup_buffer; 56 54 size_t setup_size; 57 size_t max_packet_size;58 55 size_t transfered_size; 59 56 void (*next_step)(usb_transfer_batch_t *); 60 57 int error; 61 58 ddf_fun_t *fun; 62 void *arg;63 endpoint_t *ep;64 59 void *private_data; 60 void (*private_data_dtor)(void *p_data); 65 61 }; 66 62 67 63 void usb_transfer_batch_init( 68 64 usb_transfer_batch_t *instance, 69 usb_target_t target, 70 usb_transfer_type_t transfer_type, 71 usb_speed_t speed, 72 size_t max_packet_size, 65 endpoint_t *ep, 73 66 char *buffer, 74 char * transport_buffer,67 char *data_buffer, 75 68 size_t buffer_size, 76 69 char *setup_buffer, … … 80 73 void *arg, 81 74 ddf_fun_t *fun, 82 endpoint_t *ep,83 void *private_data75 void *private_data, 76 void (*private_data_dtor)(void *p_data) 84 77 ); 85 78 86 static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l) 87 { 88 assert(l); 89 return list_get_instance(l, usb_transfer_batch_t, link); 90 } 91 92 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance); 93 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance); 79 void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance); 80 void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance); 94 81 void usb_transfer_batch_finish(usb_transfer_batch_t *instance); 82 void usb_transfer_batch_dispose(usb_transfer_batch_t *instance); 95 83 96 84 static inline void usb_transfer_batch_finish_error( … … 102 90 } 103 91 92 static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l) 93 { 94 assert(l); 95 return list_get_instance(l, usb_transfer_batch_t, link); 96 } 97 104 98 #endif 105 99 /** -
uspace/lib/usb/include/usb/host/device_keeper.h
r380e0364 re1dbcbc 54 54 usb_speed_t speed; 55 55 bool occupied; 56 link_t endpoints;57 uint16_t control_used;58 56 devman_handle_t handle; 59 57 }; … … 65 63 struct usb_device_info devices[USB_ADDRESS_COUNT]; 66 64 fibril_mutex_t guard; 67 fibril_condvar_t change;68 65 usb_address_t last_address; 69 66 } usb_device_keeper_t; 70 67 71 68 void usb_device_keeper_init(usb_device_keeper_t *instance); 72 73 void usb_device_keeper_reserve_default_address(74 usb_device_keeper_t *instance, usb_speed_t speed);75 76 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance);77 78 void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,79 usb_target_t target, const uint8_t *setup_data);80 69 81 70 usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance, -
uspace/lib/usb/include/usb/host/endpoint.h
r380e0364 re1dbcbc 54 54 fibril_condvar_t avail; 55 55 volatile bool active; 56 struct { 57 void *data; 58 int (*toggle_get)(void *); 59 void (*toggle_set)(void *, int); 60 } hc_data; 56 61 } endpoint_t; 57 62 … … 61 66 62 67 void endpoint_destroy(endpoint_t *instance); 68 69 void endpoint_set_hc_data(endpoint_t *instance, 70 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)); 71 72 void endpoint_clear_hc_data(endpoint_t *instance); 63 73 64 74 void endpoint_use(endpoint_t *instance); -
uspace/lib/usb/include/usb/host/usb_endpoint_manager.h
r380e0364 re1dbcbc 66 66 endpoint_t *ep, size_t data_size); 67 67 68 int usb_endpoint_manager_register_ep_wait(usb_endpoint_manager_t *instance,69 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,70 void *data, void (*data_remove_callback)(void* data, void* arg), void *arg,71 size_t bw);72 73 68 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance, 74 69 usb_address_t address, usb_endpoint_t ep, usb_direction_t direction); … … 80 75 void usb_endpoint_manager_reset_if_need( 81 76 usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data); 77 78 static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance, 79 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, 80 usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size, 81 size_t data_size) 82 { 83 endpoint_t *ep = malloc(sizeof(endpoint_t)); 84 if (ep == NULL) 85 return ENOMEM; 86 87 int ret = endpoint_init(ep, address, endpoint, direction, type, speed, 88 max_packet_size); 89 if (ret != EOK) { 90 free(ep); 91 return ret; 92 } 93 94 ret = usb_endpoint_manager_register_ep(instance, ep, data_size); 95 if (ret != EOK) { 96 endpoint_destroy(ep); 97 return ret; 98 } 99 return EOK; 100 } 82 101 #endif 83 102 /** -
uspace/lib/usb/include/usb/pipes.h
r380e0364 re1dbcbc 99 99 /** Number of active transfers over the pipe. */ 100 100 int refcount; 101 /** Number of failed attempts to open the HC phone. 102 * When user requests usb_pipe_start_long_transfer() and the operation 103 * fails, there is no way to report this to the user. 104 * That the soft reference counter is increased to record the attempt. 105 * When the user then request e.g. usb_pipe_read(), it will try to 106 * add reference as well. 107 * If that fails, it is reported to the user. If it is okay, the 108 * real reference counter is incremented. 109 * The problem might arise when ending the long transfer (since 110 * the number of references would be only 1, but logically it shall be 111 * two). 112 * Decrementing the soft counter first shall solve this. 113 */ 114 int refcount_soft; 115 116 /** Whether to automatically reset halt on the endpoint. 117 * Valid only for control endpoint zero. 118 */ 119 bool auto_reset_halt; 101 120 } usb_pipe_t; 102 121 … … 158 177 int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *); 159 178 160 int usb_pipe_start_session(usb_pipe_t *); 161 int usb_pipe_end_session(usb_pipe_t *); 162 bool usb_pipe_is_session_started(usb_pipe_t *); 163 164 int usb_pipe_start_long_transfer(usb_pipe_t *); 179 void usb_pipe_start_long_transfer(usb_pipe_t *); 165 180 void usb_pipe_end_long_transfer(usb_pipe_t *); 166 181 -
uspace/lib/usb/include/usb/usb.h
r380e0364 re1dbcbc 96 96 USB_REQUEST_RECIPIENT_DEVICE = 0, 97 97 USB_REQUEST_RECIPIENT_INTERFACE = 1, 98 USB_REQUEST_RECIPIENT_ENDPOINT = 2 98 USB_REQUEST_RECIPIENT_ENDPOINT = 2, 99 USB_REQUEST_RECIPIENT_OTHER = 3 99 100 } usb_request_recipient_t; 100 101 -
uspace/lib/usb/src/debug.c
r380e0364 re1dbcbc 158 158 159 159 /** Fibril local storage for the dumped buffer. */ 160 static fibril_local char buffer_dump[BUFFER_DUMP_LEN]; 160 static fibril_local char buffer_dump[2][BUFFER_DUMP_LEN]; 161 /** Fibril local storage for buffer switching. */ 162 static fibril_local int buffer_dump_index = 0; 161 163 162 164 /** Dump buffer into string. … … 167 169 * can not do that) and you do not have to guard it against concurrent 168 170 * calls to it. 169 * The only limitation is that each call rewrites the buffer again. 171 * The only limitation is that each second call rewrites the buffer again 172 * (internally, two buffer are used in cyclic manner). 170 173 * Thus, it is necessary to copy the buffer elsewhere (that includes printing 171 174 * to screen or writing to file). … … 173 176 * that is not a big limitation. 174 177 * 175 * @warning You cannot use this function twice in the same printf178 * @warning You cannot use this function more than twice in the same printf 176 179 * (see detailed explanation). 177 180 * … … 185 188 { 186 189 /* 187 * Remove previous string (that might also reveal double usage of 188 * this function). 190 * Remove previous string. 189 191 */ 190 bzero(buffer_dump , BUFFER_DUMP_LEN);192 bzero(buffer_dump[buffer_dump_index], BUFFER_DUMP_LEN); 191 193 192 194 if (buffer == NULL) { … … 202 204 /* How many bytes are available in the output buffer. */ 203 205 size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN; 204 char *it = buffer_dump ;206 char *it = buffer_dump[buffer_dump_index]; 205 207 206 208 size_t index = 0; … … 253 255 } 254 256 255 return buffer_dump; 257 /* Next time, use the other buffer. */ 258 buffer_dump_index = 1 - buffer_dump_index; 259 260 /* Need to take the old one due to previous line. */ 261 return buffer_dump[1 - buffer_dump_index]; 256 262 } 257 263 -
uspace/lib/usb/src/devdrv.c
r380e0364 re1dbcbc 236 236 237 237 /* It is worth to start a long transfer. */ 238 rc = usb_pipe_start_long_transfer(ctrl_pipe); 239 if (rc != EOK) { 240 return rc; 241 } 238 usb_pipe_start_long_transfer(ctrl_pipe); 242 239 243 240 /* Get the device descriptor. */ -
uspace/lib/usb/src/devpoll.c
r380e0364 re1dbcbc 33 33 * USB device driver framework - automatic interrupt polling. 34 34 */ 35 #include <usb/dev drv.h>35 #include <usb/devpoll.h> 36 36 #include <usb/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/classes/classes.h> 38 39 #include <errno.h> 39 40 #include <str_error.h> … … 45 46 /** Data needed for polling. */ 46 47 typedef struct { 48 int debug; 49 size_t max_failures; 50 useconds_t delay; 51 bool auto_clear_halt; 52 bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *); 53 void (*on_polling_end)(usb_device_t *, bool, void *); 54 bool (*on_error)(usb_device_t *, int, void *); 55 47 56 usb_device_t *dev; 48 57 size_t pipe_index; 49 usb_polling_callback_t callback;50 usb_polling_terminted_callback_t terminated_callback;51 58 size_t request_size; 52 59 uint8_t *buffer; … … 54 61 } polling_data_t; 55 62 63 56 64 /** Polling fibril. 57 65 * … … 67 75 = polling_data->dev->pipes[polling_data->pipe_index].pipe; 68 76 69 usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n", 70 polling_data->dev->pipes[polling_data->pipe_index].interface_no, 71 polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol, 72 polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass, 73 pipe->max_packet_size); 77 if (polling_data->debug > 0) { 78 usb_endpoint_mapping_t *mapping 79 = &polling_data->dev->pipes[polling_data->pipe_index]; 80 usb_log_debug("Poll%p: started polling of `%s' - " \ 81 "interface %d (%s,%d,%d), %zuB/%zu.\n", 82 polling_data, 83 polling_data->dev->ddf_dev->name, 84 (int) mapping->interface->interface_number, 85 usb_str_class(mapping->interface->interface_class), 86 (int) mapping->interface->interface_subclass, 87 (int) mapping->interface->interface_protocol, 88 polling_data->request_size, pipe->max_packet_size); 89 } 74 90 75 91 size_t failed_attempts = 0; 76 while (failed_attempts < MAX_FAILED_ATTEMPTS) {92 while (failed_attempts <= polling_data->max_failures) { 77 93 int rc; 78 94 … … 81 97 polling_data->request_size, &actual_size); 82 98 83 84 // if (rc == ESTALL) { 85 // usb_log_debug("Seding clear feature...\n"); 86 // usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD, 87 // USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no); 88 // continue; 89 // } 99 if (polling_data->debug > 1) { 100 if (rc == EOK) { 101 usb_log_debug( 102 "Poll%p: received: '%s' (%zuB).\n", 103 polling_data, 104 usb_debug_str_buffer(polling_data->buffer, 105 actual_size, 16), 106 actual_size); 107 } else { 108 usb_log_debug( 109 "Poll%p: polling failed: %s.\n", 110 polling_data, str_error(rc)); 111 } 112 } 113 114 /* If the pipe stalled, we can try to reset the stall. */ 115 if ((rc == ESTALL) && (polling_data->auto_clear_halt)) { 116 /* 117 * We ignore error here as this is usually a futile 118 * attempt anyway. 119 */ 120 usb_request_clear_endpoint_halt( 121 &polling_data->dev->ctrl_pipe, 122 pipe->endpoint_no); 123 } 90 124 91 125 if (rc != EOK) { 126 if (polling_data->on_error != NULL) { 127 bool cont = polling_data->on_error( 128 polling_data->dev, rc, 129 polling_data->custom_arg); 130 if (!cont) { 131 failed_attempts 132 = polling_data->max_failures; 133 } 134 } 92 135 failed_attempts++; 93 136 continue; … … 95 138 96 139 /* We have the data, execute the callback now. */ 97 bool carry_on = polling_data-> callback(polling_data->dev,140 bool carry_on = polling_data->on_data(polling_data->dev, 98 141 polling_data->buffer, actual_size, 99 142 polling_data->custom_arg); … … 106 149 /* Reset as something might be only a temporary problem. */ 107 150 failed_attempts = 0; 108 } 109 110 if (failed_attempts > 0) { 111 usb_log_error( 112 "Polling of device `%s' terminated: recurring failures.\n", 113 polling_data->dev->ddf_dev->name); 114 } 115 116 if (polling_data->terminated_callback != NULL) { 117 polling_data->terminated_callback(polling_data->dev, 151 152 /* Take a rest before next request. */ 153 async_usleep(polling_data->delay); 154 } 155 156 if (polling_data->on_polling_end != NULL) { 157 polling_data->on_polling_end(polling_data->dev, 118 158 failed_attempts > 0, polling_data->custom_arg); 159 } 160 161 if (polling_data->debug > 0) { 162 if (failed_attempts > 0) { 163 usb_log_error( 164 "Polling of device `%s' terminated: %s.\n", 165 polling_data->dev->ddf_dev->name, 166 "recurring failures"); 167 } else { 168 usb_log_debug( 169 "Polling of device `%s' terminated by user.\n", 170 polling_data->dev->ddf_dev->name 171 ); 172 } 119 173 } 120 174 … … 159 213 } 160 214 215 usb_device_auto_polling_t *auto_polling 216 = malloc(sizeof(usb_device_auto_polling_t)); 217 if (auto_polling == NULL) { 218 return ENOMEM; 219 } 220 221 auto_polling->debug = 1; 222 auto_polling->auto_clear_halt = true; 223 auto_polling->delay = 0; 224 auto_polling->max_failures = MAX_FAILED_ATTEMPTS; 225 auto_polling->on_data = callback; 226 auto_polling->on_polling_end = terminated_callback; 227 auto_polling->on_error = NULL; 228 229 int rc = usb_device_auto_polling(dev, pipe_index, auto_polling, 230 request_size, arg); 231 232 free(auto_polling); 233 234 return rc; 235 } 236 237 /** Start automatic device polling over interrupt in pipe. 238 * 239 * The polling settings is copied thus it is okay to destroy the structure 240 * after this function returns. 241 * 242 * @warning There is no guarantee when the request to the device 243 * will be sent for the first time (it is possible that this 244 * first request would be executed prior to return from this function). 245 * 246 * @param dev Device to be periodically polled. 247 * @param pipe_index Index of the endpoint pipe used for polling. 248 * @param polling Polling settings. 249 * @param request_size How many bytes to ask for in each request. 250 * @param arg Custom argument (passed as is to the callbacks). 251 * @return Error code. 252 * @retval EOK New fibril polling the device was already started. 253 */ 254 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index, 255 usb_device_auto_polling_t *polling, 256 size_t request_size, void *arg) 257 { 258 if (dev == NULL) { 259 return EBADMEM; 260 } 261 if (pipe_index >= dev->pipes_count) { 262 return EINVAL; 263 } 264 if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT) 265 || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) { 266 return EINVAL; 267 } 268 if ((polling == NULL) || (polling->on_data == NULL)) { 269 return EBADMEM; 270 } 271 161 272 polling_data_t *polling_data = malloc(sizeof(polling_data_t)); 162 273 if (polling_data == NULL) { … … 164 275 } 165 276 166 /* Allocate now to prevent immediate failure in the polling fibril. */167 polling_data->buffer = malloc( request_size);277 /* Fill-in the data. */ 278 polling_data->buffer = malloc(sizeof(request_size)); 168 279 if (polling_data->buffer == NULL) { 169 280 free(polling_data); 170 281 return ENOMEM; 171 282 } 283 polling_data->request_size = request_size; 172 284 polling_data->dev = dev; 173 285 polling_data->pipe_index = pipe_index; 174 polling_data->callback = callback;175 polling_data->terminated_callback = terminated_callback;176 polling_data->request_size = request_size;177 286 polling_data->custom_arg = arg; 287 288 polling_data->debug = polling->debug; 289 polling_data->max_failures = polling->max_failures; 290 if (polling->delay >= 0) { 291 polling_data->delay = (useconds_t) polling->delay; 292 } else { 293 polling_data->delay = (useconds_t) dev->pipes[pipe_index] 294 .descriptor->poll_interval; 295 } 296 polling_data->auto_clear_halt = polling->auto_clear_halt; 297 298 polling_data->on_data = polling->on_data; 299 polling_data->on_polling_end = polling->on_polling_end; 300 polling_data->on_error = polling->on_error; 178 301 179 302 fid_t fibril = fibril_create(polling_fibril, polling_data); … … 181 304 free(polling_data->buffer); 182 305 free(polling_data); 183 /* FIXME: better error code. */184 306 return ENOMEM; 185 307 } 186 308 fibril_add_ready(fibril); 187 309 188 /* The allocated buffer etc. will be freed by the fibril. */310 /* Fibril launched. That fibril will free the allocated data. */ 189 311 190 312 return EOK; -
uspace/lib/usb/src/hidparser.c
r380e0364 re1dbcbc 39 39 #include <mem.h> 40 40 #include <usb/debug.h> 41 42 /** */ 41 #include <assert.h> 42 43 /** The new report item flag. Used to determine when the item is completly 44 * configured and should be added to the report structure 45 */ 43 46 #define USB_HID_NEW_REPORT_ITEM 1 44 47 45 /** */ 46 #define USB_HID_NO_ACTION 2 47 48 /** */ 48 /** No special action after the report descriptor tag is processed should be 49 * done 50 */ 51 #define USB_HID_NO_ACTION 2 52 53 #define USB_HID_RESET_OFFSET 3 54 55 /** Unknown tag was founded in report descriptor data*/ 49 56 #define USB_HID_UNKNOWN_TAG -99 50 57 … … 52 59 * Private descriptor parser functions 53 60 */ 61 int usb_hid_report_init(usb_hid_report_t *report); 62 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item); 63 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); 54 64 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 55 65 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 61 71 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 62 72 73 void usb_hid_print_usage_path(usb_hid_report_path_t *path); 63 74 void usb_hid_descriptor_print_list(link_t *head); 64 int usb_hid_report_reset_local_items();75 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item); 65 76 void usb_hid_free_report_list(link_t *head); 66 77 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item); … … 68 79 * Data translation private functions 69 80 */ 70 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);81 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 71 82 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 72 int usb_hid_translate_data(usb_hid_report_ item_t *item, const uint8_t *data, size_t j);73 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int32_t value);83 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data); 84 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 74 85 int usb_pow(int a, int b); 75 86 87 #define USB_HID_UINT32_TO_INT32(x, size) ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1))) 88 #define USB_HID_INT32_TO_UINT32(x, size) (((x) < 0 ) ? ((1 << (size)) + (x)) : (x)) 76 89 // TODO: tohle ma bejt asi jinde 77 90 int usb_pow(int a, int b) … … 96 109 * @return Error code 97 110 */ 98 int usb_hid_ parser_init(usb_hid_report_parser_t *parser)99 { 100 if( parser== NULL) {111 int usb_hid_report_init(usb_hid_report_t *report) 112 { 113 if(report == NULL) { 101 114 return EINVAL; 102 115 } 103 116 104 list_initialize(&(parser->input)); 105 list_initialize(&(parser->output)); 106 list_initialize(&(parser->feature)); 107 108 list_initialize(&(parser->stack)); 109 110 parser->use_report_id = 0; 117 memset(report, 0, sizeof(usb_hid_report_t)); 118 list_initialize(&report->reports); 119 list_initialize(&report->collection_paths); 120 121 report->use_report_ids = 0; 111 122 return EOK; 112 123 } 113 124 125 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 126 { 127 usb_hid_report_field_t *field; 128 int i; 129 130 131 /* find or append current collection path to the list */ 132 link_t *path_it = report->collection_paths.next; 133 usb_hid_report_path_t *path = NULL; 134 while(path_it != &report->collection_paths) { 135 path = list_get_instance(path_it, usb_hid_report_path_t, link); 136 137 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 138 break; 139 } 140 path_it = path_it->next; 141 } 142 if(path_it == &report->collection_paths) { 143 path = usb_hid_report_path_clone(report_item->usage_path); 144 list_append(&path->link, &report->collection_paths); 145 report->collection_paths_count++; 146 } 147 148 for(i=0; i<report_item->usages_count; i++){ 149 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]); 150 } 151 152 153 for(i=0; i<report_item->count; i++){ 154 155 field = malloc(sizeof(usb_hid_report_field_t)); 156 memset(field, 0, sizeof(usb_hid_report_field_t)); 157 list_initialize(&field->link); 158 159 /* fill the attributes */ 160 field->collection_path = path; 161 field->logical_minimum = report_item->logical_minimum; 162 field->logical_maximum = report_item->logical_maximum; 163 field->physical_minimum = report_item->physical_minimum; 164 field->physical_maximum = report_item->physical_maximum; 165 166 field->usage_minimum = report_item->usage_minimum; 167 field->usage_maximum = report_item->usage_maximum; 168 if(report_item->extended_usage_page != 0){ 169 field->usage_page = report_item->extended_usage_page; 170 } 171 else { 172 field->usage_page = report_item->usage_page; 173 } 174 175 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 176 uint32_t usage; 177 if(report_item->type != USB_HID_REPORT_TYPE_INPUT) { 178 if(i < report_item->usages_count){ 179 usage = report_item->usages[i]; 180 } 181 else { 182 usage = report_item->usages[report_item->usages_count - 1]; 183 } 184 } 185 else { 186 if((report_item->count - i - 1) < report_item->usages_count){ 187 usage = report_item->usages[(report_item->count - i - 1)]; 188 } 189 else { 190 usage = report_item->usages[report_item->usages_count - 1]; 191 } 192 } 193 194 195 if((usage & 0xFFFF0000) != 0){ 196 field->usage_page = (usage >> 16); 197 field->usage = (usage & 0xFFFF); 198 } 199 else { 200 field->usage = usage; 201 } 202 203 204 } 205 206 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) { 207 if(report_item->type == USB_HID_REPORT_TYPE_INPUT) { 208 field->usage = report_item->usage_maximum - i; 209 } 210 else { 211 field->usage = report_item->usage_minimum + i; 212 } 213 214 } 215 216 field->size = report_item->size; 217 field->offset = report_item->offset + (i * report_item->size); 218 if(report_item->id != 0) { 219 field->offset += 8; 220 report->use_report_ids = 1; 221 } 222 field->item_flags = report_item->item_flags; 223 224 /* find the right report list*/ 225 usb_hid_report_description_t *report_des; 226 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 227 if(report_des == NULL){ 228 report_des = malloc(sizeof(usb_hid_report_description_t)); 229 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 230 231 report_des->type = report_item->type; 232 report_des->report_id = report_item->id; 233 list_initialize (&report_des->link); 234 list_initialize (&report_des->report_items); 235 236 list_append(&report_des->link, &report->reports); 237 report->report_count++; 238 } 239 240 /* append this field to the end of founded report list */ 241 list_append (&field->link, &report_des->report_items); 242 243 /* update the sizes */ 244 report_des->bit_length += field->size; 245 report_des->item_length++; 246 247 } 248 249 250 return EOK; 251 } 252 253 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) 254 { 255 link_t *report_it = report->reports.next; 256 usb_hid_report_description_t *report_des = NULL; 257 258 while(report_it != &report->reports) { 259 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 260 261 if((report_des->report_id == report_id) && (report_des->type == type)){ 262 return report_des; 263 } 264 265 report_it = report_it->next; 266 } 267 268 return NULL; 269 } 114 270 115 271 /** Parse HID report descriptor. … … 119 275 * @return Error code. 120 276 */ 121 int usb_hid_parse_report_descriptor(usb_hid_report_ parser_t *parser,277 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 122 278 const uint8_t *data, size_t size) 123 279 { … … 130 286 usb_hid_report_item_t *new_report_item; 131 287 usb_hid_report_path_t *usage_path; 132 usb_hid_report_path_t *tmp_usage_path;133 288 134 289 size_t offset_input=0; 135 290 size_t offset_output=0; 136 291 size_t offset_feature=0; 137 292 293 link_t stack; 294 list_initialize(&stack); 138 295 139 296 /* parser structure initialization*/ 140 if(usb_hid_ parser_init(parser) != EOK) {297 if(usb_hid_report_init(report) != EOK) { 141 298 return EINVAL; 142 299 } 143 300 144 145 301 /*report item initialization*/ 146 302 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ … … 159 315 160 316 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 161 return EINVAL; // TODO ERROR CODE317 return EINVAL; 162 318 } 163 319 … … 165 321 item_size = USB_HID_ITEM_SIZE(data[i]); 166 322 class = USB_HID_ITEM_TAG_CLASS(data[i]); 167 168 usb_log_debug2(169 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i,170 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size),171 tag, class, item_size);172 323 173 324 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 174 325 item_size,report_item, usage_path); 175 usb_log_debug2("ret: %u\n", ret);176 326 switch(ret){ 177 327 case USB_HID_NEW_REPORT_ITEM: 178 328 // store report item to report and create the new one 179 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 180 181 // store current usage path 329 // store current collection path 182 330 report_item->usage_path = usage_path; 183 331 184 // clone path to the new one185 tmp_usage_path = usb_hid_report_path_clone(usage_path);186 187 // swap188 usage_path = tmp_usage_path;189 tmp_usage_path = NULL;190 191 332 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 192 333 if(report_item->id != 0){ 193 parser->use_report_id= 1;334 report->use_report_ids = 1; 194 335 } 195 336 196 337 switch(tag) { 197 338 case USB_HID_REPORT_TAG_INPUT: 339 report_item->type = USB_HID_REPORT_TYPE_INPUT; 198 340 report_item->offset = offset_input; 199 341 offset_input += report_item->count * report_item->size; 200 usb_log_debug(" - INPUT\n");201 list_append(&(report_item->link), &(parser->input));202 342 break; 203 343 case USB_HID_REPORT_TAG_OUTPUT: 344 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 204 345 report_item->offset = offset_output; 205 346 offset_output += report_item->count * report_item->size; 206 usb_log_debug(" - OUTPUT\n");207 list_append(&(report_item->link), &(parser->output));208 347 209 348 break; 210 349 case USB_HID_REPORT_TAG_FEATURE: 350 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 211 351 report_item->offset = offset_feature; 212 352 offset_feature += report_item->count * report_item->size; 213 usb_log_debug(" - FEATURE\n");214 list_append(&(report_item->link), &(parser->feature));215 353 break; 216 354 default: … … 218 356 break; 219 357 } 220 221 /* clone current state table to the new item */222 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {223 return ENOMEM;224 }225 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));226 link_initialize(&(new_report_item->link));227 358 359 /* 360 * append new fields to the report 361 * structure 362 */ 363 usb_hid_report_append_fields(report, report_item); 364 228 365 /* reset local items */ 229 new_report_item->usage_minimum = 0; 230 new_report_item->usage_maximum = 0; 231 new_report_item->designator_index = 0; 232 new_report_item->designator_minimum = 0; 233 new_report_item->designator_maximum = 0; 234 new_report_item->string_index = 0; 235 new_report_item->string_minimum = 0; 236 new_report_item->string_maximum = 0; 237 238 /* reset usage from current usage path */ 239 usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link); 240 path->usage = 0; 241 242 report_item = new_report_item; 243 366 usb_hid_report_reset_local_items (report_item); 367 244 368 break; 369 370 case USB_HID_RESET_OFFSET: 371 offset_input = 0; 372 offset_output = 0; 373 offset_feature = 0; 374 usb_hid_report_path_set_report_id (usage_path, report_item->id); 375 break; 376 245 377 case USB_HID_REPORT_TAG_PUSH: 246 378 // push current state to stack 247 379 new_report_item = usb_hid_report_item_clone(report_item); 248 list_prepend (&parser->stack, &new_report_item->link); 249 380 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 381 new_report_item->usage_path = tmp_path; 382 383 list_prepend (&new_report_item->link, &stack); 250 384 break; 251 385 case USB_HID_REPORT_TAG_POP: 252 386 // restore current state from stack 253 if(list_empty (& parser->stack)) {387 if(list_empty (&stack)) { 254 388 return EINVAL; 255 389 } 390 free(report_item); 391 392 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 256 393 257 report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link); 258 list_remove (parser->stack.next); 394 usb_hid_report_usage_path_t *tmp_usage_path; 395 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 396 397 usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage); 398 399 usb_hid_report_path_free(report_item->usage_path); 400 list_initialize(&report_item->usage_path->link); 401 list_remove (stack.next); 259 402 260 403 break; … … 279 422 } 280 423 281 282 /**283 * Parse input report.284 *285 * @param data Data for report286 * @param size Size of report287 * @param callbacks Callbacks for report actions288 * @param arg Custom arguments289 *290 * @return Error code291 */292 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,293 const usb_hid_report_in_callbacks_t *callbacks, void *arg)294 {295 int i;296 usb_hid_report_item_t item;297 298 /* fill item due to the boot protocol report descriptor */299 // modifier keys are in the first byte300 uint8_t modifiers = data[0];301 302 item.offset = 2; /* second byte is reserved */303 item.size = 8;304 item.count = 6;305 item.usage_minimum = 0;306 item.usage_maximum = 255;307 item.logical_minimum = 0;308 item.logical_maximum = 255;309 310 if (size != 8) {311 return -1; //ERANGE;312 }313 314 uint8_t keys[6];315 for (i = 0; i < item.count; i++) {316 keys[i] = data[i + item.offset];317 }318 319 callbacks->keyboard(keys, 6, modifiers, arg);320 return EOK;321 }322 323 /**324 * Makes output report for keyboard boot protocol325 *326 * @param leds327 * @param output Output report data buffer328 * @param size Size of the output buffer329 * @return Error code330 */331 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)332 {333 if(size != 1){334 return -1;335 }336 337 /* used only first five bits, others are only padding*/338 *data = leds;339 return EOK;340 }341 424 342 425 /** … … 401 484 402 485 case USB_HID_REPORT_TAG_COLLECTION: 403 usb_hid_report_path_append_item(usage_path, 0, 0); 404 486 // TODO usage_path->flags = *data; 487 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 488 usb_hid_report_reset_local_items (report_item); 405 489 return USB_HID_NO_ACTION; 406 490 break; 407 491 408 492 case USB_HID_REPORT_TAG_END_COLLECTION: 409 // TODO410 // znici posledni uroven ve vsech usage paths411 // otazka jestli nema nicit dve, respektive novou posledni vynulovat?412 493 usb_hid_report_remove_last_item(usage_path); 413 494 return USB_HID_NO_ACTION; … … 436 517 { 437 518 case USB_HID_REPORT_TAG_USAGE_PAGE: 438 // zmeni to jenom v poslednim poli aktualni usage path 439 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 440 usb_hid_report_tag_data_int32(data,item_size)); 519 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 441 520 break; 442 521 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 443 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);522 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 444 523 break; 445 524 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 446 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);525 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 447 526 break; 448 527 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 449 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);528 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 450 529 break; 451 530 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 452 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size); 531 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 532 453 533 break; 454 534 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 455 report_item->unit_exponent = usb_hid_report_tag_data_ int32(data,item_size);535 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 456 536 break; 457 537 case USB_HID_REPORT_TAG_UNIT: 458 report_item->unit = usb_hid_report_tag_data_ int32(data,item_size);538 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 459 539 break; 460 540 case USB_HID_REPORT_TAG_REPORT_SIZE: 461 report_item->size = usb_hid_report_tag_data_ int32(data,item_size);541 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 462 542 break; 463 543 case USB_HID_REPORT_TAG_REPORT_COUNT: 464 report_item->count = usb_hid_report_tag_data_ int32(data,item_size);544 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 465 545 break; 466 546 case USB_HID_REPORT_TAG_REPORT_ID: 467 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 547 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 548 return USB_HID_RESET_OFFSET; 468 549 break; 469 550 case USB_HID_REPORT_TAG_PUSH: 470 551 case USB_HID_REPORT_TAG_POP: 552 /* 553 * stack operations are done in top level parsing 554 * function 555 */ 471 556 return tag; 472 557 break; … … 475 560 return USB_HID_NO_ACTION; 476 561 } 477 562 478 563 return EOK; 479 564 } … … 494 579 { 495 580 case USB_HID_REPORT_TAG_USAGE: 496 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,497 usb_hid_report_tag_data_int32(data,item_size));581 report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size); 582 report_item->usages_count++; 498 583 break; 499 584 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 500 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 585 if (item_size == 3) { 586 // usage extended usages 587 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 588 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 589 } 590 else { 591 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 592 } 501 593 break; 502 594 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 503 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 595 if (item_size == 3) { 596 // usage extended usages 597 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 598 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 599 } 600 else { 601 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 602 } 504 603 break; 505 604 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 506 report_item->designator_index = usb_hid_report_tag_data_ int32(data,item_size);605 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 507 606 break; 508 607 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 509 report_item->designator_minimum = usb_hid_report_tag_data_ int32(data,item_size);608 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 510 609 break; 511 610 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 512 report_item->designator_maximum = usb_hid_report_tag_data_ int32(data,item_size);611 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 513 612 break; 514 613 case USB_HID_REPORT_TAG_STRING_INDEX: 515 report_item->string_index = usb_hid_report_tag_data_ int32(data,item_size);614 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 516 615 break; 517 616 case USB_HID_REPORT_TAG_STRING_MINIMUM: 518 report_item->string_minimum = usb_hid_report_tag_data_ int32(data,item_size);617 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 519 618 break; 520 619 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 521 report_item->string_maximum = usb_hid_report_tag_data_ int32(data,item_size);620 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 522 621 break; 523 622 case USB_HID_REPORT_TAG_DELIMITER: 524 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 623 //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size); 624 //TODO: 625 // DELIMITER STUFF 525 626 break; 526 627 … … 533 634 534 635 /** 535 * Converts raw data to int32 (thats the maximum length of short item data)636 * Converts raw data to uint32 (thats the maximum length of short item data) 536 637 * 537 638 * @param Data buffer … … 539 640 * @return Converted int32 number 540 641 */ 541 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)642 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size) 542 643 { 543 644 unsigned int i; 544 int32_t result;645 uint32_t result; 545 646 546 647 result = 0; … … 552 653 } 553 654 554 555 556 655 /** 557 656 * Prints content of given list of report items. … … 562 661 void usb_hid_descriptor_print_list(link_t *head) 563 662 { 564 usb_hid_report_item_t *report_item; 565 usb_hid_report_usage_path_t *path_item; 566 link_t *path; 663 usb_hid_report_field_t *report_item; 567 664 link_t *item; 568 665 666 569 667 if(head == NULL || list_empty(head)) { 570 668 usb_log_debug("\tempty\n"); … … 574 672 for(item = head->next; item != head; item = item->next) { 575 673 576 report_item = list_get_instance(item, usb_hid_report_item_t, link); 577 578 usb_log_debug("\tOFFSET: %X\n", report_item->offset); 579 usb_log_debug("\tCOUNT: %X\n", report_item->count); 580 usb_log_debug("\tSIZE: %X\n", report_item->size); 581 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 582 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 583 usb_log_debug("\tUSAGE PATH:\n"); 584 585 path = report_item->usage_path->link.next; 586 while(path != &report_item->usage_path->link) { 587 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 588 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 589 path = path->next; 590 } 591 592 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 593 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); 594 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum); 595 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum); 596 usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum); 597 usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum); 598 599 usb_log_debug("\n"); 674 report_item = list_get_instance(item, usb_hid_report_field_t, link); 675 676 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 677 usb_log_debug("\t\tSIZE: %X\n", report_item->size); 678 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 679 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 680 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 681 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 682 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 683 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 684 685 usb_log_debug("\t\tVALUE: %X\n", report_item->value); 686 usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage); 687 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 688 689 // usb_log_debug("\n"); 600 690 601 691 } … … 609 699 * @return void 610 700 */ 611 void usb_hid_descriptor_print(usb_hid_report_ parser_t *parser)612 { 613 if( parser== NULL) {701 void usb_hid_descriptor_print(usb_hid_report_t *report) 702 { 703 if(report == NULL) { 614 704 return; 615 705 } 616 617 usb_log_debug("INPUT:\n"); 618 usb_hid_descriptor_print_list(&parser->input); 619 620 usb_log_debug("OUTPUT: \n"); 621 usb_hid_descriptor_print_list(&parser->output); 622 623 usb_log_debug("FEATURE:\n"); 624 usb_hid_descriptor_print_list(&parser->feature); 625 706 707 link_t *report_it = report->reports.next; 708 usb_hid_report_description_t *report_des; 709 710 while(report_it != &report->reports) { 711 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 712 usb_log_debug("Report ID: %d\n", report_des->report_id); 713 usb_log_debug("\tType: %d\n", report_des->type); 714 usb_log_debug("\tLength: %d\n", report_des->bit_length); 715 usb_log_debug("\tItems: %d\n", report_des->item_length); 716 717 usb_hid_descriptor_print_list(&report_des->report_items); 718 719 720 link_t *path_it = report->collection_paths.next; 721 while(path_it != &report->collection_paths) { 722 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link)); 723 path_it = path_it->next; 724 } 725 726 report_it = report_it->next; 727 } 626 728 } 627 729 … … 667 769 * @return void 668 770 */ 669 void usb_hid_free_report _parser(usb_hid_report_parser_t *parser)670 { 671 if( parser== NULL){771 void usb_hid_free_report(usb_hid_report_t *report) 772 { 773 if(report == NULL){ 672 774 return; 673 775 } 674 776 675 parser->use_report_id = 0; 676 677 usb_hid_free_report_list(&parser->input); 678 usb_hid_free_report_list(&parser->output); 679 usb_hid_free_report_list(&parser->feature); 680 777 // free collection paths 778 usb_hid_report_path_t *path; 779 while(!list_empty(&report->collection_paths)) { 780 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 781 usb_hid_report_path_free(path); 782 } 783 784 // free report items 785 usb_hid_report_description_t *report_des; 786 usb_hid_report_field_t *field; 787 while(!list_empty(&report->reports)) { 788 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 789 list_remove(&report_des->link); 790 791 while(!list_empty(&report_des->report_items)) { 792 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 793 list_remove(&field->link); 794 795 free(field); 796 } 797 798 free(report_des); 799 } 800 681 801 return; 682 802 } … … 688 808 * @param parser Opaque HID report parser structure. 689 809 * @param data Data for the report. 690 * @param callbacks Callbacks for report actions.691 * @param arg Custom argument (passed through to the callbacks).692 810 * @return Error code. 693 811 */ 694 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 695 const uint8_t *data, size_t size, 696 usb_hid_report_path_t *path, int flags, 697 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 812 int usb_hid_parse_report(const usb_hid_report_t *report, 813 const uint8_t *data, size_t size, uint8_t *report_id) 698 814 { 699 815 link_t *list_item; 700 usb_hid_report_item_t *item; 701 uint8_t *keys; 702 uint8_t item_value; 703 size_t key_count=0; 704 size_t i=0; 705 size_t j=0; 706 uint8_t report_id = 0; 707 708 if(parser == NULL) { 816 usb_hid_report_field_t *item; 817 818 usb_hid_report_description_t *report_des; 819 usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT; 820 821 if(report == NULL) { 709 822 return EINVAL; 710 823 } 711 712 /* get the size of result array */ 713 key_count = usb_hid_report_input_length(parser, path, flags); 714 715 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ 716 return ENOMEM; 717 } 718 719 if(parser->use_report_id != 0) { 720 report_id = data[0]; 721 usb_hid_report_path_set_report_id(path, report_id); 722 } 824 825 if(report->use_report_ids != 0) { 826 *report_id = data[0]; 827 } 828 else { 829 *report_id = 0; 830 } 831 832 833 report_des = usb_hid_report_find_description(report, *report_id, type); 723 834 724 835 /* read data */ 725 list_item = parser->input.next; 726 while(list_item != &(parser->input)) { 727 728 item = list_get_instance(list_item, usb_hid_report_item_t, link); 729 730 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 731 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 732 for(j=0; j<(size_t)(item->count); j++) { 733 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || 734 ((item->usage_minimum == 0) && (item->usage_maximum == 0))) { 735 // variable item 736 keys[i++] = usb_hid_translate_data(item, data,j); 737 } 738 else { 739 // bitmapa 740 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 741 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 742 } 743 else { 744 keys[i++] = 0; 745 } 746 } 747 } 836 list_item = report_des->report_items.next; 837 while(list_item != &(report_des->report_items)) { 838 839 item = list_get_instance(list_item, usb_hid_report_field_t, link); 840 841 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) { 842 843 if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) { 844 845 // array 846 item->value = usb_hid_translate_data(item, data); 847 item->usage = (item->value - item->physical_minimum) + item->usage_minimum; 848 } 849 else { 850 // variable item 851 item->value = usb_hid_translate_data(item, data); 852 } 748 853 } 749 854 list_item = list_item->next; 750 855 } 751 752 callbacks->keyboard(keys, key_count, report_id, arg);753 856 754 free(keys);755 857 return EOK; 756 858 … … 758 860 759 861 /** 760 * Translate data from the report as specified in report descriptor 862 * Translate data from the report as specified in report descriptor item 761 863 * 762 864 * @param item Report descriptor item with definition of translation … … 765 867 * @return Translated data 766 868 */ 767 int usb_hid_translate_data(usb_hid_report_ item_t *item, const uint8_t *data, size_t j)869 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data) 768 870 { 769 871 int resolution; … … 771 873 int part_size; 772 874 773 int32_t value ;875 int32_t value=0; 774 876 int32_t mask; 775 877 const uint8_t *foo; 776 878 777 // now only common numbersllowed879 // now only shot tags are allowed 778 880 if(item->size > 32) { 779 881 return 0; 780 882 } 781 883 782 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {884 if((item->physical_minimum == 0) && (item->physical_maximum == 0)){ 783 885 item->physical_minimum = item->logical_minimum; 784 item->physical_maximum = item->logical_maximum; 785 } 886 item->physical_maximum = item->logical_maximum; 887 } 888 786 889 787 890 if(item->physical_maximum == item->physical_minimum){ … … 794 897 } 795 898 796 offset = item->offset + (j * item->size); 797 if(item->id != 0) { 798 offset += 8; 799 usb_log_debug("MOVED OFFSET BY 1Byte, REPORT_ID(%d)\n", item->id); 800 } 801 899 offset = item->offset; 802 900 // FIXME 803 if((offset/8) != ((offset+item->size)/8)) { 804 usb_log_debug2("offset %d\n", offset); 901 if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) { 805 902 806 903 part_size = ((offset+item->size)%8); 807 usb_log_debug2("part size %d\n",part_size); 808 809 // the higher one 810 foo = data+(offset/8); 811 mask = ((1 << (item->size-part_size))-1); 812 value = (*foo & mask) << part_size; 813 814 usb_log_debug2("hfoo %x\n", *foo); 815 usb_log_debug2("hmaska %x\n", mask); 816 usb_log_debug2("hval %d\n", value); 817 818 // the lower one 819 foo = data+((offset+item->size)/8); 820 mask = ((1 << part_size)-1) << (8-part_size); 821 value += ((*foo & mask) >> (8-part_size)); 822 823 usb_log_debug2("lfoo %x\n", *foo); 824 usb_log_debug2("lmaska %x\n", mask); 825 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size)))); 826 usb_log_debug2("val %d\n", value); 827 828 904 905 size_t i=0; 906 for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){ 907 if(i == (size_t)(offset/8)) { 908 // the higher one 909 foo = data + i; 910 mask = ((1 << (item->size-part_size))-1); 911 value = (*foo & mask) << part_size; 912 } 913 else if(i == ((offset+item->size-1)/8)){ 914 // the lower one 915 foo = data + i; 916 mask = ((1 << part_size)-1) << (8-part_size); 917 value += ((*foo & mask) >> (8-part_size)); 918 } 919 else { 920 value = value << 8; 921 value += *(data + 1); 922 } 923 } 829 924 } 830 925 else { … … 832 927 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 833 928 value = (*foo & mask) >> (8-((offset%8)+item->size)); 834 835 usb_log_debug2("offset %d\n", offset); 836 837 usb_log_debug2("foo %x\n", *foo); 838 usb_log_debug2("maska %x\n", mask); 839 usb_log_debug2("val %d\n", value); 840 } 841 842 usb_log_debug2("---\n\n"); 929 } 930 931 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 932 value = USB_HID_UINT32_TO_INT32(value, item->size); 933 } 843 934 844 935 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); … … 847 938 848 939 /** 849 * 850 * 851 * @param parser 852 * @param path 853 * @param flags 854 * @return 855 */ 856 size_t usb_hid_report_input_length(const usb_hid_report_ parser_t *parser,940 * Returns number of items in input report which are accessible by given usage path 941 * 942 * @param parser Opaque report descriptor structure 943 * @param path Usage path specification 944 * @param flags Usage path comparison flags 945 * @return Number of items in input report 946 */ 947 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 857 948 usb_hid_report_path_t *path, int flags) 858 949 { 950 859 951 size_t ret = 0; 860 link_t *item; 861 usb_hid_report_item_t *report_item; 862 863 if(parser == NULL) { 952 953 if(report == NULL) { 864 954 return 0; 865 955 } 866 867 item = parser->input.next; 868 while(&parser->input != item) { 869 report_item = list_get_instance(item, usb_hid_report_item_t, link); 870 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 871 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 872 ret += report_item->count; 873 } 874 875 item = item->next; 876 } 956 957 usb_hid_report_description_t *report_des; 958 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT); 959 if(report_des == NULL) { 960 return 0; 961 } 962 963 link_t *field_it = report_des->report_items.next; 964 usb_hid_report_field_t *field; 965 while(field_it != &report_des->report_items) { 966 967 field = list_get_instance(field_it, usb_hid_report_field_t, link); 968 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 969 970 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 971 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 972 ret++; 973 } 974 usb_hid_report_remove_last_item (field->collection_path); 975 } 976 977 field_it = field_it->next; 978 } 877 979 878 980 return ret; 879 } 880 881 882 /** 883 * 884 * @param usage_path 885 * @param usage_page 886 * @param usage 887 * @return 981 } 982 983 984 /** 985 * Appends one item (couple of usage_path and usage) into the usage path 986 * structure 987 * 988 * @param usage_path Usage path structure 989 * @param usage_page Usage page constant 990 * @param usage Usage constant 991 * @return Error code 888 992 */ 889 993 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, … … 899 1003 item->usage = usage; 900 1004 item->usage_page = usage_page; 901 902 list_append (&usage_path->link, &item->link); 1005 item->flags = 0; 1006 1007 list_append (&item->link, &usage_path->head); 903 1008 usage_path->depth++; 904 1009 return EOK; … … 906 1011 907 1012 /** 908 * 909 * @param usage_path 910 * @return 1013 * Removes last item from the usage path structure 1014 * @param usage_path 1015 * @return void 911 1016 */ 912 1017 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) … … 914 1019 usb_hid_report_usage_path_t *item; 915 1020 916 if(!list_empty(&usage_path-> link)){917 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);918 list_remove(usage_path-> link.prev);1021 if(!list_empty(&usage_path->head)){ 1022 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 1023 list_remove(usage_path->head.prev); 919 1024 usage_path->depth--; 920 1025 free(item); … … 923 1028 924 1029 /** 1030 * Nulls last item of the usage path structure. 925 1031 * 926 1032 * @param usage_path 927 * @return 1033 * @return void 928 1034 */ 929 1035 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) … … 931 1037 usb_hid_report_usage_path_t *item; 932 1038 933 if(!list_empty(&usage_path-> link)){934 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);1039 if(!list_empty(&usage_path->head)){ 1040 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 935 1041 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 936 1042 } … … 938 1044 939 1045 /** 940 * 941 * @param usage_path 942 * @param tag 943 * @param data 944 * @return 1046 * Modifies last item of usage path structure by given usage page or usage 1047 * 1048 * @param usage_path Opaque usage path structure 1049 * @param tag Class of currently processed tag (Usage page tag falls into Global 1050 * class but Usage tag into the Local) 1051 * @param data Value of the processed tag 1052 * @return void 945 1053 */ 946 1054 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) … … 948 1056 usb_hid_report_usage_path_t *item; 949 1057 950 if(!list_empty(&usage_path-> link)){951 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);1058 if(!list_empty(&usage_path->head)){ 1059 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 952 1060 953 1061 switch(tag) { … … 963 1071 } 964 1072 965 /** 966 * 967 * 968 * @param report_path 969 * @param path 970 * @param flags 971 * @return 1073 1074 void usb_hid_print_usage_path(usb_hid_report_path_t *path) 1075 { 1076 usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id); 1077 usb_log_debug("\tLENGTH: %d\n", path->depth); 1078 1079 link_t *item = path->head.next; 1080 usb_hid_report_usage_path_t *path_item; 1081 while(item != &path->head) { 1082 1083 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link); 1084 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page); 1085 usb_log_debug("\tUSAGE: %X\n", path_item->usage); 1086 usb_log_debug("\tFLAGS: %d\n", path_item->flags); 1087 1088 item = item->next; 1089 } 1090 } 1091 1092 /** 1093 * Compares two usage paths structures 1094 * 1095 * If USB_HID_PATH_COMPARE_COLLECTION_ONLY flag is given, the last item in report_path structure is forgotten 1096 * 1097 * @param report_path usage path structure to compare 1098 * @param path usage patrh structure to compare 1099 * @param flags Flags determining the mode of comparison 1100 * @return EOK if both paths are identical, non zero number otherwise 972 1101 */ 973 1102 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, … … 1003 1132 } 1004 1133 1005 report_link = report_path-> link.next;1006 path_link = path-> link.next;1134 report_link = report_path->head.next; 1135 path_link = path->head.next; 1007 1136 1008 while((report_link != &report_path-> link) && (path_link != &path->link)) {1137 while((report_link != &report_path->head) && (path_link != &path->head)) { 1009 1138 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1010 1139 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1020 1149 } 1021 1150 1022 if((report_link == &report_path->link) && (path_link == &path->link)) { 1151 if(((report_link == &report_path->head) && (path_link == &path->head)) || 1152 (((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) && (path_link = &path->head) && (report_link == report_path->head.prev))) { 1023 1153 return EOK; 1024 1154 } … … 1030 1160 /* compare with only the end of path*/ 1031 1161 case USB_HID_PATH_COMPARE_END: 1032 report_link = report_path->link.prev; 1033 path_link = path->link.prev; 1034 1035 if(list_empty(&path->link)){ 1162 1163 if((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) { 1164 report_link = report_path->head.prev->prev; 1165 } 1166 else { 1167 report_link = report_path->head.prev; 1168 } 1169 path_link = path->head.prev; 1170 1171 if(list_empty(&path->head)){ 1036 1172 return EOK; 1037 1173 } 1038 1174 1039 while((report_link != &report_path-> link) && (path_link != &path->link)) {1175 while((report_link != &report_path->head) && (path_link != &path->head)) { 1040 1176 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1041 1177 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1051 1187 } 1052 1188 1053 if(path_link == &path-> link) {1189 if(path_link == &path->head) { 1054 1190 return EOK; 1055 1191 } … … 1070 1206 1071 1207 /** 1072 * 1073 * @return 1208 * Allocates and initializes new usage path structure. 1209 * 1210 * @return Initialized usage path structure 1074 1211 */ 1075 1212 usb_hid_report_path_t *usb_hid_report_path(void) … … 1077 1214 usb_hid_report_path_t *path; 1078 1215 path = malloc(sizeof(usb_hid_report_path_t)); 1079 if( !path){1216 if(path == NULL){ 1080 1217 return NULL; 1081 1218 } … … 1084 1221 path->report_id = 0; 1085 1222 list_initialize(&path->link); 1223 list_initialize(&path->head); 1086 1224 return path; 1087 1225 } … … 1089 1227 1090 1228 /** 1091 * 1092 * @param path 1229 * Releases given usage path structure. 1230 * 1231 * @param path usage path structure to release 1093 1232 * @return void 1094 1233 */ 1095 1234 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1096 1235 { 1097 while(!list_empty(&path-> link)){1236 while(!list_empty(&path->head)){ 1098 1237 usb_hid_report_remove_last_item(path); 1099 1238 } 1239 1240 list_remove(&path->link); 1241 free(path); 1100 1242 } 1101 1243 … … 1104 1246 * Clone content of given usage path to the new one 1105 1247 * 1106 * @param usage_path 1107 * @return 1248 * @param usage_path Usage path structure to clone 1249 * @return New copy of given usage path structure 1108 1250 */ 1109 1251 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 1110 1252 { 1253 link_t *path_link; 1111 1254 usb_hid_report_usage_path_t *path_item; 1112 link_t *path_link;1255 usb_hid_report_usage_path_t *new_path_item; 1113 1256 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1114 1257 … … 1116 1259 return NULL; 1117 1260 } 1118 1119 if(list_empty(&usage_path->link)){ 1261 1262 new_usage_path->report_id = usage_path->report_id; 1263 1264 if(list_empty(&usage_path->head)){ 1120 1265 return new_usage_path; 1121 1266 } 1122 1267 1123 path_link = usage_path-> link.next;1124 while(path_link != &usage_path-> link) {1268 path_link = usage_path->head.next; 1269 while(path_link != &usage_path->head) { 1125 1270 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1126 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1271 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t)); 1272 if(new_path_item == NULL) { 1273 return NULL; 1274 } 1275 1276 list_initialize (&new_path_item->link); 1277 new_path_item->usage_page = path_item->usage_page; 1278 new_path_item->usage = path_item->usage; 1279 new_path_item->flags = path_item->flags; 1280 1281 list_append(&new_path_item->link, &new_usage_path->head); 1282 new_usage_path->depth++; 1127 1283 1128 1284 path_link = path_link->next; … … 1135 1291 /*** OUTPUT API **/ 1136 1292 1137 /** Allocates output report buffer 1138 * 1139 * @param parser 1140 * @param size 1141 * @return 1142 */ 1143 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size) 1144 { 1145 if(parser == NULL) { 1293 /** 1294 * Allocates output report buffer for output report 1295 * 1296 * @param parser Report parsed structure 1297 * @param size Size of returned buffer 1298 * @param report_id Report id of created output report 1299 * @return Returns allocated output buffer for specified output 1300 */ 1301 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 1302 { 1303 if(report == NULL) { 1146 1304 *size = 0; 1147 1305 return NULL; 1148 1306 } 1149 1150 // read the last output report item1151 usb_hid_report_ item_t *last;1152 link_t *link;1153 1154 link = parser->output.prev;1155 if(link != &parser->output) {1156 last = list_get_instance(link, usb_hid_report_item_t, link);1157 *size = (last->offset + (last->size * last->count)) / 8; 1158 1159 uint8_t *buffer = malloc(sizeof(uint8_t) * (*size));1160 memset(buffer, 0, sizeof(uint8_t) * (*size)); 1161 usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0));1162 1163 return buffer;1307 1308 link_t *report_it = report->reports.next; 1309 usb_hid_report_description_t *report_des = NULL; 1310 while(report_it != &report->reports) { 1311 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 1312 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 1313 break; 1314 } 1315 1316 report_it = report_it->next; 1317 } 1318 1319 if(report_des == NULL){ 1320 *size = 0; 1321 return NULL; 1164 1322 } 1165 1323 else { 1166 *size = 0; 1167 return NULL; 1324 *size = (report_des->bit_length + (8 - 1))/8; 1325 uint8_t *ret = malloc((*size) * sizeof(uint8_t)); 1326 memset(ret, 0, (*size) * sizeof(uint8_t)); 1327 return ret; 1168 1328 } 1169 1329 } … … 1173 1333 * 1174 1334 * @param output Output report buffer 1175 * @return 1335 * @return void 1176 1336 */ 1177 1337 void usb_hid_report_output_free(uint8_t *output) … … 1185 1345 /** Returns size of output for given usage path 1186 1346 * 1187 * @param parser 1188 * @param path 1189 * @param flags 1190 * @return 1191 */ 1192 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,1347 * @param parser Opaque report parser structure 1348 * @param path Usage path specified which items will be thought for the output 1349 * @param flags Flags of usage path structure comparison 1350 * @return Number of items matching the given usage path 1351 */ 1352 size_t usb_hid_report_output_size(usb_hid_report_t *report, 1193 1353 usb_hid_report_path_t *path, int flags) 1194 1354 { 1195 size_t ret = 0; 1196 link_t *item; 1197 usb_hid_report_item_t *report_item; 1198 1199 if(parser == NULL) { 1355 size_t ret = 0; 1356 usb_hid_report_description_t *report_des; 1357 1358 if(report == NULL) { 1200 1359 return 0; 1201 1360 } 1202 1361 1203 item = parser->output.next; 1204 while(&parser->output != item) { 1205 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1206 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 1207 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 1208 ret += report_item->count; 1209 } 1210 1211 item = item->next; 1212 } 1362 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT); 1363 if(report_des == NULL){ 1364 return 0; 1365 } 1366 1367 link_t *field_it = report_des->report_items.next; 1368 usb_hid_report_field_t *field; 1369 while(field_it != &report_des->report_items) { 1370 1371 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1372 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){ 1373 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1374 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 1375 ret++; 1376 } 1377 usb_hid_report_remove_last_item (field->collection_path); 1378 } 1379 1380 field_it = field_it->next; 1381 } 1213 1382 1214 1383 return ret; … … 1216 1385 } 1217 1386 1218 /** Updates the output report buffer by translated given data 1219 * 1220 * @param parser 1221 * @param path 1222 * @param flags 1223 * @param buffer 1224 * @param size 1225 * @param data 1226 * @param data_size 1227 * @return 1228 */ 1229 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 1230 usb_hid_report_path_t *path, int flags, 1231 uint8_t *buffer, size_t size, 1232 int32_t *data, size_t data_size) 1233 { 1234 usb_hid_report_item_t *report_item; 1387 /** Makes the output report buffer for data given in the report structure 1388 * 1389 * @param parser Opaque report parser structure 1390 * @param path Usage path specifing which parts of output will be set 1391 * @param flags Usage path structure comparison flags 1392 * @param buffer Output buffer 1393 * @param size Size of output buffer 1394 * @return Error code 1395 */ 1396 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 1397 uint8_t *buffer, size_t size) 1398 { 1235 1399 link_t *item; 1236 size_t idx=0;1237 int i=0;1238 1400 int32_t value=0; 1239 1401 int offset; 1240 1402 int length; 1241 1403 int32_t tmp_value; 1242 size_t offset_prefix = 0; 1243 1244 if(parser == NULL) { 1404 1405 if(report == NULL) { 1245 1406 return EINVAL; 1246 1407 } 1247 1408 1248 if(parser->use_report_id != 0) { 1249 buffer[0] = path->report_id; 1250 offset_prefix = 8; 1409 if(report->use_report_ids != 0) { 1410 buffer[0] = report_id; 1251 1411 } 1252 1412 1253 1413 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1254 usb_log_debug("OUTPUT DATA[0]: %d, DATA[1]: %d, DATA[2]: %d\n", data[0], data[1], data[2]); 1255 1256 item = parser->output.next; 1257 while(item != &parser->output) { 1258 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1259 1260 for(i=0; i<report_item->count; i++) { 1261 1262 if(idx >= data_size) { 1263 break; 1264 } 1265 1266 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) || 1267 ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 1414 1415 usb_hid_report_description_t *report_des; 1416 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT); 1417 if(report_des == NULL){ 1418 return EINVAL; 1419 } 1420 1421 usb_hid_report_field_t *report_item; 1422 item = report_des->report_items.next; 1423 while(item != &report_des->report_items) { 1424 report_item = list_get_instance(item, usb_hid_report_field_t, link); 1425 1426 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 1268 1427 1269 // // variable item 1270 value = usb_hid_translate_data_reverse(report_item, data[idx++]);1271 offset = report_item->offset + (i * report_item->size) + offset_prefix;1428 // array 1429 value = usb_hid_translate_data_reverse(report_item, report_item->value); 1430 offset = report_item->offset; 1272 1431 length = report_item->size; 1273 1432 } 1274 1433 else { 1275 // bitmap1276 value += usb_hid_translate_data_reverse(report_item, data[idx++]);1277 offset = report_item->offset + offset_prefix;1278 length = report_item->size * report_item->count;1434 // variable item 1435 value = usb_hid_translate_data_reverse(report_item, report_item->value); 1436 offset = report_item->offset; 1437 length = report_item->size; 1279 1438 } 1280 1439 … … 1295 1454 } 1296 1455 else { 1297 // je to ve dvou!! FIXME: melo by to umet delsi jak 2 1298 1299 // konec prvniho -- dolni x bitu 1300 tmp_value = value; 1301 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1302 tmp_value = tmp_value << (offset%8); 1303 1456 int i = 0; 1304 1457 uint8_t mask = 0; 1305 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1306 buffer[offset/8] = (buffer[offset/8] & mask) | tmp_value; 1307 1308 // a ted druhej -- hornich length-x bitu 1309 value = value >> (8 - (offset % 8)); 1310 value = value & ((1 << (length - (8 - (offset % 8)))) - 1); 1458 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 1459 if(i == (offset/8)) { 1460 tmp_value = value; 1461 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1462 tmp_value = tmp_value << (offset%8); 1463 1464 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1465 buffer[i] = (buffer[i] & mask) | tmp_value; 1466 } 1467 else if (i == ((offset + length -1)/8)) { 1468 1469 value = value >> (length - ((offset + length) % 8)); 1470 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 1311 1471 1312 mask = ((1 << (length - (8 - (offset % 8)))) - 1); 1313 buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value; 1314 } 1315 1316 } 1317 1472 mask = (1 << (length - ((offset + length) % 8))) - 1; 1473 buffer[i] = (buffer[i] & mask) | value; 1474 } 1475 else { 1476 buffer[i] = value & (0xFF << i); 1477 } 1478 } 1479 } 1480 1481 1482 // reset value 1483 report_item->value = 0; 1484 1318 1485 item = item->next; 1319 1486 } 1320 1487 1321 1488 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1322 1489 … … 1325 1492 1326 1493 /** 1327 * 1328 * @param item 1329 * @param value 1330 * @return 1331 */ 1332 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)1494 * Translate given data for putting them into the outoput report 1495 * @param item Report item structure 1496 * @param value Value to translate 1497 * @return ranslated value 1498 */ 1499 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 1333 1500 { 1334 1501 int ret=0; … … 1339 1506 } 1340 1507 1508 if((item->physical_minimum == 0) && (item->physical_maximum == 0)){ 1509 item->physical_minimum = item->logical_minimum; 1510 item->physical_maximum = item->logical_maximum; 1511 } 1512 1513 1341 1514 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) { 1342 1515 1343 1516 // variable item 1344 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {1345 item->physical_minimum = item->logical_minimum;1346 item->physical_maximum = item->logical_maximum;1347 }1348 1349 1517 if(item->physical_maximum == item->physical_minimum){ 1350 1518 resolution = 1; … … 1369 1537 } 1370 1538 1371 1372 return ret; 1373 } 1374 1375 1539 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 1540 return USB_HID_INT32_TO_UINT32(ret, item->size); 1541 } 1542 return (int32_t)ret; 1543 } 1544 1545 /** 1546 * Sets report id in usage path structure 1547 * 1548 * @param path Usage path structure 1549 * @param report_id Report id to set 1550 * @return Error code 1551 */ 1376 1552 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id) 1377 1553 { … … 1381 1557 1382 1558 path->report_id = report_id; 1559 return EOK; 1560 } 1561 1562 /** 1563 * 1564 * 1565 * 1566 * 1567 * 1568 */ 1569 int usb_hid_report_output_set_data(usb_hid_report_t *report, 1570 usb_hid_report_path_t *path, int flags, 1571 int *data, size_t data_size) 1572 { 1573 size_t data_idx = 0; 1574 if(report == NULL){ 1575 return EINVAL; 1576 } 1577 1578 usb_hid_report_description_t *report_des; 1579 report_des = usb_hid_report_find_description (report, path->report_id, 1580 USB_HID_REPORT_TYPE_OUTPUT); 1581 if(report_des == NULL){ 1582 return EINVAL; 1583 } 1584 1585 usb_hid_report_field_t *field; 1586 link_t *field_it = report_des->report_items.next; 1587 while(field_it != &report_des->report_items){ 1588 1589 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1590 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 1591 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1592 if(usb_hid_report_compare_usage_path (field->collection_path, path, 1593 flags) == EOK) { 1594 if(data_idx < data_size) { 1595 if((data[data_idx] >= field->physical_minimum) && (data[data_idx] >= field->physical_minimum)) { 1596 field->value = data[data_idx]; 1597 } 1598 else { 1599 return ERANGE; 1600 } 1601 1602 data_idx++; 1603 } 1604 else { 1605 field->value = 0; 1606 } 1607 } 1608 usb_hid_report_remove_last_item (field->collection_path); 1609 } 1610 1611 field_it = field_it->next; 1612 } 1613 1383 1614 return EOK; 1384 1615 } … … 1398 1629 } 1399 1630 1631 1632 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 1633 usb_hid_report_field_t *field, 1634 usb_hid_report_path_t *path, int flags, 1635 usb_hid_report_type_t type) 1636 { 1637 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type); 1638 link_t *field_it; 1639 1640 if(report_des == NULL){ 1641 return NULL; 1642 } 1643 1644 if(field == NULL){ 1645 // vezmu prvni co mathuje podle path!! 1646 field_it = report_des->report_items.next; 1647 } 1648 else { 1649 field_it = field->link.next; 1650 } 1651 1652 while(field_it != &report_des->report_items) { 1653 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1654 1655 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 1656 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1657 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){ 1658 usb_hid_report_remove_last_item (field->collection_path); 1659 return field; 1660 } 1661 usb_hid_report_remove_last_item (field->collection_path); 1662 } 1663 field_it = field_it->next; 1664 } 1665 1666 return NULL; 1667 } 1668 1669 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 1670 { 1671 if(report == NULL){ 1672 return 0; 1673 } 1674 1675 usb_hid_report_description_t *report_des; 1676 link_t *report_it; 1677 1678 if(report_id == 0) { 1679 report_it = usb_hid_report_find_description (report, report_id, type)->link.next; 1680 } 1681 else { 1682 report_it = report->reports.next; 1683 } 1684 1685 while(report_it != &report->reports) { 1686 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 1687 if(report_des->type == type){ 1688 return report_des->report_id; 1689 } 1690 } 1691 1692 return 0; 1693 } 1694 1695 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item) 1696 { 1697 if(report_item == NULL) { 1698 return; 1699 } 1700 1701 report_item->usages_count = 0; 1702 memset(report_item->usages, 0, USB_HID_MAX_USAGES); 1703 1704 report_item->extended_usage_page = 0; 1705 report_item->usage_minimum = 0; 1706 report_item->usage_maximum = 0; 1707 report_item->designator_index = 0; 1708 report_item->designator_minimum = 0; 1709 report_item->designator_maximum = 0; 1710 report_item->string_index = 0; 1711 report_item->string_minimum = 0; 1712 report_item->string_maximum = 0; 1713 1714 return; 1715 } 1400 1716 /** 1401 1717 * @} -
uspace/lib/usb/src/hidreport.c
r380e0364 re1dbcbc 109 109 110 110 if (*d != sizeof(usb_standard_hid_descriptor_t)) { 111 usb_log_error("HID descriptor has s wrong size (%u, expected %u"111 usb_log_error("HID descriptor has wrong size (%u, expected %zu" 112 112 ")\n", *d, sizeof(usb_standard_hid_descriptor_t)); 113 113 return EINVAL; … … 119 119 uint16_t length = hid_desc->report_desc_info.length; 120 120 size_t actual_size = 0; 121 122 /*123 * Start session for the control transfer.124 */125 int sess_rc = usb_pipe_start_session(&dev->ctrl_pipe);126 if (sess_rc != EOK) {127 usb_log_warning("Failed to start a session: %s.\n",128 str_error(sess_rc));129 return sess_rc;130 }131 121 132 122 /* … … 159 149 free(*report_desc); 160 150 *report_desc = NULL; 161 usb_log_error("Report descriptor has wrong size (% u, expected "151 usb_log_error("Report descriptor has wrong size (%zu, expected " 162 152 "%u)\n", actual_size, length); 163 153 return EINVAL; 164 154 } 165 155 166 /*167 * End session for the control transfer.168 */169 sess_rc = usb_pipe_end_session(&dev->ctrl_pipe);170 if (sess_rc != EOK) {171 usb_log_warning("Failed to end a session: %s.\n",172 str_error(sess_rc));173 free(*report_desc);174 *report_desc = NULL;175 return sess_rc;176 }177 178 156 *size = length; 179 157 … … 186 164 187 165 int usb_hid_process_report_descriptor(usb_device_t *dev, 188 usb_hid_report_ parser_t *parser)166 usb_hid_report_t *report) 189 167 { 190 if (dev == NULL || parser== NULL) {168 if (dev == NULL || report == NULL) { 191 169 usb_log_error("Failed to process Report descriptor: wrong " 192 170 "parameters given.\n"); … … 211 189 assert(report_desc != NULL); 212 190 213 rc = usb_hid_parse_report_descriptor( parser, report_desc, report_size);191 rc = usb_hid_parse_report_descriptor(report, report_desc, report_size); 214 192 if (rc != EOK) { 215 193 usb_log_error("Problem parsing Report descriptor: %s.\n", … … 219 197 } 220 198 221 usb_hid_descriptor_print( parser);199 usb_hid_descriptor_print(report); 222 200 free(report_desc); 223 201 -
uspace/lib/usb/src/hidreq.c
r380e0364 re1dbcbc 56 56 * @retval EOK if successful. 57 57 * @retval EINVAL if no HID device is given. 58 * @return Other value inherited from one of functions 59 * usb_pipe_start_session(), usb_pipe_end_session(), 60 * usb_control_request_set(). 58 * @return Other value inherited from function usb_control_request_set(). 61 59 */ 62 60 int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no, … … 79 77 */ 80 78 81 int rc, sess_rc; 82 83 sess_rc = usb_pipe_start_session(ctrl_pipe); 84 if (sess_rc != EOK) { 85 usb_log_warning("Failed to start a session: %s.\n", 86 str_error(sess_rc)); 87 return sess_rc; 88 } 79 int rc; 89 80 90 81 uint16_t value = 0; … … 97 88 USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size); 98 89 99 sess_rc = usb_pipe_end_session(ctrl_pipe); 100 101 if (rc != EOK) { 102 usb_log_warning("Error sending output report to the keyboard: " 103 "%s.\n", str_error(rc)); 104 return rc; 105 } 106 107 if (sess_rc != EOK) { 108 usb_log_warning("Error closing session: %s.\n", 109 str_error(sess_rc)); 110 return sess_rc; 90 if (rc != EOK) { 91 usb_log_warning("Error sending output report to the keyboard: " 92 "%s.\n", str_error(rc)); 93 return rc; 111 94 } 112 95 … … 123 106 * @retval EOK if successful. 124 107 * @retval EINVAL if no HID device is given. 125 * @return Other value inherited from one of functions 126 * usb_pipe_start_session(), usb_pipe_end_session(), 127 * usb_control_request_set(). 108 * @return Other value inherited from function usb_control_request_set(). 128 109 */ 129 110 int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, … … 146 127 */ 147 128 148 int rc, sess_rc; 149 150 sess_rc = usb_pipe_start_session(ctrl_pipe); 151 if (sess_rc != EOK) { 152 usb_log_warning("Failed to start a session: %s.\n", 153 str_error(sess_rc)); 154 return sess_rc; 155 } 129 int rc; 156 130 157 131 usb_log_debug("Sending Set_Protocol request to the device (" … … 162 136 USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0); 163 137 164 sess_rc = usb_pipe_end_session(ctrl_pipe); 165 166 if (rc != EOK) { 167 usb_log_warning("Error sending output report to the keyboard: " 168 "%s.\n", str_error(rc)); 169 return rc; 170 } 171 172 if (sess_rc != EOK) { 173 usb_log_warning("Error closing session: %s.\n", 174 str_error(sess_rc)); 175 return sess_rc; 138 if (rc != EOK) { 139 usb_log_warning("Error sending output report to the keyboard: " 140 "%s.\n", str_error(rc)); 141 return rc; 176 142 } 177 143 … … 189 155 * @retval EOK if successful. 190 156 * @retval EINVAL if no HID device is given. 191 * @return Other value inherited from one of functions 192 * usb_pipe_start_session(), usb_pipe_end_session(), 193 * usb_control_request_set(). 157 * @return Other value inherited from function usb_control_request_set(). 194 158 */ 195 159 int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration) … … 211 175 */ 212 176 213 int rc, sess_rc; 214 215 sess_rc = usb_pipe_start_session(ctrl_pipe); 216 if (sess_rc != EOK) { 217 usb_log_warning("Failed to start a session: %s.\n", 218 str_error(sess_rc)); 219 return sess_rc; 220 } 177 int rc; 221 178 222 179 usb_log_debug("Sending Set_Idle request to the device (" … … 229 186 USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0); 230 187 231 sess_rc = usb_pipe_end_session(ctrl_pipe); 232 233 if (rc != EOK) { 234 usb_log_warning("Error sending output report to the keyboard: " 235 "%s.\n", str_error(rc)); 236 return rc; 237 } 238 239 if (sess_rc != EOK) { 240 usb_log_warning("Error closing session: %s.\n", 241 str_error(sess_rc)); 242 return sess_rc; 188 if (rc != EOK) { 189 usb_log_warning("Error sending output report to the keyboard: " 190 "%s.\n", str_error(rc)); 191 return rc; 243 192 } 244 193 … … 259 208 * @retval EOK if successful. 260 209 * @retval EINVAL if no HID device is given. 261 * @return Other value inherited from one of functions 262 * usb_pipe_start_session(), usb_pipe_end_session(), 263 * usb_control_request_set(). 210 * @return Other value inherited from function usb_control_request_set(). 264 211 */ 265 212 int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, … … 283 230 */ 284 231 285 int rc, sess_rc; 286 287 sess_rc = usb_pipe_start_session(ctrl_pipe); 288 if (sess_rc != EOK) { 289 usb_log_warning("Failed to start a session: %s.\n", 290 str_error(sess_rc)); 291 return sess_rc; 292 } 232 int rc; 293 233 294 234 uint16_t value = 0; … … 302 242 actual_size); 303 243 304 sess_rc = usb_pipe_end_session(ctrl_pipe); 305 306 if (rc != EOK) { 307 usb_log_warning("Error sending output report to the keyboard: " 308 "%s.\n", str_error(rc)); 309 return rc; 310 } 311 312 if (sess_rc != EOK) { 313 usb_log_warning("Error closing session: %s.\n", 314 str_error(sess_rc)); 315 return sess_rc; 244 if (rc != EOK) { 245 usb_log_warning("Error sending output report to the keyboard: " 246 "%s.\n", str_error(rc)); 247 return rc; 316 248 } 317 249 … … 328 260 * @retval EOK if successful. 329 261 * @retval EINVAL if no HID device is given. 330 * @return Other value inherited from one of functions 331 * usb_pipe_start_session(), usb_pipe_end_session(), 332 * usb_control_request_set(). 262 * @return Other value inherited from function usb_control_request_set(). 333 263 */ 334 264 int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, … … 351 281 */ 352 282 353 int rc, sess_rc; 354 355 sess_rc = usb_pipe_start_session(ctrl_pipe); 356 if (sess_rc != EOK) { 357 usb_log_warning("Failed to start a session: %s.\n", 358 str_error(sess_rc)); 359 return sess_rc; 360 } 283 int rc; 361 284 362 285 usb_log_debug("Sending Get_Protocol request to the device (" … … 370 293 USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size); 371 294 372 sess_rc = usb_pipe_end_session(ctrl_pipe); 373 374 if (rc != EOK) { 375 usb_log_warning("Error sending output report to the keyboard: " 376 "%s.\n", str_error(rc)); 377 return rc; 378 } 379 380 if (sess_rc != EOK) { 381 usb_log_warning("Error closing session: %s.\n", 382 str_error(sess_rc)); 383 return sess_rc; 295 if (rc != EOK) { 296 usb_log_warning("Error sending output report to the keyboard: " 297 "%s.\n", str_error(rc)); 298 return rc; 384 299 } 385 300 … … 427 342 */ 428 343 429 int rc, sess_rc; 430 431 sess_rc = usb_pipe_start_session(ctrl_pipe); 432 if (sess_rc != EOK) { 433 usb_log_warning("Failed to start a session: %s.\n", 434 str_error(sess_rc)); 435 return sess_rc; 436 } 344 int rc; 437 345 438 346 usb_log_debug("Sending Get_Idle request to the device (" … … 448 356 &actual_size); 449 357 450 sess_rc = usb_pipe_end_session(ctrl_pipe); 451 452 if (rc != EOK) { 453 usb_log_warning("Error sending output report to the keyboard: " 454 "%s.\n", str_error(rc)); 455 return rc; 456 } 457 458 if (sess_rc != EOK) { 459 usb_log_warning("Error closing session: %s.\n", 460 str_error(sess_rc)); 461 return sess_rc; 358 if (rc != EOK) { 359 usb_log_warning("Error sending output report to the keyboard: " 360 "%s.\n", str_error(rc)); 361 return rc; 462 362 } 463 363 -
uspace/lib/usb/src/host/batch.c
r380e0364 re1dbcbc 39 39 #include <usb/host/batch.h> 40 40 41 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance); 42 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance); 43 41 44 void usb_transfer_batch_init( 42 45 usb_transfer_batch_t *instance, 43 usb_target_t target, 44 usb_transfer_type_t transfer_type, 45 usb_speed_t speed, 46 size_t max_packet_size, 46 endpoint_t *ep, 47 47 char *buffer, 48 char * transport_buffer,48 char *data_buffer, 49 49 size_t buffer_size, 50 50 char *setup_buffer, … … 54 54 void *arg, 55 55 ddf_fun_t *fun, 56 endpoint_t *ep,57 void *private_data56 void *private_data, 57 void (*private_data_dtor)(void *p_data) 58 58 ) 59 59 { 60 60 assert(instance); 61 61 link_initialize(&instance->link); 62 instance->target = target; 63 instance->transfer_type = transfer_type; 64 instance->speed = speed; 65 instance->direction = ep->direction; 62 instance->ep = ep; 66 63 instance->callback_in = func_in; 67 64 instance->callback_out = func_out; 68 65 instance->arg = arg; 69 66 instance->buffer = buffer; 70 instance-> transport_buffer = transport_buffer;67 instance->data_buffer = data_buffer; 71 68 instance->buffer_size = buffer_size; 72 69 instance->setup_buffer = setup_buffer; 73 70 instance->setup_size = setup_size; 74 instance->max_packet_size = max_packet_size;75 71 instance->fun = fun; 76 72 instance->private_data = private_data; 73 instance->private_data_dtor = private_data_dtor; 77 74 instance->transfered_size = 0; 78 75 instance->next_step = NULL; 79 76 instance->error = EOK; 80 instance->ep = ep;81 77 endpoint_use(instance->ep); 78 } 79 /*----------------------------------------------------------------------------*/ 80 /** Helper function, calls callback and correctly destroys batch structure. 81 * 82 * @param[in] instance Batch structure to use. 83 */ 84 void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance) 85 { 86 assert(instance); 87 usb_transfer_batch_call_in(instance); 88 usb_transfer_batch_dispose(instance); 89 } 90 /*----------------------------------------------------------------------------*/ 91 /** Helper function calls callback and correctly destroys batch structure. 92 * 93 * @param[in] instance Batch structure to use. 94 */ 95 void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance) 96 { 97 assert(instance); 98 usb_transfer_batch_call_out(instance); 99 usb_transfer_batch_dispose(instance); 82 100 } 83 101 /*----------------------------------------------------------------------------*/ … … 105 123 assert(instance); 106 124 assert(instance->callback_in); 125 assert(instance->ep); 107 126 108 127 /* We are data in, we need data */ 109 memcpy(instance->buffer, instance->transport_buffer, 110 instance->buffer_size); 128 memcpy(instance->buffer, instance->data_buffer, instance->buffer_size); 111 129 112 130 usb_log_debug("Batch %p done (T%d.%d, %s %s in, %zuB): %s (%d).\n", 113 instance, 114 instance->target.address, instance->target.endpoint, 115 usb_str_speed(instance->speed), 116 usb_str_transfer_type_short(instance->transfer_type), 117 instance->transfered_size, 118 str_error(instance->error), instance->error); 131 instance, instance->ep->address, instance->ep->endpoint, 132 usb_str_speed(instance->ep->speed), 133 usb_str_transfer_type_short(instance->ep->transfer_type), 134 instance->transfered_size, str_error(instance->error), instance->error); 119 135 120 136 instance->callback_in(instance->fun, instance->error, … … 132 148 133 149 usb_log_debug("Batch %p done (T%d.%d, %s %s out): %s (%d).\n", 134 instance, 135 instance->target.address, instance->target.endpoint, 136 usb_str_speed(instance->speed), 137 usb_str_transfer_type_short(instance->transfer_type), 150 instance, instance->ep->address, instance->ep->endpoint, 151 usb_str_speed(instance->ep->speed), 152 usb_str_transfer_type_short(instance->ep->transfer_type), 138 153 str_error(instance->error), instance->error); 139 154 … … 141 156 instance->error, instance->arg); 142 157 } 158 /*----------------------------------------------------------------------------*/ 159 /** Correctly dispose all used data structures. 160 * 161 * @param[in] instance Batch structure to use. 162 */ 163 void usb_transfer_batch_dispose(usb_transfer_batch_t *instance) 164 { 165 assert(instance); 166 usb_log_debug("Batch(%p) disposing.\n", instance); 167 if (instance->private_data) { 168 assert(instance->private_data_dtor); 169 instance->private_data_dtor(instance->private_data); 170 } 171 free(instance); 172 } 143 173 /** 144 174 * @} -
uspace/lib/usb/src/host/device_keeper.c
r380e0364 re1dbcbc 48 48 { 49 49 assert(instance); 50 fibril_mutex_initialize(&instance->guard);51 fibril_condvar_initialize(&instance->change);52 instance->last_address = 0;53 50 unsigned i = 0; 54 51 for (; i < USB_ADDRESS_COUNT; ++i) { … … 60 57 // (it is needed to allow smooth registration at default address) 61 58 instance->devices[0].occupied = true; 59 instance->last_address = 0; 60 fibril_mutex_initialize(&instance->guard); 62 61 } 63 /*----------------------------------------------------------------------------*/64 /** Attempt to obtain address 0, blocks.65 *66 * @param[in] instance Device keeper structure to use.67 * @param[in] speed Speed of the device requesting default address.68 */69 void usb_device_keeper_reserve_default_address(70 usb_device_keeper_t *instance, usb_speed_t speed)71 {72 assert(instance);73 fibril_mutex_lock(&instance->guard);74 while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {75 fibril_condvar_wait(&instance->change, &instance->guard);76 }77 instance->devices[USB_ADDRESS_DEFAULT].occupied = true;78 instance->devices[USB_ADDRESS_DEFAULT].speed = speed;79 fibril_mutex_unlock(&instance->guard);80 }81 /*----------------------------------------------------------------------------*/82 /** Attempt to obtain address 0, blocks.83 *84 * @param[in] instance Device keeper structure to use.85 * @param[in] speed Speed of the device requesting default address.86 */87 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance)88 {89 assert(instance);90 fibril_mutex_lock(&instance->guard);91 instance->devices[USB_ADDRESS_DEFAULT].occupied = false;92 fibril_mutex_unlock(&instance->guard);93 fibril_condvar_signal(&instance->change);94 }95 /*----------------------------------------------------------------------------*/96 62 /*----------------------------------------------------------------------------*/ 97 63 /** Get a free USB address … … 120 86 assert(new_address != USB_ADDRESS_DEFAULT); 121 87 assert(instance->devices[new_address].occupied == false); 88 122 89 instance->devices[new_address].occupied = true; 123 90 instance->devices[new_address].speed = speed; 124 91 instance->last_address = new_address; 92 125 93 fibril_mutex_unlock(&instance->guard); 126 94 return new_address; … … 138 106 assert(instance); 139 107 fibril_mutex_lock(&instance->guard); 108 140 109 assert(address > 0); 141 110 assert(address <= USB11_ADDRESS_MAX); 142 111 assert(instance->devices[address].occupied); 112 143 113 instance->devices[address].handle = handle; 144 114 fibril_mutex_unlock(&instance->guard); … … 159 129 fibril_mutex_lock(&instance->guard); 160 130 assert(instance->devices[address].occupied); 131 161 132 instance->devices[address].occupied = false; 162 133 fibril_mutex_unlock(&instance->guard); … … 177 148 while (address <= USB11_ADDRESS_MAX) { 178 149 if (instance->devices[address].handle == handle) { 150 assert(instance->devices[address].occupied); 179 151 fibril_mutex_unlock(&instance->guard); 180 152 return address; … … 198 170 assert(address >= 0); 199 171 assert(address <= USB11_ADDRESS_MAX); 172 200 173 return instance->devices[address].speed; 201 174 } -
uspace/lib/usb/src/host/endpoint.c
r380e0364 re1dbcbc 53 53 fibril_mutex_initialize(&instance->guard); 54 54 fibril_condvar_initialize(&instance->avail); 55 endpoint_clear_hc_data(instance); 55 56 return EOK; 56 57 } … … 61 62 assert(!instance->active); 62 63 free(instance); 64 } 65 /*----------------------------------------------------------------------------*/ 66 void endpoint_set_hc_data(endpoint_t *instance, 67 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 68 { 69 assert(instance); 70 instance->hc_data.data = data; 71 instance->hc_data.toggle_get = toggle_get; 72 instance->hc_data.toggle_set = toggle_set; 73 } 74 /*----------------------------------------------------------------------------*/ 75 void endpoint_clear_hc_data(endpoint_t *instance) 76 { 77 assert(instance); 78 instance->hc_data.data = NULL; 79 instance->hc_data.toggle_get = NULL; 80 instance->hc_data.toggle_set = NULL; 63 81 } 64 82 /*----------------------------------------------------------------------------*/ … … 85 103 { 86 104 assert(instance); 105 if (instance->hc_data.toggle_get) 106 instance->toggle = 107 instance->hc_data.toggle_get(instance->hc_data.data); 87 108 return (int)instance->toggle; 88 109 } … … 92 113 assert(instance); 93 114 assert(toggle == 0 || toggle == 1); 115 if (instance->hc_data.toggle_set) 116 instance->hc_data.toggle_set(instance->hc_data.data, toggle); 94 117 instance->toggle = toggle; 95 118 } … … 100 123 if (instance->address == target.address && 101 124 (instance->endpoint == target.endpoint || target.endpoint == 0)) 102 instance->toggle = 0;125 endpoint_toggle_set(instance, 0); 103 126 } 104 127 /** -
uspace/lib/usb/src/host/usb_endpoint_manager.c
r380e0364 re1dbcbc 211 211 212 212 node_t *node = hash_table_get_instance(item, node_t, link); 213 if (node->ep->active) 214 return EBUSY; 215 213 216 instance->free_bw += node->bw; 214 217 hash_table_remove(&instance->ep_table, key, MAX_KEYS); -
uspace/lib/usb/src/pipepriv.c
r380e0364 re1dbcbc 77 77 * 78 78 * @param pipe The USB pipe. 79 * @param hide_failure Whether to hide failure when adding reference 80 * (use soft refcount). 79 81 * @return Error code. 80 82 * @retval EOK Currently always. 81 83 */ 82 int pipe_add_ref(usb_pipe_t *pipe )84 int pipe_add_ref(usb_pipe_t *pipe, bool hide_failure) 83 85 { 84 another_try:85 86 pipe_acquire(pipe); 86 87 … … 89 90 int phone = devman_device_connect(pipe->wire->hc_handle, 0); 90 91 if (phone < 0) { 91 // TODO: treat some error as non-recoverable 92 // and return error from here 92 if (hide_failure) { 93 pipe->refcount_soft++; 94 phone = EOK; 95 } 93 96 pipe_release(pipe); 94 goto another_try;97 return phone; 95 98 } 96 99 /* … … 114 117 { 115 118 pipe_acquire(pipe); 119 if (pipe->refcount_soft > 0) { 120 pipe->refcount_soft--; 121 pipe_release(pipe); 122 return; 123 } 116 124 assert(pipe->refcount > 0); 117 125 pipe->refcount--; -
uspace/lib/usb/src/pipepriv.h
r380e0364 re1dbcbc 37 37 38 38 #include <usb/pipes.h> 39 #include <bool.h> 39 40 40 41 void pipe_acquire(usb_pipe_t *); … … 44 45 void pipe_end_transaction(usb_pipe_t *); 45 46 46 int pipe_add_ref(usb_pipe_t * );47 int pipe_add_ref(usb_pipe_t *, bool); 47 48 void pipe_drop_ref(usb_pipe_t *); 48 49 -
uspace/lib/usb/src/pipes.c
r380e0364 re1dbcbc 229 229 } 230 230 231 232 /** Start a session on the endpoint pipe.233 *234 * A session is something inside what any communication occurs.235 * It is expected that sessions would be started right before the transfer236 * and ended - see usb_pipe_end_session() - after the last237 * transfer.238 * The reason for this is that session actually opens some communication239 * channel to the host controller (or to the physical hardware if you240 * wish) and thus it involves acquiring kernel resources.241 * Since they are limited, sessions shall not be longer than strictly242 * necessary.243 *244 * @deprecated245 * Obsoleted with introduction of usb_pipe_start_long_transfer246 *247 * @param pipe Endpoint pipe to start the session on.248 * @return Error code.249 */250 int usb_pipe_start_session(usb_pipe_t *pipe)251 {252 usb_log_warning("usb_pipe_start_session() was deprecated.\n");253 return EOK;254 }255 256 257 /** Ends a session on the endpoint pipe.258 *259 * @deprecated260 * Obsoleted with introduction of usb_pipe_end_long_transfer261 *262 * @see usb_pipe_start_session263 *264 * @param pipe Endpoint pipe to end the session on.265 * @return Error code.266 */267 int usb_pipe_end_session(usb_pipe_t *pipe)268 {269 usb_log_warning("usb_pipe_end_session() was deprecated.\n");270 return EOK;271 }272 273 /** Tell whether a session is started (open) on the endpoint pipe.274 *275 * The expected usage of this function is in assertions for some276 * nested functions.277 *278 * @param pipe Endpoint pipe in question.279 * @return Whether @p pipe has opened a session.280 */281 bool usb_pipe_is_session_started(usb_pipe_t *pipe)282 {283 pipe_acquire(pipe);284 bool started = pipe->refcount > 0;285 pipe_release(pipe);286 return started;287 }288 289 231 /** Prepare pipe for a long transfer. 290 232 * … … 297 239 * @return Error code. 298 240 */ 299 intusb_pipe_start_long_transfer(usb_pipe_t *pipe)300 { 301 return pipe_add_ref(pipe);241 void usb_pipe_start_long_transfer(usb_pipe_t *pipe) 242 { 243 (void) pipe_add_ref(pipe, true); 302 244 } 303 245 -
uspace/lib/usb/src/pipesinit.c
r380e0364 re1dbcbc 365 365 pipe->direction = direction; 366 366 pipe->refcount = 0; 367 pipe->refcount_soft = 0; 368 pipe->auto_reset_halt = false; 367 369 368 370 return EOK; … … 385 387 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 386 388 USB_DIRECTION_BOTH); 389 390 pipe->auto_reset_halt = true; 387 391 388 392 return rc; … … 416 420 int rc; 417 421 418 rc = usb_pipe_start_long_transfer(pipe); 419 if (rc != EOK) { 420 return rc; 421 } 422 422 usb_pipe_start_long_transfer(pipe); 423 423 424 424 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; -
uspace/lib/usb/src/pipesio.c
r380e0364 re1dbcbc 49 49 #include <assert.h> 50 50 #include <usbhc_iface.h> 51 #include <usb/request.h> 51 52 #include "pipepriv.h" 52 53 … … 172 173 173 174 int rc; 174 rc = pipe_add_ref(pipe );175 rc = pipe_add_ref(pipe, false); 175 176 if (rc != EOK) { 176 177 return rc; … … 295 296 int rc; 296 297 297 rc = pipe_add_ref(pipe );298 rc = pipe_add_ref(pipe, false); 298 299 if (rc != EOK) { 299 300 return rc; … … 305 306 306 307 return rc; 308 } 309 310 /** Try to clear endpoint halt of default control pipe. 311 * 312 * @param pipe Pipe for control endpoint zero. 313 */ 314 static void clear_self_endpoint_halt(usb_pipe_t *pipe) 315 { 316 assert(pipe != NULL); 317 318 if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) { 319 return; 320 } 321 322 323 /* Prevent indefinite recursion. */ 324 pipe->auto_reset_halt = false; 325 usb_request_clear_endpoint_halt(pipe, 0); 326 pipe->auto_reset_halt = true; 307 327 } 308 328 … … 427 447 int rc; 428 448 429 rc = pipe_add_ref(pipe );449 rc = pipe_add_ref(pipe, false); 430 450 if (rc != EOK) { 431 451 return rc; … … 436 456 setup_buffer, setup_buffer_size, 437 457 data_buffer, data_buffer_size, &act_size); 458 459 if (rc == ESTALL) { 460 clear_self_endpoint_halt(pipe); 461 } 438 462 439 463 pipe_drop_ref(pipe); … … 555 579 int rc; 556 580 557 rc = pipe_add_ref(pipe );581 rc = pipe_add_ref(pipe, false); 558 582 if (rc != EOK) { 559 583 return rc; … … 563 587 setup_buffer, setup_buffer_size, data_buffer, data_buffer_size); 564 588 589 if (rc == ESTALL) { 590 clear_self_endpoint_halt(pipe); 591 } 592 565 593 pipe_drop_ref(pipe); 566 594 -
uspace/lib/usbvirt/Makefile
r380e0364 re1dbcbc 1 1 # 2 # Copyright (c) 201 0Vojtech Horky2 # Copyright (c) 2011 Vojtech Horky 3 3 # All rights reserved. 4 4 # … … 33 33 34 34 SOURCES = \ 35 src/callback.c \ 36 src/ctrlpipe.c \ 37 src/debug.c \ 38 src/main.c \ 35 src/ipc.c \ 36 src/ctrltransfer.c \ 39 37 src/stdreq.c \ 40 src/trans action.c38 src/transfer.c 41 39 42 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbvirt/include/usbvirt/device.h
r380e0364 re1dbcbc 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 38 38 #include <usb/usb.h> 39 39 #include <usb/request.h> 40 #include <usb/descriptor.h>41 40 42 /** Request type of a control transfer. */ 43 typedef enum { 44 /** Standard USB request. */ 45 USBVIRT_REQUEST_TYPE_STANDARD = 0, 46 /** Standard class USB request. */ 47 USBVIRT_REQUEST_TYPE_CLASS = 1 48 } usbvirt_request_type_t; 49 50 /** Recipient of control request. */ 51 typedef enum { 52 /** Device is the recipient of the control request. */ 53 USBVIRT_REQUEST_RECIPIENT_DEVICE = 0, 54 /** Interface is the recipient of the control request. */ 55 USBVIRT_REQUEST_RECIPIENT_INTERFACE = 1, 56 /** Endpoint is the recipient of the control request. */ 57 USBVIRT_REQUEST_RECIPIENT_ENDPOINT = 2, 58 /** Other part of the device is the recipient of the control request. */ 59 USBVIRT_REQUEST_RECIPIENT_OTHER = 3 60 } usbvirt_request_recipient_t; 61 62 /** Possible states of virtual USB device. 63 * Notice that these are not 1:1 mappings to those in USB specification. 64 */ 65 typedef enum { 66 /** Default state, device listens at default address. */ 67 USBVIRT_STATE_DEFAULT, 68 /** Device has non-default address assigned. */ 69 USBVIRT_STATE_ADDRESS, 70 /** Device is configured. */ 71 USBVIRT_STATE_CONFIGURED 72 } usbvirt_device_state_t; 41 #define USBVIRT_ENDPOINT_MAX 16 73 42 74 43 typedef struct usbvirt_device usbvirt_device_t; 75 struct usbvirt_control_transfer;76 44 77 typedef int (*usbvirt_on_device_request_t)(usbvirt_device_t *dev, 78 usb_device_request_setup_packet_t *request, 79 uint8_t *data); 45 typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *, usb_endpoint_t, 46 usb_transfer_type_t, void *, size_t); 47 typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *, usb_endpoint_t, 48 usb_transfer_type_t, void *, size_t, size_t *); 49 typedef int (*usbvirt_on_control_t)(usbvirt_device_t *, 50 const usb_device_request_setup_packet_t *, uint8_t *, size_t *); 80 51 81 /** Callback for control request over pipe zero.82 *83 * @param dev Virtual device answering the call.84 * @param request Request setup packet.85 * @param data Data when DATA stage is present.86 * @return Error code.87 */88 typedef int (*usbvirt_control_request_callback_t)(usbvirt_device_t *dev,89 usb_device_request_setup_packet_t *request,90 uint8_t *data);91 92 /** Handler for control transfer on endpoint zero. */93 52 typedef struct { 94 /** Request type bitmap. 95 * Use USBVIRT_MAKE_CONTROL_REQUEST_TYPE for creating the bitmap. 96 */ 97 uint8_t request_type; 98 /** Request code. */ 53 usb_direction_t req_direction; 54 usb_request_recipient_t req_recipient; 55 usb_request_type_t req_type; 99 56 uint8_t request; 100 /** Request name for debugging. */101 57 const char *name; 102 /** Callback for the request. 103 * NULL value here announces end of a list. 104 */ 105 usbvirt_control_request_callback_t callback; 106 } usbvirt_control_transfer_handler_t; 107 108 /** Create control request type bitmap. 109 * 110 * @param direction Transfer direction (use usb_direction_t). 111 * @param type Request type (use usbvirt_request_type_t). 112 * @param recipient Recipient of the request (use usbvirt_request_recipient_t). 113 * @return Request type bitmap. 114 */ 115 #define USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, type, recipient) \ 116 ((((direction) == USB_DIRECTION_IN) ? 1 : 0) << 7) \ 117 | (((type) & 3) << 5) \ 118 | (((recipient) & 31)) 119 120 /** Create last item in an array of control request handlers. */ 121 #define USBVIRT_CONTROL_TRANSFER_HANDLER_LAST { 0, 0, NULL, NULL } 122 123 /** Device operations. */ 124 typedef struct { 125 /** Callbacks for transfers over control pipe zero. */ 126 usbvirt_control_transfer_handler_t *control_transfer_handlers; 127 128 int (*on_control_transfer)(usbvirt_device_t *dev, 129 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); 130 131 /** Callback for all other incoming data. */ 132 int (*on_data)(usbvirt_device_t *dev, 133 usb_endpoint_t endpoint, void *buffer, size_t size); 134 135 /** Callback for host request for data. */ 136 int (*on_data_request)(usbvirt_device_t *dev, 137 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size); 138 139 /** Decides direction of control transfer. */ 140 usb_direction_t (*decide_control_transfer_direction)( 141 usb_endpoint_t endpoint, void *buffer, size_t size); 142 143 /** Callback when device changes its state. 144 * 145 * It is correct that this function is called when both states 146 * are equal (e.g. this function is called during SET_CONFIGURATION 147 * request done on already configured device). 148 * 149 * @warning The value of <code>dev->state</code> before calling 150 * this function is not specified (i.e. can be @p old_state or 151 * @p new_state). 152 */ 153 void (*on_state_change)(usbvirt_device_t *dev, 154 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 155 } usbvirt_device_ops_t; 58 usbvirt_on_control_t callback; 59 } usbvirt_control_request_handler_t; 156 60 157 61 /** Extra configuration data for GET_CONFIGURATION request. */ … … 179 83 */ 180 84 usb_standard_device_descriptor_t *device; 181 85 182 86 /** Configurations. */ 183 87 usbvirt_device_configuration_t *configuration; 184 88 /** Number of configurations. */ 185 89 size_t configuration_count; 186 /** Index of currently selected configuration. */187 uint8_t current_configuration;188 90 } usbvirt_descriptors_t; 189 91 190 /** Information about on-going control transfer. 92 /** Possible states of virtual USB device. 93 * Notice that these are not 1:1 mappings to those in USB specification. 191 94 */ 192 typedef struct usbvirt_control_transfer { 193 /** Transfer direction (read/write control transfer). */ 194 usb_direction_t direction; 195 /** Request data. */ 196 void *request; 197 /** Size of request data. */ 198 size_t request_size; 199 /** Payload. */ 200 void *data; 201 /** Size of payload. */ 202 size_t data_size; 203 } usbvirt_control_transfer_t; 95 typedef enum { 96 /** Default state, device listens at default address. */ 97 USBVIRT_STATE_DEFAULT, 98 /** Device has non-default address assigned. */ 99 USBVIRT_STATE_ADDRESS, 100 /** Device is configured. */ 101 USBVIRT_STATE_CONFIGURED 102 } usbvirt_device_state_t; 204 103 205 typedef enum { 206 USBVIRT_DEBUGTAG_BASE = 1, 207 USBVIRT_DEBUGTAG_TRANSACTION = 2, 208 USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO = 4, 209 USBVIRT_DEBUGTAG_ALL = 255 210 } usbvirt_debug_tags_t; 104 typedef struct { 105 usbvirt_on_data_to_device_t data_out[USBVIRT_ENDPOINT_MAX]; 106 usbvirt_on_data_from_device_t data_in[USBVIRT_ENDPOINT_MAX]; 107 usbvirt_control_request_handler_t *control; 108 void (*state_changed)(usbvirt_device_t *dev, 109 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 110 } usbvirt_device_ops_t; 211 111 212 /** Virtual USB device. */213 112 struct usbvirt_device { 214 /** Callback device operations. */ 113 const char *name; 114 void *device_data; 215 115 usbvirt_device_ops_t *ops; 216 217 /** Custom device data. */ 218 void *device_data; 116 usbvirt_descriptors_t *descriptors; 117 usb_address_t address; 118 usbvirt_device_state_t state; 119 }; 219 120 220 /** Reply onto control transfer. 221 */ 222 int (*control_transfer_reply)(usbvirt_device_t *dev, 223 usb_endpoint_t endpoint, void *buffer, size_t size); 224 225 /** Device name. 226 * Used in debug prints and sent to virtual host controller. 227 */ 228 const char *name; 229 230 /** Standard descriptors. */ 231 usbvirt_descriptors_t *descriptors; 232 233 /** Current device state. */ 234 usbvirt_device_state_t state; 235 236 /** Device address. */ 237 usb_address_t address; 238 /** New device address. 239 * This field is used during SET_ADDRESS request. 240 * On all other occasions, it holds invalid address (e.g. -1). 241 */ 242 usb_address_t new_address; 243 244 /** Process OUT transaction. */ 245 int (*transaction_out)(usbvirt_device_t *dev, 246 usb_endpoint_t endpoint, void *buffer, size_t size); 247 /** Process SETUP transaction. */ 248 int (*transaction_setup)(usbvirt_device_t *dev, 249 usb_endpoint_t endpoint, void *buffer, size_t size); 250 /** Process IN transaction. */ 251 int (*transaction_in)(usbvirt_device_t *dev, 252 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size); 253 254 /** State information on control-transfer endpoints. */ 255 usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX]; 256 257 /* User debugging. */ 258 259 /** Debug print. */ 260 void (*debug)(usbvirt_device_t *dev, int level, uint8_t tag, 261 const char *format, ...); 262 263 /** Current debug level. */ 264 int debug_level; 265 266 /** Bitmap of currently enabled tags. */ 267 uint8_t debug_enabled_tags; 268 269 /* Library debugging. */ 270 271 /** Debug print. */ 272 void (*lib_debug)(usbvirt_device_t *dev, int level, uint8_t tag, 273 const char *format, ...); 274 275 /** Current debug level. */ 276 int lib_debug_level; 277 278 /** Bitmap of currently enabled tags. */ 279 uint8_t lib_debug_enabled_tags; 280 }; 121 int usbvirt_device_plug(usbvirt_device_t *, const char *); 122 123 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *, 124 uint8_t *, size_t *, void *, size_t); 125 126 int usbvirt_control_write(usbvirt_device_t *, void *, size_t, void *, size_t); 127 int usbvirt_control_read(usbvirt_device_t *, void *, size_t, void *, size_t, size_t *); 128 int usbvirt_data_out(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t, 129 void *, size_t); 130 int usbvirt_data_in(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t, 131 void *, size_t, size_t *); 132 281 133 282 134 #endif -
uspace/lib/usbvirt/include/usbvirt/ipc.h
r380e0364 re1dbcbc 33 33 * @brief Virtual USB device. 34 34 */ 35 #ifndef LIBUSBVIRT_ HUB_H_36 #define LIBUSBVIRT_ HUB_H_35 #ifndef LIBUSBVIRT_IPC_H_ 36 #define LIBUSBVIRT_IPC_H_ 37 37 38 #include "device.h" 38 #include <ipc/common.h> 39 #include <usb/usb.h> 40 #include <bool.h> 39 41 40 /** USB transaction type.41 * This types does not correspond directly to types in USB specification,42 * as actually DATA transactions are marked with these types to identify43 * their direction (and tag).44 */45 42 typedef enum { 46 USBVIRT_TRANSACTION_SETUP, 47 USBVIRT_TRANSACTION_IN, 48 USBVIRT_TRANSACTION_OUT 49 } usbvirt_transaction_type_t; 43 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD + 80, 44 IPC_M_USBVIRT_CONTROL_READ, 45 IPC_M_USBVIRT_CONTROL_WRITE, 46 IPC_M_USBVIRT_INTERRUPT_IN, 47 IPC_M_USBVIRT_INTERRUPT_OUT 48 } usbvirt_ipc_t; 50 49 51 const char *usbvirt_str_transaction_type(usbvirt_transaction_type_t type); 50 int usbvirt_ipc_send_control_read(int, usb_endpoint_t, void *, size_t, 51 void *, size_t, size_t *); 52 int usbvirt_ipc_send_control_write(int, usb_endpoint_t, void *, size_t, 53 void *, size_t); 54 int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t, 55 void *, size_t, size_t *); 56 int usbvirt_ipc_send_data_out(int, usb_endpoint_t, usb_transfer_type_t, 57 void *, size_t); 52 58 53 /** Telephony methods of virtual devices. */ 54 typedef enum { 55 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD, 56 IPC_M_USBVIRT_TRANSACTION_SETUP, 57 IPC_M_USBVIRT_TRANSACTION_OUT, 58 IPC_M_USBVIRT_TRANSACTION_IN, 59 } usbvirt_device_method_t; 60 61 int usbvirt_connect(usbvirt_device_t *); 62 int usbvirt_connect_local(usbvirt_device_t *); 63 int usbvirt_disconnect(usbvirt_device_t *dev); 59 bool usbvirt_is_usbvirt_method(sysarg_t); 60 bool usbvirt_ipc_handle_call(usbvirt_device_t *, ipc_callid_t, ipc_call_t *); 64 61 65 62 #endif -
uspace/lib/usbvirt/src/private.h
r380e0364 re1dbcbc 1 /* 2 * Copyright (c) 2010 Vojtech Horky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 1 #include <usbvirt/device.h> 28 2 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * @brief Virtual USB private header. 34 */ 35 #ifndef LIBUSBVIRT_PRIVATE_H_ 36 #define LIBUSBVIRT_PRIVATE_H_ 3 int process_control_transfer(usbvirt_device_t *, 4 usbvirt_control_request_handler_t *, 5 usb_device_request_setup_packet_t *, 6 uint8_t *, size_t *); 37 7 38 #include <usbvirt/device.h> 39 #include <usbvirt/hub.h> 40 #include <assert.h> 41 42 43 #define DEVICE_HAS_OP(dev, op) \ 44 ( \ 45 ( ((dev)->ops) != NULL ) \ 46 && \ 47 ( ((dev)->ops->op) != NULL ) \ 48 ) 49 50 int usbvirt_data_to_host(struct usbvirt_device *dev, 51 usb_endpoint_t endpoint, void *buffer, size_t size); 52 53 int handle_incoming_data(struct usbvirt_device *dev, 54 usb_endpoint_t endpoint, void *buffer, size_t size); 55 56 int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer); 57 58 int handle_std_request(usbvirt_device_t *device, usb_device_request_setup_packet_t *request, uint8_t *data); 59 60 void device_callback_connection(usbvirt_device_t *device, ipc_callid_t iid, ipc_call_t *icall); 61 62 int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint, 63 void *buffer, size_t size); 64 int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint, 65 void *buffer, size_t size); 66 int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint, 67 void *buffer, size_t size, size_t *data_size); 68 69 70 void user_debug(usbvirt_device_t *device, int level, uint8_t tag, 71 const char *format, ...); 72 void lib_debug(usbvirt_device_t *device, int level, uint8_t tag, 73 const char *format, ...); 74 75 static inline const char *str_device_state(usbvirt_device_state_t state) 76 { 77 switch (state) { 78 case USBVIRT_STATE_DEFAULT: 79 return "default"; 80 case USBVIRT_STATE_ADDRESS: 81 return "address"; 82 case USBVIRT_STATE_CONFIGURED: 83 return "configured"; 84 default: 85 return "unknown"; 86 } 87 } 88 89 extern usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[]; 90 91 #endif 92 /** 93 * @} 94 */ 8 extern usbvirt_control_request_handler_t library_handlers[]; -
uspace/lib/usbvirt/src/stdreq.c
r380e0364 re1dbcbc 1 /* 2 * Copyright (c) 2010 Vojtech Horky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 1 #include "private.h" 2 #include <usb/request.h> 3 #include <assert.h> 4 #include <errno.h> 28 5 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * @brief Preprocessing of standard device requests. 34 */ 35 #include <errno.h> 36 #include <stdlib.h> 37 #include <mem.h> 38 #include <usb/request.h> 6 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet, 7 uint8_t *data, size_t *act_size, 8 void *actual_data, size_t actual_data_size) 9 { 10 size_t expected_size = setup_packet->length; 11 if (expected_size < actual_data_size) { 12 actual_data_size = expected_size; 13 } 39 14 40 #include "private.h" 15 memcpy(data, actual_data, actual_data_size); 41 16 42 /* 43 * All sub handlers must return EFORWARD to inform the caller that 44 * they were not able to process the request (yes, it is abuse of 45 * this error code but such error code shall not collide with anything 46 * else in this context). 47 */ 48 17 if (act_size != NULL) { 18 *act_size = actual_data_size; 19 } 20 } 21 49 22 /** GET_DESCRIPTOR handler. */ 50 static int handle_get_descriptor(usbvirt_device_t *device,51 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)23 static int req_get_descriptor(usbvirt_device_t *device, 24 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size) 52 25 { 53 26 uint8_t type = setup_packet->value_high; 54 27 uint8_t index = setup_packet->value_low; 55 28 56 /* 29 /* 57 30 * Standard device descriptor. 58 31 */ 59 32 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) { 60 33 if (device->descriptors && device->descriptors->device) { 61 return device->control_transfer_reply(device, 0,34 usbvirt_control_reply_helper(setup_packet, data, act_size, 62 35 device->descriptors->device, 63 36 device->descriptors->device->length); 37 return EOK; 64 38 } else { 65 39 return EFORWARD; 66 40 } 67 41 } 68 42 69 43 /* 70 44 * Configuration descriptor together with interface, endpoint and … … 85 59 return ENOMEM; 86 60 } 87 61 88 62 uint8_t *ptr = all_data; 89 63 memcpy(ptr, config->descriptor, config->descriptor->length); … … 96 70 ptr += extra->length; 97 71 } 98 99 int rc = device->control_transfer_reply(device, 0,72 73 usbvirt_control_reply_helper(setup_packet, data, act_size, 100 74 all_data, config->descriptor->total_length); 101 75 102 76 free(all_data); 103 104 return rc;77 78 return EOK; 105 79 } 106 80 107 81 return EFORWARD; 108 82 } 109 83 110 /** SET_ADDRESS handler. */ 111 static int handle_set_address(usbvirt_device_t *device, 112 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 84 static int req_set_address(usbvirt_device_t *device, 85 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size) 113 86 { 114 87 uint16_t new_address = setup_packet->value; … … 119 92 return EINVAL; 120 93 } 121 94 122 95 if (new_address > 127) { 123 96 return EINVAL; 124 97 } 125 126 device-> new_address = new_address;127 98 99 device->address = new_address; 100 128 101 return EOK; 129 102 } 130 103 131 /** SET_CONFIGURATION handler. */ 132 static int handle_set_configuration(usbvirt_device_t *device, 133 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 104 static int req_set_configuration(usbvirt_device_t *device, 105 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size) 134 106 { 135 107 uint16_t configuration_value = setup_packet->value; … … 140 112 return EINVAL; 141 113 } 142 114 143 115 /* 144 116 * Configuration value is 1 byte information. … … 147 119 return EINVAL; 148 120 } 149 121 150 122 /* 151 123 * Do nothing when in default state. According to specification, … … 155 127 return EOK; 156 128 } 157 129 130 usbvirt_device_state_t new_state; 158 131 if (configuration_value == 0) { 159 if (DEVICE_HAS_OP(device, on_state_change)) { 160 device->ops->on_state_change(device, device->state, 161 USBVIRT_STATE_ADDRESS); 162 } 163 device->state = USBVIRT_STATE_ADDRESS; 132 new_state = USBVIRT_STATE_ADDRESS; 164 133 } else { 165 /* 166 * TODO: browse provided configurations and verify that 167 * user selected existing configuration. 168 */ 169 if (DEVICE_HAS_OP(device, on_state_change)) { 170 device->ops->on_state_change(device, device->state, 171 USBVIRT_STATE_CONFIGURED); 172 } 173 device->state = USBVIRT_STATE_CONFIGURED; 174 if (device->descriptors) { 175 device->descriptors->current_configuration 176 = configuration_value; 177 } 134 // FIXME: check that this configuration exists 135 new_state = USBVIRT_STATE_CONFIGURED; 178 136 } 179 137 138 if (device->ops && device->ops->state_changed) { 139 device->ops->state_changed(device, device->state, new_state); 140 } 141 device->state = new_state; 142 180 143 return EOK; 181 144 } 182 145 183 184 #define MAKE_BM_REQUEST(direction, recipient) \ 185 USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \ 186 USBVIRT_REQUEST_TYPE_STANDARD, recipient) 187 #define MAKE_BM_REQUEST_DEV(direction) \ 188 MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE) 189 190 usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = { 146 usbvirt_control_request_handler_t library_handlers[] = { 191 147 { 192 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN), 193 .request = USB_DEVREQ_GET_DESCRIPTOR, 194 .name = "GetDescriptor()", 195 .callback = handle_get_descriptor 148 .req_direction = USB_DIRECTION_OUT, 149 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE, 150 .req_type = USB_REQUEST_TYPE_STANDARD, 151 .request = USB_DEVREQ_SET_ADDRESS, 152 .name = "SetAddress", 153 .callback = req_set_address 196 154 }, 197 155 { 198 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 199 .request = USB_DEVREQ_SET_ADDRESS, 200 .name = "SetAddress()", 201 .callback = handle_set_address 156 .req_direction = USB_DIRECTION_IN, 157 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE, 158 .req_type = USB_REQUEST_TYPE_STANDARD, 159 .request = USB_DEVREQ_GET_DESCRIPTOR, 160 .name = "GetDescriptor", 161 .callback = req_get_descriptor 202 162 }, 203 163 { 204 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 164 .req_direction = USB_DIRECTION_OUT, 165 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE, 166 .req_type = USB_REQUEST_TYPE_STANDARD, 205 167 .request = USB_DEVREQ_SET_CONFIGURATION, 206 .name = "SetConfiguration ()",207 .callback = handle_set_configuration168 .name = "SetConfiguration", 169 .callback = req_set_configuration 208 170 }, 209 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 171 172 { .callback = NULL } 210 173 }; 211 174 212 /**213 * @}214 */
Note:
See TracChangeset
for help on using the changeset viewer.
