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 /*
28 * hci1394_misc.c
29 * Misc. HBA functions. These include getinfo, open, close, shutdown, and
30 * overall driver state control functions.
31 */
32
33 #include <sys/conf.h>
34 #include <sys/ddi.h>
35 #include <sys/modctl.h>
36 #include <sys/sunddi.h>
37 #include <sys/types.h>
38 #include <sys/mkdev.h>
39
40 #include <sys/1394/adapters/hci1394.h>
41 #include <sys/1394/adapters/hci1394_extern.h>
42
43
44
45 /* ARGSUSED */
46 int
hci1394_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)47 hci1394_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
48 {
49 dev_t dev;
50 hci1394_state_t *soft_state;
51 minor_t instance;
52 int status;
53
54 switch (cmd) {
55 case DDI_INFO_DEVT2DEVINFO:
56 dev = (dev_t)arg;
57 instance = getminor(dev);
58 soft_state = ddi_get_soft_state(hci1394_statep, instance);
59 if (soft_state == NULL) {
60 return (DDI_FAILURE);
61 }
62 *result = (void *)soft_state->drvinfo.di_dip;
63 status = DDI_SUCCESS;
64 break;
65
66 case DDI_INFO_DEVT2INSTANCE:
67 dev = (dev_t)arg;
68 instance = getminor(dev);
69 *result = (void *)(uintptr_t)instance;
70 status = DDI_SUCCESS;
71 break;
72
73 default:
74 status = DDI_FAILURE;
75 }
76
77 return (status);
78 }
79
80
81 /* ARGSUSED */
82 int
hci1394_open(dev_t * devp,int flag,int otyp,cred_t * credp)83 hci1394_open(dev_t *devp, int flag, int otyp, cred_t *credp)
84 {
85 hci1394_state_t *soft_state;
86
87 soft_state = ddi_get_soft_state(hci1394_statep, getminor(*devp));
88 if (soft_state == NULL) {
89 return (ENXIO);
90 }
91
92 return (0);
93 }
94
95
96 /* ARGSUSED */
97 int
hci1394_close(dev_t dev,int flag,int otyp,cred_t * credp)98 hci1394_close(dev_t dev, int flag, int otyp, cred_t *credp)
99 {
100 return (0);
101 }
102
103
104 /*
105 * hci1394_shutdown()
106 * Shutdown the HW. Something bad that we cannot recover from happened.
107 */
108 void
hci1394_shutdown(dev_info_t * dip)109 hci1394_shutdown(dev_info_t *dip)
110 {
111 hci1394_state_t *soft_state;
112
113
114 /*
115 * In the debug version of the driver, we want to do an assert here so
116 * that we don't reset the hardware and can look and see what happened
117 * to cause the shutdown.
118 */
119 #ifndef TEST_SHUTDOWN
120 ASSERT(0);
121 #endif
122
123 soft_state = ddi_get_soft_state(hci1394_statep, ddi_get_instance(dip));
124 if (soft_state == NULL) {
125 return;
126 }
127
128 /*
129 * Don't allow the HW to generate any more interrupts. Make sure we
130 * disable interrupts before setting the driver state to shutdown.
131 */
132 hci1394_ohci_intr_master_disable(soft_state->ohci);
133
134 /* don't accept anymore commands from services layer */
135 (void) hci1394_state_set(&soft_state->drvinfo, HCI1394_SHUTDOWN);
136
137 /* Reset the OHCI HW */
138 (void) hci1394_ohci_soft_reset(soft_state->ohci);
139
140 /* Flush out async DMA Q's (cancels pendingQ timeouts too) */
141 hci1394_async_flush(soft_state->async);
142 }
143
144
145 /*
146 * hci1394_state()
147 * returns the current state of the driver
148 */
149 hci1394_statevar_t
hci1394_state(hci1394_drvinfo_t * drvinfo)150 hci1394_state(hci1394_drvinfo_t *drvinfo)
151 {
152 hci1394_statevar_t hal_state;
153
154 mutex_enter(&drvinfo->di_drvstate.ds_mutex);
155 hal_state = drvinfo->di_drvstate.ds_state;
156 mutex_exit(&drvinfo->di_drvstate.ds_mutex);
157
158 return (hal_state);
159 }
160
161
162 /*
163 * hci1394_state_set()
164 * Set the current state of the driver. This routine will return failure
165 * if the driver state is currently set to HCI1394_SHUTDOWN. We do not
166 * allow a transition out of shutdown.
167 */
168 int
hci1394_state_set(hci1394_drvinfo_t * drvinfo,hci1394_statevar_t state)169 hci1394_state_set(hci1394_drvinfo_t *drvinfo, hci1394_statevar_t state)
170 {
171 mutex_enter(&drvinfo->di_drvstate.ds_mutex);
172
173 /* Do not allow a transition out of shutdown */
174 if (drvinfo->di_drvstate.ds_state == HCI1394_SHUTDOWN) {
175 mutex_exit(&drvinfo->di_drvstate.ds_mutex);
176 return (DDI_FAILURE);
177 }
178
179 drvinfo->di_drvstate.ds_state = state;
180 mutex_exit(&drvinfo->di_drvstate.ds_mutex);
181
182 return (DDI_SUCCESS);
183 }
184