970 mutex_destroy(&ehcip->ehci_int_mutex);
971 kmem_free(ehcip->ehci_htable, intr_size);
972
973 return (DDI_FAILURE);
974 }
975
976 /* Enable all interrupts */
977 if (ehcip->ehci_intr_cap & DDI_INTR_FLAG_BLOCK) {
978 /* Call ddi_intr_block_enable() for MSI interrupts */
979 (void) ddi_intr_block_enable(ehcip->ehci_htable,
980 ehcip->ehci_intr_cnt);
981 } else {
982 /* Call ddi_intr_enable for MSI or FIXED interrupts */
983 for (i = 0; i < ehcip->ehci_intr_cnt; i++)
984 (void) ddi_intr_enable(ehcip->ehci_htable[i]);
985 }
986
987 return (DDI_SUCCESS);
988 }
989
990
991 /*
992 * ehci_init_hardware
993 *
994 * take control from BIOS, reset EHCI host controller, and check version, etc.
995 */
996 int
997 ehci_init_hardware(ehci_state_t *ehcip)
998 {
999 int revision;
1000 uint16_t cmd_reg;
1001 int abort_on_BIOS_take_over_failure;
1002
1003 /* Take control from the BIOS */
1004 if (ehci_take_control(ehcip) != USB_SUCCESS) {
1005
1006 /* read .conf file properties */
1007 abort_on_BIOS_take_over_failure =
1008 ddi_prop_get_int(DDI_DEV_T_ANY,
1009 ehcip->ehci_dip, DDI_PROP_DONTPASS,
1010 "abort-on-BIOS-take-over-failure", 0);
1014 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1015 "Unable to take control from BIOS.");
1016
1017 return (DDI_FAILURE);
1018 }
1019
1020 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1021 "Unable to take control from BIOS. Failure is ignored.");
1022 }
1023
1024 /* set Memory Master Enable */
1025 cmd_reg = pci_config_get16(ehcip->ehci_config_handle, PCI_CONF_COMM);
1026 cmd_reg |= (PCI_COMM_MAE | PCI_COMM_ME);
1027 pci_config_put16(ehcip->ehci_config_handle, PCI_CONF_COMM, cmd_reg);
1028
1029 /* Reset the EHCI host controller */
1030 Set_OpReg(ehci_command,
1031 Get_OpReg(ehci_command) | EHCI_CMD_HOST_CTRL_RESET);
1032
1033 /* Wait 10ms for reset to complete */
1034 drv_usecwait(EHCI_RESET_TIMEWAIT);
1035
1036 ASSERT(Get_OpReg(ehci_status) & EHCI_STS_HOST_CTRL_HALTED);
1037
1038 /* Verify the version number */
1039 revision = Get_16Cap(ehci_version);
1040
1041 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1042 "ehci_init_hardware: Revision 0x%x", revision);
1043
1044 /*
1045 * EHCI driver supports EHCI host controllers compliant to
1046 * 0.95 and higher revisions of EHCI specifications.
1047 */
1048 if (revision < EHCI_REVISION_0_95) {
1049
1050 USB_DPRINTF_L0(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1051 "Revision 0x%x is not supported", revision);
1052
1053 return (DDI_FAILURE);
1054 }
3799 Set_OpReg(ehci_interrupt, EHCI_INTR_HOST_SYSTEM_ERROR |
3800 EHCI_INTR_FRAME_LIST_ROLLOVER |
3801 EHCI_INTR_USB_ERROR |
3802 EHCI_INTR_USB);
3803
3804 /*
3805 * Deallocate the space that allocated for saving
3806 * HC registers.
3807 */
3808 kmem_free((void *) ehci_save_regs, sizeof (ehci_regs_t));
3809
3810 /*
3811 * Set the desired interrupt threshold, frame list size (if
3812 * applicable) and turn EHCI host controller.
3813 */
3814 Set_OpReg(ehci_command, ((Get_OpReg(ehci_command) &
3815 ~EHCI_CMD_INTR_THRESHOLD) |
3816 (EHCI_CMD_01_INTR | EHCI_CMD_HOST_CTRL_RUN)));
3817
3818 /* Wait 10ms for EHCI to start sending SOF */
3819 drv_usecwait(EHCI_RESET_TIMEWAIT);
3820
3821 /*
3822 * Get the current usb frame number before waiting for
3823 * few milliseconds.
3824 */
3825 before_frame_number = ehci_get_current_frame_number(ehcip);
3826
3827 /* Wait for few milliseconds */
3828 drv_usecwait(EHCI_SOF_TIMEWAIT);
3829
3830 /*
3831 * Get the current usb frame number after waiting for
3832 * few milliseconds.
3833 */
3834 after_frame_number = ehci_get_current_frame_number(ehcip);
3835
3836 USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
3837 "ehci_do_soft_reset: Before Frame Number 0x%llx "
3838 "After Frame Number 0x%llx",
3839 (unsigned long long)before_frame_number,
|
970 mutex_destroy(&ehcip->ehci_int_mutex);
971 kmem_free(ehcip->ehci_htable, intr_size);
972
973 return (DDI_FAILURE);
974 }
975
976 /* Enable all interrupts */
977 if (ehcip->ehci_intr_cap & DDI_INTR_FLAG_BLOCK) {
978 /* Call ddi_intr_block_enable() for MSI interrupts */
979 (void) ddi_intr_block_enable(ehcip->ehci_htable,
980 ehcip->ehci_intr_cnt);
981 } else {
982 /* Call ddi_intr_enable for MSI or FIXED interrupts */
983 for (i = 0; i < ehcip->ehci_intr_cnt; i++)
984 (void) ddi_intr_enable(ehcip->ehci_htable[i]);
985 }
986
987 return (DDI_SUCCESS);
988 }
989
990 /*
991 * ehci_wait_reset
992 *
993 * wait specified time for chip to reset
994 * with workaround of 250us for HPE iLO chip
995 */
996 static void
997 ehci_wait_reset(ehci_state_t *ehcip, clock_t microsecs)
998 {
999 /* Wait specified times for reset to complete */
1000 drv_usecwait(microsecs);
1001
1002 if (ehcip->ehci_vendor_id == PCI_VENDOR_HP) {
1003 for (int i = 10; i < 250; i += 10) {
1004 /* Wait 10ms for reset to complete */
1005 drv_usecwait(EHCI_RESET_TIMEWAIT);
1006 }
1007 }
1008 }
1009
1010 /*
1011 * ehci_init_hardware
1012 *
1013 * take control from BIOS, reset EHCI host controller, and check version, etc.
1014 */
1015 int
1016 ehci_init_hardware(ehci_state_t *ehcip)
1017 {
1018 int revision;
1019 uint16_t cmd_reg;
1020 int abort_on_BIOS_take_over_failure;
1021
1022 /* Take control from the BIOS */
1023 if (ehci_take_control(ehcip) != USB_SUCCESS) {
1024
1025 /* read .conf file properties */
1026 abort_on_BIOS_take_over_failure =
1027 ddi_prop_get_int(DDI_DEV_T_ANY,
1028 ehcip->ehci_dip, DDI_PROP_DONTPASS,
1029 "abort-on-BIOS-take-over-failure", 0);
1033 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1034 "Unable to take control from BIOS.");
1035
1036 return (DDI_FAILURE);
1037 }
1038
1039 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1040 "Unable to take control from BIOS. Failure is ignored.");
1041 }
1042
1043 /* set Memory Master Enable */
1044 cmd_reg = pci_config_get16(ehcip->ehci_config_handle, PCI_CONF_COMM);
1045 cmd_reg |= (PCI_COMM_MAE | PCI_COMM_ME);
1046 pci_config_put16(ehcip->ehci_config_handle, PCI_CONF_COMM, cmd_reg);
1047
1048 /* Reset the EHCI host controller */
1049 Set_OpReg(ehci_command,
1050 Get_OpReg(ehci_command) | EHCI_CMD_HOST_CTRL_RESET);
1051
1052 /* Wait 10ms for reset to complete */
1053 ehci_wait_reset(ehcip, EHCI_RESET_TIMEWAIT);
1054
1055 ASSERT(Get_OpReg(ehci_status) & EHCI_STS_HOST_CTRL_HALTED);
1056
1057 /* Verify the version number */
1058 revision = Get_16Cap(ehci_version);
1059
1060 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1061 "ehci_init_hardware: Revision 0x%x", revision);
1062
1063 /*
1064 * EHCI driver supports EHCI host controllers compliant to
1065 * 0.95 and higher revisions of EHCI specifications.
1066 */
1067 if (revision < EHCI_REVISION_0_95) {
1068
1069 USB_DPRINTF_L0(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1070 "Revision 0x%x is not supported", revision);
1071
1072 return (DDI_FAILURE);
1073 }
3818 Set_OpReg(ehci_interrupt, EHCI_INTR_HOST_SYSTEM_ERROR |
3819 EHCI_INTR_FRAME_LIST_ROLLOVER |
3820 EHCI_INTR_USB_ERROR |
3821 EHCI_INTR_USB);
3822
3823 /*
3824 * Deallocate the space that allocated for saving
3825 * HC registers.
3826 */
3827 kmem_free((void *) ehci_save_regs, sizeof (ehci_regs_t));
3828
3829 /*
3830 * Set the desired interrupt threshold, frame list size (if
3831 * applicable) and turn EHCI host controller.
3832 */
3833 Set_OpReg(ehci_command, ((Get_OpReg(ehci_command) &
3834 ~EHCI_CMD_INTR_THRESHOLD) |
3835 (EHCI_CMD_01_INTR | EHCI_CMD_HOST_CTRL_RUN)));
3836
3837 /* Wait 10ms for EHCI to start sending SOF */
3838 ehci_wait_reset(ehcip, EHCI_RESET_TIMEWAIT);
3839
3840 /*
3841 * Get the current usb frame number before waiting for
3842 * few milliseconds.
3843 */
3844 before_frame_number = ehci_get_current_frame_number(ehcip);
3845
3846 /* Wait for few milliseconds */
3847 drv_usecwait(EHCI_SOF_TIMEWAIT);
3848
3849 /*
3850 * Get the current usb frame number after waiting for
3851 * few milliseconds.
3852 */
3853 after_frame_number = ehci_get_current_frame_number(ehcip);
3854
3855 USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
3856 "ehci_do_soft_reset: Before Frame Number 0x%llx "
3857 "After Frame Number 0x%llx",
3858 (unsigned long long)before_frame_number,
|