xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_misc.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * hci1394_misc.c
31*0Sstevel@tonic-gate  *    Misc. HBA functions.  These include getinfo, open, close, shutdown, and
32*0Sstevel@tonic-gate  *    overall driver state control functions.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <sys/conf.h>
36*0Sstevel@tonic-gate #include <sys/ddi.h>
37*0Sstevel@tonic-gate #include <sys/modctl.h>
38*0Sstevel@tonic-gate #include <sys/sunddi.h>
39*0Sstevel@tonic-gate #include <sys/types.h>
40*0Sstevel@tonic-gate #include <sys/mkdev.h>
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
43*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate /* ARGSUSED */
48*0Sstevel@tonic-gate int
hci1394_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)49*0Sstevel@tonic-gate hci1394_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
50*0Sstevel@tonic-gate {
51*0Sstevel@tonic-gate 	dev_t dev;
52*0Sstevel@tonic-gate 	hci1394_state_t *soft_state;
53*0Sstevel@tonic-gate 	minor_t instance;
54*0Sstevel@tonic-gate 	int status;
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_getinfo_enter, HCI1394_TNF_HAL_STACK, "");
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	switch (cmd) {
60*0Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
61*0Sstevel@tonic-gate 		dev = (dev_t)arg;
62*0Sstevel@tonic-gate 		instance = getminor(dev);
63*0Sstevel@tonic-gate 		soft_state = ddi_get_soft_state(hci1394_statep, instance);
64*0Sstevel@tonic-gate 		if (soft_state == NULL) {
65*0Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_getinfo_gss_fail,
66*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
67*0Sstevel@tonic-gate 			    "ddi_get_soft_state() failed");
68*0Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_getinfo_exit,
69*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
70*0Sstevel@tonic-gate 			return (DDI_FAILURE);
71*0Sstevel@tonic-gate 		}
72*0Sstevel@tonic-gate 		*result = (void *)soft_state->drvinfo.di_dip;
73*0Sstevel@tonic-gate 		status = DDI_SUCCESS;
74*0Sstevel@tonic-gate 		break;
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
77*0Sstevel@tonic-gate 		dev = (dev_t)arg;
78*0Sstevel@tonic-gate 		instance = getminor(dev);
79*0Sstevel@tonic-gate 		*result = (void *)(uintptr_t)instance;
80*0Sstevel@tonic-gate 		status = DDI_SUCCESS;
81*0Sstevel@tonic-gate 		break;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 	default:
84*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_getinfo_def_fail, HCI1394_TNF_HAL_ERROR, "",
85*0Sstevel@tonic-gate 		    tnf_string, errmsg, "reached default in switch");
86*0Sstevel@tonic-gate 		status = DDI_FAILURE;
87*0Sstevel@tonic-gate 	}
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_getinfo_exit, HCI1394_TNF_HAL_STACK, "");
90*0Sstevel@tonic-gate 	return (status);
91*0Sstevel@tonic-gate }
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate /* ARGSUSED */
95*0Sstevel@tonic-gate int
hci1394_open(dev_t * devp,int flag,int otyp,cred_t * credp)96*0Sstevel@tonic-gate hci1394_open(dev_t *devp, int flag, int otyp, cred_t *credp)
97*0Sstevel@tonic-gate {
98*0Sstevel@tonic-gate 	hci1394_state_t *soft_state;
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_open_enter, HCI1394_TNF_HAL_STACK, "");
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	soft_state = ddi_get_soft_state(hci1394_statep, getminor(*devp));
104*0Sstevel@tonic-gate 	if (soft_state == NULL) {
105*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_open_gss_fail, HCI1394_TNF_HAL_ERROR, "",
106*0Sstevel@tonic-gate 		    tnf_string, errmsg, "ddi_get_soft_state() failed");
107*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_open_exit, HCI1394_TNF_HAL_STACK, "");
108*0Sstevel@tonic-gate 		return (ENXIO);
109*0Sstevel@tonic-gate 	}
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_open_exit, HCI1394_TNF_HAL_STACK, "");
112*0Sstevel@tonic-gate 	return (0);
113*0Sstevel@tonic-gate }
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate /* ARGSUSED */
117*0Sstevel@tonic-gate int
hci1394_close(dev_t dev,int flag,int otyp,cred_t * credp)118*0Sstevel@tonic-gate hci1394_close(dev_t dev, int flag, int otyp, cred_t *credp)
119*0Sstevel@tonic-gate {
120*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_close_enter, HCI1394_TNF_HAL_STACK, "");
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_close_exit, HCI1394_TNF_HAL_STACK, "");
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate 	return (0);
125*0Sstevel@tonic-gate }
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate /*
129*0Sstevel@tonic-gate  * hci1394_shutdown()
130*0Sstevel@tonic-gate  *    Shutdown the HW.  Something bad that we cannot recover from happened.
131*0Sstevel@tonic-gate  */
132*0Sstevel@tonic-gate void
hci1394_shutdown(dev_info_t * dip)133*0Sstevel@tonic-gate hci1394_shutdown(dev_info_t *dip)
134*0Sstevel@tonic-gate {
135*0Sstevel@tonic-gate 	hci1394_state_t *soft_state;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	/*
139*0Sstevel@tonic-gate 	 * In the debug version of the driver, we want to do an assert here so
140*0Sstevel@tonic-gate 	 * that we don't reset the hardware and can look and see what happened
141*0Sstevel@tonic-gate 	 * to cause the shutdown.
142*0Sstevel@tonic-gate 	 */
143*0Sstevel@tonic-gate #ifndef	TEST_SHUTDOWN
144*0Sstevel@tonic-gate 	ASSERT(0);
145*0Sstevel@tonic-gate #endif
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_shutdown_enter, HCI1394_TNF_HAL_STACK, "");
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate 	soft_state = ddi_get_soft_state(hci1394_statep, ddi_get_instance(dip));
150*0Sstevel@tonic-gate 	if (soft_state == NULL) {
151*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_shutdown_gss_fail, HCI1394_TNF_HAL_ERROR,
152*0Sstevel@tonic-gate 		    "", tnf_string, errmsg, "ddi_get_soft_state() failed");
153*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_shutdown_exit,
154*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
155*0Sstevel@tonic-gate 		return;
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	/*
159*0Sstevel@tonic-gate 	 * Don't allow the HW to generate any more interrupts. Make sure we
160*0Sstevel@tonic-gate 	 * disable interrupts before setting the driver state to shutdown.
161*0Sstevel@tonic-gate 	 */
162*0Sstevel@tonic-gate 	hci1394_ohci_intr_master_disable(soft_state->ohci);
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	/* don't accept anymore commands from services layer */
165*0Sstevel@tonic-gate 	(void) hci1394_state_set(&soft_state->drvinfo, HCI1394_SHUTDOWN);
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	/* Reset the OHCI HW */
168*0Sstevel@tonic-gate 	(void) hci1394_ohci_soft_reset(soft_state->ohci);
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	/* Flush out async DMA Q's (cancels pendingQ timeouts too) */
171*0Sstevel@tonic-gate 	hci1394_async_flush(soft_state->async);
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_shutdown_exit, HCI1394_TNF_HAL_STACK, "");
174*0Sstevel@tonic-gate }
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate /*
178*0Sstevel@tonic-gate  * hci1394_state()
179*0Sstevel@tonic-gate  *    returns the current state of the driver
180*0Sstevel@tonic-gate  */
181*0Sstevel@tonic-gate hci1394_statevar_t
hci1394_state(hci1394_drvinfo_t * drvinfo)182*0Sstevel@tonic-gate hci1394_state(hci1394_drvinfo_t *drvinfo)
183*0Sstevel@tonic-gate {
184*0Sstevel@tonic-gate 	hci1394_statevar_t hal_state;
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_state_enter, HCI1394_TNF_HAL_STACK, "");
187*0Sstevel@tonic-gate 	mutex_enter(&drvinfo->di_drvstate.ds_mutex);
188*0Sstevel@tonic-gate 	hal_state = drvinfo->di_drvstate.ds_state;
189*0Sstevel@tonic-gate 	mutex_exit(&drvinfo->di_drvstate.ds_mutex);
190*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_state_exit, HCI1394_TNF_HAL_STACK, "");
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 	return (hal_state);
193*0Sstevel@tonic-gate }
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate /*
197*0Sstevel@tonic-gate  * hci1394_state_set()
198*0Sstevel@tonic-gate  *    Set the current state of the driver. This routine will return failure
199*0Sstevel@tonic-gate  *    if the driver state is currently set to HCI1394_SHUTDOWN.  We do not
200*0Sstevel@tonic-gate  *    allow a transition out of shutdown.
201*0Sstevel@tonic-gate  */
202*0Sstevel@tonic-gate int
hci1394_state_set(hci1394_drvinfo_t * drvinfo,hci1394_statevar_t state)203*0Sstevel@tonic-gate hci1394_state_set(hci1394_drvinfo_t *drvinfo, hci1394_statevar_t state)
204*0Sstevel@tonic-gate {
205*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_state_set_enter, HCI1394_TNF_HAL_STACK, "");
206*0Sstevel@tonic-gate 	mutex_enter(&drvinfo->di_drvstate.ds_mutex);
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	/* Do not allow a transition out of shutdown */
209*0Sstevel@tonic-gate 	if (drvinfo->di_drvstate.ds_state == HCI1394_SHUTDOWN) {
210*0Sstevel@tonic-gate 		mutex_exit(&drvinfo->di_drvstate.ds_mutex);
211*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_state_set_fail, HCI1394_TNF_HAL_STACK, "",
212*0Sstevel@tonic-gate 		    tnf_string, errmsg, "driver shutdown");
213*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_state_set_exit, HCI1394_TNF_HAL_STACK,
214*0Sstevel@tonic-gate 		    "");
215*0Sstevel@tonic-gate 		return (DDI_FAILURE);
216*0Sstevel@tonic-gate 	}
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 	drvinfo->di_drvstate.ds_state = state;
219*0Sstevel@tonic-gate 	mutex_exit(&drvinfo->di_drvstate.ds_mutex);
220*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_state_set_exit, HCI1394_TNF_HAL_STACK, "");
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
223*0Sstevel@tonic-gate }
224