580 NDI_EVENT_POST_TO_ALL}
581 };
582
583 #define HUBD_N_NDI_EVENTS \
584 (sizeof (hubd_ndi_event_defs) / sizeof (ndi_event_definition_t))
585
586 static ndi_event_set_t hubd_ndi_events = {
587 NDI_EVENTS_REV1, HUBD_N_NDI_EVENTS, hubd_ndi_event_defs};
588
589 /* events received from parent */
590 static usb_event_t hubd_events = {
591 hubd_disconnect_event_cb,
592 hubd_reconnect_event_cb,
593 hubd_pre_suspend_event_cb,
594 hubd_post_resume_event_cb
595 };
596
597
598 /*
599 * hubd_get_soft_state() returns the hubd soft state
600 *
601 * WUSB support extends this function to support wire adapter class
602 * devices. The hubd soft state for the wire adapter class device
603 * would be stored in usb_root_hubd field of the usba_device structure,
604 * just as the USB host controller drivers do.
605 */
606 hubd_t *
607 hubd_get_soft_state(dev_info_t *dip)
608 {
609 if (dip == NULL) {
610
611 return (NULL);
612 }
613
614 if (usba_is_root_hub(dip) || usba_is_wa(dip)) {
615 usba_device_t *usba_device = usba_get_usba_device(dip);
616
617 return (usba_device->usb_root_hubd);
618 } else {
619 int instance = ddi_get_instance(dip);
620
621 return (ddi_get_soft_state(hubd_statep, instance));
622 }
623 }
624
625
626 /*
627 * PM support functions:
628 */
629 /*ARGSUSED*/
630 static void
631 hubd_pm_busy_component(hubd_t *hubd, dev_info_t *dip, int component)
632 {
633 if (hubd->h_hubpm != NULL) {
634 hubd->h_hubpm->hubp_busy_pm++;
6449 child_dip = hubd->h_children_dips[port];
6450 usba_device = hubd->h_usba_devices[port];
6451
6452 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6453 "hubd_delete_child: port=%d, dip=0x%p usba_device=0x%p",
6454 port, (void *)child_dip, (void *)usba_device);
6455
6456 mutex_exit(HUBD_MUTEX(hubd));
6457 if (child_dip) {
6458 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6459 "hubd_delete_child:\n\t"
6460 "dip = 0x%p (%s) at port %d",
6461 (void *)child_dip, ddi_node_name(child_dip), port);
6462
6463 if (usba_device) {
6464 usba_hubdi_incr_power_budget(hubd->h_dip, usba_device);
6465 }
6466
6467 rval = usba_destroy_child_devi(child_dip, flag);
6468
6469 if ((rval != USB_SUCCESS) && usba_is_hwa(child_dip)) {
6470 /*
6471 * This is only useful for HWA device node.
6472 * Since hwahc interface must hold hwarc interface
6473 * open until hwahc is detached, the first call to
6474 * ndi_devi_unconfig_one() can only offline hwahc
6475 * driver but not hwarc driver. Need to make a second
6476 * call to ndi_devi_unconfig_one() to make the hwarc
6477 * driver detach.
6478 */
6479 rval = usba_destroy_child_devi(child_dip, flag);
6480 }
6481
6482 if ((rval == USB_SUCCESS) && (flag & NDI_DEVI_REMOVE)) {
6483 /*
6484 * if the child was still < DS_INITIALIZED
6485 * then our bus_unconfig was not called and
6486 * we have to zap the child here
6487 */
6488 mutex_enter(HUBD_MUTEX(hubd));
6489 if (hubd->h_children_dips[port] == child_dip) {
6490 usba_device_t *ud =
6491 hubd->h_usba_devices[port];
6492 hubd->h_children_dips[port] = NULL;
6493 if (ud) {
6494 mutex_exit(HUBD_MUTEX(hubd));
6495
6496 mutex_enter(&ud->usb_mutex);
6497 ud->usb_ref_count = 0;
6498 mutex_exit(&ud->usb_mutex);
6499
6500 usba_free_usba_device(ud);
6501 mutex_enter(HUBD_MUTEX(hubd));
|
580 NDI_EVENT_POST_TO_ALL}
581 };
582
583 #define HUBD_N_NDI_EVENTS \
584 (sizeof (hubd_ndi_event_defs) / sizeof (ndi_event_definition_t))
585
586 static ndi_event_set_t hubd_ndi_events = {
587 NDI_EVENTS_REV1, HUBD_N_NDI_EVENTS, hubd_ndi_event_defs};
588
589 /* events received from parent */
590 static usb_event_t hubd_events = {
591 hubd_disconnect_event_cb,
592 hubd_reconnect_event_cb,
593 hubd_pre_suspend_event_cb,
594 hubd_post_resume_event_cb
595 };
596
597
598 /*
599 * hubd_get_soft_state() returns the hubd soft state
600 */
601 hubd_t *
602 hubd_get_soft_state(dev_info_t *dip)
603 {
604 if (dip == NULL) {
605
606 return (NULL);
607 }
608
609 if (usba_is_root_hub(dip)) {
610 usba_device_t *usba_device = usba_get_usba_device(dip);
611
612 return (usba_device->usb_root_hubd);
613 } else {
614 int instance = ddi_get_instance(dip);
615
616 return (ddi_get_soft_state(hubd_statep, instance));
617 }
618 }
619
620
621 /*
622 * PM support functions:
623 */
624 /*ARGSUSED*/
625 static void
626 hubd_pm_busy_component(hubd_t *hubd, dev_info_t *dip, int component)
627 {
628 if (hubd->h_hubpm != NULL) {
629 hubd->h_hubpm->hubp_busy_pm++;
6444 child_dip = hubd->h_children_dips[port];
6445 usba_device = hubd->h_usba_devices[port];
6446
6447 USB_DPRINTF_L4(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6448 "hubd_delete_child: port=%d, dip=0x%p usba_device=0x%p",
6449 port, (void *)child_dip, (void *)usba_device);
6450
6451 mutex_exit(HUBD_MUTEX(hubd));
6452 if (child_dip) {
6453 USB_DPRINTF_L2(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
6454 "hubd_delete_child:\n\t"
6455 "dip = 0x%p (%s) at port %d",
6456 (void *)child_dip, ddi_node_name(child_dip), port);
6457
6458 if (usba_device) {
6459 usba_hubdi_incr_power_budget(hubd->h_dip, usba_device);
6460 }
6461
6462 rval = usba_destroy_child_devi(child_dip, flag);
6463
6464 if ((rval == USB_SUCCESS) && (flag & NDI_DEVI_REMOVE)) {
6465 /*
6466 * if the child was still < DS_INITIALIZED
6467 * then our bus_unconfig was not called and
6468 * we have to zap the child here
6469 */
6470 mutex_enter(HUBD_MUTEX(hubd));
6471 if (hubd->h_children_dips[port] == child_dip) {
6472 usba_device_t *ud =
6473 hubd->h_usba_devices[port];
6474 hubd->h_children_dips[port] = NULL;
6475 if (ud) {
6476 mutex_exit(HUBD_MUTEX(hubd));
6477
6478 mutex_enter(&ud->usb_mutex);
6479 ud->usb_ref_count = 0;
6480 mutex_exit(&ud->usb_mutex);
6481
6482 usba_free_usba_device(ud);
6483 mutex_enter(HUBD_MUTEX(hubd));
|