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