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
hci1394_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)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
hci1394_open(dev_t * devp,int flag,int otyp,cred_t * credp)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
hci1394_close(dev_t dev,int flag,int otyp,cred_t * credp)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
hci1394_shutdown(dev_info_t * dip)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
hci1394_state(hci1394_drvinfo_t * drvinfo)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
hci1394_state_set(hci1394_drvinfo_t * drvinfo,hci1394_statevar_t state)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