Changeset 361e61b in mainline for uspace/lib
- Timestamp:
- 2011-03-21T14:23:15Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 55e388a1
- Parents:
- c32688d (diff), 48fe0c9 (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:
-
- 6 added
- 16 edited
- 2 moved
-
block/libblock.c (modified) (2 diffs)
-
c/Makefile (modified) (1 diff)
-
c/generic/l18n/langs.c (added)
-
c/include/l18n/langs.h (modified) (1 diff)
-
drv/generic/remote_usbhc.c (modified) (3 diffs)
-
drv/include/usbhc_iface.h (modified) (2 diffs)
-
usb/Makefile (modified) (2 diffs)
-
usb/include/usb/classes/hub.h (modified) (1 diff)
-
usb/include/usb/devdrv.h (added)
-
usb/include/usb/dp.h (modified) (1 diff)
-
usb/include/usb/host/batch.h (added)
-
usb/include/usb/host/device_keeper.h (moved) (moved from uspace/drv/uhci-hcd/utils/device_keeper.h ) (4 diffs)
-
usb/include/usb/pipes.h (modified) (3 diffs)
-
usb/include/usb/request.h (modified) (2 diffs)
-
usb/src/devdrv.c (added)
-
usb/src/devpoll.c (added)
-
usb/src/dp.c (modified) (1 diff)
-
usb/src/host/batch.c (added)
-
usb/src/host/device_keeper.c (moved) (moved from uspace/drv/uhci-hcd/utils/device_keeper.c ) (19 diffs)
-
usb/src/hub.c (modified) (1 diff)
-
usb/src/pipes.c (modified) (4 diffs)
-
usb/src/pipesinit.c (modified) (2 diffs)
-
usb/src/recognise.c (modified) (4 diffs)
-
usb/src/request.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
rc32688d r361e61b 411 411 l = hash_table_find(&cache->block_hash, &key); 412 412 if (l) { 413 found: 413 414 /* 414 415 * We found the block in the cache. … … 493 494 fibril_mutex_unlock(&b->lock); 494 495 goto retry; 496 } 497 l = hash_table_find(&cache->block_hash, &key); 498 if (l) { 499 /* 500 * Someone else must have already 501 * instantiated the block while we were 502 * not holding the cache lock. 503 * Leave the recycled block on the 504 * freelist and continue as if we 505 * found the block of interest during 506 * the first try. 507 */ 508 fibril_mutex_unlock(&b->lock); 509 goto found; 495 510 } 496 511 -
uspace/lib/c/Makefile
rc32688d r361e61b 65 65 generic/str.c \ 66 66 generic/str_error.c \ 67 generic/l18n/langs.c \ 67 68 generic/fibril.c \ 68 69 generic/fibril_synch.c \ -
uspace/lib/c/include/l18n/langs.h
rc32688d r361e61b 57 57 } l18_win_locales_t; 58 58 59 const char *str_l18_win_locale(l18_win_locales_t); 60 59 61 #endif 60 62 -
uspace/lib/drv/generic/remote_usbhc.c
rc32688d r361e61b 55 55 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 56 56 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 57 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 58 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 57 59 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 58 60 … … 73 75 74 76 remote_usbhc_control_write, 75 remote_usbhc_control_read 77 remote_usbhc_control_read, 78 79 remote_usbhc_register_endpoint, 80 remote_usbhc_unregister_endpoint 76 81 }; 77 82 … … 522 527 523 528 529 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface, 530 ipc_callid_t callid, ipc_call_t *call) 531 { 532 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 533 534 if (!usb_iface->register_endpoint) { 535 async_answer_0(callid, ENOTSUP); 536 return; 537 } 538 539 #define INIT_FROM_HIGH_DATA(type, var, arg_no) \ 540 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256 541 #define INIT_FROM_LOW_DATA(type, var, arg_no) \ 542 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256 543 544 INIT_FROM_HIGH_DATA(usb_address_t, address, 1); 545 INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1); 546 INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2); 547 INIT_FROM_LOW_DATA(usb_direction_t, direction, 2); 548 549 #undef INIT_FROM_HIGH_DATA 550 #undef INIT_FROM_LOW_DATA 551 552 size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call); 553 unsigned int interval = (unsigned int) DEV_IPC_GET_ARG4(*call); 554 555 int rc = usb_iface->register_endpoint(fun, address, endpoint, 556 transfer_type, direction, max_packet_size, interval); 557 558 async_answer_0(callid, rc); 559 } 560 561 562 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface, 563 ipc_callid_t callid, ipc_call_t *call) 564 { 565 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 566 567 if (!usb_iface->unregister_endpoint) { 568 async_answer_0(callid, ENOTSUP); 569 return; 570 } 571 572 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 573 usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call); 574 usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call); 575 576 int rc = usb_iface->unregister_endpoint(fun, 577 address, endpoint, direction); 578 579 async_answer_0(callid, rc); 580 } 581 524 582 525 583 /** -
uspace/lib/drv/include/usbhc_iface.h
rc32688d r361e61b 167 167 IPC_M_USBHC_CONTROL_READ, 168 168 169 /* IPC_M_USB_ */ 169 /** Register endpoint attributes at host controller. 170 * This is used to reserve portion of USB bandwidth. 171 * Parameters: 172 * - USB address + endpoint number (ADDR * 256 + EP) 173 * - transfer type + direction (TYPE * 256 + DIR) 174 * - maximum packet size 175 * - interval (in milliseconds) 176 * Answer: 177 * - EOK - reservation successful 178 * - ELIMIT - not enough bandwidth to satisfy the request 179 */ 180 IPC_M_USBHC_REGISTER_ENDPOINT, 181 182 /** Revert endpoint registration. 183 * Parameters: 184 * - USB address 185 * - endpoint number 186 * - data direction 187 * Answer: 188 * - EOK - endpoint unregistered 189 * - ENOENT - unknown endpoint 190 */ 191 IPC_M_USBHC_UNREGISTER_ENDPOINT 170 192 } usbhc_iface_funcs_t; 171 193 … … 200 222 int (*release_address)(ddf_fun_t *, usb_address_t); 201 223 224 int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t, 225 usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 226 int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t, 227 usb_direction_t); 228 202 229 usbhc_iface_transfer_out_t interrupt_out; 203 230 usbhc_iface_transfer_in_t interrupt_in; -
uspace/lib/usb/Makefile
rc32688d r361e61b 37 37 src/ddfiface.c \ 38 38 src/debug.c \ 39 src/devdrv.c \ 40 src/devpoll.c \ 39 41 src/dp.c \ 40 42 src/dump.c \ … … 47 49 src/request.c \ 48 50 src/usb.c \ 49 src/usbdevice.c 51 src/usbdevice.c \ 52 src/host/device_keeper.c \ 53 src/host/batch.c 50 54 51 55 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usb/include/usb/classes/hub.h
rc32688d r361e61b 60 60 } usb_hub_class_feature_t; 61 61 62 /** Header of standard hub descriptor without the "variadic" part. */ 63 typedef struct { 64 /** Descriptor length. */ 65 uint8_t length; 66 /** Descriptor type (0x29). */ 67 uint8_t descriptor_type; 68 /** Number of downstream ports. */ 69 uint8_t port_count; 70 /** Characteristics bitmask. */ 71 uint16_t characteristics; 72 /** Time from power-on to stabilization of current on the port. */ 73 uint8_t power_good_time; 74 /** Maximum current requirements in mA. */ 75 uint8_t max_current; 76 } __attribute__ ((packed)) usb_hub_descriptor_header_t; 62 77 63 78 /** -
uspace/lib/usb/include/usb/dp.h
rc32688d r361e61b 77 77 usb_dp_parser_data_t *, uint8_t *, uint8_t *); 78 78 79 void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *, 80 void (*)(uint8_t *, size_t, void *), void *); 81 79 82 #endif 80 83 /** -
uspace/lib/usb/include/usb/host/device_keeper.h
rc32688d r361e61b 27 27 */ 28 28 29 /** @addtogroup drvusbuhci29 /** @addtogroup libusb 30 30 * @{ 31 31 */ … … 33 33 * @brief UHCI driver 34 34 */ 35 #ifndef UTILS_DEVICE_KEEPER_H36 #define UTILS_DEVICE_KEEPER_H35 #ifndef LIBUSB_HOST_DEVICE_KEEPER_H 36 #define LIBUSB_HOST_DEVICE_KEEPER_H 37 37 #include <devman.h> 38 38 #include <fibril_synch.h> … … 44 44 usb_speed_t speed; 45 45 bool occupied; 46 uint16_t toggle_status ;46 uint16_t toggle_status[2]; 47 47 devman_handle_t handle; 48 48 }; … … 63 63 64 64 void device_keeper_reset_if_need( 65 device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data); 65 device_keeper_t *instance, usb_target_t target, 66 const unsigned char *setup_data); 66 67 67 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target); 68 int device_keeper_get_toggle( 69 device_keeper_t *instance, usb_target_t target, usb_direction_t direction); 68 70 69 int device_keeper_set_toggle( 70 device_keeper_t *instance, usb_target_t target, bool toggle);71 int device_keeper_set_toggle(device_keeper_t *instance, 72 usb_target_t target, usb_direction_t direction, bool toggle); 71 73 72 74 usb_address_t device_keeper_request( -
uspace/lib/usb/include/usb/pipes.h
rc32688d r361e61b 106 106 const usb_endpoint_description_t *description; 107 107 /** Interface number the endpoint must belong to (-1 for any). */ 108 constint interface_no;108 int interface_no; 109 109 /** Found descriptor fitting the description. */ 110 110 usb_standard_endpoint_descriptor_t *descriptor; … … 123 123 124 124 int usb_device_get_assigned_interface(ddf_dev_t *); 125 usb_address_t usb_device_get_assigned_address(devman_handle_t); 125 126 126 127 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, … … 129 130 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *, 130 131 usb_device_connection_t *); 132 int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *); 131 133 int usb_endpoint_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 132 134 size_t, uint8_t *, size_t, usb_device_connection_t *); 133 135 int usb_endpoint_pipe_register(usb_endpoint_pipe_t *, unsigned int, 136 usb_hc_connection_t *); 137 int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *, usb_hc_connection_t *); 134 138 135 139 int usb_endpoint_pipe_start_session(usb_endpoint_pipe_t *); -
uspace/lib/usb/include/usb/request.h
rc32688d r361e61b 94 94 uint16_t, uint16_t, void *, size_t, size_t *); 95 95 96 int usb_request_get_status(usb_endpoint_pipe_t *, usb_request_recipient_t, 97 uint16_t, uint16_t *); 98 int usb_request_clear_feature(usb_endpoint_pipe_t *, usb_request_type_t, 99 usb_request_recipient_t, uint16_t, uint16_t); 100 int usb_request_set_feature(usb_endpoint_pipe_t *, usb_request_type_t, 101 usb_request_recipient_t, uint16_t, uint16_t); 96 102 int usb_request_set_address(usb_endpoint_pipe_t *, usb_address_t); 97 103 int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t, … … 108 114 int usb_request_get_full_configuration_descriptor_alloc(usb_endpoint_pipe_t *, 109 115 int, void **, size_t *); 116 int usb_request_set_descriptor(usb_endpoint_pipe_t *, usb_request_type_t, 117 usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t); 118 int usb_request_get_configuration(usb_endpoint_pipe_t *, uint8_t *); 110 119 int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t); 120 int usb_request_get_interface(usb_endpoint_pipe_t *, uint8_t, uint8_t *); 121 int usb_request_set_interface(usb_endpoint_pipe_t *, uint8_t, uint8_t); 111 122 112 123 int usb_request_get_supported_languages(usb_endpoint_pipe_t *, -
uspace/lib/usb/src/dp.c
rc32688d r361e61b 258 258 } 259 259 260 /** Browser of the descriptor tree. 261 * 262 * @see usb_dp_walk_simple 263 * 264 * @param parser Descriptor parser. 265 * @param data Data for descriptor parser. 266 * @param root Pointer to current root of the tree. 267 * @param depth Current nesting depth. 268 * @param callback Callback for each found descriptor. 269 * @param arg Custom (user) argument. 270 */ 271 static void usb_dp_browse_simple_internal(usb_dp_parser_t *parser, 272 usb_dp_parser_data_t *data, uint8_t *root, size_t depth, 273 void (*callback)(uint8_t *, size_t, void *), void *arg) 274 { 275 if (root == NULL) { 276 return; 277 } 278 callback(root, depth, arg); 279 uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root); 280 do { 281 usb_dp_browse_simple_internal(parser, data, child, depth + 1, 282 callback, arg); 283 child = usb_dp_get_sibling_descriptor(parser, data, 284 root, child); 285 } while (child != NULL); 286 } 287 288 /** Browse flatten descriptor tree. 289 * 290 * The callback is called with following arguments: pointer to the start 291 * of the descriptor (somewhere inside @p descriptors), depth of the nesting 292 * (starting from 0 for the first descriptor) and the custom argument. 293 * Note that the size of the descriptor is not passed because it can 294 * be read from the first byte of the descriptor. 295 * 296 * @param descriptors Descriptor data. 297 * @param descriptors_size Size of descriptor data (in bytes). 298 * @param descriptor_nesting Possible descriptor nesting. 299 * @param callback Callback for each found descriptor. 300 * @param arg Custom (user) argument. 301 */ 302 void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size, 303 usb_dp_descriptor_nesting_t *descriptor_nesting, 304 void (*callback)(uint8_t *, size_t, void *), void *arg) 305 { 306 if ((descriptors == NULL) || (descriptors_size == 0) 307 || (descriptor_nesting == NULL) || (callback == NULL)) { 308 return; 309 } 310 311 usb_dp_parser_data_t data = { 312 .data = descriptors, 313 .size = descriptors_size, 314 .arg = NULL 315 }; 316 317 usb_dp_parser_t parser = { 318 .nesting = descriptor_nesting 319 }; 320 321 usb_dp_browse_simple_internal(&parser, &data, descriptors, 322 0, callback, arg); 323 } 260 324 261 325 /** @} -
uspace/lib/usb/src/host/device_keeper.c
rc32688d r361e61b 27 27 */ 28 28 29 /** @addtogroup drvusbuhci29 /** @addtogroup libusb 30 30 * @{ 31 31 */ … … 36 36 #include <errno.h> 37 37 #include <usb/debug.h> 38 39 #include "device_keeper.h" 40 41 /*----------------------------------------------------------------------------*/ 42 /** Initializes device keeper structure. 38 #include <usb/host/device_keeper.h> 39 40 /*----------------------------------------------------------------------------*/ 41 /** Initialize device keeper structure. 43 42 * 44 43 * @param[in] instance Memory place to initialize. 44 * 45 * Set all values to false/0. 45 46 */ 46 47 void device_keeper_init(device_keeper_t *instance) … … 54 55 instance->devices[i].occupied = false; 55 56 instance->devices[i].handle = 0; 56 instance->devices[i].toggle_status = 0; 57 } 58 } 59 /*----------------------------------------------------------------------------*/ 60 /** Attempts to obtain address 0, blocks. 57 instance->devices[i].toggle_status[0] = 0; 58 instance->devices[i].toggle_status[1] = 0; 59 } 60 } 61 /*----------------------------------------------------------------------------*/ 62 /** Attempt to obtain address 0, blocks. 61 63 * 62 64 * @param[in] instance Device keeper structure to use. … … 76 78 } 77 79 /*----------------------------------------------------------------------------*/ 78 /** Attempt sto obtain address 0, blocks.80 /** Attempt to obtain address 0, blocks. 79 81 * 80 82 * @param[in] instance Device keeper structure to use. … … 90 92 } 91 93 /*----------------------------------------------------------------------------*/ 92 /** Check s setupdata for signs of toggle reset.94 /** Check setup packet data for signs of toggle reset. 93 95 * 94 96 * @param[in] instance Device keeper structure to use. 95 97 * @param[in] target Device to receive setup packet. 96 98 * @param[in] data Setup packet data. 99 * 100 * Really ugly one. 97 101 */ 98 102 void device_keeper_reset_if_need( … … 105 109 || !instance->devices[target.address].occupied) { 106 110 fibril_mutex_unlock(&instance->guard); 111 usb_log_error("Invalid data when checking for toggle reset.\n"); 107 112 return; 108 113 } … … 114 119 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 115 120 /* endpoint number is < 16, thus first byte is enough */ 116 instance->devices[target.address].toggle_status &= 121 instance->devices[target.address].toggle_status[0] &= 122 ~(1 << data[4]); 123 instance->devices[target.address].toggle_status[1] &= 117 124 ~(1 << data[4]); 118 125 } … … 123 130 /* target must be device */ 124 131 if ((data[0] & 0xf) == 0) { 125 instance->devices[target.address].toggle_status = 0; 132 instance->devices[target.address].toggle_status[0] = 0; 133 instance->devices[target.address].toggle_status[1] = 0; 126 134 } 127 135 break; … … 130 138 } 131 139 /*----------------------------------------------------------------------------*/ 132 /** Get scurrent value of endpoint toggle.140 /** Get current value of endpoint toggle. 133 141 * 134 142 * @param[in] instance Device keeper structure to use. … … 136 144 * @return Error code 137 145 */ 138 int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target) 139 { 140 assert(instance); 146 int device_keeper_get_toggle( 147 device_keeper_t *instance, usb_target_t target, usb_direction_t direction) 148 { 149 assert(instance); 150 /* only control pipes are bi-directional and those do not need toggle */ 151 if (direction == USB_DIRECTION_BOTH) 152 return ENOENT; 141 153 int ret; 142 154 fibril_mutex_lock(&instance->guard); … … 144 156 || target.address >= USB_ADDRESS_COUNT || target.address < 0 145 157 || !instance->devices[target.address].occupied) { 158 usb_log_error("Invalid data when asking for toggle value.\n"); 146 159 ret = EINVAL; 147 160 } else { 148 ret = 149 (instance->devices[target.address].toggle_status 161 ret = (instance->devices[target.address].toggle_status[direction] 150 162 >> target.endpoint) & 1; 151 163 } … … 154 166 } 155 167 /*----------------------------------------------------------------------------*/ 156 /** Set scurrent value of endpoint toggle.168 /** Set current value of endpoint toggle. 157 169 * 158 170 * @param[in] instance Device keeper structure to use. 159 171 * @param[in] target Device and endpoint used. 160 * @param[in] toggle Current toggle value.172 * @param[in] toggle Toggle value. 161 173 * @return Error code. 162 174 */ 163 int device_keeper_set_toggle( 164 device_keeper_t *instance, usb_target_t target, bool toggle) 165 { 166 assert(instance); 175 int device_keeper_set_toggle(device_keeper_t *instance, 176 usb_target_t target, usb_direction_t direction, bool toggle) 177 { 178 assert(instance); 179 /* only control pipes are bi-directional and those do not need toggle */ 180 if (direction == USB_DIRECTION_BOTH) 181 return ENOENT; 167 182 int ret; 168 183 fibril_mutex_lock(&instance->guard); … … 170 185 || target.address >= USB_ADDRESS_COUNT || target.address < 0 171 186 || !instance->devices[target.address].occupied) { 187 usb_log_error("Invalid data when setting toggle value.\n"); 172 188 ret = EINVAL; 173 189 } else { 174 190 if (toggle) { 175 instance->devices[target.address].toggle_status |= (1 << target.endpoint); 191 instance->devices[target.address].toggle_status[direction] 192 |= (1 << target.endpoint); 176 193 } else { 177 instance->devices[target.address].toggle_status &= ~(1 << target.endpoint); 194 instance->devices[target.address].toggle_status[direction] 195 &= ~(1 << target.endpoint); 178 196 } 179 197 ret = EOK; … … 183 201 } 184 202 /*----------------------------------------------------------------------------*/ 185 /** Get sa free USB address203 /** Get a free USB address 186 204 * 187 205 * @param[in] instance Device keeper structure to use. … … 210 228 instance->devices[new_address].occupied = true; 211 229 instance->devices[new_address].speed = speed; 212 instance->devices[new_address].toggle_status = 0; 230 instance->devices[new_address].toggle_status[0] = 0; 231 instance->devices[new_address].toggle_status[1] = 0; 213 232 instance->last_address = new_address; 214 233 fibril_mutex_unlock(&instance->guard); … … 216 235 } 217 236 /*----------------------------------------------------------------------------*/ 218 /** Bind sUSB address to devman handle.237 /** Bind USB address to devman handle. 219 238 * 220 239 * @param[in] instance Device keeper structure to use. … … 234 253 } 235 254 /*----------------------------------------------------------------------------*/ 236 /** Release sused USB address.255 /** Release used USB address. 237 256 * 238 257 * @param[in] instance Device keeper structure to use. … … 251 270 } 252 271 /*----------------------------------------------------------------------------*/ 253 /** Find sUSB address associated with the device272 /** Find USB address associated with the device 254 273 * 255 274 * @param[in] instance Device keeper structure to use. … … 274 293 } 275 294 /*----------------------------------------------------------------------------*/ 276 /** Get sspeed associated with the address295 /** Get speed associated with the address 277 296 * 278 297 * @param[in] instance Device keeper structure to use. -
uspace/lib/usb/src/hub.c
rc32688d r361e61b 235 235 goto leave_release_default_address; 236 236 } 237 rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe); 238 if (rc != EOK) { 239 rc = ENOTCONN; 240 goto leave_release_default_address; 241 } 237 242 238 243 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); -
uspace/lib/usb/src/pipes.c
rc32688d r361e61b 42 42 #include <assert.h> 43 43 44 #define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */ 45 44 46 /** Tell USB address assigned to given device. 45 47 * … … 51 53 { 52 54 sysarg_t address; 53 54 55 55 56 /* … … 96 97 } 97 98 99 /** Tell USB address assigned to given device. 100 * 101 * @param dev_handle Devman handle of the USB device in question. 102 * @return USB address or negative error code. 103 */ 104 usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle) 105 { 106 int parent_phone = devman_parent_device_connect(dev_handle, 107 IPC_FLAG_BLOCKING); 108 if (parent_phone < 0) { 109 return parent_phone; 110 } 111 112 sysarg_t address; 113 114 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 115 IPC_M_USB_GET_ADDRESS, 116 dev_handle, &address); 117 118 if (rc != EOK) { 119 return rc; 120 } 121 122 async_hangup(parent_phone); 123 124 return (usb_address_t) address; 125 } 126 98 127 /** Initialize connection to USB device. 99 128 * … … 123 152 } 124 153 125 my_address = get_my_address(parent_phone, dev); 126 if (my_address < 0) { 127 rc = my_address; 128 goto leave; 129 } 154 /* 155 * Asking for "my" address may require several attempts. 156 * That is because following scenario may happen: 157 * - parent driver (i.e. driver of parent device) announces new device 158 * and devman launches current driver 159 * - parent driver is preempted and thus does not send address-handle 160 * binding to HC driver 161 * - this driver gets here and wants the binding 162 * - the HC does not know the binding yet and thus it answers ENOENT 163 * So, we need to wait for the HC to learn the binding. 164 */ 165 do { 166 my_address = get_my_address(parent_phone, dev); 167 168 if (my_address == ENOENT) { 169 /* Be nice, let other fibrils run and try again. */ 170 async_usleep(IPC_AGAIN_DELAY); 171 } else if (my_address < 0) { 172 /* Some other problem, no sense trying again. */ 173 rc = my_address; 174 goto leave; 175 } 176 177 } while (my_address < 0); 130 178 131 179 rc = usb_device_connection_initialize(connection, -
uspace/lib/usb/src/pipesinit.c
rc32688d r361e61b 37 37 #include <usb/pipes.h> 38 38 #include <usb/dp.h> 39 #include <usb/request.h> 40 #include <usbhc_iface.h> 39 41 #include <errno.h> 40 42 #include <assert.h> 43 44 #define CTRL_PIPE_MIN_PACKET_SIZE 8 45 #define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7 41 46 42 47 … … 369 374 370 375 int rc = usb_endpoint_pipe_initialize(pipe, connection, 371 0, USB_TRANSFER_CONTROL, 8, USB_DIRECTION_BOTH); 376 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 377 USB_DIRECTION_BOTH); 372 378 373 379 return rc; 380 } 381 382 /** Probe default control pipe for max packet size. 383 * 384 * The function tries to get the correct value of max packet size several 385 * time before giving up. 386 * 387 * The session on the pipe shall not be started. 388 * 389 * @param pipe Default control pipe. 390 * @return Error code. 391 */ 392 int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *pipe) 393 { 394 assert(pipe); 395 assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE); 396 397 if ((pipe->direction != USB_DIRECTION_BOTH) || 398 (pipe->transfer_type != USB_TRANSFER_CONTROL) || 399 (pipe->endpoint_no != 0)) { 400 return EINVAL; 401 } 402 403 #define TRY_LOOP(attempt_var) \ 404 for (attempt_var = 0; attempt_var < 3; attempt_var++) 405 406 size_t failed_attempts; 407 int rc; 408 409 TRY_LOOP(failed_attempts) { 410 rc = usb_endpoint_pipe_start_session(pipe); 411 if (rc == EOK) { 412 break; 413 } 414 } 415 if (rc != EOK) { 416 return rc; 417 } 418 419 420 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; 421 size_t transferred_size; 422 TRY_LOOP(failed_attempts) { 423 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD, 424 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE, 425 0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE, 426 &transferred_size); 427 if (rc == EOK) { 428 if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) { 429 rc = ELIMIT; 430 continue; 431 } 432 break; 433 } 434 } 435 usb_endpoint_pipe_end_session(pipe); 436 if (rc != EOK) { 437 return rc; 438 } 439 440 pipe->max_packet_size 441 = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET]; 442 443 return EOK; 444 } 445 446 /** Register endpoint with the host controller. 447 * 448 * @param pipe Pipe to be registered. 449 * @param interval Polling interval. 450 * @param hc_connection Connection to the host controller (must be opened). 451 * @return Error code. 452 */ 453 int usb_endpoint_pipe_register(usb_endpoint_pipe_t *pipe, 454 unsigned int interval, 455 usb_hc_connection_t *hc_connection) 456 { 457 assert(pipe); 458 assert(hc_connection); 459 460 if (!usb_hc_connection_is_opened(hc_connection)) { 461 return EBADF; 462 } 463 464 #define _PACK(high, low) ((high) * 256 + (low)) 465 466 return async_req_5_0(hc_connection->hc_phone, 467 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT, 468 _PACK(pipe->wire->address, pipe->endpoint_no), 469 _PACK(pipe->transfer_type, pipe->direction), 470 pipe->max_packet_size, interval); 471 472 #undef _PACK 473 } 474 475 /** Revert endpoint registration with the host controller. 476 * 477 * @param pipe Pipe to be unregistered. 478 * @param hc_connection Connection to the host controller (must be opened). 479 * @return Error code. 480 */ 481 int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *pipe, 482 usb_hc_connection_t *hc_connection) 483 { 484 assert(pipe); 485 assert(hc_connection); 486 487 if (!usb_hc_connection_is_opened(hc_connection)) { 488 return EBADF; 489 } 490 491 return async_req_4_0(hc_connection->hc_phone, 492 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT, 493 pipe->wire->address, pipe->endpoint_no, pipe->direction); 374 494 } 375 495 -
uspace/lib/usb/src/recognise.c
rc32688d r361e61b 247 247 #undef VENDOR_ONLY_FMT 248 248 #undef VENDOR_ONLY_ARGS 249 250 /* As a last resort, try fallback driver. */ 251 ADD_MATCHID_OR_RETURN(matches, 10, "usb&interface&fallback"); 249 252 250 253 return EOK; … … 291 294 } 292 295 296 /* As a last resort, try fallback driver. */ 297 ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback"); 298 293 299 return EOK; 294 300 } … … 369 375 goto failure; 370 376 } 377 rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe); 378 if (rc != EOK) { 379 goto failure; 380 } 371 381 372 382 /* … … 374 384 * naming etc., something more descriptive could be created. 375 385 */ 376 rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index); 386 rc = asprintf(&child_name, "usb%02zu_a%d", 387 this_device_name_index, address); 377 388 if (rc < 0) { 378 389 goto failure; -
uspace/lib/usb/src/request.c
rc32688d r361e61b 157 157 } 158 158 159 /** Retrieve status of a USB device. 160 * 161 * @param[in] pipe Control endpoint pipe (session must be already started). 162 * @param[in] index Recipient index (in native endianness). 163 * @param[in] recipient Recipient of the GET_STATUS request. 164 * @param[out] status Recipient status (in native endianness). 165 * @return Error code. 166 */ 167 int usb_request_get_status(usb_endpoint_pipe_t *pipe, 168 usb_request_recipient_t recipient, uint16_t index, 169 uint16_t *status) 170 { 171 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) { 172 return EINVAL; 173 } 174 175 if (status == NULL) { 176 return EBADMEM; 177 } 178 179 uint16_t status_usb_endianess; 180 size_t data_transfered_size; 181 int rc = usb_control_request_get(pipe, USB_REQUEST_TYPE_STANDARD, 182 recipient, USB_DEVREQ_GET_STATUS, 0, uint16_host2usb(index), 183 &status_usb_endianess, 2, &data_transfered_size); 184 if (rc != EOK) { 185 return rc; 186 } 187 if (data_transfered_size != 2) { 188 return ELIMIT; 189 } 190 191 *status = uint16_usb2host(status_usb_endianess); 192 193 return EOK; 194 } 195 196 /** Clear or disable specific device feature. 197 * 198 * @param[in] pipe Control endpoint pipe (session must be already started). 199 * @param[in] request_type Request type (standard/class/vendor). 200 * @param[in] recipient Recipient of the CLEAR_FEATURE request. 201 * @param[in] feature_selector Feature selector (in native endianness). 202 * @param[in] index Recipient index (in native endianness). 203 * @return Error code. 204 */ 205 int usb_request_clear_feature(usb_endpoint_pipe_t *pipe, 206 usb_request_type_t request_type, usb_request_recipient_t recipient, 207 uint16_t feature_selector, uint16_t index) 208 { 209 if (request_type == USB_REQUEST_TYPE_STANDARD) { 210 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) 211 && (index != 0)) { 212 return EINVAL; 213 } 214 } 215 216 int rc = usb_control_request_set(pipe, request_type, recipient, 217 USB_DEVREQ_CLEAR_FEATURE, 218 uint16_host2usb(feature_selector), uint16_host2usb(index), 219 NULL, 0); 220 221 return rc; 222 } 223 224 /** Set or enable specific device feature. 225 * 226 * @param[in] pipe Control endpoint pipe (session must be already started). 227 * @param[in] request_type Request type (standard/class/vendor). 228 * @param[in] recipient Recipient of the SET_FEATURE request. 229 * @param[in] feature_selector Feature selector (in native endianness). 230 * @param[in] index Recipient index (in native endianness). 231 * @return Error code. 232 */ 233 int usb_request_set_feature(usb_endpoint_pipe_t *pipe, 234 usb_request_type_t request_type, usb_request_recipient_t recipient, 235 uint16_t feature_selector, uint16_t index) 236 { 237 if (request_type == USB_REQUEST_TYPE_STANDARD) { 238 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) 239 && (index != 0)) { 240 return EINVAL; 241 } 242 } 243 244 int rc = usb_control_request_set(pipe, request_type, recipient, 245 USB_DEVREQ_SET_FEATURE, 246 uint16_host2usb(feature_selector), uint16_host2usb(index), 247 NULL, 0); 248 249 return rc; 250 } 251 159 252 /** Change address of connected device. 160 253 * This function automatically updates the backing connection to point to … … 473 566 } 474 567 568 /** Update existing or add new USB descriptor to a USB device. 569 * 570 * @param[in] pipe Control endpoint pipe (session must be already started). 571 * @param[in] request_type Request type (standard/class/vendor). 572 * @param[in] recipient Request recipient (device/interface/endpoint). 573 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 574 * @param[in] descriptor_index Descriptor index. 575 * @param[in] language Language index (in native endianness). 576 * @param[in] buffer Buffer with the new descriptor (in USB endianness). 577 * @param[in] size Size of the @p buffer in bytes (in native endianness). 578 * @return Error code. 579 */ 580 int usb_request_set_descriptor(usb_endpoint_pipe_t *pipe, 581 usb_request_type_t request_type, usb_request_recipient_t recipient, 582 uint8_t descriptor_type, uint8_t descriptor_index, 583 uint16_t language, 584 void *buffer, size_t size) 585 { 586 if (buffer == NULL) { 587 return EBADMEM; 588 } 589 if (size == 0) { 590 return EINVAL; 591 } 592 593 /* FIXME: proper endianness. */ 594 uint16_t wValue = descriptor_index | (descriptor_type << 8); 595 596 return usb_control_request_set(pipe, 597 request_type, recipient, 598 USB_DEVREQ_SET_DESCRIPTOR, 599 wValue, language, 600 buffer, size); 601 } 602 603 /** Get current configuration value of USB device. 604 * 605 * @param[in] pipe Control endpoint pipe (session must be already started). 606 * @param[out] configuration_value Current configuration value. 607 * @return Error code. 608 */ 609 int usb_request_get_configuration(usb_endpoint_pipe_t *pipe, 610 uint8_t *configuration_value) 611 { 612 uint8_t value; 613 size_t actual_size; 614 615 int rc = usb_control_request_get(pipe, 616 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 617 USB_DEVREQ_GET_CONFIGURATION, 618 0, 0, 619 &value, 1, &actual_size); 620 621 if (rc != EOK) { 622 return rc; 623 } 624 if (actual_size != 1) { 625 return ELIMIT; 626 } 627 628 if (configuration_value != NULL) { 629 *configuration_value = value; 630 } 631 632 return EOK; 633 } 634 475 635 /** Set configuration of USB device. 476 636 * … … 488 648 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 489 649 USB_DEVREQ_SET_CONFIGURATION, config_value, 0, 650 NULL, 0); 651 } 652 653 /** Get selected alternate setting for USB interface. 654 * 655 * @param[in] pipe Control endpoint pipe (session must be already started). 656 * @param[in] interface_index Interface index. 657 * @param[out] alternate_setting Alternate setting for the interface. 658 * @return Error code. 659 */ 660 int usb_request_get_interface(usb_endpoint_pipe_t *pipe, 661 uint8_t interface_index, uint8_t *alternate_setting) 662 { 663 uint8_t value; 664 size_t actual_size; 665 666 int rc = usb_control_request_get(pipe, 667 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 668 USB_DEVREQ_GET_INTERFACE, 669 0, uint16_host2usb((uint16_t) interface_index), 670 &value, 1, &actual_size); 671 672 if (rc != EOK) { 673 return rc; 674 } 675 if (actual_size != 1) { 676 return ELIMIT; 677 } 678 679 if (alternate_setting != NULL) { 680 *alternate_setting = value; 681 } 682 683 return EOK; 684 } 685 686 /** Select alternate setting for USB interface. 687 * 688 * @param[in] pipe Control endpoint pipe (session must be already started). 689 * @param[in] interface_index Interface index. 690 * @param[in] alternate_setting Alternate setting to select. 691 * @return Error code. 692 */ 693 int usb_request_set_interface(usb_endpoint_pipe_t *pipe, 694 uint8_t interface_index, uint8_t alternate_setting) 695 { 696 return usb_control_request_set(pipe, 697 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 698 USB_DEVREQ_SET_INTERFACE, 699 uint16_host2usb((uint16_t) alternate_setting), 700 uint16_host2usb((uint16_t) interface_index), 490 701 NULL, 0); 491 702 }
Note:
See TracChangeset
for help on using the changeset viewer.
