Print this page
5832 EOF wireless usb (aka UWB)
Reviewed by: TBD
Reviewed by: TBD
Approved by: TBD


   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 {