10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6881Sbharding * Common Development and Distribution License (the "License").
6*6881Sbharding * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*6881Sbharding * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * hci1394_ohci.c
300Sstevel@tonic-gate * Provides access routines to the OpenHCI HW.
310Sstevel@tonic-gate */
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include <sys/conf.h>
340Sstevel@tonic-gate #include <sys/ddi.h>
350Sstevel@tonic-gate #include <sys/modctl.h>
360Sstevel@tonic-gate #include <sys/sunddi.h>
370Sstevel@tonic-gate #include <sys/types.h>
380Sstevel@tonic-gate #include <sys/mkdev.h>
390Sstevel@tonic-gate #include <sys/kmem.h>
400Sstevel@tonic-gate #include <sys/pci.h>
410Sstevel@tonic-gate
420Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
430Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
440Sstevel@tonic-gate
450Sstevel@tonic-gate
460Sstevel@tonic-gate /*
470Sstevel@tonic-gate * Data swap macros used to swap config rom data that is going to be placed
480Sstevel@tonic-gate * in OpenHCI registers. The config rom is treated like a byte stream. When
490Sstevel@tonic-gate * the services layer calls into us to update the config rom, they pass us a
500Sstevel@tonic-gate * byte stream of data. This works well except for the the fact that the
510Sstevel@tonic-gate * hardware uses its internal registers for the first 5 quadlets. We have to
520Sstevel@tonic-gate * copy the cfgrom header and bus options into their corresponding OpenHCI
530Sstevel@tonic-gate * registers. On an x86 machine, this means we have to byte swap them first.
540Sstevel@tonic-gate */
550Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
560Sstevel@tonic-gate #define OHCI_SWAP32(DATA) (ddi_swap32(DATA))
570Sstevel@tonic-gate #else
580Sstevel@tonic-gate #define OHCI_SWAP32(DATA) (DATA)
590Sstevel@tonic-gate #endif
600Sstevel@tonic-gate
610Sstevel@tonic-gate
620Sstevel@tonic-gate static int hci1394_ohci_selfid_init(hci1394_ohci_handle_t ohci_hdl);
630Sstevel@tonic-gate static int hci1394_ohci_cfgrom_init(hci1394_ohci_handle_t ohci_hdl);
640Sstevel@tonic-gate static int hci1394_ohci_chip_init(hci1394_ohci_handle_t ohci_hdl);
650Sstevel@tonic-gate static int hci1394_ohci_phy_resume(hci1394_ohci_handle_t ohci_hdl);
660Sstevel@tonic-gate static int hci1394_ohci_1394a_init(hci1394_ohci_handle_t ohci_hdl);
670Sstevel@tonic-gate static int hci1394_ohci_1394a_resume(hci1394_ohci_handle_t ohci_hdl);
680Sstevel@tonic-gate static int hci1394_ohci_phy_read_no_lock(hci1394_ohci_handle_t ohci_hdl,
690Sstevel@tonic-gate uint_t address, uint_t *data);
700Sstevel@tonic-gate static int hci1394_ohci_phy_write_no_lock(hci1394_ohci_handle_t ohci_hdl,
710Sstevel@tonic-gate uint_t address, uint_t data);
720Sstevel@tonic-gate
730Sstevel@tonic-gate
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate * hci1394_ohci_init()
760Sstevel@tonic-gate * Initialize the OpenHCI hardware.
770Sstevel@tonic-gate */
780Sstevel@tonic-gate int
hci1394_ohci_init(hci1394_state_t * soft_state,hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t * ohci_hdl)790Sstevel@tonic-gate hci1394_ohci_init(hci1394_state_t *soft_state, hci1394_drvinfo_t *drvinfo,
800Sstevel@tonic-gate hci1394_ohci_handle_t *ohci_hdl)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate int status;
830Sstevel@tonic-gate uint32_t version;
840Sstevel@tonic-gate hci1394_ohci_t *ohci;
850Sstevel@tonic-gate #if defined(__x86)
860Sstevel@tonic-gate uint16_t cmdreg;
870Sstevel@tonic-gate #endif
880Sstevel@tonic-gate
890Sstevel@tonic-gate
900Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
910Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_enter, HCI1394_TNF_HAL_STACK, "");
920Sstevel@tonic-gate
930Sstevel@tonic-gate /* alloc the space for ohci */
940Sstevel@tonic-gate ohci = kmem_alloc(sizeof (hci1394_ohci_t), KM_SLEEP);
950Sstevel@tonic-gate *ohci_hdl = ohci;
960Sstevel@tonic-gate
970Sstevel@tonic-gate /*
980Sstevel@tonic-gate * Start with the cycle timer rollover interrupt disabled. When it is
990Sstevel@tonic-gate * enabled, we will get an interrupt every 64 seconds, even if we have
1000Sstevel@tonic-gate * nothing plugged into the bus. This interrupt is used to keep track
1010Sstevel@tonic-gate * of the bus time. We will enable the interrupt when the bus manager
1020Sstevel@tonic-gate * writes to the bus_time CSR register (Currently there are not known
1030Sstevel@tonic-gate * implementations that write to the bus_time register)
1040Sstevel@tonic-gate */
1050Sstevel@tonic-gate ohci->ohci_bustime_enabled = B_FALSE;
1060Sstevel@tonic-gate ohci->ohci_bustime_count = 0;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate ohci->ohci_set_root_holdoff = B_FALSE;
1090Sstevel@tonic-gate ohci->ohci_set_gap_count = B_FALSE;
1100Sstevel@tonic-gate ohci->ohci_gap_count = 0;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate mutex_init(&ohci->ohci_mutex, NULL, MUTEX_DRIVER,
1130Sstevel@tonic-gate drvinfo->di_iblock_cookie);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate /* Map OpenHCI Registers */
1160Sstevel@tonic-gate status = ddi_regs_map_setup(drvinfo->di_dip, OHCI_REG_SET,
1170Sstevel@tonic-gate (caddr_t *)&ohci->ohci_regs, 0, 0, &drvinfo->di_reg_attr,
1180Sstevel@tonic-gate &ohci->ohci_reg_handle);
1190Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1200Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
1210Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
1220Sstevel@tonic-gate *ohci_hdl = NULL;
1230Sstevel@tonic-gate TNF_PROBE_0(ddi_regs_map_setup_fail, HCI1394_TNF_HAL_ERROR,
1240Sstevel@tonic-gate "");
1250Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit, HCI1394_TNF_HAL_STACK,
1260Sstevel@tonic-gate "");
1270Sstevel@tonic-gate return (DDI_FAILURE);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate ohci->soft_state = soft_state;
1310Sstevel@tonic-gate ohci->ohci_drvinfo = drvinfo;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate /*
1340Sstevel@tonic-gate * make sure PCI Master and PCI Memory Access are enabled on x86
1350Sstevel@tonic-gate * platforms. This may not be the case if plug and play OS is
1360Sstevel@tonic-gate * set in the BIOS
1370Sstevel@tonic-gate */
1380Sstevel@tonic-gate #if defined(__x86)
1390Sstevel@tonic-gate cmdreg = pci_config_get16(soft_state->pci_config, PCI_CONF_COMM);
1400Sstevel@tonic-gate if ((cmdreg & (PCI_COMM_MAE | PCI_COMM_ME)) != (PCI_COMM_MAE |
1410Sstevel@tonic-gate PCI_COMM_ME)) {
1420Sstevel@tonic-gate cmdreg |= PCI_COMM_MAE | PCI_COMM_ME;
1430Sstevel@tonic-gate pci_config_put16(soft_state->pci_config, PCI_CONF_COMM, cmdreg);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate #endif
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate /*
1480Sstevel@tonic-gate * Initialize the openHCI chip. This is broken out because we need to
1490Sstevel@tonic-gate * do this when resuming too.
1500Sstevel@tonic-gate */
1510Sstevel@tonic-gate status = hci1394_ohci_chip_init(ohci);
1520Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1530Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
1540Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
1550Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
1560Sstevel@tonic-gate *ohci_hdl = NULL;
1570Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_chip_init_fail, HCI1394_TNF_HAL_ERROR,
1580Sstevel@tonic-gate "");
1590Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
1600Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1610Sstevel@tonic-gate return (DDI_FAILURE);
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate /* Init the 1394 PHY */
1650Sstevel@tonic-gate status = hci1394_ohci_phy_init(ohci);
1660Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1670Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
1680Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
1690Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
1700Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
1710Sstevel@tonic-gate *ohci_hdl = NULL;
1720Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_init_fail,
1730Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1740Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
1750Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1760Sstevel@tonic-gate return (DDI_FAILURE);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate /* Init 1394a features if present */
1800Sstevel@tonic-gate if (ohci->ohci_phy == H1394_PHY_1394A) {
1810Sstevel@tonic-gate status = hci1394_ohci_1394a_init(ohci);
1820Sstevel@tonic-gate if (status != DDI_SUCCESS) {
1830Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
1840Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
1850Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
1860Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
1870Sstevel@tonic-gate *ohci_hdl = NULL;
1880Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_1394a_init_fail,
1890Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
1900Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
1910Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
1920Sstevel@tonic-gate return (DDI_FAILURE);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate /* save away guid, phy type, and vendor info */
1970Sstevel@tonic-gate soft_state->halinfo.guid = hci1394_ohci_guid(ohci);
1980Sstevel@tonic-gate soft_state->halinfo.phy = ohci->ohci_phy;
1990Sstevel@tonic-gate soft_state->vendor_info.ohci_vendor_id =
2000Sstevel@tonic-gate ddi_get32(ohci->ohci_reg_handle, &ohci->ohci_regs->vendor_id);
2010Sstevel@tonic-gate version = ddi_get32(ohci->ohci_reg_handle, &ohci->ohci_regs->version);
2020Sstevel@tonic-gate soft_state->vendor_info.ohci_version = version;
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate /* We do not support version < 1.0 */
2050Sstevel@tonic-gate if (OHCI_VERSION(version) == 0) {
2060Sstevel@tonic-gate cmn_err(CE_NOTE,
2070Sstevel@tonic-gate "hci1394(%d): OpenHCI version %x.%x is not supported",
2080Sstevel@tonic-gate drvinfo->di_instance, OHCI_VERSION(version),
2090Sstevel@tonic-gate OHCI_REVISION(version));
2100Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
2110Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
2120Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
2130Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
2140Sstevel@tonic-gate *ohci_hdl = NULL;
2150Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_selfid_init_fail,
2160Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
2170Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
2180Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2190Sstevel@tonic-gate return (DDI_FAILURE);
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate /* Initialize the selfid buffer */
2230Sstevel@tonic-gate status = hci1394_ohci_selfid_init(ohci);
2240Sstevel@tonic-gate if (status != DDI_SUCCESS) {
2250Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
2260Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
2270Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
2280Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
2290Sstevel@tonic-gate *ohci_hdl = NULL;
2300Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_selfid_init_fail,
2310Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
2320Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
2330Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2340Sstevel@tonic-gate return (DDI_FAILURE);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /* Initialize the config rom buffer */
2380Sstevel@tonic-gate status = hci1394_ohci_cfgrom_init(ohci);
2390Sstevel@tonic-gate if (status != DDI_SUCCESS) {
2400Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
2410Sstevel@tonic-gate hci1394_buf_free(&ohci->ohci_selfid_handle);
2420Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
2430Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
2440Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
2450Sstevel@tonic-gate *ohci_hdl = NULL;
2460Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_cfgrom_init_fail,
2470Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
2480Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
2490Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
2500Sstevel@tonic-gate return (DDI_FAILURE);
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit, HCI1394_TNF_HAL_STACK, "");
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate return (DDI_SUCCESS);
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate /*
2600Sstevel@tonic-gate * hci1394_ohci_fini()
2610Sstevel@tonic-gate * Cleanup after OpenHCI init. This should be called during detach.
2620Sstevel@tonic-gate */
2630Sstevel@tonic-gate void
hci1394_ohci_fini(hci1394_ohci_handle_t * ohci_hdl)2640Sstevel@tonic-gate hci1394_ohci_fini(hci1394_ohci_handle_t *ohci_hdl)
2650Sstevel@tonic-gate {
2660Sstevel@tonic-gate hci1394_ohci_t *ohci;
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
2700Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_fini_enter, HCI1394_TNF_HAL_STACK, "");
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate ohci = *ohci_hdl;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate /* reset chip */
2750Sstevel@tonic-gate (void) hci1394_ohci_soft_reset(ohci);
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate /* Free config rom space */
2780Sstevel@tonic-gate hci1394_buf_free(&ohci->ohci_cfgrom_handle);
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate /* Free selfid buffer space */
2810Sstevel@tonic-gate hci1394_buf_free(&ohci->ohci_selfid_handle);
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate /* Free up the OpenHCI registers */
2840Sstevel@tonic-gate ddi_regs_map_free(&ohci->ohci_reg_handle);
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate mutex_destroy(&ohci->ohci_mutex);
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate /* Free the OpenHCI state space */
2890Sstevel@tonic-gate kmem_free(ohci, sizeof (hci1394_ohci_t));
2900Sstevel@tonic-gate *ohci_hdl = NULL;
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_fini_exit, HCI1394_TNF_HAL_STACK, "");
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate /*
2970Sstevel@tonic-gate * hci1394_ohci_chip_init()
2980Sstevel@tonic-gate * Initialize the OpenHCI registers. This contains the bulk of the initial
2990Sstevel@tonic-gate * register setup.
3000Sstevel@tonic-gate */
3010Sstevel@tonic-gate static int
hci1394_ohci_chip_init(hci1394_ohci_handle_t ohci_hdl)3020Sstevel@tonic-gate hci1394_ohci_chip_init(hci1394_ohci_handle_t ohci_hdl)
3030Sstevel@tonic-gate {
3040Sstevel@tonic-gate int status;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
3080Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_chip_init_enter, HCI1394_TNF_HAL_STACK,
3090Sstevel@tonic-gate "");
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate /* Reset 1394 OHCI HW */
3120Sstevel@tonic-gate status = hci1394_ohci_soft_reset(ohci_hdl);
3130Sstevel@tonic-gate if (status != DDI_SUCCESS) {
3140Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_soft_reset_fail,
3150Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
3160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_init_exit,
3170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
3180Sstevel@tonic-gate return (DDI_FAILURE);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate
3210Sstevel@tonic-gate /*
3220Sstevel@tonic-gate * Setup Host Control Register. The software reset does not put all
3230Sstevel@tonic-gate * registers in a known state. The Host Control Register is one of these
3240Sstevel@tonic-gate * registers. First make sure noByteSwapData and postedWriteEnable and
3250Sstevel@tonic-gate * are cleared.
3260Sstevel@tonic-gate */
3270Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3280Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_clr, OHCI_HC_NO_BSWAP |
3290Sstevel@tonic-gate OHCI_HC_POSTWR_ENBL);
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate /*
3320Sstevel@tonic-gate * the determination if we should swap data is made during the PCI
3330Sstevel@tonic-gate * initialization.
3340Sstevel@tonic-gate */
3350Sstevel@tonic-gate if (ohci_hdl->soft_state->swap_data == B_FALSE) {
3360Sstevel@tonic-gate /*
3370Sstevel@tonic-gate * most hba's don't swap data. It will be swapped in the
3380Sstevel@tonic-gate * global swap for SPARC. Enable Link Power(LPS). Enable
3390Sstevel@tonic-gate * Posted Writes
3400Sstevel@tonic-gate */
3410Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3420Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_NO_BSWAP |
3430Sstevel@tonic-gate OHCI_HC_LPS | OHCI_HC_POSTWR_ENBL);
3440Sstevel@tonic-gate } else {
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate * Swap Data. Enable Link Power(LPS). Enable Posted Writes
3470Sstevel@tonic-gate */
3480Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3490Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_LPS |
3500Sstevel@tonic-gate OHCI_HC_POSTWR_ENBL);
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate /*
3540Sstevel@tonic-gate * Wait for PHY to come up. There does not seem to be standard time for
3550Sstevel@tonic-gate * how long wait for the PHY to come up. The problem is that the PHY
3560Sstevel@tonic-gate * provides a clock to the link layer and if that is not stable, we
3570Sstevel@tonic-gate * could get a PCI timeout error when reading/writing a phy register
3580Sstevel@tonic-gate * (and maybe an OpenHCI register?) This used to be set to 10mS which
3590Sstevel@tonic-gate * works for just about every adapter we tested on. We got a new TI
3600Sstevel@tonic-gate * adapter which would crash the system once in a while if nothing
3610Sstevel@tonic-gate * (1394 device) was pluged into the adapter. Changing this delay to
3620Sstevel@tonic-gate * 50mS made that problem go away. This value is set via a patchable
3630Sstevel@tonic-gate * variable located in hci1394_extern.c
3640Sstevel@tonic-gate */
3650Sstevel@tonic-gate delay(drv_usectohz(hci1394_phy_stabilization_delay_uS));
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate /* Clear Isochrounous receive multi-chan mode registers */
3680Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3690Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_multi_maskhi_clr, 0xFFFFFFFF);
3700Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3710Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_multi_masklo_clr, 0xFFFFFFFF);
3720Sstevel@tonic-gate
3730Sstevel@tonic-gate /*
3740Sstevel@tonic-gate * Setup async retry on busy or ack_data_error
3750Sstevel@tonic-gate * secondlimit = 0 <= bits 31-29
3760Sstevel@tonic-gate * cycleLimit = 0 <= bits 28-16
3770Sstevel@tonic-gate * maxPhysRespRetries = 0 <= bits 11-8
3780Sstevel@tonic-gate * maxARRespRetries = 0 <= bits 7-4
3790Sstevel@tonic-gate * maxATReqRetries = 2 <= bits 3-0
3800Sstevel@tonic-gate */
3810Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3820Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_retries, 0x00000002);
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate /*
3850Sstevel@tonic-gate * Setup Link Control
3860Sstevel@tonic-gate * Enable cycleMaster, cycleTimerEnable, and rcvPhyPkt.
3870Sstevel@tonic-gate */
3880Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3890Sstevel@tonic-gate &ohci_hdl->ohci_regs->link_ctrl_clr, 0xFFFFFFFF);
3900Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
3910Sstevel@tonic-gate &ohci_hdl->ohci_regs->link_ctrl_set, OHCI_LC_CYC_MAST |
3920Sstevel@tonic-gate OHCI_LC_CTIME_ENBL | OHCI_LC_RCV_PHY);
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate /*
3950Sstevel@tonic-gate * Set the Physical address map boundary to 0x0000FFFFFFFF. The
3960Sstevel@tonic-gate * phys_upper_bound is the upper 32-bits of the 48-bit 1394 address. The
3970Sstevel@tonic-gate * lower 16 bits are assumed to be 0xFFFF.
3980Sstevel@tonic-gate */
3990Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4000Sstevel@tonic-gate &ohci_hdl->ohci_regs->phys_upper_bound, (uint32_t)0x0000FFFF);
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate /*
4030Sstevel@tonic-gate * Enable all async requests.
4040Sstevel@tonic-gate * The asyncReqResourceAll bit (0x80000000) does not get cleared during
4050Sstevel@tonic-gate * a bus reset. If this code is changed to selectively allow nodes to
4060Sstevel@tonic-gate * perform ARREQ's, the ARREQ filter bits will need to be updated after
4070Sstevel@tonic-gate * every bus reset.
4080Sstevel@tonic-gate */
4090Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4100Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_req_filterhi_set, (uint32_t)0x80000000);
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate /*
4130Sstevel@tonic-gate * clear isochronous interrupt event and mask registers clearing the
4140Sstevel@tonic-gate * mask registers disable all isoc tx & rx ints
4150Sstevel@tonic-gate */
4160Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4170Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_event_clr, (uint32_t)0xFFFFFFFF);
4180Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4190Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_mask_clr, (uint32_t)0xFFFFFFFF);
4200Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4210Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_event_clr, (uint32_t)0xFFFFFFFF);
4220Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4230Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_mask_clr, (uint32_t)0xFFFFFFFF);
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate /* Clear interrupt event/mask register */
4260Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4270Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_event_clr, (uint32_t)0xFFFFFFFF);
4280Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4290Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_mask_clr, (uint32_t)0xFFFFFFFF);
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_chip_init_exit, HCI1394_TNF_HAL_STACK,
4320Sstevel@tonic-gate "");
4330Sstevel@tonic-gate return (DDI_SUCCESS);
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate /*
4380Sstevel@tonic-gate * hci1394_ohci_soft_reset()
4390Sstevel@tonic-gate * Reset OpenHCI HW.
4400Sstevel@tonic-gate */
4410Sstevel@tonic-gate int
hci1394_ohci_soft_reset(hci1394_ohci_handle_t ohci_hdl)4420Sstevel@tonic-gate hci1394_ohci_soft_reset(hci1394_ohci_handle_t ohci_hdl)
4430Sstevel@tonic-gate {
4440Sstevel@tonic-gate uint32_t resetStatus;
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
4480Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_soft_reset_enter,
4490Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate /* Reset 1394 HW - Reset is bit 16 in HCControl */
4520Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
4530Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_SOFT_RESET);
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate /* Wait for reset to complete */
4560Sstevel@tonic-gate drv_usecwait(OHCI_CHIP_RESET_TIME_IN_uSEC);
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate /* Verify reset is complete */
4590Sstevel@tonic-gate resetStatus = ddi_get32(ohci_hdl->ohci_reg_handle,
4600Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set);
4610Sstevel@tonic-gate resetStatus = resetStatus & OHCI_HC_SOFT_RESET;
4620Sstevel@tonic-gate if (resetStatus != 0) {
4630Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_reset_not_complete_fail,
4640Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
4650Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_soft_reset_exit,
4660Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4670Sstevel@tonic-gate return (DDI_FAILURE);
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_soft_reset_exit,
4710Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate return (DDI_SUCCESS);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate /*
4780Sstevel@tonic-gate * hci1394_ohci_reg_read()
4790Sstevel@tonic-gate * Read OpenHCI register. This is called from the test ioctl interface
4800Sstevel@tonic-gate * through devctl.
4810Sstevel@tonic-gate */
4820Sstevel@tonic-gate void
hci1394_ohci_reg_read(hci1394_ohci_handle_t ohci_hdl,uint_t offset,uint32_t * data)4830Sstevel@tonic-gate hci1394_ohci_reg_read(hci1394_ohci_handle_t ohci_hdl,
4840Sstevel@tonic-gate uint_t offset, uint32_t *data)
4850Sstevel@tonic-gate {
4860Sstevel@tonic-gate uint32_t *addr;
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate
4890Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
4900Sstevel@tonic-gate ASSERT(data != NULL);
4910Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_reg_read_enter,
4920Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate addr = (uint32_t *)((uintptr_t)ohci_hdl->ohci_regs +
4950Sstevel@tonic-gate (uintptr_t)(offset & OHCI_REG_ADDR_MASK));
4960Sstevel@tonic-gate *data = ddi_get32(ohci_hdl->ohci_reg_handle, addr);
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_reg_read_exit,
4990Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate /*
5040Sstevel@tonic-gate * hci1394_ohci_reg_write()
5050Sstevel@tonic-gate * Write OpenHCI register. This is called from the test ioctl interface
5060Sstevel@tonic-gate * through devctl.
5070Sstevel@tonic-gate */
5080Sstevel@tonic-gate void
hci1394_ohci_reg_write(hci1394_ohci_handle_t ohci_hdl,uint_t offset,uint32_t data)5090Sstevel@tonic-gate hci1394_ohci_reg_write(hci1394_ohci_handle_t ohci_hdl,
5100Sstevel@tonic-gate uint_t offset, uint32_t data)
5110Sstevel@tonic-gate {
5120Sstevel@tonic-gate uint32_t *addr;
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
5160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_reg_read_enter,
5170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5180Sstevel@tonic-gate
5190Sstevel@tonic-gate addr = (uint32_t *)((uintptr_t)ohci_hdl->ohci_regs +
5200Sstevel@tonic-gate (uintptr_t)(offset & OHCI_REG_ADDR_MASK));
5210Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle, addr, data);
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_reg_read_exit,
5240Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate /*
5290Sstevel@tonic-gate * hci1394_ohci_intr_master_enable()
5300Sstevel@tonic-gate * Enable interrupts to be passed on from OpenHCI. This is a global mask.
5310Sstevel@tonic-gate * Individual interrupts still need to be enabled for interrupts to be
5320Sstevel@tonic-gate * generated.
5330Sstevel@tonic-gate */
5340Sstevel@tonic-gate void
hci1394_ohci_intr_master_enable(hci1394_ohci_handle_t ohci_hdl)5350Sstevel@tonic-gate hci1394_ohci_intr_master_enable(hci1394_ohci_handle_t ohci_hdl)
5360Sstevel@tonic-gate {
5370Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
5380Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_master_enable_enter,
5390Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
5420Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_mask_set, OHCI_INTR_MASTER_INTR_ENBL);
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_master_enable_exit,
5450Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5460Sstevel@tonic-gate }
5470Sstevel@tonic-gate
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate /*
5500Sstevel@tonic-gate * hci1394_ohci_intr_master_disable()
5510Sstevel@tonic-gate * Disable all OpenHCI interrupts from being passed on. This does not affect
5520Sstevel@tonic-gate * the individual interrupt mask settings. When interrupts are enabled
5530Sstevel@tonic-gate * again, the same individual interrupts will still be enabled.
5540Sstevel@tonic-gate */
5550Sstevel@tonic-gate void
hci1394_ohci_intr_master_disable(hci1394_ohci_handle_t ohci_hdl)5560Sstevel@tonic-gate hci1394_ohci_intr_master_disable(hci1394_ohci_handle_t ohci_hdl)
5570Sstevel@tonic-gate {
5580Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
5590Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_master_disable_enter,
5600Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
5630Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_mask_clr, OHCI_INTR_MASTER_INTR_ENBL);
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_master_disable_exit,
5660Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5670Sstevel@tonic-gate }
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate /*
5710Sstevel@tonic-gate * hci1394_ohci_intr_asserted()
5720Sstevel@tonic-gate * Return which ENABLED interrupts are asserted. If an interrupt is disabled
5730Sstevel@tonic-gate * via its mask bit, it will not be returned from here.
5740Sstevel@tonic-gate *
5750Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
5760Sstevel@tonic-gate */
5770Sstevel@tonic-gate uint32_t
hci1394_ohci_intr_asserted(hci1394_ohci_handle_t ohci_hdl)5780Sstevel@tonic-gate hci1394_ohci_intr_asserted(hci1394_ohci_handle_t ohci_hdl)
5790Sstevel@tonic-gate {
5800Sstevel@tonic-gate uint32_t interrupts_asserted;
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
5830Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_asserted_enter,
5840Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate /*
5870Sstevel@tonic-gate * Only look at interrupts which are enabled by reading the
5880Sstevel@tonic-gate * intr_event_clr register.
5890Sstevel@tonic-gate */
5900Sstevel@tonic-gate interrupts_asserted = ddi_get32(ohci_hdl->ohci_reg_handle,
5910Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_event_clr);
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_asserted_exit,
5940Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
5950Sstevel@tonic-gate return (interrupts_asserted);
5960Sstevel@tonic-gate }
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate
5990Sstevel@tonic-gate /*
6000Sstevel@tonic-gate * hci1394_ohci_intr_enable()
6010Sstevel@tonic-gate * Enable an individual interrupt or set of interrupts. This does not affect
6020Sstevel@tonic-gate * the global interrupt mask.
6030Sstevel@tonic-gate */
6040Sstevel@tonic-gate void
hci1394_ohci_intr_enable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)6050Sstevel@tonic-gate hci1394_ohci_intr_enable(hci1394_ohci_handle_t ohci_hdl,
6060Sstevel@tonic-gate uint32_t interrupt_mask)
6070Sstevel@tonic-gate {
6080Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
6090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_enable_enter,
6100Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6110Sstevel@tonic-gate
6120Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
6130Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_mask_set, interrupt_mask);
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_enable_exit,
6160Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate /*
6210Sstevel@tonic-gate * hci1394_ohci_intr_disable()
6220Sstevel@tonic-gate * Disable an individual interrupt or set of interrupts. This does not affect
6230Sstevel@tonic-gate * the global interrupt mask.
6240Sstevel@tonic-gate */
6250Sstevel@tonic-gate void
hci1394_ohci_intr_disable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)6260Sstevel@tonic-gate hci1394_ohci_intr_disable(hci1394_ohci_handle_t ohci_hdl,
6270Sstevel@tonic-gate uint32_t interrupt_mask)
6280Sstevel@tonic-gate {
6290Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
6300Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_disable_enter,
6310Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
6340Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_mask_clr, interrupt_mask);
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_disable_exit,
6370Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6380Sstevel@tonic-gate }
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate
6410Sstevel@tonic-gate /*
6420Sstevel@tonic-gate * hci1394_ohci_intr_clear()
6430Sstevel@tonic-gate * Clear a set of interrupts so that they are not asserted anymore.
6440Sstevel@tonic-gate *
6450Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
6460Sstevel@tonic-gate */
6470Sstevel@tonic-gate void
hci1394_ohci_intr_clear(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)6480Sstevel@tonic-gate hci1394_ohci_intr_clear(hci1394_ohci_handle_t ohci_hdl,
6490Sstevel@tonic-gate uint32_t interrupt_mask)
6500Sstevel@tonic-gate {
6510Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
6520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_clear_enter,
6530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
6560Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_event_clr, interrupt_mask);
6570Sstevel@tonic-gate TNF_PROBE_1_DEBUG(hci1394_ohci_intr_clear, HCI1394_TNF_HAL, "",
6580Sstevel@tonic-gate tnf_uint, intr_mask, interrupt_mask);
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_intr_clear_exit,
6610Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6620Sstevel@tonic-gate }
6630Sstevel@tonic-gate
6640Sstevel@tonic-gate
6650Sstevel@tonic-gate /*
6660Sstevel@tonic-gate * hci1394_ohci_it_intr_asserted()
6670Sstevel@tonic-gate * Return which ENABLED isoch TX interrupts are asserted. If an interrupt is
6680Sstevel@tonic-gate * disabled via its mask bit, it will not be returned from here.
6690Sstevel@tonic-gate *
6700Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
6710Sstevel@tonic-gate */
6720Sstevel@tonic-gate uint32_t
hci1394_ohci_it_intr_asserted(hci1394_ohci_handle_t ohci_hdl)6730Sstevel@tonic-gate hci1394_ohci_it_intr_asserted(hci1394_ohci_handle_t ohci_hdl)
6740Sstevel@tonic-gate {
6750Sstevel@tonic-gate uint32_t interrupts_asserted;
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
6780Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_asserted_enter,
6790Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6800Sstevel@tonic-gate
6810Sstevel@tonic-gate /* Only look at interrupts which are enabled */
6820Sstevel@tonic-gate interrupts_asserted = ddi_get32(ohci_hdl->ohci_reg_handle,
6830Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_event_clr);
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_asserted_exit,
6860Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
6870Sstevel@tonic-gate return (interrupts_asserted);
6880Sstevel@tonic-gate }
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate
6910Sstevel@tonic-gate /*
6920Sstevel@tonic-gate * hci1394_ohci_it_intr_enable()
6930Sstevel@tonic-gate * Enable an individual isoch TX interrupt. This does not affect the general
6940Sstevel@tonic-gate * isoch interrupt mask in the OpenHCI Mask register. That is enabled/
6950Sstevel@tonic-gate * disabled via hci1394_ohci_intr_enable/hci1394_ohci_intr_disable.
6960Sstevel@tonic-gate */
6970Sstevel@tonic-gate void
hci1394_ohci_it_intr_enable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)6980Sstevel@tonic-gate hci1394_ohci_it_intr_enable(hci1394_ohci_handle_t ohci_hdl,
6990Sstevel@tonic-gate uint32_t interrupt_mask)
7000Sstevel@tonic-gate {
7010Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
7020Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_enable_enter,
7030Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7040Sstevel@tonic-gate
7050Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
7060Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_mask_set, interrupt_mask);
7070Sstevel@tonic-gate
7080Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_enable_exit,
7090Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7100Sstevel@tonic-gate }
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate /*
7140Sstevel@tonic-gate * hci1394_ohci_it_intr_disable()
7150Sstevel@tonic-gate * Disable an individual isoch TX interrupt. This does not affect the general
7160Sstevel@tonic-gate * isoch interrupt mask in the OpenHCI Mask register. That is enabled/
7170Sstevel@tonic-gate * disabled via hci1394_ohci_intr_enable/hci1394_ohci_intr_disable.
7180Sstevel@tonic-gate */
7190Sstevel@tonic-gate void
hci1394_ohci_it_intr_disable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)7200Sstevel@tonic-gate hci1394_ohci_it_intr_disable(hci1394_ohci_handle_t ohci_hdl,
7210Sstevel@tonic-gate uint32_t interrupt_mask)
7220Sstevel@tonic-gate {
7230Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
7240Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_disable_enter,
7250Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
7280Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_mask_clr, interrupt_mask);
7290Sstevel@tonic-gate
7300Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_disable_exit,
7310Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7320Sstevel@tonic-gate }
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate /*
7360Sstevel@tonic-gate * hci1394_ohci_it_intr_clear()
7370Sstevel@tonic-gate * Clear an individual isoch TX interrupt so that it is not asserted anymore.
7380Sstevel@tonic-gate *
7390Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
7400Sstevel@tonic-gate */
7410Sstevel@tonic-gate void
hci1394_ohci_it_intr_clear(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)7420Sstevel@tonic-gate hci1394_ohci_it_intr_clear(hci1394_ohci_handle_t ohci_hdl,
7430Sstevel@tonic-gate uint32_t interrupt_mask)
7440Sstevel@tonic-gate {
7450Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
7460Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_clear_enter,
7470Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
7500Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_event_clr, interrupt_mask);
7510Sstevel@tonic-gate
7520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_intr_clear_exit,
7530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate /*
7580Sstevel@tonic-gate * hci1394_ohci_it_ctxt_count_get()
7590Sstevel@tonic-gate * Determine the number of supported isochronous transmit contexts.
7600Sstevel@tonic-gate */
7610Sstevel@tonic-gate int
hci1394_ohci_it_ctxt_count_get(hci1394_ohci_handle_t ohci_hdl)7620Sstevel@tonic-gate hci1394_ohci_it_ctxt_count_get(hci1394_ohci_handle_t ohci_hdl)
7630Sstevel@tonic-gate {
7640Sstevel@tonic-gate uint32_t channel_mask;
7650Sstevel@tonic-gate int count;
7660Sstevel@tonic-gate
7670Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
7680Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_ctxt_count_get_enter,
7690Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate /*
7720Sstevel@tonic-gate * hw is required to support contexts 0 to N, where N <= 31
7730Sstevel@tonic-gate * the interrupt mask bits are wired to ground for unsupported
7740Sstevel@tonic-gate * contexts. Write 1's to all it mask bits, then read the mask.
7750Sstevel@tonic-gate * Implemented contexts will read (sequentially) as 1
7760Sstevel@tonic-gate */
7770Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
7780Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_mask_set, 0xFFFFFFFF);
7790Sstevel@tonic-gate channel_mask = ddi_get32(ohci_hdl->ohci_reg_handle,
7800Sstevel@tonic-gate &ohci_hdl->ohci_regs->it_intr_mask_set);
7810Sstevel@tonic-gate count = 0;
7820Sstevel@tonic-gate while (channel_mask != 0) {
7830Sstevel@tonic-gate channel_mask = channel_mask >> 1;
7840Sstevel@tonic-gate count++;
7850Sstevel@tonic-gate }
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_ctxt_count_get_exit,
7880Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
7890Sstevel@tonic-gate return (count);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate
7930Sstevel@tonic-gate /*
7940Sstevel@tonic-gate * hci1394_ohci_it_cmd_ptr_set()
7950Sstevel@tonic-gate * Set the context pointer for a given isoch TX context. This is the IO
7960Sstevel@tonic-gate * address for the HW to fetch the first descriptor. The context should
7970Sstevel@tonic-gate * not be running when this routine is called.
7980Sstevel@tonic-gate */
7990Sstevel@tonic-gate void
hci1394_ohci_it_cmd_ptr_set(hci1394_ohci_handle_t ohci_hdl,uint_t context_number,uint32_t io_addr)8000Sstevel@tonic-gate hci1394_ohci_it_cmd_ptr_set(hci1394_ohci_handle_t ohci_hdl,
8010Sstevel@tonic-gate uint_t context_number, uint32_t io_addr)
8020Sstevel@tonic-gate {
8030Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
8040Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_cmd_ptr_set_enter,
8050Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
8080Sstevel@tonic-gate &ohci_hdl->ohci_regs->it[context_number].cmd_ptrlo,
8090Sstevel@tonic-gate io_addr);
8100Sstevel@tonic-gate
8110Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_it_cmd_ptr_set_exit,
8120Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate
8160Sstevel@tonic-gate /*
8170Sstevel@tonic-gate * hci1394_ohci_ir_intr_asserted()
8180Sstevel@tonic-gate * Return which ENABLED isoch RX interrupts are asserted. If an interrupt is
8190Sstevel@tonic-gate * disabled via its mask bit, it will not be returned from here.
8200Sstevel@tonic-gate *
8210Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
8220Sstevel@tonic-gate */
8230Sstevel@tonic-gate uint32_t
hci1394_ohci_ir_intr_asserted(hci1394_ohci_handle_t ohci_hdl)8240Sstevel@tonic-gate hci1394_ohci_ir_intr_asserted(hci1394_ohci_handle_t ohci_hdl)
8250Sstevel@tonic-gate {
8260Sstevel@tonic-gate uint32_t interrupts_asserted;
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
8290Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_asserted_enter,
8300Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8310Sstevel@tonic-gate
8320Sstevel@tonic-gate /* Only look at interrupts which are enabled */
8330Sstevel@tonic-gate interrupts_asserted = ddi_get32(ohci_hdl->ohci_reg_handle,
8340Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_event_clr);
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_asserted_exit,
8370Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8380Sstevel@tonic-gate return (interrupts_asserted);
8390Sstevel@tonic-gate }
8400Sstevel@tonic-gate
8410Sstevel@tonic-gate
8420Sstevel@tonic-gate /*
8430Sstevel@tonic-gate * hci1394_ohci_ir_intr_enable()
8440Sstevel@tonic-gate * Enable an individual isoch RX interrupt. This does not affect the isoch
8450Sstevel@tonic-gate * interrupt mask in the OpenHCI Mask register. That is enabled/disabled
8460Sstevel@tonic-gate * via hci1394_ohci_intr_enable/hci1394_ohci_intr_disable.
8470Sstevel@tonic-gate */
8480Sstevel@tonic-gate void
hci1394_ohci_ir_intr_enable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)8490Sstevel@tonic-gate hci1394_ohci_ir_intr_enable(hci1394_ohci_handle_t ohci_hdl,
8500Sstevel@tonic-gate uint32_t interrupt_mask)
8510Sstevel@tonic-gate {
8520Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
8530Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_enable_enter,
8540Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
8570Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_mask_set, interrupt_mask);
8580Sstevel@tonic-gate
8590Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_enable_exit,
8600Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8610Sstevel@tonic-gate }
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate /*
8650Sstevel@tonic-gate * hci1394_ohci_ir_intr_disable()
8660Sstevel@tonic-gate * Disable an individual isoch RX interrupt. This does not affect the isoch
8670Sstevel@tonic-gate * interrupt mask in the OpenHCI Mask register. That is enabled/disabled
8680Sstevel@tonic-gate * via hci1394_ohci_intr_enable/hci1394_ohci_intr_disable.
8690Sstevel@tonic-gate */
8700Sstevel@tonic-gate void
hci1394_ohci_ir_intr_disable(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)8710Sstevel@tonic-gate hci1394_ohci_ir_intr_disable(hci1394_ohci_handle_t ohci_hdl,
8720Sstevel@tonic-gate uint32_t interrupt_mask)
8730Sstevel@tonic-gate {
8740Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
8750Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_disable_enter,
8760Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
8790Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_mask_clr, interrupt_mask);
8800Sstevel@tonic-gate
8810Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_disable_exit,
8820Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8830Sstevel@tonic-gate }
8840Sstevel@tonic-gate
8850Sstevel@tonic-gate
8860Sstevel@tonic-gate /*
8870Sstevel@tonic-gate * hci1394_ohci_ir_intr_clear()
8880Sstevel@tonic-gate * Clear an individual isoch RX interrupt so that it is not asserted anymore.
8890Sstevel@tonic-gate *
8900Sstevel@tonic-gate * NOTE: we may want to make this a macro at some point.
8910Sstevel@tonic-gate */
8920Sstevel@tonic-gate void
hci1394_ohci_ir_intr_clear(hci1394_ohci_handle_t ohci_hdl,uint32_t interrupt_mask)8930Sstevel@tonic-gate hci1394_ohci_ir_intr_clear(hci1394_ohci_handle_t ohci_hdl,
8940Sstevel@tonic-gate uint32_t interrupt_mask)
8950Sstevel@tonic-gate {
8960Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
8970Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_clear_enter,
8980Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
8990Sstevel@tonic-gate
9000Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
9010Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_event_clr, interrupt_mask);
9020Sstevel@tonic-gate
9030Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_intr_clear_exit,
9040Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate /*
9090Sstevel@tonic-gate * hci1394_ohci_ir_ctxt_count_get()
9100Sstevel@tonic-gate * Determine the number of supported isochronous receive contexts.
9110Sstevel@tonic-gate */
9120Sstevel@tonic-gate int
hci1394_ohci_ir_ctxt_count_get(hci1394_ohci_handle_t ohci_hdl)9130Sstevel@tonic-gate hci1394_ohci_ir_ctxt_count_get(hci1394_ohci_handle_t ohci_hdl)
9140Sstevel@tonic-gate {
9150Sstevel@tonic-gate uint32_t channel_mask;
9160Sstevel@tonic-gate int count;
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
9190Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_ctxt_count_get_enter,
9200Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate /*
9230Sstevel@tonic-gate * hw is required to support contexts 0 to N, where N <= 31
9240Sstevel@tonic-gate * the interrupt mask bits are wired to ground for unsupported
9250Sstevel@tonic-gate * contexts. Write 1's to all ir mask bits, then read the mask.
9260Sstevel@tonic-gate * Implemented contexts will read (sequentially) as 1
9270Sstevel@tonic-gate */
9280Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
9290Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_mask_set, 0xFFFFFFFF);
9300Sstevel@tonic-gate channel_mask = ddi_get32(ohci_hdl->ohci_reg_handle,
9310Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir_intr_mask_set);
9320Sstevel@tonic-gate count = 0;
9330Sstevel@tonic-gate while (channel_mask != 0) {
9340Sstevel@tonic-gate channel_mask = channel_mask >> 1;
9350Sstevel@tonic-gate count++;
9360Sstevel@tonic-gate }
9370Sstevel@tonic-gate
9380Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_ctxt_count_get_exit,
9390Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9400Sstevel@tonic-gate return (count);
9410Sstevel@tonic-gate }
9420Sstevel@tonic-gate
9430Sstevel@tonic-gate
9440Sstevel@tonic-gate /*
9450Sstevel@tonic-gate * hci1394_ohci_ir_cmd_ptr_set()
9460Sstevel@tonic-gate * Set the context pointer for a given isoch RX context. This is the IO
9470Sstevel@tonic-gate * address for the HW to fetch the first descriptor. The context should
9480Sstevel@tonic-gate * not be running when this routine is called.
9490Sstevel@tonic-gate */
9500Sstevel@tonic-gate void
hci1394_ohci_ir_cmd_ptr_set(hci1394_ohci_handle_t ohci_hdl,uint_t context_number,uint32_t io_addr)9510Sstevel@tonic-gate hci1394_ohci_ir_cmd_ptr_set(hci1394_ohci_handle_t ohci_hdl,
9520Sstevel@tonic-gate uint_t context_number, uint32_t io_addr)
9530Sstevel@tonic-gate {
9540Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
9550Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_cmd_ptr_set_enter,
9560Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9570Sstevel@tonic-gate
9580Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
9590Sstevel@tonic-gate &ohci_hdl->ohci_regs->ir[context_number].cmd_ptrlo,
9600Sstevel@tonic-gate io_addr);
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_ir_cmd_ptr_set_exit,
9630Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9640Sstevel@tonic-gate }
9650Sstevel@tonic-gate
9660Sstevel@tonic-gate
9670Sstevel@tonic-gate /*
9680Sstevel@tonic-gate * hci1394_ohci_link_enable()
9690Sstevel@tonic-gate * Enable the 1394 link layer. When the link is enabled, the PHY will pass
9700Sstevel@tonic-gate * up any 1394 bus transactions which would normally come up to the link.
9710Sstevel@tonic-gate */
9720Sstevel@tonic-gate void
hci1394_ohci_link_enable(hci1394_ohci_handle_t ohci_hdl)9730Sstevel@tonic-gate hci1394_ohci_link_enable(hci1394_ohci_handle_t ohci_hdl)
9740Sstevel@tonic-gate {
9750Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
9760Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_link_enable_enter,
9770Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9780Sstevel@tonic-gate
9790Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
9800Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_LINK_ENBL);
9810Sstevel@tonic-gate
9820Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_link_enable_exit,
9830Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate
9860Sstevel@tonic-gate
9870Sstevel@tonic-gate /*
9880Sstevel@tonic-gate * hci1394_ohci_link_disable()
9890Sstevel@tonic-gate * Disable the 1394 link layer. When the link is disabled, the PHY will NOT
9900Sstevel@tonic-gate * pass up any 1394 bus transactions which would normally come up to the
9910Sstevel@tonic-gate * link. This "logically" disconnects us from the 1394 bus.
9920Sstevel@tonic-gate */
9930Sstevel@tonic-gate void
hci1394_ohci_link_disable(hci1394_ohci_handle_t ohci_hdl)9940Sstevel@tonic-gate hci1394_ohci_link_disable(hci1394_ohci_handle_t ohci_hdl)
9950Sstevel@tonic-gate {
9960Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
9970Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_link_disable_enter,
9980Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
9990Sstevel@tonic-gate
10000Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
10010Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_clr, OHCI_HC_LINK_ENBL);
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_link_disable_exit,
10040Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
10050Sstevel@tonic-gate }
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate
10080Sstevel@tonic-gate /*
10090Sstevel@tonic-gate * hci1394_ohci_bus_reset()
10100Sstevel@tonic-gate * Reset the 1394 bus. This performs a "long" bus reset and can be called
10110Sstevel@tonic-gate * when the adapter has either a 1394-1995 or 1394A PHY.
10120Sstevel@tonic-gate */
10130Sstevel@tonic-gate int
hci1394_ohci_bus_reset(hci1394_ohci_handle_t ohci_hdl)10140Sstevel@tonic-gate hci1394_ohci_bus_reset(hci1394_ohci_handle_t ohci_hdl)
10150Sstevel@tonic-gate {
10160Sstevel@tonic-gate int status;
10170Sstevel@tonic-gate uint_t reg;
10180Sstevel@tonic-gate
10190Sstevel@tonic-gate
10200Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
10210Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_enter,
10220Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
10230Sstevel@tonic-gate
10240Sstevel@tonic-gate /*
10250Sstevel@tonic-gate * We want to reset the bus. We also handle the root_holdoff and gap
10260Sstevel@tonic-gate * count cacheing explained at the top of this file.
10270Sstevel@tonic-gate */
10280Sstevel@tonic-gate reg = OHCI_PHY_IBR;
10290Sstevel@tonic-gate if (ohci_hdl->ohci_set_root_holdoff == B_TRUE) {
10300Sstevel@tonic-gate reg = reg | OHCI_PHY_RHB;
10310Sstevel@tonic-gate }
10320Sstevel@tonic-gate if (ohci_hdl->ohci_set_gap_count == B_TRUE) {
10330Sstevel@tonic-gate reg = reg | ohci_hdl->ohci_gap_count;
10340Sstevel@tonic-gate } else {
10350Sstevel@tonic-gate reg = reg | OHCI_PHY_MAX_GAP;
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate /*
10390Sstevel@tonic-gate * Reset the bus. We intentionally do NOT do a PHY read here. A PHY
10400Sstevel@tonic-gate * read could introduce race conditions and would be more likely to fail
10410Sstevel@tonic-gate * due to a timeout.
10420Sstevel@tonic-gate */
10430Sstevel@tonic-gate status = hci1394_ohci_phy_write(ohci_hdl, 0x1, reg);
10440Sstevel@tonic-gate if (status != DDI_SUCCESS) {
10450Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_write_fail,
10460Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
10470Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_exit,
10480Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
10490Sstevel@tonic-gate return (DDI_FAILURE);
10500Sstevel@tonic-gate }
10510Sstevel@tonic-gate
10520Sstevel@tonic-gate /* clear the root holdoff and gap count state bits */
10530Sstevel@tonic-gate ohci_hdl->ohci_set_root_holdoff = B_FALSE;
10540Sstevel@tonic-gate ohci_hdl->ohci_set_gap_count = B_FALSE;
10550Sstevel@tonic-gate
10560Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_exit,
10570Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
10580Sstevel@tonic-gate
10590Sstevel@tonic-gate return (DDI_SUCCESS);
10600Sstevel@tonic-gate }
10610Sstevel@tonic-gate
1062*6881Sbharding /*
1063*6881Sbharding *
1064*6881Sbharding * hci1394_ohci_bus_reset_nroot()
1065*6881Sbharding * Reset the 1394 bus. This performs a "long" bus reset with out a root.
1066*6881Sbharding */
1067*6881Sbharding int
hci1394_ohci_bus_reset_nroot(hci1394_ohci_handle_t ohci_hdl)1068*6881Sbharding hci1394_ohci_bus_reset_nroot(hci1394_ohci_handle_t ohci_hdl)
1069*6881Sbharding {
1070*6881Sbharding int status;
1071*6881Sbharding uint_t reg;
1072*6881Sbharding
1073*6881Sbharding ASSERT(ohci_hdl != NULL);
1074*6881Sbharding
1075*6881Sbharding /*
1076*6881Sbharding * We want to reset the bus. We don't care about any holdoff
1077*6881Sbharding * we are suspending need no root...
1078*6881Sbharding */
1079*6881Sbharding (void) hci1394_ohci_phy_read(ohci_hdl, 0x1, ®);
1080*6881Sbharding reg = reg | OHCI_PHY_IBR;
1081*6881Sbharding reg = reg & ~OHCI_PHY_RHB;
1082*6881Sbharding
1083*6881Sbharding /*
1084*6881Sbharding * Reset the bus. We intentionally do NOT do a PHY read here. A PHY
1085*6881Sbharding * read could introduce race conditions and would be more likely to fail
1086*6881Sbharding * due to a timeout.
1087*6881Sbharding */
1088*6881Sbharding status = hci1394_ohci_phy_write(ohci_hdl, 0x1, reg);
1089*6881Sbharding if (status != DDI_SUCCESS) {
1090*6881Sbharding TNF_PROBE_0(hci1394_ohci_phy_write_fail,
1091*6881Sbharding HCI1394_TNF_HAL_ERROR, "");
1092*6881Sbharding TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_nroot_exit,
1093*6881Sbharding HCI1394_TNF_HAL_STACK, "");
1094*6881Sbharding return (DDI_FAILURE);
1095*6881Sbharding }
1096*6881Sbharding
1097*6881Sbharding return (DDI_SUCCESS);
1098*6881Sbharding }
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate /*
11010Sstevel@tonic-gate * hci1394_ohci_phy_init()
11020Sstevel@tonic-gate * Setup the PHY. This should be called during attach and performs any PHY
11030Sstevel@tonic-gate * initialization required including figuring out what kind of PHY we have.
11040Sstevel@tonic-gate */
11050Sstevel@tonic-gate int
hci1394_ohci_phy_init(hci1394_ohci_handle_t ohci_hdl)11060Sstevel@tonic-gate hci1394_ohci_phy_init(hci1394_ohci_handle_t ohci_hdl)
11070Sstevel@tonic-gate {
11080Sstevel@tonic-gate int status;
11090Sstevel@tonic-gate uint_t phy_reg;
11100Sstevel@tonic-gate
11110Sstevel@tonic-gate
11120Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
11130Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_init_enter,
11140Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11150Sstevel@tonic-gate
11160Sstevel@tonic-gate /*
11170Sstevel@tonic-gate * if the phy has extended set to 7, the phy is a not a 1394-1995 PHY.
11180Sstevel@tonic-gate * It could be a 1394a phy or beyond. The PHY type can be found in PHY
11190Sstevel@tonic-gate * register page 1 in the compliance_level register.
11200Sstevel@tonic-gate *
11210Sstevel@tonic-gate * Since there are not any current standards beyond 1394A, we are going
11220Sstevel@tonic-gate * to consider the PHY to be a 1394A phy if the extended bit is set.
11230Sstevel@tonic-gate *
11240Sstevel@tonic-gate * phy registers are byte wide registers and are addressed as 0, 1, 2,
11250Sstevel@tonic-gate * 3, ... Phy register 0 may not be read or written.
11260Sstevel@tonic-gate *
11270Sstevel@tonic-gate * Phy register 0x2 (bit 0 MSB, 7 LSB)
11280Sstevel@tonic-gate * Extended - bits 0 - 2
11290Sstevel@tonic-gate * Total Ports - bits 4 - 7
11300Sstevel@tonic-gate */
11310Sstevel@tonic-gate status = hci1394_ohci_phy_read(ohci_hdl, 2, &phy_reg);
11320Sstevel@tonic-gate if (status != DDI_SUCCESS) {
11330Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_failed,
11340Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
11350Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_init_exit,
11360Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11370Sstevel@tonic-gate return (DDI_FAILURE);
11380Sstevel@tonic-gate }
11390Sstevel@tonic-gate
11400Sstevel@tonic-gate if ((phy_reg & OHCI_PHY_EXTND_MASK) != OHCI_PHY_EXTND) {
11410Sstevel@tonic-gate /*
11420Sstevel@tonic-gate * if the extended bit is not set, we have to be a 1394-1995
11430Sstevel@tonic-gate * PHY
11440Sstevel@tonic-gate */
11450Sstevel@tonic-gate ohci_hdl->ohci_phy = H1394_PHY_1995;
11460Sstevel@tonic-gate } else {
11470Sstevel@tonic-gate /* Treat all other PHY's as a 1394A PHY */
11480Sstevel@tonic-gate ohci_hdl->ohci_phy = H1394_PHY_1394A;
11490Sstevel@tonic-gate }
11500Sstevel@tonic-gate
11510Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_init_exit,
11520Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11530Sstevel@tonic-gate
11540Sstevel@tonic-gate return (DDI_SUCCESS);
11550Sstevel@tonic-gate }
11560Sstevel@tonic-gate
11570Sstevel@tonic-gate
11580Sstevel@tonic-gate /*
11590Sstevel@tonic-gate * hci1394_ohci_phy_resume()
11600Sstevel@tonic-gate * re-initialize the PHY. This routine should be called during a resume after
11610Sstevel@tonic-gate * a successful suspend has been done.
11620Sstevel@tonic-gate */
11630Sstevel@tonic-gate /* ARGSUSED */
11640Sstevel@tonic-gate static int
hci1394_ohci_phy_resume(hci1394_ohci_handle_t ohci_hdl)11650Sstevel@tonic-gate hci1394_ohci_phy_resume(hci1394_ohci_handle_t ohci_hdl)
11660Sstevel@tonic-gate {
11670Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
11680Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_resume_enter,
11690Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11700Sstevel@tonic-gate
11710Sstevel@tonic-gate /* There is currently nothing to re-initialize here */
11720Sstevel@tonic-gate
11730Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_resume_exit,
11740Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11750Sstevel@tonic-gate
11760Sstevel@tonic-gate return (DDI_SUCCESS);
11770Sstevel@tonic-gate }
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate
11800Sstevel@tonic-gate /*
11810Sstevel@tonic-gate * hci1394_ohci_phy_set()
11820Sstevel@tonic-gate * Perform bitset operation on PHY register.
11830Sstevel@tonic-gate */
11840Sstevel@tonic-gate int
hci1394_ohci_phy_set(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t bits)11850Sstevel@tonic-gate hci1394_ohci_phy_set(hci1394_ohci_handle_t ohci_hdl, uint_t address,
11860Sstevel@tonic-gate uint_t bits)
11870Sstevel@tonic-gate {
11880Sstevel@tonic-gate int status;
11890Sstevel@tonic-gate uint_t reg;
11900Sstevel@tonic-gate
11910Sstevel@tonic-gate
11920Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
11930Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_set_enter,
11940Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
11950Sstevel@tonic-gate
11960Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
11970Sstevel@tonic-gate
11980Sstevel@tonic-gate /* read the PHY register */
11990Sstevel@tonic-gate status = hci1394_ohci_phy_read_no_lock(ohci_hdl, address, ®);
12000Sstevel@tonic-gate if (status != DDI_SUCCESS) {
12010Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12020Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_fail,
12030Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
12040Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_set_exit,
12050Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
12060Sstevel@tonic-gate return (DDI_FAILURE);
12070Sstevel@tonic-gate }
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate /* Set the bits and write the result back */
12100Sstevel@tonic-gate reg = reg | bits;
12110Sstevel@tonic-gate status = hci1394_ohci_phy_write_no_lock(ohci_hdl, address, reg);
12120Sstevel@tonic-gate if (status != DDI_SUCCESS) {
12130Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12140Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_write_fail,
12150Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
12160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_set_exit,
12170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
12180Sstevel@tonic-gate return (DDI_FAILURE);
12190Sstevel@tonic-gate }
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12220Sstevel@tonic-gate
12230Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_set_exit, HCI1394_TNF_HAL_STACK,
12240Sstevel@tonic-gate "");
12250Sstevel@tonic-gate
12260Sstevel@tonic-gate return (DDI_SUCCESS);
12270Sstevel@tonic-gate }
12280Sstevel@tonic-gate
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate /*
12310Sstevel@tonic-gate * hci1394_ohci_phy_clr()
12320Sstevel@tonic-gate * Perform bitclr operation on PHY register.
12330Sstevel@tonic-gate */
12340Sstevel@tonic-gate int
hci1394_ohci_phy_clr(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t bits)12350Sstevel@tonic-gate hci1394_ohci_phy_clr(hci1394_ohci_handle_t ohci_hdl, uint_t address,
12360Sstevel@tonic-gate uint_t bits)
12370Sstevel@tonic-gate {
12380Sstevel@tonic-gate int status;
12390Sstevel@tonic-gate uint_t reg;
12400Sstevel@tonic-gate
12410Sstevel@tonic-gate
12420Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
12430Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_clr_enter,
12440Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
12450Sstevel@tonic-gate
12460Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
12470Sstevel@tonic-gate
12480Sstevel@tonic-gate /* read the PHY register */
12490Sstevel@tonic-gate status = hci1394_ohci_phy_read_no_lock(ohci_hdl, address, ®);
12500Sstevel@tonic-gate if (status != DDI_SUCCESS) {
12510Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12520Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_fail,
12530Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
12540Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_clr_exit,
12550Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
12560Sstevel@tonic-gate return (DDI_FAILURE);
12570Sstevel@tonic-gate }
12580Sstevel@tonic-gate
12590Sstevel@tonic-gate /* Set the bits and write the result back */
12600Sstevel@tonic-gate reg = reg & ~bits;
12610Sstevel@tonic-gate status = hci1394_ohci_phy_write_no_lock(ohci_hdl, address, reg);
12620Sstevel@tonic-gate if (status != DDI_SUCCESS) {
12630Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12640Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_write_fail,
12650Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
12660Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_clr_exit,
12670Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
12680Sstevel@tonic-gate return (DDI_FAILURE);
12690Sstevel@tonic-gate }
12700Sstevel@tonic-gate
12710Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12720Sstevel@tonic-gate
12730Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_clr_exit, HCI1394_TNF_HAL_STACK,
12740Sstevel@tonic-gate "");
12750Sstevel@tonic-gate
12760Sstevel@tonic-gate return (DDI_SUCCESS);
12770Sstevel@tonic-gate }
12780Sstevel@tonic-gate
12790Sstevel@tonic-gate
12800Sstevel@tonic-gate /*
12810Sstevel@tonic-gate * hci1394_ohci_phy_read()
12820Sstevel@tonic-gate * Atomic PHY register read
12830Sstevel@tonic-gate */
12840Sstevel@tonic-gate int
hci1394_ohci_phy_read(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t * data)12850Sstevel@tonic-gate hci1394_ohci_phy_read(hci1394_ohci_handle_t ohci_hdl, uint_t address,
12860Sstevel@tonic-gate uint_t *data)
12870Sstevel@tonic-gate {
12880Sstevel@tonic-gate int status;
12890Sstevel@tonic-gate
12900Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
12910Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_enter, HCI1394_TNF_HAL_STACK,
12920Sstevel@tonic-gate "");
12930Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
12940Sstevel@tonic-gate status = hci1394_ohci_phy_read_no_lock(ohci_hdl, address, data);
12950Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
12960Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_exit, HCI1394_TNF_HAL_STACK,
12970Sstevel@tonic-gate "");
12980Sstevel@tonic-gate
12990Sstevel@tonic-gate return (status);
13000Sstevel@tonic-gate }
13010Sstevel@tonic-gate
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate /*
13040Sstevel@tonic-gate * hci1394_ohci_phy_write()
13050Sstevel@tonic-gate * Atomic PHY register write
13060Sstevel@tonic-gate */
13070Sstevel@tonic-gate int
hci1394_ohci_phy_write(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t data)13080Sstevel@tonic-gate hci1394_ohci_phy_write(hci1394_ohci_handle_t ohci_hdl, uint_t address,
13090Sstevel@tonic-gate uint_t data)
13100Sstevel@tonic-gate {
13110Sstevel@tonic-gate int status;
13120Sstevel@tonic-gate
13130Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
13140Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_enter, HCI1394_TNF_HAL_STACK,
13150Sstevel@tonic-gate "");
13160Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
13170Sstevel@tonic-gate status = hci1394_ohci_phy_write_no_lock(ohci_hdl, address, data);
13180Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
13190Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_exit, HCI1394_TNF_HAL_STACK,
13200Sstevel@tonic-gate "");
13210Sstevel@tonic-gate
13220Sstevel@tonic-gate return (status);
13230Sstevel@tonic-gate }
13240Sstevel@tonic-gate
13250Sstevel@tonic-gate
13260Sstevel@tonic-gate /*
13270Sstevel@tonic-gate * hci1394_ohci_phy_read_no_lock()
13280Sstevel@tonic-gate * This routine actually performs the PHY register read. It is seperated
13290Sstevel@tonic-gate * out from phy_read so set & clr lock can perform an atomic PHY register
13300Sstevel@tonic-gate * operation. It assumes the OpenHCI mutex is held.
13310Sstevel@tonic-gate */
13320Sstevel@tonic-gate static int
hci1394_ohci_phy_read_no_lock(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t * data)13330Sstevel@tonic-gate hci1394_ohci_phy_read_no_lock(hci1394_ohci_handle_t ohci_hdl, uint_t address,
13340Sstevel@tonic-gate uint_t *data)
13350Sstevel@tonic-gate {
13360Sstevel@tonic-gate uint32_t ohci_reg;
13370Sstevel@tonic-gate int count;
13380Sstevel@tonic-gate
13390Sstevel@tonic-gate
13400Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
13410Sstevel@tonic-gate ASSERT(data != NULL);
13420Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ohci_hdl->ohci_mutex));
13430Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_no_lock_enter,
13440Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
13450Sstevel@tonic-gate
13460Sstevel@tonic-gate /* You can't read or write PHY register #0 */
13470Sstevel@tonic-gate if (address == 0) {
13480Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_phy_addr_fail, HCI1394_TNF_HAL_ERROR,
13490Sstevel@tonic-gate "", tnf_string, errmsg, "can't rd/wr PHY reg #0");
13500Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_no_lock_exit,
13510Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
13520Sstevel@tonic-gate return (DDI_FAILURE);
13530Sstevel@tonic-gate }
13540Sstevel@tonic-gate
13550Sstevel@tonic-gate /* Verify phy access not in progress */
13560Sstevel@tonic-gate ohci_reg = ddi_get32(ohci_hdl->ohci_reg_handle,
13570Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl);
13580Sstevel@tonic-gate if ((ohci_reg & (OHCI_PHYC_RDREG | OHCI_PHYC_WRREG)) != 0) {
13590Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_phy_xfer_fail, HCI1394_TNF_HAL_ERROR,
13600Sstevel@tonic-gate "", tnf_string, errmsg, "transfer already in progress?");
13610Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_no_lock_exit,
13620Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
13630Sstevel@tonic-gate return (DDI_FAILURE);
13640Sstevel@tonic-gate }
13650Sstevel@tonic-gate
13660Sstevel@tonic-gate /* Start the PHY register read */
13670Sstevel@tonic-gate ohci_reg = OHCI_PHYC_RDREG | ((address & 0xF) <<
13680Sstevel@tonic-gate OHCI_PHYC_REGADDR_SHIFT);
13690Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle, &ohci_hdl->ohci_regs->phy_ctrl,
13700Sstevel@tonic-gate ohci_reg);
13710Sstevel@tonic-gate
13720Sstevel@tonic-gate /*
13730Sstevel@tonic-gate * The PHY read usually takes less than 1uS. It is not worth having
13740Sstevel@tonic-gate * this be interrupt driven. Having this be interrupt driven would also
13750Sstevel@tonic-gate * make the bus reset and self id processing much more complex for
13760Sstevel@tonic-gate * 1995 PHY's. We will wait up to hci1394_phy_delay_uS for the read
13770Sstevel@tonic-gate * to complete (this was initially set to 10). I have yet to see
13780Sstevel@tonic-gate * count > 1. The delay is a patchable variable.
13790Sstevel@tonic-gate */
13800Sstevel@tonic-gate count = 0;
13810Sstevel@tonic-gate while (count < hci1394_phy_delay_uS) {
13820Sstevel@tonic-gate /* See if the read is done yet */
13830Sstevel@tonic-gate ohci_reg = ddi_get32(ohci_hdl->ohci_reg_handle,
13840Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl);
13850Sstevel@tonic-gate if ((ohci_reg & OHCI_PHYC_RDDONE) != 0) {
13860Sstevel@tonic-gate /*
13870Sstevel@tonic-gate * The read is done. clear the phyRegRecv interrupt. We
13880Sstevel@tonic-gate * do not have this interrupt enabled but this keeps
13890Sstevel@tonic-gate * things clean in case someone in the future does.
13900Sstevel@tonic-gate * Break out of the loop, we are done.
13910Sstevel@tonic-gate */
13920Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
13930Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_event_clr,
13940Sstevel@tonic-gate OHCI_INTR_PHY_REG_RCVD);
13950Sstevel@tonic-gate break;
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate
13980Sstevel@tonic-gate /*
13990Sstevel@tonic-gate * the phy read did not yet complete, wait 1uS, increment the
14000Sstevel@tonic-gate * count and try again.
14010Sstevel@tonic-gate */
14020Sstevel@tonic-gate drv_usecwait(1);
14030Sstevel@tonic-gate count++;
14040Sstevel@tonic-gate }
14050Sstevel@tonic-gate
14060Sstevel@tonic-gate /* Check to see if we timed out */
14070Sstevel@tonic-gate if (count >= hci1394_phy_delay_uS) {
14080Sstevel@tonic-gate /* we timed out, return failure */
14090Sstevel@tonic-gate *data = 0;
14100Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_rd_timeout_fail,
14110Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
14120Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_no_lock_exit,
14130Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
14140Sstevel@tonic-gate return (DDI_FAILURE);
14150Sstevel@tonic-gate }
14160Sstevel@tonic-gate
14170Sstevel@tonic-gate /* setup the PHY read data to be returned */
14180Sstevel@tonic-gate *data = (ddi_get32(ohci_hdl->ohci_reg_handle,
14190Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl) & OHCI_PHYC_RDDATA_MASK) >>
14200Sstevel@tonic-gate OHCI_PHYC_RDDATA_SHIFT;
14210Sstevel@tonic-gate
14220Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_read_no_lock_exit,
14230Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
14240Sstevel@tonic-gate
14250Sstevel@tonic-gate return (DDI_SUCCESS);
14260Sstevel@tonic-gate }
14270Sstevel@tonic-gate
14280Sstevel@tonic-gate
14290Sstevel@tonic-gate /*
14300Sstevel@tonic-gate * hci1394_ohci_phy_write_no_lock()
14310Sstevel@tonic-gate * This routine actually performs the PHY register write. It is separated
14320Sstevel@tonic-gate * out from phy_write so set & clr lock can perform an atomic PHY register
14330Sstevel@tonic-gate * operation. It assumes the OpenHCI mutex is held.
14340Sstevel@tonic-gate */
14350Sstevel@tonic-gate static int
hci1394_ohci_phy_write_no_lock(hci1394_ohci_handle_t ohci_hdl,uint_t address,uint_t data)14360Sstevel@tonic-gate hci1394_ohci_phy_write_no_lock(hci1394_ohci_handle_t ohci_hdl, uint_t address,
14370Sstevel@tonic-gate uint_t data)
14380Sstevel@tonic-gate {
14390Sstevel@tonic-gate uint32_t ohci_reg;
14400Sstevel@tonic-gate int count;
14410Sstevel@tonic-gate
14420Sstevel@tonic-gate
14430Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
14440Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ohci_hdl->ohci_mutex));
14450Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_enter,
14460Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate /* You can't read or write PHY register #0 */
14490Sstevel@tonic-gate if (address == 0) {
14500Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_phy_addr_fail, HCI1394_TNF_HAL_ERROR,
14510Sstevel@tonic-gate "", tnf_string, errmsg, "can't rd/wr PHY reg #0");
14520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_exit,
14530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
14540Sstevel@tonic-gate return (DDI_FAILURE);
14550Sstevel@tonic-gate }
14560Sstevel@tonic-gate
14570Sstevel@tonic-gate /* Verify phy access not in progress */
14580Sstevel@tonic-gate ohci_reg = ddi_get32(ohci_hdl->ohci_reg_handle,
14590Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl);
14600Sstevel@tonic-gate if ((ohci_reg & (OHCI_PHYC_RDREG | OHCI_PHYC_WRREG)) != 0) {
14610Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_phy_xfer_fail, HCI1394_TNF_HAL_ERROR,
14620Sstevel@tonic-gate "", tnf_string, errmsg, "transfer already in progress?");
14630Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_exit,
14640Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
14650Sstevel@tonic-gate return (DDI_FAILURE);
14660Sstevel@tonic-gate }
14670Sstevel@tonic-gate
14680Sstevel@tonic-gate /* Start the PHY register write */
14690Sstevel@tonic-gate ohci_reg = OHCI_PHYC_WRREG | ((address & 0xF) <<
14700Sstevel@tonic-gate OHCI_PHYC_REGADDR_SHIFT) | (data & OHCI_PHYC_WRDATA_MASK);
14710Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
14720Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl, ohci_reg);
14730Sstevel@tonic-gate
14740Sstevel@tonic-gate /*
14750Sstevel@tonic-gate * The PHY write usually takes less than 1uS. It is not worth having
14760Sstevel@tonic-gate * this be interrupt driven. Having this be interrupt driven would also
14770Sstevel@tonic-gate * make the bus reset and self id processing much more complex. We will
14780Sstevel@tonic-gate * wait up to hci1394_phy_delay_uS for the write to complete (this was
14790Sstevel@tonic-gate * initially set to 10). I have yet to see count > 0. The delay is a
14800Sstevel@tonic-gate * patchable variable.
14810Sstevel@tonic-gate */
14820Sstevel@tonic-gate count = 0;
14830Sstevel@tonic-gate while (count < hci1394_phy_delay_uS) {
14840Sstevel@tonic-gate /* See if the write is done yet */
14850Sstevel@tonic-gate ohci_reg = ddi_get32(ohci_hdl->ohci_reg_handle,
14860Sstevel@tonic-gate &ohci_hdl->ohci_regs->phy_ctrl);
14870Sstevel@tonic-gate if ((ohci_reg & OHCI_PHYC_WRREG) == 0) {
14880Sstevel@tonic-gate /*
14890Sstevel@tonic-gate * The write completed. Break out of the loop, we are
14900Sstevel@tonic-gate * done.
14910Sstevel@tonic-gate */
14920Sstevel@tonic-gate break;
14930Sstevel@tonic-gate }
14940Sstevel@tonic-gate
14950Sstevel@tonic-gate /*
14960Sstevel@tonic-gate * the phy write did not yet complete, wait 1uS, increment the
14970Sstevel@tonic-gate * count and try again.
14980Sstevel@tonic-gate */
14990Sstevel@tonic-gate drv_usecwait(1);
15000Sstevel@tonic-gate count++;
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate
15030Sstevel@tonic-gate /* Check to see if we timed out */
15040Sstevel@tonic-gate if (count >= hci1394_phy_delay_uS) {
15050Sstevel@tonic-gate /* we timed out, return failure */
15060Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_wr_timeout_fail,
15070Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
15080Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_exit,
15090Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15100Sstevel@tonic-gate return (DDI_FAILURE);
15110Sstevel@tonic-gate }
15120Sstevel@tonic-gate
15130Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_write_exit,
15140Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15150Sstevel@tonic-gate
15160Sstevel@tonic-gate return (DDI_SUCCESS);
15170Sstevel@tonic-gate }
15180Sstevel@tonic-gate
15190Sstevel@tonic-gate
15200Sstevel@tonic-gate /*
15210Sstevel@tonic-gate * hci1394_ohci_phy_info()
15220Sstevel@tonic-gate * Return selfid word for our PHY. This routine should ONLY be called for
15230Sstevel@tonic-gate * adapters with a 1394-1995 PHY. These PHY's do not embed their own selfid
15240Sstevel@tonic-gate * information in the selfid buffer so we need to do it for them in the
15250Sstevel@tonic-gate * selfid complete interrupt handler. This routine only supports building
15260Sstevel@tonic-gate * selfid info for a 3 port PHY. Since we will probably not ever see a
15270Sstevel@tonic-gate * 1394-1995 PHY in any production system, and if we do it will have 3 ports
15280Sstevel@tonic-gate * or less, this is a pretty safe assumption.
15290Sstevel@tonic-gate */
15300Sstevel@tonic-gate int
hci1394_ohci_phy_info(hci1394_ohci_handle_t ohci_hdl,uint32_t * info)15310Sstevel@tonic-gate hci1394_ohci_phy_info(hci1394_ohci_handle_t ohci_hdl, uint32_t *info)
15320Sstevel@tonic-gate {
15330Sstevel@tonic-gate int status;
15340Sstevel@tonic-gate uint32_t phy_info;
15350Sstevel@tonic-gate uint32_t reg;
15360Sstevel@tonic-gate int index;
15370Sstevel@tonic-gate int num_ports;
15380Sstevel@tonic-gate int count;
15390Sstevel@tonic-gate uint32_t port_status;
15400Sstevel@tonic-gate
15410Sstevel@tonic-gate
15420Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
15430Sstevel@tonic-gate ASSERT(info != NULL);
15440Sstevel@tonic-gate ASSERT(ohci_hdl->ohci_phy == H1394_PHY_1995);
15450Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_enter,
15460Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15470Sstevel@tonic-gate
15480Sstevel@tonic-gate /*
15490Sstevel@tonic-gate * Set Link on. We are using power class 0 since we have no idea what
15500Sstevel@tonic-gate * our real power class is.
15510Sstevel@tonic-gate */
15520Sstevel@tonic-gate phy_info = 0x80400000;
15530Sstevel@tonic-gate
15540Sstevel@tonic-gate /* Add in Physical ID */
15550Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
15560Sstevel@tonic-gate &ohci_hdl->ohci_regs->node_id);
15570Sstevel@tonic-gate phy_info = phy_info | ((reg << IEEE1394_SELFID_PHYID_SHIFT) &
15580Sstevel@tonic-gate IEEE1394_SELFID_PHYID_MASK);
15590Sstevel@tonic-gate
15600Sstevel@tonic-gate /* Add in Gap Count */
15610Sstevel@tonic-gate status = hci1394_ohci_phy_read(ohci_hdl, 1, ®);
15620Sstevel@tonic-gate if (status != DDI_SUCCESS) {
15630Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_fail,
15640Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
15650Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_exit,
15660Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15670Sstevel@tonic-gate return (DDI_FAILURE);
15680Sstevel@tonic-gate }
15690Sstevel@tonic-gate phy_info = phy_info | ((reg << IEEE1394_SELFID_GAP_CNT_SHIFT) &
15700Sstevel@tonic-gate IEEE1394_SELFID_GAP_CNT_MASK);
15710Sstevel@tonic-gate
15720Sstevel@tonic-gate /* Add in speed & ports */
15730Sstevel@tonic-gate status = hci1394_ohci_phy_read(ohci_hdl, 2, ®);
15740Sstevel@tonic-gate if (status != DDI_SUCCESS) {
15750Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_fail,
15760Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
15770Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_exit,
15780Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15790Sstevel@tonic-gate return (DDI_FAILURE);
15800Sstevel@tonic-gate }
15810Sstevel@tonic-gate phy_info = phy_info | ((reg & 0xC0) << 8);
15820Sstevel@tonic-gate num_ports = reg & 0x1F;
15830Sstevel@tonic-gate
15840Sstevel@tonic-gate /* PHY reports that it has 0 ports?? */
15850Sstevel@tonic-gate if (num_ports == 0) {
15860Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_phy_zero_ports_fail,
15870Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
15880Sstevel@tonic-gate "1995 phy has zero ports?");
15890Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_exit,
15900Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
15910Sstevel@tonic-gate return (DDI_FAILURE);
15920Sstevel@tonic-gate }
15930Sstevel@tonic-gate
15940Sstevel@tonic-gate /* Build up the port information for each port in the PHY */
15950Sstevel@tonic-gate count = 0;
15960Sstevel@tonic-gate for (index = 0; index < 3; index++) {
15970Sstevel@tonic-gate if (num_ports > 0) {
15980Sstevel@tonic-gate status = hci1394_ohci_phy_read(ohci_hdl,
15990Sstevel@tonic-gate count + 3, ®);
16000Sstevel@tonic-gate if (status != DDI_SUCCESS) {
16010Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_fail,
16020Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
16030Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_exit,
16040Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
16050Sstevel@tonic-gate return (DDI_FAILURE);
16060Sstevel@tonic-gate }
16070Sstevel@tonic-gate /* if port is not connected */
16080Sstevel@tonic-gate if ((reg & 0x04) == 0) {
16090Sstevel@tonic-gate port_status =
16100Sstevel@tonic-gate IEEE1394_SELFID_PORT_NOT_CONNECTED;
16110Sstevel@tonic-gate
16120Sstevel@tonic-gate /* else if port is connected to parent */
16130Sstevel@tonic-gate } else if ((reg & 0x08) == 0) {
16140Sstevel@tonic-gate port_status = IEEE1394_SELFID_PORT_TO_PARENT;
16150Sstevel@tonic-gate
16160Sstevel@tonic-gate /* else port is connected to child */
16170Sstevel@tonic-gate } else {
16180Sstevel@tonic-gate port_status = IEEE1394_SELFID_PORT_TO_CHILD;
16190Sstevel@tonic-gate }
16200Sstevel@tonic-gate
16210Sstevel@tonic-gate num_ports--;
16220Sstevel@tonic-gate } else {
16230Sstevel@tonic-gate port_status = IEEE1394_SELFID_PORT_NO_PORT;
16240Sstevel@tonic-gate }
16250Sstevel@tonic-gate
16260Sstevel@tonic-gate /* add in the port information */
16270Sstevel@tonic-gate phy_info = phy_info | (port_status << (6 - (index * 2)));
16280Sstevel@tonic-gate count++;
16290Sstevel@tonic-gate }
16300Sstevel@tonic-gate
16310Sstevel@tonic-gate /* Copy the PHY selfid info to the return parameter */
16320Sstevel@tonic-gate *info = phy_info;
16330Sstevel@tonic-gate
16340Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_info_exit,
16350Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate return (DDI_SUCCESS);
16380Sstevel@tonic-gate }
16390Sstevel@tonic-gate
16400Sstevel@tonic-gate
16410Sstevel@tonic-gate /*
16420Sstevel@tonic-gate * hci1394_ohci_current_busgen()
16430Sstevel@tonic-gate * return the current bus generation.
16440Sstevel@tonic-gate */
16450Sstevel@tonic-gate uint_t
hci1394_ohci_current_busgen(hci1394_ohci_handle_t ohci_hdl)16460Sstevel@tonic-gate hci1394_ohci_current_busgen(hci1394_ohci_handle_t ohci_hdl)
16470Sstevel@tonic-gate {
16480Sstevel@tonic-gate uint32_t reg;
16490Sstevel@tonic-gate uint_t generation_count;
16500Sstevel@tonic-gate
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
16530Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_current_busgen_enter,
16540Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
16550Sstevel@tonic-gate
16560Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
16570Sstevel@tonic-gate &ohci_hdl->ohci_regs->self_id_count);
16580Sstevel@tonic-gate generation_count = (reg & OHCI_SLFC_GEN_MASK) >> OHCI_SLFC_GEN_SHIFT;
16590Sstevel@tonic-gate
16600Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_current_busgen_exit,
16610Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
16620Sstevel@tonic-gate
16630Sstevel@tonic-gate return (generation_count);
16640Sstevel@tonic-gate }
16650Sstevel@tonic-gate
16660Sstevel@tonic-gate
16670Sstevel@tonic-gate /*
16680Sstevel@tonic-gate * hci1394_ohci_startup()
16690Sstevel@tonic-gate * Startup the 1394 nexus driver. This is called after all of the HW has
16700Sstevel@tonic-gate * been initialized (in both attach and resume) and we are ready to
16710Sstevel@tonic-gate * participate on the bus.
16720Sstevel@tonic-gate */
16730Sstevel@tonic-gate int
hci1394_ohci_startup(hci1394_ohci_handle_t ohci_hdl)16740Sstevel@tonic-gate hci1394_ohci_startup(hci1394_ohci_handle_t ohci_hdl)
16750Sstevel@tonic-gate {
16760Sstevel@tonic-gate int status;
16770Sstevel@tonic-gate
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
16800Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_startup_enter,
16810Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
16820Sstevel@tonic-gate
16830Sstevel@tonic-gate /*
16840Sstevel@tonic-gate * Turn on 1394 link. This allows us to receive 1394 traffic off the
16850Sstevel@tonic-gate * bus
16860Sstevel@tonic-gate */
16870Sstevel@tonic-gate hci1394_ohci_link_enable(ohci_hdl);
16880Sstevel@tonic-gate
16890Sstevel@tonic-gate /*
16900Sstevel@tonic-gate * Reset the 1394 Bus.
16910Sstevel@tonic-gate * Need to do this so that the link layer can collect all of the self-id
16920Sstevel@tonic-gate * packets. The Interrupt routine will cause further initialization
16930Sstevel@tonic-gate * after the bus reset has completed
16940Sstevel@tonic-gate */
16950Sstevel@tonic-gate status = hci1394_ohci_bus_reset(ohci_hdl);
16960Sstevel@tonic-gate if (status != DDI_SUCCESS) {
16970Sstevel@tonic-gate TNF_PROBE_1_DEBUG(hci1394_ohci_startup_exit,
16980Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
16990Sstevel@tonic-gate "failed to reset bus");
17000Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_startup_exit,
17010Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
17020Sstevel@tonic-gate return (DDI_FAILURE);
17030Sstevel@tonic-gate }
17040Sstevel@tonic-gate
17050Sstevel@tonic-gate /* setup out initial interrupt mask and enable interrupts */
17060Sstevel@tonic-gate hci1394_isr_mask_setup(ohci_hdl->soft_state);
17070Sstevel@tonic-gate hci1394_ohci_intr_master_enable(ohci_hdl);
17080Sstevel@tonic-gate
17090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_startup_exit, HCI1394_TNF_HAL_STACK,
17100Sstevel@tonic-gate "");
17110Sstevel@tonic-gate
17120Sstevel@tonic-gate return (DDI_SUCCESS);
17130Sstevel@tonic-gate }
17140Sstevel@tonic-gate
17150Sstevel@tonic-gate
17160Sstevel@tonic-gate /*
17170Sstevel@tonic-gate * hci1394_ohci_postwr_addr()
17180Sstevel@tonic-gate * Read the Posted Write Address registers. This should be read when a
17190Sstevel@tonic-gate * posted write error is detected to find out what transaction had an error.
17200Sstevel@tonic-gate */
17210Sstevel@tonic-gate void
hci1394_ohci_postwr_addr(hci1394_ohci_handle_t ohci_hdl,uint64_t * addr)17220Sstevel@tonic-gate hci1394_ohci_postwr_addr(hci1394_ohci_handle_t ohci_hdl, uint64_t *addr)
17230Sstevel@tonic-gate {
17240Sstevel@tonic-gate uint32_t reg;
17250Sstevel@tonic-gate
17260Sstevel@tonic-gate
17270Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
17280Sstevel@tonic-gate ASSERT(addr != NULL);
17290Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_postwr_addr_enter,
17300Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
17310Sstevel@tonic-gate
17320Sstevel@tonic-gate /* read in the errored address */
17330Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
17340Sstevel@tonic-gate &ohci_hdl->ohci_regs->posted_write_addrhi);
17350Sstevel@tonic-gate *addr = ((uint64_t)reg) << 32;
17360Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
17370Sstevel@tonic-gate &ohci_hdl->ohci_regs->posted_write_addrlo);
17380Sstevel@tonic-gate *addr = *addr | (uint64_t)reg;
17390Sstevel@tonic-gate
17400Sstevel@tonic-gate /*
17410Sstevel@tonic-gate * Interrupt should be cleared after reading the posted write address.
17420Sstevel@tonic-gate * See 13.2.8.1 in OpenHCI spec v1.0.
17430Sstevel@tonic-gate */
17440Sstevel@tonic-gate hci1394_ohci_intr_clear(ohci_hdl, OHCI_INTR_POST_WR_ERR);
17450Sstevel@tonic-gate
17460Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_postwr_addr_exit,
17470Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
17480Sstevel@tonic-gate }
17490Sstevel@tonic-gate
17500Sstevel@tonic-gate
17510Sstevel@tonic-gate /*
17520Sstevel@tonic-gate * hci1394_ohci_guid()
17530Sstevel@tonic-gate * Return the adapter's GUID
17540Sstevel@tonic-gate */
17550Sstevel@tonic-gate uint64_t
hci1394_ohci_guid(hci1394_ohci_handle_t ohci_hdl)17560Sstevel@tonic-gate hci1394_ohci_guid(hci1394_ohci_handle_t ohci_hdl)
17570Sstevel@tonic-gate {
17580Sstevel@tonic-gate uint32_t reg;
17590Sstevel@tonic-gate uint64_t guid;
17600Sstevel@tonic-gate
17610Sstevel@tonic-gate
17620Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
17630Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_guid_enter, HCI1394_TNF_HAL_STACK, "");
17640Sstevel@tonic-gate
17650Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
17660Sstevel@tonic-gate &ohci_hdl->ohci_regs->guid_hi);
17670Sstevel@tonic-gate guid = ((uint64_t)reg) << 32;
17680Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
17690Sstevel@tonic-gate &ohci_hdl->ohci_regs->guid_lo);
17700Sstevel@tonic-gate guid = guid | (uint64_t)reg;
17710Sstevel@tonic-gate
17720Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_guid_exit, HCI1394_TNF_HAL_STACK, "");
17730Sstevel@tonic-gate
17740Sstevel@tonic-gate return (guid);
17750Sstevel@tonic-gate }
17760Sstevel@tonic-gate
17770Sstevel@tonic-gate
17780Sstevel@tonic-gate /*
17790Sstevel@tonic-gate * hci1394_ohci_csr_read()
17800Sstevel@tonic-gate * Read one of the HW implemented CSR registers. These include
17810Sstevel@tonic-gate * bus_manager_id, bandwidth_available, channels_available_hi, and
17820Sstevel@tonic-gate * channels_available_lo. Offset should be set to
17830Sstevel@tonic-gate * OHCI_CSR_SEL_BUS_MGR_ID, OHCI_CSR_SEL_BANDWIDTH_AVAIL
17840Sstevel@tonic-gate * OHCI_CSR_SEL_CHANS_AVAIL_HI, or OHCI_CSR_SEL_CHANS_AVAIL_LO.
17850Sstevel@tonic-gate */
17860Sstevel@tonic-gate int
hci1394_ohci_csr_read(hci1394_ohci_handle_t ohci_hdl,uint_t offset,uint32_t * data)17870Sstevel@tonic-gate hci1394_ohci_csr_read(hci1394_ohci_handle_t ohci_hdl, uint_t offset,
17880Sstevel@tonic-gate uint32_t *data)
17890Sstevel@tonic-gate {
17900Sstevel@tonic-gate uint_t generation;
17910Sstevel@tonic-gate int status;
17920Sstevel@tonic-gate
17930Sstevel@tonic-gate
17940Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
17950Sstevel@tonic-gate ASSERT(data != NULL);
17960Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_read_enter, HCI1394_TNF_HAL_STACK,
17970Sstevel@tonic-gate "");
17980Sstevel@tonic-gate
17990Sstevel@tonic-gate /*
18000Sstevel@tonic-gate * read the CSR register by doing a cswap with the same compare and
18010Sstevel@tonic-gate * swap value.
18020Sstevel@tonic-gate */
18030Sstevel@tonic-gate generation = hci1394_ohci_current_busgen(ohci_hdl);
18040Sstevel@tonic-gate status = hci1394_ohci_csr_cswap(ohci_hdl, generation, offset, 0, 0,
18050Sstevel@tonic-gate data);
18060Sstevel@tonic-gate if (status != DDI_SUCCESS) {
18070Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_csr_read_csw_fail,
18080Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
18090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_read_exit,
18100Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
18110Sstevel@tonic-gate return (DDI_FAILURE);
18120Sstevel@tonic-gate }
18130Sstevel@tonic-gate
18140Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_read_exit, HCI1394_TNF_HAL_STACK,
18150Sstevel@tonic-gate "");
18160Sstevel@tonic-gate
18170Sstevel@tonic-gate return (DDI_SUCCESS);
18180Sstevel@tonic-gate }
18190Sstevel@tonic-gate
18200Sstevel@tonic-gate
18210Sstevel@tonic-gate /*
18220Sstevel@tonic-gate * hci1394_ohci_csr_cswap()
18230Sstevel@tonic-gate * Perform a compare/swap on one of the HW implemented CSR registers. These
18240Sstevel@tonic-gate * include bus_manager_id, bandwidth_available, channels_available_hi, and
18250Sstevel@tonic-gate * channels_available_lo. Offset should be set to
18260Sstevel@tonic-gate * OHCI_CSR_SEL_BUS_MGR_ID, OHCI_CSR_SEL_BANDWIDTH_AVAIL
18270Sstevel@tonic-gate * OHCI_CSR_SEL_CHANS_AVAIL_HI, or OHCI_CSR_SEL_CHANS_AVAIL_LO.
18280Sstevel@tonic-gate */
18290Sstevel@tonic-gate int
hci1394_ohci_csr_cswap(hci1394_ohci_handle_t ohci_hdl,uint_t generation,uint_t offset,uint32_t compare,uint32_t swap,uint32_t * old)18300Sstevel@tonic-gate hci1394_ohci_csr_cswap(hci1394_ohci_handle_t ohci_hdl, uint_t generation,
18310Sstevel@tonic-gate uint_t offset, uint32_t compare, uint32_t swap, uint32_t *old)
18320Sstevel@tonic-gate {
18330Sstevel@tonic-gate int count;
18340Sstevel@tonic-gate uint32_t ohci_reg;
18350Sstevel@tonic-gate
18360Sstevel@tonic-gate
18370Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
18380Sstevel@tonic-gate ASSERT(old != NULL);
18390Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_cswap_enter,
18400Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
18410Sstevel@tonic-gate
18420Sstevel@tonic-gate /*
18430Sstevel@tonic-gate * Make sure we have not gotten a bus reset since this action was
18440Sstevel@tonic-gate * started.
18450Sstevel@tonic-gate */
18460Sstevel@tonic-gate if (generation != hci1394_ohci_current_busgen(ohci_hdl)) {
18470Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_invbusgen_fail, HCI1394_TNF_HAL_ERROR,
18480Sstevel@tonic-gate "", tnf_string, errmsg, "Invalid Bus Generation");
18490Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_cswap_exit,
18500Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
18510Sstevel@tonic-gate return (DDI_FAILURE);
18520Sstevel@tonic-gate }
18530Sstevel@tonic-gate
18540Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
18550Sstevel@tonic-gate
18560Sstevel@tonic-gate /* init csrData and csrCompare */
18570Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
18580Sstevel@tonic-gate &ohci_hdl->ohci_regs->csr_data, swap);
18590Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
18600Sstevel@tonic-gate &ohci_hdl->ohci_regs->csr_compare_data, compare);
18610Sstevel@tonic-gate
18620Sstevel@tonic-gate /* start the compare swap */
18630Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
18640Sstevel@tonic-gate &ohci_hdl->ohci_regs->csr_ctrl, offset & OHCI_CSR_SELECT);
18650Sstevel@tonic-gate
18660Sstevel@tonic-gate /*
18670Sstevel@tonic-gate * The CSR access should be immediate. There in nothing that officially
18680Sstevel@tonic-gate * states this so we will wait up to 2uS just in case before we timeout.
18690Sstevel@tonic-gate * We actually perform a compare swap with both compare and swap set
18700Sstevel@tonic-gate * to the same value. This will return the old value which is in
18710Sstevel@tonic-gate * essence, a read.
18720Sstevel@tonic-gate */
18730Sstevel@tonic-gate count = 0;
18740Sstevel@tonic-gate while (count < 2) {
18750Sstevel@tonic-gate /* See if the compare swap is done */
18760Sstevel@tonic-gate ohci_reg = ddi_get32(ohci_hdl->ohci_reg_handle,
18770Sstevel@tonic-gate &ohci_hdl->ohci_regs->csr_ctrl);
18780Sstevel@tonic-gate if ((ohci_reg & OHCI_CSR_DONE) != 0) {
18790Sstevel@tonic-gate /* The compare swap is done, break out of the loop */
18800Sstevel@tonic-gate break;
18810Sstevel@tonic-gate }
18820Sstevel@tonic-gate /*
18830Sstevel@tonic-gate * The compare swap has not completed yet, wait 1uS, increment
18840Sstevel@tonic-gate * the count and try again
18850Sstevel@tonic-gate */
18860Sstevel@tonic-gate drv_usecwait(1);
18870Sstevel@tonic-gate count++;
18880Sstevel@tonic-gate }
18890Sstevel@tonic-gate
18900Sstevel@tonic-gate /* If we timed out, return an error */
18910Sstevel@tonic-gate if (count >= 2) {
18920Sstevel@tonic-gate *old = 0;
18930Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
18940Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_csr_timeout_fail,
18950Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
18960Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_cswap_exit,
18970Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
18980Sstevel@tonic-gate return (DDI_FAILURE);
18990Sstevel@tonic-gate }
19000Sstevel@tonic-gate
19010Sstevel@tonic-gate /* Copy the old data into the return parameter */
19020Sstevel@tonic-gate *old = ddi_get32(ohci_hdl->ohci_reg_handle,
19030Sstevel@tonic-gate &ohci_hdl->ohci_regs->csr_data);
19040Sstevel@tonic-gate
19050Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
19060Sstevel@tonic-gate
19070Sstevel@tonic-gate /*
19080Sstevel@tonic-gate * There is a race condition in the OpenHCI design here. After checking
19090Sstevel@tonic-gate * the generation and before performing the cswap, we could get a bus
19100Sstevel@tonic-gate * reset and incorrectly set something like the bus manager. This would
19110Sstevel@tonic-gate * put us into a condition where we would not have a bus manager and
19120Sstevel@tonic-gate * we would think there was one. If it is possible that this race
19130Sstevel@tonic-gate * condition occured, we will reset the bus to clean things up. We only
19140Sstevel@tonic-gate * care about this if the compare swap was successful.
19150Sstevel@tonic-gate */
19160Sstevel@tonic-gate if (generation != hci1394_ohci_current_busgen(ohci_hdl)) {
19170Sstevel@tonic-gate if (*old == compare) {
19180Sstevel@tonic-gate (void) hci1394_ohci_bus_reset(ohci_hdl);
19190Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_invbusgen_fail,
19200Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
19210Sstevel@tonic-gate "Invalid Bus Generation");
19220Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_cswap_exit,
19230Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19240Sstevel@tonic-gate return (DDI_FAILURE);
19250Sstevel@tonic-gate }
19260Sstevel@tonic-gate }
19270Sstevel@tonic-gate
19280Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_csr_cswap_exit, HCI1394_TNF_HAL_STACK,
19290Sstevel@tonic-gate "");
19300Sstevel@tonic-gate
19310Sstevel@tonic-gate return (DDI_SUCCESS);
19320Sstevel@tonic-gate }
19330Sstevel@tonic-gate
19340Sstevel@tonic-gate
19350Sstevel@tonic-gate /*
19360Sstevel@tonic-gate * hci1394_ohci_contender_enable()
19370Sstevel@tonic-gate * Set the contender bit in the PHY. This routine should only be called
19380Sstevel@tonic-gate * if our PHY is 1394A compliant. (i.e. this routine should not be called
19390Sstevel@tonic-gate * for a 1394-1995 PHY).
19400Sstevel@tonic-gate */
19410Sstevel@tonic-gate int
hci1394_ohci_contender_enable(hci1394_ohci_handle_t ohci_hdl)19420Sstevel@tonic-gate hci1394_ohci_contender_enable(hci1394_ohci_handle_t ohci_hdl)
19430Sstevel@tonic-gate {
19440Sstevel@tonic-gate int status;
19450Sstevel@tonic-gate
19460Sstevel@tonic-gate
19470Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
19480Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_contender_enable_enter,
19490Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19500Sstevel@tonic-gate
19510Sstevel@tonic-gate /*
19520Sstevel@tonic-gate * Make sure that phy is not a 1394-1995 phy. Those phy's do not have a
19530Sstevel@tonic-gate * contender bit to set.
19540Sstevel@tonic-gate */
19550Sstevel@tonic-gate if (ohci_hdl->ohci_phy == H1394_PHY_1995) {
19560Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_type_fail,
19570Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
19580Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_contender_enable_exit,
19590Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19600Sstevel@tonic-gate return (DDI_FAILURE);
19610Sstevel@tonic-gate }
19620Sstevel@tonic-gate
19630Sstevel@tonic-gate /* Set the Contender Bit */
19640Sstevel@tonic-gate status = hci1394_ohci_phy_set(ohci_hdl, 0x4, OHCI_PHY_CNTDR);
19650Sstevel@tonic-gate if (status != DDI_SUCCESS) {
19660Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_set_fail,
19670Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
19680Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_contender_enable_exit,
19690Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19700Sstevel@tonic-gate return (DDI_FAILURE);
19710Sstevel@tonic-gate }
19720Sstevel@tonic-gate
19730Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_contender_enable_exit,
19740Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19750Sstevel@tonic-gate
19760Sstevel@tonic-gate return (DDI_SUCCESS);
19770Sstevel@tonic-gate }
19780Sstevel@tonic-gate
19790Sstevel@tonic-gate
19800Sstevel@tonic-gate /*
19810Sstevel@tonic-gate * hci1394_ohci_root_holdoff_enable()
19820Sstevel@tonic-gate * Set the root holdoff bit in the PHY. Since there are race conditions when
19830Sstevel@tonic-gate * writing to PHY register 1 (which can get updated from a PHY packet off the
19840Sstevel@tonic-gate * bus), we cache this state until a "long" bus reset is issued.
19850Sstevel@tonic-gate */
19860Sstevel@tonic-gate int
hci1394_ohci_root_holdoff_enable(hci1394_ohci_handle_t ohci_hdl)19870Sstevel@tonic-gate hci1394_ohci_root_holdoff_enable(hci1394_ohci_handle_t ohci_hdl)
19880Sstevel@tonic-gate {
19890Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
19900Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_root_holdoff_enable_enter,
19910Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19920Sstevel@tonic-gate
19930Sstevel@tonic-gate ohci_hdl->ohci_set_root_holdoff = B_TRUE;
19940Sstevel@tonic-gate
19950Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_root_holdoff_enable_exit,
19960Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
19970Sstevel@tonic-gate
19980Sstevel@tonic-gate return (DDI_SUCCESS);
19990Sstevel@tonic-gate }
20000Sstevel@tonic-gate
20010Sstevel@tonic-gate
20020Sstevel@tonic-gate /*
20030Sstevel@tonic-gate * hci1394_ohci_gap_count_set()
20040Sstevel@tonic-gate * Set the gap count in the PHY. Since there are race conditions when writing
20050Sstevel@tonic-gate * to PHY register 1 (which can get updated from a PHY packet off the bus),
20060Sstevel@tonic-gate * we cache this gap count until a "long" bus reset is issued.
20070Sstevel@tonic-gate */
20080Sstevel@tonic-gate int
hci1394_ohci_gap_count_set(hci1394_ohci_handle_t ohci_hdl,uint_t gap_count)20090Sstevel@tonic-gate hci1394_ohci_gap_count_set(hci1394_ohci_handle_t ohci_hdl, uint_t gap_count)
20100Sstevel@tonic-gate {
20110Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
20120Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_gap_count_set_enter,
20130Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20140Sstevel@tonic-gate
20150Sstevel@tonic-gate ohci_hdl->ohci_set_gap_count = B_TRUE;
20160Sstevel@tonic-gate ohci_hdl->ohci_gap_count = gap_count & OHCI_PHY_MAX_GAP;
20170Sstevel@tonic-gate
20180Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_gap_count_set_exit,
20190Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20200Sstevel@tonic-gate
20210Sstevel@tonic-gate return (DDI_SUCCESS);
20220Sstevel@tonic-gate }
20230Sstevel@tonic-gate
20240Sstevel@tonic-gate
20250Sstevel@tonic-gate /*
20260Sstevel@tonic-gate * hci1394_ohci_phy_filter_set()
20270Sstevel@tonic-gate * Enable a node (or nodes) to perform transactions to our physical
20280Sstevel@tonic-gate * memory. OpenHCI allows you to disable/enable physical requests on a node
20290Sstevel@tonic-gate * per node basis. A physical request is basically a read/write to 1394
20300Sstevel@tonic-gate * address space 0x0 - 0xFFFFFFFF. This address goes out to the IO MMU (in
20310Sstevel@tonic-gate * the case of a SPARC machine). The HAL starts with all nodes unable to
20320Sstevel@tonic-gate * read/write physical memory. The Services Layer will call down and enable
20330Sstevel@tonic-gate * nodes via setting a physical filter bit for that given node. Since node
20340Sstevel@tonic-gate * numbers change every bus reset, the services layer has to call down after
20350Sstevel@tonic-gate * every bus reset to re-enable physical accesses. (NOTE: the hardware
20360Sstevel@tonic-gate * automatically clears these bits.
20370Sstevel@tonic-gate */
20380Sstevel@tonic-gate int
hci1394_ohci_phy_filter_set(hci1394_ohci_handle_t ohci_hdl,uint64_t mask,uint_t generation)20390Sstevel@tonic-gate hci1394_ohci_phy_filter_set(hci1394_ohci_handle_t ohci_hdl, uint64_t mask,
20400Sstevel@tonic-gate uint_t generation)
20410Sstevel@tonic-gate {
20420Sstevel@tonic-gate uint32_t data;
20430Sstevel@tonic-gate
20440Sstevel@tonic-gate
20450Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
20460Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_set_enter,
20470Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20480Sstevel@tonic-gate
20490Sstevel@tonic-gate /*
20500Sstevel@tonic-gate * Make sure we have not gotten a bus reset since this action was
20510Sstevel@tonic-gate * started.
20520Sstevel@tonic-gate */
20530Sstevel@tonic-gate if (generation != hci1394_ohci_current_busgen(ohci_hdl)) {
20540Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_invbusgen_fail, HCI1394_TNF_HAL_ERROR,
20550Sstevel@tonic-gate "", tnf_string, errmsg, "Invalid Bus Generation");
20560Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_set_exit,
20570Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20580Sstevel@tonic-gate return (DDI_FAILURE);
20590Sstevel@tonic-gate }
20600Sstevel@tonic-gate
20610Sstevel@tonic-gate data = (uint32_t)((mask >> 32) & 0xFFFFFFFF);
20620Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
20630Sstevel@tonic-gate &ohci_hdl->ohci_regs->phys_req_filterhi_set, data);
20640Sstevel@tonic-gate data = (uint32_t)(mask & 0xFFFFFFFF);
20650Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
20660Sstevel@tonic-gate &ohci_hdl->ohci_regs->phys_req_filterlo_set, data);
20670Sstevel@tonic-gate
20680Sstevel@tonic-gate /*
20690Sstevel@tonic-gate * There is a race condition in the OpenHCI design here. After checking
20700Sstevel@tonic-gate * the generation and before setting the physical filter bits, we could
20710Sstevel@tonic-gate * get a bus reset and incorrectly set the physical filter bits. If it
20720Sstevel@tonic-gate * is possible that this race condition occured, we will reset the bus
20730Sstevel@tonic-gate * to clean things up.
20740Sstevel@tonic-gate */
20750Sstevel@tonic-gate if (generation != hci1394_ohci_current_busgen(ohci_hdl)) {
20760Sstevel@tonic-gate (void) hci1394_ohci_bus_reset(ohci_hdl);
20770Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_filterrace_fail, HCI1394_TNF_HAL_ERROR,
20780Sstevel@tonic-gate "", tnf_string, errmsg, "Invalid Bus Generation");
20790Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_set_exit,
20800Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20810Sstevel@tonic-gate return (DDI_SUCCESS);
20820Sstevel@tonic-gate }
20830Sstevel@tonic-gate
20840Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_set_exit,
20850Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
20860Sstevel@tonic-gate
20870Sstevel@tonic-gate return (DDI_SUCCESS);
20880Sstevel@tonic-gate }
20890Sstevel@tonic-gate
20900Sstevel@tonic-gate
20910Sstevel@tonic-gate /*
20920Sstevel@tonic-gate * hci1394_ohci_phy_filter_clr()
20930Sstevel@tonic-gate * Disable a node (or nodes) from performing transactions to our physical
20940Sstevel@tonic-gate * memory. See hci1394_ohci_phy_filter_set() above for more info.
20950Sstevel@tonic-gate */
20960Sstevel@tonic-gate int
hci1394_ohci_phy_filter_clr(hci1394_ohci_handle_t ohci_hdl,uint64_t mask,uint_t generation)20970Sstevel@tonic-gate hci1394_ohci_phy_filter_clr(hci1394_ohci_handle_t ohci_hdl,
20980Sstevel@tonic-gate uint64_t mask, uint_t generation)
20990Sstevel@tonic-gate {
21000Sstevel@tonic-gate uint32_t data;
21010Sstevel@tonic-gate
21020Sstevel@tonic-gate
21030Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
21040Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_clr_enter,
21050Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21060Sstevel@tonic-gate
21070Sstevel@tonic-gate /*
21080Sstevel@tonic-gate * Make sure we have not gotten a bus reset since this action was
21090Sstevel@tonic-gate * started.
21100Sstevel@tonic-gate */
21110Sstevel@tonic-gate if (generation != hci1394_ohci_current_busgen(ohci_hdl)) {
21120Sstevel@tonic-gate TNF_PROBE_1(hci1394_ohci_invbusgen_fail, HCI1394_TNF_HAL_ERROR,
21130Sstevel@tonic-gate "", tnf_string, errmsg, "Invalid Bus Generation");
21140Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_clr_exit,
21150Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21160Sstevel@tonic-gate return (DDI_FAILURE);
21170Sstevel@tonic-gate }
21180Sstevel@tonic-gate
21190Sstevel@tonic-gate data = (uint32_t)((mask >> 32) & 0xFFFFFFFF);
21200Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
21210Sstevel@tonic-gate &ohci_hdl->ohci_regs->phys_req_filterhi_clr, data);
21220Sstevel@tonic-gate data = (uint32_t)(mask & 0xFFFFFFFF);
21230Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
21240Sstevel@tonic-gate &ohci_hdl->ohci_regs->phys_req_filterlo_clr, data);
21250Sstevel@tonic-gate
21260Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_phy_filter_clr_exit,
21270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21280Sstevel@tonic-gate
21290Sstevel@tonic-gate return (DDI_SUCCESS);
21300Sstevel@tonic-gate }
21310Sstevel@tonic-gate
21320Sstevel@tonic-gate
21330Sstevel@tonic-gate /*
21340Sstevel@tonic-gate * hci1394_ohci_bus_reset_short()
21350Sstevel@tonic-gate * Perform a 1394A short bus reset. This function should only be called
21360Sstevel@tonic-gate * on an adapter with a 1394A PHY (or later).
21370Sstevel@tonic-gate */
21380Sstevel@tonic-gate int
hci1394_ohci_bus_reset_short(hci1394_ohci_handle_t ohci_hdl)21390Sstevel@tonic-gate hci1394_ohci_bus_reset_short(hci1394_ohci_handle_t ohci_hdl)
21400Sstevel@tonic-gate {
21410Sstevel@tonic-gate int status;
21420Sstevel@tonic-gate
21430Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
21440Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_short_enter,
21450Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21460Sstevel@tonic-gate
21470Sstevel@tonic-gate /*
21480Sstevel@tonic-gate * Make sure that phy is not a 1394-1995 phy. Those phy's do not have a
21490Sstevel@tonic-gate * contender bit to set.
21500Sstevel@tonic-gate */
21510Sstevel@tonic-gate if (ohci_hdl->ohci_phy == H1394_PHY_1995) {
21520Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_brs_phy_fail,
21530Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
21540Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_short_exit,
21550Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21560Sstevel@tonic-gate return (DDI_FAILURE);
21570Sstevel@tonic-gate }
21580Sstevel@tonic-gate
21590Sstevel@tonic-gate /* Initiate the short bus reset */
21600Sstevel@tonic-gate status = hci1394_ohci_phy_set(ohci_hdl, 0x5, OHCI_PHY_ISBR);
21610Sstevel@tonic-gate if (status != DDI_SUCCESS) {
21620Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_set_fail,
21630Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
21640Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_short_exit,
21650Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21660Sstevel@tonic-gate return (DDI_FAILURE);
21670Sstevel@tonic-gate }
21680Sstevel@tonic-gate
21690Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_reset_short_exit,
21700Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21710Sstevel@tonic-gate
21720Sstevel@tonic-gate return (status);
21730Sstevel@tonic-gate }
21740Sstevel@tonic-gate
21750Sstevel@tonic-gate
21760Sstevel@tonic-gate /*
21770Sstevel@tonic-gate * hci1394_ohci_cfgrom_update()
21780Sstevel@tonic-gate * Update the config rom with the provided contents. The config rom is
21790Sstevel@tonic-gate * provided as a byte stream which is multiple of 4 bytes large. The
21800Sstevel@tonic-gate * size is passed as a quadlet (4 bytes) count. The entire contents
21810Sstevel@tonic-gate * of the config rom is updated at once. We do not provide a partial
21820Sstevel@tonic-gate * update interface.
21830Sstevel@tonic-gate */
21840Sstevel@tonic-gate void
hci1394_ohci_cfgrom_update(hci1394_ohci_handle_t ohci_hdl,void * local_buf,uint_t quadlet_count)21850Sstevel@tonic-gate hci1394_ohci_cfgrom_update(hci1394_ohci_handle_t ohci_hdl, void *local_buf,
21860Sstevel@tonic-gate uint_t quadlet_count)
21870Sstevel@tonic-gate {
21880Sstevel@tonic-gate uint32_t *data;
21890Sstevel@tonic-gate
21900Sstevel@tonic-gate
21910Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
21920Sstevel@tonic-gate ASSERT(local_buf != NULL);
21930Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cfgrom_update_enter,
21940Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
21950Sstevel@tonic-gate
21960Sstevel@tonic-gate data = (uint32_t *)local_buf;
21970Sstevel@tonic-gate
21980Sstevel@tonic-gate /* zero out the config ROM header to start */
21990Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
22000Sstevel@tonic-gate &ohci_hdl->ohci_regs->config_rom_hdr, 0);
22010Sstevel@tonic-gate
22020Sstevel@tonic-gate /* copy Services Layer buffer into config rom buffer */
22030Sstevel@tonic-gate ddi_rep_put8(ohci_hdl->ohci_cfgrom.bi_handle, local_buf,
22040Sstevel@tonic-gate (uint8_t *)ohci_hdl->ohci_cfgrom.bi_kaddr, quadlet_count << 2,
22050Sstevel@tonic-gate DDI_DEV_AUTOINCR);
22060Sstevel@tonic-gate
22070Sstevel@tonic-gate (void) ddi_dma_sync(ohci_hdl->ohci_cfgrom.bi_dma_handle, 0,
22080Sstevel@tonic-gate quadlet_count << 2, DDI_DMA_SYNC_FORDEV);
22090Sstevel@tonic-gate
22100Sstevel@tonic-gate /*
22110Sstevel@tonic-gate * setup OHCI bus options and config rom hdr registers. We need to swap
22120Sstevel@tonic-gate * the config rom header and bus options on an X86 machine since the
22130Sstevel@tonic-gate * data is provided to us as a byte stream and the OHCI registers expect
22140Sstevel@tonic-gate * a big endian 32-bit number.
22150Sstevel@tonic-gate */
22160Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
22170Sstevel@tonic-gate &ohci_hdl->ohci_regs->bus_options, OHCI_SWAP32(data[2]));
22180Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
22190Sstevel@tonic-gate &ohci_hdl->ohci_regs->config_rom_hdr, OHCI_SWAP32(data[0]));
22200Sstevel@tonic-gate
22210Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cfgrom_update_exit,
22220Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
22230Sstevel@tonic-gate }
22240Sstevel@tonic-gate
22250Sstevel@tonic-gate
22260Sstevel@tonic-gate /*
22270Sstevel@tonic-gate * hci1394_ohci_nodeid_get()
22280Sstevel@tonic-gate * Return our current nodeid (bus #/Node #)
22290Sstevel@tonic-gate */
22300Sstevel@tonic-gate void
hci1394_ohci_nodeid_get(hci1394_ohci_handle_t ohci_hdl,uint_t * nodeid)22310Sstevel@tonic-gate hci1394_ohci_nodeid_get(hci1394_ohci_handle_t ohci_hdl, uint_t *nodeid)
22320Sstevel@tonic-gate {
22330Sstevel@tonic-gate uint32_t reg;
22340Sstevel@tonic-gate
22350Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
22360Sstevel@tonic-gate ASSERT(nodeid != NULL);
22370Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_get_enter, HCI1394_TNF_HAL_STACK,
22380Sstevel@tonic-gate "");
22390Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
22400Sstevel@tonic-gate &ohci_hdl->ohci_regs->node_id);
22410Sstevel@tonic-gate *nodeid = (reg & 0xFFFF) << 16;
22420Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_get_exit, HCI1394_TNF_HAL_STACK,
22430Sstevel@tonic-gate "");
22440Sstevel@tonic-gate }
22450Sstevel@tonic-gate
22460Sstevel@tonic-gate
22470Sstevel@tonic-gate /*
22480Sstevel@tonic-gate * hci1394_ohci_nodeid_set()
22490Sstevel@tonic-gate * Set our current nodeid (bus #/Node #). This actually sets our bus number.
22500Sstevel@tonic-gate * Our node number cannot be set by software. This is usually trigered via
22510Sstevel@tonic-gate * a write to the CSR NODEIDS register.
22520Sstevel@tonic-gate */
22530Sstevel@tonic-gate void
hci1394_ohci_nodeid_set(hci1394_ohci_handle_t ohci_hdl,uint_t nodeid)22540Sstevel@tonic-gate hci1394_ohci_nodeid_set(hci1394_ohci_handle_t ohci_hdl, uint_t nodeid)
22550Sstevel@tonic-gate {
22560Sstevel@tonic-gate uint32_t reg;
22570Sstevel@tonic-gate
22580Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
22590Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_set_enter,
22600Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
22610Sstevel@tonic-gate
22620Sstevel@tonic-gate reg = ((nodeid & 0xFFC00000) >> 16);
22630Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
22640Sstevel@tonic-gate &ohci_hdl->ohci_regs->node_id, reg);
22650Sstevel@tonic-gate
22660Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_set_exit,
22670Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
22680Sstevel@tonic-gate }
22690Sstevel@tonic-gate
22700Sstevel@tonic-gate
22710Sstevel@tonic-gate /*
22720Sstevel@tonic-gate * hci1394_ohci_nodeid_info()
22730Sstevel@tonic-gate * Return our current nodeid (bus #/Node #). This also returns whether or
22740Sstevel@tonic-gate * not our nodeid error bit is set. This is useful in determining if the
22750Sstevel@tonic-gate * bus reset completed without errors in the selfid complete interrupt
22760Sstevel@tonic-gate * processing.
22770Sstevel@tonic-gate */
22780Sstevel@tonic-gate void
hci1394_ohci_nodeid_info(hci1394_ohci_handle_t ohci_hdl,uint_t * nodeid,boolean_t * error)22790Sstevel@tonic-gate hci1394_ohci_nodeid_info(hci1394_ohci_handle_t ohci_hdl, uint_t *nodeid,
22800Sstevel@tonic-gate boolean_t *error)
22810Sstevel@tonic-gate {
22820Sstevel@tonic-gate uint32_t reg;
22830Sstevel@tonic-gate
22840Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
22850Sstevel@tonic-gate ASSERT(nodeid != NULL);
22860Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_info_enter,
22870Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
22880Sstevel@tonic-gate
22890Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
22900Sstevel@tonic-gate &ohci_hdl->ohci_regs->node_id);
22910Sstevel@tonic-gate *nodeid = reg & 0xFFFF;
22920Sstevel@tonic-gate if ((reg & OHCI_NDID_IDVALID) == 0) {
22930Sstevel@tonic-gate *error = B_TRUE;
22940Sstevel@tonic-gate } else {
22950Sstevel@tonic-gate *error = B_FALSE;
22960Sstevel@tonic-gate }
22970Sstevel@tonic-gate
22980Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_nodeid_info_exit,
22990Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23000Sstevel@tonic-gate }
23010Sstevel@tonic-gate
23020Sstevel@tonic-gate
23030Sstevel@tonic-gate /*
23040Sstevel@tonic-gate * hci1394_ohci_cycletime_get()
23050Sstevel@tonic-gate * Return the current cycle time
23060Sstevel@tonic-gate */
23070Sstevel@tonic-gate void
hci1394_ohci_cycletime_get(hci1394_ohci_handle_t ohci_hdl,uint32_t * cycle_time)23080Sstevel@tonic-gate hci1394_ohci_cycletime_get(hci1394_ohci_handle_t ohci_hdl,
23090Sstevel@tonic-gate uint32_t *cycle_time)
23100Sstevel@tonic-gate {
23110Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
23120Sstevel@tonic-gate ASSERT(cycle_time != NULL);
23130Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycletime_get_enter,
23140Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23150Sstevel@tonic-gate *cycle_time = ddi_get32(ohci_hdl->ohci_reg_handle,
23160Sstevel@tonic-gate &ohci_hdl->ohci_regs->isoch_cycle_timer);
23170Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycletime_get_exit,
23180Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23190Sstevel@tonic-gate }
23200Sstevel@tonic-gate
23210Sstevel@tonic-gate
23220Sstevel@tonic-gate /*
23230Sstevel@tonic-gate * hci1394_ohci_cycletime_get()
23240Sstevel@tonic-gate * Set the cycle time
23250Sstevel@tonic-gate */
23260Sstevel@tonic-gate void
hci1394_ohci_cycletime_set(hci1394_ohci_handle_t ohci_hdl,uint32_t cycle_time)23270Sstevel@tonic-gate hci1394_ohci_cycletime_set(hci1394_ohci_handle_t ohci_hdl,
23280Sstevel@tonic-gate uint32_t cycle_time)
23290Sstevel@tonic-gate {
23300Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
23310Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycletime_set_enter,
23320Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23330Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
23340Sstevel@tonic-gate &ohci_hdl->ohci_regs->isoch_cycle_timer, cycle_time);
23350Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycletime_set_exit,
23360Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23370Sstevel@tonic-gate }
23380Sstevel@tonic-gate
23390Sstevel@tonic-gate
23400Sstevel@tonic-gate /*
23410Sstevel@tonic-gate * hci1394_ohci_bustime_get()
23420Sstevel@tonic-gate * Return the current bus time.
23430Sstevel@tonic-gate */
23440Sstevel@tonic-gate void
hci1394_ohci_bustime_get(hci1394_ohci_handle_t ohci_hdl,uint32_t * bus_time)23450Sstevel@tonic-gate hci1394_ohci_bustime_get(hci1394_ohci_handle_t ohci_hdl, uint32_t *bus_time)
23460Sstevel@tonic-gate {
23470Sstevel@tonic-gate uint32_t bus_time1;
23480Sstevel@tonic-gate uint32_t bus_time2;
23490Sstevel@tonic-gate uint32_t cycle_time;
23500Sstevel@tonic-gate
23510Sstevel@tonic-gate
23520Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
23530Sstevel@tonic-gate ASSERT(bus_time != NULL);
23540Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bustime_get_enter,
23550Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23560Sstevel@tonic-gate
23570Sstevel@tonic-gate /*
23580Sstevel@tonic-gate * The bus time is composed of a portion of the cycle time and the
23590Sstevel@tonic-gate * cycle time rollover count (ohci_bustime_count). There is a race
23600Sstevel@tonic-gate * condition where we read the rollover count and then the cycle
23610Sstevel@tonic-gate * timer rolls over. This is the reason for the double read of the
23620Sstevel@tonic-gate * rollover count.
23630Sstevel@tonic-gate */
23640Sstevel@tonic-gate do {
23650Sstevel@tonic-gate bus_time1 = ohci_hdl->ohci_bustime_count;
23660Sstevel@tonic-gate cycle_time = ddi_get32(ohci_hdl->ohci_reg_handle,
23670Sstevel@tonic-gate &ohci_hdl->ohci_regs->isoch_cycle_timer);
23680Sstevel@tonic-gate bus_time2 = ohci_hdl->ohci_bustime_count;
23690Sstevel@tonic-gate } while (bus_time1 != bus_time2);
23700Sstevel@tonic-gate
23710Sstevel@tonic-gate *bus_time = (bus_time2 << 7) | (cycle_time >> 25);
23720Sstevel@tonic-gate
23730Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bustime_get_exit,
23740Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23750Sstevel@tonic-gate }
23760Sstevel@tonic-gate
23770Sstevel@tonic-gate
23780Sstevel@tonic-gate /*
23790Sstevel@tonic-gate * hci1394_ohci_bustime_set()
23800Sstevel@tonic-gate * Set the cycle timer rollover portion of the bus time.
23810Sstevel@tonic-gate */
23820Sstevel@tonic-gate void
hci1394_ohci_bustime_set(hci1394_ohci_handle_t ohci_hdl,uint32_t bus_time)23830Sstevel@tonic-gate hci1394_ohci_bustime_set(hci1394_ohci_handle_t ohci_hdl, uint32_t bus_time)
23840Sstevel@tonic-gate {
23850Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
23860Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bustime_set_enter,
23870Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
23880Sstevel@tonic-gate
23890Sstevel@tonic-gate /*
23900Sstevel@tonic-gate * we will start with the cycle 64 seconds interrupt disabled. If this
23910Sstevel@tonic-gate * is the first write to bus time, enable the interrupt.
23920Sstevel@tonic-gate */
23930Sstevel@tonic-gate if (ohci_hdl->ohci_bustime_enabled == B_FALSE) {
23940Sstevel@tonic-gate ohci_hdl->ohci_bustime_enabled = B_TRUE;
23950Sstevel@tonic-gate /* Clear the cycle64Seconds interrupt then enable it */
23960Sstevel@tonic-gate hci1394_ohci_intr_clear(ohci_hdl, OHCI_INTR_CYC_64_SECS);
23970Sstevel@tonic-gate hci1394_ohci_intr_enable(ohci_hdl, OHCI_INTR_CYC_64_SECS);
23980Sstevel@tonic-gate }
23990Sstevel@tonic-gate ohci_hdl->ohci_bustime_count = (bus_time >> 7);
24000Sstevel@tonic-gate
24010Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bustime_set_exit,
24020Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24030Sstevel@tonic-gate }
24040Sstevel@tonic-gate
24050Sstevel@tonic-gate
24060Sstevel@tonic-gate /*
24070Sstevel@tonic-gate * hci1394_ohci_atreq_retries_get()
24080Sstevel@tonic-gate * Get the number of atreq retries we will perform.
24090Sstevel@tonic-gate */
24100Sstevel@tonic-gate void
hci1394_ohci_atreq_retries_get(hci1394_ohci_handle_t ohci_hdl,uint_t * atreq_retries)24110Sstevel@tonic-gate hci1394_ohci_atreq_retries_get(hci1394_ohci_handle_t ohci_hdl,
24120Sstevel@tonic-gate uint_t *atreq_retries)
24130Sstevel@tonic-gate {
24140Sstevel@tonic-gate uint32_t reg;
24150Sstevel@tonic-gate
24160Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
24170Sstevel@tonic-gate ASSERT(atreq_retries != NULL);
24180Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_retries_get_enter,
24190Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24200Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
24210Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_retries);
24220Sstevel@tonic-gate *atreq_retries = reg & OHCI_RET_MAX_ATREQ_MASK;
24230Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_retries_get_exit,
24240Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24250Sstevel@tonic-gate }
24260Sstevel@tonic-gate
24270Sstevel@tonic-gate
24280Sstevel@tonic-gate /*
24290Sstevel@tonic-gate * hci1394_ohci_atreq_retries_get()
24300Sstevel@tonic-gate * Set the number of atreq retries we will perform.
24310Sstevel@tonic-gate */
24320Sstevel@tonic-gate void
hci1394_ohci_atreq_retries_set(hci1394_ohci_handle_t ohci_hdl,uint_t atreq_retries)24330Sstevel@tonic-gate hci1394_ohci_atreq_retries_set(hci1394_ohci_handle_t ohci_hdl,
24340Sstevel@tonic-gate uint_t atreq_retries)
24350Sstevel@tonic-gate {
24360Sstevel@tonic-gate uint32_t reg;
24370Sstevel@tonic-gate
24380Sstevel@tonic-gate
24390Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
24400Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_retries_set_enter,
24410Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24420Sstevel@tonic-gate
24430Sstevel@tonic-gate mutex_enter(&ohci_hdl->ohci_mutex);
24440Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
24450Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_retries);
24460Sstevel@tonic-gate reg = reg & ~OHCI_RET_MAX_ATREQ_MASK;
24470Sstevel@tonic-gate reg = reg | (atreq_retries & OHCI_RET_MAX_ATREQ_MASK);
24480Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
24490Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_retries, reg);
24500Sstevel@tonic-gate mutex_exit(&ohci_hdl->ohci_mutex);
24510Sstevel@tonic-gate
24520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_retries_set_exit,
24530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24540Sstevel@tonic-gate }
24550Sstevel@tonic-gate
24560Sstevel@tonic-gate
24570Sstevel@tonic-gate /*
24580Sstevel@tonic-gate * hci1394_ohci_isr_cycle64seconds()
24590Sstevel@tonic-gate * Interrupt handler for the cycle64seconds interrupt.
24600Sstevel@tonic-gate */
24610Sstevel@tonic-gate void
hci1394_ohci_isr_cycle64seconds(hci1394_ohci_handle_t ohci_hdl)24620Sstevel@tonic-gate hci1394_ohci_isr_cycle64seconds(hci1394_ohci_handle_t ohci_hdl)
24630Sstevel@tonic-gate {
24640Sstevel@tonic-gate uint32_t cycle_time;
24650Sstevel@tonic-gate
24660Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
24670Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_cycle64seconds_enter,
24680Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24690Sstevel@tonic-gate
24700Sstevel@tonic-gate hci1394_ohci_intr_clear(ohci_hdl, OHCI_INTR_CYC_64_SECS);
24710Sstevel@tonic-gate cycle_time = ddi_get32(ohci_hdl->ohci_reg_handle,
24720Sstevel@tonic-gate &ohci_hdl->ohci_regs->isoch_cycle_timer);
24730Sstevel@tonic-gate
24740Sstevel@tonic-gate /*
24750Sstevel@tonic-gate * cycle64second interrupts when the MSBit in the cycle timer changes
24760Sstevel@tonic-gate * state. We only care about rollover so we will increment only when
24770Sstevel@tonic-gate * the MSBit is set to 0.
24780Sstevel@tonic-gate */
24790Sstevel@tonic-gate if ((cycle_time & 0x80000000) == 0) {
24800Sstevel@tonic-gate ohci_hdl->ohci_bustime_count++;
24810Sstevel@tonic-gate }
24820Sstevel@tonic-gate
24830Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_cycle64seconds_exit,
24840Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
24850Sstevel@tonic-gate }
24860Sstevel@tonic-gate
24870Sstevel@tonic-gate
24880Sstevel@tonic-gate /*
24890Sstevel@tonic-gate * hci1394_ohci_isr_phy()
24900Sstevel@tonic-gate * Interrupt handler for a PHY event
24910Sstevel@tonic-gate */
24920Sstevel@tonic-gate void
hci1394_ohci_isr_phy(hci1394_ohci_handle_t ohci_hdl)24930Sstevel@tonic-gate hci1394_ohci_isr_phy(hci1394_ohci_handle_t ohci_hdl)
24940Sstevel@tonic-gate {
24950Sstevel@tonic-gate uint_t phy_status;
24960Sstevel@tonic-gate int status;
24970Sstevel@tonic-gate
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
25000Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_phy_enter,
25010Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
25020Sstevel@tonic-gate
25030Sstevel@tonic-gate /* clear the interrupt */
25040Sstevel@tonic-gate hci1394_ohci_intr_clear(ohci_hdl, OHCI_INTR_PHY);
25050Sstevel@tonic-gate
25060Sstevel@tonic-gate /* increment the statistics count */
25070Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_stats.st_phy_isr++;
25080Sstevel@tonic-gate
25090Sstevel@tonic-gate /*
25100Sstevel@tonic-gate * If the PHY is a 1995 phy, just return since there are no status bits
25110Sstevel@tonic-gate * to read.
25120Sstevel@tonic-gate */
25130Sstevel@tonic-gate if (ohci_hdl->ohci_phy == H1394_PHY_1995) {
25140Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_isr_1995,
25150Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
25160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_phy_exit,
25170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
25180Sstevel@tonic-gate return;
25190Sstevel@tonic-gate }
25200Sstevel@tonic-gate
25210Sstevel@tonic-gate /* See why we got this interrupt */
25220Sstevel@tonic-gate status = hci1394_ohci_phy_read(ohci_hdl, 5, &phy_status);
25230Sstevel@tonic-gate if (status != DDI_SUCCESS) {
25240Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_read_failed,
25250Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
25260Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_phy_exit,
25270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
25280Sstevel@tonic-gate return;
25290Sstevel@tonic-gate }
25300Sstevel@tonic-gate
25310Sstevel@tonic-gate if (phy_status & OHCI_PHY_LOOP_ERR) {
25320Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_stats.st_phy_loop_err++;
25330Sstevel@tonic-gate cmn_err(CE_NOTE, "hci1394(%d): ERROR - bus loop detected",
25340Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_instance);
25350Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_isr_loop, HCI1394_TNF_HAL, "");
25360Sstevel@tonic-gate }
25370Sstevel@tonic-gate if (phy_status & OHCI_PHY_PWRFAIL_ERR) {
25380Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_stats.st_phy_pwrfail_err++;
25390Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_isr_pwr, HCI1394_TNF_HAL, "");
25400Sstevel@tonic-gate }
25410Sstevel@tonic-gate if (phy_status & OHCI_PHY_TIMEOUT_ERR) {
25420Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_stats.st_phy_timeout_err++;
25430Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_isr_tmout, HCI1394_TNF_HAL, "");
25440Sstevel@tonic-gate }
25450Sstevel@tonic-gate if (phy_status & OHCI_PHY_PORTEVT_ERR) {
25460Sstevel@tonic-gate ohci_hdl->ohci_drvinfo->di_stats.st_phy_portevt_err++;
25470Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_isr_pevt, HCI1394_TNF_HAL, "");
25480Sstevel@tonic-gate }
25490Sstevel@tonic-gate
25500Sstevel@tonic-gate /* clear any set status bits */
25510Sstevel@tonic-gate status = hci1394_ohci_phy_write(ohci_hdl, 5, phy_status);
25520Sstevel@tonic-gate if (status != DDI_SUCCESS) {
25530Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_write_failed,
25540Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
25550Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_phy_exit,
25560Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
25570Sstevel@tonic-gate return;
25580Sstevel@tonic-gate }
25590Sstevel@tonic-gate
25600Sstevel@tonic-gate /*
25610Sstevel@tonic-gate * Disable the PHY interrupt. We are getting stuck in this ISR in
25620Sstevel@tonic-gate * certain PHY implementations so we will disable the interrupt until
25630Sstevel@tonic-gate * we see a selfid complete.
25640Sstevel@tonic-gate */
25650Sstevel@tonic-gate hci1394_ohci_intr_disable(ohci_hdl, OHCI_INTR_PHY);
25660Sstevel@tonic-gate
25670Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_isr_phy_exit,
25680Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
25690Sstevel@tonic-gate }
25700Sstevel@tonic-gate
25710Sstevel@tonic-gate
25720Sstevel@tonic-gate /*
25730Sstevel@tonic-gate * hci1394_ohci_root_check
25740Sstevel@tonic-gate * Returns status about if we are currently the root node on the 1394 bus.
25750Sstevel@tonic-gate * returns B_TRUE if we are the root, B_FALSE if we are not the root.
25760Sstevel@tonic-gate */
25770Sstevel@tonic-gate boolean_t
hci1394_ohci_root_check(hci1394_ohci_handle_t ohci_hdl)25780Sstevel@tonic-gate hci1394_ohci_root_check(hci1394_ohci_handle_t ohci_hdl)
25790Sstevel@tonic-gate {
25800Sstevel@tonic-gate uint32_t reg;
25810Sstevel@tonic-gate int status;
25820Sstevel@tonic-gate
25830Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
25840Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_root_check_enter, HCI1394_TNF_HAL_STACK,
25850Sstevel@tonic-gate "");
25860Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
25870Sstevel@tonic-gate &ohci_hdl->ohci_regs->node_id);
25880Sstevel@tonic-gate if ((reg & OHCI_REG_NODEID_ROOT) && (reg & OHCI_NDID_IDVALID)) {
25890Sstevel@tonic-gate status = B_TRUE;
25900Sstevel@tonic-gate } else {
25910Sstevel@tonic-gate status = B_FALSE;
25920Sstevel@tonic-gate }
25930Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_root_check_exit, HCI1394_TNF_HAL_STACK,
25940Sstevel@tonic-gate "");
25950Sstevel@tonic-gate
25960Sstevel@tonic-gate return (status);
25970Sstevel@tonic-gate }
25980Sstevel@tonic-gate
25990Sstevel@tonic-gate
26000Sstevel@tonic-gate /*
26010Sstevel@tonic-gate * hci1394_ohci_cmc_check()
26020Sstevel@tonic-gate * Returns status about if we are cycle master capable. Returns
26030Sstevel@tonic-gate * B_TRUE if we are the cycle master capable, B_FALSE if we are not the cycle
26040Sstevel@tonic-gate * master capable.
26050Sstevel@tonic-gate */
26060Sstevel@tonic-gate boolean_t
hci1394_ohci_cmc_check(hci1394_ohci_handle_t ohci_hdl)26070Sstevel@tonic-gate hci1394_ohci_cmc_check(hci1394_ohci_handle_t ohci_hdl)
26080Sstevel@tonic-gate {
26090Sstevel@tonic-gate uint32_t reg;
26100Sstevel@tonic-gate int status;
26110Sstevel@tonic-gate
26120Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
26130Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cmc_check_enter, HCI1394_TNF_HAL_STACK,
26140Sstevel@tonic-gate "");
26150Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
26160Sstevel@tonic-gate &ohci_hdl->ohci_regs->bus_options);
26170Sstevel@tonic-gate if (reg & OHCI_REG_BUSOPTIONS_CMC) {
26180Sstevel@tonic-gate status = B_TRUE;
26190Sstevel@tonic-gate } else {
26200Sstevel@tonic-gate status = B_FALSE;
26210Sstevel@tonic-gate }
26220Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cmc_check_exit, HCI1394_TNF_HAL_STACK,
26230Sstevel@tonic-gate "");
26240Sstevel@tonic-gate
26250Sstevel@tonic-gate return (status);
26260Sstevel@tonic-gate }
26270Sstevel@tonic-gate
26280Sstevel@tonic-gate
26290Sstevel@tonic-gate /*
26300Sstevel@tonic-gate * hci1394_ohci_cycle_master_enable()
26310Sstevel@tonic-gate * Enables us to be cycle master. If we are root, we will start generating
26320Sstevel@tonic-gate * cycle start packets.
26330Sstevel@tonic-gate */
26340Sstevel@tonic-gate void
hci1394_ohci_cycle_master_enable(hci1394_ohci_handle_t ohci_hdl)26350Sstevel@tonic-gate hci1394_ohci_cycle_master_enable(hci1394_ohci_handle_t ohci_hdl)
26360Sstevel@tonic-gate {
26370Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
26380Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycle_master_enable_enter,
26390Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26400Sstevel@tonic-gate
26410Sstevel@tonic-gate /* First make sure that cycleTooLong is clear */
26420Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
26430Sstevel@tonic-gate &ohci_hdl->ohci_regs->intr_event_clr, OHCI_INTR_CYC_TOO_LONG);
26440Sstevel@tonic-gate
26450Sstevel@tonic-gate /* Enable Cycle Master */
26460Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
26470Sstevel@tonic-gate &ohci_hdl->ohci_regs->link_ctrl_set, OHCI_LC_CYC_MAST);
26480Sstevel@tonic-gate
26490Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycle_master_enable_exit,
26500Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26510Sstevel@tonic-gate }
26520Sstevel@tonic-gate
26530Sstevel@tonic-gate
26540Sstevel@tonic-gate /*
26550Sstevel@tonic-gate * hci1394_ohci_cycle_master_disable()
26560Sstevel@tonic-gate * Disabled us from being cycle master. If we are root, we will stop
26570Sstevel@tonic-gate * generating cycle start packets.
26580Sstevel@tonic-gate */
26590Sstevel@tonic-gate void
hci1394_ohci_cycle_master_disable(hci1394_ohci_handle_t ohci_hdl)26600Sstevel@tonic-gate hci1394_ohci_cycle_master_disable(hci1394_ohci_handle_t ohci_hdl)
26610Sstevel@tonic-gate {
26620Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
26630Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycle_master_disable_enter,
26640Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26650Sstevel@tonic-gate
26660Sstevel@tonic-gate /* disable cycle master */
26670Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
26680Sstevel@tonic-gate &ohci_hdl->ohci_regs->link_ctrl_clr, OHCI_LC_CYC_MAST);
26690Sstevel@tonic-gate
26700Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cycle_master_disable_exit,
26710Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26720Sstevel@tonic-gate }
26730Sstevel@tonic-gate
26740Sstevel@tonic-gate
26750Sstevel@tonic-gate /*
26760Sstevel@tonic-gate * hci1394_ohci_resume()
26770Sstevel@tonic-gate * Re-initialize the openHCI HW during a resume. (after a power suspend)
26780Sstevel@tonic-gate */
26790Sstevel@tonic-gate int
hci1394_ohci_resume(hci1394_ohci_handle_t ohci_hdl)26800Sstevel@tonic-gate hci1394_ohci_resume(hci1394_ohci_handle_t ohci_hdl)
26810Sstevel@tonic-gate {
26820Sstevel@tonic-gate uint32_t quadlet;
26830Sstevel@tonic-gate int status;
26840Sstevel@tonic-gate
26850Sstevel@tonic-gate
26860Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
26870Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_resume_enter,
26880Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26890Sstevel@tonic-gate
26900Sstevel@tonic-gate /* Re-initialize the OpenHCI chip */
26910Sstevel@tonic-gate status = hci1394_ohci_chip_init(ohci_hdl);
26920Sstevel@tonic-gate if (status != DDI_SUCCESS) {
26930Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_chip_init_fail, HCI1394_TNF_HAL_ERROR,
26940Sstevel@tonic-gate "");
26950Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_resume_exit,
26960Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
26970Sstevel@tonic-gate return (DDI_FAILURE);
26980Sstevel@tonic-gate }
26990Sstevel@tonic-gate
27000Sstevel@tonic-gate /* Re-initialize the PHY */
27010Sstevel@tonic-gate status = hci1394_ohci_phy_resume(ohci_hdl);
27020Sstevel@tonic-gate if (status != DDI_SUCCESS) {
27030Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_phy_resume_fail,
27040Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
27050Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_resume_exit,
27060Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
27070Sstevel@tonic-gate return (DDI_FAILURE);
27080Sstevel@tonic-gate }
27090Sstevel@tonic-gate
27100Sstevel@tonic-gate /* Re-initialize any 1394A features we are using */
27110Sstevel@tonic-gate status = hci1394_ohci_1394a_resume(ohci_hdl);
27120Sstevel@tonic-gate if (status != DDI_SUCCESS) {
27130Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_1394a_resume_fail,
27140Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
27150Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_resume_exit,
27160Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
27170Sstevel@tonic-gate return (DDI_FAILURE);
27180Sstevel@tonic-gate }
27190Sstevel@tonic-gate
27200Sstevel@tonic-gate /* Tell OpenHCI where the Config ROM buffer is */
27210Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
27220Sstevel@tonic-gate &ohci_hdl->ohci_regs->config_rom_maplo,
27230Sstevel@tonic-gate (uint32_t)ohci_hdl->ohci_cfgrom.bi_cookie.dmac_address);
27240Sstevel@tonic-gate
27250Sstevel@tonic-gate /* Tell OpenHCI where the SelfId buffer is */
27260Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
27270Sstevel@tonic-gate &ohci_hdl->ohci_regs->self_id_buflo,
27280Sstevel@tonic-gate (uint32_t)ohci_hdl->ohci_selfid.bi_cookie.dmac_address);
27290Sstevel@tonic-gate
27300Sstevel@tonic-gate /* Enable selfid DMA engine */
27310Sstevel@tonic-gate hci1394_ohci_selfid_enable(ohci_hdl);
27320Sstevel@tonic-gate
27330Sstevel@tonic-gate /*
27340Sstevel@tonic-gate * re-setup OHCI bus options and config rom hdr registers. We need to
27350Sstevel@tonic-gate * read from the config rom using ddi_rep_get8 since it is stored as
27360Sstevel@tonic-gate * a byte stream. We need to swap he config rom header and bus options
27370Sstevel@tonic-gate * on an X86 machine since the data is a byte stream and the OHCI
27380Sstevel@tonic-gate * registers expect a big endian 32-bit number.
27390Sstevel@tonic-gate */
27400Sstevel@tonic-gate ddi_rep_get8(ohci_hdl->ohci_cfgrom.bi_handle, (uint8_t *)&quadlet,
27410Sstevel@tonic-gate &((uint8_t *)ohci_hdl->ohci_cfgrom.bi_kaddr)[8], 4,
27420Sstevel@tonic-gate DDI_DEV_AUTOINCR);
27430Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
27440Sstevel@tonic-gate &ohci_hdl->ohci_regs->bus_options, OHCI_SWAP32(quadlet));
27450Sstevel@tonic-gate ddi_rep_get8(ohci_hdl->ohci_cfgrom.bi_handle, (uint8_t *)&quadlet,
27460Sstevel@tonic-gate &((uint8_t *)ohci_hdl->ohci_cfgrom.bi_kaddr)[0], 4,
27470Sstevel@tonic-gate DDI_DEV_AUTOINCR);
27480Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
27490Sstevel@tonic-gate &ohci_hdl->ohci_regs->config_rom_hdr, OHCI_SWAP32(quadlet));
27500Sstevel@tonic-gate
27510Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_resume_exit,
27520Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
27530Sstevel@tonic-gate return (DDI_SUCCESS);
27540Sstevel@tonic-gate }
27550Sstevel@tonic-gate
27560Sstevel@tonic-gate
27570Sstevel@tonic-gate /*
27580Sstevel@tonic-gate * hci1394_ohci_selfid_init()
27590Sstevel@tonic-gate * Initialize the selfid buffer
27600Sstevel@tonic-gate */
27610Sstevel@tonic-gate static int
hci1394_ohci_selfid_init(hci1394_ohci_handle_t ohci_hdl)27620Sstevel@tonic-gate hci1394_ohci_selfid_init(hci1394_ohci_handle_t ohci_hdl)
27630Sstevel@tonic-gate {
27640Sstevel@tonic-gate hci1394_buf_parms_t parms;
27650Sstevel@tonic-gate int status;
27660Sstevel@tonic-gate
27670Sstevel@tonic-gate
27680Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
27690Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_init_selfid_enter, HCI1394_TNF_HAL_STACK, "");
27700Sstevel@tonic-gate
27710Sstevel@tonic-gate /*
27720Sstevel@tonic-gate * Setup for 2K buffer, aligned on a 2Kbyte address boundary. Make sure
27730Sstevel@tonic-gate * that the buffer is not broken up into multiple cookies. OpenHCI can
27740Sstevel@tonic-gate * only handle one address for the selfid buffer location.
27750Sstevel@tonic-gate */
27760Sstevel@tonic-gate parms.bp_length = 2048;
27770Sstevel@tonic-gate parms.bp_max_cookies = 1;
27780Sstevel@tonic-gate parms.bp_alignment = 2048;
27790Sstevel@tonic-gate status = hci1394_buf_alloc(ohci_hdl->ohci_drvinfo, &parms,
27800Sstevel@tonic-gate &ohci_hdl->ohci_selfid, &ohci_hdl->ohci_selfid_handle);
27810Sstevel@tonic-gate if (status != DDI_SUCCESS) {
27820Sstevel@tonic-gate TNF_PROBE_0(hci1394_buf_alloc_fail, HCI1394_TNF_HAL_ERROR, "");
27830Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_init_selfid_exit,
27840Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
27850Sstevel@tonic-gate return (DDI_FAILURE);
27860Sstevel@tonic-gate }
27870Sstevel@tonic-gate
27880Sstevel@tonic-gate /* Tell OpenHCI where the buffer is */
27890Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
27900Sstevel@tonic-gate &ohci_hdl->ohci_regs->self_id_buflo,
27910Sstevel@tonic-gate (uint32_t)ohci_hdl->ohci_selfid.bi_cookie.dmac_address);
27920Sstevel@tonic-gate
27930Sstevel@tonic-gate /* Enable selfid DMA engine */
27940Sstevel@tonic-gate hci1394_ohci_selfid_enable(ohci_hdl);
27950Sstevel@tonic-gate
27960Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_init_selfid_exit, HCI1394_TNF_HAL_STACK, "");
27970Sstevel@tonic-gate
27980Sstevel@tonic-gate return (DDI_SUCCESS);
27990Sstevel@tonic-gate }
28000Sstevel@tonic-gate
28010Sstevel@tonic-gate
28020Sstevel@tonic-gate /*
28030Sstevel@tonic-gate * hci1394_ohci_selfid_enable()
28040Sstevel@tonic-gate * Allow selfid packets to be placed into the selfid buffer. This should be
28050Sstevel@tonic-gate * called after the selfid buffer address has been setup in the HW.
28060Sstevel@tonic-gate */
28070Sstevel@tonic-gate void
hci1394_ohci_selfid_enable(hci1394_ohci_handle_t ohci_hdl)28080Sstevel@tonic-gate hci1394_ohci_selfid_enable(hci1394_ohci_handle_t ohci_hdl)
28090Sstevel@tonic-gate {
28100Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
28110Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_enable_enter,
28120Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28130Sstevel@tonic-gate
28140Sstevel@tonic-gate /*
28150Sstevel@tonic-gate * Allow selfid packets to be received. This should be called during
28160Sstevel@tonic-gate * driver attach after the selfid buffer address has been initialized.
28170Sstevel@tonic-gate *
28180Sstevel@tonic-gate * Link Control Register
28190Sstevel@tonic-gate * rscSelfId = 1 <= bit 9
28200Sstevel@tonic-gate */
28210Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
28220Sstevel@tonic-gate &ohci_hdl->ohci_regs->link_ctrl_set, OHCI_LC_RCV_SELF);
28230Sstevel@tonic-gate
28240Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_enable_exit,
28250Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28260Sstevel@tonic-gate }
28270Sstevel@tonic-gate
28280Sstevel@tonic-gate
28290Sstevel@tonic-gate /*
28300Sstevel@tonic-gate * hci1394_ohci_selfid_read()
28310Sstevel@tonic-gate * Read a word out of the selfid buffer.
28320Sstevel@tonic-gate */
28330Sstevel@tonic-gate void
hci1394_ohci_selfid_read(hci1394_ohci_handle_t ohci_hdl,uint_t offset,uint32_t * data)28340Sstevel@tonic-gate hci1394_ohci_selfid_read(hci1394_ohci_handle_t ohci_hdl, uint_t offset,
28350Sstevel@tonic-gate uint32_t *data)
28360Sstevel@tonic-gate {
28370Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
28380Sstevel@tonic-gate ASSERT(data != NULL);
28390Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_read_enter,
28400Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28410Sstevel@tonic-gate *data = ddi_get32(ohci_hdl->ohci_selfid.bi_handle,
28420Sstevel@tonic-gate &((uint32_t *)ohci_hdl->ohci_selfid.bi_kaddr)[offset]);
28430Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_read_exit,
28440Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28450Sstevel@tonic-gate }
28460Sstevel@tonic-gate
28470Sstevel@tonic-gate
28480Sstevel@tonic-gate /*
28490Sstevel@tonic-gate * hci1394_ohci_selfid_info()
28500Sstevel@tonic-gate * Return the current bus generation, the number of bytes currently in the
28510Sstevel@tonic-gate * selfid buffer, and if we have seen any selfid errors.
28520Sstevel@tonic-gate */
28530Sstevel@tonic-gate void
hci1394_ohci_selfid_info(hci1394_ohci_handle_t ohci_hdl,uint_t * busgen,uint_t * size,boolean_t * error)28540Sstevel@tonic-gate hci1394_ohci_selfid_info(hci1394_ohci_handle_t ohci_hdl, uint_t *busgen,
28550Sstevel@tonic-gate uint_t *size, boolean_t *error)
28560Sstevel@tonic-gate {
28570Sstevel@tonic-gate uint32_t reg;
28580Sstevel@tonic-gate
28590Sstevel@tonic-gate
28600Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
28610Sstevel@tonic-gate ASSERT(busgen != NULL);
28620Sstevel@tonic-gate ASSERT(size != NULL);
28630Sstevel@tonic-gate ASSERT(error != NULL);
28640Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_info_enter,
28650Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28660Sstevel@tonic-gate
28670Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
28680Sstevel@tonic-gate &ohci_hdl->ohci_regs->self_id_count);
28690Sstevel@tonic-gate *busgen = (reg & OHCI_SLFC_GEN_MASK) >> OHCI_SLFC_GEN_SHIFT;
28700Sstevel@tonic-gate *size = reg & OHCI_SLFC_NUM_QUADS_MASK;
28710Sstevel@tonic-gate if ((reg & OHCI_SLFC_ERROR) == 0) {
28720Sstevel@tonic-gate *error = B_FALSE;
28730Sstevel@tonic-gate } else {
28740Sstevel@tonic-gate *error = B_TRUE;
28750Sstevel@tonic-gate }
28760Sstevel@tonic-gate
28770Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_info_exit,
28780Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28790Sstevel@tonic-gate }
28800Sstevel@tonic-gate
28810Sstevel@tonic-gate
28820Sstevel@tonic-gate /*
28830Sstevel@tonic-gate * hci1394_ohci_selfid_buf_current()
28840Sstevel@tonic-gate * Test if the selfid buffer is current. Return B_TRUE if it is current and
28850Sstevel@tonic-gate * B_FALSE if it is not current.
28860Sstevel@tonic-gate */
28870Sstevel@tonic-gate boolean_t
hci1394_ohci_selfid_buf_current(hci1394_ohci_handle_t ohci_hdl)28880Sstevel@tonic-gate hci1394_ohci_selfid_buf_current(hci1394_ohci_handle_t ohci_hdl)
28890Sstevel@tonic-gate {
28900Sstevel@tonic-gate uint32_t reg;
28910Sstevel@tonic-gate int status;
28920Sstevel@tonic-gate
28930Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
28940Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_buf_current_enter,
28950Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
28960Sstevel@tonic-gate
28970Sstevel@tonic-gate /*
28980Sstevel@tonic-gate * if the generation stored in the selfid buffer is not equal to the
28990Sstevel@tonic-gate * generation we have previously stored, the selfid buffer is not
29000Sstevel@tonic-gate * current. (It maybe older or it maybe newer)
29010Sstevel@tonic-gate */
29020Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_selfid.bi_handle,
29030Sstevel@tonic-gate &((uint32_t *)ohci_hdl->ohci_selfid.bi_kaddr)[0]);
29040Sstevel@tonic-gate if (ohci_hdl->ohci_drvinfo->di_gencnt != ((reg & OHCI_SLFC_GEN_MASK) >>
29050Sstevel@tonic-gate OHCI_SLFC_GEN_SHIFT)) {
29060Sstevel@tonic-gate status = B_FALSE;
29070Sstevel@tonic-gate } else {
29080Sstevel@tonic-gate status = B_TRUE;
29090Sstevel@tonic-gate }
29100Sstevel@tonic-gate
29110Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_buf_current_exit,
29120Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
29130Sstevel@tonic-gate
29140Sstevel@tonic-gate return (status);
29150Sstevel@tonic-gate }
29160Sstevel@tonic-gate
29170Sstevel@tonic-gate
29180Sstevel@tonic-gate /*
29190Sstevel@tonic-gate * hci1394_ohci_selfid_sync()
29200Sstevel@tonic-gate * Perform a ddi_dma_sync on the selfid buffer
29210Sstevel@tonic-gate */
29220Sstevel@tonic-gate void
hci1394_ohci_selfid_sync(hci1394_ohci_handle_t ohci_hdl)29230Sstevel@tonic-gate hci1394_ohci_selfid_sync(hci1394_ohci_handle_t ohci_hdl)
29240Sstevel@tonic-gate {
29250Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
29260Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_sync_enter,
29270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
29280Sstevel@tonic-gate (void) ddi_dma_sync(ohci_hdl->ohci_selfid.bi_dma_handle, 0,
29290Sstevel@tonic-gate ohci_hdl->ohci_selfid.bi_length, DDI_DMA_SYNC_FORKERNEL);
29300Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_selfid_sync_exit, HCI1394_TNF_HAL_STACK,
29310Sstevel@tonic-gate "");
29320Sstevel@tonic-gate }
29330Sstevel@tonic-gate
29340Sstevel@tonic-gate
29350Sstevel@tonic-gate /*
29360Sstevel@tonic-gate * hci1394_ohci_cfgrom_init()
29370Sstevel@tonic-gate * Initialize the configuration ROM buffer
29380Sstevel@tonic-gate */
29390Sstevel@tonic-gate static int
hci1394_ohci_cfgrom_init(hci1394_ohci_handle_t ohci_hdl)29400Sstevel@tonic-gate hci1394_ohci_cfgrom_init(hci1394_ohci_handle_t ohci_hdl)
29410Sstevel@tonic-gate {
29420Sstevel@tonic-gate hci1394_buf_parms_t parms;
29430Sstevel@tonic-gate int status;
29440Sstevel@tonic-gate
29450Sstevel@tonic-gate
29460Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
29470Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cfgrom_init_enter,
29480Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
29490Sstevel@tonic-gate
29500Sstevel@tonic-gate /*
29510Sstevel@tonic-gate * Setup for 1K buffer, aligned at 1K address boundary, and allow no
29520Sstevel@tonic-gate * less than 4 byte data transfers. Create the Buffer. Make sure that
29530Sstevel@tonic-gate * the buffer is not broken up into multiple cookies. OpenHCI can only
29540Sstevel@tonic-gate * handle one address for the config ROM buffer location.
29550Sstevel@tonic-gate */
29560Sstevel@tonic-gate parms.bp_length = 1024;
29570Sstevel@tonic-gate parms.bp_max_cookies = 1;
29580Sstevel@tonic-gate parms.bp_alignment = 1024;
29590Sstevel@tonic-gate status = hci1394_buf_alloc(ohci_hdl->ohci_drvinfo, &parms,
29600Sstevel@tonic-gate &ohci_hdl->ohci_cfgrom, &ohci_hdl->ohci_cfgrom_handle);
29610Sstevel@tonic-gate if (status != DDI_SUCCESS) {
29620Sstevel@tonic-gate TNF_PROBE_0(hci1394_buf_alloc_fail, HCI1394_TNF_HAL_ERROR, "");
29630Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cfgrom_init_exit,
29640Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
29650Sstevel@tonic-gate return (DDI_FAILURE);
29660Sstevel@tonic-gate }
29670Sstevel@tonic-gate
29680Sstevel@tonic-gate /* Tell OpenHCI where the buffer is */
29690Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
29700Sstevel@tonic-gate &ohci_hdl->ohci_regs->config_rom_maplo,
29710Sstevel@tonic-gate (uint32_t)ohci_hdl->ohci_cfgrom.bi_cookie.dmac_address);
29720Sstevel@tonic-gate
29730Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_cfgrom_init_exit, HCI1394_TNF_HAL_STACK,
29740Sstevel@tonic-gate "");
29750Sstevel@tonic-gate
29760Sstevel@tonic-gate return (DDI_SUCCESS);
29770Sstevel@tonic-gate }
29780Sstevel@tonic-gate
29790Sstevel@tonic-gate
29800Sstevel@tonic-gate /*
29810Sstevel@tonic-gate * hci1394_ohci_bus_capabilities()
29820Sstevel@tonic-gate * Return our current bus capabilities
29830Sstevel@tonic-gate */
29840Sstevel@tonic-gate void
hci1394_ohci_bus_capabilities(hci1394_ohci_handle_t ohci_hdl,uint32_t * bus_capabilities)29850Sstevel@tonic-gate hci1394_ohci_bus_capabilities(hci1394_ohci_handle_t ohci_hdl,
29860Sstevel@tonic-gate uint32_t *bus_capabilities)
29870Sstevel@tonic-gate {
29880Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
29890Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_capabilities_enter,
29900Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
29910Sstevel@tonic-gate /*
29920Sstevel@tonic-gate * read in the bus options register. Set bits saying that we are isoch
29930Sstevel@tonic-gate * resource manager capable, Cycle master capable, and Isoch capable
29940Sstevel@tonic-gate */
29950Sstevel@tonic-gate *bus_capabilities = ddi_get32(ohci_hdl->ohci_reg_handle,
29960Sstevel@tonic-gate &ohci_hdl->ohci_regs->bus_options) | (OHCI_BOPT_IRMC |
29970Sstevel@tonic-gate OHCI_BOPT_CMC | OHCI_BOPT_ISC);
29980Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_bus_capabilities_exit,
29990Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30000Sstevel@tonic-gate }
30010Sstevel@tonic-gate
30020Sstevel@tonic-gate
30030Sstevel@tonic-gate /*
30040Sstevel@tonic-gate * hci1394_ohci_at_active()
30050Sstevel@tonic-gate * Returns status one if either of the AT engines are active. If either AT
30060Sstevel@tonic-gate * engine is active, we return B_TRUE. If both AT engines are not active, we
30070Sstevel@tonic-gate * return B_FALSE.
30080Sstevel@tonic-gate */
30090Sstevel@tonic-gate boolean_t
hci1394_ohci_at_active(hci1394_ohci_handle_t ohci_hdl)30100Sstevel@tonic-gate hci1394_ohci_at_active(hci1394_ohci_handle_t ohci_hdl)
30110Sstevel@tonic-gate {
30120Sstevel@tonic-gate uint32_t reg;
30130Sstevel@tonic-gate
30140Sstevel@tonic-gate
30150Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
30160Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_at_active_enter,
30170Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30180Sstevel@tonic-gate
30190Sstevel@tonic-gate /* see if atreq active bit set */
30200Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
30210Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_req.ctxt_ctrl_set);
30220Sstevel@tonic-gate if (reg & OHCI_CC_ACTIVE_MASK) {
30230Sstevel@tonic-gate /* atreq engine is still active */
30240Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_atreq_active_fail,
30250Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
30260Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_at_active_exit,
30270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30280Sstevel@tonic-gate return (B_TRUE);
30290Sstevel@tonic-gate }
30300Sstevel@tonic-gate
30310Sstevel@tonic-gate /* see if atresp active bit set */
30320Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
30330Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_resp.ctxt_ctrl_set);
30340Sstevel@tonic-gate if (reg & OHCI_CC_ACTIVE_MASK) {
30350Sstevel@tonic-gate /* atresp engine is still active */
30360Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_atresp_active_fail,
30370Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR, "");
30380Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_at_active_exit,
30390Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30400Sstevel@tonic-gate return (B_TRUE);
30410Sstevel@tonic-gate }
30420Sstevel@tonic-gate
30430Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_at_active_exit,
30440Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30450Sstevel@tonic-gate
30460Sstevel@tonic-gate /* both atreq and atresp active bits are cleared */
30470Sstevel@tonic-gate return (B_FALSE);
30480Sstevel@tonic-gate }
30490Sstevel@tonic-gate
30500Sstevel@tonic-gate
30510Sstevel@tonic-gate /*
30520Sstevel@tonic-gate * hci1394_ohci_atreq_start()
30530Sstevel@tonic-gate * Start the atreq dma engine. Set the address of the first descriptor
30540Sstevel@tonic-gate * to read in equal to cmdptr.
30550Sstevel@tonic-gate */
30560Sstevel@tonic-gate void
hci1394_ohci_atreq_start(hci1394_ohci_handle_t ohci_hdl,uint32_t cmdptr)30570Sstevel@tonic-gate hci1394_ohci_atreq_start(hci1394_ohci_handle_t ohci_hdl, uint32_t cmdptr)
30580Sstevel@tonic-gate {
30590Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
30600Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_start_enter,
30610Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30620Sstevel@tonic-gate
30630Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
30640Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_req.cmd_ptrlo, cmdptr);
30650Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
30660Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_req.ctxt_ctrl_set, OHCI_CC_RUN_MASK);
30670Sstevel@tonic-gate
30680Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_start_exit,
30690Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30700Sstevel@tonic-gate }
30710Sstevel@tonic-gate
30720Sstevel@tonic-gate
30730Sstevel@tonic-gate /*
30740Sstevel@tonic-gate * hci1394_ohci_atreq_wake()
30750Sstevel@tonic-gate * Wake up the atreq dma engine. This should be called when a new descriptor
30760Sstevel@tonic-gate * is added to the Q and the dma engine has already be started. It it OK to
30770Sstevel@tonic-gate * call this when the DMA engine is active.
30780Sstevel@tonic-gate */
30790Sstevel@tonic-gate void
hci1394_ohci_atreq_wake(hci1394_ohci_handle_t ohci_hdl)30800Sstevel@tonic-gate hci1394_ohci_atreq_wake(hci1394_ohci_handle_t ohci_hdl)
30810Sstevel@tonic-gate {
30820Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
30830Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_wake_enter,
30840Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30850Sstevel@tonic-gate
30860Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
30870Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_req.ctxt_ctrl_set, OHCI_CC_WAKE_MASK);
30880Sstevel@tonic-gate
30890Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_wake_exit,
30900Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
30910Sstevel@tonic-gate }
30920Sstevel@tonic-gate
30930Sstevel@tonic-gate
30940Sstevel@tonic-gate /*
30950Sstevel@tonic-gate * hci1394_ohci_atreq_stop()
30960Sstevel@tonic-gate * Stop the atreq dma engine. No further descriptors will be read until
30970Sstevel@tonic-gate * it dma engine is started again.
30980Sstevel@tonic-gate */
30990Sstevel@tonic-gate void
hci1394_ohci_atreq_stop(hci1394_ohci_handle_t ohci_hdl)31000Sstevel@tonic-gate hci1394_ohci_atreq_stop(hci1394_ohci_handle_t ohci_hdl)
31010Sstevel@tonic-gate {
31020Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
31030Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_stop_enter,
31040Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31050Sstevel@tonic-gate
31060Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31070Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_req.ctxt_ctrl_clr, OHCI_CC_RUN_MASK);
31080Sstevel@tonic-gate
31090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atreq_stop_exit,
31100Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31110Sstevel@tonic-gate }
31120Sstevel@tonic-gate
31130Sstevel@tonic-gate
31140Sstevel@tonic-gate /*
31150Sstevel@tonic-gate * hci1394_ohci_arresp_start()
31160Sstevel@tonic-gate * Start the arresp dma engine. Set the address of the first descriptor
31170Sstevel@tonic-gate * to read in equal to cmdptr.
31180Sstevel@tonic-gate */
31190Sstevel@tonic-gate void
hci1394_ohci_arresp_start(hci1394_ohci_handle_t ohci_hdl,uint32_t cmdptr)31200Sstevel@tonic-gate hci1394_ohci_arresp_start(hci1394_ohci_handle_t ohci_hdl, uint32_t cmdptr)
31210Sstevel@tonic-gate {
31220Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
31230Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_start_enter,
31240Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31250Sstevel@tonic-gate
31260Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31270Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_resp.cmd_ptrlo, cmdptr);
31280Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31290Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_resp.ctxt_ctrl_set, OHCI_CC_RUN_MASK);
31300Sstevel@tonic-gate
31310Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_start_exit,
31320Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31330Sstevel@tonic-gate }
31340Sstevel@tonic-gate
31350Sstevel@tonic-gate
31360Sstevel@tonic-gate /*
31370Sstevel@tonic-gate * hci1394_ohci_arresp_wake()
31380Sstevel@tonic-gate * Wake up the arresp dma engine. This should be called when a new
31390Sstevel@tonic-gate * descriptor is added to the Q and the dma engine has already be started.
31400Sstevel@tonic-gate * It is OK to call this when the DMA engine is active.
31410Sstevel@tonic-gate */
31420Sstevel@tonic-gate void
hci1394_ohci_arresp_wake(hci1394_ohci_handle_t ohci_hdl)31430Sstevel@tonic-gate hci1394_ohci_arresp_wake(hci1394_ohci_handle_t ohci_hdl)
31440Sstevel@tonic-gate {
31450Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
31460Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_wake_enter,
31470Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31480Sstevel@tonic-gate
31490Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31500Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_resp.ctxt_ctrl_set, OHCI_CC_WAKE_MASK);
31510Sstevel@tonic-gate
31520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_wake_exit,
31530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31540Sstevel@tonic-gate }
31550Sstevel@tonic-gate
31560Sstevel@tonic-gate
31570Sstevel@tonic-gate /*
31580Sstevel@tonic-gate * hci1394_ohci_atreq_stop()
31590Sstevel@tonic-gate * Stop the arresp dma engine. No further data will be received after any
31600Sstevel@tonic-gate * current packets being received have finished.
31610Sstevel@tonic-gate */
31620Sstevel@tonic-gate void
hci1394_ohci_arresp_stop(hci1394_ohci_handle_t ohci_hdl)31630Sstevel@tonic-gate hci1394_ohci_arresp_stop(hci1394_ohci_handle_t ohci_hdl)
31640Sstevel@tonic-gate {
31650Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
31660Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_stop_enter,
31670Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31680Sstevel@tonic-gate
31690Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31700Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_resp.ctxt_ctrl_clr, OHCI_CC_RUN_MASK);
31710Sstevel@tonic-gate
31720Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arresp_stop_exit,
31730Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31740Sstevel@tonic-gate }
31750Sstevel@tonic-gate
31760Sstevel@tonic-gate
31770Sstevel@tonic-gate /*
31780Sstevel@tonic-gate * hci1394_ohci_arreq_start()
31790Sstevel@tonic-gate * Start the arreq dma engine. Set the address of the first descriptor
31800Sstevel@tonic-gate * to read in equal to cmdptr.
31810Sstevel@tonic-gate */
31820Sstevel@tonic-gate void
hci1394_ohci_arreq_start(hci1394_ohci_handle_t ohci_hdl,uint32_t cmdptr)31830Sstevel@tonic-gate hci1394_ohci_arreq_start(hci1394_ohci_handle_t ohci_hdl, uint32_t cmdptr)
31840Sstevel@tonic-gate {
31850Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
31860Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_start_enter,
31870Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31880Sstevel@tonic-gate
31890Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31900Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_req.cmd_ptrlo, cmdptr);
31910Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
31920Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_req.ctxt_ctrl_set, OHCI_CC_RUN_MASK);
31930Sstevel@tonic-gate
31940Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_start_exit,
31950Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
31960Sstevel@tonic-gate }
31970Sstevel@tonic-gate
31980Sstevel@tonic-gate
31990Sstevel@tonic-gate /*
32000Sstevel@tonic-gate * hci1394_ohci_arreq_wake()
32010Sstevel@tonic-gate * Wake up the arreq dma engine. This should be called when a new descriptor
32020Sstevel@tonic-gate * is added to the Q and the dma engine has already be started. It is OK to
32030Sstevel@tonic-gate * call this when the DMA engine is active.
32040Sstevel@tonic-gate */
32050Sstevel@tonic-gate void
hci1394_ohci_arreq_wake(hci1394_ohci_handle_t ohci_hdl)32060Sstevel@tonic-gate hci1394_ohci_arreq_wake(hci1394_ohci_handle_t ohci_hdl)
32070Sstevel@tonic-gate {
32080Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
32090Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_wake_enter,
32100Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32110Sstevel@tonic-gate
32120Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32130Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_req.ctxt_ctrl_set, OHCI_CC_WAKE_MASK);
32140Sstevel@tonic-gate
32150Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_wake_exit,
32160Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32170Sstevel@tonic-gate }
32180Sstevel@tonic-gate
32190Sstevel@tonic-gate
32200Sstevel@tonic-gate /*
32210Sstevel@tonic-gate * hci1394_ohci_arreq_stop()
32220Sstevel@tonic-gate * Stop the arreq dma engine. No further data will be received after any
32230Sstevel@tonic-gate * current packets being received have finished.
32240Sstevel@tonic-gate */
32250Sstevel@tonic-gate void
hci1394_ohci_arreq_stop(hci1394_ohci_handle_t ohci_hdl)32260Sstevel@tonic-gate hci1394_ohci_arreq_stop(hci1394_ohci_handle_t ohci_hdl)
32270Sstevel@tonic-gate {
32280Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
32290Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_stop_enter,
32300Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32310Sstevel@tonic-gate
32320Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32330Sstevel@tonic-gate &ohci_hdl->ohci_regs->ar_req.ctxt_ctrl_clr, OHCI_CC_RUN_MASK);
32340Sstevel@tonic-gate
32350Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_arreq_stop_exit,
32360Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32370Sstevel@tonic-gate }
32380Sstevel@tonic-gate
32390Sstevel@tonic-gate
32400Sstevel@tonic-gate /*
32410Sstevel@tonic-gate * hci1394_ohci_atresp_start()
32420Sstevel@tonic-gate * Start the atresp dma engine. Set the address of the first descriptor
32430Sstevel@tonic-gate * to read in equal to cmdptr.
32440Sstevel@tonic-gate */
32450Sstevel@tonic-gate void
hci1394_ohci_atresp_start(hci1394_ohci_handle_t ohci_hdl,uint32_t cmdptr)32460Sstevel@tonic-gate hci1394_ohci_atresp_start(hci1394_ohci_handle_t ohci_hdl, uint32_t cmdptr)
32470Sstevel@tonic-gate {
32480Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
32490Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_start_enter,
32500Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32510Sstevel@tonic-gate
32520Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32530Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_resp.cmd_ptrlo, cmdptr);
32540Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32550Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_resp.ctxt_ctrl_set, OHCI_CC_RUN_MASK);
32560Sstevel@tonic-gate
32570Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_start_exit,
32580Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32590Sstevel@tonic-gate }
32600Sstevel@tonic-gate
32610Sstevel@tonic-gate
32620Sstevel@tonic-gate /*
32630Sstevel@tonic-gate * hci1394_ohci_atresp_wake()
32640Sstevel@tonic-gate * Wake up the atresp dma engine. This should be called when a new
32650Sstevel@tonic-gate * descriptor is added to the Q and the dma engine has already be started.
32660Sstevel@tonic-gate * It is OK to call this when the DMA engine is active.
32670Sstevel@tonic-gate */
32680Sstevel@tonic-gate void
hci1394_ohci_atresp_wake(hci1394_ohci_handle_t ohci_hdl)32690Sstevel@tonic-gate hci1394_ohci_atresp_wake(hci1394_ohci_handle_t ohci_hdl)
32700Sstevel@tonic-gate {
32710Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
32720Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_wake_enter,
32730Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32740Sstevel@tonic-gate
32750Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32760Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_resp.ctxt_ctrl_set, OHCI_CC_WAKE_MASK);
32770Sstevel@tonic-gate
32780Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_wake_exit,
32790Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32800Sstevel@tonic-gate }
32810Sstevel@tonic-gate
32820Sstevel@tonic-gate
32830Sstevel@tonic-gate /*
32840Sstevel@tonic-gate * hci1394_ohci_atresp_stop()
32850Sstevel@tonic-gate * Stop the atresp dma engine. No further descriptors will be read until
32860Sstevel@tonic-gate * it dma engine is started again.
32870Sstevel@tonic-gate */
32880Sstevel@tonic-gate void
hci1394_ohci_atresp_stop(hci1394_ohci_handle_t ohci_hdl)32890Sstevel@tonic-gate hci1394_ohci_atresp_stop(hci1394_ohci_handle_t ohci_hdl)
32900Sstevel@tonic-gate {
32910Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
32920Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_stop_enter,
32930Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
32940Sstevel@tonic-gate
32950Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
32960Sstevel@tonic-gate &ohci_hdl->ohci_regs->at_resp.ctxt_ctrl_clr, OHCI_CC_RUN_MASK);
32970Sstevel@tonic-gate
32980Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_atresp_stop_exit,
32990Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33000Sstevel@tonic-gate }
33010Sstevel@tonic-gate
33020Sstevel@tonic-gate
33030Sstevel@tonic-gate /*
33040Sstevel@tonic-gate * hci1394_ohci_1394a_init()
33050Sstevel@tonic-gate * Initialize any 1394a features that we are using.
33060Sstevel@tonic-gate */
33070Sstevel@tonic-gate /* ARGSUSED */
33080Sstevel@tonic-gate int
hci1394_ohci_1394a_init(hci1394_ohci_handle_t ohci_hdl)33090Sstevel@tonic-gate hci1394_ohci_1394a_init(hci1394_ohci_handle_t ohci_hdl)
33100Sstevel@tonic-gate {
33110Sstevel@tonic-gate uint32_t reg;
33120Sstevel@tonic-gate int status;
33130Sstevel@tonic-gate
33140Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
33150Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_init_enter, HCI1394_TNF_HAL_STACK,
33160Sstevel@tonic-gate "");
33170Sstevel@tonic-gate
33180Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
33190Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set);
33200Sstevel@tonic-gate if (reg & OHCI_HC_PROG_PHY_ENBL) {
33210Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
33220Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_APHY_ENBL);
33230Sstevel@tonic-gate status = hci1394_ohci_phy_set(ohci_hdl, 5,
33240Sstevel@tonic-gate (OHCI_PHY_ENBL_ACCEL | OHCI_PHY_ENBL_MULTI));
33250Sstevel@tonic-gate if (status != DDI_SUCCESS) {
33260Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_1394a_init_phy_fail,
33270Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33280Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_init_exit,
33290Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33300Sstevel@tonic-gate return (DDI_FAILURE);
33310Sstevel@tonic-gate }
33320Sstevel@tonic-gate }
33330Sstevel@tonic-gate
33340Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_init_exit, HCI1394_TNF_HAL_STACK,
33350Sstevel@tonic-gate "");
33360Sstevel@tonic-gate return (DDI_SUCCESS);
33370Sstevel@tonic-gate }
33380Sstevel@tonic-gate
33390Sstevel@tonic-gate
33400Sstevel@tonic-gate /*
33410Sstevel@tonic-gate * hci1394_ohci_1394a_init()
33420Sstevel@tonic-gate * Re-initialize any 1394a features that we are using.
33430Sstevel@tonic-gate */
33440Sstevel@tonic-gate /* ARGSUSED */
33450Sstevel@tonic-gate int
hci1394_ohci_1394a_resume(hci1394_ohci_handle_t ohci_hdl)33460Sstevel@tonic-gate hci1394_ohci_1394a_resume(hci1394_ohci_handle_t ohci_hdl)
33470Sstevel@tonic-gate {
33480Sstevel@tonic-gate uint32_t reg;
33490Sstevel@tonic-gate int status;
33500Sstevel@tonic-gate
33510Sstevel@tonic-gate ASSERT(ohci_hdl != NULL);
33520Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_resume_enter,
33530Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33540Sstevel@tonic-gate
33550Sstevel@tonic-gate reg = ddi_get32(ohci_hdl->ohci_reg_handle,
33560Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set);
33570Sstevel@tonic-gate if (reg & OHCI_HC_PROG_PHY_ENBL) {
33580Sstevel@tonic-gate ddi_put32(ohci_hdl->ohci_reg_handle,
33590Sstevel@tonic-gate &ohci_hdl->ohci_regs->hc_ctrl_set, OHCI_HC_APHY_ENBL);
33600Sstevel@tonic-gate status = hci1394_ohci_phy_set(ohci_hdl, 5,
33610Sstevel@tonic-gate (OHCI_PHY_ENBL_ACCEL | OHCI_PHY_ENBL_MULTI));
33620Sstevel@tonic-gate if (status != DDI_SUCCESS) {
33630Sstevel@tonic-gate TNF_PROBE_0(hci1394_ohci_1394a_resume_phy_fail,
33640Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33650Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_resume_exit,
33660Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33670Sstevel@tonic-gate return (DDI_FAILURE);
33680Sstevel@tonic-gate }
33690Sstevel@tonic-gate }
33700Sstevel@tonic-gate
33710Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ohci_1394a_resume_exit,
33720Sstevel@tonic-gate HCI1394_TNF_HAL_STACK, "");
33730Sstevel@tonic-gate return (DDI_SUCCESS);
33740Sstevel@tonic-gate }
3375