Lines Matching refs:hubd

28  * Most of the code for hubd resides in this file and
29 * is shared between the HCD root hub support and hubd
39 #include <sys/usb/hubd/hub.h>
40 #include <sys/usb/hubd/hubdvar.h>
41 #include <sys/usb/hubd/hubd_impl.h>
499 static int hubd_cleanup(dev_info_t *dip, hubd_t *hubd);
500 static int hubd_check_ports(hubd_t *hubd);
502 static int hubd_open_intr_pipe(hubd_t *hubd);
503 static void hubd_start_polling(hubd_t *hubd, int always);
504 static void hubd_stop_polling(hubd_t *hubd);
505 static void hubd_close_intr_pipe(hubd_t *hubd);
513 hubd_t *hubd,
519 static int hubd_delete_child(hubd_t *hubd, usb_port_t port, uint_t flag,
522 static int hubd_get_hub_descriptor(hubd_t *hubd);
524 static int hubd_get_hub_status_words(hubd_t *hubd, uint16_t *status);
526 static int hubd_reset_port(hubd_t *hubd, usb_port_t port);
528 static int hubd_get_hub_status(hubd_t *hubd);
530 static int hubd_handle_port_connect(hubd_t *hubd, usb_port_t port);
532 static int hubd_disable_port(hubd_t *hubd, usb_port_t port);
534 static int hubd_enable_port(hubd_t *hubd, usb_port_t port);
535 static int hubd_recover_disabled_port(hubd_t *hubd, usb_port_t port);
537 static int hubd_determine_port_status(hubd_t *hubd, usb_port_t port,
540 static int hubd_enable_all_port_power(hubd_t *hubd);
541 static int hubd_disable_all_port_power(hubd_t *hubd);
542 static int hubd_disable_port_power(hubd_t *hubd, usb_port_t port);
543 static int hubd_enable_port_power(hubd_t *hubd, usb_port_t port);
545 static void hubd_free_usba_device(hubd_t *hubd, usba_device_t *usba_device);
547 static int hubd_can_suspend(hubd_t *hubd);
548 static void hubd_restore_device_state(dev_info_t *dip, hubd_t *hubd);
549 static int hubd_setdevaddr(hubd_t *hubd, usb_port_t port);
550 static void hubd_setdevconfig(hubd_t *hubd, usb_port_t port);
552 static int hubd_register_events(hubd_t *hubd);
553 static void hubd_do_callback(hubd_t *hubd, dev_info_t *dip,
555 static void hubd_run_callbacks(hubd_t *hubd, usba_event_t type);
556 static void hubd_post_event(hubd_t *hubd, usb_port_t port, usba_event_t type);
557 static void hubd_create_pm_components(dev_info_t *dip, hubd_t *hubd);
563 static int hubd_cpr_suspend(hubd_t *hubd);
566 static int hubd_check_same_device(hubd_t *hubd, usb_port_t port);
568 static int hubd_init_power_budget(hubd_t *hubd);
597 * hubd_get_soft_state() returns the hubd soft state
600 * devices. The hubd soft state for the wire adapter class device
629 hubd_pm_busy_component(hubd_t *hubd, dev_info_t *dip, int component)
631 if (hubd->h_hubpm != NULL) {
632 hubd->h_hubpm->hubp_busy_pm++;
633 mutex_exit(HUBD_MUTEX(hubd));
635 mutex_enter(HUBD_MUTEX(hubd));
636 hubd->h_hubpm->hubp_busy_pm--;
637 mutex_exit(HUBD_MUTEX(hubd));
639 mutex_enter(HUBD_MUTEX(hubd));
640 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
641 "hubd_pm_busy_component: %d", hubd->h_hubpm->hubp_busy_pm);
648 hubd_pm_idle_component(hubd_t *hubd, dev_info_t *dip, int component)
650 if (hubd->h_hubpm != NULL) {
651 mutex_exit(HUBD_MUTEX(hubd));
653 mutex_enter(HUBD_MUTEX(hubd));
654 ASSERT(hubd->h_hubpm->hubp_busy_pm > 0);
655 hubd->h_hubpm->hubp_busy_pm--;
656 mutex_exit(HUBD_MUTEX(hubd));
658 mutex_enter(HUBD_MUTEX(hubd));
659 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
660 "hubd_pm_idle_component: %d", hubd->h_hubpm->hubp_busy_pm);
669 hubd_set_child_pwrlvl(hubd_t *hubd, usb_port_t port, uint8_t power)
675 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
679 mutex_enter(HUBD_MUTEX(hubd));
680 hubpm = hubd->h_hubpm;
683 for (portno = 1; portno <= hubd->h_hub_descr.bNbrPorts; portno++) {
688 pwr = hubd->h_hubpm->hubp_child_pwrstate[port];
689 hubd->h_hubpm->hubp_child_pwrstate[port] = power;
692 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
698 (void) hubd_pm_busy_component(hubd, hubd->h_dip, 0);
701 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
703 mutex_exit(HUBD_MUTEX(hubd));
711 hubd_child_dip2port(hubd_t *hubd, dev_info_t *dip)
715 mutex_enter(HUBD_MUTEX(hubd));
716 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
717 if (hubd->h_children_dips[port] == dip) {
722 ASSERT(port <= hubd->h_hub_descr.bNbrPorts);
723 mutex_exit(HUBD_MUTEX(hubd));
734 hubd_can_suspend(hubd_t *hubd)
740 hubpm = hubd->h_hubpm;
742 if (DEVI_IS_DETACHING(hubd->h_dip)) {
758 (port <= hubd->h_hub_descr.bNbrPorts); port++) {
762 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
773 hubd_resume_port(hubd_t *hubd, usb_port_t port)
782 mutex_enter(HUBD_MUTEX(hubd));
784 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
786 hubd->h_dev_state, usb_str_dev_state(hubd->h_dev_state));
788 switch (hubd->h_dev_state) {
794 if ((hubd->h_port_state[port] & PORT_STATUS_PSS) == 0) {
798 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
807 mutex_exit(HUBD_MUTEX(hubd));
808 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
809 hubd->h_default_pipe,
816 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
821 mutex_enter(HUBD_MUTEX(hubd));
824 (void) hubd_determine_port_status(hubd, port,
831 * When hubd's connect event callback posts a connect
837 if (((hubd->h_port_state[port] & PORT_STATUS_CCS) == 0) ||
838 ((hubd->h_port_state[port] & PORT_STATUS_PSS) == 0)) {
845 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
853 hubd->h_hotplug_thread++;
854 hubd_stop_polling(hubd);
858 mutex_exit(HUBD_MUTEX(hubd));
859 rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
860 hubd->h_default_pipe,
867 mutex_enter(HUBD_MUTEX(hubd));
870 hubd->h_log_handle,
881 mutex_exit(HUBD_MUTEX(hubd));
883 mutex_enter(HUBD_MUTEX(hubd));
884 (void) hubd_determine_port_status(hubd, port,
897 hubd->h_hotplug_thread--;
898 hubd_start_polling(hubd, 0);
909 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
914 mutex_exit(HUBD_MUTEX(hubd));
924 hubd_suspend_port(hubd_t *hubd, usb_port_t port)
933 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
936 mutex_enter(HUBD_MUTEX(hubd));
938 switch (hubd->h_dev_state) {
941 * When hubd's connect event callback posts a connect
953 hubd->h_hotplug_thread++;
954 hubd_stop_polling(hubd);
963 mutex_exit(HUBD_MUTEX(hubd));
964 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
965 hubd->h_default_pipe,
974 hubd->h_log_handle,
987 mutex_enter(HUBD_MUTEX(hubd));
988 (void) hubd_determine_port_status(hubd, port,
997 hubd->h_log_handle,
1003 hubd->h_hotplug_thread--;
1004 hubd_start_polling(hubd, 0);
1017 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
1022 mutex_exit(HUBD_MUTEX(hubd));
1032 hubd_post_attach(hubd_t *hubd, usb_port_t port, struct attachspec *as)
1036 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
1048 mutex_enter(HUBD_MUTEX(hubd));
1049 dip = hubd->h_children_dips[port];
1050 mutex_exit(HUBD_MUTEX(hubd));
1052 hubd_set_child_pwrlvl(hubd, port, USB_DEV_OS_FULL_PWR);
1059 hubd_post_detach(hubd_t *hubd, usb_port_t port, struct detachspec *ds)
1061 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
1068 mutex_enter(HUBD_MUTEX(hubd));
1070 usba_device_t *usba_device = hubd->h_usba_devices[port];
1071 dev_info_t *pdip = hubd->h_dip;
1072 mutex_exit(HUBD_MUTEX(hubd));
1081 hubd_set_child_pwrlvl(hubd, port, USB_DEV_OS_PWR_OFF);
1088 mutex_exit(HUBD_MUTEX(hubd));
1100 hubd_post_power(hubd_t *hubd, usb_port_t port, pm_bp_child_pwrchg_t *bpc,
1105 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1111 hubd_set_child_pwrlvl(hubd, port, bpc->bpc_nlevel);
1116 retval = hubd_suspend_port(hubd, port);
1120 retval = hubd_resume_port(hubd, port);
1125 hubd_set_child_pwrlvl(hubd, port, bpc->bpc_olevel);
1133 retval = hubd_suspend_port(hubd, port);
1155 hubd_t *hubd;
1160 hubd = hubd_get_soft_state(dip);
1162 mutex_enter(HUBD_MUTEX(hubd));
1165 hubd->h_bus_ctls++;
1166 mutex_exit(HUBD_MUTEX(hubd));
1168 USB_DPRINTF_L3(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1176 port = hubd_child_dip2port(hubd, rdip);
1184 ndi_devi_enter(hubd->h_dip, &circ);
1188 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1192 mutex_enter(HUBD_MUTEX(hubd));
1193 hubd->h_port_state[port] |= HUBD_CHILD_ATTACHING;
1196 (void) hubd_pm_busy_component(hubd, dip, 0);
1197 mutex_exit(HUBD_MUTEX(hubd));
1205 rval = hubd_resume_port(hubd, port);
1212 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1216 mutex_enter(HUBD_MUTEX(hubd));
1217 hubd->h_port_state[port] &= ~HUBD_CHILD_ATTACHING;
1218 mutex_exit(HUBD_MUTEX(hubd));
1220 hubd_post_attach(hubd, port, (struct attachspec *)arg);
1222 mutex_enter(HUBD_MUTEX(hubd));
1225 (void) hubd_pm_idle_component(hubd, dip, 0);
1226 mutex_exit(HUBD_MUTEX(hubd));
1228 ndi_devi_exit(hubd->h_dip, circ);
1233 port = hubd_child_dip2port(hubd, rdip);
1241 ndi_devi_enter(hubd->h_dip, &circ);
1245 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1249 mutex_enter(HUBD_MUTEX(hubd));
1250 hubd->h_port_state[port] |= HUBD_CHILD_DETACHING;
1253 (void) hubd_pm_busy_component(hubd, dip, 0);
1255 mutex_exit(HUBD_MUTEX(hubd));
1260 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1264 mutex_enter(HUBD_MUTEX(hubd));
1265 hubd->h_port_state[port] &= ~HUBD_CHILD_DETACHING;
1266 mutex_exit(HUBD_MUTEX(hubd));
1269 hubd_post_detach(hubd, port, (struct detachspec *)arg);
1271 mutex_enter(HUBD_MUTEX(hubd));
1272 (void) hubd_pm_idle_component(hubd, dip, 0);
1273 mutex_exit(HUBD_MUTEX(hubd));
1277 ndi_devi_exit(hubd->h_dip, circ);
1285 mutex_enter(HUBD_MUTEX(hubd));
1286 hubd->h_bus_ctls--;
1287 ASSERT(hubd->h_bus_ctls >= 0);
1288 mutex_exit(HUBD_MUTEX(hubd));
1299 hubd_config_one(hubd_t *hubd, int port)
1302 dev_info_t *hdip = hubd->h_dip;
1303 dev_info_t *rh_dip = hubd->h_usba_device->usb_root_hub_dip;
1307 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
1322 mutex_enter(HUBD_MUTEX(hubd));
1324 hubd_pm_busy_component(hubd, hubd->h_dip, 0);
1326 if (!hubd->h_children_dips[port]) {
1328 (void) hubd_determine_port_status(hubd, port,
1332 online_child |= (hubd_handle_port_connect(hubd,
1340 mutex_exit(HUBD_MUTEX(hubd));
1347 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
1350 (void) ndi_devi_online(hubd->h_dip, 0);
1353 mutex_enter(HUBD_MUTEX(hubd));
1355 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
1357 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
1360 mutex_exit(HUBD_MUTEX(hubd));
1374 hubd_t *hubd = hubd_get_soft_state(dip);
1378 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1390 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
1402 found = hubd_config_one(hubd, port);
1409 ndi_devi_enter(hubd->h_dip, &circ);
1411 ndi_devi_exit(hubd->h_dip, circ);
1421 hubd_t *hubd = hubd_get_soft_state(dip);
1427 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1444 mutex_enter(HUBD_MUTEX(hubd));
1445 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
1446 hubd->h_port_state[port] |= HUBD_CHILD_ZAP;
1448 mutex_exit(HUBD_MUTEX(hubd));
1459 mutex_enter(HUBD_MUTEX(hubd));
1461 hubd->h_children_dips[port] = cdip;
1462 hubd->h_port_state[port] &= ~HUBD_CHILD_ZAP;
1463 mutex_exit(HUBD_MUTEX(hubd));
1467 mutex_enter(HUBD_MUTEX(hubd));
1468 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
1469 if (hubd->h_port_state[port] & HUBD_CHILD_ZAP) {
1471 hubd_free_usba_device(hubd, hubd->h_usba_devices[port]);
1472 hubd->h_children_dips[port] = NULL;
1473 hubd->h_port_state[port] &= ~HUBD_CHILD_ZAP;
1476 mutex_exit(HUBD_MUTEX(hubd));
1480 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
1492 hubd_t *hubd;
1499 hubd = hubd_get_soft_state(dip);
1501 USB_DPRINTF_L4(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1507 mutex_enter(HUBD_MUTEX(hubd));
1508 hubd->h_bus_pwr++;
1509 mutex_exit(HUBD_MUTEX(hubd));
1513 port = hubd_child_dip2port(hubd, bpc->bpc_dip);
1514 USB_DPRINTF_L3(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1519 mutex_enter(HUBD_MUTEX(hubd));
1525 hubd_pm_busy_component(hubd, dip, 0);
1531 if ((hubd->h_dev_state == USB_DEV_PWRED_DOWN) &&
1532 hubd->h_hubpm->hubp_wakeup_enabled) {
1533 mutex_exit(HUBD_MUTEX(hubd));
1545 mutex_enter(HUBD_MUTEX(hubd));
1546 hubd_pm_idle_component(hubd, dip, 0);
1547 mutex_exit(HUBD_MUTEX(hubd));
1551 mutex_enter(HUBD_MUTEX(hubd));
1555 hubd->h_port_state[port] |= HUBD_CHILD_PWRLVL_CHNG;
1556 mutex_exit(HUBD_MUTEX(hubd));
1564 rval = hubd_resume_port(hubd, port);
1569 mutex_enter(HUBD_MUTEX(hubd));
1570 hubd->h_port_state[port] &=
1572 hubd_pm_idle_component(hubd, dip, 0);
1573 mutex_exit(HUBD_MUTEX(hubd));
1581 port = hubd_child_dip2port(hubd, bpc->bpc_dip);
1582 USB_DPRINTF_L3(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1586 mutex_enter(HUBD_MUTEX(hubd));
1587 hubd->h_port_state[port] &= ~HUBD_CHILD_PWRLVL_CHNG;
1588 mutex_exit(HUBD_MUTEX(hubd));
1591 rval = hubd_post_power(hubd, port, bpc, *(int *)result);
1597 mutex_enter(HUBD_MUTEX(hubd));
1603 hubd_pm_idle_component(hubd, dip, 0);
1605 mutex_exit(HUBD_MUTEX(hubd));
1614 mutex_enter(HUBD_MUTEX(hubd));
1615 hubd->h_bus_pwr--;
1616 mutex_exit(HUBD_MUTEX(hubd));
1626 hubd_pwrlvl0(hubd_t *hubd)
1631 if (hubd->h_hotplug_thread || hubd->h_hubpm->hubp_busy_pm ||
1632 (hubd_can_suspend(hubd) == USB_FAILURE)) {
1637 switch (hubd->h_dev_state) {
1639 hubpm = hubd->h_hubpm;
1646 hubd->h_dev_state = USB_DEV_PWRED_DOWN;
1653 if (usba_is_root_hub(hubd->h_dip)) {
1655 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
1658 hubd_stop_polling(hubd);
1662 (void) usb_set_device_pwrlvl3(hubd->h_dip);
1679 hubd_pwrlvl1(hubd_t *hubd)
1682 (void) usb_set_device_pwrlvl2(hubd->h_dip);
1690 hubd_pwrlvl2(hubd_t *hubd)
1693 (void) usb_set_device_pwrlvl1(hubd->h_dip);
1700 hubd_pwrlvl3(hubd_t *hubd)
1705 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle, "hubd_pwrlvl3");
1707 hubpm = hubd->h_hubpm;
1708 switch (hubd->h_dev_state) {
1711 if (usba_is_root_hub(hubd->h_dip)) {
1714 hubd->h_log_handle,
1718 rval = usb_set_device_pwrlvl0(hubd->h_dip);
1720 hubd->h_dev_state = USB_DEV_ONLINE;
1723 hubd_start_polling(hubd, 0);
1742 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
1743 "hubd_pwrlvl3: Illegal dev_state=%d", hubd->h_dev_state);
1755 hubd_t *hubd;
1760 hubd = hubd_get_soft_state(dip);
1761 USB_DPRINTF_L3(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1766 mutex_enter(HUBD_MUTEX(hubd));
1767 hubpm = hubd->h_hubpm;
1771 USB_DPRINTF_L2(DPRINT_MASK_HUBDI, hubd->h_log_handle,
1774 mutex_exit(HUBD_MUTEX(hubd));
1783 retval = hubd_pwrlvl0(hubd);
1787 retval = hubd_pwrlvl1(hubd);
1791 retval = hubd_pwrlvl2(hubd);
1795 retval = hubd_pwrlvl3(hubd);
1799 mutex_exit(HUBD_MUTEX(hubd));
1822 hubd_t *hubd = NULL;
1853 hubd = hubd_get_soft_state(dip);
1876 hubd = hubd_get_soft_state(dip);
1877 if (hubd == NULL) {
1882 hubd->h_log_handle = usb_alloc_log_hdl(dip, log_name, &hubd_errlevel,
1885 hubd->h_usba_device = child_ud = usba_get_usba_device(dip);
1886 hubd->h_dip = dip;
1887 hubd->h_instance = instance;
1899 USB_DPRINTF_L0(DPRINT_MASK_ATTA, hubd->h_log_handle,
1904 hubd->h_pipe_policy.pp_max_async_reqs = 1;
1908 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
1914 if (usb_get_dev_data(dip, &hubd->h_dev_data,
1916 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
1922 if ((ep_data = usb_lookup_ep_data(dip, hubd->h_dev_data,
1923 hubd->h_dev_data->dev_curr_if, 0, 0,
1925 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
1931 hubd->h_ep1_descr = ep_data->ep_descr;
1932 hubd->h_default_pipe = hubd->h_dev_data->dev_default_ph;
1934 mutex_init(HUBD_MUTEX(hubd), NULL, MUTEX_DRIVER,
1935 hubd->h_dev_data->dev_iblock_cookie);
1936 cv_init(&hubd->h_cv_reset_port, NULL, CV_DRIVER, NULL);
1937 cv_init(&hubd->h_cv_hotplug_dev, NULL, CV_DRIVER, NULL);
1939 hubd->h_init_state |= HUBD_LOCKS_DONE;
1941 usb_free_descr_tree(dip, hubd->h_dev_data);
1948 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
1953 mutex_enter(HUBD_MUTEX(hubd));
1954 hubd->h_init_state |= HUBD_HUBDI_REGISTERED;
1955 hubd->h_dev_state = USB_DEV_ONLINE;
1956 mutex_exit(HUBD_MUTEX(hubd));
1959 hubd_create_pm_components(dip, hubd);
1967 (void) ndi_event_alloc_hdl(dip, 0, &hubd->h_ndi_event_hdl, NDI_SLEEP);
1970 if (ndi_event_bind_set(hubd->h_ndi_event_hdl, &hubd_ndi_events,
1972 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
1979 if (hubd_register_events(hubd) != USB_SUCCESS) {
1980 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
1986 mutex_enter(HUBD_MUTEX(hubd));
1987 hubd->h_init_state |= HUBD_EVENTS_REGISTERED;
1989 if ((hubd_get_hub_descriptor(hubd)) != USB_SUCCESS) {
1990 mutex_exit(HUBD_MUTEX(hubd));
1998 hubd->h_ignore_pwr_budget = B_TRUE;
2000 hubd->h_ignore_pwr_budget = B_FALSE;
2003 if (hubd_init_power_budget(hubd) != USB_SUCCESS) {
2004 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2006 mutex_exit(HUBD_MUTEX(hubd));
2013 if (hubd_check_ports(hubd) != USB_SUCCESS) {
2014 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2016 mutex_exit(HUBD_MUTEX(hubd));
2024 hubd->h_ancestry_str = (char *)kmem_zalloc(HUBD_APID_NAMELEN, KM_SLEEP);
2025 hubd_get_ancestry_str(hubd);
2027 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2028 "#ports=0x%x", hubd->h_hub_descr.bNbrPorts);
2030 for (i = 1; i <= hubd->h_hub_descr.bNbrPorts; i++) {
2034 hubd->h_ancestry_str, i);
2035 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2040 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2043 mutex_exit(HUBD_MUTEX(hubd));
2049 ports_count = hubd->h_hub_descr.bNbrPorts;
2050 mutex_exit(HUBD_MUTEX(hubd));
2053 if (ddi_create_minor_node(dip, "hubd", S_IFCHR,
2056 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2062 mutex_enter(HUBD_MUTEX(hubd));
2063 hubd->h_init_state |= HUBD_MINOR_NODE_CREATED;
2064 mutex_exit(HUBD_MUTEX(hubd));
2068 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2081 hubd->h_cleanup_enabled = B_TRUE;
2082 mutex_enter(HUBD_MUTEX(hubd));
2083 hubd_pm_idle_component(hubd, dip, 0);
2084 mutex_exit(HUBD_MUTEX(hubd));
2098 mutex_enter(HUBD_MUTEX(hubd));
2099 hubd_pm_idle_component(hubd, dip, 0);
2100 mutex_exit(HUBD_MUTEX(hubd));
2102 if (hubd) {
2103 rval = hubd_cleanup(dip, hubd);
2117 hubd_t *hubd = hubd_get_soft_state(dip);
2120 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2125 rval = hubd_cleanup(dip, hubd);
2129 rval = hubd_cpr_suspend(hubd);
2143 hubd_setdevaddr(hubd_t *hubd, usb_port_t port)
2155 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2158 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
2160 child_dip = hubd->h_children_dips[port];
2161 address = hubd->h_usba_devices[port]->usb_addr;
2162 usba_device = hubd->h_usba_devices[port];
2165 mutex_exit(HUBD_MUTEX(hubd));
2169 mutex_enter(HUBD_MUTEX(hubd));
2180 mutex_exit(HUBD_MUTEX(hubd));
2189 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2204 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2224 mutex_enter(HUBD_MUTEX(hubd));
2237 hubd_setdevconfig(hubd_t *hubd, usb_port_t port)
2247 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2250 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
2252 child_dip = hubd->h_children_dips[port];
2253 usba_device = hubd->h_usba_devices[port];
2254 config_value = hubd->h_usba_devices[port]->usb_cfg_value;
2255 mutex_exit(HUBD_MUTEX(hubd));
2271 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2283 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2286 mutex_enter(HUBD_MUTEX(hubd));
2296 hubd_t *hubd;
2297 major_t hub_major = ddi_name_to_major("hubd");
2325 hubd = hubd_get_soft_state(dip);
2326 if (hubd == NULL) {
2336 mutex_enter(HUBD_MUTEX(hubd));
2337 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
2338 dev_info_t *cdip = hubd->h_children_dips[port];
2345 (void) hubd_delete_child(hubd, port, NDI_DEVI_REMOVE,
2348 mutex_exit(HUBD_MUTEX(hubd));
2351 if (hubd->h_cleanup_child != NULL) {
2352 if (hubd->h_cleanup_child(dip) != USB_SUCCESS) {
2502 hubd_restore_device_state(dev_info_t *dip, hubd_t *hubd)
2513 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2516 mutex_enter(HUBD_MUTEX(hubd));
2517 hub_prev_state = hubd->h_dev_state;
2521 (void) hubd_pm_busy_component(hubd, dip, 0);
2522 mutex_exit(HUBD_MUTEX(hubd));
2527 (usb_check_same_device(dip, hubd->h_log_handle, USB_LOG_L0,
2532 mutex_enter(HUBD_MUTEX(hubd));
2533 hubd->h_dev_state = USB_DEV_DISCONNECTED;
2534 (void) hubd_pm_idle_component(hubd, dip, 0);
2535 mutex_exit(HUBD_MUTEX(hubd));
2542 mutex_enter(HUBD_MUTEX(hubd));
2544 rval = hubd_disable_all_port_power(hubd);
2546 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
2552 mutex_exit(HUBD_MUTEX(hubd));
2554 mutex_enter(HUBD_MUTEX(hubd));
2557 if (hubd_enable_all_port_power(hubd) != USB_SUCCESS) {
2558 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2562 (void) hubd_disable_all_port_power(hubd);
2564 (void) hubd_pm_idle_component(hubd, dip, 0);
2565 mutex_exit(HUBD_MUTEX(hubd));
2575 mutex_exit(HUBD_MUTEX(hubd));
2577 mutex_enter(HUBD_MUTEX(hubd));
2579 hubd->h_dev_state = USB_DEV_HUB_STATE_RECOVER;
2581 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
2582 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
2590 ch_dip = hubd->h_children_dips[port];
2593 (void) hubd_determine_port_status(hubd, port,
2604 (void) hubd_reset_port(hubd, port);
2607 (void) hubd_enable_port(hubd, port);
2610 mutex_exit(HUBD_MUTEX(hubd));
2613 mutex_enter(HUBD_MUTEX(hubd));
2616 rval = hubd_setdevaddr(hubd, port);
2621 hubd_setdevconfig(hubd, port);
2625 mutex_exit(HUBD_MUTEX(hubd));
2626 hubd_post_event(hubd, port,
2628 mutex_enter(HUBD_MUTEX(hubd));
2635 mutex_exit(HUBD_MUTEX(hubd));
2646 mutex_enter(HUBD_MUTEX(hubd));
2655 mutex_exit(HUBD_MUTEX(hubd));
2658 hubd->h_log_handle,
2666 mutex_enter(HUBD_MUTEX(hubd));
2670 (void) hubd_determine_port_status(hubd, port,
2682 (void) hubd_reset_port(hubd, port);
2684 (void) hubd_determine_port_status(hubd, port,
2695 (void) hubd_toggle_port(hubd, port);
2698 hubd->h_log_handle,
2710 if (hubd->h_hubpm->hubp_wakeup_enabled) {
2711 mutex_exit(HUBD_MUTEX(hubd));
2712 (void) usb_handle_remote_wakeup(hubd->h_dip,
2714 mutex_enter(HUBD_MUTEX(hubd));
2717 hubd->h_dev_state = USB_DEV_ONLINE;
2718 hubd_start_polling(hubd, 0);
2719 (void) hubd_pm_idle_component(hubd, dip, 0);
2720 mutex_exit(HUBD_MUTEX(hubd));
2726 * cleanup hubd and deallocate. this function is called for
2733 hubd_cleanup(dev_info_t *dip, hubd_t *hubd)
2741 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2744 if ((hubd->h_init_state & HUBD_LOCKS_DONE) == 0) {
2751 mutex_enter(HUBD_MUTEX(hubd));
2755 dev_info_t *rh_dip = hubd->h_usba_device->usb_root_hub_dip;
2763 if (hubd->h_bus_ctls || hubd->h_bus_pwr ||
2764 hubd->h_hotplug_thread) {
2765 mutex_exit(HUBD_MUTEX(hubd));
2768 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
2782 if (hubd->h_cleanup_needed ||
2783 hubd->h_cleanup_active) {
2784 mutex_exit(HUBD_MUTEX(hubd));
2788 hubd->h_log_handle,
2797 old_dev_state = hubd->h_dev_state;
2798 hubd->h_dev_state = USB_DEV_DISCONNECTED;
2800 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2802 hubd_close_intr_pipe(hubd);
2804 ASSERT((hubd->h_bus_ctls || hubd->h_bus_pwr ||
2805 hubd->h_hotplug_thread) == 0);
2806 mutex_exit(HUBD_MUTEX(hubd));
2812 if (hubd->h_ndi_event_hdl) {
2814 rval = ndi_event_free_hdl(hubd->h_ndi_event_hdl);
2822 USB_DPRINTF_L2(DPRINT_MASK_ALL, hubd->h_log_handle,
2831 mutex_enter(HUBD_MUTEX(hubd));
2833 if (hubd->h_init_state & HUBD_CHILDREN_CREATED) {
2835 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
2836 ASSERT(hubd->h_usba_devices[port] == NULL);
2837 ASSERT(hubd->h_children_dips[port] == NULL);
2840 kmem_free(hubd->h_children_dips, hubd->h_cd_list_length);
2841 kmem_free(hubd->h_usba_devices, hubd->h_cd_list_length);
2852 if (hubd->h_init_state & HUBD_EVENTS_REGISTERED) {
2853 mutex_exit(HUBD_MUTEX(hubd));
2855 hubd_unregister_cpr_callback(hubd);
2856 mutex_enter(HUBD_MUTEX(hubd));
2860 hubd->h_dev_state = old_dev_state;
2861 hubpm = hubd->h_hubpm;
2863 if ((hubpm) && (hubd->h_dev_state != USB_DEV_DISCONNECTED)) {
2864 (void) hubd_pm_busy_component(hubd, dip, 0);
2865 mutex_exit(HUBD_MUTEX(hubd));
2866 if (hubd->h_hubpm->hubp_wakeup_enabled) {
2873 if ((rval = usb_handle_remote_wakeup(hubd->h_dip,
2876 hubd->h_log_handle,
2882 (void) pm_lower_power(hubd->h_dip, 0, USB_DEV_OS_PWR_OFF);
2884 mutex_enter(HUBD_MUTEX(hubd));
2885 (void) hubd_pm_idle_component(hubd, dip, 0);
2895 mutex_exit(HUBD_MUTEX(hubd));
2897 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
2900 if (hubd->h_init_state & HUBD_HUBDI_REGISTERED) {
2905 if (hubd->h_init_state & HUBD_LOCKS_DONE) {
2906 mutex_destroy(HUBD_MUTEX(hubd));
2907 cv_destroy(&hubd->h_cv_reset_port);
2908 cv_destroy(&hubd->h_cv_hotplug_dev);
2913 if (hubd->h_init_state & HUBD_MINOR_NODE_CREATED) {
2918 usb_pipe_close(dip, hubd->h_default_pipe,
2923 if (hubd->h_ancestry_str) {
2924 kmem_free(hubd->h_ancestry_str, HUBD_APID_NAMELEN);
2927 usb_client_detach(dip, hubd->h_dev_data);
2929 usb_free_log_hdl(hubd->h_log_handle);
2949 hubd_determine_port_connection(hubd_t *hubd)
2957 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
2959 hub_descr = &hubd->h_hub_descr;
2963 (void) hubd_determine_port_status(hubd, port, &status,
2997 hubd_check_ports(hubd_t *hubd)
3003 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
3005 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
3006 "hubd_check_ports: addr=0x%x", usb_get_addr(hubd->h_dip));
3011 if ((rval = hubd_disable_all_port_power(hubd)) != USB_SUCCESS) {
3014 (void) hubd_disable_all_port_power(hubd);
3023 mutex_exit(HUBD_MUTEX(hubd));
3025 mutex_enter(HUBD_MUTEX(hubd));
3030 if ((rval = hubd_enable_all_port_power(hubd)) != USB_SUCCESS) {
3032 (void) hubd_disable_all_port_power(hubd);
3038 mutex_exit(HUBD_MUTEX(hubd));
3040 mutex_enter(HUBD_MUTEX(hubd));
3047 hubd->h_cd_list_length =
3048 (sizeof (dev_info_t **)) * (hubd->h_hub_descr.bNbrPorts + 1);
3050 hubd->h_children_dips = (dev_info_t **)kmem_zalloc(
3051 hubd->h_cd_list_length, KM_SLEEP);
3052 hubd->h_usba_devices = (usba_device_t **)kmem_zalloc(
3053 hubd->h_cd_list_length, KM_SLEEP);
3055 hubd->h_init_state |= HUBD_CHILDREN_CREATED;
3057 mutex_exit(HUBD_MUTEX(hubd));
3060 mutex_enter(HUBD_MUTEX(hubd));
3062 if ((rval = hubd_open_intr_pipe(hubd)) != USB_SUCCESS) {
3068 hubd_start_polling(hubd, 0);
3080 port_change = hubd_determine_port_connection(hubd);
3083 hubd_pm_busy_component(hubd, hubd->h_dip, 0);
3085 arg->hubd = hubd;
3087 hubd->h_port_change |= port_change;
3089 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
3091 hubd->h_port_change);
3093 if (usb_async_req(hubd->h_dip, hubd_hotplug_thread,
3095 hubd->h_hotplug_thread++;
3098 hubd_pm_idle_component(hubd, hubd->h_dip, 0);
3105 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
3116 hubd_get_hub_descriptor(hubd_t *hubd)
3118 usb_hub_descr_t *hub_descr = &hubd->h_hub_descr;
3126 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3129 if ((hubd->h_dev_data->dev_descr->idVendor == USB_HUB_INTEL_VID) &&
3130 (hubd->h_dev_data->dev_descr->idProduct == USB_HUB_INTEL_PID)) {
3134 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
3135 ASSERT(hubd->h_default_pipe != 0);
3138 mutex_exit(HUBD_MUTEX(hubd));
3140 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
3141 hubd->h_default_pipe,
3149 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
3153 mutex_enter(HUBD_MUTEX(hubd));
3165 rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
3166 hubd->h_default_pipe,
3180 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
3186 mutex_enter(HUBD_MUTEX(hubd));
3192 mutex_enter(HUBD_MUTEX(hubd));
3200 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
3210 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
3217 USB_DPRINTF_L0(DPRINT_MASK_ATTA, hubd->h_log_handle,
3233 hubd_get_hub_status_words(hubd_t *hubd, uint16_t *status)
3239 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
3241 mutex_exit(HUBD_MUTEX(hubd));
3243 if (usb_pipe_sync_ctrl_xfer(hubd->h_dip, hubd->h_default_pipe,
3251 USB_DPRINTF_L2(DPRINT_MASK_HUB, hubd->h_log_handle,
3259 mutex_enter(HUBD_MUTEX(hubd));
3264 mutex_enter(HUBD_MUTEX(hubd));
3269 USB_DPRINTF_L3(DPRINT_MASK_HUB, hubd->h_log_handle,
3284 hubd_open_intr_pipe(hubd_t *hubd)
3288 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3291 ASSERT(hubd->h_intr_pipe_state == HUBD_INTR_PIPE_IDLE);
3293 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_OPENING;
3294 mutex_exit(HUBD_MUTEX(hubd));
3296 if ((rval = usb_pipe_open(hubd->h_dip,
3297 &hubd->h_ep1_descr, &hubd->h_pipe_policy,
3298 0, &hubd->h_ep1_ph)) != USB_SUCCESS) {
3299 USB_DPRINTF_L2(DPRINT_MASK_HUB, hubd->h_log_handle,
3302 mutex_enter(HUBD_MUTEX(hubd));
3303 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_IDLE;
3308 mutex_enter(HUBD_MUTEX(hubd));
3309 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_ACTIVE;
3311 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3312 "open intr pipe succeeded, ph=0x%p", (void *)hubd->h_ep1_ph);
3323 hubd_start_polling(hubd_t *hubd, int always)
3329 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3332 always, hubd->h_dev_state, hubd->h_intr_pipe_state,
3333 hubd->h_hotplug_thread, (void *)hubd->h_ep1_ph);
3340 ((hubd->h_dev_state == USB_DEV_ONLINE) &&
3341 (hubd->h_intr_pipe_state == HUBD_INTR_PIPE_ACTIVE) &&
3342 (hubd->h_hotplug_thread == 0) && hubd->h_ep1_ph)) {
3343 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3346 reqp = usb_alloc_intr_req(hubd->h_dip, 0, USB_FLAGS_SLEEP);
3348 reqp->intr_client_private = (usb_opaque_t)hubd;
3351 reqp->intr_len = hubd->h_ep1_descr.wMaxPacketSize;
3354 mutex_exit(HUBD_MUTEX(hubd));
3355 if ((rval = usb_pipe_intr_xfer(hubd->h_ep1_ph, reqp,
3357 USB_DPRINTF_L2(DPRINT_MASK_HUB, hubd->h_log_handle,
3362 rval = usb_pipe_get_state(hubd->h_ep1_ph, &pipe_state,
3365 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
3368 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3371 mutex_enter(HUBD_MUTEX(hubd));
3381 hubd_stop_polling(hubd_t *hubd)
3386 if (hubd->h_ep1_ph) {
3387 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
3389 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_STOPPED;
3390 mutex_exit(HUBD_MUTEX(hubd));
3392 usb_pipe_stop_intr_polling(hubd->h_ep1_ph, USB_FLAGS_SLEEP);
3393 rval = usb_pipe_get_state(hubd->h_ep1_ph, &pipe_state,
3397 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
3400 mutex_enter(HUBD_MUTEX(hubd));
3401 if (hubd->h_intr_pipe_state == HUBD_INTR_PIPE_STOPPED) {
3402 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_ACTIVE;
3414 hubd_close_intr_pipe(hubd_t *hubd)
3416 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3423 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_CLOSING;
3425 ASSERT(hubd->h_hotplug_thread == 0);
3427 if (hubd->h_ep1_ph) {
3428 mutex_exit(HUBD_MUTEX(hubd));
3429 usb_pipe_close(hubd->h_dip, hubd->h_ep1_ph, USB_FLAGS_SLEEP,
3431 mutex_enter(HUBD_MUTEX(hubd));
3432 hubd->h_ep1_ph = NULL;
3435 hubd->h_intr_pipe_state = HUBD_INTR_PIPE_IDLE;
3449 hubd_t *hubd = (hubd_t *)(reqp->intr_client_private);
3451 USB_DPRINTF_L2(DPRINT_MASK_CALLBACK, hubd->h_log_handle,
3459 mutex_enter(HUBD_MUTEX(hubd));
3460 (void) hubd_pm_busy_component(hubd, hubd->h_dip, 0);
3465 if ((hubd->h_intr_pipe_state == HUBD_INTR_PIPE_ACTIVE) &&
3466 (hubd->h_port_reset_wait == 0)) {
3467 hubd_start_polling(hubd, 0);
3483 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
3484 mutex_exit(HUBD_MUTEX(hubd));
3524 hubd_t *hubd = (hubd_t *)(reqp->intr_client_private);
3530 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
3550 mutex_enter(HUBD_MUTEX(hubd));
3552 if ((hubd->h_dev_state == USB_DEV_SUSPENDED) ||
3553 (hubd->h_intr_pipe_state != HUBD_INTR_PIPE_ACTIVE)) {
3554 mutex_exit(HUBD_MUTEX(hubd));
3561 ASSERT(hubd->h_ep1_ph == pipe);
3582 hubd->h_port_change |= port_change &
3583 ~hubd->h_port_reset_wait;
3585 USB_DPRINTF_L3(DPRINT_MASK_CALLBACK, hubd->h_log_handle,
3587 hubd->h_port_change, hubd->h_port_reset_wait);
3590 if (hubd->h_port_reset_wait & port_change) {
3591 hubd->h_port_reset_wait = 0;
3592 cv_signal(&hubd->h_cv_reset_port);
3599 if ((hubd->h_dev_state == USB_DEV_ONLINE) &&
3600 (!DEVI_IS_ATTACHING(hubd->h_dip)) &&
3601 (!DEVI_IS_DETACHING(hubd->h_dip)) &&
3602 (hubd->h_port_change) &&
3603 (hubd->h_hotplug_thread == 0)) {
3604 USB_DPRINTF_L3(DPRINT_MASK_CALLBACK, hubd->h_log_handle,
3606 "dev_state=%d", hubd->h_dev_state);
3613 (void) hubd_pm_busy_component(hubd, hubd->h_dip, 0);
3615 arg->hubd = hubd;
3618 if (usb_async_req(hubd->h_dip,
3621 hubd->h_hotplug_thread++;
3625 (void) hubd_pm_idle_component(hubd,
3626 hubd->h_dip, 0);
3630 mutex_exit(HUBD_MUTEX(hubd));
3651 hubd_t *hubd = hd_arg->hubd;
3657 dev_info_t *hdip = hubd->h_dip;
3658 dev_info_t *rh_dip = hubd->h_usba_device->usb_root_hub_dip;
3665 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3687 mutex_enter(HUBD_MUTEX(hubd));
3688 if (hubd->h_bus_pwr || (hubd->h_hotplug_thread > 1)) {
3689 hubd->h_hotplug_thread--;
3692 hubd_pm_idle_component(hubd, hubd->h_dip, 0);
3693 mutex_exit(HUBD_MUTEX(hubd));
3695 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3701 mutex_exit(HUBD_MUTEX(hubd));
3705 mutex_enter(HUBD_MUTEX(hubd));
3709 if (hubd->h_dev_state == USB_DEV_PWRED_DOWN) {
3710 hubpm = hubd->h_hubpm;
3715 mutex_exit(HUBD_MUTEX(hubd));
3717 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3723 mutex_enter(HUBD_MUTEX(hubd));
3724 hubd->h_dev_state = USB_DEV_ONLINE;
3728 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3732 mutex_exit(HUBD_MUTEX(hubd));
3745 mutex_enter(HUBD_MUTEX(hubd));
3747 ASSERT(hubd->h_intr_pipe_state == HUBD_INTR_PIPE_ACTIVE);
3749 nports = hubd->h_hub_descr.bNbrPorts;
3751 hubd_stop_polling(hubd);
3753 while ((hubd->h_dev_state == USB_DEV_ONLINE) &&
3754 (hubd->h_port_change)) {
3759 if (hubd->h_port_change & HUB_CHANGE_STATUS) {
3760 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3767 hubd->h_port_change &= ~HUB_CHANGE_STATUS;
3774 (void) hubd_get_hub_status(hubd);
3783 (hubd->h_port_state[port] & PORT_STATUS_CCS) &&
3784 (hubd->h_children_dips[port]);
3786 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3789 port, port_mask, hubd->h_port_change,
3795 if ((hubd->h_port_change & port_mask) == 0) {
3799 hubd->h_port_change &= ~port_mask;
3802 (void) hubd_determine_port_status(hubd, port,
3805 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3813 hubd->h_log_handle,
3825 (hubd_recover_disabled_port(hubd,
3838 (hubd_handle_port_connect(hubd,
3849 child_dip = hubd->h_children_dips[port];
3851 mutex_exit(HUBD_MUTEX(hubd));
3867 hubd_post_event(hubd, port,
3869 mutex_enter(HUBD_MUTEX(hubd));
3877 hubd, port) == USB_SUCCESS);
3879 mutex_exit(HUBD_MUTEX(hubd));
3883 mutex_enter(HUBD_MUTEX(hubd));
3886 mutex_exit(HUBD_MUTEX(hubd));
3887 hubd_post_event(hubd, port,
3889 mutex_enter(HUBD_MUTEX(hubd));
3901 hubd->h_children_dips[port]) {
3906 dip = hubd->h_children_dips[port];
3925 hubd->h_port_state[port] |=
3928 mutex_exit(HUBD_MUTEX(hubd));
3936 mutex_enter(HUBD_MUTEX(hubd));
3946 hubd->h_log_handle,
3960 (void) hubd_enable_port_power(hubd,
3968 mutex_exit(HUBD_MUTEX(hubd));
3970 mutex_enter(HUBD_MUTEX(hubd));
3977 mutex_exit(HUBD_MUTEX(hubd));
3988 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3991 (void) ndi_devi_online(hubd->h_dip, 0);
3996 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
3999 hubd_schedule_cleanup(hubd->h_usba_device->usb_root_hub_dip);
4002 mutex_enter(HUBD_MUTEX(hubd));
4006 old_state = hubd->h_dev_state;
4007 hubd->h_dev_state = USB_DEV_HUB_CHILD_PWRLVL;
4009 if (hubd->h_port_state[port] & HUBD_CHILD_RAISE_POWER) {
4010 dev_info_t *dip = hubd->h_children_dips[port];
4012 mutex_exit(HUBD_MUTEX(hubd));
4022 mutex_enter(HUBD_MUTEX(hubd));
4023 hubd->h_port_state[port] &=
4031 if (hubd->h_dev_state == USB_DEV_HUB_CHILD_PWRLVL) {
4032 hubd->h_dev_state = old_state;
4046 if (hubd->h_reset_port[port]) {
4052 hubd_start_polling(hubd, HUBD_ALWAYS_START_POLLING);
4064 hubd->h_hotplug_thread--;
4067 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
4069 cv_broadcast(&hubd->h_cv_hotplug_dev);
4071 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4074 mutex_exit(HUBD_MUTEX(hubd));
4087 hubd_handle_port_connect(hubd_t *hubd, usb_port_t port)
4101 usba_device = hubd->h_usba_device;
4125 mutex_exit(HUBD_MUTEX(hubd));
4127 mutex_enter(HUBD_MUTEX(hubd));
4132 for (retry = 0; (hubd->h_dev_state == USB_DEV_ONLINE) &&
4134 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4137 if ((rval = hubd_reset_port(hubd, port)) != USB_SUCCESS) {
4138 (void) hubd_determine_port_status(hubd,
4159 (void) hubd_enable_port(hubd, port);
4167 mutex_exit(HUBD_MUTEX(hubd));
4169 mutex_enter(HUBD_MUTEX(hubd));
4178 (void) hubd_enable_port(hubd, port);
4181 if ((rval = hubd_determine_port_status(hubd, port, &status,
4184 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4187 (void) hubd_disable_port(hubd, port);
4193 USB_DPRINTF_L0(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4196 (void) hubd_disable_port(hubd, port);
4199 (void) hubd_determine_port_status(hubd,
4207 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4231 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4240 if (hubd->h_children_dips[port]) {
4242 rval = hubd_setdevaddr(hubd, port);
4250 mutex_exit(HUBD_MUTEX(hubd));
4253 mutex_enter(HUBD_MUTEX(hubd));
4261 if ((hubd->h_reset_port[port]) &&
4262 (hubd_check_same_device(hubd,
4273 hubd_setdevconfig(hubd, port);
4281 if (hubd->h_reset_port[port]) {
4290 mutex_exit(HUBD_MUTEX(hubd));
4291 hubd_post_event(hubd, port,
4293 mutex_enter(HUBD_MUTEX(hubd));
4310 rval = hubd_create_child(hubd->h_dip,
4311 hubd,
4312 hubd->h_usba_device,
4316 usba_update_hotplug_stats(hubd->h_dip,
4319 hubd->h_total_hotplug_success++;
4324 hubd->h_log_handle,
4339 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4342 (void) hubd_disable_port(hubd, port);
4344 mutex_exit(HUBD_MUTEX(hubd));
4346 mutex_enter(HUBD_MUTEX(hubd));
4349 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4366 hubd->h_log_handle,
4371 hubd->h_log_handle,
4375 (void) hubd_disable_port(hubd, port);
4376 usba_update_hotplug_stats(hubd->h_dip,
4378 hubd->h_total_hotplug_failure++;
4385 (void) hubd_disable_port(hubd, port);
4388 (void) hubd_determine_port_status(hubd,
4401 hubd_get_hub_status(hubd_t *hubd)
4416 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4419 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
4421 if ((hubd_get_hub_status_words(hubd, stword)) != USB_SUCCESS) {
4428 mutex_exit(HUBD_MUTEX(hubd));
4431 usb_cfg = usb_get_raw_cfg_data(hubd->h_dip, &cfg_length);
4439 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4442 mutex_enter(HUBD_MUTEX(hubd));
4467 hubd->h_log_handle,
4476 hubd->h_log_handle,
4485 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4488 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4489 hubd->h_default_pipe,
4498 hubd->h_log_handle,
4510 if (usba_is_root_hub(hubd->h_dip)) {
4518 hubd->h_log_handle,
4535 hubd->h_log_handle,
4544 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
4547 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4548 hubd->h_default_pipe,
4557 hubd->h_log_handle,
4568 if (!usba_is_root_hub(hubd->h_dip)) {
4570 mutex_enter(HUBD_MUTEX(hubd));
4576 (void) hubd_determine_port_status(hubd, 1, &status,
4584 hub_descr = &hubd->h_hub_descr;
4589 (void) hubd_enable_port_power(hubd, port);
4592 mutex_exit(HUBD_MUTEX(hubd));
4602 mutex_enter(HUBD_MUTEX(hubd));
4612 hubd_reset_port(hubd_t *hubd, usb_port_t port)
4624 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4627 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
4629 hubd->h_port_reset_wait |= port_mask;
4631 mutex_exit(HUBD_MUTEX(hubd));
4633 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4634 hubd->h_default_pipe,
4642 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
4646 mutex_enter(HUBD_MUTEX(hubd));
4651 mutex_enter(HUBD_MUTEX(hubd));
4653 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4665 hubd_start_polling(hubd, HUBD_ALWAYS_START_POLLING);
4671 if (hubd->h_port_reset_wait & port_mask) {
4672 rval = cv_reltimedwait(&hubd->h_cv_reset_port,
4673 &hubd->h_mutex, delta, TR_CLOCK_TICK);
4675 (hubd->h_port_reset_wait & port_mask)) {
4678 hubd->h_log_handle,
4681 hubd->h_port_reset_wait &= ~port_mask;
4683 hubd_stop_polling(hubd);
4689 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4692 hubd_stop_polling(hubd);
4697 mutex_exit(HUBD_MUTEX(hubd));
4698 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4699 hubd->h_default_pipe,
4708 hubd->h_log_handle,
4716 mutex_enter(HUBD_MUTEX(hubd));
4732 mutex_enter(HUBD_MUTEX(hubd));
4738 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4740 mutex_enter(HUBD_MUTEX(hubd));
4744 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4749 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4752 if (usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4753 hubd->h_default_pipe,
4762 hubd->h_log_handle,
4768 mutex_enter(HUBD_MUTEX(hubd));
4787 hubd_enable_port(hubd_t *hubd, usb_port_t port)
4793 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4796 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
4798 mutex_exit(HUBD_MUTEX(hubd));
4801 if (!usba_is_root_hub(hubd->h_dip)) {
4802 mutex_enter(HUBD_MUTEX(hubd));
4807 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4808 hubd->h_default_pipe,
4816 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
4821 mutex_enter(HUBD_MUTEX(hubd));
4823 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4834 hubd_disable_port(hubd_t *hubd, usb_port_t port)
4840 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4843 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
4845 mutex_exit(HUBD_MUTEX(hubd));
4847 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4848 hubd->h_default_pipe,
4856 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
4859 mutex_enter(HUBD_MUTEX(hubd));
4864 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4867 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4868 hubd->h_default_pipe,
4877 hubd->h_log_handle,
4882 mutex_enter(HUBD_MUTEX(hubd));
4887 mutex_enter(HUBD_MUTEX(hubd));
4897 hubd_determine_port_status(hubd_t *hubd, usb_port_t port,
4905 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
4907 hubd->h_port_state[port], ack_flag);
4909 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
4911 mutex_exit(HUBD_MUTEX(hubd));
4913 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
4914 hubd->h_default_pipe,
4922 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
4931 mutex_enter(HUBD_MUTEX(hubd));
4936 mutex_enter(HUBD_MUTEX(hubd));
4938 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
4951 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4957 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4960 hubd->h_port_state[port] |= (PORT_STATUS_CCS & ack_flag);
4962 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4965 hubd->h_port_state[port] &= ~(PORT_STATUS_CCS & ack_flag);
4969 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4972 hubd->h_port_state[port] |= (PORT_STATUS_PES & ack_flag);
4974 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4977 hubd->h_port_state[port] &= ~(PORT_STATUS_PES & ack_flag);
4981 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4984 hubd->h_port_state[port] |= (PORT_STATUS_PSS & ack_flag);
4986 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4989 hubd->h_port_state[port] &= ~(PORT_STATUS_PSS & ack_flag);
4993 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
4996 hubd->h_port_state[port] |= (PORT_CHANGE_PRSC & ack_flag);
4999 hubd->h_port_state[port] &= ~(PORT_CHANGE_PRSC & ack_flag);
5003 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
5006 hubd->h_port_state[port] |= (PORT_STATUS_POCI & ack_flag);
5009 hubd->h_port_state[port] &= ~(PORT_STATUS_POCI & ack_flag);
5013 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5016 hubd->h_port_state[port] |= (PORT_STATUS_PRS & ack_flag);
5018 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5021 hubd->h_port_state[port] &= ~(PORT_STATUS_PRS & ack_flag);
5024 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5027 hubd->h_port_state[port] |= (PORT_STATUS_PPS & ack_flag);
5029 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5032 hubd->h_port_state[port] &= ~(PORT_STATUS_PPS & ack_flag);
5035 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5038 hubd->h_port_state[port] |= (PORT_STATUS_LSDA & ack_flag);
5040 hubd->h_port_state[port] &= ~(PORT_STATUS_LSDA & ack_flag);
5043 hubd->h_log_handle, "port%d "
5046 hubd->h_port_state[port] |=
5050 hubd->h_log_handle, "port%d "
5053 hubd->h_port_state[port] &=
5062 mutex_exit(HUBD_MUTEX(hubd));
5064 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5066 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5067 hubd->h_default_pipe,
5076 hubd->h_log_handle,
5083 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5085 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5086 hubd->h_default_pipe,
5095 hubd->h_log_handle,
5102 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5105 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5106 hubd->h_default_pipe,
5115 hubd->h_log_handle,
5122 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5125 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5126 hubd->h_default_pipe,
5135 hubd->h_log_handle,
5142 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
5144 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5145 hubd->h_default_pipe,
5154 hubd->h_log_handle,
5160 mutex_enter(HUBD_MUTEX(hubd));
5163 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5164 "new port%d state 0x%x", port, hubd->h_port_state[port]);
5178 hubd_recover_disabled_port(hubd_t *hubd, usb_port_t port)
5185 (void) hubd_enable_port(hubd, port);
5188 (void) hubd_determine_port_status(hubd, port, &status, &change,
5192 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5196 mutex_exit(HUBD_MUTEX(hubd));
5197 hubd_post_event(hubd, port, USBA_EVENT_TAG_HOT_REMOVAL);
5198 mutex_enter(HUBD_MUTEX(hubd));
5201 rval = hubd_handle_port_connect(hubd, port);
5203 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5215 hubd_enable_all_port_power(hubd_t *hubd)
5224 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5227 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
5229 hub_descr = &hubd->h_hub_descr;
5247 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5261 hubd->h_log_handle,
5264 (void) hubd_enable_port_power(hubd, port);
5267 mutex_exit(HUBD_MUTEX(hubd));
5269 mutex_enter(HUBD_MUTEX(hubd));
5278 (void) hubd_determine_port_status(hubd, port,
5284 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
5288 (void) hubd_enable_port_power(hubd, port);
5290 mutex_exit(HUBD_MUTEX(hubd));
5292 mutex_enter(HUBD_MUTEX(hubd));
5295 (void) hubd_determine_port_status(hubd, port,
5302 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
5317 hubd_enable_port_power(hubd_t *hubd, usb_port_t port)
5323 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5326 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
5327 ASSERT(hubd->h_default_pipe != 0);
5329 mutex_exit(HUBD_MUTEX(hubd));
5331 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5332 hubd->h_default_pipe,
5339 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
5342 mutex_enter(HUBD_MUTEX(hubd));
5346 mutex_enter(HUBD_MUTEX(hubd));
5347 hubd->h_port_state[port] |= PORT_STATUS_PPS;
5358 hubd_disable_all_port_power(hubd_t *hubd)
5362 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5365 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
5370 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
5371 (void) hubd_disable_port_power(hubd, port);
5383 hubd_disable_port_power(hubd_t *hubd, usb_port_t port)
5389 USB_DPRINTF_L4(DPRINT_MASK_PORT, hubd->h_log_handle,
5392 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
5394 mutex_exit(HUBD_MUTEX(hubd));
5396 if ((rval = usb_pipe_sync_ctrl_xfer(hubd->h_dip,
5397 hubd->h_default_pipe,
5404 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
5408 mutex_enter(HUBD_MUTEX(hubd));
5413 mutex_enter(HUBD_MUTEX(hubd));
5415 hubd->h_port_state[port] &= ~PORT_STATUS_PPS;
5427 hubd_select_device_configuration(hubd_t *hubd, usb_port_t port,
5454 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5467 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5482 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5503 hubd_get_this_config_cloud(hubd_t *hubd, dev_info_t *dip,
5515 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5542 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5562 hubd->h_log_handle,
5572 hubd->h_log_handle,
5600 hubd->h_log_handle,
5628 hubd->h_log_handle,
5652 hubd->h_log_handle,
5667 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5690 hubd_get_all_device_config_cloud(hubd_t *hubd, dev_info_t *dip,
5701 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5726 rval = hubd_get_this_config_cloud(hubd, dip, child_ud,
5742 hubd_ready_device(hubd_t *hubd, dev_info_t *child_dip, usba_device_t *child_ud,
5752 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5826 hubd_t *hubd,
5851 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5854 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
5855 ASSERT(hubd->h_usba_devices[port] == NULL);
5857 mutex_exit(HUBD_MUTEX(hubd));
5873 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5882 parent_ud = hubd->h_usba_device;
5920 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5929 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5953 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5966 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5983 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5990 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
5997 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6013 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6022 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6051 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6062 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6078 hubd->h_log_handle,
6103 hubd->h_log_handle,
6118 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6129 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6148 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6172 rval = hubd_get_all_device_config_cloud(hubd, child_dip, child_ud);
6174 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6181 user_conf_index = hubd_select_device_configuration(hubd, port,
6187 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6237 hubd->h_log_handle,
6275 child_dip = hubd_ready_device(hubd, child_dip,
6282 mutex_enter(HUBD_MUTEX(hubd));
6283 hubd->h_children_dips[port] = child_dip;
6284 mutex_exit(HUBD_MUTEX(hubd));
6298 child_dip = hubd_ready_device(hubd, child_dip,
6305 mutex_enter(HUBD_MUTEX(hubd));
6306 hubd->h_children_dips[port] = child_dip;
6307 mutex_exit(HUBD_MUTEX(hubd));
6343 child_dip = hubd_ready_device(hubd, child_dip,
6345 mutex_enter(HUBD_MUTEX(hubd));
6346 hubd->h_children_dips[port] = child_dip;
6347 mutex_exit(HUBD_MUTEX(hubd));
6358 child_dip = hubd_ready_device(hubd, child_dip,
6365 mutex_enter(HUBD_MUTEX(hubd));
6366 hubd->h_children_dips[port] = child_dip;
6367 mutex_exit(HUBD_MUTEX(hubd));
6374 mutex_enter(HUBD_MUTEX(hubd));
6375 if (hubd->h_usba_devices[port] == NULL) {
6376 hubd->h_usba_devices[port] = usba_get_usba_device(child_dip);
6378 ASSERT(hubd->h_usba_devices[port] ==
6386 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6389 mutex_enter(HUBD_MUTEX(hubd));
6390 hubd->h_children_dips[port] = NULL;
6391 mutex_exit(HUBD_MUTEX(hubd));
6406 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6418 mutex_enter(HUBD_MUTEX(hubd));
6419 if (hubd->h_usba_devices[port] == NULL) {
6420 mutex_exit(HUBD_MUTEX(hubd));
6423 hubd_free_usba_device(hubd, hubd->h_usba_devices[port]);
6424 mutex_exit(HUBD_MUTEX(hubd));
6428 mutex_enter(HUBD_MUTEX(hubd));
6441 hubd_delete_child(hubd_t *hubd, usb_port_t port, uint_t flag, boolean_t retry)
6447 child_dip = hubd->h_children_dips[port];
6448 usba_device = hubd->h_usba_devices[port];
6450 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6454 mutex_exit(HUBD_MUTEX(hubd));
6456 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6462 usba_hubdi_incr_power_budget(hubd->h_dip, usba_device);
6486 mutex_enter(HUBD_MUTEX(hubd));
6487 if (hubd->h_children_dips[port] == child_dip) {
6489 hubd->h_usba_devices[port];
6490 hubd->h_children_dips[port] = NULL;
6492 mutex_exit(HUBD_MUTEX(hubd));
6499 mutex_enter(HUBD_MUTEX(hubd));
6500 hubd->h_usba_devices[port] = NULL;
6503 mutex_exit(HUBD_MUTEX(hubd));
6511 mutex_enter(HUBD_MUTEX(hubd));
6523 hubd_free_usba_device(hubd_t *hubd, usba_device_t *usba_device)
6525 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6526 "hubd_free_usba_device: hubd=0x%p, usba_device=0x%p",
6527 (void *)hubd, (void *)usba_device);
6531 dev_info_t *dip = hubd->h_children_dips[port];
6540 hubd->h_usba_devices[port] = NULL;
6542 mutex_exit(HUBD_MUTEX(hubd));
6544 mutex_enter(HUBD_MUTEX(hubd));
6560 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6562 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6565 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6571 return (ndi_event_retrieve_cookie(hubd->h_ndi_event_hdl,
6585 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6586 usb_port_t port = hubd_child_dip2port(hubd, rdip);
6588 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6592 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6596 ndi_event_cookie_to_name(hubd->h_ndi_event_hdl, cookie));
6599 switch (ndi_event_cookie_to_tag(hubd->h_ndi_event_hdl, cookie)) {
6601 mutex_enter(HUBD_MUTEX(hubd));
6602 hubd->h_child_events[port] |= HUBD_CHILD_EVENT_DISCONNECT;
6603 mutex_exit(HUBD_MUTEX(hubd));
6607 mutex_enter(HUBD_MUTEX(hubd));
6608 hubd->h_child_events[port] |= HUBD_CHILD_EVENT_PRESUSPEND;
6609 mutex_exit(HUBD_MUTEX(hubd));
6618 return (ndi_event_add_callback(hubd->h_ndi_event_hdl,
6626 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6629 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6633 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6638 ndi_event_cookie_to_name(hubd->h_ndi_event_hdl,
6642 return (ndi_event_remove_callback(hubd->h_ndi_event_hdl, cb_id));
6653 hubd_do_callback(hubd_t *hubd, dev_info_t *cdip, ddi_eventcookie_t cookie)
6655 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6658 (void) ndi_event_do_callback(hubd->h_ndi_event_hdl, cdip, cookie, NULL);
6667 hubd_run_callbacks(hubd_t *hubd, usba_event_t type)
6671 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6674 mutex_enter(HUBD_MUTEX(hubd));
6675 for (port = 1; port <= hubd->h_hub_descr.bNbrPorts; port++) {
6681 if (hubd->h_children_dips[port]) {
6682 mutex_exit(HUBD_MUTEX(hubd));
6683 hubd_post_event(hubd, port, type);
6684 mutex_enter(HUBD_MUTEX(hubd));
6687 mutex_exit(HUBD_MUTEX(hubd));
6696 hubd_post_event(hubd_t *hubd, usb_port_t port, usba_event_t type)
6703 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6705 ndi_event_tag_to_name(hubd->h_ndi_event_hdl, type));
6707 cookie = ndi_event_tag_to_cookie(hubd->h_ndi_event_hdl, type);
6708 rm_cookie = ndi_event_tag_to_cookie(hubd->h_ndi_event_hdl,
6710 suspend_cookie = ndi_event_tag_to_cookie(hubd->h_ndi_event_hdl,
6719 mutex_enter(HUBD_MUTEX(hubd));
6720 dip = hubd->h_children_dips[port];
6721 usba_device = hubd->h_usba_devices[port];
6722 mutex_exit(HUBD_MUTEX(hubd));
6727 mutex_enter(HUBD_MUTEX(hubd));
6728 hubd->h_child_events[port] &= ~HUBD_CHILD_EVENT_DISCONNECT;
6729 mutex_exit(HUBD_MUTEX(hubd));
6731 hubd_do_callback(hubd, dip, cookie);
6745 mutex_enter(HUBD_MUTEX(hubd));
6746 hubd->h_child_events[port] &= ~HUBD_CHILD_EVENT_PRESUSPEND;
6747 mutex_exit(HUBD_MUTEX(hubd));
6749 hubd_do_callback(hubd, dip, cookie);
6761 mutex_enter(HUBD_MUTEX(hubd));
6762 if (hubd->h_child_events[port] & HUBD_CHILD_EVENT_DISCONNECT) {
6764 hubd->h_child_events[port] &=
6766 mutex_exit(HUBD_MUTEX(hubd));
6767 hubd_do_callback(hubd, dip, rm_cookie);
6769 mutex_enter(HUBD_MUTEX(hubd));
6771 mutex_exit(HUBD_MUTEX(hubd));
6784 hubd->h_log_handle,
6788 hubd_do_callback(hubd, dip, cookie);
6796 mutex_enter(HUBD_MUTEX(hubd));
6797 hubd->h_child_events[port] |= HUBD_CHILD_EVENT_DISCONNECT;
6798 mutex_exit(HUBD_MUTEX(hubd));
6806 mutex_enter(HUBD_MUTEX(hubd));
6807 if (hubd->h_child_events[port] & HUBD_CHILD_EVENT_PRESUSPEND) {
6809 hubd->h_port_state[port] &=
6811 mutex_exit(HUBD_MUTEX(hubd));
6812 hubd_do_callback(hubd, dip, suspend_cookie);
6813 mutex_enter(HUBD_MUTEX(hubd));
6815 mutex_exit(HUBD_MUTEX(hubd));
6826 hubd_do_callback(hubd, dip, cookie);
6833 mutex_enter(HUBD_MUTEX(hubd));
6834 hubd->h_child_events[port] |= HUBD_CHILD_EVENT_PRESUSPEND;
6835 mutex_exit(HUBD_MUTEX(hubd));
6847 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6853 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6858 mutex_enter(HUBD_MUTEX(hubd));
6859 switch (hubd->h_dev_state) {
6862 hubd->h_dev_state = USB_DEV_DISCONNECTED;
6864 hubd_stop_polling(hubd);
6869 mutex_exit(HUBD_MUTEX(hubd));
6870 hubd_run_callbacks(hubd, tag);
6871 mutex_enter(HUBD_MUTEX(hubd));
6874 nports = hubd->h_hub_descr.bNbrPorts;
6876 usba_dev = hubd->h_usba_devices[port];
6878 mutex_exit(HUBD_MUTEX(hubd));
6880 mutex_enter(HUBD_MUTEX(hubd));
6887 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6892 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6894 hubd->h_dev_state);
6898 mutex_exit(HUBD_MUTEX(hubd));
6927 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6929 USB_DPRINTF_L4(DPRINT_MASK_EVENTS, hubd->h_log_handle,
6933 mutex_enter(HUBD_MUTEX(hubd));
6934 hubd->h_hotplug_thread++;
6935 hubd_stop_polling(hubd);
6938 (void) hubd_pm_busy_component(hubd, hubd->h_dip, 0);
6939 mutex_exit(HUBD_MUTEX(hubd));
6942 hubd_run_callbacks(hubd, USBA_EVENT_TAG_PRE_SUSPEND);
6957 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
6959 USB_DPRINTF_L4(DPRINT_MASK_EVENTS, hubd->h_log_handle,
6963 hubd_run_callbacks(hubd, USBA_EVENT_TAG_POST_RESUME);
6966 mutex_enter(HUBD_MUTEX(hubd));
6969 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
6972 hubd->h_hotplug_thread--;
6975 hubd_start_polling(hubd, 0);
6976 mutex_exit(HUBD_MUTEX(hubd));
6987 hubd_cpr_suspend(hubd_t *hubd)
6994 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6998 mutex_enter(HUBD_MUTEX(hubd));
6999 hubd_pm_busy_component(hubd, hubd->h_dip, 0);
7000 mutex_exit(HUBD_MUTEX(hubd));
7003 (void) pm_raise_power(hubd->h_dip, 0, USB_DEV_OS_FULL_PWR);
7004 mutex_enter(HUBD_MUTEX(hubd));
7006 switch (hubd->h_dev_state) {
7011 nports = hubd->h_hub_descr.bNbrPorts;
7013 usba_dev = hubd->h_usba_devices[port];
7021 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
7031 if ((hubd->h_hotplug_thread > 1) ||
7032 (hubd->h_cleanup_active == B_TRUE)) {
7034 hubd->h_log_handle,
7042 hubd_stop_polling(hubd);
7046 usba_dev = hubd->h_usba_devices[port];
7048 mutex_exit(HUBD_MUTEX(hubd));
7050 if (hubd_suspend_port(hubd, port)) {
7053 hubd->h_log_handle,
7057 mutex_enter(HUBD_MUTEX(hubd));
7061 hubd->h_dev_state = USB_DEV_SUSPENDED;
7067 if (usba_is_root_hub(hubd->h_dip)) {
7068 mutex_exit(HUBD_MUTEX(hubd));
7070 usba_get_usba_device(hubd->h_dip));
7071 mutex_enter(HUBD_MUTEX(hubd));
7079 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
7081 hubd->h_dev_state);
7086 hubd_pm_idle_component(hubd, hubd->h_dip, 0);
7087 mutex_exit(HUBD_MUTEX(hubd));
7119 hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip);
7121 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
7125 hubd_restore_device_state(dip, hubd);
7135 hubd_register_events(hubd_t *hubd)
7139 if (usba_is_root_hub(hubd->h_dip)) {
7140 hubd_register_cpr_callback(hubd);
7142 rval = usb_register_event_cbs(hubd->h_dip, &hubd_events, 0);
7150 * hubd cpr callback related functions
7162 hubd_t *hubd = cpr_cb->statep;
7165 USB_DPRINTF_L4(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7170 USB_DPRINTF_L3(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7173 mutex_enter(HUBD_MUTEX(hubd));
7176 hubd->h_cleanup_enabled = B_FALSE;
7179 while ((hubd->h_cleanup_active == B_TRUE) && (retry++ < 3)) {
7180 mutex_exit(HUBD_MUTEX(hubd));
7183 USB_DPRINTF_L2(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7186 mutex_enter(HUBD_MUTEX(hubd));
7189 mutex_exit(HUBD_MUTEX(hubd));
7192 (void) hubd_pre_suspend_event_cb(hubd->h_dip);
7196 USB_DPRINTF_L3(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7200 (void) hubd_post_resume_event_cb(hubd->h_dip);
7203 mutex_enter(HUBD_MUTEX(hubd));
7204 hubd->h_cleanup_enabled = B_TRUE;
7205 mutex_exit(HUBD_MUTEX(hubd));
7207 hubd_schedule_cleanup(hubd->h_usba_device->usb_root_hub_dip);
7220 hubd_register_cpr_callback(hubd_t *hubd)
7222 USB_DPRINTF_L4(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7225 mutex_enter(HUBD_MUTEX(hubd));
7226 hubd->h_cpr_cb =
7228 mutex_exit(HUBD_MUTEX(hubd));
7229 mutex_init(&hubd->h_cpr_cb->lockp, NULL, MUTEX_DRIVER,
7230 hubd->h_dev_data->dev_iblock_cookie);
7231 hubd->h_cpr_cb->statep = hubd;
7232 hubd->h_cpr_cb->cpr.cc_lockp = &hubd->h_cpr_cb->lockp;
7233 hubd->h_cpr_cb->cpr.cc_id = callb_add(hubd_cpr_post_user_callb,
7234 (void *)hubd->h_cpr_cb, CB_CL_CPR_POST_USER, "hubd");
7240 hubd_unregister_cpr_callback(hubd_t *hubd)
7242 USB_DPRINTF_L4(DPRINT_MASK_EVENTS, hubd->h_log_handle,
7245 if (hubd->h_cpr_cb) {
7246 (void) callb_delete(hubd->h_cpr_cb->cpr.cc_id);
7247 mutex_destroy(&hubd->h_cpr_cb->lockp);
7248 mutex_enter(HUBD_MUTEX(hubd));
7249 kmem_free(hubd->h_cpr_cb, sizeof (hubd_cpr_t));
7250 mutex_exit(HUBD_MUTEX(hubd));
7261 hubd_create_pm_components(dev_info_t *dip, hubd_t *hubd)
7265 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
7271 hubd->h_hubpm = hubpm;
7272 hubpm->hubp_hubd = hubd;
7293 USB_DPRINTF_L2(DPRINT_MASK_PM, hubd->h_log_handle,
7299 mutex_enter(HUBD_MUTEX(hubd));
7304 hubd_pm_busy_component(hubd, dip, 0);
7305 mutex_exit(HUBD_MUTEX(hubd));
7313 USB_DPRINTF_L4(DPRINT_MASK_PM, hubd->h_log_handle,
7326 hubd_t *hubd;
7331 hubd = hubd_get_soft_state(dip);
7332 if (hubd == NULL) {
7336 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7339 mutex_enter(HUBD_MUTEX(hubd));
7340 if ((flags & FEXCL) && (hubd->h_softstate & HUBD_SS_ISOPEN)) {
7341 mutex_exit(HUBD_MUTEX(hubd));
7346 hubd->h_softstate |= HUBD_SS_ISOPEN;
7347 mutex_exit(HUBD_MUTEX(hubd));
7349 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle, "opened");
7360 hubd_t *hubd;
7366 hubd = hubd_get_soft_state(dip);
7368 if (hubd == NULL) {
7372 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle, "hubd_close:");
7374 mutex_enter(HUBD_MUTEX(hubd));
7375 hubd->h_softstate &= ~HUBD_SS_ISOPEN;
7376 mutex_exit(HUBD_MUTEX(hubd));
7378 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle, "closed");
7394 hubd_t *hubd;
7403 if ((hubd = hubd_get_soft_state(self)) == NULL) {
7408 rh_dip = hubd->h_usba_device->usb_root_hub_dip;
7410 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7427 mutex_enter(HUBD_MUTEX(hubd));
7433 if (hubd->h_dev_state == USB_DEV_DISCONNECTED) {
7434 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
7435 "hubd: already gone");
7436 mutex_exit(HUBD_MUTEX(hubd));
7446 if ((port = hubd_get_port_num(hubd, dcp)) == 0) {
7447 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
7448 "hubd: bad port");
7449 mutex_exit(HUBD_MUTEX(hubd));
7462 mutex_exit(HUBD_MUTEX(hubd));
7471 if (hubd->h_dev_state == USB_DEV_SUSPENDED) {
7472 mutex_exit(HUBD_MUTEX(hubd));
7480 if (hubd->h_reset_port[port]) {
7481 USB_DPRINTF_L2(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7483 mutex_exit(HUBD_MUTEX(hubd));
7491 hubd_pm_busy_component(hubd, hubd->h_dip, 0);
7492 mutex_exit(HUBD_MUTEX(hubd));
7495 (void) pm_raise_power(hubd->h_dip, 0, USB_DEV_OS_FULL_PWR);
7499 ndi_devi_enter(hubd->h_dip, &circ);
7501 mutex_enter(HUBD_MUTEX(hubd));
7503 hubd->h_hotplug_thread++;
7506 if (hubd->h_ep1_ph) {
7507 mutex_exit(HUBD_MUTEX(hubd));
7508 (void) usb_pipe_get_state(hubd->h_ep1_ph, &prev_pipe_state,
7510 mutex_enter(HUBD_MUTEX(hubd));
7513 hubd_stop_polling(hubd);
7519 if (hubd_delete_child(hubd, port,
7526 if (hubd_delete_child(hubd, port,
7534 if (hubd_toggle_port(hubd, port) != USB_SUCCESS) {
7540 (void) hubd_handle_port_connect(hubd, port);
7541 child_dip = hubd_get_child_dip(hubd, port);
7542 mutex_exit(HUBD_MUTEX(hubd));
7544 ndi_devi_exit(hubd->h_dip, circ);
7557 ndi_devi_enter(hubd->h_dip, &circ);
7559 mutex_enter(HUBD_MUTEX(hubd));
7563 switch (hubd_cfgadm_state(hubd, port)) {
7602 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7648 USB_DPRINTF_L3(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7674 hubd->h_log_handle,
7684 if ((child_dip = hubd_get_child_dip(hubd,
7694 hubd->h_log_handle,
7706 hubd->h_log_handle,
7721 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7725 if ((child_dip = hubd_get_child_dip(hubd, ioc.port)) ==
7755 hubd->h_log_handle,
7772 hubd->h_log_handle,
7781 hubd->h_log_handle,
7790 hubd->h_log_handle,
7800 hubd->h_log_handle,
7815 if ((child_dip = hubd_get_child_dip(hubd, ioc.port)) ==
7828 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7835 hubd->h_log_handle,
7844 hubd->h_log_handle,
7854 hubd->h_log_handle,
7876 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7884 if ((child_dip = hubd_get_child_dip(hubd, ioc.port)) ==
7900 hubd->h_log_handle,
7909 hubd->h_log_handle,
7918 hubd->h_log_handle,
7932 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7936 if ((child_dip = hubd_get_child_dip(hubd, ioc.port)) ==
7949 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7957 hubd->h_log_handle,
7964 hubd->h_log_handle,
7970 hubd->h_log_handle,
7981 USB_DPRINTF_L3(DPRINT_MASK_CBOPS, hubd->h_log_handle,
7986 hubd->h_log_handle,
8008 hubd->h_hotplug_thread--;
8010 if ((hubd->h_dev_state == USB_DEV_ONLINE) &&
8011 hubd->h_ep1_ph && (prev_pipe_state == USB_PIPE_STATE_ACTIVE)) {
8012 hubd_start_polling(hubd, 0);
8014 mutex_exit(HUBD_MUTEX(hubd));
8016 ndi_devi_exit(hubd->h_dip, circ);
8020 mutex_enter(HUBD_MUTEX(hubd));
8021 hubd_pm_idle_component(hubd, hubd->h_dip, 0);
8022 mutex_exit(HUBD_MUTEX(hubd));
8043 hubd_get_ancestry_str(hubd_t *hubd)
8050 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
8051 "hubd_get_ancestry_str: hubd=0x%p", (void *)hubd);
8053 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8063 if (usba_is_root_hub(hubd->h_dip)) {
8064 hubd->h_ancestry_str[0] = '\0';
8066 port = hubd->h_usba_device->usb_port;
8067 mutex_exit(HUBD_MUTEX(hubd));
8069 pdip = ddi_get_parent(hubd->h_dip);
8086 mutex_enter(HUBD_MUTEX(hubd));
8087 (void) strcpy(hubd->h_ancestry_str, ap_name);
8088 (void) strcat(hubd->h_ancestry_str, ".");
8095 hubd_get_port_num(hubd_t *hubd, struct devctl_iocdata *dcp)
8099 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8103 USB_DPRINTF_L2(DPRINT_MASK_CBOPS, hubd->h_log_handle,
8108 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
8109 "hubd_get_port_num: hubd=0x%p, port=%d", (void *)hubd, port);
8117 hubd_get_child_dip(hubd_t *hubd, usb_port_t port)
8119 dev_info_t *child_dip = hubd->h_children_dips[port];
8121 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
8122 "hubd_get_child_dip: hubd=0x%p, port=%d", (void *)hubd, port);
8124 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8143 hubd_cfgadm_state(hubd_t *hubd, usb_port_t port)
8146 dev_info_t *child_dip = hubd_get_child_dip(hubd, port);
8149 if (hubd->h_port_state[port] & PORT_STATUS_CCS) {
8171 if (hubd->h_port_state[port] & PORT_STATUS_CCS) {
8180 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
8181 "hubd_cfgadm_state: hubd=0x%p, port=%d state=0x%x",
8182 (void *)hubd, port, state);
8192 hubd_toggle_port(hubd_t *hubd, usb_port_t port)
8200 USB_DPRINTF_L4(DPRINT_MASK_CBOPS, hubd->h_log_handle,
8201 "hubd_toggle_port: hubd=0x%p, port=%d", (void *)hubd, port);
8203 if ((hubd_disable_port_power(hubd, port)) != USB_SUCCESS) {
8212 mutex_exit(HUBD_MUTEX(hubd));
8214 mutex_enter(HUBD_MUTEX(hubd));
8216 hub_descr = &hubd->h_hub_descr;
8234 USB_DPRINTF_L3(DPRINT_MASK_PORT, hubd->h_log_handle,
8241 (void) hubd_enable_port_power(hubd, port);
8243 mutex_exit(HUBD_MUTEX(hubd));
8245 mutex_enter(HUBD_MUTEX(hubd));
8248 (void) hubd_determine_port_status(hubd, port,
8261 USB_DPRINTF_L2(DPRINT_MASK_PORT, hubd->h_log_handle,
8274 * Init power budget variables in hubd structure. According
8286 hubd_init_power_budget(hubd_t *hubd)
8295 if (hubd->h_ignore_pwr_budget) {
8300 USB_DPRINTF_L4(DPRINT_MASK_HUB, hubd->h_log_handle,
8303 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8304 ASSERT(hubd->h_default_pipe != 0);
8305 mutex_exit(HUBD_MUTEX(hubd));
8308 if ((usb_get_status(hubd->h_dip, hubd->h_default_pipe,
8311 mutex_enter(HUBD_MUTEX(hubd));
8316 hubd_ud = usba_get_usba_device(hubd->h_dip);
8322 USB_DPRINTF_L2(DPRINT_MASK_HUB, hubd->h_log_handle,
8324 mutex_enter(HUBD_MUTEX(hubd));
8329 mutex_enter(HUBD_MUTEX(hubd));
8331 hubd->h_local_pwr_capable = (cfg_descr.bmAttributes &
8334 if (hubd->h_local_pwr_capable) {
8335 USB_DPRINTF_L3(DPRINT_MASK_HUB, hubd->h_log_handle,
8339 hubd->h_local_pwr_on = (status &
8340 USB_DEV_SLF_PWRD_STATUS) && hubd->h_local_pwr_capable;
8342 if (hubd->h_local_pwr_on) {
8343 USB_DPRINTF_L3(DPRINT_MASK_HUB, hubd->h_log_handle,
8346 hubd->h_pwr_limit = (USB_PWR_UNIT_LOAD *
8349 hubd->h_pwr_limit = (USB_PWR_UNIT_LOAD *
8352 hubd->h_pwr_left = (USB_PWR_UNIT_LOAD *
8355 ASSERT(!usba_is_root_hub(hubd->h_dip));
8357 if (!usba_is_root_hub(hubd->h_dip)) {
8362 mutex_exit(HUBD_MUTEX(hubd));
8364 pdip = ddi_get_parent(hubd->h_dip);
8372 hubd->h_log_handle,
8377 mutex_enter(HUBD_MUTEX(hubd));
8384 mutex_enter(HUBD_MUTEX(hubd));
8386 USB_DPRINTF_L3(DPRINT_MASK_HUB, hubd->h_log_handle,
8389 USB_DPRINTF_L3(DPRINT_MASK_HUB, hubd->h_log_handle,
8398 hubd->h_pwr_left -=
8399 hubd->h_hub_descr.bHubContrCurrent /
8401 if (hubd->h_pwr_left < 0) {
8402 USB_DPRINTF_L2(DPRINT_MASK_HUB, hubd->h_log_handle,
8403 "hubd->h_pwr_left is less than bHubContrCurrent, "
8426 hubd_t *hubd;
8428 if ((hubd = hubd_get_soft_state(dip)) == NULL) {
8433 if (hubd->h_ignore_pwr_budget) {
8438 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8443 mutex_enter(HUBD_MUTEX(hubd));
8444 pwr_limit = hubd->h_pwr_limit;
8445 if (hubd->h_local_pwr_on == B_FALSE) {
8446 pwr_left = hubd->h_pwr_left;
8449 mutex_exit(HUBD_MUTEX(hubd));
8451 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8460 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8468 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8475 USB_DPRINTF_L1(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8501 hubd_t *hubd = hubd_get_soft_state(dip);
8503 ASSERT(hubd != NULL);
8505 if (hubd->h_ignore_pwr_budget) {
8510 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
8514 mutex_enter(HUBD_MUTEX(hubd));
8515 if (hubd->h_local_pwr_on == B_TRUE) {
8516 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8519 mutex_exit(HUBD_MUTEX(hubd));
8523 mutex_exit(HUBD_MUTEX(hubd));
8534 mutex_enter(HUBD_MUTEX(hubd));
8535 hubd->h_pwr_left += pwr_value;
8537 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8540 hubd->h_pwr_left * USB_CFG_DESCR_PWR_UNIT,
8543 mutex_exit(HUBD_MUTEX(hubd));
8562 hubd_t *hubd = hubd_get_soft_state(dip);
8564 ASSERT(hubd != NULL);
8566 if (hubd->h_ignore_pwr_budget) {
8571 USB_DPRINTF_L4(DPRINT_MASK_ATTA, hubd->h_log_handle,
8575 mutex_enter(HUBD_MUTEX(hubd));
8576 if (hubd->h_local_pwr_on == B_TRUE) {
8577 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8580 mutex_exit(HUBD_MUTEX(hubd));
8584 mutex_exit(HUBD_MUTEX(hubd));
8599 mutex_enter(HUBD_MUTEX(hubd));
8601 hubd->h_pwr_left -= pwr_value;
8602 ASSERT(hubd->h_pwr_left >= 0);
8604 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8607 hubd->h_pwr_left * USB_CFG_DESCR_PWR_UNIT,
8610 mutex_exit(HUBD_MUTEX(hubd));
8622 hubd_wait_for_hotplug_exit(hubd_t *hubd)
8627 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8629 if (hubd->h_hotplug_thread) {
8630 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8631 "waiting for hubd hotplug thread exit");
8632 rval = cv_reltimedwait(&hubd->h_cv_hotplug_dev,
8633 &hubd->h_mutex, until, TR_CLOCK_TICK);
8635 if ((rval <= 0) && (hubd->h_hotplug_thread)) {
8656 hubd_t *hubd = hd_arg->hubd;
8660 dev_info_t *hdip = hubd->h_dip;
8661 dev_info_t *rh_dip = hubd->h_usba_device->usb_root_hub_dip;
8669 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8674 mutex_enter(HUBD_MUTEX(hubd));
8676 child_dip = hubd->h_children_dips[reset_port];
8683 if (hubd->h_bus_pwr) {
8684 USB_DPRINTF_L0(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8692 if (hubd_wait_for_hotplug_exit(hubd) == USB_FAILURE) {
8695 hubd->h_log_handle, "Time out when resetting the device"
8702 hubd->h_hotplug_thread++;
8706 (hubd->h_dev_state == USB_DEV_PWRED_DOWN)) {
8707 hubpm = hubd->h_hubpm;
8712 mutex_exit(HUBD_MUTEX(hubd));
8714 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8720 mutex_enter(HUBD_MUTEX(hubd));
8721 hubd->h_dev_state = USB_DEV_ONLINE;
8724 mutex_exit(HUBD_MUTEX(hubd));
8736 mutex_enter(HUBD_MUTEX(hubd));
8742 if (hubd->h_children_dips[reset_port]) {
8743 mutex_exit(HUBD_MUTEX(hubd));
8745 hubd_post_event(hubd, reset_port, USBA_EVENT_TAG_HOT_REMOVAL);
8766 mutex_enter(HUBD_MUTEX(hubd));
8767 rval = hubd_delete_child(hubd, reset_port,
8769 mutex_exit(HUBD_MUTEX(hubd));
8781 mutex_enter(HUBD_MUTEX(hubd));
8784 if ((rval != USB_SUCCESS) && (hubd_delete_child(hubd,
8786 USB_DPRINTF_L0(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8792 mutex_exit(HUBD_MUTEX(hubd));
8794 hubd_post_event(hubd, reset_port,
8796 mutex_enter(HUBD_MUTEX(hubd));
8798 (void) hubd_determine_port_status(hubd, reset_port,
8801 /* Reset the parent hubd port and create new child */
8803 online_child |= (hubd_handle_port_connect(hubd,
8810 mutex_exit(HUBD_MUTEX(hubd));
8821 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8824 (void) ndi_devi_online(hubd->h_dip, 0);
8827 mutex_enter(HUBD_MUTEX(hubd));
8830 hubd->h_hotplug_thread--;
8832 hubd_start_polling(hubd, 0);
8835 (void) hubd_pm_idle_component(hubd, hubd->h_dip, 0);
8837 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8838 "hubd_reset_thread: exit, %d", hubd->h_hotplug_thread);
8840 hubd->h_reset_port[reset_port] = B_FALSE;
8842 mutex_exit(HUBD_MUTEX(hubd));
8854 hubd_check_same_device(hubd_t *hubd, usb_port_t port)
8856 dev_info_t *dip = hubd->h_children_dips[port];
8860 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8862 mutex_exit(HUBD_MUTEX(hubd));
8872 hubd->h_log_handle, USB_LOG_L0,
8878 mutex_enter(HUBD_MUTEX(hubd));
8890 hubd_t *hubd;
8928 if ((hubd = hubd_get_soft_state(hdip)) == NULL) {
8935 mutex_enter(HUBD_MUTEX(hubd));
8938 if ((hubd->h_dev_state == USB_DEV_DISCONNECTED) ||
8939 (hubd->h_dev_state == USB_DEV_SUSPENDED)) {
8940 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
8943 hubd->h_dev_state, (void *)dip);
8944 mutex_exit(HUBD_MUTEX(hubd));
8949 mutex_exit(HUBD_MUTEX(hubd));
8951 port = hubd_child_dip2port(hubd, dip);
8953 mutex_enter(HUBD_MUTEX(hubd));
8955 if (hubd->h_reset_port[port]) {
8956 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
8958 mutex_exit(HUBD_MUTEX(hubd));
8969 usba_device = hubd->h_usba_devices[port];
8970 mutex_exit(HUBD_MUTEX(hubd));
8973 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
8986 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
8992 mutex_enter(HUBD_MUTEX(hubd));
8996 if (hubd->h_port_state[port] & HUBD_CHILD_DETACHING) {
8997 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
9000 mutex_exit(HUBD_MUTEX(hubd));
9005 hubd->h_reset_port[port] = B_TRUE;
9006 hdip = hubd->h_dip;
9007 mutex_exit(HUBD_MUTEX(hubd));
9012 mutex_enter(HUBD_MUTEX(hubd));
9013 hubd_pm_busy_component(hubd, hdip, 0);
9014 mutex_exit(HUBD_MUTEX(hubd));
9017 mutex_enter(HUBD_MUTEX(hubd));
9019 hubd->h_hotplug_thread++;
9022 if (hubd->h_ep1_ph) {
9023 mutex_exit(HUBD_MUTEX(hubd));
9024 (void) usb_pipe_get_state(hubd->h_ep1_ph, &prev_pipe_state,
9026 mutex_enter(HUBD_MUTEX(hubd));
9029 hubd_stop_polling(hubd);
9035 mutex_exit(HUBD_MUTEX(hubd));
9038 arg->hubd = hubd;
9040 mutex_enter(HUBD_MUTEX(hubd));
9044 hubd->h_hotplug_thread--;
9045 mutex_exit(HUBD_MUTEX(hubd));
9049 USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle,
9064 if ((rval = hubd_handle_port_connect(hubd, port))
9066 mutex_exit(HUBD_MUTEX(hubd));
9069 mutex_enter(HUBD_MUTEX(hubd));
9072 hubd->h_log_handle, "failed to reopen "
9080 (void) hubd_disable_port(hubd, port);
9091 hubd->h_hotplug_thread--;
9093 if ((hubd->h_dev_state == USB_DEV_ONLINE) && hubd->h_ep1_ph &&
9095 hubd_start_polling(hubd, 0);
9098 hubd_pm_idle_component(hubd, hdip, 0);
9101 hubd->h_reset_port[port] = B_FALSE;
9103 mutex_exit(HUBD_MUTEX(hubd));