Changeset 92574f4 in mainline for uspace/lib/usb
- Timestamp:
- 2011-02-24T12:03:27Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e7b7ebd5
- Parents:
- 4837092 (diff), a80849c (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/usb
- Files:
-
- 9 added
- 10 deleted
- 18 edited
- 1 moved
-
Makefile (modified) (1 diff)
-
include/usb/addrkeep.h (moved) (moved from uspace/lib/usb/include/usb/hcd.h ) (1 diff)
-
include/usb/classes/hid.h (modified) (1 diff)
-
include/usb/classes/hub.h (modified) (4 diffs)
-
include/usb/ddfiface.h (added)
-
include/usb/descriptor.h (modified) (1 diff)
-
include/usb/devreq.h (deleted)
-
include/usb/dp.h (modified) (1 diff)
-
include/usb/hcdhubd.h (deleted)
-
include/usb/hub.h (added)
-
include/usb/pipes.h (modified) (5 diffs)
-
include/usb/recognise.h (added)
-
include/usb/request.h (modified) (3 diffs)
-
include/usb/usb.h (modified) (3 diffs)
-
include/usb/usbdevice.h (added)
-
include/usb/usbdrv.h (deleted)
-
include/usb/usbmem.h (modified) (3 diffs)
-
src/addrkeep.c (modified) (1 diff)
-
src/ddfiface.c (added)
-
src/debug.c (modified) (2 diffs)
-
src/dp.c (modified) (1 diff)
-
src/drvpsync.c (deleted)
-
src/dump.c (modified) (1 diff)
-
src/hcdhubd.c (deleted)
-
src/hcdrv.c (deleted)
-
src/hub.c (added)
-
src/localdrv.c (deleted)
-
src/pipes.c (modified) (8 diffs)
-
src/pipesinit.c (added)
-
src/pipesio.c (added)
-
src/recognise.c (modified) (9 diffs)
-
src/remotedrv.c (deleted)
-
src/request.c (modified) (3 diffs)
-
src/usb.c (modified) (1 diff)
-
src/usbdevice.c (added)
-
src/usbdrv.c (deleted)
-
src/usbdrvreq.c (deleted)
-
src/usbmem.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/Makefile
r4837092 r92574f4 35 35 src/addrkeep.c \ 36 36 src/class.c \ 37 src/ddfiface.c \ 37 38 src/debug.c \ 38 39 src/dp.c \ 39 src/drvpsync.c \40 40 src/dump.c \ 41 src/hcdhubd.c \42 src/hcdrv.c \43 41 src/hidparser.c \ 44 src/ localdrv.c \42 src/hub.c \ 45 43 src/pipes.c \ 44 src/pipesinit.c \ 45 src/pipesio.c \ 46 46 src/recognise.c \ 47 src/remotedrv.c \48 47 src/request.c \ 49 48 src/usb.c \ 50 src/usbdrvreq.c \ 51 src/usbdrv.c \ 49 src/usbdevice.c \ 52 50 src/usbmem.c 53 51 -
uspace/lib/usb/include/usb/addrkeep.h
r4837092 r92574f4 31 31 */ 32 32 /** @file 33 * @brief HC driver.33 * USB address keeping for host controller drivers. 34 34 */ 35 #ifndef LIBUSB_ HCD_H_36 #define LIBUSB_ HCD_H_35 #ifndef LIBUSB_ADDRKEEP_H_ 36 #define LIBUSB_ADDRKEEP_H_ 37 37 38 38 #include <usb/usb.h> -
uspace/lib/usb/include/usb/classes/hid.h
r4837092 r92574f4 50 50 USB_HIDREQ_SET_PROTOCOL = 11 51 51 } usb_hid_request_t; 52 53 /** USB/HID subclass constants. */ 54 typedef enum { 55 USB_HID_SUBCLASS_NONE = 0, 56 USB_HID_SUBCLASS_BOOT = 1 57 } usb_hid_subclass_t; 52 58 53 59 /** USB/HID interface protocols. */ -
uspace/lib/usb/include/usb/classes/hub.h
r4837092 r92574f4 1 1 /* 2 * Copyright (c) 2010 Vojtech Horky2 * Copyright (c) 2010 Matus Dekanek 3 3 * All rights reserved. 4 4 * … … 33 33 * @brief USB hub related structures. 34 34 */ 35 #ifndef LIBUSB_ HUB_H_36 #define LIBUSB_ HUB_H_35 #ifndef LIBUSB_CLASS_HUB_H_ 36 #define LIBUSB_CLASS_HUB_H_ 37 37 38 38 #include <sys/types.h> 39 #include <usb/hcdhubd.h>40 41 39 42 40 /** Hub class feature selector. … … 80 78 /** 81 79 D1...D0: Logical Power Switching Mode 82 00: Ganged power switching (all ports ’power at80 00: Ganged power switching (all ports power at 83 81 once) 84 82 01: Individual port power switching … … 91 89 00: Global Over-current Protection. The hub 92 90 reports over-current as a summation of all 93 ports ’current draw, without a breakdown of91 ports current draw, without a breakdown of 94 92 individual port over-current status. 95 93 01: Individual Port Over-current Protection. The -
uspace/lib/usb/include/usb/descriptor.h
r4837092 r92574f4 36 36 #define LIBUSB_DESCRIPTOR_H_ 37 37 38 #include <ipc/ipc.h>39 38 #include <async.h> 40 39 -
uspace/lib/usb/include/usb/dp.h
r4837092 r92574f4 45 45 } usb_dp_descriptor_nesting_t; 46 46 47 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[]; 48 47 49 typedef struct { 48 50 usb_dp_descriptor_nesting_t *nesting; -
uspace/lib/usb/include/usb/pipes.h
r4837092 r92574f4 31 31 */ 32 32 /** @file 33 * Communication between device drivers and host controller driver.33 * USB pipes representation. 34 34 */ 35 35 #ifndef LIBUSB_PIPES_H_ … … 38 38 #include <sys/types.h> 39 39 #include <usb/usb.h> 40 #include <usb/usbdevice.h> 41 #include <usb/descriptor.h> 40 42 #include <ipc/devman.h> 41 #include <d river.h>43 #include <ddf/driver.h> 42 44 43 45 /** … … 73 75 usb_direction_t direction; 74 76 77 /** Maximum packet size for the endpoint. */ 78 size_t max_packet_size; 79 75 80 /** Phone to the host controller. 76 81 * Negative when no session is active. … … 80 85 81 86 87 /** Description of endpoint characteristics. */ 88 typedef struct { 89 /** Transfer type (e.g. control or interrupt). */ 90 usb_transfer_type_t transfer_type; 91 /** Transfer direction (to or from a device). */ 92 usb_direction_t direction; 93 /** Interface class this endpoint belongs to (-1 for any). */ 94 int interface_class; 95 /** Interface subclass this endpoint belongs to (-1 for any). */ 96 int interface_subclass; 97 /** Interface protocol this endpoint belongs to (-1 for any). */ 98 int interface_protocol; 99 /** Extra endpoint flags. */ 100 unsigned int flags; 101 } usb_endpoint_description_t; 102 103 /** Mapping of endpoint pipes and endpoint descriptions. */ 104 typedef struct { 105 /** Endpoint pipe. */ 106 usb_endpoint_pipe_t *pipe; 107 /** Endpoint description. */ 108 const usb_endpoint_description_t *description; 109 /** Interface number the endpoint must belong to (-1 for any). */ 110 const int interface_no; 111 /** Found descriptor fitting the description. */ 112 usb_standard_endpoint_descriptor_t *descriptor; 113 /** Interface the endpoint belongs to. */ 114 usb_standard_interface_descriptor_t *interface; 115 /** Whether the endpoint was actually found. */ 116 bool present; 117 } usb_endpoint_mapping_t; 118 119 int usb_device_connection_initialize_on_default_address( 120 usb_device_connection_t *, usb_hc_connection_t *); 82 121 int usb_device_connection_initialize_from_device(usb_device_connection_t *, 83 d evice_t *);122 ddf_dev_t *); 84 123 int usb_device_connection_initialize(usb_device_connection_t *, 85 124 devman_handle_t, usb_address_t); 86 125 126 int usb_device_get_assigned_interface(ddf_dev_t *); 127 87 128 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, 88 129 usb_device_connection_t *, 89 usb_endpoint_t, usb_transfer_type_t, usb_direction_t);130 usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t); 90 131 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *, 91 132 usb_device_connection_t *); 133 int usb_endpoint_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 134 size_t, uint8_t *, size_t, usb_device_connection_t *); 92 135 93 136 94 137 int usb_endpoint_pipe_start_session(usb_endpoint_pipe_t *); 95 138 int usb_endpoint_pipe_end_session(usb_endpoint_pipe_t *); 139 bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *); 96 140 97 141 int usb_endpoint_pipe_read(usb_endpoint_pipe_t *, void *, size_t, size_t *); … … 103 147 void *, size_t); 104 148 105 106 107 int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *, void *, size_t,108 size_t *, usb_handle_t *);109 int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *, void *, size_t,110 usb_handle_t *);111 112 int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *, void *, size_t,113 void *, size_t, size_t *, usb_handle_t *);114 int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *, void *, size_t,115 void *, size_t, usb_handle_t *);116 117 int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *, usb_handle_t);118 119 149 #endif 120 150 /** -
uspace/lib/usb/include/usb/request.h
r4837092 r92574f4 37 37 38 38 #include <sys/types.h> 39 #include <l18n/langs.h> 39 40 #include <usb/usb.h> 40 41 #include <usb/pipes.h> 41 42 #include <usb/descriptor.h> 43 44 /** Standard device request. */ 45 typedef enum { 46 USB_DEVREQ_GET_STATUS = 0, 47 USB_DEVREQ_CLEAR_FEATURE = 1, 48 USB_DEVREQ_SET_FEATURE = 3, 49 USB_DEVREQ_SET_ADDRESS = 5, 50 USB_DEVREQ_GET_DESCRIPTOR = 6, 51 USB_DEVREQ_SET_DESCRIPTOR = 7, 52 USB_DEVREQ_GET_CONFIGURATION = 8, 53 USB_DEVREQ_SET_CONFIGURATION = 9, 54 USB_DEVREQ_GET_INTERFACE = 10, 55 USB_DEVREQ_SET_INTERFACE = 11, 56 USB_DEVREQ_SYNCH_FRAME = 12, 57 USB_DEVREQ_LAST_STD 58 } usb_stddevreq_t; 59 60 /** Device request setup packet. 61 * The setup packet describes the request. 62 */ 63 typedef struct { 64 /** Request type. 65 * The type combines transfer direction, request type and 66 * intended recipient. 67 */ 68 uint8_t request_type; 69 /** Request identification. */ 70 uint8_t request; 71 /** Main parameter to the request. */ 72 union { 73 uint16_t value; 74 /* FIXME: add #ifdefs according to host endianess */ 75 struct { 76 uint8_t value_low; 77 uint8_t value_high; 78 }; 79 }; 80 /** Auxiliary parameter to the request. 81 * Typically, it is offset to something. 82 */ 83 uint16_t index; 84 /** Length of extra data. */ 85 uint16_t length; 86 } __attribute__ ((packed)) usb_device_request_setup_packet_t; 42 87 43 88 int usb_control_request_set(usb_endpoint_pipe_t *, … … 52 97 int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t, 53 98 uint8_t, uint8_t, uint16_t, void *, size_t, size_t *); 99 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t, 100 uint8_t, uint8_t, uint16_t, void **, size_t *); 54 101 int usb_request_get_device_descriptor(usb_endpoint_pipe_t *, 55 102 usb_standard_device_descriptor_t *); … … 60 107 int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t); 61 108 109 int usb_request_get_supported_languages(usb_endpoint_pipe_t *, 110 l18_win_locales_t **, size_t *); 111 int usb_request_get_string(usb_endpoint_pipe_t *, size_t, l18_win_locales_t, 112 char **); 113 62 114 #endif 63 115 /** -
uspace/lib/usb/include/usb/usb.h
r4837092 r92574f4 38 38 #include <sys/types.h> 39 39 #include <byteorder.h> 40 #include <ipc/ipc.h>41 40 42 41 /** Convert 16bit value from native (host) endianness to USB endianness. */ … … 70 69 } usb_direction_t; 71 70 71 /** USB speeds. */ 72 typedef enum { 73 /** USB 1.1 low speed (1.5Mbits/s). */ 74 USB_SPEED_LOW, 75 /** USB 1.1 full speed (12Mbits/s). */ 76 USB_SPEED_FULL, 77 /** USB 2.0 high speed (480Mbits/s). */ 78 USB_SPEED_HIGH 79 } usb_speed_t; 80 72 81 /** USB request type target. */ 73 82 typedef enum { … … 83 92 USB_REQUEST_RECIPIENT_ENDPOINT = 2 84 93 } usb_request_recipient_t; 85 86 /** USB transaction outcome. */87 typedef enum {88 USB_OUTCOME_OK,89 USB_OUTCOME_CRCERROR,90 USB_OUTCOME_BABBLE91 } usb_transaction_outcome_t;92 93 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);94 94 95 95 /** USB address type. -
uspace/lib/usb/include/usb/usbmem.h
r4837092 r92574f4 1 1 /* 2 * Copyright (c) 201 0Matus Dekanek2 * Copyright (c) 2011 Matus Dekanek 3 3 * All rights reserved. 4 4 * … … 35 35 * @{ 36 36 */ 37 /** @file definitions of special memory management, used mostly in usb stack37 /** @file definitions of memory management with address translation, used mostly in usb stack 38 38 * 39 39 * USB HCD needs traslation between physical and virtual addresses. These … … 59 59 60 60 extern void * mman_malloc( 61 size_t size,62 size_t alignment,63 unsigned long max_physical_address);61 size_t size, 62 size_t alignment, 63 unsigned long max_physical_address); 64 64 65 65 extern void * mman_getVA(void * addr); -
uspace/lib/usb/src/addrkeep.c
r4837092 r92574f4 33 33 * @brief Address keeping. 34 34 */ 35 #include <usb/ hcd.h>35 #include <usb/addrkeep.h> 36 36 #include <errno.h> 37 37 #include <assert.h> -
uspace/lib/usb/src/debug.c
r4837092 r92574f4 206 206 void usb_log_printf(usb_log_level_t level, const char *format, ...) 207 207 { 208 FILE *s tream = NULL;208 FILE *screen_stream = NULL; 209 209 switch (level) { 210 210 case USB_LOG_LEVEL_FATAL: 211 211 case USB_LOG_LEVEL_ERROR: 212 s tream = stderr;212 screen_stream = stderr; 213 213 break; 214 214 default: 215 s tream = stdout;215 screen_stream = stdout; 216 216 break; 217 217 } 218 assert(s tream != NULL);218 assert(screen_stream != NULL); 219 219 220 220 va_list args; 221 va_start(args, format);222 221 223 222 /* … … 231 230 232 231 if (log_stream != NULL) { 232 va_start(args, format); 233 233 234 fprintf(log_stream, "[%s]%s: ", log_prefix, level_name); 234 235 vfprintf(log_stream, format, args); 236 fflush(log_stream); 237 238 va_end(args); 235 239 } 236 240 237 241 if (level <= log_level) { 238 fprintf(stream, "[%s]%s: ", log_prefix, level_name); 239 vfprintf(stream, format, args); 242 va_start(args, format); 243 244 fprintf(screen_stream, "[%s]%s: ", log_prefix, level_name); 245 vfprintf(screen_stream, format, args); 246 fflush(screen_stream); 247 248 va_end(args); 240 249 } 241 250 242 251 fibril_mutex_unlock(&log_serializer); 243 244 va_end(args);245 252 } 246 253 -
uspace/lib/usb/src/dp.c
r4837092 r92574f4 37 37 #include <str_error.h> 38 38 #include <errno.h> 39 #include < usb/usbdrv.h>39 #include <assert.h> 40 40 #include <bool.h> 41 41 #include <usb/dp.h> 42 #include <usb/descriptor.h> 43 44 #define NESTING(parentname, childname) \ 45 { \ 46 .child = USB_DESCTYPE_##childname, \ 47 .parent = USB_DESCTYPE_##parentname, \ 48 } 49 #define LAST_NESTING { -1, -1 } 50 51 /** Nesting of standard USB descriptors. */ 52 usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = { 53 NESTING(CONFIGURATION, INTERFACE), 54 NESTING(INTERFACE, ENDPOINT), 55 NESTING(INTERFACE, HUB), 56 NESTING(INTERFACE, HID), 57 NESTING(HID, HID_REPORT), 58 LAST_NESTING 59 }; 60 61 #undef NESTING 62 #undef LAST_NESTING 42 63 43 64 /** Tells whether pointer points inside descriptor data. -
uspace/lib/usb/src/dump.c
r4837092 r92574f4 147 147 PRINTLINE("bDeviceProtocol = 0x%02x", d->device_protocol); 148 148 PRINTLINE("bMaxPacketSize0 = %d", d->max_packet_size); 149 PRINTLINE("idVendor = %d", d->vendor_id);150 PRINTLINE("idProduct = %d", d->product_id);149 PRINTLINE("idVendor = 0x%04x", d->vendor_id); 150 PRINTLINE("idProduct = 0x%04x", d->product_id); 151 151 PRINTLINE("bcdDevice = %d", d->device_version); 152 152 PRINTLINE("iManufacturer = %d", d->str_manufacturer); -
uspace/lib/usb/src/pipes.c
r4837092 r92574f4 31 31 */ 32 32 /** @file 33 * Communication between device drivers and host controller driver. 34 * 35 * Note on synchronousness of the operations: there is ABSOLUTELY NO 36 * guarantee that a call to particular function will not trigger a fibril 37 * switch. 38 * The initialization functions may actually involve contacting some other 39 * task, starting/ending a session might involve asynchronous IPC and since 40 * the transfer functions uses IPC, asynchronous nature of them is obvious. 41 * The pseudo synchronous versions for the transfers internally call the 42 * asynchronous ones and so fibril switch is possible in them as well. 33 * USB endpoint pipes miscellaneous functions. 43 34 */ 44 35 #include <usb/usb.h> 45 36 #include <usb/pipes.h> 37 #include <usb/debug.h> 38 #include <usbhc_iface.h> 39 #include <usb_iface.h> 40 #include <devman.h> 46 41 #include <errno.h> 47 42 #include <assert.h> 48 #include <usb/usbdrv.h> 49 50 #define _PREPARE_TARGET(varname, pipe) \ 51 usb_target_t varname = { \ 52 .address = (pipe)->wire->address, \ 53 .endpoint = (pipe)->endpoint_no \ 54 } 43 44 /** Tell USB address assigned to given device. 45 * 46 * @param phone Phone to parent device. 47 * @param dev Device in question. 48 * @return USB address or error code. 49 */ 50 static usb_address_t get_my_address(int phone, ddf_dev_t *dev) 51 { 52 sysarg_t address; 53 54 55 /* 56 * We are sending special value as a handle - zero - to get 57 * handle of the parent function (that handle was used 58 * when registering our device @p dev. 59 */ 60 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 61 IPC_M_USB_GET_ADDRESS, 62 0, &address); 63 64 if (rc != EOK) { 65 return rc; 66 } 67 68 return (usb_address_t) address; 69 } 70 71 /** Tell USB interface assigned to given device. 72 * 73 * @param device Device in question. 74 * @return Interface number (negative code means any). 75 */ 76 int usb_device_get_assigned_interface(ddf_dev_t *device) 77 { 78 int parent_phone = devman_parent_device_connect(device->handle, 79 IPC_FLAG_BLOCKING); 80 if (parent_phone < 0) { 81 return -1; 82 } 83 84 sysarg_t iface_no; 85 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 86 IPC_M_USB_GET_INTERFACE, 87 device->handle, &iface_no); 88 89 async_hangup(parent_phone); 90 91 if (rc != EOK) { 92 return -1; 93 } 94 95 return (int) iface_no; 96 } 55 97 56 98 /** Initialize connection to USB device. … … 61 103 */ 62 104 int usb_device_connection_initialize_from_device( 63 usb_device_connection_t *connection, d evice_t *device)105 usb_device_connection_t *connection, ddf_dev_t *dev) 64 106 { 65 107 assert(connection); 66 assert(dev ice);108 assert(dev); 67 109 68 110 int rc; … … 70 112 usb_address_t my_address; 71 113 72 rc = usb_ drv_find_hc(device, &hc_handle);114 rc = usb_hc_find(dev->handle, &hc_handle); 73 115 if (rc != EOK) { 74 116 return rc; 75 117 } 76 118 77 int hc_phone = devman_device_connect(hc_handle, 0); 78 if (hc_phone < 0) { 79 return hc_phone; 80 } 81 82 my_address = usb_drv_get_my_address(hc_phone, device); 119 int parent_phone = devman_parent_device_connect(dev->handle, 120 IPC_FLAG_BLOCKING); 121 if (parent_phone < 0) { 122 return parent_phone; 123 } 124 125 my_address = get_my_address(parent_phone, dev); 83 126 if (my_address < 0) { 84 127 rc = my_address; … … 90 133 91 134 leave: 92 ipc_hangup(hc_phone);135 async_hangup(parent_phone); 93 136 return rc; 94 137 } … … 117 160 } 118 161 119 /** Initialize USB endpoint pipe. 120 * 121 * @param pipe Endpoint pipe to be initialized. 122 * @param connection Connection to the USB device backing this pipe (the wire). 123 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15). 124 * @param transfer_type Transfer type (e.g. interrupt or bulk). 125 * @param direction Endpoint direction (in/out). 126 * @return Error code. 127 */ 128 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *pipe, 129 usb_device_connection_t *connection, usb_endpoint_t endpoint_no, 130 usb_transfer_type_t transfer_type, usb_direction_t direction) 131 { 132 assert(pipe); 133 assert(connection); 134 135 pipe->wire = connection; 136 pipe->hc_phone = -1; 137 pipe->endpoint_no = endpoint_no; 138 pipe->transfer_type = transfer_type; 139 pipe->direction = direction; 140 141 return EOK; 142 } 143 144 145 /** Initialize USB endpoint pipe as the default zero control pipe. 146 * 147 * @param pipe Endpoint pipe to be initialized. 148 * @param connection Connection to the USB device backing this pipe (the wire). 149 * @return Error code. 150 */ 151 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *pipe, 152 usb_device_connection_t *connection) 153 { 154 assert(pipe); 155 assert(connection); 156 157 int rc = usb_endpoint_pipe_initialize(pipe, connection, 158 0, USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH); 159 160 return rc; 162 /** Initialize connection to USB device on default address. 163 * 164 * @param dev_connection Device connection structure to be initialized. 165 * @param hc_connection Initialized connection to host controller. 166 * @return Error code. 167 */ 168 int usb_device_connection_initialize_on_default_address( 169 usb_device_connection_t *dev_connection, 170 usb_hc_connection_t *hc_connection) 171 { 172 assert(dev_connection); 173 174 if (hc_connection == NULL) { 175 return EBADMEM; 176 } 177 178 return usb_device_connection_initialize(dev_connection, 179 hc_connection->hc_handle, (usb_address_t) 0); 161 180 } 162 181 … … 181 200 assert(pipe); 182 201 183 if ( pipe->hc_phone >= 0) {202 if (usb_endpoint_pipe_is_session_started(pipe)) { 184 203 return EBUSY; 185 204 } … … 207 226 assert(pipe); 208 227 209 if ( pipe->hc_phone < 0) {228 if (!usb_endpoint_pipe_is_session_started(pipe)) { 210 229 return ENOENT; 211 230 } 212 231 213 int rc = ipc_hangup(pipe->hc_phone);232 int rc = async_hangup(pipe->hc_phone); 214 233 if (rc != EOK) { 215 234 return rc; … … 221 240 } 222 241 223 224 /** Request a read (in) transfer on an endpoint pipe. 225 * 226 * @param[in] pipe Pipe used for the transfer. 227 * @param[out] buffer Buffer where to store the data. 228 * @param[in] size Size of the buffer (in bytes). 229 * @param[out] size_transfered Number of bytes that were actually transfered. 230 * @return Error code. 231 */ 232 int usb_endpoint_pipe_read(usb_endpoint_pipe_t *pipe, 233 void *buffer, size_t size, size_t *size_transfered) 234 { 235 assert(pipe); 236 237 int rc; 238 usb_handle_t handle; 239 240 rc = usb_endpoint_pipe_async_read(pipe, buffer, size, size_transfered, 241 &handle); 242 if (rc != EOK) { 243 return rc; 244 } 245 246 rc = usb_endpoint_pipe_wait_for(pipe, handle); 247 return rc; 248 } 249 250 /** Request a write (out) transfer on an endpoint pipe. 251 * 252 * @param[in] pipe Pipe used for the transfer. 253 * @param[in] buffer Buffer with data to transfer. 254 * @param[in] size Size of the buffer (in bytes). 255 * @return Error code. 256 */ 257 int usb_endpoint_pipe_write(usb_endpoint_pipe_t *pipe, 258 void *buffer, size_t size) 259 { 260 assert(pipe); 261 262 int rc; 263 usb_handle_t handle; 264 265 rc = usb_endpoint_pipe_async_write(pipe, buffer, size, &handle); 266 if (rc != EOK) { 267 return rc; 268 } 269 270 rc = usb_endpoint_pipe_wait_for(pipe, handle); 271 return rc; 272 } 273 274 275 /** Request a control read transfer on an endpoint pipe. 276 * 277 * This function encapsulates all three stages of a control transfer. 278 * 279 * @param[in] pipe Pipe used for the transfer. 280 * @param[in] setup_buffer Buffer with the setup packet. 281 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 282 * @param[out] data_buffer Buffer for incoming data. 283 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes). 284 * @param[out] data_transfered_size Number of bytes that were actually 285 * transfered during the DATA stage. 286 * @return Error code. 287 */ 288 int usb_endpoint_pipe_control_read(usb_endpoint_pipe_t *pipe, 289 void *setup_buffer, size_t setup_buffer_size, 290 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size) 291 { 292 assert(pipe); 293 294 int rc; 295 usb_handle_t handle; 296 297 rc = usb_endpoint_pipe_async_control_read(pipe, 298 setup_buffer, setup_buffer_size, 299 data_buffer, data_buffer_size, data_transfered_size, 300 &handle); 301 if (rc != EOK) { 302 return rc; 303 } 304 305 rc = usb_endpoint_pipe_wait_for(pipe, handle); 306 return rc; 307 } 308 309 310 /** Request a control write transfer on an endpoint pipe. 311 * 312 * This function encapsulates all three stages of a control transfer. 313 * 314 * @param[in] pipe Pipe used for the transfer. 315 * @param[in] setup_buffer Buffer with the setup packet. 316 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 317 * @param[in] data_buffer Buffer with data to be sent. 318 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes). 319 * @return Error code. 320 */ 321 int usb_endpoint_pipe_control_write(usb_endpoint_pipe_t *pipe, 322 void *setup_buffer, size_t setup_buffer_size, 323 void *data_buffer, size_t data_buffer_size) 324 { 325 assert(pipe); 326 327 int rc; 328 usb_handle_t handle; 329 330 rc = usb_endpoint_pipe_async_control_write(pipe, 331 setup_buffer, setup_buffer_size, 332 data_buffer, data_buffer_size, 333 &handle); 334 if (rc != EOK) { 335 return rc; 336 } 337 338 rc = usb_endpoint_pipe_wait_for(pipe, handle); 339 return rc; 340 } 341 342 343 /** Request a read (in) transfer on an endpoint pipe (asynchronous version). 344 * 345 * @param[in] pipe Pipe used for the transfer. 346 * @param[out] buffer Buffer where to store the data. 347 * @param[in] size Size of the buffer (in bytes). 348 * @param[out] size_transfered Number of bytes that were actually transfered. 349 * @param[out] handle Handle of the transfer. 350 * @return Error code. 351 */ 352 int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *pipe, 353 void *buffer, size_t size, size_t *size_transfered, 354 usb_handle_t *handle) 355 { 356 assert(pipe); 357 358 if (pipe->hc_phone < 0) { 359 return EBADF; 360 } 361 362 if (pipe->direction != USB_DIRECTION_IN) { 363 return EBADF; 364 } 365 366 int rc; 367 _PREPARE_TARGET(target, pipe); 368 369 switch (pipe->transfer_type) { 370 case USB_TRANSFER_INTERRUPT: 371 rc = usb_drv_async_interrupt_in(pipe->hc_phone, target, 372 buffer, size, size_transfered, handle); 373 break; 374 case USB_TRANSFER_CONTROL: 375 rc = EBADF; 376 break; 377 default: 378 rc = ENOTSUP; 379 break; 380 } 381 382 return rc; 383 } 384 385 386 /** Request a write (out) transfer on an endpoint pipe (asynchronous version). 387 * 388 * @param[in] pipe Pipe used for the transfer. 389 * @param[in] buffer Buffer with data to transfer. 390 * @param[in] size Size of the buffer (in bytes). 391 * @param[out] handle Handle of the transfer. 392 * @return Error code. 393 */ 394 int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *pipe, 395 void *buffer, size_t size, 396 usb_handle_t *handle) 397 { 398 assert(pipe); 399 400 if (pipe->hc_phone < 0) { 401 return EBADF; 402 } 403 404 if (pipe->direction != USB_DIRECTION_OUT) { 405 return EBADF; 406 } 407 408 int rc; 409 _PREPARE_TARGET(target, pipe); 410 411 switch (pipe->transfer_type) { 412 case USB_TRANSFER_INTERRUPT: 413 rc = usb_drv_async_interrupt_out(pipe->hc_phone, target, 414 buffer, size, handle); 415 break; 416 case USB_TRANSFER_CONTROL: 417 rc = EBADF; 418 break; 419 default: 420 rc = ENOTSUP; 421 break; 422 } 423 424 return rc; 425 } 426 427 428 /** Request a control read transfer on an endpoint pipe (asynchronous version). 429 * 430 * This function encapsulates all three stages of a control transfer. 431 * 432 * @param[in] pipe Pipe used for the transfer. 433 * @param[in] setup_buffer Buffer with the setup packet. 434 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 435 * @param[out] data_buffer Buffer for incoming data. 436 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes). 437 * @param[out] data_transfered_size Number of bytes that were actually 438 * transfered during the DATA stage. 439 * @param[out] handle Handle of the transfer. 440 * @return Error code. 441 */ 442 int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *pipe, 443 void *setup_buffer, size_t setup_buffer_size, 444 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size, 445 usb_handle_t *handle) 446 { 447 assert(pipe); 448 449 if (pipe->hc_phone < 0) { 450 return EBADF; 451 } 452 453 if ((pipe->direction != USB_DIRECTION_BOTH) 454 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { 455 return EBADF; 456 } 457 458 int rc; 459 _PREPARE_TARGET(target, pipe); 460 461 rc = usb_drv_async_control_read(pipe->hc_phone, target, 462 setup_buffer, setup_buffer_size, 463 data_buffer, data_buffer_size, data_transfered_size, 464 handle); 465 466 return rc; 467 } 468 469 470 /** Request a control write transfer on an endpoint pipe (asynchronous version). 471 * 472 * This function encapsulates all three stages of a control transfer. 473 * 474 * @param[in] pipe Pipe used for the transfer. 475 * @param[in] setup_buffer Buffer with the setup packet. 476 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 477 * @param[in] data_buffer Buffer with data to be sent. 478 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes). 479 * @param[out] handle Handle of the transfer. 480 * @return Error code. 481 */ 482 int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *pipe, 483 void *setup_buffer, size_t setup_buffer_size, 484 void *data_buffer, size_t data_buffer_size, 485 usb_handle_t *handle) 486 { 487 assert(pipe); 488 489 if (pipe->hc_phone < 0) { 490 return EBADF; 491 } 492 493 if ((pipe->direction != USB_DIRECTION_BOTH) 494 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { 495 return EBADF; 496 } 497 498 int rc; 499 _PREPARE_TARGET(target, pipe); 500 501 rc = usb_drv_async_control_write(pipe->hc_phone, target, 502 setup_buffer, setup_buffer_size, 503 data_buffer, data_buffer_size, 504 handle); 505 506 return rc; 507 } 508 509 /** Wait for transfer completion. 510 * 511 * The function blocks the caller fibril until the transfer associated 512 * with given @p handle is completed. 513 * 514 * @param[in] pipe Pipe the transfer executed on. 515 * @param[in] handle Transfer handle. 516 * @return Error code. 517 */ 518 int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *pipe, usb_handle_t handle) 519 { 520 return usb_drv_async_wait_for(handle); 521 } 522 242 /** Tell whether a session is started (open) on the endpoint pipe. 243 * 244 * The expected usage of this function is in assertions for some 245 * nested functions. 246 * 247 * @param pipe Endpoint pipe in question. 248 * @return Whether @p pipe has opened a session. 249 */ 250 bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *pipe) 251 { 252 return (pipe->hc_phone >= 0); 253 } 523 254 524 255 /** -
uspace/lib/usb/src/recognise.c
r4837092 r92574f4 33 33 * @brief Functions for recognising kind of attached devices. 34 34 */ 35 #include <usb_iface.h> 36 #include <usb/usbdrv.h> 35 #include <sys/types.h> 36 #include <fibril_synch.h> 37 #include <usb/pipes.h> 38 #include <usb/recognise.h> 39 #include <usb/ddfiface.h> 40 #include <usb/request.h> 37 41 #include <usb/classes/classes.h> 38 42 #include <stdio.h> 39 43 #include <errno.h> 40 41 /** Callback for getting host controller handle. 42 * 43 * @param dev Device in question. 44 * @param[out] handle Devman handle of the host controller. 45 * @return Error code. 46 */ 47 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 48 { 49 assert(dev); 50 assert(dev->parent != NULL); 51 52 device_t *parent = dev->parent; 53 54 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 55 usb_iface_t *usb_iface 56 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 57 assert(usb_iface != NULL); 58 if (usb_iface->get_hc_handle) { 59 int rc = usb_iface->get_hc_handle(parent, handle); 60 return rc; 61 } 62 } 63 64 return ENOTSUP; 65 } 66 67 static usb_iface_t usb_iface = { 68 .get_hc_handle = usb_iface_get_hc_handle 69 }; 70 71 static device_ops_t child_ops = { 72 .interfaces[USB_DEV_IFACE] = &usb_iface 44 #include <assert.h> 45 46 static size_t device_name_index = 0; 47 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 48 49 ddf_dev_ops_t child_ops = { 50 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 73 51 }; 74 52 … … 135 113 } 136 114 115 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 116 do { \ 117 int __rc = usb_add_match_id((match_ids), (score), \ 118 format, ##__VA_ARGS__); \ 119 if (__rc != EOK) { \ 120 return __rc; \ 121 } \ 122 } while (0) 123 124 /** Create device match ids based on its interface. 125 * 126 * @param[in] descriptor Interface descriptor. 127 * @param[out] matches Initialized list of match ids. 128 * @return Error code (the two mentioned are not the only ones). 129 * @retval EINVAL Invalid input parameters (expects non NULL pointers). 130 * @retval ENOENT Interface does not specify class. 131 */ 132 int usb_device_create_match_ids_from_interface( 133 const usb_standard_device_descriptor_t *desc_device, 134 const usb_standard_interface_descriptor_t *desc_interface, 135 match_id_list_t *matches) 136 { 137 if (desc_interface == NULL) { 138 return EINVAL; 139 } 140 if (matches == NULL) { 141 return EINVAL; 142 } 143 144 if (desc_interface->interface_class == USB_CLASS_USE_INTERFACE) { 145 return ENOENT; 146 } 147 148 const char *classname = usb_str_class(desc_interface->interface_class); 149 assert(classname != NULL); 150 151 #define IFACE_PROTOCOL_FMT "interface&class=%s&subclass=0x%02x&protocol=0x%02x" 152 #define IFACE_PROTOCOL_ARGS classname, desc_interface->interface_subclass, \ 153 desc_interface->interface_protocol 154 155 #define IFACE_SUBCLASS_FMT "interface&class=%s&subclass=0x%02x" 156 #define IFACE_SUBCLASS_ARGS classname, desc_interface->interface_subclass 157 158 #define IFACE_CLASS_FMT "interface&class=%s" 159 #define IFACE_CLASS_ARGS classname 160 161 #define VENDOR_RELEASE_FMT "vendor=0x%04x&product=0x%04x&release=" BCD_FMT 162 #define VENDOR_RELEASE_ARGS desc_device->vendor_id, desc_device->product_id, \ 163 BCD_ARGS(desc_device->device_version) 164 165 #define VENDOR_PRODUCT_FMT "vendor=0x%04x&product=0x%04x" 166 #define VENDOR_PRODUCT_ARGS desc_device->vendor_id, desc_device->product_id 167 168 #define VENDOR_ONLY_FMT "vendor=0x%04x" 169 #define VENDOR_ONLY_ARGS desc_device->vendor_id 170 171 /* 172 * If the vendor is specified, create match ids with vendor with 173 * higher score. 174 * Then the same ones without the vendor part. 175 */ 176 if ((desc_device != NULL) && (desc_device->vendor_id != 0)) { 177 /* First, interface matches with device release number. */ 178 ADD_MATCHID_OR_RETURN(matches, 250, 179 "usb&" VENDOR_RELEASE_FMT "&" IFACE_PROTOCOL_FMT, 180 VENDOR_RELEASE_ARGS, IFACE_PROTOCOL_ARGS); 181 ADD_MATCHID_OR_RETURN(matches, 240, 182 "usb&" VENDOR_RELEASE_FMT "&" IFACE_SUBCLASS_FMT, 183 VENDOR_RELEASE_ARGS, IFACE_SUBCLASS_ARGS); 184 ADD_MATCHID_OR_RETURN(matches, 230, 185 "usb&" VENDOR_RELEASE_FMT "&" IFACE_CLASS_FMT, 186 VENDOR_RELEASE_ARGS, IFACE_CLASS_ARGS); 187 188 /* Next, interface matches without release number. */ 189 ADD_MATCHID_OR_RETURN(matches, 220, 190 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_PROTOCOL_FMT, 191 VENDOR_PRODUCT_ARGS, IFACE_PROTOCOL_ARGS); 192 ADD_MATCHID_OR_RETURN(matches, 210, 193 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_SUBCLASS_FMT, 194 VENDOR_PRODUCT_ARGS, IFACE_SUBCLASS_ARGS); 195 ADD_MATCHID_OR_RETURN(matches, 200, 196 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_CLASS_FMT, 197 VENDOR_PRODUCT_ARGS, IFACE_CLASS_ARGS); 198 199 /* Finally, interface matches with only vendor. */ 200 ADD_MATCHID_OR_RETURN(matches, 190, 201 "usb&" VENDOR_ONLY_FMT "&" IFACE_PROTOCOL_FMT, 202 VENDOR_ONLY_ARGS, IFACE_PROTOCOL_ARGS); 203 ADD_MATCHID_OR_RETURN(matches, 180, 204 "usb&" VENDOR_ONLY_FMT "&" IFACE_SUBCLASS_FMT, 205 VENDOR_ONLY_ARGS, IFACE_SUBCLASS_ARGS); 206 ADD_MATCHID_OR_RETURN(matches, 170, 207 "usb&" VENDOR_ONLY_FMT "&" IFACE_CLASS_FMT, 208 VENDOR_ONLY_ARGS, IFACE_CLASS_ARGS); 209 } 210 211 /* Now, the same but without any vendor specification. */ 212 ADD_MATCHID_OR_RETURN(matches, 160, 213 "usb&" IFACE_PROTOCOL_FMT, 214 IFACE_PROTOCOL_ARGS); 215 ADD_MATCHID_OR_RETURN(matches, 150, 216 "usb&" IFACE_SUBCLASS_FMT, 217 IFACE_SUBCLASS_ARGS); 218 ADD_MATCHID_OR_RETURN(matches, 140, 219 "usb&" IFACE_CLASS_FMT, 220 IFACE_CLASS_ARGS); 221 222 #undef IFACE_PROTOCOL_FMT 223 #undef IFACE_PROTOCOL_ARGS 224 #undef IFACE_SUBCLASS_FMT 225 #undef IFACE_SUBCLASS_ARGS 226 #undef IFACE_CLASS_FMT 227 #undef IFACE_CLASS_ARGS 228 #undef VENDOR_RELEASE_FMT 229 #undef VENDOR_RELEASE_ARGS 230 #undef VENDOR_PRODUCT_FMT 231 #undef VENDOR_PRODUCT_ARGS 232 #undef VENDOR_ONLY_FMT 233 #undef VENDOR_ONLY_ARGS 234 235 return EOK; 236 } 237 137 238 /** Create DDF match ids from USB device descriptor. 138 239 * … … 141 242 * @return Error code. 142 243 */ 143 int usb_d rv_create_match_ids_from_device_descriptor(144 match_id_list_t *matches,145 const usb_standard_device_descriptor_t *device_descriptor)244 int usb_device_create_match_ids_from_device_descriptor( 245 const usb_standard_device_descriptor_t *device_descriptor, 246 match_id_list_t *matches) 146 247 { 147 int rc;148 149 248 /* 150 249 * Unless the vendor id is 0, the pair idVendor-idProduct … … 153 252 if (device_descriptor->vendor_id != 0) { 154 253 /* First, with release number. */ 155 rc = usb_add_match_id(matches, 100,156 "usb&vendor= %d&product=%d&release=" BCD_FMT,254 ADD_MATCHID_OR_RETURN(matches, 100, 255 "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT, 157 256 (int) device_descriptor->vendor_id, 158 257 (int) device_descriptor->product_id, 159 258 BCD_ARGS(device_descriptor->device_version)); 160 if (rc != EOK) {161 return rc;162 }163 259 164 260 /* Next, without release number. */ 165 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d", 261 ADD_MATCHID_OR_RETURN(matches, 90, 262 "usb&vendor=0x%04x&product=0x%04x", 166 263 (int) device_descriptor->vendor_id, 167 264 (int) device_descriptor->product_id); 168 if (rc != EOK) {169 return rc;170 }171 265 } 172 266 173 267 /* 174 268 * If the device class points to interface we skip adding 175 * class directly .269 * class directly but we add a multi interface device. 176 270 */ 177 271 if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) { 178 rc = usb_add_match_id(matches, 50, "usb&class=%s",272 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s", 179 273 usb_str_class(device_descriptor->device_class)); 180 if (rc != EOK) { 181 return rc; 182 } 274 } else { 275 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid"); 183 276 } 184 277 … … 186 279 } 187 280 188 /** Create DDF match ids from USB configuration descriptor. 189 * The configuration descriptor is expected to be in the complete form, 190 * i.e. including interface, endpoint etc. descriptors. 191 * 192 * @param matches List of match ids to extend. 193 * @param config_descriptor Configuration descriptor returned by given device. 194 * @param total_size Size of the @p config_descriptor. 281 282 /** Create match ids describing attached device. 283 * 284 * @warning The list of match ids @p matches may change even when 285 * function exits with error. 286 * 287 * @param ctrl_pipe Control pipe to given device (session must be already 288 * started). 289 * @param matches Initialized list of match ids. 195 290 * @return Error code. 196 291 */ 197 int usb_drv_create_match_ids_from_configuration_descriptor( 198 match_id_list_t *matches, 199 const void *config_descriptor, size_t total_size) 292 int usb_device_create_match_ids(usb_endpoint_pipe_t *ctrl_pipe, 293 match_id_list_t *matches) 200 294 { 201 /* 202 * Iterate through config descriptor to find the interface 203 * descriptors. 204 */ 205 size_t position = sizeof(usb_standard_configuration_descriptor_t); 206 while (position + 1 < total_size) { 207 uint8_t *current_descriptor 208 = ((uint8_t *) config_descriptor) + position; 209 uint8_t cur_descr_len = current_descriptor[0]; 210 uint8_t cur_descr_type = current_descriptor[1]; 211 212 if (cur_descr_len == 0) { 213 return ENOENT; 214 } 215 216 position += cur_descr_len; 217 218 if (cur_descr_type != USB_DESCTYPE_INTERFACE) { 219 continue; 220 } 221 222 /* 223 * Finally, we found an interface descriptor. 224 */ 225 usb_standard_interface_descriptor_t *interface 226 = (usb_standard_interface_descriptor_t *) 227 current_descriptor; 228 229 int rc = usb_add_match_id(matches, 50, 230 "usb&interface&class=%s", 231 usb_str_class(interface->interface_class)); 232 if (rc != EOK) { 233 return rc; 234 } 235 } 236 295 int rc; 296 /* 297 * Retrieve device descriptor and add matches from it. 298 */ 299 usb_standard_device_descriptor_t device_descriptor; 300 301 rc = usb_request_get_device_descriptor(ctrl_pipe, &device_descriptor); 302 if (rc != EOK) { 303 return rc; 304 } 305 306 rc = usb_device_create_match_ids_from_device_descriptor( 307 &device_descriptor, matches); 308 if (rc != EOK) { 309 return rc; 310 } 311 237 312 return EOK; 238 313 } 239 314 240 /** Add match ids based on configuration descriptor.241 *242 * @param hc Open phone to host controller.243 * @param matches Match ids list to add matches to.244 * @param address USB address of the attached device.245 * @param config_count Number of configurations the device has.246 * @return Error code.247 */248 static int usb_add_config_descriptor_match_ids(int hc,249 match_id_list_t *matches, usb_address_t address,250 int config_count)251 {252 int final_rc = EOK;253 254 int config_index;255 for (config_index = 0; config_index < config_count; config_index++) {256 int rc;257 usb_standard_configuration_descriptor_t config_descriptor;258 rc = usb_drv_req_get_bare_configuration_descriptor(hc,259 address, config_index, &config_descriptor);260 if (rc != EOK) {261 final_rc = rc;262 continue;263 }264 265 size_t full_config_descriptor_size;266 void *full_config_descriptor267 = malloc(config_descriptor.total_length);268 rc = usb_drv_req_get_full_configuration_descriptor(hc,269 address, config_index,270 full_config_descriptor, config_descriptor.total_length,271 &full_config_descriptor_size);272 if (rc != EOK) {273 final_rc = rc;274 continue;275 }276 if (full_config_descriptor_size277 != config_descriptor.total_length) {278 final_rc = ERANGE;279 continue;280 }281 282 rc = usb_drv_create_match_ids_from_configuration_descriptor(283 matches,284 full_config_descriptor, full_config_descriptor_size);285 if (rc != EOK) {286 final_rc = rc;287 continue;288 }289 290 }291 292 return final_rc;293 }294 295 /** Create match ids describing attached device.296 *297 * @warning The list of match ids @p matches may change even when298 * function exits with error.299 *300 * @param hc Open phone to host controller.301 * @param matches Initialized list of match ids.302 * @param address USB address of the attached device.303 * @return Error code.304 */305 int usb_drv_create_device_match_ids(int hc, match_id_list_t *matches,306 usb_address_t address)307 {308 int rc;309 310 /*311 * Retrieve device descriptor and add matches from it.312 */313 usb_standard_device_descriptor_t device_descriptor;314 315 rc = usb_drv_req_get_device_descriptor(hc, address,316 &device_descriptor);317 if (rc != EOK) {318 return rc;319 }320 321 rc = usb_drv_create_match_ids_from_device_descriptor(matches,322 &device_descriptor);323 if (rc != EOK) {324 return rc;325 }326 327 /*328 * Go through all configurations and add matches329 * based on interface class.330 */331 rc = usb_add_config_descriptor_match_ids(hc, matches,332 address, device_descriptor.configuration_count);333 if (rc != EOK) {334 return rc;335 }336 337 /*338 * As a fallback, provide the simplest match id possible.339 */340 rc = usb_add_match_id(matches, 1, "usb&fallback");341 if (rc != EOK) {342 return rc;343 }344 345 return EOK;346 }347 348 349 315 /** Probe for device kind and register it in devman. 350 316 * 351 * @param[in] hc Open phone to the host controller. 317 * @param[in] address Address of the (unknown) attached device. 318 * @param[in] hc_handle Handle of the host controller. 352 319 * @param[in] parent Parent device. 353 * @param[in] address Address of the (unknown) attached device.354 320 * @param[out] child_handle Handle of the child device. 355 321 * @return Error code. 356 322 */ 357 int usb_drv_register_child_in_devman(int hc, device_t *parent, 358 usb_address_t address, devman_handle_t *child_handle) 323 int usb_device_register_child_in_devman(usb_address_t address, 324 devman_handle_t hc_handle, 325 ddf_dev_t *parent, devman_handle_t *child_handle, 326 ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun) 359 327 { 360 static size_t device_name_index = 0; 361 362 device_t *child = NULL; 328 size_t this_device_name_index; 329 330 fibril_mutex_lock(&device_name_index_mutex); 331 this_device_name_index = device_name_index; 332 device_name_index++; 333 fibril_mutex_unlock(&device_name_index_mutex); 334 335 ddf_fun_t *child = NULL; 363 336 char *child_name = NULL; 364 337 int rc; 365 366 child = create_device(); 338 usb_device_connection_t dev_connection; 339 usb_endpoint_pipe_t ctrl_pipe; 340 341 rc = usb_device_connection_initialize(&dev_connection, hc_handle, address); 342 if (rc != EOK) { 343 goto failure; 344 } 345 346 rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, 347 &dev_connection); 348 if (rc != EOK) { 349 goto failure; 350 } 351 352 /* 353 * TODO: Once the device driver framework support persistent 354 * naming etc., something more descriptive could be created. 355 */ 356 rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index); 357 if (rc < 0) { 358 goto failure; 359 } 360 361 child = ddf_fun_create(parent, fun_inner, child_name); 367 362 if (child == NULL) { 368 363 rc = ENOMEM; … … 370 365 } 371 366 372 /* 373 * TODO: Once the device driver framework support persistent 374 * naming etc., something more descriptive could be created. 375 */ 376 rc = asprintf(&child_name, "usbdev%02zu", device_name_index); 377 if (rc < 0) { 378 goto failure; 379 } 380 child->parent = parent; 381 child->name = child_name; 382 child->ops = &child_ops; 383 384 rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address); 385 if (rc != EOK) { 386 goto failure; 387 } 388 389 rc = child_device_register(child, parent); 367 if (dev_ops != NULL) { 368 child->ops = dev_ops; 369 } else { 370 child->ops = &child_ops; 371 } 372 373 child->driver_data = dev_data; 374 375 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); 376 if (rc != EOK) { 377 goto failure; 378 } 379 380 rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids); 381 if (rc != EOK) { 382 goto failure; 383 } 384 385 rc = usb_endpoint_pipe_end_session(&ctrl_pipe); 386 if (rc != EOK) { 387 goto failure; 388 } 389 390 rc = ddf_fun_bind(child); 390 391 if (rc != EOK) { 391 392 goto failure; … … 395 396 *child_handle = child->handle; 396 397 } 397 398 device_name_index++; 398 399 if (child_fun != NULL) { 400 *child_fun = child; 401 } 399 402 400 403 return EOK; … … 404 407 child->name = NULL; 405 408 /* This takes care of match_id deallocation as well. */ 406 d elete_device(child);409 ddf_fun_destroy(child); 407 410 } 408 411 if (child_name != NULL) { … … 411 414 412 415 return rc; 413 414 416 } 415 417 -
uspace/lib/usb/src/request.c
r4837092 r92574f4 34 34 */ 35 35 #include <usb/request.h> 36 #include <usb/devreq.h>37 36 #include <errno.h> 37 #include <assert.h> 38 38 39 39 #define MAX_DATA_LENGTH ((size_t)(0xFFFF)) … … 230 230 } 231 231 232 /** Retrieve USB descriptor, allocate space for it. 233 * 234 * @param[in] pipe Control endpoint pipe (session must be already started). 235 * @param[in] request_type Request type (standard/class/vendor). 236 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 237 * @param[in] descriptor_index Descriptor index. 238 * @param[in] language Language index. 239 * @param[out] buffer_ptr Where to store pointer to allocated buffer. 240 * @param[out] buffer_size Where to store the size of the descriptor. 241 * @return 242 */ 243 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe, 244 usb_request_type_t request_type, 245 uint8_t descriptor_type, uint8_t descriptor_index, 246 uint16_t language, 247 void **buffer_ptr, size_t *buffer_size) 248 { 249 if (buffer_ptr == NULL) { 250 return EBADMEM; 251 } 252 253 int rc; 254 255 /* 256 * Get only first byte to retrieve descriptor length. 257 */ 258 uint8_t tmp_buffer[1]; 259 size_t bytes_transfered; 260 rc = usb_request_get_descriptor(pipe, request_type, 261 descriptor_type, descriptor_index, language, 262 &tmp_buffer, 1, &bytes_transfered); 263 if (rc != EOK) { 264 return rc; 265 } 266 if (bytes_transfered != 1) { 267 /* FIXME: some better error code? */ 268 return ESTALL; 269 } 270 271 size_t size = tmp_buffer[0]; 272 if (size == 0) { 273 /* FIXME: some better error code? */ 274 return ESTALL; 275 } 276 277 /* 278 * Allocate buffer and get the descriptor again. 279 */ 280 void *buffer = malloc(size); 281 if (buffer == NULL) { 282 return ENOMEM; 283 } 284 285 rc = usb_request_get_descriptor(pipe, request_type, 286 descriptor_type, descriptor_index, language, 287 buffer, size, &bytes_transfered); 288 if (rc != EOK) { 289 free(buffer); 290 return rc; 291 } 292 if (bytes_transfered != size) { 293 free(buffer); 294 /* FIXME: some better error code? */ 295 return ESTALL; 296 } 297 298 *buffer_ptr = buffer; 299 if (buffer_size != NULL) { 300 *buffer_size = size; 301 } 302 303 return EOK; 304 } 305 232 306 /** Retrieve standard device descriptor of a USB device. 233 307 * … … 355 429 } 356 430 431 /** Get list of supported languages by USB device. 432 * 433 * @param[in] pipe Control endpoint pipe (session must be already started). 434 * @param[out] languages_ptr Where to store pointer to allocated array of 435 * supported languages. 436 * @param[out] languages_count Number of supported languages. 437 * @return Error code. 438 */ 439 int usb_request_get_supported_languages(usb_endpoint_pipe_t *pipe, 440 l18_win_locales_t **languages_ptr, size_t *languages_count) 441 { 442 int rc; 443 444 if (languages_ptr == NULL) { 445 return EBADMEM; 446 } 447 if (languages_count == NULL) { 448 return EBADMEM; 449 } 450 451 uint8_t *string_descriptor = NULL; 452 size_t string_descriptor_size = 0; 453 rc = usb_request_get_descriptor_alloc(pipe, 454 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0, 455 (void **) &string_descriptor, &string_descriptor_size); 456 if (rc != EOK) { 457 return rc; 458 } 459 if (string_descriptor_size <= 2) { 460 free(string_descriptor); 461 return EEMPTY; 462 } 463 /* Substract first 2 bytes (length and descriptor type). */ 464 string_descriptor_size -= 2; 465 466 /* Odd number of bytes - descriptor is broken? */ 467 if ((string_descriptor_size % 2) != 0) { 468 /* FIXME: shall we return with error or silently ignore? */ 469 free(string_descriptor); 470 return ESTALL; 471 } 472 473 size_t langs_count = string_descriptor_size / 2; 474 l18_win_locales_t *langs 475 = malloc(sizeof(l18_win_locales_t) * langs_count); 476 if (langs == NULL) { 477 free(string_descriptor); 478 return ENOMEM; 479 } 480 481 size_t i; 482 for (i = 0; i < langs_count; i++) { 483 /* Language code from the descriptor is in USB endianess. */ 484 /* FIXME: is this really correct? */ 485 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8) 486 + string_descriptor[2 + 2 * i]; 487 langs[i] = uint16_usb2host(lang_code); 488 } 489 490 free(string_descriptor); 491 492 *languages_ptr = langs; 493 *languages_count =langs_count; 494 495 return EOK; 496 } 497 498 /** Get string (descriptor) from USB device. 499 * 500 * The string is returned in native encoding of the operating system. 501 * For HelenOS, that is UTF-8. 502 * 503 * @param[in] pipe Control endpoint pipe (session must be already started). 504 * @param[in] index String index (in native endianess). 505 * @param[in] lang String language (in native endianess). 506 * @param[out] string_ptr Where to store allocated string in native encoding. 507 * @return Error code. 508 */ 509 int usb_request_get_string(usb_endpoint_pipe_t *pipe, 510 size_t index, l18_win_locales_t lang, char **string_ptr) 511 { 512 if (string_ptr == NULL) { 513 return EBADMEM; 514 } 515 /* Index is actually one byte value. */ 516 if (index > 0xFF) { 517 return ERANGE; 518 } 519 /* Language is actually two byte value. */ 520 if (lang > 0xFFFF) { 521 return ERANGE; 522 } 523 524 int rc; 525 526 /* Prepare dynamically allocated variables. */ 527 uint8_t *string = NULL; 528 wchar_t *string_chars = NULL; 529 530 /* Get the actual descriptor. */ 531 size_t string_size; 532 rc = usb_request_get_descriptor_alloc(pipe, 533 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 534 index, uint16_host2usb(lang), 535 (void **) &string, &string_size); 536 if (rc != EOK) { 537 goto leave; 538 } 539 540 if (string_size <= 2) { 541 rc = EEMPTY; 542 goto leave; 543 } 544 /* Substract first 2 bytes (length and descriptor type). */ 545 string_size -= 2; 546 547 /* Odd number of bytes - descriptor is broken? */ 548 if ((string_size % 2) != 0) { 549 /* FIXME: shall we return with error or silently ignore? */ 550 rc = ESTALL; 551 goto leave; 552 } 553 554 size_t string_char_count = string_size / 2; 555 string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1)); 556 if (string_chars == NULL) { 557 rc = ENOMEM; 558 goto leave; 559 } 560 561 /* 562 * Build a wide string. 563 * And do not forget to set NULL terminator (string descriptors 564 * do not have them). 565 */ 566 size_t i; 567 for (i = 0; i < string_char_count; i++) { 568 uint16_t uni_char = (string[2 + 2 * i + 1] << 8) 569 + string[2 + 2 * i]; 570 string_chars[i] = uni_char; 571 } 572 string_chars[string_char_count] = 0; 573 574 575 /* Convert to normal string. */ 576 char *str = wstr_to_astr(string_chars); 577 if (str == NULL) { 578 rc = ENOMEM; 579 goto leave; 580 } 581 582 *string_ptr = str; 583 rc = EOK; 584 585 leave: 586 if (string != NULL) { 587 free(string); 588 } 589 if (string_chars != NULL) { 590 free(string_chars); 591 } 592 593 return rc; 594 } 595 357 596 /** 358 597 * @} -
uspace/lib/usb/src/usb.c
r4837092 r92574f4 54 54 } 55 55 56 /** String representation of USB transaction outcome. */57 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)58 {59 switch (o) {60 case USB_OUTCOME_OK:61 return "ok";62 case USB_OUTCOME_CRCERROR:63 return "CRC error";64 case USB_OUTCOME_BABBLE:65 return "babble";66 default:67 return "unknown";68 }69 }70 71 72 56 /** 73 57 * @} -
uspace/lib/usb/src/usbmem.c
r4837092 r92574f4 1 1 /* 2 * Copyright (c) 201 0Matus Dekanek2 * Copyright (c) 2011 Matus Dekanek 3 3 * All rights reserved. 4 4 * … … 69 69 } 70 70 71 static void addr_remove_callback(link_t * item)71 static void addr_remove_callback(link_t * item) 72 72 { 73 73 //delete item
Note:
See TracChangeset
for help on using the changeset viewer.
