Deleted Added
full compact
usb_device.c (246363) usb_device.c (246616)
1/* $FreeBSD: head/sys/dev/usb/usb_device.c 246363 2013-02-05 14:44:25Z hselasky $ */
1/* $FreeBSD: head/sys/dev/usb/usb_device.c 246616 2013-02-10 10:56:13Z hselasky $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 445 unchanged lines hidden (view full) ---

455 *
456 * Flag values, see "USB_UNCFG_FLAG_XXX".
457 *------------------------------------------------------------------------*/
458static void
459usb_unconfigure(struct usb_device *udev, uint8_t flag)
460{
461 uint8_t do_unlock;
462
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 445 unchanged lines hidden (view full) ---

455 *
456 * Flag values, see "USB_UNCFG_FLAG_XXX".
457 *------------------------------------------------------------------------*/
458static void
459usb_unconfigure(struct usb_device *udev, uint8_t flag)
460{
461 uint8_t do_unlock;
462
463 /* automatic locking */
464 if (usbd_enum_is_locked(udev)) {
465 do_unlock = 0;
466 } else {
467 do_unlock = 1;
468 usbd_enum_lock(udev);
469 }
463 /* Prevent re-enumeration */
464 do_unlock = usbd_enum_lock(udev);
470
471 /* detach all interface drivers */
472 usb_detach_device(udev, USB_IFACE_INDEX_ANY, flag);
473
474#if USB_HAVE_UGEN
475 /* free all FIFOs except control endpoint FIFOs */
476 usb_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, flag);
477

--- 46 unchanged lines hidden (view full) ---

524 uint16_t power;
525 uint16_t max_power;
526 uint8_t selfpowered;
527 uint8_t do_unlock;
528 usb_error_t err;
529
530 DPRINTFN(6, "udev=%p index=%d\n", udev, index);
531
465
466 /* detach all interface drivers */
467 usb_detach_device(udev, USB_IFACE_INDEX_ANY, flag);
468
469#if USB_HAVE_UGEN
470 /* free all FIFOs except control endpoint FIFOs */
471 usb_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, flag);
472

--- 46 unchanged lines hidden (view full) ---

519 uint16_t power;
520 uint16_t max_power;
521 uint8_t selfpowered;
522 uint8_t do_unlock;
523 usb_error_t err;
524
525 DPRINTFN(6, "udev=%p index=%d\n", udev, index);
526
532 /* automatic locking */
533 if (usbd_enum_is_locked(udev)) {
534 do_unlock = 0;
535 } else {
536 do_unlock = 1;
537 usbd_enum_lock(udev);
538 }
527 /* Prevent re-enumeration */
528 do_unlock = usbd_enum_lock(udev);
539
540 usb_unconfigure(udev, 0);
541
542 if (index == USB_UNCONFIG_INDEX) {
543 /*
544 * Leave unallocated when unconfiguring the
545 * device. "usb_unconfigure()" will also reset
546 * the current config number and index.

--- 336 unchanged lines hidden (view full) ---

883usb_error_t
884usbd_set_alt_interface_index(struct usb_device *udev,
885 uint8_t iface_index, uint8_t alt_index)
886{
887 struct usb_interface *iface = usbd_get_iface(udev, iface_index);
888 usb_error_t err;
889 uint8_t do_unlock;
890
529
530 usb_unconfigure(udev, 0);
531
532 if (index == USB_UNCONFIG_INDEX) {
533 /*
534 * Leave unallocated when unconfiguring the
535 * device. "usb_unconfigure()" will also reset
536 * the current config number and index.

--- 336 unchanged lines hidden (view full) ---

873usb_error_t
874usbd_set_alt_interface_index(struct usb_device *udev,
875 uint8_t iface_index, uint8_t alt_index)
876{
877 struct usb_interface *iface = usbd_get_iface(udev, iface_index);
878 usb_error_t err;
879 uint8_t do_unlock;
880
891 /* automatic locking */
892 if (usbd_enum_is_locked(udev)) {
893 do_unlock = 0;
894 } else {
895 do_unlock = 1;
896 usbd_enum_lock(udev);
897 }
881 /* Prevent re-enumeration */
882 do_unlock = usbd_enum_lock(udev);
883
898 if (iface == NULL) {
899 err = USB_ERR_INVAL;
900 goto done;
901 }
902 if (iface->alt_index == alt_index) {
903 /*
904 * Optimise away duplicate setting of
905 * alternate setting in USB Host Mode!

--- 20 unchanged lines hidden (view full) ---

926 }
927
928 err = usbd_req_set_alt_interface_no(udev, NULL, iface_index,
929 iface->idesc->bAlternateSetting);
930
931done:
932 if (do_unlock)
933 usbd_enum_unlock(udev);
884 if (iface == NULL) {
885 err = USB_ERR_INVAL;
886 goto done;
887 }
888 if (iface->alt_index == alt_index) {
889 /*
890 * Optimise away duplicate setting of
891 * alternate setting in USB Host Mode!

--- 20 unchanged lines hidden (view full) ---

912 }
913
914 err = usbd_req_set_alt_interface_no(udev, NULL, iface_index,
915 iface->idesc->bAlternateSetting);
916
917done:
918 if (do_unlock)
919 usbd_enum_unlock(udev);
934
935 return (err);
936}
937
938/*------------------------------------------------------------------------*
939 * usbd_set_endpoint_stall
940 *
941 * This function is used to make a BULK or INTERRUPT endpoint send
942 * STALL tokens in USB device mode.

--- 362 unchanged lines hidden (view full) ---

1305 uint8_t i;
1306 uint8_t j;
1307 uint8_t do_unlock;
1308
1309 if (udev == NULL) {
1310 DPRINTF("udev == NULL\n");
1311 return (USB_ERR_INVAL);
1312 }
920 return (err);
921}
922
923/*------------------------------------------------------------------------*
924 * usbd_set_endpoint_stall
925 *
926 * This function is used to make a BULK or INTERRUPT endpoint send
927 * STALL tokens in USB device mode.

--- 362 unchanged lines hidden (view full) ---

1290 uint8_t i;
1291 uint8_t j;
1292 uint8_t do_unlock;
1293
1294 if (udev == NULL) {
1295 DPRINTF("udev == NULL\n");
1296 return (USB_ERR_INVAL);
1297 }
1313 /* automatic locking */
1314 if (usbd_enum_is_locked(udev)) {
1315 do_unlock = 0;
1316 } else {
1317 do_unlock = 1;
1318 usbd_enum_lock(udev);
1319 }
1298 /* Prevent re-enumeration */
1299 do_unlock = usbd_enum_lock(udev);
1320
1321 if (udev->curr_config_index == USB_UNCONFIG_INDEX) {
1322 /* do nothing - no configuration has been set */
1323 goto done;
1324 }
1325 /* setup USB attach arguments */
1326
1327 usb_init_attach_arg(udev, &uaa);

--- 70 unchanged lines hidden (view full) ---

1398 continue;
1399 if (device_delete_child(udev->parent_dev, uaa.temp_dev))
1400 DPRINTFN(0, "device delete child failed\n");
1401 uaa.temp_dev = NULL;
1402 }
1403done:
1404 if (do_unlock)
1405 usbd_enum_unlock(udev);
1300
1301 if (udev->curr_config_index == USB_UNCONFIG_INDEX) {
1302 /* do nothing - no configuration has been set */
1303 goto done;
1304 }
1305 /* setup USB attach arguments */
1306
1307 usb_init_attach_arg(udev, &uaa);

--- 70 unchanged lines hidden (view full) ---

1378 continue;
1379 if (device_delete_child(udev->parent_dev, uaa.temp_dev))
1380 DPRINTFN(0, "device delete child failed\n");
1381 uaa.temp_dev = NULL;
1382 }
1383done:
1384 if (do_unlock)
1385 usbd_enum_unlock(udev);
1406
1407 return (0);
1408}
1409
1410/*------------------------------------------------------------------------*
1411 * usb_suspend_resume_sub
1412 *
1413 * This function is called when the suspend or resume methods should
1414 * be executed on an USB device.

--- 112 unchanged lines hidden (view full) ---

1527 struct usb_device *adev;
1528 struct usb_device *hub;
1529 uint8_t *scratch_ptr;
1530 usb_error_t err;
1531 uint8_t device_index;
1532 uint8_t config_index;
1533 uint8_t config_quirk;
1534 uint8_t set_config_failed;
1386 return (0);
1387}
1388
1389/*------------------------------------------------------------------------*
1390 * usb_suspend_resume_sub
1391 *
1392 * This function is called when the suspend or resume methods should
1393 * be executed on an USB device.

--- 112 unchanged lines hidden (view full) ---

1506 struct usb_device *adev;
1507 struct usb_device *hub;
1508 uint8_t *scratch_ptr;
1509 usb_error_t err;
1510 uint8_t device_index;
1511 uint8_t config_index;
1512 uint8_t config_quirk;
1513 uint8_t set_config_failed;
1514 uint8_t do_unlock;
1535
1536 DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, "
1537 "port_index=%u, port_no=%u, speed=%u, usb_mode=%u\n",
1538 parent_dev, bus, parent_hub, depth, port_index, port_no,
1539 speed, mode);
1540
1541 /*
1542 * Find an unused device index. In USB Host mode this is the

--- 202 unchanged lines hidden (view full) ---

1745 * It appears that some string-less USB chips will crash and
1746 * disappear if any attempts are made to read any string
1747 * descriptors.
1748 *
1749 * Try to detect such chips by checking the strings in the USB
1750 * device descriptor. If no strings are present there we
1751 * simply disable all USB strings.
1752 */
1515
1516 DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, "
1517 "port_index=%u, port_no=%u, speed=%u, usb_mode=%u\n",
1518 parent_dev, bus, parent_hub, depth, port_index, port_no,
1519 speed, mode);
1520
1521 /*
1522 * Find an unused device index. In USB Host mode this is the

--- 202 unchanged lines hidden (view full) ---

1725 * It appears that some string-less USB chips will crash and
1726 * disappear if any attempts are made to read any string
1727 * descriptors.
1728 *
1729 * Try to detect such chips by checking the strings in the USB
1730 * device descriptor. If no strings are present there we
1731 * simply disable all USB strings.
1732 */
1753 scratch_ptr = udev->bus->scratch[0].data;
1754
1733
1734 /* Protect scratch area */
1735 do_unlock = usbd_enum_lock(udev);
1736
1737 scratch_ptr = udev->scratch.data;
1738
1755 if (udev->ddesc.iManufacturer ||
1756 udev->ddesc.iProduct ||
1757 udev->ddesc.iSerialNumber) {
1758 /* read out the language ID string */
1759 err = usbd_req_get_string_desc(udev, NULL,
1760 (char *)scratch_ptr, 4, 0, USB_LANGUAGE_TABLE);
1761 } else {
1762 err = USB_ERR_INVAL;

--- 7 unchanged lines hidden (view full) ---

1770 uint16_t mask;
1771 uint8_t x;
1772
1773 /* load preferred value and mask */
1774 pref = usb_lang_id;
1775 mask = usb_lang_mask;
1776
1777 /* align length correctly */
1739 if (udev->ddesc.iManufacturer ||
1740 udev->ddesc.iProduct ||
1741 udev->ddesc.iSerialNumber) {
1742 /* read out the language ID string */
1743 err = usbd_req_get_string_desc(udev, NULL,
1744 (char *)scratch_ptr, 4, 0, USB_LANGUAGE_TABLE);
1745 } else {
1746 err = USB_ERR_INVAL;

--- 7 unchanged lines hidden (view full) ---

1754 uint16_t mask;
1755 uint8_t x;
1756
1757 /* load preferred value and mask */
1758 pref = usb_lang_id;
1759 mask = usb_lang_mask;
1760
1761 /* align length correctly */
1778 scratch_ptr[0] &= ~1;
1762 scratch_ptr[0] &= ~1U;
1779
1780 /* fix compiler warning */
1781 langid = 0;
1782
1783 /* search for preferred language */
1784 for (x = 2; (x < scratch_ptr[0]); x += 2) {
1785 langid = UGETW(scratch_ptr + x);
1786 if ((langid & mask) == pref)

--- 4 unchanged lines hidden (view full) ---

1791 DPRINTFN(1, "Using first language\n");
1792 langid = UGETW(scratch_ptr + 2);
1793 }
1794
1795 DPRINTFN(1, "Language selected: 0x%04x\n", langid);
1796 udev->langid = langid;
1797 }
1798
1763
1764 /* fix compiler warning */
1765 langid = 0;
1766
1767 /* search for preferred language */
1768 for (x = 2; (x < scratch_ptr[0]); x += 2) {
1769 langid = UGETW(scratch_ptr + x);
1770 if ((langid & mask) == pref)

--- 4 unchanged lines hidden (view full) ---

1775 DPRINTFN(1, "Using first language\n");
1776 langid = UGETW(scratch_ptr + 2);
1777 }
1778
1779 DPRINTFN(1, "Language selected: 0x%04x\n", langid);
1780 udev->langid = langid;
1781 }
1782
1783 if (do_unlock)
1784 usbd_enum_unlock(udev);
1785
1799 /* assume 100mA bus powered for now. Changed when configured. */
1800 udev->power = USB_MIN_POWER;
1801 /* fetch the vendor and product strings from the device */
1802 usbd_set_device_strings(udev);
1803
1804 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
1805 /* USB device mode setup is complete */
1806 err = 0;

--- 483 unchanged lines hidden (view full) ---

2290 struct usb_device_descriptor *udd = &udev->ddesc;
2291#ifdef USB_VERBOSE
2292 const struct usb_knowndev *kdp;
2293#endif
2294 char *temp_ptr;
2295 size_t temp_size;
2296 uint16_t vendor_id;
2297 uint16_t product_id;
1786 /* assume 100mA bus powered for now. Changed when configured. */
1787 udev->power = USB_MIN_POWER;
1788 /* fetch the vendor and product strings from the device */
1789 usbd_set_device_strings(udev);
1790
1791 if (udev->flags.usb_mode == USB_MODE_DEVICE) {
1792 /* USB device mode setup is complete */
1793 err = 0;

--- 483 unchanged lines hidden (view full) ---

2277 struct usb_device_descriptor *udd = &udev->ddesc;
2278#ifdef USB_VERBOSE
2279 const struct usb_knowndev *kdp;
2280#endif
2281 char *temp_ptr;
2282 size_t temp_size;
2283 uint16_t vendor_id;
2284 uint16_t product_id;
2285 uint8_t do_unlock;
2298
2286
2299 temp_ptr = (char *)udev->bus->scratch[0].data;
2300 temp_size = sizeof(udev->bus->scratch[0].data);
2287 /* Protect scratch area */
2288 do_unlock = usbd_enum_lock(udev);
2301
2289
2290 temp_ptr = (char *)udev->scratch.data;
2291 temp_size = sizeof(udev->scratch.data);
2292
2302 vendor_id = UGETW(udd->idVendor);
2303 product_id = UGETW(udd->idProduct);
2304
2305 /* get serial number string */
2306 usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
2307 udev->ddesc.iSerialNumber);
2308 udev->serial = strdup(temp_ptr, M_USB);
2309

--- 37 unchanged lines hidden (view full) ---

2347 if (udev->manufacturer == NULL) {
2348 snprintf(temp_ptr, temp_size, "vendor 0x%04x", vendor_id);
2349 udev->manufacturer = strdup(temp_ptr, M_USB);
2350 }
2351 if (udev->product == NULL) {
2352 snprintf(temp_ptr, temp_size, "product 0x%04x", product_id);
2353 udev->product = strdup(temp_ptr, M_USB);
2354 }
2293 vendor_id = UGETW(udd->idVendor);
2294 product_id = UGETW(udd->idProduct);
2295
2296 /* get serial number string */
2297 usbd_req_get_string_any(udev, NULL, temp_ptr, temp_size,
2298 udev->ddesc.iSerialNumber);
2299 udev->serial = strdup(temp_ptr, M_USB);
2300

--- 37 unchanged lines hidden (view full) ---

2338 if (udev->manufacturer == NULL) {
2339 snprintf(temp_ptr, temp_size, "vendor 0x%04x", vendor_id);
2340 udev->manufacturer = strdup(temp_ptr, M_USB);
2341 }
2342 if (udev->product == NULL) {
2343 snprintf(temp_ptr, temp_size, "product 0x%04x", product_id);
2344 udev->product = strdup(temp_ptr, M_USB);
2345 }
2346
2347 if (do_unlock)
2348 usbd_enum_unlock(udev);
2355}
2356
2357/*
2358 * Returns:
2359 * See: USB_MODE_XXX
2360 */
2361enum usb_hc_mode
2362usbd_get_mode(struct usb_device *udev)

--- 296 unchanged lines hidden (view full) ---

2659}
2660
2661uint8_t
2662usbd_device_attached(struct usb_device *udev)
2663{
2664 return (udev->state > USB_STATE_DETACHED);
2665}
2666
2349}
2350
2351/*
2352 * Returns:
2353 * See: USB_MODE_XXX
2354 */
2355enum usb_hc_mode
2356usbd_get_mode(struct usb_device *udev)

--- 296 unchanged lines hidden (view full) ---

2653}
2654
2655uint8_t
2656usbd_device_attached(struct usb_device *udev)
2657{
2658 return (udev->state > USB_STATE_DETACHED);
2659}
2660
2667/* The following function locks enumerating the given USB device. */
2668
2669void
2661/*
2662 * The following function locks enumerating the given USB device. If
2663 * the lock is already grabbed this function returns zero. Else a
2664 * non-zero value is returned.
2665 */
2666uint8_t
2670usbd_enum_lock(struct usb_device *udev)
2671{
2667usbd_enum_lock(struct usb_device *udev)
2668{
2669 if (sx_xlocked(&udev->enum_sx))
2670 return (0);
2671
2672 sx_xlock(&udev->enum_sx);
2673 sx_xlock(&udev->sr_sx);
2674 /*
2675 * NEWBUS LOCK NOTE: We should check if any parent SX locks
2676 * are locked before locking Giant. Else the lock can be
2677 * locked multiple times.
2678 */
2679 mtx_lock(&Giant);
2672 sx_xlock(&udev->enum_sx);
2673 sx_xlock(&udev->sr_sx);
2674 /*
2675 * NEWBUS LOCK NOTE: We should check if any parent SX locks
2676 * are locked before locking Giant. Else the lock can be
2677 * locked multiple times.
2678 */
2679 mtx_lock(&Giant);
2680 return (1);
2680}
2681
2682/* The following function unlocks enumerating the given USB device. */
2683
2684void
2685usbd_enum_unlock(struct usb_device *udev)
2686{
2687 mtx_unlock(&Giant);

--- 90 unchanged lines hidden (view full) ---

2778
2779usb_error_t
2780usbd_set_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep,
2781 uint8_t ep_mode)
2782{
2783 usb_error_t error;
2784 uint8_t do_unlock;
2785
2681}
2682
2683/* The following function unlocks enumerating the given USB device. */
2684
2685void
2686usbd_enum_unlock(struct usb_device *udev)
2687{
2688 mtx_unlock(&Giant);

--- 90 unchanged lines hidden (view full) ---

2779
2780usb_error_t
2781usbd_set_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep,
2782 uint8_t ep_mode)
2783{
2784 usb_error_t error;
2785 uint8_t do_unlock;
2786
2786 /* automatic locking */
2787 if (usbd_enum_is_locked(udev)) {
2788 do_unlock = 0;
2789 } else {
2790 do_unlock = 1;
2791 usbd_enum_lock(udev);
2792 }
2787 /* Prevent re-enumeration */
2788 do_unlock = usbd_enum_lock(udev);
2793
2794 if (udev->bus->methods->set_endpoint_mode != NULL) {
2795 error = (udev->bus->methods->set_endpoint_mode) (
2796 udev, ep, ep_mode);
2797 } else if (ep_mode != USB_EP_MODE_DEFAULT) {
2798 error = USB_ERR_INVAL;
2799 } else {
2800 error = 0;
2801 }
2802
2803 /* only set new mode regardless of error */
2804 ep->ep_mode = ep_mode;
2805
2806 if (do_unlock)
2807 usbd_enum_unlock(udev);
2789
2790 if (udev->bus->methods->set_endpoint_mode != NULL) {
2791 error = (udev->bus->methods->set_endpoint_mode) (
2792 udev, ep, ep_mode);
2793 } else if (ep_mode != USB_EP_MODE_DEFAULT) {
2794 error = USB_ERR_INVAL;
2795 } else {
2796 error = 0;
2797 }
2798
2799 /* only set new mode regardless of error */
2800 ep->ep_mode = ep_mode;
2801
2802 if (do_unlock)
2803 usbd_enum_unlock(udev);
2808
2809 return (error);
2810}
2811
2812uint8_t
2813usbd_get_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep)
2814{
2815 return (ep->ep_mode);
2816}
2804 return (error);
2805}
2806
2807uint8_t
2808usbd_get_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep)
2809{
2810 return (ep->ep_mode);
2811}