4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * USBA: Solaris USB Architecture support
29 */
30 #define USBA_FRAMEWORK
31 #include <sys/usb/usba/usba_impl.h>
32 #include <sys/usb/usba/hcdi_impl.h>
33 #include <sys/usb/hubd/hub.h>
34 #include <sys/fs/dv_node.h>
35
36 static int usba_str_startcmp(char *, char *);
37
38 /*
39 * USBA private variables and tunables
40 */
41 static kmutex_t usba_mutex;
42
43 /* mutex to protect usba_root_hubs */
102 static usb_log_handle_t usba_log_handle;
103 uint_t usba_errlevel = USB_LOG_L4;
104 uint_t usba_errmask = (uint_t)-1;
105
106 extern usb_log_handle_t hubdi_log_handle;
107
108 int
109 _init(void)
110 {
111 int rval;
112
113 /*
114 * usbai providing log support needs to be init'ed first
115 * and destroyed last
116 */
117 usba_usbai_initialization();
118 usba_usba_initialization();
119 usba_usbai_register_initialization();
120 usba_hcdi_initialization();
121 usba_hubdi_initialization();
122 usba_whcdi_initialization();
123 usba_devdb_initialization();
124
125 if ((rval = mod_install(&modlinkage)) != 0) {
126 usba_devdb_destroy();
127 usba_whcdi_destroy();
128 usba_hubdi_destroy();
129 usba_hcdi_destroy();
130 usba_usbai_register_destroy();
131 usba_usba_destroy();
132 usba_usbai_destroy();
133 }
134
135 return (rval);
136 }
137
138 int
139 _fini()
140 {
141 int rval;
142
143 if ((rval = mod_remove(&modlinkage)) == 0) {
144 usba_devdb_destroy();
145 usba_whcdi_destroy();
146 usba_hubdi_destroy();
147 usba_hcdi_destroy();
148 usba_usbai_register_destroy();
149 usba_usba_destroy();
150 usba_usbai_destroy();
151 }
152
153 return (rval);
154 }
155
156 int
157 _info(struct modinfo *modinfop)
158 {
159 return (mod_info(&modlinkage, modinfop));
160 }
161
162 boolean_t
163 usba_owns_ia(dev_info_t *dip)
164 {
165 int if_count = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
624
625 return (usba_device);
626 }
627
628
629 /* free NDI event data associated with usba_device */
630 void
631 usba_free_evdata(usba_evdata_t *evdata)
632 {
633 usba_evdata_t *next;
634
635 while (evdata) {
636 next = evdata->ev_next;
637 kmem_free(evdata, sizeof (usba_evdata_t));
638 evdata = next;
639 }
640 }
641
642
643 /*
644 * free wireless usb specific structure
645 */
646 void
647 usba_free_wireless_data(usba_wireless_data_t *wireless_data)
648 {
649 if (wireless_data == NULL) {
650
651 return;
652 }
653
654 if (wireless_data->wusb_bos) {
655 kmem_free(wireless_data->wusb_bos,
656 wireless_data->wusb_bos_length);
657 }
658
659 kmem_free(wireless_data, sizeof (usba_wireless_data_t));
660 }
661
662
663 /*
664 * free usb device structure
665 */
666 void
667 usba_free_usba_device(usba_device_t *usba_device)
668 {
669 int i, ep_idx;
670 usb_pipe_handle_t def_ph;
671
672 if (usba_device == NULL) {
673
674 return;
675 }
676
677 mutex_enter(&usba_device->usb_mutex);
678 if (usba_device->usb_ref_count) {
679 mutex_exit(&usba_device->usb_mutex);
680
681 return;
682 }
683
771 if (usba_device->usb_dev_descr) {
772 kmem_free(usba_device->usb_dev_descr,
773 sizeof (usb_dev_descr_t));
774 }
775
776 if (usba_device->usb_mfg_str) {
777 kmem_free(usba_device->usb_mfg_str,
778 strlen(usba_device->usb_mfg_str) + 1);
779 }
780
781 if (usba_device->usb_product_str) {
782 kmem_free(usba_device->usb_product_str,
783 strlen(usba_device->usb_product_str) + 1);
784 }
785
786 if (usba_device->usb_serialno_str) {
787 kmem_free(usba_device->usb_serialno_str,
788 strlen(usba_device->usb_serialno_str) + 1);
789 }
790
791 if (usba_device->usb_wireless_data) {
792 mutex_enter(&usba_device->usb_mutex);
793 usba_free_wireless_data(
794 usba_device->usb_wireless_data);
795 mutex_exit(&usba_device->usb_mutex);
796 }
797
798 /*
799 * The device address on the wireless bus is assigned
800 * by the wireless host controller driver(whci or hwahc),
801 * not by USBA framework, so skip this for wireless
802 * USB devices.
803 */
804 if (!usba_device->usb_is_wireless) {
805 usba_unset_usb_address(usba_device);
806 }
807 }
808
809 #ifndef __lock_lint
810 ASSERT(usba_device->usb_client_dev_data_list.cddl_next == NULL);
811 #endif
812
813 if (usba_device->usb_client_flags) {
814 #ifndef __lock_lint
815 int i;
816
817 for (i = 0; i < usba_device->usb_n_ifs; i++) {
818 ASSERT(usba_device->usb_client_flags[i] == 0);
819 }
820 #endif
821 kmem_free(usba_device->usb_client_flags,
822 usba_device->usb_n_ifs * USBA_CLIENT_FLAG_SIZE);
823 }
824
825
826 if (usba_device->usb_client_attach_list) {
827 kmem_free(usba_device->usb_client_attach_list,
1412 * usba is recorded in the linked list pointed to by usba_root_hubs
1413 */
1414 int
1415 usba_is_root_hub(dev_info_t *dip)
1416 {
1417 usba_root_hub_ent_t *hub;
1418
1419 mutex_enter(&usba_hub_mutex);
1420 hub = usba_root_hubs;
1421 while (hub) {
1422 if (hub->dip == dip) {
1423 mutex_exit(&usba_hub_mutex);
1424
1425 return (1);
1426 }
1427 hub = hub->next;
1428 }
1429 mutex_exit(&usba_hub_mutex);
1430
1431 return (0);
1432 }
1433
1434 /*
1435 * check whether this dip is a wire adapter device
1436 */
1437 int
1438 usba_is_wa(dev_info_t *dip)
1439 {
1440 if (dip) {
1441 usba_device_t *usba_device;
1442
1443 usba_device = usba_get_usba_device(dip);
1444
1445 return (usba_device->usb_is_wa? 1:0);
1446 }
1447
1448 return (0);
1449 }
1450
1451 /*
1452 * check whether this dip is a host wire adapter device node
1453 */
1454 int
1455 usba_is_hwa(dev_info_t *dip)
1456 {
1457 dev_info_t *cdip;
1458
1459 if (dip == NULL) {
1460
1461 return (0);
1462 }
1463
1464 if (strcmp(ddi_driver_name(dip), "usb_mid") != 0) {
1465
1466 return (0);
1467 }
1468
1469 for (cdip = ddi_get_child(dip); cdip;
1470 cdip = ddi_get_next_sibling(cdip)) {
1471 if (strcmp(ddi_driver_name(cdip), "hwarc") == 0) {
1472
1473 return (1);
1474 }
1475 }
1476
1477 return (0);
1478 }
1479
1480 /*
1481 * get and store usba_device pointer in the devi
1482 */
1483 usba_device_t *
1484 usba_get_usba_device(dev_info_t *dip)
1485 {
1486 /*
1487 * we cannot use parent_data in the usb node because its
1488 * bus parent (eg. PCI nexus driver) uses this data
1489 *
1490 * we cannot use driver data in the other usb nodes since
1491 * usb drivers may need to use this
1492 */
1493 if (usba_is_root_hub(dip)) {
1494 usba_hcdi_t *hcdi = usba_hcdi_get_hcdi(dip);
1495
1496 return (hcdi->hcdi_usba_device);
1497 } else {
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
26 */
27
28
29 /*
30 * USBA: Solaris USB Architecture support
31 */
32 #define USBA_FRAMEWORK
33 #include <sys/usb/usba/usba_impl.h>
34 #include <sys/usb/usba/hcdi_impl.h>
35 #include <sys/usb/hubd/hub.h>
36 #include <sys/fs/dv_node.h>
37
38 static int usba_str_startcmp(char *, char *);
39
40 /*
41 * USBA private variables and tunables
42 */
43 static kmutex_t usba_mutex;
44
45 /* mutex to protect usba_root_hubs */
104 static usb_log_handle_t usba_log_handle;
105 uint_t usba_errlevel = USB_LOG_L4;
106 uint_t usba_errmask = (uint_t)-1;
107
108 extern usb_log_handle_t hubdi_log_handle;
109
110 int
111 _init(void)
112 {
113 int rval;
114
115 /*
116 * usbai providing log support needs to be init'ed first
117 * and destroyed last
118 */
119 usba_usbai_initialization();
120 usba_usba_initialization();
121 usba_usbai_register_initialization();
122 usba_hcdi_initialization();
123 usba_hubdi_initialization();
124 usba_devdb_initialization();
125
126 if ((rval = mod_install(&modlinkage)) != 0) {
127 usba_devdb_destroy();
128 usba_hubdi_destroy();
129 usba_hcdi_destroy();
130 usba_usbai_register_destroy();
131 usba_usba_destroy();
132 usba_usbai_destroy();
133 }
134
135 return (rval);
136 }
137
138 int
139 _fini()
140 {
141 int rval;
142
143 if ((rval = mod_remove(&modlinkage)) == 0) {
144 usba_devdb_destroy();
145 usba_hubdi_destroy();
146 usba_hcdi_destroy();
147 usba_usbai_register_destroy();
148 usba_usba_destroy();
149 usba_usbai_destroy();
150 }
151
152 return (rval);
153 }
154
155 int
156 _info(struct modinfo *modinfop)
157 {
158 return (mod_info(&modlinkage, modinfop));
159 }
160
161 boolean_t
162 usba_owns_ia(dev_info_t *dip)
163 {
164 int if_count = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
623
624 return (usba_device);
625 }
626
627
628 /* free NDI event data associated with usba_device */
629 void
630 usba_free_evdata(usba_evdata_t *evdata)
631 {
632 usba_evdata_t *next;
633
634 while (evdata) {
635 next = evdata->ev_next;
636 kmem_free(evdata, sizeof (usba_evdata_t));
637 evdata = next;
638 }
639 }
640
641
642 /*
643 * free usb device structure
644 */
645 void
646 usba_free_usba_device(usba_device_t *usba_device)
647 {
648 int i, ep_idx;
649 usb_pipe_handle_t def_ph;
650
651 if (usba_device == NULL) {
652
653 return;
654 }
655
656 mutex_enter(&usba_device->usb_mutex);
657 if (usba_device->usb_ref_count) {
658 mutex_exit(&usba_device->usb_mutex);
659
660 return;
661 }
662
750 if (usba_device->usb_dev_descr) {
751 kmem_free(usba_device->usb_dev_descr,
752 sizeof (usb_dev_descr_t));
753 }
754
755 if (usba_device->usb_mfg_str) {
756 kmem_free(usba_device->usb_mfg_str,
757 strlen(usba_device->usb_mfg_str) + 1);
758 }
759
760 if (usba_device->usb_product_str) {
761 kmem_free(usba_device->usb_product_str,
762 strlen(usba_device->usb_product_str) + 1);
763 }
764
765 if (usba_device->usb_serialno_str) {
766 kmem_free(usba_device->usb_serialno_str,
767 strlen(usba_device->usb_serialno_str) + 1);
768 }
769
770 usba_unset_usb_address(usba_device);
771 }
772
773 #ifndef __lock_lint
774 ASSERT(usba_device->usb_client_dev_data_list.cddl_next == NULL);
775 #endif
776
777 if (usba_device->usb_client_flags) {
778 #ifndef __lock_lint
779 int i;
780
781 for (i = 0; i < usba_device->usb_n_ifs; i++) {
782 ASSERT(usba_device->usb_client_flags[i] == 0);
783 }
784 #endif
785 kmem_free(usba_device->usb_client_flags,
786 usba_device->usb_n_ifs * USBA_CLIENT_FLAG_SIZE);
787 }
788
789
790 if (usba_device->usb_client_attach_list) {
791 kmem_free(usba_device->usb_client_attach_list,
1376 * usba is recorded in the linked list pointed to by usba_root_hubs
1377 */
1378 int
1379 usba_is_root_hub(dev_info_t *dip)
1380 {
1381 usba_root_hub_ent_t *hub;
1382
1383 mutex_enter(&usba_hub_mutex);
1384 hub = usba_root_hubs;
1385 while (hub) {
1386 if (hub->dip == dip) {
1387 mutex_exit(&usba_hub_mutex);
1388
1389 return (1);
1390 }
1391 hub = hub->next;
1392 }
1393 mutex_exit(&usba_hub_mutex);
1394
1395 return (0);
1396 }
1397
1398 /*
1399 * get and store usba_device pointer in the devi
1400 */
1401 usba_device_t *
1402 usba_get_usba_device(dev_info_t *dip)
1403 {
1404 /*
1405 * we cannot use parent_data in the usb node because its
1406 * bus parent (eg. PCI nexus driver) uses this data
1407 *
1408 * we cannot use driver data in the other usb nodes since
1409 * usb drivers may need to use this
1410 */
1411 if (usba_is_root_hub(dip)) {
1412 usba_hcdi_t *hcdi = usba_hcdi_get_hcdi(dip);
1413
1414 return (hcdi->hcdi_usba_device);
1415 } else {
|