4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * EHCI Host Controller Driver (EHCI)
28 *
29 * The EHCI driver is a software driver which interfaces to the Universal
30 * Serial Bus layer (USBA) and the Host Controller (HC). The interface to
31 * the Host Controller is defined by the EHCI Host Controller Interface.
32 *
33 * This module contains the main EHCI driver code which handles all USB
34 * transfers, bandwidth allocations and other general functionalities.
35 */
36
37 #include <sys/usb/hcd/ehci/ehcid.h>
38 #include <sys/usb/hcd/ehci/ehci_isoch.h>
39 #include <sys/usb/hcd/ehci/ehci_xfer.h>
40
41 /*
42 * EHCI MSI tunable:
43 *
44 * By default MSI is enabled on all supported platforms except for the
45 * EHCI controller of ULI1575 South bridge.
46 */
728 */
729 if ((ehcip->ehci_vendor_id == PCI_VENDOR_ULi_M1575) &&
730 (ehcip->ehci_device_id == PCI_DEVICE_ULi_M1575)) {
731 ehcip->ehci_msi_enabled = B_FALSE;
732 } else {
733 /* Set the MSI enable flag from the global EHCI MSI tunable */
734 ehcip->ehci_msi_enabled = ehci_enable_msi;
735 }
736
737 /* launch polling thread instead of enabling pci interrupt */
738 if (ehci_is_polled(ehcip->ehci_dip)) {
739 extern pri_t maxclsyspri;
740
741 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
742 "ehci_register_intrs_and_init_mutex: "
743 "running in simulated polled mode");
744
745 (void) thread_create(NULL, 0, ehci_poll_intr, ehcip, 0, &p0,
746 TS_RUN, maxclsyspri);
747
748 goto skip_intr;
749 }
750
751 #if defined(__x86)
752 /*
753 * Make sure that the interrupt pin is connected to the
754 * interrupt controller on x86. Interrupt line 255 means
755 * "unknown" or "not connected" (PCI spec 6.2.4, footnote 43).
756 * If we would return failure when interrupt line equals 255, then
757 * high speed devices will be routed to companion host controllers.
758 * However, it is not necessary to return failure here, and
759 * o/uhci codes don't check the interrupt line either.
760 * But it's good to log a message here for debug purposes.
761 */
762 iline = pci_config_get8(ehcip->ehci_config_handle,
763 PCI_CONF_ILINE);
764
765 if (iline == 255) {
766 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
767 "ehci_register_intrs_and_init_mutex: "
768 "interrupt line value out of range (%d)",
802
803 if ((!(ehcip->ehci_flags & EHCI_INTR)) &&
804 (intr_types & DDI_INTR_TYPE_FIXED)) {
805 if (ehci_add_intrs(ehcip, DDI_INTR_TYPE_FIXED)
806 != DDI_SUCCESS) {
807 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
808 "ehci_register_intrs_and_init_mutex: "
809 "FIXED interrupt registration failed\n");
810
811 return (DDI_FAILURE);
812 }
813
814 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
815 "ehci_register_intrs_and_init_mutex: "
816 "Using FIXED interrupt type\n");
817
818 ehcip->ehci_intr_type = DDI_INTR_TYPE_FIXED;
819 ehcip->ehci_flags |= EHCI_INTR;
820 }
821
822 skip_intr:
823 /* Create prototype for advance on async schedule */
824 cv_init(&ehcip->ehci_async_schedule_advance_cv,
825 NULL, CV_DRIVER, NULL);
826
827 return (DDI_SUCCESS);
828 }
829
830
831 /*
832 * ehci_add_intrs:
833 *
834 * Register FIXED or MSI interrupts.
835 */
836 static int
837 ehci_add_intrs(ehci_state_t *ehcip,
838 int intr_type)
839 {
840 int actual, avail, intr_size, count = 0;
841 int i, flag, ret;
842
843 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
844 "ehci_add_intrs: interrupt type 0x%x", intr_type);
845
846 /* Get number of interrupts */
847 ret = ddi_intr_get_nintrs(ehcip->ehci_dip, intr_type, &count);
848 if ((ret != DDI_SUCCESS) || (count == 0)) {
849 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
850 "ehci_add_intrs: ddi_intr_get_nintrs() failure, "
851 "ret: %d, count: %d", ret, count);
852
853 return (DDI_FAILURE);
854 }
855
856 /* Get number of available interrupts */
857 ret = ddi_intr_get_navail(ehcip->ehci_dip, intr_type, &avail);
858 if ((ret != DDI_SUCCESS) || (avail == 0)) {
1157 "Please also refer to www.sun.com/io for");
1158 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1159 "Solaris Ready products and to");
1160 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1161 "www.sun.com/bigadmin/hcl for additional");
1162 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1163 "compatible USB products.");
1164
1165 return (DDI_FAILURE);
1166
1167 } else if (ehci_vt62x2_workaround) {
1168
1169 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1170 "Applying VIA workarounds");
1171 }
1172 }
1173
1174 return (DDI_SUCCESS);
1175 }
1176
1177
1178 /*
1179 * ehci_init_check_status
1180 *
1181 * Check if EHCI host controller is running
1182 */
1183 int
1184 ehci_init_check_status(ehci_state_t *ehcip)
1185 {
1186 clock_t sof_time_wait;
1187
1188 /*
1189 * Get the number of clock ticks to wait.
1190 * This is based on the maximum time it takes for a frame list rollover
1191 * and maximum time wait for SOFs to begin.
1192 */
1193 sof_time_wait = drv_usectohz((EHCI_NUM_PERIODIC_FRAME_LISTS * 1000) +
1194 EHCI_SOF_TIMEWAIT);
1195
1196 /* Tell the ISR to broadcast ehci_async_schedule_advance_cv */
1197 ehcip->ehci_flags |= EHCI_CV_INTR;
1198
1199 /* We need to add a delay to allow the chip time to start running */
1200 (void) cv_reltimedwait(&ehcip->ehci_async_schedule_advance_cv,
1201 &ehcip->ehci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
1202
1203 /*
1204 * Check EHCI host controller is running, otherwise return failure.
1205 */
1206 if ((ehcip->ehci_flags & EHCI_CV_INTR) ||
1207 (Get_OpReg(ehci_status) & EHCI_STS_HOST_CTRL_HALTED)) {
1208
1209 USB_DPRINTF_L0(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1210 "No SOF interrupts have been received, this USB EHCI host"
1211 "controller is unusable");
1212
1213 /*
1214 * Route all Root hub ports to Classic host
1215 * controller, in case this is an unusable ALI M5273
1216 * EHCI controller.
1217 */
1218 if (ehcip->ehci_vendor_id == PCI_VENDOR_ALI) {
1219 Set_OpReg(ehci_config_flag, EHCI_CONFIG_FLAG_CLASSIC);
1220 }
1221
1222 return (DDI_FAILURE);
1223 }
1224
1225 return (DDI_SUCCESS);
1226 }
1227
1228
1229 /*
1230 * ehci_init_ctlr:
1231 *
1232 * Initialize the Host Controller (HC).
1233 */
1234 int
1235 ehci_init_ctlr(ehci_state_t *ehcip,
1236 int init_type)
1237 {
1238 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehci_init_ctlr:");
1239
1240 if (init_type == EHCI_NORMAL_INITIALIZATION) {
1241
1242 if (ehci_init_hardware(ehcip) != DDI_SUCCESS) {
1243
1244 return (DDI_FAILURE);
1245 }
1246 }
1247
1248 /*
1249 * Check for Asynchronous schedule park capability feature. If this
1250 * feature is supported, then, program ehci command register with
1251 * appropriate values..
1252 */
1253 if (Get_Cap(ehci_hcc_params) & EHCI_HCC_ASYNC_SCHED_PARK_CAP) {
1254
1255 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1256 "ehci_init_ctlr: Async park mode is supported");
1307 EHCI_PERIODIC_LIST_BASE));
1308
1309 /*
1310 * Set ehci_interrupt to enable all interrupts except Root
1311 * Hub Status change interrupt.
1312 */
1313 Set_OpReg(ehci_interrupt, EHCI_INTR_HOST_SYSTEM_ERROR |
1314 EHCI_INTR_FRAME_LIST_ROLLOVER | EHCI_INTR_USB_ERROR |
1315 EHCI_INTR_USB);
1316
1317 /*
1318 * Set the desired interrupt threshold and turn on EHCI host controller.
1319 */
1320 Set_OpReg(ehci_command,
1321 ((Get_OpReg(ehci_command) & ~EHCI_CMD_INTR_THRESHOLD) |
1322 (EHCI_CMD_01_INTR | EHCI_CMD_HOST_CTRL_RUN)));
1323
1324 ASSERT(Get_OpReg(ehci_command) & EHCI_CMD_HOST_CTRL_RUN);
1325
1326 if (init_type == EHCI_NORMAL_INITIALIZATION) {
1327
1328 if (ehci_init_workaround(ehcip) != DDI_SUCCESS) {
1329
1330 /* Set host controller soft state to error */
1331 ehcip->ehci_hc_soft_state = EHCI_CTLR_ERROR_STATE;
1332
1333 return (DDI_FAILURE);
1334 }
1335
1336 if (ehci_init_check_status(ehcip) != DDI_SUCCESS) {
1337
1338 /* Set host controller soft state to error */
1339 ehcip->ehci_hc_soft_state = EHCI_CTLR_ERROR_STATE;
1340
1341 return (DDI_FAILURE);
1342 }
1343
1344 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1345 "ehci_init_ctlr: SOF's have started");
1346 }
1347
1348 /* Route all Root hub ports to EHCI host controller */
1349 Set_OpReg(ehci_config_flag, EHCI_CONFIG_FLAG_EHCI);
1350
1351 return (DDI_SUCCESS);
1352 }
1353
1354 /*
1355 * ehci_take_control:
1356 *
1357 * Handshake to take EHCI control from BIOS if necessary. Its only valid for
1358 * x86 machines, because sparc doesn't have a BIOS.
1359 * On x86 machine, the take control process includes
1360 * o get the base address of the extended capability list
1361 * o find out the capability for handoff synchronization in the list.
1362 * o check if BIOS has owned the host controller.
1363 * o set the OS Owned semaphore bit, ask the BIOS to release the ownership.
1364 * o wait for a constant time and check if BIOS has relinquished control.
1365 */
1366 /* ARGSUSED */
1367 static int
1389 * worry about BIOS handoff.
1390 */
1391 if (extended_cap_offset < EHCI_HCC_EECP_MIN_OFFSET) {
1392
1393 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1394 "ehci_take_control: Hardware doesn't support legacy.");
1395
1396 goto success;
1397 }
1398
1399 /*
1400 * According EHCI Spec 2.1.7, A zero offset indicates the
1401 * end of the extended capability list.
1402 */
1403 while (extended_cap_offset) {
1404
1405 /* Get the extended capability value. */
1406 extended_cap = pci_config_get32(ehcip->ehci_config_handle,
1407 extended_cap_offset);
1408
1409 /* Get the capability ID */
1410 extended_cap_id = (extended_cap & EHCI_EX_CAP_ID) >>
1411 EHCI_EX_CAP_ID_SHIFT;
1412
1413 /* Check if the card support legacy */
1414 if (extended_cap_id == EHCI_EX_CAP_ID_BIOS_HANDOFF) {
1415 break;
1416 }
1417
1418 /* Get the offset of the next capability */
1419 extended_cap_offset = (extended_cap & EHCI_EX_CAP_NEXT_PTR) >>
1420 EHCI_EX_CAP_NEXT_PTR_SHIFT;
1421 }
1422
1423 /*
1424 * Unable to find legacy support in hardware's extended capability list.
1425 * This means we don't need to worry about BIOS handoff.
1426 */
1427 if (extended_cap_id != EHCI_EX_CAP_ID_BIOS_HANDOFF) {
1428
1429 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1430 "ehci_take_control: Hardware doesn't support legacy");
1431
1432 goto success;
1433 }
1434
1435 /* Check if BIOS has owned it. */
1436 if (!(extended_cap & EHCI_LEGSUP_BIOS_OWNED_SEM)) {
1437
1438 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1439 "ehci_take_control: BIOS does not own EHCI");
1440
1914 EHCI_PFLT_DMA_BOUND) == EHCI_PFLT_DMA_BOUND) {
1915
1916 rval = ddi_dma_unbind_handle(
1917 ehcip->ehci_pflt_dma_handle);
1918
1919 ASSERT(rval == DDI_SUCCESS);
1920 }
1921
1922 ddi_dma_mem_free(&ehcip->ehci_pflt_mem_handle);
1923 }
1924
1925 (void) ehci_isoc_cleanup(ehcip);
1926
1927 if (ehcip->ehci_pflt_dma_handle) {
1928 ddi_dma_free_handle(&ehcip->ehci_pflt_dma_handle);
1929 }
1930
1931 if (flags & EHCI_INTR) {
1932 /* Destroy the mutex */
1933 mutex_destroy(&ehcip->ehci_int_mutex);
1934
1935 /* Destroy the async schedule advance condition variable */
1936 cv_destroy(&ehcip->ehci_async_schedule_advance_cv);
1937 }
1938
1939 /* clean up kstat structs */
1940 ehci_destroy_stats(ehcip);
1941
1942 /* Free ehci hcdi ops */
1943 if (ehcip->ehci_hcdi_ops) {
1944 usba_free_hcdi_ops(ehcip->ehci_hcdi_ops);
1945 }
1946
1947 if (flags & EHCI_ZALLOC) {
1948
1949 usb_free_log_hdl(ehcip->ehci_log_hdl);
1950
1951 /* Remove all properties that might have been created */
1952 ddi_prop_remove_all(ehcip->ehci_dip);
1953
1954 /* Free the soft state */
1955 ddi_soft_state_free(ehci_statep,
1956 ddi_get_instance(ehcip->ehci_dip));
2959 */
2960 static uint_t
2961 ehci_lattice_parent(uint_t node)
2962 {
2963 if ((node % 2) == 0) {
2964
2965 return ((node/2) - 1);
2966 } else {
2967
2968 return ((node + 1)/2 - 1);
2969 }
2970 }
2971
2972
2973 /*
2974 * ehci_find_periodic_node:
2975 *
2976 * Based on the "real" array leaf node and interval, get the periodic node.
2977 */
2978 static uint_t
2979 ehci_find_periodic_node(uint_t leaf, int interval) {
2980 uint_t lattice_leaf;
2981 uint_t height = ehci_lattice_height(interval);
2982 uint_t pnode;
2983 int i;
2984
2985 /* Get the leaf number in the lattice */
2986 lattice_leaf = leaf + EHCI_NUM_INTR_QH_LISTS - 1;
2987
2988 /* Get the node in the lattice based on the height and leaf */
2989 pnode = lattice_leaf;
2990 for (i = 0; i < height; i++) {
2991 pnode = ehci_lattice_parent(pnode);
2992 }
2993
2994 return (pnode);
2995 }
2996
2997
2998 /*
2999 * ehci_leftmost_leaf:
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2018, Joyent, Inc.
25 */
26
27 /*
28 * Copyright 2018 Nexenta Systems, Inc.
29 */
30
31 /*
32 * EHCI Host Controller Driver (EHCI)
33 *
34 * The EHCI driver is a software driver which interfaces to the Universal
35 * Serial Bus layer (USBA) and the Host Controller (HC). The interface to
36 * the Host Controller is defined by the EHCI Host Controller Interface.
37 *
38 * This module contains the main EHCI driver code which handles all USB
39 * transfers, bandwidth allocations and other general functionalities.
40 */
41
42 #include <sys/usb/hcd/ehci/ehcid.h>
43 #include <sys/usb/hcd/ehci/ehci_isoch.h>
44 #include <sys/usb/hcd/ehci/ehci_xfer.h>
45
46 /*
47 * EHCI MSI tunable:
48 *
49 * By default MSI is enabled on all supported platforms except for the
50 * EHCI controller of ULI1575 South bridge.
51 */
733 */
734 if ((ehcip->ehci_vendor_id == PCI_VENDOR_ULi_M1575) &&
735 (ehcip->ehci_device_id == PCI_DEVICE_ULi_M1575)) {
736 ehcip->ehci_msi_enabled = B_FALSE;
737 } else {
738 /* Set the MSI enable flag from the global EHCI MSI tunable */
739 ehcip->ehci_msi_enabled = ehci_enable_msi;
740 }
741
742 /* launch polling thread instead of enabling pci interrupt */
743 if (ehci_is_polled(ehcip->ehci_dip)) {
744 extern pri_t maxclsyspri;
745
746 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
747 "ehci_register_intrs_and_init_mutex: "
748 "running in simulated polled mode");
749
750 (void) thread_create(NULL, 0, ehci_poll_intr, ehcip, 0, &p0,
751 TS_RUN, maxclsyspri);
752
753 return (DDI_SUCCESS);
754 }
755
756 #if defined(__x86)
757 /*
758 * Make sure that the interrupt pin is connected to the
759 * interrupt controller on x86. Interrupt line 255 means
760 * "unknown" or "not connected" (PCI spec 6.2.4, footnote 43).
761 * If we would return failure when interrupt line equals 255, then
762 * high speed devices will be routed to companion host controllers.
763 * However, it is not necessary to return failure here, and
764 * o/uhci codes don't check the interrupt line either.
765 * But it's good to log a message here for debug purposes.
766 */
767 iline = pci_config_get8(ehcip->ehci_config_handle,
768 PCI_CONF_ILINE);
769
770 if (iline == 255) {
771 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
772 "ehci_register_intrs_and_init_mutex: "
773 "interrupt line value out of range (%d)",
807
808 if ((!(ehcip->ehci_flags & EHCI_INTR)) &&
809 (intr_types & DDI_INTR_TYPE_FIXED)) {
810 if (ehci_add_intrs(ehcip, DDI_INTR_TYPE_FIXED)
811 != DDI_SUCCESS) {
812 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
813 "ehci_register_intrs_and_init_mutex: "
814 "FIXED interrupt registration failed\n");
815
816 return (DDI_FAILURE);
817 }
818
819 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
820 "ehci_register_intrs_and_init_mutex: "
821 "Using FIXED interrupt type\n");
822
823 ehcip->ehci_intr_type = DDI_INTR_TYPE_FIXED;
824 ehcip->ehci_flags |= EHCI_INTR;
825 }
826
827 return (DDI_SUCCESS);
828 }
829
830
831 /*
832 * ehci_add_intrs:
833 *
834 * Register FIXED or MSI interrupts.
835 */
836 static int
837 ehci_add_intrs(ehci_state_t *ehcip, int intr_type)
838 {
839 int actual, avail, intr_size, count = 0;
840 int i, flag, ret;
841
842 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
843 "ehci_add_intrs: interrupt type 0x%x", intr_type);
844
845 /* Get number of interrupts */
846 ret = ddi_intr_get_nintrs(ehcip->ehci_dip, intr_type, &count);
847 if ((ret != DDI_SUCCESS) || (count == 0)) {
848 USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
849 "ehci_add_intrs: ddi_intr_get_nintrs() failure, "
850 "ret: %d, count: %d", ret, count);
851
852 return (DDI_FAILURE);
853 }
854
855 /* Get number of available interrupts */
856 ret = ddi_intr_get_navail(ehcip->ehci_dip, intr_type, &avail);
857 if ((ret != DDI_SUCCESS) || (avail == 0)) {
1156 "Please also refer to www.sun.com/io for");
1157 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1158 "Solaris Ready products and to");
1159 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1160 "www.sun.com/bigadmin/hcl for additional");
1161 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1162 "compatible USB products.");
1163
1164 return (DDI_FAILURE);
1165
1166 } else if (ehci_vt62x2_workaround) {
1167
1168 USB_DPRINTF_L1(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1169 "Applying VIA workarounds");
1170 }
1171 }
1172
1173 return (DDI_SUCCESS);
1174 }
1175
1176 /*
1177 * ehci_init_ctlr:
1178 *
1179 * Initialize the Host Controller (HC).
1180 */
1181 int
1182 ehci_init_ctlr(ehci_state_t *ehcip, int init_type)
1183 {
1184 USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehci_init_ctlr:");
1185
1186 if (init_type == EHCI_NORMAL_INITIALIZATION) {
1187
1188 if (ehci_init_hardware(ehcip) != DDI_SUCCESS) {
1189
1190 return (DDI_FAILURE);
1191 }
1192 }
1193
1194 /*
1195 * Check for Asynchronous schedule park capability feature. If this
1196 * feature is supported, then, program ehci command register with
1197 * appropriate values..
1198 */
1199 if (Get_Cap(ehci_hcc_params) & EHCI_HCC_ASYNC_SCHED_PARK_CAP) {
1200
1201 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1202 "ehci_init_ctlr: Async park mode is supported");
1253 EHCI_PERIODIC_LIST_BASE));
1254
1255 /*
1256 * Set ehci_interrupt to enable all interrupts except Root
1257 * Hub Status change interrupt.
1258 */
1259 Set_OpReg(ehci_interrupt, EHCI_INTR_HOST_SYSTEM_ERROR |
1260 EHCI_INTR_FRAME_LIST_ROLLOVER | EHCI_INTR_USB_ERROR |
1261 EHCI_INTR_USB);
1262
1263 /*
1264 * Set the desired interrupt threshold and turn on EHCI host controller.
1265 */
1266 Set_OpReg(ehci_command,
1267 ((Get_OpReg(ehci_command) & ~EHCI_CMD_INTR_THRESHOLD) |
1268 (EHCI_CMD_01_INTR | EHCI_CMD_HOST_CTRL_RUN)));
1269
1270 ASSERT(Get_OpReg(ehci_command) & EHCI_CMD_HOST_CTRL_RUN);
1271
1272 if (init_type == EHCI_NORMAL_INITIALIZATION) {
1273 if (ehci_init_workaround(ehcip) != DDI_SUCCESS) {
1274
1275 /* Set host controller soft state to error */
1276 ehcip->ehci_hc_soft_state = EHCI_CTLR_ERROR_STATE;
1277
1278 return (DDI_FAILURE);
1279 }
1280 }
1281
1282 /* Route all Root hub ports to EHCI host controller */
1283 Set_OpReg(ehci_config_flag, EHCI_CONFIG_FLAG_EHCI);
1284
1285 return (DDI_SUCCESS);
1286 }
1287
1288 /*
1289 * ehci_take_control:
1290 *
1291 * Handshake to take EHCI control from BIOS if necessary. Its only valid for
1292 * x86 machines, because sparc doesn't have a BIOS.
1293 * On x86 machine, the take control process includes
1294 * o get the base address of the extended capability list
1295 * o find out the capability for handoff synchronization in the list.
1296 * o check if BIOS has owned the host controller.
1297 * o set the OS Owned semaphore bit, ask the BIOS to release the ownership.
1298 * o wait for a constant time and check if BIOS has relinquished control.
1299 */
1300 /* ARGSUSED */
1301 static int
1323 * worry about BIOS handoff.
1324 */
1325 if (extended_cap_offset < EHCI_HCC_EECP_MIN_OFFSET) {
1326
1327 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1328 "ehci_take_control: Hardware doesn't support legacy.");
1329
1330 goto success;
1331 }
1332
1333 /*
1334 * According EHCI Spec 2.1.7, A zero offset indicates the
1335 * end of the extended capability list.
1336 */
1337 while (extended_cap_offset) {
1338
1339 /* Get the extended capability value. */
1340 extended_cap = pci_config_get32(ehcip->ehci_config_handle,
1341 extended_cap_offset);
1342
1343 /*
1344 * It's possible that we'll receive an invalid PCI read here due
1345 * to something going wrong due to platform firmware. This has
1346 * been observed in the wild depending on the version of ACPI in
1347 * use. If this happens, we'll assume that the capability does
1348 * not exist and that we do not need to take control from the
1349 * BIOS.
1350 */
1351 if (extended_cap == PCI_EINVAL32) {
1352 extended_cap_id = EHCI_EX_CAP_ID_RESERVED;
1353 break;
1354 }
1355
1356 /* Get the capability ID */
1357 extended_cap_id = (extended_cap & EHCI_EX_CAP_ID) >>
1358 EHCI_EX_CAP_ID_SHIFT;
1359
1360 /* Check if the card support legacy */
1361 if (extended_cap_id == EHCI_EX_CAP_ID_BIOS_HANDOFF) {
1362 break;
1363 }
1364
1365 /* Get the offset of the next capability */
1366 extended_cap_offset = (extended_cap & EHCI_EX_CAP_NEXT_PTR) >>
1367 EHCI_EX_CAP_NEXT_PTR_SHIFT;
1368
1369 }
1370
1371 /*
1372 * Unable to find legacy support in hardware's extended capability list.
1373 * This means we don't need to worry about BIOS handoff.
1374 */
1375 if (extended_cap_id != EHCI_EX_CAP_ID_BIOS_HANDOFF) {
1376
1377 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1378 "ehci_take_control: Hardware doesn't support legacy");
1379
1380 goto success;
1381 }
1382
1383 /* Check if BIOS has owned it. */
1384 if (!(extended_cap & EHCI_LEGSUP_BIOS_OWNED_SEM)) {
1385
1386 USB_DPRINTF_L3(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
1387 "ehci_take_control: BIOS does not own EHCI");
1388
1862 EHCI_PFLT_DMA_BOUND) == EHCI_PFLT_DMA_BOUND) {
1863
1864 rval = ddi_dma_unbind_handle(
1865 ehcip->ehci_pflt_dma_handle);
1866
1867 ASSERT(rval == DDI_SUCCESS);
1868 }
1869
1870 ddi_dma_mem_free(&ehcip->ehci_pflt_mem_handle);
1871 }
1872
1873 (void) ehci_isoc_cleanup(ehcip);
1874
1875 if (ehcip->ehci_pflt_dma_handle) {
1876 ddi_dma_free_handle(&ehcip->ehci_pflt_dma_handle);
1877 }
1878
1879 if (flags & EHCI_INTR) {
1880 /* Destroy the mutex */
1881 mutex_destroy(&ehcip->ehci_int_mutex);
1882 }
1883
1884 /* clean up kstat structs */
1885 ehci_destroy_stats(ehcip);
1886
1887 /* Free ehci hcdi ops */
1888 if (ehcip->ehci_hcdi_ops) {
1889 usba_free_hcdi_ops(ehcip->ehci_hcdi_ops);
1890 }
1891
1892 if (flags & EHCI_ZALLOC) {
1893
1894 usb_free_log_hdl(ehcip->ehci_log_hdl);
1895
1896 /* Remove all properties that might have been created */
1897 ddi_prop_remove_all(ehcip->ehci_dip);
1898
1899 /* Free the soft state */
1900 ddi_soft_state_free(ehci_statep,
1901 ddi_get_instance(ehcip->ehci_dip));
2904 */
2905 static uint_t
2906 ehci_lattice_parent(uint_t node)
2907 {
2908 if ((node % 2) == 0) {
2909
2910 return ((node/2) - 1);
2911 } else {
2912
2913 return ((node + 1)/2 - 1);
2914 }
2915 }
2916
2917
2918 /*
2919 * ehci_find_periodic_node:
2920 *
2921 * Based on the "real" array leaf node and interval, get the periodic node.
2922 */
2923 static uint_t
2924 ehci_find_periodic_node(uint_t leaf, int interval)
2925 {
2926 uint_t lattice_leaf;
2927 uint_t height = ehci_lattice_height(interval);
2928 uint_t pnode;
2929 int i;
2930
2931 /* Get the leaf number in the lattice */
2932 lattice_leaf = leaf + EHCI_NUM_INTR_QH_LISTS - 1;
2933
2934 /* Get the node in the lattice based on the height and leaf */
2935 pnode = lattice_leaf;
2936 for (i = 0; i < height; i++) {
2937 pnode = ehci_lattice_parent(pnode);
2938 }
2939
2940 return (pnode);
2941 }
2942
2943
2944 /*
2945 * ehci_leftmost_leaf:
|