xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_csr.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_csr.c
31*0Sstevel@tonic-gate  *    This code contains the code for the CSR registers handled by the HAL in
32*0Sstevel@tonic-gate  *    SW.  The HW implemented CSR registers are in hci1394_ohci.c
33*0Sstevel@tonic-gate  *
34*0Sstevel@tonic-gate  *   For more information on CSR registers, see
35*0Sstevel@tonic-gate  *	IEEE 1212
36*0Sstevel@tonic-gate  *	IEEE 1394-1995
37*0Sstevel@tonic-gate  *		section 8.3.2
38*0Sstevel@tonic-gate  *	IEEE P1394A Draft 3.0
39*0Sstevel@tonic-gate  *		sections 10.32,10.33
40*0Sstevel@tonic-gate  *
41*0Sstevel@tonic-gate  * NOTE: A read/write to a CSR SW based register will first go to the Services
42*0Sstevel@tonic-gate  *    Layer which will do some filtering and then come through the s1394if. Look
43*0Sstevel@tonic-gate  *    in hci1394_s1394if.c to see which registers are implemented in HW and
44*0Sstevel@tonic-gate  *    which are implemented in SW.
45*0Sstevel@tonic-gate  */
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #include <sys/conf.h>
48*0Sstevel@tonic-gate #include <sys/ddi.h>
49*0Sstevel@tonic-gate #include <sys/modctl.h>
50*0Sstevel@tonic-gate #include <sys/stat.h>
51*0Sstevel@tonic-gate #include <sys/sunddi.h>
52*0Sstevel@tonic-gate #include <sys/cmn_err.h>
53*0Sstevel@tonic-gate #include <sys/kmem.h>
54*0Sstevel@tonic-gate #include <sys/types.h>
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
57*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate /*
61*0Sstevel@tonic-gate  * The split_timeout_lo register cannot be set below 800 and above 7999.  The
62*0Sstevel@tonic-gate  * split_timeout_hi register cannot be set above 7.
63*0Sstevel@tonic-gate  */
64*0Sstevel@tonic-gate #define	CSR_MIN_SPLIT_TIMEOUT_LO	800
65*0Sstevel@tonic-gate #define	CSR_MAX_SPLIT_TIMEOUT_LO	7999
66*0Sstevel@tonic-gate #define	CSR_MAX_SPLIT_TIMEOUT_HI	7
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate /*
69*0Sstevel@tonic-gate  * We will convert the split_timeout_lo to return the data in most significant
70*0Sstevel@tonic-gate  * 13 bits on the fly.
71*0Sstevel@tonic-gate  */
72*0Sstevel@tonic-gate #define	CSR_SPLIT_TIMEOUT_LO_SHIFT	19
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate /*
75*0Sstevel@tonic-gate  * This is what we report to the services layer as our node capabilities.
76*0Sstevel@tonic-gate  * See IEEE 1212_1994, section 8.4.11
77*0Sstevel@tonic-gate  *
78*0Sstevel@tonic-gate  * Split Timeout Registers are implemented (bit 15)
79*0Sstevel@tonic-gate  * This node uses 64-bit addressing (bit 9)
80*0Sstevel@tonic-gate  * This node uses fixed addressing scheme (bit 8)
81*0Sstevel@tonic-gate  * STATE_BITS.lost is implemented
82*0Sstevel@tonic-gate  * STATE_BITS.dreq is implemented
83*0Sstevel@tonic-gate  */
84*0Sstevel@tonic-gate #define	CSR_INITIAL_NODE_CAPABILITIES	0x000083C0
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate /*
87*0Sstevel@tonic-gate  * macro to calculate split_timeout based on split_timeout_lo and
88*0Sstevel@tonic-gate  * split_timeout_hi
89*0Sstevel@tonic-gate  */
90*0Sstevel@tonic-gate #define	CSR_SPLIT_TIMEOUT(split_hi, split_lo) \
91*0Sstevel@tonic-gate 	((split_hi * IEEE1394_BUS_CYCLES_PER_SEC) + split_lo)
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate static void hci1394_csr_state_init(hci1394_csr_t *csr);
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate /*
98*0Sstevel@tonic-gate  * hci1394_csr_init()
99*0Sstevel@tonic-gate  *    Initialize CSR state and CSR SW based registers.
100*0Sstevel@tonic-gate  */
101*0Sstevel@tonic-gate void
hci1394_csr_init(hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t ohci,hci1394_csr_handle_t * csr_handle)102*0Sstevel@tonic-gate hci1394_csr_init(hci1394_drvinfo_t *drvinfo, hci1394_ohci_handle_t ohci,
103*0Sstevel@tonic-gate     hci1394_csr_handle_t *csr_handle)
104*0Sstevel@tonic-gate {
105*0Sstevel@tonic-gate 	hci1394_csr_t *csr;
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	ASSERT(drvinfo != NULL);
109*0Sstevel@tonic-gate 	ASSERT(ohci != NULL);
110*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
111*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_init_enter, HCI1394_TNF_HAL_STACK, "");
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 	/* alloc the space to keep track of the csr registers */
114*0Sstevel@tonic-gate 	csr = kmem_alloc(sizeof (hci1394_csr_t), KM_SLEEP);
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	/* setup the return parameter */
117*0Sstevel@tonic-gate 	*csr_handle = csr;
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate 	/* Initialize the csr structure */
120*0Sstevel@tonic-gate 	csr->csr_drvinfo = drvinfo;
121*0Sstevel@tonic-gate 	csr->csr_ohci = ohci;
122*0Sstevel@tonic-gate 	mutex_init(&csr->csr_mutex, NULL, MUTEX_DRIVER,
123*0Sstevel@tonic-gate 	    drvinfo->di_iblock_cookie);
124*0Sstevel@tonic-gate 	hci1394_csr_state_init(csr);
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_init_exit, HCI1394_TNF_HAL_STACK, "");
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate /*
131*0Sstevel@tonic-gate  * hci1394_csr_fini()
132*0Sstevel@tonic-gate  *    Free up any space allocated and any mutexes used.
133*0Sstevel@tonic-gate  */
134*0Sstevel@tonic-gate void
hci1394_csr_fini(hci1394_csr_handle_t * csr_handle)135*0Sstevel@tonic-gate hci1394_csr_fini(hci1394_csr_handle_t *csr_handle)
136*0Sstevel@tonic-gate {
137*0Sstevel@tonic-gate 	hci1394_csr_t *csr;
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
141*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_fini_enter, HCI1394_TNF_HAL_STACK, "");
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate 	csr = (hci1394_csr_t *)*csr_handle;
144*0Sstevel@tonic-gate 	mutex_destroy(&csr->csr_mutex);
145*0Sstevel@tonic-gate 	kmem_free(csr, sizeof (hci1394_csr_t));
146*0Sstevel@tonic-gate 	*csr_handle = NULL;
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_fini_exit, HCI1394_TNF_HAL_STACK, "");
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate /*
153*0Sstevel@tonic-gate  * hci1394_csr_resume()
154*0Sstevel@tonic-gate  *    When resuming power on a workstation, re-setup our CSR registers.
155*0Sstevel@tonic-gate  */
156*0Sstevel@tonic-gate void
hci1394_csr_resume(hci1394_csr_handle_t csr_handle)157*0Sstevel@tonic-gate hci1394_csr_resume(hci1394_csr_handle_t csr_handle)
158*0Sstevel@tonic-gate {
159*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
160*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_resume_enter, HCI1394_TNF_HAL_STACK, "");
161*0Sstevel@tonic-gate 	hci1394_csr_state_init(csr_handle);
162*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_resume_exit, HCI1394_TNF_HAL_STACK, "");
163*0Sstevel@tonic-gate }
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate /*
167*0Sstevel@tonic-gate  * hci1394_csr_node_capabilities()
168*0Sstevel@tonic-gate  *    Return the CSR node capabilities.
169*0Sstevel@tonic-gate  */
170*0Sstevel@tonic-gate void
hci1394_csr_node_capabilities(hci1394_csr_handle_t csr_handle,uint32_t * capabilities)171*0Sstevel@tonic-gate hci1394_csr_node_capabilities(hci1394_csr_handle_t csr_handle,
172*0Sstevel@tonic-gate     uint32_t *capabilities)
173*0Sstevel@tonic-gate {
174*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
175*0Sstevel@tonic-gate 	ASSERT(capabilities != NULL);
176*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_node_capabilities_enter,
177*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
180*0Sstevel@tonic-gate 	*capabilities = csr_handle->csr_capabilities;
181*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_node_capabilities_exit,
184*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate /*
189*0Sstevel@tonic-gate  * hci1394_csr_state_get()
190*0Sstevel@tonic-gate  *    Read the CSR state register. Currently we only support the dreq, cmstr,
191*0Sstevel@tonic-gate  *    and abdicate bits in the CSR state register.  See the specs mentioned
192*0Sstevel@tonic-gate  *    above for the behavior of these bits.
193*0Sstevel@tonic-gate  */
194*0Sstevel@tonic-gate void
hci1394_csr_state_get(hci1394_csr_handle_t csr_handle,uint32_t * state)195*0Sstevel@tonic-gate hci1394_csr_state_get(hci1394_csr_handle_t csr_handle, uint32_t *state)
196*0Sstevel@tonic-gate {
197*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
198*0Sstevel@tonic-gate 	ASSERT(state != NULL);
199*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_get_enter, HCI1394_TNF_HAL_STACK,
200*0Sstevel@tonic-gate 	    "");
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
203*0Sstevel@tonic-gate 	*state = csr_handle->csr_state;
204*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_get_exit, HCI1394_TNF_HAL_STACK,
207*0Sstevel@tonic-gate 	    "");
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate /*
212*0Sstevel@tonic-gate  * hci1394_csr_state_bset()
213*0Sstevel@tonic-gate  *    Perform a bit set on the CSR state register.  The value of state will be
214*0Sstevel@tonic-gate  *    or'd with the CSR state register. Currently we only support the dreq,
215*0Sstevel@tonic-gate  *    cmstr, and abdicate bits in the CSR state register.  See the specs
216*0Sstevel@tonic-gate  *    mentioned above for the behavior of these bits.
217*0Sstevel@tonic-gate  */
218*0Sstevel@tonic-gate void
hci1394_csr_state_bset(hci1394_csr_handle_t csr_handle,uint32_t state)219*0Sstevel@tonic-gate hci1394_csr_state_bset(hci1394_csr_handle_t csr_handle, uint32_t state)
220*0Sstevel@tonic-gate {
221*0Sstevel@tonic-gate 	uint32_t supported_state;
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
225*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_bset_enter, HCI1394_TNF_HAL_STACK,
226*0Sstevel@tonic-gate 	    "");
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate 	/* only support dreq, cmstr, and abdicate bits */
231*0Sstevel@tonic-gate 	supported_state = state & (IEEE1394_CSR_STATE_ABDICATE |
232*0Sstevel@tonic-gate 	    IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ);
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 	/*
235*0Sstevel@tonic-gate 	 * If we are setting the Cycle Master bit and we are the root node,
236*0Sstevel@tonic-gate 	 * enable Cycle Start Packets.
237*0Sstevel@tonic-gate 	 */
238*0Sstevel@tonic-gate 	if ((supported_state & IEEE1394_CSR_STATE_CMSTR) &&
239*0Sstevel@tonic-gate 	    (hci1394_ohci_root_check(csr_handle->csr_ohci))) {
240*0Sstevel@tonic-gate 		hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci);
241*0Sstevel@tonic-gate 	}
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate 	/* set the supported bits in csr_state */
244*0Sstevel@tonic-gate 	csr_handle->csr_state |= supported_state;
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_bset_exit, HCI1394_TNF_HAL_STACK,
249*0Sstevel@tonic-gate 	    "");
250*0Sstevel@tonic-gate }
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate /*
254*0Sstevel@tonic-gate  * hci1394_csr_state_bclr()
255*0Sstevel@tonic-gate  *     Perform a bit clear on the CSR state register. The inverted value of
256*0Sstevel@tonic-gate  *     state will be and'd with CSR state register. Currently we only support
257*0Sstevel@tonic-gate  *     the dreq, cmstr, and abdicate bits in the CSR state register.  See the
258*0Sstevel@tonic-gate  *     specs mentioned above for the behavior of these bits.
259*0Sstevel@tonic-gate  */
260*0Sstevel@tonic-gate void
hci1394_csr_state_bclr(hci1394_csr_handle_t csr_handle,uint32_t state)261*0Sstevel@tonic-gate hci1394_csr_state_bclr(hci1394_csr_handle_t csr_handle, uint32_t state)
262*0Sstevel@tonic-gate {
263*0Sstevel@tonic-gate 	uint32_t supported_state;
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
267*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_bclr_enter, HCI1394_TNF_HAL_STACK,
268*0Sstevel@tonic-gate 	    "");
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 	/* only support dreq, cmstr, and abdicate bits */
273*0Sstevel@tonic-gate 	supported_state = state & (IEEE1394_CSR_STATE_ABDICATE |
274*0Sstevel@tonic-gate 	    IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ);
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	/*
277*0Sstevel@tonic-gate 	 * If we are clearing the Cycle Master bit and we are the root node,
278*0Sstevel@tonic-gate 	 * disable Cycle Start Packets.
279*0Sstevel@tonic-gate 	 */
280*0Sstevel@tonic-gate 	if ((supported_state & IEEE1394_CSR_STATE_CMSTR) &&
281*0Sstevel@tonic-gate 	    (hci1394_ohci_root_check(csr_handle->csr_ohci))) {
282*0Sstevel@tonic-gate 		hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci);
283*0Sstevel@tonic-gate 	}
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	/* Clear the supported bits in csr_state */
286*0Sstevel@tonic-gate 	csr_handle->csr_state &= ~state;
287*0Sstevel@tonic-gate 
288*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_bclr_exit, HCI1394_TNF_HAL_STACK,
291*0Sstevel@tonic-gate 	    "");
292*0Sstevel@tonic-gate }
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate /*
296*0Sstevel@tonic-gate  * hci1394_csr_split_timeout_hi_get()
297*0Sstevel@tonic-gate  *    Read the CSR split_timeout_hi register.
298*0Sstevel@tonic-gate  */
299*0Sstevel@tonic-gate void
hci1394_csr_split_timeout_hi_get(hci1394_csr_handle_t csr_handle,uint32_t * split_timeout_hi)300*0Sstevel@tonic-gate hci1394_csr_split_timeout_hi_get(hci1394_csr_handle_t csr_handle,
301*0Sstevel@tonic-gate     uint32_t *split_timeout_hi)
302*0Sstevel@tonic-gate {
303*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
304*0Sstevel@tonic-gate 	ASSERT(split_timeout_hi != NULL);
305*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_hi_get_enter,
306*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
309*0Sstevel@tonic-gate 	*split_timeout_hi = csr_handle->csr_split_timeout_hi;
310*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_hi_get_exit,
313*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate }
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate /*
319*0Sstevel@tonic-gate  * hci1394_csr_split_timeout_lo_get()
320*0Sstevel@tonic-gate  *    Read the CSR split_timeout_lo register.
321*0Sstevel@tonic-gate  */
322*0Sstevel@tonic-gate void
hci1394_csr_split_timeout_lo_get(hci1394_csr_handle_t csr_handle,uint32_t * split_timeout_lo)323*0Sstevel@tonic-gate hci1394_csr_split_timeout_lo_get(hci1394_csr_handle_t csr_handle,
324*0Sstevel@tonic-gate     uint32_t *split_timeout_lo)
325*0Sstevel@tonic-gate {
326*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
327*0Sstevel@tonic-gate 	ASSERT(split_timeout_lo != NULL);
328*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_lo_get_enter,
329*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	/*
334*0Sstevel@tonic-gate 	 * Read the split_timeout_lo CSR register. Convert split_timeout_lo to
335*0Sstevel@tonic-gate 	 * use the data in most significant 13 bits on the fly.
336*0Sstevel@tonic-gate 	 */
337*0Sstevel@tonic-gate 	*split_timeout_lo = csr_handle->csr_split_timeout_lo <<
338*0Sstevel@tonic-gate 	    CSR_SPLIT_TIMEOUT_LO_SHIFT;
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_lo_get_exit,
343*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 
348*0Sstevel@tonic-gate /*
349*0Sstevel@tonic-gate  * hci1394_csr_split_timeout_hi_set()
350*0Sstevel@tonic-gate  *    Write the CSR split_timeout_hi register. This routine will also
351*0Sstevel@tonic-gate  *    re-calculate the "split_timeout" which is used internally in the HAL
352*0Sstevel@tonic-gate  *    driver. The only accesses to split_timeout_hi and split_timeout_lo
353*0Sstevel@tonic-gate  *    should be over the 1394 bus. Only the least significant 3 bits are
354*0Sstevel@tonic-gate  *    relevant in the split_timeout_hi register.
355*0Sstevel@tonic-gate  */
356*0Sstevel@tonic-gate void
hci1394_csr_split_timeout_hi_set(hci1394_csr_handle_t csr_handle,uint32_t split_timeout_hi)357*0Sstevel@tonic-gate hci1394_csr_split_timeout_hi_set(hci1394_csr_handle_t csr_handle,
358*0Sstevel@tonic-gate     uint32_t split_timeout_hi)
359*0Sstevel@tonic-gate {
360*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
361*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_hi_set_enter,
362*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	/*
367*0Sstevel@tonic-gate 	 * update the split_timeout_hi CSR register. Only look at the 3 LSBits.
368*0Sstevel@tonic-gate 	 * Update our internal split_timeout value.
369*0Sstevel@tonic-gate 	 */
370*0Sstevel@tonic-gate 	csr_handle->csr_split_timeout_hi = split_timeout_hi &
371*0Sstevel@tonic-gate 	    CSR_MAX_SPLIT_TIMEOUT_HI;
372*0Sstevel@tonic-gate 	csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT(
373*0Sstevel@tonic-gate 	    csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo);
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_hi_set_exit,
378*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate /*
383*0Sstevel@tonic-gate  * hci1394_csr_split_timeout_lo_set()
384*0Sstevel@tonic-gate  *    Write the CSR split_timeout_lo register. This routine will also
385*0Sstevel@tonic-gate  *    re-calculate the "split_timeout" which is used internally in the HAL
386*0Sstevel@tonic-gate  *    driver. The only accesses to split_timeout_hi and split_timeout_lo
387*0Sstevel@tonic-gate  *    should be over the 1394 bus. Only the most significant 13 bits are
388*0Sstevel@tonic-gate  *    relevant in the split_timeout_lo register.
389*0Sstevel@tonic-gate  */
390*0Sstevel@tonic-gate void
hci1394_csr_split_timeout_lo_set(hci1394_csr_handle_t csr_handle,uint32_t split_timeout_lo)391*0Sstevel@tonic-gate hci1394_csr_split_timeout_lo_set(hci1394_csr_handle_t csr_handle,
392*0Sstevel@tonic-gate     uint32_t split_timeout_lo)
393*0Sstevel@tonic-gate {
394*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
395*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_lo_set_enter,
396*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
397*0Sstevel@tonic-gate 
398*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate 	/*
401*0Sstevel@tonic-gate 	 * Update the split_timeout_lo CSR register.  Only look at the 3 LSBits.
402*0Sstevel@tonic-gate 	 * Convert the split_timeout_lo to use the data in most significant 13
403*0Sstevel@tonic-gate 	 * bits on the fly.
404*0Sstevel@tonic-gate 	 */
405*0Sstevel@tonic-gate 	csr_handle->csr_split_timeout_lo = split_timeout_lo >>
406*0Sstevel@tonic-gate 	    CSR_SPLIT_TIMEOUT_LO_SHIFT;
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate 	/* threshold the split_timeout_lo value */
409*0Sstevel@tonic-gate 	if (csr_handle->csr_split_timeout_lo < CSR_MIN_SPLIT_TIMEOUT_LO) {
410*0Sstevel@tonic-gate 		csr_handle->csr_split_timeout_lo = CSR_MIN_SPLIT_TIMEOUT_LO;
411*0Sstevel@tonic-gate 	} else if (csr_handle->csr_split_timeout_lo >
412*0Sstevel@tonic-gate 	    CSR_MAX_SPLIT_TIMEOUT_LO) {
413*0Sstevel@tonic-gate 		csr_handle->csr_split_timeout_lo = CSR_MAX_SPLIT_TIMEOUT_LO;
414*0Sstevel@tonic-gate 	}
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate 	/* Update our internal split_timeout value */
417*0Sstevel@tonic-gate 	csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT(
418*0Sstevel@tonic-gate 	    csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo);
419*0Sstevel@tonic-gate 
420*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
421*0Sstevel@tonic-gate 
422*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_lo_set_exit,
423*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
424*0Sstevel@tonic-gate }
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate /*
428*0Sstevel@tonic-gate  * hci1394_csr_split_timeout_get()
429*0Sstevel@tonic-gate  *    Return the current value of split_timeout.  This is the  only routine
430*0Sstevel@tonic-gate  *    which should be used to get the split timeout for use in a calculation
431*0Sstevel@tonic-gate  *    (e.g. for calculating ACK pending timeout).
432*0Sstevel@tonic-gate  */
433*0Sstevel@tonic-gate uint_t
hci1394_csr_split_timeout_get(hci1394_csr_handle_t csr_handle)434*0Sstevel@tonic-gate hci1394_csr_split_timeout_get(hci1394_csr_handle_t csr_handle)
435*0Sstevel@tonic-gate {
436*0Sstevel@tonic-gate 	uint_t split_timeout;
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
440*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_get_enter,
441*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
442*0Sstevel@tonic-gate 
443*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate 	/* read our internal split_timeout value */
446*0Sstevel@tonic-gate 	split_timeout = csr_handle->csr_split_timeout;
447*0Sstevel@tonic-gate 
448*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
449*0Sstevel@tonic-gate 
450*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_split_timeout_get_exit,
451*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
452*0Sstevel@tonic-gate 
453*0Sstevel@tonic-gate 	return (split_timeout);
454*0Sstevel@tonic-gate }
455*0Sstevel@tonic-gate 
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate /*
458*0Sstevel@tonic-gate  * hci1394_csr_bus_reset()
459*0Sstevel@tonic-gate  *    Perform required bus reset processing on CSR registers. This includes
460*0Sstevel@tonic-gate  *    clearing the abdicate bit, and setting/clearing the Cycle Master bit.
461*0Sstevel@tonic-gate  *    See sections 10.32 and 10.33 in the IEEE P1394A Draft 3.0 spec.  See
462*0Sstevel@tonic-gate  *    section 8.3.2.2.1 in the IEEE 1394-1995 spec. This routine should be
463*0Sstevel@tonic-gate  *    called every bus reset.
464*0Sstevel@tonic-gate  */
465*0Sstevel@tonic-gate void
hci1394_csr_bus_reset(hci1394_csr_handle_t csr_handle)466*0Sstevel@tonic-gate hci1394_csr_bus_reset(hci1394_csr_handle_t csr_handle)
467*0Sstevel@tonic-gate {
468*0Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
469*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_bus_reset_enter, HCI1394_TNF_HAL_STACK,
470*0Sstevel@tonic-gate 	    "");
471*0Sstevel@tonic-gate 
472*0Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
473*0Sstevel@tonic-gate 
474*0Sstevel@tonic-gate 	/* Clear the abdicate bit.  Always do this. */
475*0Sstevel@tonic-gate 	csr_handle->csr_state &= ~IEEE1394_CSR_STATE_ABDICATE;
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate 	/* if we are NOT currently the root node on the bus */
478*0Sstevel@tonic-gate 	if (hci1394_ohci_root_check(csr_handle->csr_ohci) == B_FALSE) {
479*0Sstevel@tonic-gate 		/*
480*0Sstevel@tonic-gate 		 * Set the was_root state.  This is needed for the Cycle Master
481*0Sstevel@tonic-gate 		 * state machine below.
482*0Sstevel@tonic-gate 		 */
483*0Sstevel@tonic-gate 		csr_handle->csr_was_root = B_FALSE;
484*0Sstevel@tonic-gate 
485*0Sstevel@tonic-gate 		/*
486*0Sstevel@tonic-gate 		 * Clear the Cycle Master bit.  We do not have to shut off cycle
487*0Sstevel@tonic-gate 		 * master in OpenHCI.  The HW will automatically stop generating
488*0Sstevel@tonic-gate 		 * Cycle Start packets when it is not the root node.
489*0Sstevel@tonic-gate 		 */
490*0Sstevel@tonic-gate 		csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR;
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate 	/*
493*0Sstevel@tonic-gate 	 * if we are currently the root node on the bus and we were NOT
494*0Sstevel@tonic-gate 	 * the root before the reset.
495*0Sstevel@tonic-gate 	 */
496*0Sstevel@tonic-gate 	} else if (csr_handle->csr_was_root == B_FALSE) {
497*0Sstevel@tonic-gate 
498*0Sstevel@tonic-gate 		/* set the was_root state to TRUE */
499*0Sstevel@tonic-gate 		csr_handle->csr_was_root = B_TRUE;
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate 		/*
502*0Sstevel@tonic-gate 		 * if we are cycle master capable, set the Cycle Master bit and
503*0Sstevel@tonic-gate 		 * start Cycle Start packets. We should always be Cycle Master
504*0Sstevel@tonic-gate 		 * capable.
505*0Sstevel@tonic-gate 		 */
506*0Sstevel@tonic-gate 		if (hci1394_ohci_cmc_check(csr_handle->csr_ohci)) {
507*0Sstevel@tonic-gate 			csr_handle->csr_state |= IEEE1394_CSR_STATE_CMSTR;
508*0Sstevel@tonic-gate 			hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci);
509*0Sstevel@tonic-gate 
510*0Sstevel@tonic-gate 		/*
511*0Sstevel@tonic-gate 		 * if we are NOT cycle master capable, clear the Cycle Master
512*0Sstevel@tonic-gate 		 * bit and stop Cycle Start packets. We should never see this
513*0Sstevel@tonic-gate 		 * in OpenHCI. I think? :-)
514*0Sstevel@tonic-gate 		 */
515*0Sstevel@tonic-gate 		} else {
516*0Sstevel@tonic-gate 			csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR;
517*0Sstevel@tonic-gate 			hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci);
518*0Sstevel@tonic-gate 		}
519*0Sstevel@tonic-gate 	}
520*0Sstevel@tonic-gate 	/*
521*0Sstevel@tonic-gate 	 * else {}
522*0Sstevel@tonic-gate 	 * else we are root now. We were root before, keep cmstr the same.
523*0Sstevel@tonic-gate 	 * Nothing to do.
524*0Sstevel@tonic-gate 	 */
525*0Sstevel@tonic-gate 
526*0Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_bus_reset_exit, HCI1394_TNF_HAL_STACK,
529*0Sstevel@tonic-gate 	    "");
530*0Sstevel@tonic-gate }
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate /*
534*0Sstevel@tonic-gate  * hci1394_csr_state_init()
535*0Sstevel@tonic-gate  *    set the CSR SW registers and state variables to their initial settings.
536*0Sstevel@tonic-gate  */
hci1394_csr_state_init(hci1394_csr_t * csr)537*0Sstevel@tonic-gate static void hci1394_csr_state_init(hci1394_csr_t *csr)
538*0Sstevel@tonic-gate {
539*0Sstevel@tonic-gate 	ASSERT(csr != NULL);
540*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_init_enter, HCI1394_TNF_HAL_STACK,
541*0Sstevel@tonic-gate 	    "");
542*0Sstevel@tonic-gate 
543*0Sstevel@tonic-gate 	mutex_enter(&csr->csr_mutex);
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate 	/*
546*0Sstevel@tonic-gate 	 * Initialize the split timeout to be 0 seconds (split_timeout_hi) and
547*0Sstevel@tonic-gate 	 * use a patchable variable for the initial split_timeout_lo. This
548*0Sstevel@tonic-gate 	 * variable must be patched before the driver attaches.  It is never
549*0Sstevel@tonic-gate 	 * looked at again after this code is run.
550*0Sstevel@tonic-gate 	 *
551*0Sstevel@tonic-gate 	 * Calculate the split_timeout which we will use in the driver based on
552*0Sstevel@tonic-gate 	 * split_timeout_lo and split_timeout_hi.
553*0Sstevel@tonic-gate 	 */
554*0Sstevel@tonic-gate 	csr->csr_split_timeout_hi = 0;
555*0Sstevel@tonic-gate 	csr->csr_split_timeout_lo = hci1394_split_timeout;
556*0Sstevel@tonic-gate 	csr->csr_split_timeout = CSR_SPLIT_TIMEOUT(
557*0Sstevel@tonic-gate 	    csr->csr_split_timeout_hi, csr->csr_split_timeout_lo);
558*0Sstevel@tonic-gate 
559*0Sstevel@tonic-gate 	/* Set the initial CSR State register to 0 */
560*0Sstevel@tonic-gate 	csr->csr_state = 0;
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate 	/*
563*0Sstevel@tonic-gate 	 * was_root is an internal state variable which tracks if we were root
564*0Sstevel@tonic-gate 	 * last bus reset.  This is needed for the required state register bus
565*0Sstevel@tonic-gate 	 * reset processing.
566*0Sstevel@tonic-gate 	 */
567*0Sstevel@tonic-gate 	csr->csr_was_root = B_FALSE;
568*0Sstevel@tonic-gate 
569*0Sstevel@tonic-gate 	/* setup our initial capabilities setting */
570*0Sstevel@tonic-gate 	csr->csr_capabilities = CSR_INITIAL_NODE_CAPABILITIES;
571*0Sstevel@tonic-gate 
572*0Sstevel@tonic-gate 	mutex_exit(&csr->csr_mutex);
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_csr_state_init_exit, HCI1394_TNF_HAL_STACK,
575*0Sstevel@tonic-gate 	    "");
576*0Sstevel@tonic-gate }
577