Changeset 7526e3d in mainline
- Timestamp:
- 2011-04-03T16:34:31Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 159b91f4
- Parents:
- bb18a59
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/devdrv.h
rbb18a59 r7526e3d 47 47 } usb_device_descriptors_t; 48 48 49 /** Wrapper for data related to alternate interface setting. 50 * The pointers will typically point inside configuration descriptor and 51 * thus you shall not deallocate them. 52 */ 53 typedef struct { 54 /** Interface descriptor. */ 55 usb_standard_interface_descriptor_t *interface; 56 /** Pointer to start of descriptor tree bound with this interface. */ 57 uint8_t *nested_descriptors; 58 /** Size of data pointed by nested_descriptors in bytes. */ 59 size_t nested_descriptors_size; 60 } usb_alternate_interface_descriptors_t; 61 62 /** Alternate interface settings. */ 63 typedef struct { 64 /** Array of alternate interfaces descriptions. */ 65 usb_alternate_interface_descriptors_t *alternatives; 66 /** Size of @c alternatives array. */ 67 size_t alternative_count; 68 /** Index of currently selected one. */ 69 size_t current; 70 } usb_alternate_interfaces_t; 71 49 72 /** USB device structure. */ 50 73 typedef struct { … … 61 84 */ 62 85 int interface_no; 86 87 /** Alternative interfaces. 88 * Set to NULL when the driver controls whole device 89 * (i.e. more (or any) interfaces). 90 */ 91 usb_alternate_interfaces_t *alternate_interfaces; 63 92 64 93 /** Some useful descriptors. */ … … 132 161 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *); 133 162 134 135 163 int usb_device_auto_poll(usb_device_t *, size_t, 136 164 usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *); -
uspace/lib/usb/src/devdrv.c
rbb18a59 r7526e3d 36 36 #include <usb/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/dp.h> 38 39 #include <errno.h> 39 40 #include <str_error.h> … … 275 276 } 276 277 278 /** Count number of alternate settings of a interface. 279 * 280 * @param config_descr Full configuration descriptor. 281 * @param config_descr_size Size of @p config_descr in bytes. 282 * @param interface_no Interface number. 283 * @return Number of alternate interfaces for @p interface_no interface. 284 */ 285 static size_t count_alternate_interfaces(uint8_t *config_descr, 286 size_t config_descr_size, int interface_no) 287 { 288 assert(config_descr != NULL); 289 usb_dp_parser_t dp_parser = { 290 .nesting = usb_dp_standard_descriptor_nesting 291 }; 292 usb_dp_parser_data_t dp_data = { 293 .data = config_descr, 294 .size = config_descr_size, 295 .arg = NULL 296 }; 297 298 size_t alternate_count = 0; 299 300 uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser, 301 &dp_data, config_descr); 302 while (iface_ptr != NULL) { 303 usb_standard_interface_descriptor_t *iface 304 = (usb_standard_interface_descriptor_t *) iface_ptr; 305 if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) { 306 if (iface->interface_number == interface_no) { 307 alternate_count++; 308 } 309 } 310 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 311 config_descr, iface_ptr); 312 } 313 314 return alternate_count; 315 } 316 317 /** Initialize structures related to alternate interfaces. 318 * 319 * @param dev Device where alternate settings shall be initialized. 320 * @return Error code. 321 */ 322 static int initialize_alternate_interfaces(usb_device_t *dev) 323 { 324 if (dev->interface_no < 0) { 325 dev->alternate_interfaces = NULL; 326 return EOK; 327 } 328 329 usb_alternate_interfaces_t *alternates 330 = malloc(sizeof(usb_alternate_interfaces_t)); 331 332 if (alternates == NULL) { 333 return ENOMEM; 334 } 335 336 alternates->alternative_count 337 = count_alternate_interfaces(dev->descriptors.configuration, 338 dev->descriptors.configuration_size, dev->interface_no); 339 340 if (alternates->alternative_count == 0) { 341 free(alternates); 342 return ENOENT; 343 } 344 345 alternates->alternatives = malloc(alternates->alternative_count 346 * sizeof(usb_alternate_interface_descriptors_t)); 347 if (alternates->alternatives == NULL) { 348 free(alternates); 349 return ENOMEM; 350 } 351 352 alternates->current = 0; 353 354 usb_dp_parser_t dp_parser = { 355 .nesting = usb_dp_standard_descriptor_nesting 356 }; 357 usb_dp_parser_data_t dp_data = { 358 .data = dev->descriptors.configuration, 359 .size = dev->descriptors.configuration_size, 360 .arg = NULL 361 }; 362 363 usb_alternate_interface_descriptors_t *cur_alt_iface 364 = &alternates->alternatives[0]; 365 366 uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser, 367 &dp_data, dp_data.data); 368 while (iface_ptr != NULL) { 369 usb_standard_interface_descriptor_t *iface 370 = (usb_standard_interface_descriptor_t *) iface_ptr; 371 if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE) 372 || (iface->interface_number != dev->interface_no)) { 373 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, 374 &dp_data, 375 dp_data.data, iface_ptr); 376 continue; 377 } 378 379 cur_alt_iface->interface = iface; 380 cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface); 381 382 /* Find next interface to count size of nested descriptors. */ 383 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 384 dp_data.data, iface_ptr); 385 if (iface_ptr == NULL) { 386 uint8_t *next = dp_data.data + dp_data.size; 387 cur_alt_iface->nested_descriptors_size 388 = next - cur_alt_iface->nested_descriptors; 389 } else { 390 cur_alt_iface->nested_descriptors_size 391 = iface_ptr - cur_alt_iface->nested_descriptors; 392 } 393 394 cur_alt_iface++; 395 } 396 397 dev->alternate_interfaces = alternates; 398 399 return EOK; 400 } 401 277 402 /** Callback when new device is supposed to be controlled by this driver. 278 403 * … … 309 434 } 310 435 436 (void) initialize_alternate_interfaces(dev); 437 311 438 return driver->ops->add_device(dev); 312 439 }
Note:
See TracChangeset
for help on using the changeset viewer.