8588 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8589 "usba_hubdi_decr_power_budget: "
8590 "available power is %dmA, decreased by %dmA",
8591 hubd->h_pwr_left * USB_CFG_DESCR_PWR_UNIT,
8592 pwr_value * USB_CFG_DESCR_PWR_UNIT);
8593
8594 mutex_exit(HUBD_MUTEX(hubd));
8595
8596 mutex_enter(&child_ud->usb_mutex);
8597 child_ud->usb_pwr_from_hub = pwr_value;
8598 mutex_exit(&child_ud->usb_mutex);
8599 }
8600
8601 /*
8602 * hubd_wait_for_hotplug_exit:
8603 * Waiting for the exit of the running hotplug thread or ioctl thread.
8604 */
8605 static int
8606 hubd_wait_for_hotplug_exit(hubd_t *hubd)
8607 {
8608 clock_t until = drv_usectohz(1000000);
8609 int rval;
8610
8611 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8612
8613 if (hubd->h_hotplug_thread) {
8614 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8615 "waiting for hubd hotplug thread exit");
8616 rval = cv_reltimedwait(&hubd->h_cv_hotplug_dev,
8617 &hubd->h_mutex, until, TR_CLOCK_TICK);
8618
8619 if ((rval <= 0) && (hubd->h_hotplug_thread)) {
8620
8621 return (USB_FAILURE);
8622 }
8623 }
8624
8625 return (USB_SUCCESS);
8626 }
8627
8628 /*
8737
8738 /*
8739 * workaround only for storage device. When it's able to force
8740 * detach a driver, this code can be removed safely.
8741 *
8742 * If we're to reset storage device and the device is used, we
8743 * will wait at most extra 20s for applications to exit and
8744 * close the device. This is especially useful for HAL-based
8745 * applications.
8746 */
8747 if ((strcmp(devname, "scsa2usb") == 0) &&
8748 DEVI(child_dip)->devi_ref != 0) {
8749 while (i++ < hubdi_reset_delay) {
8750 mutex_enter(HUBD_MUTEX(hubd));
8751 rval = hubd_delete_child(hubd, reset_port,
8752 NDI_DEVI_REMOVE, B_FALSE);
8753 mutex_exit(HUBD_MUTEX(hubd));
8754 if (rval == USB_SUCCESS)
8755 break;
8756
8757 delay(drv_usectohz(1000000)); /* 1s */
8758 }
8759 }
8760
8761 ndi_devi_enter(ddi_get_parent(rh_dip), &prh_circ);
8762 ndi_devi_enter(rh_dip, &rh_circ);
8763 ndi_devi_enter(hdip, &circ);
8764
8765 mutex_enter(HUBD_MUTEX(hubd));
8766
8767 /* Then force detaching the device */
8768 if ((rval != USB_SUCCESS) && (hubd_delete_child(hubd,
8769 reset_port, NDI_DEVI_REMOVE, B_FALSE) != USB_SUCCESS)) {
8770 USB_DPRINTF_L0(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8771 "%s%d cannot be reset due to other applications "
8772 "are using it, please first close these "
8773 "applications, then disconnect and reconnect"
8774 "the device.", devname, devinst);
8775
8776 mutex_exit(HUBD_MUTEX(hubd));
8777 /* post a re-connect event */
|
8588 USB_DPRINTF_L3(DPRINT_MASK_ATTA, hubd->h_log_handle,
8589 "usba_hubdi_decr_power_budget: "
8590 "available power is %dmA, decreased by %dmA",
8591 hubd->h_pwr_left * USB_CFG_DESCR_PWR_UNIT,
8592 pwr_value * USB_CFG_DESCR_PWR_UNIT);
8593
8594 mutex_exit(HUBD_MUTEX(hubd));
8595
8596 mutex_enter(&child_ud->usb_mutex);
8597 child_ud->usb_pwr_from_hub = pwr_value;
8598 mutex_exit(&child_ud->usb_mutex);
8599 }
8600
8601 /*
8602 * hubd_wait_for_hotplug_exit:
8603 * Waiting for the exit of the running hotplug thread or ioctl thread.
8604 */
8605 static int
8606 hubd_wait_for_hotplug_exit(hubd_t *hubd)
8607 {
8608 clock_t until = drv_sectohz(1);
8609 int rval;
8610
8611 ASSERT(mutex_owned(HUBD_MUTEX(hubd)));
8612
8613 if (hubd->h_hotplug_thread) {
8614 USB_DPRINTF_L3(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8615 "waiting for hubd hotplug thread exit");
8616 rval = cv_reltimedwait(&hubd->h_cv_hotplug_dev,
8617 &hubd->h_mutex, until, TR_CLOCK_TICK);
8618
8619 if ((rval <= 0) && (hubd->h_hotplug_thread)) {
8620
8621 return (USB_FAILURE);
8622 }
8623 }
8624
8625 return (USB_SUCCESS);
8626 }
8627
8628 /*
8737
8738 /*
8739 * workaround only for storage device. When it's able to force
8740 * detach a driver, this code can be removed safely.
8741 *
8742 * If we're to reset storage device and the device is used, we
8743 * will wait at most extra 20s for applications to exit and
8744 * close the device. This is especially useful for HAL-based
8745 * applications.
8746 */
8747 if ((strcmp(devname, "scsa2usb") == 0) &&
8748 DEVI(child_dip)->devi_ref != 0) {
8749 while (i++ < hubdi_reset_delay) {
8750 mutex_enter(HUBD_MUTEX(hubd));
8751 rval = hubd_delete_child(hubd, reset_port,
8752 NDI_DEVI_REMOVE, B_FALSE);
8753 mutex_exit(HUBD_MUTEX(hubd));
8754 if (rval == USB_SUCCESS)
8755 break;
8756
8757 delay(drv_sectohz(1));
8758 }
8759 }
8760
8761 ndi_devi_enter(ddi_get_parent(rh_dip), &prh_circ);
8762 ndi_devi_enter(rh_dip, &rh_circ);
8763 ndi_devi_enter(hdip, &circ);
8764
8765 mutex_enter(HUBD_MUTEX(hubd));
8766
8767 /* Then force detaching the device */
8768 if ((rval != USB_SUCCESS) && (hubd_delete_child(hubd,
8769 reset_port, NDI_DEVI_REMOVE, B_FALSE) != USB_SUCCESS)) {
8770 USB_DPRINTF_L0(DPRINT_MASK_HOTPLUG, hubd->h_log_handle,
8771 "%s%d cannot be reset due to other applications "
8772 "are using it, please first close these "
8773 "applications, then disconnect and reconnect"
8774 "the device.", devname, devinst);
8775
8776 mutex_exit(HUBD_MUTEX(hubd));
8777 /* post a re-connect event */
|