Changeset 93fb170c in mainline for uspace/lib/usb
- Timestamp:
- 2011-01-08T18:51:31Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 15be932
- Parents:
- 8f748215 (diff), a523af4 (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 edited
-
include/usb/devreq.h (modified) (1 diff)
-
include/usb/hcdhubd.h (modified) (1 diff)
-
include/usb/usb.h (modified) (1 diff)
-
include/usb/usbdrv.h (modified) (2 diffs)
-
src/addrkeep.c (modified) (2 diffs)
-
src/hcdhubd.c (modified) (3 diffs)
-
src/recognise.c (modified) (7 diffs)
-
src/usbdrv.c (modified) (3 diffs)
-
src/usbdrvreq.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/devreq.h
r8f748215 r93fb170c 92 92 int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int, 93 93 void *, size_t, size_t *); 94 int usb_drv_req_get_descriptor(int, usb_address_t, usb_request_type_t, 95 uint8_t, uint8_t, uint16_t, void *, size_t, size_t *); 94 96 95 97 -
uspace/lib/usb/include/usb/hcdhubd.h
r8f748215 r93fb170c 207 207 int usb_hc_add_child_device(device_t *, const char *, const char *, bool); 208 208 209 210 /** 211 * @} 212 */ 213 209 214 #endif -
uspace/lib/usb/include/usb/usb.h
r8f748215 r93fb170c 54 54 USB_DIRECTION_OUT 55 55 } usb_direction_t; 56 57 /** USB request type target. */ 58 typedef enum { 59 USB_REQUEST_TYPE_STANDARD = 0, 60 USB_REQUEST_TYPE_CLASS = 1, 61 USB_REQUEST_TYPE_VENDOR = 2 62 } usb_request_type_t; 56 63 57 64 /** USB transaction outcome. */ -
uspace/lib/usb/include/usb/usbdrv.h
r8f748215 r93fb170c 41 41 #include <usb/descriptor.h> 42 42 43 int usb_drv_hc_connect(device_t *, unsigned int); 43 int usb_drv_find_hc(device_t *, devman_handle_t *); 44 int usb_drv_hc_connect(device_t *, devman_handle_t, unsigned int); 45 int usb_drv_hc_connect_auto(device_t *, unsigned int); 44 46 45 47 int usb_drv_reserve_default_address(int); … … 94 96 int usb_drv_async_wait_for(usb_handle_t); 95 97 98 int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *, 99 const usb_standard_device_descriptor_t *); 100 int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *, 101 const void *, size_t); 102 96 103 int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t); 97 104 int usb_drv_register_child_in_devman(int, device_t *, usb_address_t, -
uspace/lib/usb/src/addrkeep.c
r8f748215 r93fb170c 187 187 new_address_position = addresses->used_addresses.next; 188 188 } else { 189 usb_address_keeping_used_t *first 190 = used_address_get_instance(addresses->used_addresses.next); 191 previous_address = first->address; 192 189 193 for_all_used_addresses(new_address_position, addresses) { 190 194 usb_address_keeping_used_t *info … … 194 198 break; 195 199 } 200 previous_address = info->address; 196 201 } 197 202 -
uspace/lib/usb/src/hcdhubd.c
r8f748215 r93fb170c 36 36 #include <usb/devreq.h> 37 37 #include <usbhc_iface.h> 38 #include <usb_iface.h> 38 39 #include <usb/descriptor.h> 39 40 #include <driver.h> … … 45 46 #include "hcdhubd_private.h" 46 47 48 49 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 50 { 51 assert(dev); 52 assert(dev->parent != NULL); 53 54 device_t *parent = dev->parent; 55 56 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 57 usb_iface_t *usb_iface 58 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 59 assert(usb_iface != NULL); 60 if (usb_iface->get_hc_handle) { 61 int rc = usb_iface->get_hc_handle(parent, handle); 62 return rc; 63 } 64 } 65 66 return ENOTSUP; 67 } 68 69 static usb_iface_t usb_iface = { 70 .get_hc_handle = usb_iface_get_hc_handle 71 }; 72 73 static device_ops_t child_ops = { 74 .interfaces[USB_DEV_IFACE] = &usb_iface 75 }; 76 47 77 /** Callback when new device is detected and must be handled by this driver. 48 78 * … … 129 159 } 130 160 child->name = child_info->name; 161 child->parent = child_info->parent; 162 child->ops = &child_ops; 131 163 132 164 match_id = create_match_id(); -
uspace/lib/usb/src/recognise.c
r8f748215 r93fb170c 33 33 * @brief Functions for recognising kind of attached devices. 34 34 */ 35 #include <usb_iface.h> 35 36 #include <usb/usbdrv.h> 36 37 #include <usb/classes/classes.h> … … 38 39 #include <errno.h> 39 40 41 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle) 42 { 43 assert(dev); 44 assert(dev->parent != NULL); 45 46 device_t *parent = dev->parent; 47 48 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 49 usb_iface_t *usb_iface 50 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 51 assert(usb_iface != NULL); 52 if (usb_iface->get_hc_handle) { 53 int rc = usb_iface->get_hc_handle(parent, handle); 54 return rc; 55 } 56 } 57 58 return ENOTSUP; 59 } 60 61 static usb_iface_t usb_iface = { 62 .get_hc_handle = usb_iface_get_hc_handle 63 }; 64 65 static device_ops_t child_ops = { 66 .interfaces[USB_DEV_IFACE] = &usb_iface 67 }; 40 68 41 69 #define BCD_INT(a) (((unsigned int)(a)) / 256) … … 99 127 100 128 return rc; 129 } 130 131 /** Create DDF match ids from USB device descriptor. 132 * 133 * @param matches List of match ids to extend. 134 * @param device_descriptor Device descriptor returned by given device. 135 * @return Error code. 136 */ 137 int usb_drv_create_match_ids_from_device_descriptor( 138 match_id_list_t *matches, 139 const usb_standard_device_descriptor_t *device_descriptor) 140 { 141 int rc; 142 143 /* 144 * Unless the vendor id is 0, the pair idVendor-idProduct 145 * quite uniquely describes the device. 146 */ 147 if (device_descriptor->vendor_id != 0) { 148 /* First, with release number. */ 149 rc = usb_add_match_id(matches, 100, 150 "usb&vendor=%d&product=%d&release=" BCD_FMT, 151 (int) device_descriptor->vendor_id, 152 (int) device_descriptor->product_id, 153 BCD_ARGS(device_descriptor->device_version)); 154 if (rc != EOK) { 155 return rc; 156 } 157 158 /* Next, without release number. */ 159 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d", 160 (int) device_descriptor->vendor_id, 161 (int) device_descriptor->product_id); 162 if (rc != EOK) { 163 return rc; 164 } 165 } 166 167 /* 168 * If the device class points to interface we skip adding 169 * class directly. 170 */ 171 if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) { 172 rc = usb_add_match_id(matches, 50, "usb&class=%s", 173 usb_str_class(device_descriptor->device_class)); 174 if (rc != EOK) { 175 return rc; 176 } 177 } 178 179 return EOK; 180 } 181 182 /** Create DDF match ids from USB configuration descriptor. 183 * The configuration descriptor is expected to be in the complete form, 184 * i.e. including interface, endpoint etc. descriptors. 185 * 186 * @param matches List of match ids to extend. 187 * @param config_descriptor Configuration descriptor returned by given device. 188 * @param total_size Size of the @p config_descriptor. 189 * @return Error code. 190 */ 191 int usb_drv_create_match_ids_from_configuration_descriptor( 192 match_id_list_t *matches, 193 const void *config_descriptor, size_t total_size) 194 { 195 /* 196 * Iterate through config descriptor to find the interface 197 * descriptors. 198 */ 199 size_t position = sizeof(usb_standard_configuration_descriptor_t); 200 while (position + 1 < total_size) { 201 uint8_t *current_descriptor 202 = ((uint8_t *) config_descriptor) + position; 203 uint8_t cur_descr_len = current_descriptor[0]; 204 uint8_t cur_descr_type = current_descriptor[1]; 205 206 position += cur_descr_len; 207 208 if (cur_descr_type != USB_DESCTYPE_INTERFACE) { 209 continue; 210 } 211 212 /* 213 * Finally, we found an interface descriptor. 214 */ 215 usb_standard_interface_descriptor_t *interface 216 = (usb_standard_interface_descriptor_t *) 217 current_descriptor; 218 219 int rc = usb_add_match_id(matches, 50, 220 "usb&interface&class=%s", 221 usb_str_class(interface->interface_class)); 222 if (rc != EOK) { 223 return rc; 224 } 225 } 226 227 return EOK; 101 228 } 102 229 … … 141 268 continue; 142 269 } 143 144 /* 145 * Iterate through config descriptor to find the interface 146 * descriptors. 147 */ 148 size_t position = sizeof(config_descriptor); 149 while (position + 1 < full_config_descriptor_size) { 150 uint8_t *current_descriptor 151 = ((uint8_t *) full_config_descriptor) + position; 152 uint8_t cur_descr_len = current_descriptor[0]; 153 uint8_t cur_descr_type = current_descriptor[1]; 154 155 position += cur_descr_len; 156 157 if (cur_descr_type != USB_DESCTYPE_INTERFACE) { 158 continue; 159 } 160 /* 161 * Finally, we found an interface descriptor. 162 */ 163 usb_standard_interface_descriptor_t *interface 164 = (usb_standard_interface_descriptor_t *) 165 current_descriptor; 166 167 rc = usb_add_match_id(matches, 50, 168 "usb&interface&class=%s", 169 usb_str_class(interface->interface_class)); 170 if (rc != EOK) { 171 final_rc = rc; 172 break; 173 } 174 } 270 271 rc = usb_drv_create_match_ids_from_configuration_descriptor( 272 matches, 273 full_config_descriptor, full_config_descriptor_size); 274 if (rc != EOK) { 275 final_rc = rc; 276 continue; 277 } 278 175 279 } 176 280 … … 192 296 { 193 297 int rc; 298 299 /* 300 * Retrieve device descriptor and add matches from it. 301 */ 194 302 usb_standard_device_descriptor_t device_descriptor; 195 303 … … 199 307 return rc; 200 308 } 201 202 /* 203 * Unless the vendor id is 0, the pair idVendor-idProduct 204 * quite uniquely describes the device. 205 */ 206 if (device_descriptor.vendor_id != 0) { 207 /* First, with release number. */ 208 rc = usb_add_match_id(matches, 100, 209 "usb&vendor=%d&product=%d&release=" BCD_FMT, 210 (int) device_descriptor.vendor_id, 211 (int) device_descriptor.product_id, 212 BCD_ARGS(device_descriptor.device_version)); 213 if (rc != EOK) { 214 return rc; 215 } 216 217 /* Next, without release number. */ 218 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d", 219 (int) device_descriptor.vendor_id, 220 (int) device_descriptor.product_id); 221 if (rc != EOK) { 222 return rc; 223 } 224 225 } 226 227 /* 228 * If the device class points to interface we skip adding 229 * class directly. 230 */ 231 if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) { 232 rc = usb_add_match_id(matches, 50, "usb&class=%s", 233 usb_str_class(device_descriptor.device_class)); 234 if (rc != EOK) { 235 return rc; 236 } 237 } 309 310 rc = usb_drv_create_match_ids_from_device_descriptor(matches, 311 &device_descriptor); 312 if (rc != EOK) { 313 return rc; 314 } 315 238 316 /* 239 317 * Go through all configurations and add matches … … 285 363 goto failure; 286 364 } 365 child->parent = parent; 287 366 child->name = child_name; 367 child->ops = &child_ops; 288 368 289 369 rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address); -
uspace/lib/usb/src/usbdrv.c
r8f748215 r93fb170c 35 35 #include <usb/usbdrv.h> 36 36 #include <usbhc_iface.h> 37 #include <usb_iface.h> 37 38 #include <errno.h> 38 39 #include <str_error.h> … … 54 55 } transfer_info_t; 55 56 57 /** Find handle of host controller the device is physically attached to. 58 * 59 * @param[in] dev Device looking for its host controller. 60 * @param[out] handle Host controller devman handle. 61 * @return Error code. 62 */ 63 int usb_drv_find_hc(device_t *dev, devman_handle_t *handle) 64 { 65 if (dev == NULL) { 66 return EBADMEM; 67 } 68 if (handle == NULL) { 69 return EBADMEM; 70 } 71 72 int parent_phone = devman_parent_device_connect(dev->handle, 73 IPC_FLAG_BLOCKING); 74 if (parent_phone < 0) { 75 return parent_phone; 76 } 77 78 devman_handle_t h; 79 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 80 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h); 81 82 ipc_hangup(parent_phone); 83 84 if (rc != EOK) { 85 return rc; 86 } 87 88 *handle = h; 89 90 return EOK; 91 } 92 93 /** Connect to host controller the device is physically attached to. 94 * 95 * @param dev Device asking for connection. 96 * @param hc_handle Devman handle of the host controller. 97 * @param flags Connection flags (blocking connection). 98 * @return Phone to the HC or error code. 99 */ 100 int usb_drv_hc_connect(device_t *dev, devman_handle_t hc_handle, 101 unsigned int flags) 102 { 103 return devman_device_connect(hc_handle, flags); 104 } 105 56 106 /** Connect to host controller the device is physically attached to. 57 107 * … … 60 110 * @return Phone to corresponding HC or error code. 61 111 */ 62 int usb_drv_hc_connect(device_t *dev, unsigned int flags) 63 { 112 int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags) 113 { 114 int rc; 115 devman_handle_t hc_handle; 116 64 117 /* 65 118 * Call parent hub to obtain device handle of respective HC. 66 119 */ 67 68 /* 69 * FIXME: currently we connect always to virtual host controller. 70 */ 71 int rc; 72 devman_handle_t handle; 73 74 rc = devman_device_get_handle("/virt/usbhc", &handle, flags); 120 rc = usb_drv_find_hc(dev, &hc_handle); 75 121 if (rc != EOK) { 76 122 return rc; 77 123 } 78 124 79 int phone = devman_device_connect(handle, flags); 80 81 return phone; 125 return usb_drv_hc_connect(dev, hc_handle, flags); 82 126 } 83 127 -
uspace/lib/usb/src/usbdrvreq.c
r8f748215 r93fb170c 73 73 } 74 74 75 /** Retrieve device descriptor of connected USB device. 76 * 77 * @param[in] phone Open phone to HC driver. 78 * @param[in] address Device USB address. 79 * @param[out] descriptor Storage for the device descriptor. 80 * @return Error code. 81 * @retval EBADMEM @p descriptor is NULL. 82 */ 83 int usb_drv_req_get_device_descriptor(int phone, usb_address_t address, 84 usb_standard_device_descriptor_t *descriptor) 85 { 86 if (descriptor == NULL) { 87 return EBADMEM; 88 } 89 75 /** Retrieve USB descriptor of connected USB device. 76 * 77 * @param[in] hc_phone Open phone to HC driver. 78 * @param[in] address Device USB address. 79 * @param[in] request_type Request type (standard/class/vendor). 80 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 81 * @param[in] descriptor_index Descriptor index. 82 * @param[in] langauge Language index. 83 * @param[out] buffer Buffer where to store the retrieved descriptor. 84 * @param[in] size Size of the @p buffer. 85 * @param[out] actual_size Number of bytes actually transferred. 86 * @return Error code. 87 */ 88 int usb_drv_req_get_descriptor(int hc_phone, usb_address_t address, 89 usb_request_type_t request_type, 90 uint8_t descriptor_type, uint8_t descriptor_index, 91 uint16_t language, 92 void *buffer, size_t size, size_t *actual_size) 93 { 90 94 /* Prepare the target. */ 91 95 usb_target_t target = { … … 96 100 /* Prepare the setup packet. */ 97 101 usb_device_request_setup_packet_t setup_packet = { 98 .request_type = 128 ,102 .request_type = 128 | (request_type << 5), 99 103 .request = USB_DEVREQ_GET_DESCRIPTOR, 100 .index = 0, 101 .length = sizeof(usb_standard_device_descriptor_t) 102 }; 103 setup_packet.value_high = USB_DESCTYPE_DEVICE; 104 setup_packet.value_low = 0; 105 106 /* Prepare local descriptor. */ 104 .index = language, 105 .length = (uint16_t) size, 106 }; 107 setup_packet.value_high = descriptor_type; 108 setup_packet.value_low = descriptor_index; 109 110 /* Perform CONTROL READ */ 111 int rc = usb_drv_psync_control_read(hc_phone, target, 112 &setup_packet, sizeof(setup_packet), 113 buffer, size, actual_size); 114 115 return rc; 116 } 117 118 /** Retrieve device descriptor of connected USB device. 119 * 120 * @param[in] phone Open phone to HC driver. 121 * @param[in] address Device USB address. 122 * @param[out] descriptor Storage for the device descriptor. 123 * @return Error code. 124 * @retval EBADMEM @p descriptor is NULL. 125 */ 126 int usb_drv_req_get_device_descriptor(int phone, usb_address_t address, 127 usb_standard_device_descriptor_t *descriptor) 128 { 129 if (descriptor == NULL) { 130 return EBADMEM; 131 } 132 107 133 size_t actually_transferred = 0; 108 134 usb_standard_device_descriptor_t descriptor_tmp; 109 110 /* Perform the control read transaction. */ 111 int rc = usb_drv_psync_control_read(phone, target, 112 &setup_packet, sizeof(setup_packet), 113 &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred); 135 int rc = usb_drv_req_get_descriptor(phone, address, 136 USB_REQUEST_TYPE_STANDARD, 137 USB_DESCTYPE_DEVICE, 0, 138 0, 139 &descriptor_tmp, sizeof(descriptor_tmp), 140 &actually_transferred); 114 141 115 142 if (rc != EOK) { … … 150 177 return EBADMEM; 151 178 } 152 153 /* Prepare the target. */ 154 usb_target_t target = { 155 .address = address, 156 .endpoint = 0 157 }; 158 159 /* Prepare the setup packet. */ 160 usb_device_request_setup_packet_t setup_packet = { 161 .request_type = 128, 162 .request = USB_DEVREQ_GET_DESCRIPTOR, 163 .index = 0, 164 .length = sizeof(usb_standard_configuration_descriptor_t) 165 }; 166 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; 167 setup_packet.value_low = index; 168 169 /* Prepare local descriptor. */ 179 170 180 size_t actually_transferred = 0; 171 181 usb_standard_configuration_descriptor_t descriptor_tmp; 172 173 /* Perform the control read transaction. */ 174 int rc = usb_drv_psync_control_read(phone, target, 175 &setup_packet, sizeof(setup_packet), 176 &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred); 182 int rc = usb_drv_req_get_descriptor(phone, address, 183 USB_REQUEST_TYPE_STANDARD, 184 USB_DESCTYPE_CONFIGURATION, 0, 185 0, 186 &descriptor_tmp, sizeof(descriptor_tmp), 187 &actually_transferred); 177 188 178 189 if (rc != EOK) { … … 214 225 } 215 226 216 /* Prepare the target. */ 217 usb_target_t target = { 218 .address = address, 219 .endpoint = 0 220 }; 221 222 /* Prepare the setup packet. */ 223 usb_device_request_setup_packet_t setup_packet = { 224 .request_type = 128, 225 .request = USB_DEVREQ_GET_DESCRIPTOR, 226 .index = 0, 227 .length = buffer_size 228 }; 229 setup_packet.value_high = USB_DESCTYPE_CONFIGURATION; 230 setup_packet.value_low = index; 231 232 /* Perform the control read transaction. */ 233 int rc = usb_drv_psync_control_read(phone, target, 234 &setup_packet, sizeof(setup_packet), 235 buffer, buffer_size, actual_buffer_size); 227 int rc = usb_drv_req_get_descriptor(phone, address, 228 USB_REQUEST_TYPE_STANDARD, 229 USB_DESCTYPE_CONFIGURATION, 0, 230 0, 231 buffer, buffer_size, 232 actual_buffer_size); 236 233 237 234 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.
