xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_attach.c (revision 7391:37b58541d6f7)
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*7391SBarry.Harding@Sun.COM  * Common Development and Distribution License (the "License").
6*7391SBarry.Harding@Sun.COM  * 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*7391SBarry.Harding@Sun.COM  * 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 /*
270Sstevel@tonic-gate  * hci1394_attach.c
280Sstevel@tonic-gate  *    HBA attach() routine with associated funtions.
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <sys/kmem.h>
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/stat.h>
370Sstevel@tonic-gate #include <sys/sunddi.h>
380Sstevel@tonic-gate #include <sys/cmn_err.h>
390Sstevel@tonic-gate #include <sys/pci.h>
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include <sys/1394/h1394.h>
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  * Attach State Information. These states are used to track the status of the
480Sstevel@tonic-gate  * attach.  They are bit offsets.
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate #define	STATE_ZALLOC		0
510Sstevel@tonic-gate #define	STATE_ISR_INIT		1
520Sstevel@tonic-gate #define	STATE_MINOR_NODE	2
530Sstevel@tonic-gate #define	STATE_HW_INIT		3
540Sstevel@tonic-gate #define	STATE_PHASE2		4
550Sstevel@tonic-gate #define	STATE_POWER_INIT	5
560Sstevel@tonic-gate #define	STATE_H1394_ATTACH	6
570Sstevel@tonic-gate #define	STATE_ISR_HANDLER	7
580Sstevel@tonic-gate #define	STATE_STARTUP		8
590Sstevel@tonic-gate 
600Sstevel@tonic-gate static void hci1394_statebit_set(uint64_t *state, uint_t statebit);
610Sstevel@tonic-gate static boolean_t hci1394_statebit_tst(uint64_t state, uint_t statebit);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate static void hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state);
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static int hci1394_hardware_init(hci1394_state_t *soft_state);
660Sstevel@tonic-gate static int hci1394_hardware_resume(hci1394_state_t *soft_state);
670Sstevel@tonic-gate 
680Sstevel@tonic-gate static int hci1394_pci_init(hci1394_state_t *soft_state);
690Sstevel@tonic-gate static void hci1394_pci_resume(hci1394_state_t *soft_state);
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static void hci1394_soft_state_phase1_init(hci1394_state_t *soft_state,
720Sstevel@tonic-gate     dev_info_t *dip, int instance);
730Sstevel@tonic-gate static void hci1394_soft_state_phase2_init(hci1394_state_t *soft_state);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate static int hci1394_resmap_get(hci1394_state_t *soft_state);
760Sstevel@tonic-gate static void hci1394_resmap_free(hci1394_state_t *soft_state);
770Sstevel@tonic-gate 
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 
800Sstevel@tonic-gate int
hci1394_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)810Sstevel@tonic-gate hci1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	hci1394_state_t *soft_state;
840Sstevel@tonic-gate 	uint64_t attach_state = 0;
850Sstevel@tonic-gate 	int instance;
860Sstevel@tonic-gate 	int status;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_attach_enter, HCI1394_TNF_HAL_STACK, "");
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	switch (cmd) {
920Sstevel@tonic-gate 	case DDI_ATTACH:
930Sstevel@tonic-gate 		instance = ddi_get_instance(dip);
940Sstevel@tonic-gate 		status = ddi_soft_state_zalloc(hci1394_statep, instance);
950Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
960Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_attach_ssz_fail,
970Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
980Sstevel@tonic-gate 			    "ddi_soft_state_zalloc() failed");
990Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1000Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1010Sstevel@tonic-gate 			return (DDI_FAILURE);
1020Sstevel@tonic-gate 		}
1030Sstevel@tonic-gate 		soft_state = ddi_get_soft_state(hci1394_statep, instance);
1040Sstevel@tonic-gate 		if (soft_state == NULL) {
1050Sstevel@tonic-gate 			ddi_soft_state_free(hci1394_statep, instance);
1060Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_attach_gss_fail,
1070Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
1080Sstevel@tonic-gate 			    "ddi_get_soft_state() failed");
1090Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1100Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1110Sstevel@tonic-gate 			return (DDI_FAILURE);
1120Sstevel@tonic-gate 		}
1130Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_ZALLOC);
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 		hci1394_soft_state_phase1_init(soft_state, dip, instance);
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 		/* get iblock cookie, other interrupt init stuff */
1180Sstevel@tonic-gate 		status = hci1394_isr_init(soft_state);
1190Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1200Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1210Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_isr_fail,
1220Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
1230Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1240Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1250Sstevel@tonic-gate 			return (DDI_FAILURE);
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_ISR_INIT);
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 		status = ddi_create_minor_node(dip, "devctl", S_IFCHR,
1300Sstevel@tonic-gate 		    instance, DDI_NT_NEXUS, 0);
1310Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1320Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1330Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_cmn_fail,
1340Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
1350Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1360Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1370Sstevel@tonic-gate 			return (DDI_FAILURE);
1380Sstevel@tonic-gate 		}
1390Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_MINOR_NODE);
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 		status = hci1394_hardware_init(soft_state);
1420Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1430Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1440Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_hwi_fail,
1450Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
1460Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1470Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1480Sstevel@tonic-gate 			return (DDI_FAILURE);
1490Sstevel@tonic-gate 		}
1500Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_HW_INIT);
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 		hci1394_soft_state_phase2_init(soft_state);
1530Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_PHASE2);
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 		/* build up the reserved addresses map */
1560Sstevel@tonic-gate 		status = hci1394_resmap_get(soft_state);
1570Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1580Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1590Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_rmg_fail,
1600Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
1610Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1620Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1630Sstevel@tonic-gate 			return (DDI_FAILURE);
1640Sstevel@tonic-gate 		}
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 		/* "attach" to the Services Layer */
1670Sstevel@tonic-gate 		status = h1394_attach(&soft_state->halinfo, DDI_ATTACH,
1680Sstevel@tonic-gate 		    &soft_state->drvinfo.di_sl_private);
1690Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1700Sstevel@tonic-gate 			hci1394_resmap_free(soft_state);
1710Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1720Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_ha_fail,
1730Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
1740Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
1750Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
1760Sstevel@tonic-gate 			return (DDI_FAILURE);
1770Sstevel@tonic-gate 		}
1780Sstevel@tonic-gate 		/* free the reserved addresses map */
1790Sstevel@tonic-gate 		hci1394_resmap_free(soft_state);
180*7391SBarry.Harding@Sun.COM 
1810Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_H1394_ATTACH);
1820Sstevel@tonic-gate 		status = hci1394_isr_handler_init(soft_state);
1830Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
1840Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
1850Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_ih_fail,
186*7391SBarry.Harding@Sun.COM 			    HCI1394_TNF_HAL_ERROR, "");
1870Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
188*7391SBarry.Harding@Sun.COM 			    HCI1394_TNF_HAL_STACK, "");
1890Sstevel@tonic-gate 			return (DDI_FAILURE);
1900Sstevel@tonic-gate 		}
1910Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_ISR_HANDLER);
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 		/* Report that driver was loaded */
1940Sstevel@tonic-gate 		ddi_report_dev(dip);
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 		/*
1970Sstevel@tonic-gate 		 * Turn on link, Reset Bus, enable interrupts.  Should be the
1980Sstevel@tonic-gate 		 * last routine called in attach. The statebit for starup must
1990Sstevel@tonic-gate 		 * be set before startup is called since startup enables
2000Sstevel@tonic-gate 		 * interrupts.
2010Sstevel@tonic-gate 		 */
2020Sstevel@tonic-gate 		hci1394_statebit_set(&attach_state, STATE_STARTUP);
2030Sstevel@tonic-gate 		status = hci1394_ohci_startup(soft_state->ohci);
2040Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
2050Sstevel@tonic-gate 			hci1394_cleanup(soft_state, attach_state);
2060Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_attach_str_fail,
2070Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
2080Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2090Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
2100Sstevel@tonic-gate 			return (DDI_FAILURE);
2110Sstevel@tonic-gate 		}
2120Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
2130Sstevel@tonic-gate 		    "");
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		return (DDI_SUCCESS);
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	case DDI_RESUME:
2180Sstevel@tonic-gate 		instance = ddi_get_instance(dip);
2190Sstevel@tonic-gate 		soft_state = ddi_get_soft_state(hci1394_statep, instance);
2200Sstevel@tonic-gate 		if (soft_state == NULL) {
2210Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_attach_resgss_fail,
2220Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2230Sstevel@tonic-gate 			    "ddi_get_soft_state() failed");
2240Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2250Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
2260Sstevel@tonic-gate 			return (DDI_FAILURE);
2270Sstevel@tonic-gate 		}
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 		status = hci1394_hardware_resume(soft_state);
2300Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
2310Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_attach_res_hwr_fail,
2320Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2330Sstevel@tonic-gate 			    "hardware failed to resume");
2340Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2350Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
2360Sstevel@tonic-gate 			return (DDI_FAILURE);
2370Sstevel@tonic-gate 		}
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 		/*
2400Sstevel@tonic-gate 		 * set our state back to initial.  The next bus reset were
2410Sstevel@tonic-gate 		 * about to generate will set us in motion.
2420Sstevel@tonic-gate 		 */
2430Sstevel@tonic-gate 		soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 		/* turn on the link, enable interrupts, reset the bus */
2460Sstevel@tonic-gate 		status = hci1394_ohci_startup(soft_state->ohci);
2470Sstevel@tonic-gate 		if (status != DDI_SUCCESS) {
2480Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_attach_res_str_fail,
2490Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2500Sstevel@tonic-gate 			    "hci1394_ohci_startup() failed");
2510Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
2520Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
2530Sstevel@tonic-gate 			return (DDI_FAILURE);
2540Sstevel@tonic-gate 		}
2550Sstevel@tonic-gate 
256*7391SBarry.Harding@Sun.COM 		/* tell the Services Layer that we are resuming */
257*7391SBarry.Harding@Sun.COM 		status = h1394_attach(&soft_state->halinfo, DDI_RESUME,
258*7391SBarry.Harding@Sun.COM 		    &soft_state->drvinfo.di_sl_private);
259*7391SBarry.Harding@Sun.COM 		if (status != DDI_SUCCESS) {
260*7391SBarry.Harding@Sun.COM 			TNF_PROBE_0(hci1394_attach_res_ha_fail,
261*7391SBarry.Harding@Sun.COM 			    HCI1394_TNF_HAL_ERROR, "");
262*7391SBarry.Harding@Sun.COM 			TNF_PROBE_0_DEBUG(hci1394_attach_exit,
263*7391SBarry.Harding@Sun.COM 			    HCI1394_TNF_HAL_STACK, "");
264*7391SBarry.Harding@Sun.COM 			return (DDI_FAILURE);
265*7391SBarry.Harding@Sun.COM 		}
266*7391SBarry.Harding@Sun.COM 
2670Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK,
2680Sstevel@tonic-gate 		    "");
2690Sstevel@tonic-gate 		return (DDI_SUCCESS);
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	default:
2720Sstevel@tonic-gate 		TNF_PROBE_0(h1394_attach_default_fail, HCI1394_TNF_HAL_ERROR,
2730Sstevel@tonic-gate 		    "");
2740Sstevel@tonic-gate 		break;
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_attach_exit, HCI1394_TNF_HAL_STACK, "");
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	return (DDI_FAILURE);
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate /*
2840Sstevel@tonic-gate  * hci1394_soft_state_phase1_init()
2850Sstevel@tonic-gate  *    First part soft_state initialization.  This should be called before any
2860Sstevel@tonic-gate  *    other initialization routines are called.  Anything that requires cleanup
2870Sstevel@tonic-gate  *    on detach or after an attach failure should be setup in phase2 init (i.e.
2880Sstevel@tonic-gate  *    mutex's, cv's, etc.)
2890Sstevel@tonic-gate  */
2900Sstevel@tonic-gate static void
hci1394_soft_state_phase1_init(hci1394_state_t * soft_state,dev_info_t * dip,int instance)2910Sstevel@tonic-gate hci1394_soft_state_phase1_init(hci1394_state_t *soft_state, dev_info_t *dip,
2920Sstevel@tonic-gate     int instance)
2930Sstevel@tonic-gate {
2940Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
2950Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_enter,
2960Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate 	soft_state->drvinfo.di_dip = dip;
2990Sstevel@tonic-gate 	soft_state->drvinfo.di_instance = instance;
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate 	/* current bus generation */
3020Sstevel@tonic-gate 	soft_state->drvinfo.di_gencnt = 0;
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 	soft_state->drvinfo.di_sl_private = NULL;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	/* initialize statistics */
3070Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_bus_reset_count = 0;
3080Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_selfid_count = 0;
3090Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_phy_isr = 0;
3100Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_phy_loop_err = 0;
3110Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_phy_pwrfail_err = 0;
3120Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_phy_timeout_err = 0;
3130Sstevel@tonic-gate 	soft_state->drvinfo.di_stats.st_phy_portevt_err = 0;
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate 	soft_state->swap_data = B_FALSE;
3160Sstevel@tonic-gate 	soft_state->sl_selfid_buf = NULL;
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate 	/* halinfo is what is passed up to the Services Layer */
3190Sstevel@tonic-gate 	soft_state->halinfo.hal_private = soft_state;
3200Sstevel@tonic-gate 	soft_state->halinfo.dip = soft_state->drvinfo.di_dip;
3210Sstevel@tonic-gate 	soft_state->halinfo.hal_events = hci1394_evts;
3220Sstevel@tonic-gate 	soft_state->halinfo.max_generation = OHCI_BUSGEN_MAX;
3230Sstevel@tonic-gate 	soft_state->halinfo.addr_map_num_entries = HCI1394_ADDR_MAP_SIZE;
3240Sstevel@tonic-gate 	soft_state->halinfo.addr_map = hci1394_addr_map;
3250Sstevel@tonic-gate 	hci1394_buf_attr_get(&soft_state->halinfo.dma_attr);
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase1_init_exit,
3280Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate /*
3330Sstevel@tonic-gate  * hci1394_soft_state_phase2_init()
3340Sstevel@tonic-gate  *    Second part of soft_state initialization.  This should be called after a
3350Sstevel@tonic-gate  *    successful hardware_init() and before the call to h1394_attach().
3360Sstevel@tonic-gate  */
3370Sstevel@tonic-gate static void
hci1394_soft_state_phase2_init(hci1394_state_t * soft_state)3380Sstevel@tonic-gate hci1394_soft_state_phase2_init(hci1394_state_t *soft_state)
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
3410Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_enter,
3420Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	/*
3450Sstevel@tonic-gate 	 * Setup our initial driver state.  This requires the HW iblock
3460Sstevel@tonic-gate 	 * cookie so this must be setup in phase2_init()
3470Sstevel@tonic-gate 	 */
3480Sstevel@tonic-gate 	soft_state->drvinfo.di_drvstate.ds_state = HCI1394_INITIAL;
3490Sstevel@tonic-gate 	mutex_init(&soft_state->drvinfo.di_drvstate.ds_mutex, NULL,
3500Sstevel@tonic-gate 	    MUTEX_DRIVER, soft_state->drvinfo.di_iblock_cookie);
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	/*
3530Sstevel@tonic-gate 	 * halinfo.acc_attr tells the services layer what our buffer access
3540Sstevel@tonic-gate 	 * attributes are.  drvinfo.di_buf_attr it initialized in pci_init so
3550Sstevel@tonic-gate 	 * this must be setup in phase2_init()
3560Sstevel@tonic-gate 	 */
3570Sstevel@tonic-gate 	soft_state->halinfo.acc_attr = soft_state->drvinfo.di_buf_attr;
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	/*
3600Sstevel@tonic-gate 	 * halinfo.hw_interrupt tells the services layer what our
3610Sstevel@tonic-gate 	 * iblock_cookie is. drvinfo.di_iblock_cookie is setup in isr_init so
3620Sstevel@tonic-gate 	 * this must be setup in phase2_init()
3630Sstevel@tonic-gate 	 */
3640Sstevel@tonic-gate 	soft_state->halinfo.hw_interrupt = soft_state->drvinfo.di_iblock_cookie;
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	/*
3670Sstevel@tonic-gate 	 * Read in our node capabilities.  Since we are calling into csr
3680Sstevel@tonic-gate 	 * we must have first called hardware_init().  Therefore, this must
3690Sstevel@tonic-gate 	 * be in phase2_init().
3700Sstevel@tonic-gate 	 */
3710Sstevel@tonic-gate 	hci1394_csr_node_capabilities(soft_state->csr,
3720Sstevel@tonic-gate 	    &soft_state->halinfo.node_capabilities);
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 	/*
3750Sstevel@tonic-gate 	 * Read in our bus capabilities.  Since we are calling into ohci
3760Sstevel@tonic-gate 	 * we must have first called hardware_init().  Therefore, this must
3770Sstevel@tonic-gate 	 * be in phase2_init().
3780Sstevel@tonic-gate 	 */
3790Sstevel@tonic-gate 	hci1394_ohci_bus_capabilities(soft_state->ohci,
3800Sstevel@tonic-gate 	    &soft_state->halinfo.bus_capabilities);
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	/*
3830Sstevel@tonic-gate 	 * Setup our async command overhead. When a target driver or the ARREQ
3840Sstevel@tonic-gate 	 * engine allocates a command, the services layer will tack on space
3850Sstevel@tonic-gate 	 * for itself and the HAL so we do not have to manage memory for every
3860Sstevel@tonic-gate 	 * command.  hal_overhead is how much memory the hal requires to track
3870Sstevel@tonic-gate 	 * an async command. Since we are calling into async we must have first
3880Sstevel@tonic-gate 	 * called hardware_init().  Therefore, this must be in phase2_init().
3890Sstevel@tonic-gate 	 */
3900Sstevel@tonic-gate 	soft_state->halinfo.hal_overhead = hci1394_async_cmd_overhead();
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_soft_state_phase2_init_exit,
3930Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate /*
3980Sstevel@tonic-gate  * hci1394_hardware_init()
3990Sstevel@tonic-gate  *    Initialize the adapter hardware.  This should be called during
4000Sstevel@tonic-gate  *    the initial attach().
4010Sstevel@tonic-gate  */
4020Sstevel@tonic-gate static int
hci1394_hardware_init(hci1394_state_t * soft_state)4030Sstevel@tonic-gate hci1394_hardware_init(hci1394_state_t *soft_state)
4040Sstevel@tonic-gate {
4050Sstevel@tonic-gate 	int status;
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
4090Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_hardware_init_enter, HCI1394_TNF_HAL_STACK,
4100Sstevel@tonic-gate 	    "");
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	/* Initialize PCI config registers */
4130Sstevel@tonic-gate 	status = hci1394_pci_init(soft_state);
4140Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
4150Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_init_pci_fail,
4160Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
4170Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4180Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
4190Sstevel@tonic-gate 		return (DDI_FAILURE);
4200Sstevel@tonic-gate 	}
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate 	/* Initialize the OpenHCI Hardware */
4230Sstevel@tonic-gate 	status = hci1394_ohci_init(soft_state, &soft_state->drvinfo,
4240Sstevel@tonic-gate 	    &soft_state->ohci);
4250Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
4260Sstevel@tonic-gate 		hci1394_pci_fini(soft_state);
4270Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_init_ohci_fail,
4280Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
4290Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4300Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
4310Sstevel@tonic-gate 		return (DDI_FAILURE);
4320Sstevel@tonic-gate 	}
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 	/* Initialize SW based CSR registers */
4350Sstevel@tonic-gate 	hci1394_csr_init(&soft_state->drvinfo, soft_state->ohci,
4360Sstevel@tonic-gate 	    &soft_state->csr);
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	/* Initialize the Asynchronous Q's */
4390Sstevel@tonic-gate 	status = hci1394_async_init(&soft_state->drvinfo, soft_state->ohci,
4400Sstevel@tonic-gate 	    soft_state->csr, &soft_state->async);
4410Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
4420Sstevel@tonic-gate 		hci1394_csr_fini(&soft_state->csr);
4430Sstevel@tonic-gate 		hci1394_ohci_fini(&soft_state->ohci);
4440Sstevel@tonic-gate 		hci1394_pci_fini(soft_state);
4450Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_init_asyn_fail,
4460Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
4470Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4480Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
4490Sstevel@tonic-gate 		return (DDI_FAILURE);
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	/* Initialize the Isochronous logic */
4530Sstevel@tonic-gate 	hci1394_isoch_init(&soft_state->drvinfo, soft_state->ohci,
4540Sstevel@tonic-gate 	    &soft_state->isoch);
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 	/* Initialize any Vendor Specific Registers */
4570Sstevel@tonic-gate 	status = hci1394_vendor_init(&soft_state->drvinfo, soft_state->ohci,
4580Sstevel@tonic-gate 	    &soft_state->vendor_info, &soft_state->vendor);
4590Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
4600Sstevel@tonic-gate 		hci1394_isoch_fini(&soft_state->isoch);
4610Sstevel@tonic-gate 		hci1394_async_fini(&soft_state->async);
4620Sstevel@tonic-gate 		hci1394_csr_fini(&soft_state->csr);
4630Sstevel@tonic-gate 		hci1394_ohci_fini(&soft_state->ohci);
4640Sstevel@tonic-gate 		hci1394_pci_fini(soft_state);
4650Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_init_vend_fail,
4660Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
4670Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4680Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
4690Sstevel@tonic-gate 		return (DDI_FAILURE);
4700Sstevel@tonic-gate 	}
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_hardware_init_exit,
4730Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 	return (DDI_SUCCESS);
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate /*
4800Sstevel@tonic-gate  * hci1394_hardware_resume()
4810Sstevel@tonic-gate  *    Resume the adapter HW.  This routine will be called during resume after
4820Sstevel@tonic-gate  *    a successful system suspend.  All memory should be in the state it was
4830Sstevel@tonic-gate  *    before the suspend.  All we have to do is re-setup the HW.
4840Sstevel@tonic-gate  */
4850Sstevel@tonic-gate static int
hci1394_hardware_resume(hci1394_state_t * soft_state)4860Sstevel@tonic-gate hci1394_hardware_resume(hci1394_state_t *soft_state)
4870Sstevel@tonic-gate {
4880Sstevel@tonic-gate 	int status;
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
4920Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_hardware_resume_enter, HCI1394_TNF_HAL_STACK,
4930Sstevel@tonic-gate 	    "");
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate 	/* re-enable global byte swap (if we using it) */
4960Sstevel@tonic-gate 	hci1394_pci_resume(soft_state);
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	/* Re-init the OpenHCI HW */
4990Sstevel@tonic-gate 	status = hci1394_ohci_resume(soft_state->ohci);
5000Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
5010Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_resume_ohci_fail,
5020Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
5030Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5040Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
5050Sstevel@tonic-gate 		return (DDI_FAILURE);
5060Sstevel@tonic-gate 	}
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 	/* re-setup our SW based CSR registers */
5090Sstevel@tonic-gate 	hci1394_csr_resume(soft_state->csr);
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	/* Re-setup the Async Q's */
5120Sstevel@tonic-gate 	status = hci1394_async_resume(soft_state->async);
5130Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
5140Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_resume_asyn_fail,
5150Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
5160Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5170Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
5180Sstevel@tonic-gate 		return (DDI_FAILURE);
5190Sstevel@tonic-gate 	}
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	/* Re-setup any Vendor Specific Registers */
5220Sstevel@tonic-gate 	status = hci1394_vendor_resume(soft_state->vendor);
5230Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
5240Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_hardware_resume_vend_fail,
5250Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
5260Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5270Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
5280Sstevel@tonic-gate 		return (DDI_FAILURE);
5290Sstevel@tonic-gate 	}
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_hardware_resume_exit,
5320Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 	return (DDI_SUCCESS);
5350Sstevel@tonic-gate }
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 
5380Sstevel@tonic-gate /*
5390Sstevel@tonic-gate  * hci1394_pci_init()
5400Sstevel@tonic-gate  *    Map in PCI config space and initialize PCI config space registers.
5410Sstevel@tonic-gate  */
5420Sstevel@tonic-gate static int
hci1394_pci_init(hci1394_state_t * soft_state)5430Sstevel@tonic-gate hci1394_pci_init(hci1394_state_t *soft_state)
5440Sstevel@tonic-gate {
5450Sstevel@tonic-gate 	int status;
5460Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN
5470Sstevel@tonic-gate 	uint32_t global_swap;
5480Sstevel@tonic-gate #endif
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
5520Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_pci_init_enter, HCI1394_TNF_HAL_STACK, "");
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 	/* Setup PCI configuration space */
5550Sstevel@tonic-gate 	status = pci_config_setup(soft_state->drvinfo.di_dip,
5560Sstevel@tonic-gate 	    &soft_state->pci_config);
5570Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
5580Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_pci_init_cfg_fail, HCI1394_TNF_HAL_ERROR,
5590Sstevel@tonic-gate 		    "");
5600Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK,
5610Sstevel@tonic-gate 		    "");
5620Sstevel@tonic-gate 		return (DDI_FAILURE);
5630Sstevel@tonic-gate 	}
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
5670Sstevel@tonic-gate 	/* Start of little endian specific code */
5680Sstevel@tonic-gate 	soft_state->drvinfo.di_reg_attr.devacc_attr_version =
5690Sstevel@tonic-gate 	    DDI_DEVICE_ATTR_V0;
5700Sstevel@tonic-gate 	soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
5710Sstevel@tonic-gate 	    DDI_STRUCTURE_LE_ACC;
5720Sstevel@tonic-gate 	soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
5730Sstevel@tonic-gate 	    DDI_STRICTORDER_ACC;
5740Sstevel@tonic-gate 	soft_state->drvinfo.di_buf_attr.devacc_attr_version =
5750Sstevel@tonic-gate 	    DDI_DEVICE_ATTR_V0;
5760Sstevel@tonic-gate 	soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
5770Sstevel@tonic-gate 	    DDI_STRUCTURE_LE_ACC;
5780Sstevel@tonic-gate 	soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
5790Sstevel@tonic-gate 	    DDI_STRICTORDER_ACC;
5800Sstevel@tonic-gate 	soft_state->swap_data = B_TRUE;
5810Sstevel@tonic-gate 	/* End of little endian specific code */
5820Sstevel@tonic-gate #else
5830Sstevel@tonic-gate 	/* Start of big endian specific code */
5840Sstevel@tonic-gate 	/* If PCI_Global_Swap bit is not set, try to set it */
5850Sstevel@tonic-gate 	global_swap = pci_config_get32(soft_state->pci_config,
5860Sstevel@tonic-gate 	    OHCI_PCI_HCI_CONTROL_REG);
5870Sstevel@tonic-gate 
5880Sstevel@tonic-gate 	/* Lets see if the global byte swap feature is supported */
5890Sstevel@tonic-gate 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
5900Sstevel@tonic-gate 		global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
5910Sstevel@tonic-gate 		pci_config_put32(soft_state->pci_config,
5920Sstevel@tonic-gate 		    OHCI_PCI_HCI_CONTROL_REG, global_swap);
5930Sstevel@tonic-gate 	}
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 	global_swap = pci_config_get32(soft_state->pci_config,
5960Sstevel@tonic-gate 	    OHCI_PCI_HCI_CONTROL_REG);
5970Sstevel@tonic-gate 
5980Sstevel@tonic-gate 	/* If PCI_Global_Swap bit is not set, it is unsupported */
5990Sstevel@tonic-gate 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
6000Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_pci_gbs_npresent,
6010Sstevel@tonic-gate 		    HCI1394_TNF_HAL_INFO, "global swap not present");
6020Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_version =
6030Sstevel@tonic-gate 		    DDI_DEVICE_ATTR_V0;
6040Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
6050Sstevel@tonic-gate 		    DDI_STRUCTURE_LE_ACC;
6060Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
6070Sstevel@tonic-gate 		    DDI_STRICTORDER_ACC;
6080Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_version =
6090Sstevel@tonic-gate 		    DDI_DEVICE_ATTR_V0;
6100Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
6110Sstevel@tonic-gate 		    DDI_STRUCTURE_LE_ACC;
6120Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
6130Sstevel@tonic-gate 		    DDI_STRICTORDER_ACC;
6140Sstevel@tonic-gate 		soft_state->swap_data = B_TRUE;
6150Sstevel@tonic-gate 	/*
6160Sstevel@tonic-gate 	 * global byte swap is supported.  This should be the case
6170Sstevel@tonic-gate 	 * for almost all of the adapters.
6180Sstevel@tonic-gate 	 */
6190Sstevel@tonic-gate 	} else {
6200Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_pci_gbs_present,
6210Sstevel@tonic-gate 		    HCI1394_TNF_HAL_INFO, "global swap present");
6220Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_version =
6230Sstevel@tonic-gate 		    DDI_DEVICE_ATTR_V0;
6240Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_endian_flags =
6250Sstevel@tonic-gate 		    DDI_STRUCTURE_BE_ACC;
6260Sstevel@tonic-gate 		soft_state->drvinfo.di_reg_attr.devacc_attr_dataorder =
6270Sstevel@tonic-gate 		    DDI_STRICTORDER_ACC;
6280Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_version =
6290Sstevel@tonic-gate 		    DDI_DEVICE_ATTR_V0;
6300Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_endian_flags =
6310Sstevel@tonic-gate 		    DDI_STRUCTURE_BE_ACC;
6320Sstevel@tonic-gate 		soft_state->drvinfo.di_buf_attr.devacc_attr_dataorder =
6330Sstevel@tonic-gate 		    DDI_STRICTORDER_ACC;
6340Sstevel@tonic-gate 		soft_state->swap_data = B_FALSE;
6350Sstevel@tonic-gate 	}
6360Sstevel@tonic-gate 	/* End of big endian specific code */
6370Sstevel@tonic-gate #endif
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 	/* read in vendor Information */
6400Sstevel@tonic-gate 	soft_state->vendor_info.vendor_id =
6410Sstevel@tonic-gate 	    (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_VENID);
6420Sstevel@tonic-gate 	soft_state->vendor_info.device_id =
6430Sstevel@tonic-gate 	    (uint_t)pci_config_get16(soft_state->pci_config, PCI_CONF_DEVID);
6440Sstevel@tonic-gate 	soft_state->vendor_info.revision_id =
6450Sstevel@tonic-gate 	    (uint_t)pci_config_get8(soft_state->pci_config, PCI_CONF_REVID);
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_pci_init_exit, HCI1394_TNF_HAL_STACK, "");
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 	return (DDI_SUCCESS);
6500Sstevel@tonic-gate }
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate /*
6540Sstevel@tonic-gate  * hci1394_pci_resume()
6550Sstevel@tonic-gate  *    Re-Initialize PCI config space registers during a resume.
6560Sstevel@tonic-gate  */
6570Sstevel@tonic-gate /* ARGSUSED */
6580Sstevel@tonic-gate static void
hci1394_pci_resume(hci1394_state_t * soft_state)6590Sstevel@tonic-gate hci1394_pci_resume(hci1394_state_t *soft_state)
6600Sstevel@tonic-gate {
6610Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN
6620Sstevel@tonic-gate 	uint32_t global_swap;
6630Sstevel@tonic-gate #endif
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
6670Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_pci_resume_enter, HCI1394_TNF_HAL_STACK, "");
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
6700Sstevel@tonic-gate 	/* Start of little endian specific code */
6710Sstevel@tonic-gate 	/* nothing to do here yet.  Maybe later?? */
6720Sstevel@tonic-gate 	/* End of little endian specific code */
6730Sstevel@tonic-gate #else
6740Sstevel@tonic-gate 	/* Start of big endian specific code */
6750Sstevel@tonic-gate 	/* If PCI_Global_Swap bit is not set, try to set it */
6760Sstevel@tonic-gate 	global_swap = pci_config_get32(soft_state->pci_config,
6770Sstevel@tonic-gate 	    OHCI_PCI_HCI_CONTROL_REG);
6780Sstevel@tonic-gate 	/* Try and set GlobalByteSwap */
6790Sstevel@tonic-gate 	if ((global_swap & OHCI_PCI_GLOBAL_SWAP) == 0) {
6800Sstevel@tonic-gate 		global_swap = global_swap | OHCI_PCI_GLOBAL_SWAP;
6810Sstevel@tonic-gate 		pci_config_put32(soft_state->pci_config,
6820Sstevel@tonic-gate 		    OHCI_PCI_HCI_CONTROL_REG, global_swap);
6830Sstevel@tonic-gate 	}
6840Sstevel@tonic-gate 	/* End of big endian specific code */
6850Sstevel@tonic-gate #endif
6860Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_pci_resume_exit, HCI1394_TNF_HAL_STACK, "");
6870Sstevel@tonic-gate }
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate /*
6910Sstevel@tonic-gate  * hci1394_resmap_get()
6920Sstevel@tonic-gate  *    Look for adapter property "reserved-addresses".  This property is used to
6930Sstevel@tonic-gate  *    reserve 1394 address space so that it will not randomly be given to a
6940Sstevel@tonic-gate  *    target driver during a 1394 address space alloc.  Some protocols hard
6950Sstevel@tonic-gate  *    code addresses which make us do this.  The target driver must specifically
6960Sstevel@tonic-gate  *    ask for these addresses.  This routine should be called before the
6970Sstevel@tonic-gate  *    call to h1394_attach().
6980Sstevel@tonic-gate  */
6990Sstevel@tonic-gate static int
hci1394_resmap_get(hci1394_state_t * soft_state)7000Sstevel@tonic-gate hci1394_resmap_get(hci1394_state_t *soft_state)
7010Sstevel@tonic-gate {
7020Sstevel@tonic-gate 	h1394_addr_map_t *resv_map;
7030Sstevel@tonic-gate 	int resv_num;
7040Sstevel@tonic-gate 	int status;
7050Sstevel@tonic-gate 	int reslen;
7060Sstevel@tonic-gate 	uint32_t *resptr;
7070Sstevel@tonic-gate 	int rescnt;
7080Sstevel@tonic-gate 	int mapcnt;
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
7120Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_resmap_get_enter, HCI1394_TNF_HAL_STACK, "");
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate 	/*
7150Sstevel@tonic-gate 	 * See if the "reserved-addresses" property is defined.  The format
7160Sstevel@tonic-gate 	 * should be:
7170Sstevel@tonic-gate 	 *
7180Sstevel@tonic-gate 	 * reserved-addresses=	0x0000ffff,0xf0000B00,0x200,
7190Sstevel@tonic-gate 	 * 			0x0000ffff,0xf0000D00,0x200,
7200Sstevel@tonic-gate 	 * 			0x0000ffff,0xf0000234,0x4;
7210Sstevel@tonic-gate 	 * You can have multiple reserved addresses.  Each reserved address
7220Sstevel@tonic-gate 	 * takes up 3 integers.
7230Sstevel@tonic-gate 	 *    MSWofAddr,LSWofAddr,ByteCount
7240Sstevel@tonic-gate 	 */
7250Sstevel@tonic-gate 	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
7260Sstevel@tonic-gate 	    soft_state->drvinfo.di_dip, DDI_PROP_DONTPASS, "reserved-addresses",
7270Sstevel@tonic-gate 	    (int **)&resptr, (uint_t *)&reslen);
7280Sstevel@tonic-gate 	if (status != DDI_PROP_SUCCESS) {
7290Sstevel@tonic-gate 		/* the property is not defined,  0 reserved addresses */
7300Sstevel@tonic-gate 		soft_state->halinfo.resv_map_num_entries = 0;
7310Sstevel@tonic-gate 		soft_state->halinfo.resv_map = NULL;
7320Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit,
7330Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
7340Sstevel@tonic-gate 		return (DDI_SUCCESS);
7350Sstevel@tonic-gate 	} else if ((reslen < 3) || ((reslen % 3) != 0)) {
7360Sstevel@tonic-gate 		/*
7370Sstevel@tonic-gate 		 * the property is defined but the correct number of integers
7380Sstevel@tonic-gate 		 * is not present.
7390Sstevel@tonic-gate 		 */
7400Sstevel@tonic-gate 		resv_num = 0;
7410Sstevel@tonic-gate 		resv_map = NULL;
7420Sstevel@tonic-gate 		cmn_err(CE_NOTE, "!%s(%d): Invalid reserved-addresses property."
7430Sstevel@tonic-gate 		    " Property ignored", ddi_node_name(
7440Sstevel@tonic-gate 		    soft_state->drvinfo.di_dip), ddi_get_instance(
7450Sstevel@tonic-gate 		    soft_state->drvinfo.di_dip));
7460Sstevel@tonic-gate 	} else {
7470Sstevel@tonic-gate 		/* the property is defined. Alloc space to copy data into */
7480Sstevel@tonic-gate 		resv_num = reslen / 3;
7490Sstevel@tonic-gate 		resv_map = kmem_alloc((sizeof (h1394_addr_map_t) * (resv_num)),
7500Sstevel@tonic-gate 		    KM_SLEEP);
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 		/* read in the address, length, and set the type to reserved */
7530Sstevel@tonic-gate 		rescnt = 0;
7540Sstevel@tonic-gate 		mapcnt = 0;
7550Sstevel@tonic-gate 		while (rescnt < reslen) {
7560Sstevel@tonic-gate 			resv_map[mapcnt].address =
7570Sstevel@tonic-gate 			    (uint64_t)resptr[rescnt] << 32;
7580Sstevel@tonic-gate 			rescnt++;
7590Sstevel@tonic-gate 			resv_map[mapcnt].address |= (uint64_t)resptr[rescnt];
7600Sstevel@tonic-gate 			rescnt++;
7610Sstevel@tonic-gate 			resv_map[mapcnt].length = (uint64_t)resptr[rescnt];
7620Sstevel@tonic-gate 			rescnt++;
7630Sstevel@tonic-gate 			resv_map[mapcnt].addr_type = H1394_ADDR_RESERVED;
7640Sstevel@tonic-gate 			mapcnt++;
7650Sstevel@tonic-gate 		}
7660Sstevel@tonic-gate 	}
7670Sstevel@tonic-gate 
7680Sstevel@tonic-gate 	ddi_prop_free(resptr);
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	/*
7710Sstevel@tonic-gate 	 * copy the number of reserved address ranges and a pointer to the map
7720Sstevel@tonic-gate 	 * into halinfo so we can tell the services layer about them in
7730Sstevel@tonic-gate 	 * h1394_attach()
7740Sstevel@tonic-gate 	 */
7750Sstevel@tonic-gate 	soft_state->halinfo.resv_map_num_entries = resv_num;
7760Sstevel@tonic-gate 	soft_state->halinfo.resv_map = resv_map;
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_resmap_get_exit, HCI1394_TNF_HAL_STACK, "");
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	return (DDI_SUCCESS);
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 
7840Sstevel@tonic-gate /*
7850Sstevel@tonic-gate  * hci1394_resmap_free()
7860Sstevel@tonic-gate  *    Free up the space alloced in hci1394_resmap_get().  This routine should
7870Sstevel@tonic-gate  *    be called after h1394_attach().  The HAL does not need this information
7880Sstevel@tonic-gate  *    and the services layer only uses it for a calculation during attach and
7890Sstevel@tonic-gate  *    should not refer to the pointer after it returns from h1394_attach().
7900Sstevel@tonic-gate  */
7910Sstevel@tonic-gate static void
hci1394_resmap_free(hci1394_state_t * soft_state)7920Sstevel@tonic-gate hci1394_resmap_free(hci1394_state_t *soft_state)
7930Sstevel@tonic-gate {
7940Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
7950Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_resmap_free_enter, HCI1394_TNF_HAL_STACK, "");
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate 	/*
7980Sstevel@tonic-gate 	 * if we have one or more reserved map entries, free up the space that
7990Sstevel@tonic-gate 	 * was allocated to store them
8000Sstevel@tonic-gate 	 */
8010Sstevel@tonic-gate 	if (soft_state->halinfo.resv_map_num_entries > 0) {
8020Sstevel@tonic-gate 		ASSERT(soft_state->halinfo.resv_map != NULL);
8030Sstevel@tonic-gate 		kmem_free(soft_state->halinfo.resv_map,
8040Sstevel@tonic-gate 		    (sizeof (h1394_addr_map_t) *
8050Sstevel@tonic-gate 		    soft_state->halinfo.resv_map_num_entries));
8060Sstevel@tonic-gate 	}
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_resmap_free_exit, HCI1394_TNF_HAL_STACK, "");
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate /*
8130Sstevel@tonic-gate  * hci1394_statebit_set()
8140Sstevel@tonic-gate  *     Set bit "statebit" in "state"
8150Sstevel@tonic-gate  */
8160Sstevel@tonic-gate static void
hci1394_statebit_set(uint64_t * state,uint_t statebit)8170Sstevel@tonic-gate hci1394_statebit_set(uint64_t *state, uint_t statebit)
8180Sstevel@tonic-gate {
8190Sstevel@tonic-gate 	ASSERT(state != NULL);
8200Sstevel@tonic-gate 	ASSERT(statebit < 64);
8210Sstevel@tonic-gate 	*state |= (uint64_t)0x1 << statebit;
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate /*
8260Sstevel@tonic-gate  * hci1394_statebit_tst()
8270Sstevel@tonic-gate  *    Return status of bit "statebit".  Is it set or not?
8280Sstevel@tonic-gate  */
8290Sstevel@tonic-gate static boolean_t
hci1394_statebit_tst(uint64_t state,uint_t statebit)8300Sstevel@tonic-gate hci1394_statebit_tst(uint64_t state, uint_t statebit)
8310Sstevel@tonic-gate {
8320Sstevel@tonic-gate 	uint64_t bitset;
8330Sstevel@tonic-gate 	int status;
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 	ASSERT(statebit < 64);
8370Sstevel@tonic-gate 	bitset = state & ((uint64_t)0x1 << statebit);
8380Sstevel@tonic-gate 	if (bitset == 0) {
8390Sstevel@tonic-gate 		status = B_FALSE;
8400Sstevel@tonic-gate 	} else {
8410Sstevel@tonic-gate 		status = B_TRUE;
8420Sstevel@tonic-gate 	}
8430Sstevel@tonic-gate 	return (status);
8440Sstevel@tonic-gate }
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate /*
8480Sstevel@tonic-gate  * hci1394_cleanup()
8490Sstevel@tonic-gate  *    Cleanup after a failed attach
8500Sstevel@tonic-gate  */
8510Sstevel@tonic-gate static void
hci1394_cleanup(hci1394_state_t * soft_state,uint64_t attach_state)8520Sstevel@tonic-gate hci1394_cleanup(hci1394_state_t *soft_state, uint64_t attach_state)
8530Sstevel@tonic-gate {
8540Sstevel@tonic-gate 	int status;
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
8580Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_cleanup_enter, HCI1394_TNF_HAL_STACK, "");
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_STARTUP);
8620Sstevel@tonic-gate 	if (status == B_TRUE) {
8630Sstevel@tonic-gate 		/* Don't allow the HW to generate any more interrupts */
8640Sstevel@tonic-gate 		hci1394_ohci_intr_master_disable(soft_state->ohci);
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 		/* don't accept anymore commands from services layer */
8670Sstevel@tonic-gate 		(void) hci1394_state_set(&soft_state->drvinfo,
8680Sstevel@tonic-gate 		    HCI1394_SHUTDOWN);
8690Sstevel@tonic-gate 
8700Sstevel@tonic-gate 		/* Reset the chip */
8710Sstevel@tonic-gate 		(void) hci1394_ohci_soft_reset(soft_state->ohci);
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 		/* Flush out async DMA Q's (cancels pendingQ timeouts too) */
8740Sstevel@tonic-gate 		hci1394_async_flush(soft_state->async);
8750Sstevel@tonic-gate 	}
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_ISR_HANDLER);
8780Sstevel@tonic-gate 	if (status == B_TRUE) {
8790Sstevel@tonic-gate 		hci1394_isr_handler_fini(soft_state);
8800Sstevel@tonic-gate 	}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_H1394_ATTACH);
8830Sstevel@tonic-gate 	if (status == B_TRUE) {
8840Sstevel@tonic-gate 		(void) h1394_detach(&soft_state->drvinfo.di_sl_private,
8850Sstevel@tonic-gate 		    DDI_DETACH);
8860Sstevel@tonic-gate 	}
8870Sstevel@tonic-gate 
8880Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_HW_INIT);
8890Sstevel@tonic-gate 	if (status == B_TRUE) {
8900Sstevel@tonic-gate 		hci1394_detach_hardware(soft_state);
8910Sstevel@tonic-gate 	}
8920Sstevel@tonic-gate 
8930Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_MINOR_NODE);
8940Sstevel@tonic-gate 	if (status == B_TRUE) {
8950Sstevel@tonic-gate 		ddi_remove_minor_node(soft_state->drvinfo.di_dip, "devctl");
8960Sstevel@tonic-gate 	}
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_ISR_INIT);
8990Sstevel@tonic-gate 	if (status == B_TRUE) {
9000Sstevel@tonic-gate 		hci1394_isr_fini(soft_state);
9010Sstevel@tonic-gate 	}
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_PHASE2);
9040Sstevel@tonic-gate 	if (status == B_TRUE) {
9050Sstevel@tonic-gate 		hci1394_soft_state_fini(soft_state);
9060Sstevel@tonic-gate 	}
9070Sstevel@tonic-gate 
9080Sstevel@tonic-gate 	status = hci1394_statebit_tst(attach_state, STATE_ZALLOC);
9090Sstevel@tonic-gate 	if (status == B_TRUE) {
9100Sstevel@tonic-gate 		ddi_soft_state_free(hci1394_statep,
9110Sstevel@tonic-gate 		    soft_state->drvinfo.di_instance);
9120Sstevel@tonic-gate 	}
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_cleanup_exit, HCI1394_TNF_HAL_STACK, "");
9150Sstevel@tonic-gate }
916