| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: usb_subr.c,v 1.203 2015/10/26 15:07:07 skrll Exp $ */ | | 1 | /* $NetBSD: usb_subr.c,v 1.204 2015/11/08 23:25:17 joerg Exp $ */ |
2 | /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ | | 2 | /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. | | 5 | * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation | | 8 | * This code is derived from software contributed to The NetBSD Foundation |
9 | * by Lennart Augustsson (lennart@augustsson.net) at | | 9 | * by Lennart Augustsson (lennart@augustsson.net) at |
10 | * Carlstedt Research & Technology. | | 10 | * Carlstedt Research & Technology. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 22 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | * POSSIBILITY OF SUCH DAMAGE. | | 31 | * POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.203 2015/10/26 15:07:07 skrll Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.204 2015/11/08 23:25:17 joerg Exp $"); |
36 | | | 36 | |
37 | #ifdef _KERNEL_OPT | | 37 | #ifdef _KERNEL_OPT |
38 | #include "opt_compat_netbsd.h" | | 38 | #include "opt_compat_netbsd.h" |
39 | #include "opt_usb.h" | | 39 | #include "opt_usb.h" |
40 | #include "opt_usbverbose.h" | | 40 | #include "opt_usbverbose.h" |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <sys/param.h> | | 43 | #include <sys/param.h> |
44 | #include <sys/systm.h> | | 44 | #include <sys/systm.h> |
45 | #include <sys/kernel.h> | | 45 | #include <sys/kernel.h> |
46 | #include <sys/malloc.h> | | 46 | #include <sys/malloc.h> |
47 | #include <sys/device.h> | | 47 | #include <sys/device.h> |
48 | #include <sys/select.h> | | 48 | #include <sys/select.h> |
| @@ -781,26 +781,44 @@ usbd_attach_roothub(device_t parent, usb | | | @@ -781,26 +781,44 @@ usbd_attach_roothub(device_t parent, usb |
781 | uaa.proto = dd->bDeviceProtocol; | | 781 | uaa.proto = dd->bDeviceProtocol; |
782 | | | 782 | |
783 | dv = config_found_ia(parent, "usbroothubif", &uaa, 0); | | 783 | dv = config_found_ia(parent, "usbroothubif", &uaa, 0); |
784 | if (dv) { | | 784 | if (dv) { |
785 | dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); | | 785 | dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); |
786 | if (dev->subdevs == NULL) | | 786 | if (dev->subdevs == NULL) |
787 | return (USBD_NOMEM); | | 787 | return (USBD_NOMEM); |
788 | dev->subdevs[0] = dv; | | 788 | dev->subdevs[0] = dv; |
789 | dev->subdevlen = 1; | | 789 | dev->subdevlen = 1; |
790 | } | | 790 | } |
791 | return (USBD_NORMAL_COMPLETION); | | 791 | return (USBD_NORMAL_COMPLETION); |
792 | } | | 792 | } |
793 | | | 793 | |
| | | 794 | static void |
| | | 795 | usbd_serialnumber(device_t dv, usbd_device_handle dev) |
| | | 796 | { |
| | | 797 | usb_device_descriptor_t *dd = &dev->ddesc; |
| | | 798 | char *serialnumber; |
| | | 799 | |
| | | 800 | serialnumber = malloc(USB_MAX_ENCODED_STRING_LEN, M_USB, M_NOWAIT); |
| | | 801 | if (serialnumber == NULL) |
| | | 802 | return; |
| | | 803 | serialnumber[0] = '\0'; |
| | | 804 | (void)usbd_get_string(dev, dd->iSerialNumber, serialnumber); |
| | | 805 | if (serialnumber[0]) { |
| | | 806 | prop_dictionary_set_cstring(device_properties(dv), |
| | | 807 | "serialnumber", serialnumber); |
| | | 808 | } |
| | | 809 | free(serialnumber, M_USB); |
| | | 810 | } |
| | | 811 | |
794 | static usbd_status | | 812 | static usbd_status |
795 | usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port, | | 813 | usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port, |
796 | int usegeneric) | | 814 | int usegeneric) |
797 | { | | 815 | { |
798 | struct usb_attach_arg uaa; | | 816 | struct usb_attach_arg uaa; |
799 | usb_device_descriptor_t *dd = &dev->ddesc; | | 817 | usb_device_descriptor_t *dd = &dev->ddesc; |
800 | device_t dv; | | 818 | device_t dv; |
801 | int dlocs[USBDEVIFCF_NLOCS]; | | 819 | int dlocs[USBDEVIFCF_NLOCS]; |
802 | | | 820 | |
803 | uaa.device = dev; | | 821 | uaa.device = dev; |
804 | uaa.usegeneric = usegeneric; | | 822 | uaa.usegeneric = usegeneric; |
805 | uaa.port = port; | | 823 | uaa.port = port; |
806 | uaa.vendor = UGETW(dd->idVendor); | | 824 | uaa.vendor = UGETW(dd->idVendor); |
| @@ -817,26 +835,27 @@ usbd_attachwholedevice(device_t parent, | | | @@ -817,26 +835,27 @@ usbd_attachwholedevice(device_t parent, |
817 | /* the rest is historical ballast */ | | 835 | /* the rest is historical ballast */ |
818 | dlocs[USBDEVIFCF_CONFIGURATION] = -1; | | 836 | dlocs[USBDEVIFCF_CONFIGURATION] = -1; |
819 | dlocs[USBDEVIFCF_INTERFACE] = -1; | | 837 | dlocs[USBDEVIFCF_INTERFACE] = -1; |
820 | | | 838 | |
821 | dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print, | | 839 | dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print, |
822 | config_stdsubmatch); | | 840 | config_stdsubmatch); |
823 | if (dv) { | | 841 | if (dv) { |
824 | dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); | | 842 | dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); |
825 | if (dev->subdevs == NULL) | | 843 | if (dev->subdevs == NULL) |
826 | return (USBD_NOMEM); | | 844 | return (USBD_NOMEM); |
827 | dev->subdevs[0] = dv; | | 845 | dev->subdevs[0] = dv; |
828 | dev->subdevlen = 1; | | 846 | dev->subdevlen = 1; |
829 | dev->nifaces_claimed = 1; /* XXX */ | | 847 | dev->nifaces_claimed = 1; /* XXX */ |
| | | 848 | usbd_serialnumber(dv, dev); |
830 | } | | 849 | } |
831 | return (USBD_NORMAL_COMPLETION); | | 850 | return (USBD_NORMAL_COMPLETION); |
832 | } | | 851 | } |
833 | | | 852 | |
834 | static usbd_status | | 853 | static usbd_status |
835 | usbd_attachinterfaces(device_t parent, usbd_device_handle dev, | | 854 | usbd_attachinterfaces(device_t parent, usbd_device_handle dev, |
836 | int port, const int *locators) | | 855 | int port, const int *locators) |
837 | { | | 856 | { |
838 | struct usbif_attach_arg uiaa; | | 857 | struct usbif_attach_arg uiaa; |
839 | int ilocs[USBIFIFCF_NLOCS]; | | 858 | int ilocs[USBIFIFCF_NLOCS]; |
840 | usb_device_descriptor_t *dd = &dev->ddesc; | | 859 | usb_device_descriptor_t *dd = &dev->ddesc; |
841 | int nifaces; | | 860 | int nifaces; |
842 | usbd_interface_handle *ifaces; | | 861 | usbd_interface_handle *ifaces; |
| @@ -887,26 +906,29 @@ usbd_attachinterfaces(device_t parent, u | | | @@ -887,26 +906,29 @@ usbd_attachinterfaces(device_t parent, u |
887 | loc = locators[USBIFIFCF_CONFIGURATION]; | | 906 | loc = locators[USBIFIFCF_CONFIGURATION]; |
888 | if (loc != USBIFIFCF_CONFIGURATION_DEFAULT && | | 907 | if (loc != USBIFIFCF_CONFIGURATION_DEFAULT && |
889 | loc != uiaa.configno) | | 908 | loc != uiaa.configno) |
890 | continue; | | 909 | continue; |
891 | loc = locators[USBIFIFCF_INTERFACE]; | | 910 | loc = locators[USBIFIFCF_INTERFACE]; |
892 | if (loc != USBIFIFCF_INTERFACE_DEFAULT && | | 911 | if (loc != USBIFIFCF_INTERFACE_DEFAULT && |
893 | loc != uiaa.ifaceno) | | 912 | loc != uiaa.ifaceno) |
894 | continue; | | 913 | continue; |
895 | } | | 914 | } |
896 | dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa, | | 915 | dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa, |
897 | usbd_ifprint, config_stdsubmatch); | | 916 | usbd_ifprint, config_stdsubmatch); |
898 | if (!dv) | | 917 | if (!dv) |
899 | continue; | | 918 | continue; |
| | | 919 | |
| | | 920 | usbd_serialnumber(dv, dev); |
| | | 921 | |
900 | /* claim */ | | 922 | /* claim */ |
901 | ifaces[i] = NULL; | | 923 | ifaces[i] = NULL; |
902 | /* account for ifaces claimed by the driver behind our back */ | | 924 | /* account for ifaces claimed by the driver behind our back */ |
903 | for (j = 0; j < nifaces; j++) { | | 925 | for (j = 0; j < nifaces; j++) { |
904 | if (!ifaces[j] && !dev->subdevs[j]) { | | 926 | if (!ifaces[j] && !dev->subdevs[j]) { |
905 | DPRINTF(("%s: interface %d claimed " | | 927 | DPRINTF(("%s: interface %d claimed " |
906 | "behind our back\n", __func__, j)); | | 928 | "behind our back\n", __func__, j)); |
907 | dev->subdevs[j] = dv; | | 929 | dev->subdevs[j] = dv; |
908 | dev->nifaces_claimed++; | | 930 | dev->nifaces_claimed++; |
909 | } | | 931 | } |
910 | } | | 932 | } |
911 | } | | 933 | } |
912 | | | 934 | |