Changeset ace12560 in mainline for uspace/lib/usb
- Timestamp:
- 2011-02-20T21:52:43Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b317b0b, d37b235
- Parents:
- 62066b4 (diff), 41e645c (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:
-
- 2 added
- 11 edited
-
Makefile (modified) (1 diff)
-
include/usb/ddfiface.h (added)
-
include/usb/dp.h (modified) (1 diff)
-
include/usb/pipes.h (modified) (2 diffs)
-
include/usb/recognise.h (modified) (1 diff)
-
include/usb/usbdrv.h (modified) (1 diff)
-
src/ddfiface.c (added)
-
src/dp.c (modified) (1 diff)
-
src/hub.c (modified) (1 diff)
-
src/pipes.c (modified) (6 diffs)
-
src/pipesinit.c (modified) (3 diffs)
-
src/pipesio.c (modified) (2 diffs)
-
src/recognise.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/Makefile
r62066b4 race12560 35 35 src/addrkeep.c \ 36 36 src/class.c \ 37 src/ddfiface.c \ 37 38 src/debug.c \ 38 39 src/dp.c \ -
uspace/lib/usb/include/usb/dp.h
r62066b4 race12560 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
r62066b4 race12560 107 107 /** Endpoint description. */ 108 108 const usb_endpoint_description_t *description; 109 /** Interface number the endpoint must belong to (-1 for any). */ 110 const int interface_no; 109 111 /** Found descriptor fitting the description. */ 110 112 usb_standard_endpoint_descriptor_t *descriptor; … … 121 123 int usb_device_connection_initialize(usb_device_connection_t *, 122 124 devman_handle_t, usb_address_t); 125 126 int usb_device_get_assigned_interface(device_t *); 123 127 124 128 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, -
uspace/lib/usb/include/usb/recognise.h
r62066b4 race12560 41 41 #include <ipc/devman.h> 42 42 43 int usb_device_create_match_ids_from_interface( 44 const usb_standard_device_descriptor_t *, 45 const usb_standard_interface_descriptor_t *, match_id_list_t *); 46 43 47 int usb_device_create_match_ids(usb_endpoint_pipe_t *, match_id_list_t *); 44 48 -
uspace/lib/usb/include/usb/usbdrv.h
r62066b4 race12560 103 103 int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *, 104 104 const usb_standard_device_descriptor_t *); 105 int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *,106 const void *, size_t);107 108 105 109 106 #endif -
uspace/lib/usb/src/dp.c
r62066b4 race12560 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/hub.c
r62066b4 race12560 301 301 } 302 302 303 304 303 /** 305 304 * @} -
uspace/lib/usb/src/pipes.c
r62066b4 race12560 36 36 #include <usb/pipes.h> 37 37 #include <usbhc_iface.h> 38 #include <usb_iface.h> 38 39 #include <errno.h> 39 40 #include <assert.h> … … 41 42 /** Tell USB address assigned to given device. 42 43 * 43 * @param phone Phone to my HC.44 * @param phone Phone to parent device. 44 45 * @param dev Device in question. 45 46 * @return USB address or error code. … … 48 49 { 49 50 sysarg_t address; 50 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB HC_DEV_IFACE),51 IPC_M_USB HC_GET_ADDRESS,51 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 52 IPC_M_USB_GET_ADDRESS, 52 53 dev->handle, &address); 53 54 … … 57 58 58 59 return (usb_address_t) address; 60 } 61 62 /** Tell USB interface assigned to given device. 63 * 64 * @param device Device in question. 65 * @return Interface number (negative code means any). 66 */ 67 int usb_device_get_assigned_interface(device_t *device) 68 { 69 int parent_phone = devman_parent_device_connect(device->handle, 70 IPC_FLAG_BLOCKING); 71 if (parent_phone < 0) { 72 return -1; 73 } 74 75 sysarg_t iface_no; 76 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 77 IPC_M_USB_GET_INTERFACE, 78 device->handle, &iface_no); 79 80 async_hangup(parent_phone); 81 82 if (rc != EOK) { 83 return -1; 84 } 85 86 return (int) iface_no; 59 87 } 60 88 … … 80 108 } 81 109 82 int hc_phone = devman_device_connect(hc_handle, 0); 83 if (hc_phone < 0) { 84 return hc_phone; 85 } 86 87 my_address = get_my_address(hc_phone, device); 110 int parent_phone = devman_parent_device_connect(device->handle, 111 IPC_FLAG_BLOCKING); 112 if (parent_phone < 0) { 113 return parent_phone; 114 } 115 116 my_address = get_my_address(parent_phone, device); 88 117 if (my_address < 0) { 89 118 rc = my_address; … … 95 124 96 125 leave: 97 async_hangup( hc_phone);126 async_hangup(parent_phone); 98 127 return rc; 99 128 } -
uspace/lib/usb/src/pipesinit.c
r62066b4 race12560 109 109 * @param mapping_count Number of endpoint mappings in @p mapping. 110 110 * @param found_endpoint Description of found endpoint. 111 * @param interface_number Number of currently processed interface. 111 112 * @return Endpoint mapping corresponding to @p found_endpoint. 112 113 * @retval NULL No corresponding endpoint found. … … 114 115 static usb_endpoint_mapping_t *find_endpoint_mapping( 115 116 usb_endpoint_mapping_t *mapping, size_t mapping_count, 116 usb_endpoint_description_t *found_endpoint) 117 usb_endpoint_description_t *found_endpoint, 118 int interface_number) 117 119 { 118 120 while (mapping_count > 0) { 119 if (endpoint_fits_description(mapping->description, 120 found_endpoint)) { 121 bool interface_number_fits = (mapping->interface_no < 0) 122 || (mapping->interface_no == interface_number); 123 124 bool endpoint_descriptions_fits = endpoint_fits_description( 125 mapping->description, found_endpoint); 126 127 if (interface_number_fits && endpoint_descriptions_fits) { 121 128 return mapping; 122 129 } … … 169 176 */ 170 177 usb_endpoint_mapping_t *ep_mapping = find_endpoint_mapping(mapping, 171 mapping_count, &description );178 mapping_count, &description, interface->interface_number); 172 179 if (ep_mapping == NULL) { 173 180 return ENOENT; -
uspace/lib/usb/src/pipesio.c
r62066b4 race12560 71 71 ipc_method = IPC_M_USBHC_INTERRUPT_IN; 72 72 break; 73 case USB_TRANSFER_BULK: 74 ipc_method = IPC_M_USBHC_BULK_IN; 75 break; 73 76 default: 74 77 return ENOTSUP; … … 194 197 case USB_TRANSFER_INTERRUPT: 195 198 ipc_method = IPC_M_USBHC_INTERRUPT_OUT; 199 break; 200 case USB_TRANSFER_BULK: 201 ipc_method = IPC_M_USBHC_BULK_OUT; 196 202 break; 197 203 default: -
uspace/lib/usb/src/recognise.c
r62066b4 race12560 34 34 */ 35 35 #include <sys/types.h> 36 #include <usb_iface.h>37 36 #include <usb/usbdrv.h> 38 37 #include <usb/pipes.h> 39 38 #include <usb/recognise.h> 39 #include <usb/ddfiface.h> 40 40 #include <usb/request.h> 41 41 #include <usb/classes/classes.h> … … 46 46 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 47 47 48 /** Callback for getting host controller handle.49 *50 * @param dev Device in question.51 * @param[out] handle Devman handle of the host controller.52 * @return Error code.53 */54 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)55 {56 assert(dev);57 assert(dev->parent != NULL);58 59 device_t *parent = dev->parent;60 61 if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {62 usb_iface_t *usb_iface63 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];64 assert(usb_iface != NULL);65 if (usb_iface->get_hc_handle) {66 int rc = usb_iface->get_hc_handle(parent, handle);67 return rc;68 }69 }70 71 return ENOTSUP;72 }73 74 static usb_iface_t usb_iface = {75 .get_hc_handle = usb_iface_get_hc_handle76 };77 78 48 device_ops_t child_ops = { 79 .interfaces[USB_DEV_IFACE] = &usb_iface 49 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 80 50 }; 81 51 … … 142 112 } 143 113 114 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 115 do { \ 116 int __rc = usb_add_match_id((match_ids), (score), \ 117 format, ##__VA_ARGS__); \ 118 if (__rc != EOK) { \ 119 return __rc; \ 120 } \ 121 } while (0) 122 123 /** Create device match ids based on its interface. 124 * 125 * @param[in] descriptor Interface descriptor. 126 * @param[out] matches Initialized list of match ids. 127 * @return Error code (the two mentioned are not the only ones). 128 * @retval EINVAL Invalid input parameters (expects non NULL pointers). 129 * @retval ENOENT Interface does not specify class. 130 */ 131 int usb_device_create_match_ids_from_interface( 132 const usb_standard_device_descriptor_t *desc_device, 133 const usb_standard_interface_descriptor_t *desc_interface, 134 match_id_list_t *matches) 135 { 136 if (desc_interface == NULL) { 137 return EINVAL; 138 } 139 if (matches == NULL) { 140 return EINVAL; 141 } 142 143 if (desc_interface->interface_class == USB_CLASS_USE_INTERFACE) { 144 return ENOENT; 145 } 146 147 const char *classname = usb_str_class(desc_interface->interface_class); 148 assert(classname != NULL); 149 150 #define IFACE_PROTOCOL_FMT "interface&class=%s&subclass=0x%02x&protocol=0x%02x" 151 #define IFACE_PROTOCOL_ARGS classname, desc_interface->interface_subclass, \ 152 desc_interface->interface_protocol 153 154 #define IFACE_SUBCLASS_FMT "interface&class=%s&subclass=0x%02x" 155 #define IFACE_SUBCLASS_ARGS classname, desc_interface->interface_subclass 156 157 #define IFACE_CLASS_FMT "interface&class=%s" 158 #define IFACE_CLASS_ARGS classname 159 160 #define VENDOR_RELEASE_FMT "vendor=0x%04x&product=0x%04x&release=" BCD_FMT 161 #define VENDOR_RELEASE_ARGS desc_device->vendor_id, desc_device->product_id, \ 162 BCD_ARGS(desc_device->device_version) 163 164 #define VENDOR_PRODUCT_FMT "vendor=0x%04x&product=0x%04x" 165 #define VENDOR_PRODUCT_ARGS desc_device->vendor_id, desc_device->product_id 166 167 #define VENDOR_ONLY_FMT "vendor=0x%04x" 168 #define VENDOR_ONLY_ARGS desc_device->vendor_id 169 170 /* 171 * If the vendor is specified, create match ids with vendor with 172 * higher score. 173 * Then the same ones without the vendor part. 174 */ 175 if ((desc_device != NULL) && (desc_device->vendor_id != 0)) { 176 /* First, interface matches with device release number. */ 177 ADD_MATCHID_OR_RETURN(matches, 250, 178 "usb&" VENDOR_RELEASE_FMT "&" IFACE_PROTOCOL_FMT, 179 VENDOR_RELEASE_ARGS, IFACE_PROTOCOL_ARGS); 180 ADD_MATCHID_OR_RETURN(matches, 240, 181 "usb&" VENDOR_RELEASE_FMT "&" IFACE_SUBCLASS_FMT, 182 VENDOR_RELEASE_ARGS, IFACE_SUBCLASS_ARGS); 183 ADD_MATCHID_OR_RETURN(matches, 230, 184 "usb&" VENDOR_RELEASE_FMT "&" IFACE_CLASS_FMT, 185 VENDOR_RELEASE_ARGS, IFACE_CLASS_ARGS); 186 187 /* Next, interface matches without release number. */ 188 ADD_MATCHID_OR_RETURN(matches, 220, 189 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_PROTOCOL_FMT, 190 VENDOR_PRODUCT_ARGS, IFACE_PROTOCOL_ARGS); 191 ADD_MATCHID_OR_RETURN(matches, 210, 192 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_SUBCLASS_FMT, 193 VENDOR_PRODUCT_ARGS, IFACE_SUBCLASS_ARGS); 194 ADD_MATCHID_OR_RETURN(matches, 200, 195 "usb&" VENDOR_PRODUCT_FMT "&" IFACE_CLASS_FMT, 196 VENDOR_PRODUCT_ARGS, IFACE_CLASS_ARGS); 197 198 /* Finally, interface matches with only vendor. */ 199 ADD_MATCHID_OR_RETURN(matches, 190, 200 "usb&" VENDOR_ONLY_FMT "&" IFACE_PROTOCOL_FMT, 201 VENDOR_ONLY_ARGS, IFACE_PROTOCOL_ARGS); 202 ADD_MATCHID_OR_RETURN(matches, 180, 203 "usb&" VENDOR_ONLY_FMT "&" IFACE_SUBCLASS_FMT, 204 VENDOR_ONLY_ARGS, IFACE_SUBCLASS_ARGS); 205 ADD_MATCHID_OR_RETURN(matches, 170, 206 "usb&" VENDOR_ONLY_FMT "&" IFACE_CLASS_FMT, 207 VENDOR_ONLY_ARGS, IFACE_CLASS_ARGS); 208 } 209 210 /* Now, the same but without any vendor specification. */ 211 ADD_MATCHID_OR_RETURN(matches, 160, 212 "usb&" IFACE_PROTOCOL_FMT, 213 IFACE_PROTOCOL_ARGS); 214 ADD_MATCHID_OR_RETURN(matches, 150, 215 "usb&" IFACE_SUBCLASS_FMT, 216 IFACE_SUBCLASS_ARGS); 217 ADD_MATCHID_OR_RETURN(matches, 140, 218 "usb&" IFACE_CLASS_FMT, 219 IFACE_CLASS_ARGS); 220 221 #undef IFACE_PROTOCOL_FMT 222 #undef IFACE_PROTOCOL_ARGS 223 #undef IFACE_SUBCLASS_FMT 224 #undef IFACE_SUBCLASS_ARGS 225 #undef IFACE_CLASS_FMT 226 #undef IFACE_CLASS_ARGS 227 #undef VENDOR_RELEASE_FMT 228 #undef VENDOR_RELEASE_ARGS 229 #undef VENDOR_PRODUCT_FMT 230 #undef VENDOR_PRODUCT_ARGS 231 #undef VENDOR_ONLY_FMT 232 #undef VENDOR_ONLY_ARGS 233 234 return EOK; 235 } 236 144 237 /** Create DDF match ids from USB device descriptor. 145 238 * … … 152 245 const usb_standard_device_descriptor_t *device_descriptor) 153 246 { 154 int rc;155 156 247 /* 157 248 * Unless the vendor id is 0, the pair idVendor-idProduct … … 160 251 if (device_descriptor->vendor_id != 0) { 161 252 /* First, with release number. */ 162 rc = usb_add_match_id(matches, 100,253 ADD_MATCHID_OR_RETURN(matches, 100, 163 254 "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT, 164 255 (int) device_descriptor->vendor_id, 165 256 (int) device_descriptor->product_id, 166 257 BCD_ARGS(device_descriptor->device_version)); 167 if (rc != EOK) {168 return rc;169 }170 258 171 259 /* Next, without release number. */ 172 rc = usb_add_match_id(matches, 90,260 ADD_MATCHID_OR_RETURN(matches, 90, 173 261 "usb&vendor=0x%04x&product=0x%04x", 174 262 (int) device_descriptor->vendor_id, 175 263 (int) device_descriptor->product_id); 176 if (rc != EOK) {177 return rc;178 }179 264 } 180 265 181 266 /* 182 267 * If the device class points to interface we skip adding 183 * class directly .268 * class directly but we add a multi interface device. 184 269 */ 185 270 if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) { 186 rc = usb_add_match_id(matches, 50, "usb&class=%s",271 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s", 187 272 usb_str_class(device_descriptor->device_class)); 188 if (rc != EOK) { 189 return rc; 190 } 273 } else { 274 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid"); 191 275 } 192 276 … … 194 278 } 195 279 196 /** Create DDF match ids from USB configuration descriptor.197 * The configuration descriptor is expected to be in the complete form,198 * i.e. including interface, endpoint etc. descriptors.199 *200 * @param matches List of match ids to extend.201 * @param config_descriptor Configuration descriptor returned by given device.202 * @param total_size Size of the @p config_descriptor.203 * @return Error code.204 */205 int usb_drv_create_match_ids_from_configuration_descriptor(206 match_id_list_t *matches,207 const void *config_descriptor, size_t total_size)208 {209 /*210 * Iterate through config descriptor to find the interface211 * descriptors.212 */213 size_t position = sizeof(usb_standard_configuration_descriptor_t);214 while (position + 1 < total_size) {215 uint8_t *current_descriptor216 = ((uint8_t *) config_descriptor) + position;217 uint8_t cur_descr_len = current_descriptor[0];218 uint8_t cur_descr_type = current_descriptor[1];219 220 if (cur_descr_len == 0) {221 return ENOENT;222 }223 224 position += cur_descr_len;225 226 if (cur_descr_type != USB_DESCTYPE_INTERFACE) {227 continue;228 }229 230 /*231 * Finally, we found an interface descriptor.232 */233 usb_standard_interface_descriptor_t *interface234 = (usb_standard_interface_descriptor_t *)235 current_descriptor;236 237 int rc = usb_add_match_id(matches, 50,238 "usb&interface&class=%s",239 usb_str_class(interface->interface_class));240 if (rc != EOK) {241 return rc;242 }243 }244 245 return EOK;246 }247 248 /** Add match ids based on configuration descriptor.249 *250 * @param pipe Control pipe to the device.251 * @param matches Match ids list to add matches to.252 * @param config_count Number of configurations the device has.253 * @return Error code.254 */255 static int usb_add_config_descriptor_match_ids(usb_endpoint_pipe_t *pipe,256 match_id_list_t *matches, int config_count)257 {258 int final_rc = EOK;259 260 int config_index;261 for (config_index = 0; config_index < config_count; config_index++) {262 int rc;263 usb_standard_configuration_descriptor_t config_descriptor;264 rc = usb_request_get_bare_configuration_descriptor(pipe,265 config_index, &config_descriptor);266 if (rc != EOK) {267 final_rc = rc;268 continue;269 }270 271 size_t full_config_descriptor_size;272 void *full_config_descriptor273 = malloc(config_descriptor.total_length);274 rc = usb_request_get_full_configuration_descriptor(pipe,275 config_index,276 full_config_descriptor, config_descriptor.total_length,277 &full_config_descriptor_size);278 if (rc != EOK) {279 final_rc = rc;280 continue;281 }282 if (full_config_descriptor_size283 != config_descriptor.total_length) {284 final_rc = ERANGE;285 continue;286 }287 288 rc = usb_drv_create_match_ids_from_configuration_descriptor(289 matches,290 full_config_descriptor, full_config_descriptor_size);291 if (rc != EOK) {292 final_rc = rc;293 continue;294 }295 296 }297 298 return final_rc;299 }300 280 301 281 /** Create match ids describing attached device. … … 330 310 331 311 /* 332 * Go through all configurations and add matches333 * based on interface class.334 */335 rc = usb_add_config_descriptor_match_ids(ctrl_pipe, matches,336 device_descriptor.configuration_count);337 if (rc != EOK) {338 return rc;339 }340 341 /*342 312 * As a fallback, provide the simplest match id possible. 343 313 */ 344 rc = usb_add_match_id(matches, 1, "usb&fallback"); 345 if (rc != EOK) { 346 return rc; 347 } 314 ADD_MATCHID_OR_RETURN(matches, 1, "usb&fallback"); 348 315 349 316 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.
