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} |