xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_ioctl.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 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
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_ioctl.c
31*0Sstevel@tonic-gate  *   Test ioctl's to support test/debug of the 1394 HW. hci1394_ioctl_enum_t is
32*0Sstevel@tonic-gate  *   passed in cmd and a pointer to the appropriate structure (i.e.
33*0Sstevel@tonic-gate  *   hci1394_ioctl_wrreg_t) is passed in arg.
34*0Sstevel@tonic-gate  */
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #include <sys/conf.h>
37*0Sstevel@tonic-gate #include <sys/modctl.h>
38*0Sstevel@tonic-gate #include <sys/mkdev.h>
39*0Sstevel@tonic-gate #include <sys/cred.h>
40*0Sstevel@tonic-gate #include <sys/file.h>
41*0Sstevel@tonic-gate #include <sys/types.h>
42*0Sstevel@tonic-gate #include <sys/errno.h>
43*0Sstevel@tonic-gate #include <sys/ddi.h>
44*0Sstevel@tonic-gate #include <sys/sunddi.h>
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate #include <sys/1394/h1394.h>
47*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
48*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
49*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_ioctl.h>
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate /* HCI1394_IOCTL_READ_SELFID for 32-bit apps in 64-bit kernel */
53*0Sstevel@tonic-gate typedef struct hci1394_ioctl_readselfid32_s {
54*0Sstevel@tonic-gate 	uint32_t buf;
55*0Sstevel@tonic-gate 	uint_t count;
56*0Sstevel@tonic-gate } hci1394_ioctl_readselfid32_t;
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate static int hci1394_ioctl_wrreg(hci1394_state_t *soft_state, void *arg,
60*0Sstevel@tonic-gate     int mode);
61*0Sstevel@tonic-gate static int hci1394_ioctl_rdreg(hci1394_state_t *soft_state, void *arg,
62*0Sstevel@tonic-gate     int mode);
63*0Sstevel@tonic-gate static int hci1394_ioctl_wrvreg(hci1394_state_t *soft_state, void *arg,
64*0Sstevel@tonic-gate     int mode);
65*0Sstevel@tonic-gate static int hci1394_ioctl_rdvreg(hci1394_state_t *soft_state, void *arg,
66*0Sstevel@tonic-gate     int mode);
67*0Sstevel@tonic-gate static int hci1394_ioctl_selfid_cnt(hci1394_state_t *soft_state, void *arg,
68*0Sstevel@tonic-gate     int mode);
69*0Sstevel@tonic-gate static int hci1394_ioctl_busgen_cnt(hci1394_state_t *soft_state, void *arg,
70*0Sstevel@tonic-gate     int mode);
71*0Sstevel@tonic-gate static int hci1394_ioctl_wrphy(hci1394_state_t *soft_state, void *arg,
72*0Sstevel@tonic-gate     int mode);
73*0Sstevel@tonic-gate static int hci1394_ioctl_rdphy(hci1394_state_t *soft_state, void *arg,
74*0Sstevel@tonic-gate     int mode);
75*0Sstevel@tonic-gate static int hci1394_ioctl_hbainfo(hci1394_state_t *soft_state, void *arg,
76*0Sstevel@tonic-gate     int mode);
77*0Sstevel@tonic-gate static int hci1394_ioctl_read_selfid(hci1394_state_t *soft_state, void *arg,
78*0Sstevel@tonic-gate     int mode);
79*0Sstevel@tonic-gate #ifdef	_MULTI_DATAMODEL
80*0Sstevel@tonic-gate static int hci1394_ioctl_read_selfid32(hci1394_state_t *soft_state,
81*0Sstevel@tonic-gate     hci1394_ioctl_readselfid32_t *read_selfid, int mode);
82*0Sstevel@tonic-gate #endif
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate /* ARGSUSED */
86*0Sstevel@tonic-gate int
hci1394_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)87*0Sstevel@tonic-gate hci1394_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
88*0Sstevel@tonic-gate     int *rvalp)
89*0Sstevel@tonic-gate {
90*0Sstevel@tonic-gate 	hci1394_state_t *soft_state;
91*0Sstevel@tonic-gate 	int instance;
92*0Sstevel@tonic-gate 	int status;
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_enter, HCI1394_TNF_HAL_STACK, "");
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	instance = getminor(dev);
98*0Sstevel@tonic-gate 	if (instance == -1) {
99*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_gm_fail, HCI1394_TNF_HAL_ERROR, "");
100*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_exit, HCI1394_TNF_HAL_STACK,
101*0Sstevel@tonic-gate 		    "");
102*0Sstevel@tonic-gate 		return (EBADF);
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	soft_state = ddi_get_soft_state(hci1394_statep, instance);
106*0Sstevel@tonic-gate 	if (soft_state == NULL) {
107*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_gss_fail, HCI1394_TNF_HAL_ERROR, "");
108*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_exit, HCI1394_TNF_HAL_STACK,
109*0Sstevel@tonic-gate 		    "");
110*0Sstevel@tonic-gate 		return (EBADF);
111*0Sstevel@tonic-gate 	}
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 	status = 0;
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	switch (cmd) {
116*0Sstevel@tonic-gate 	case HCI1394_IOCTL_WRITE_REG:
117*0Sstevel@tonic-gate 		status = hci1394_ioctl_wrreg(soft_state, (void *)arg, mode);
118*0Sstevel@tonic-gate 		break;
119*0Sstevel@tonic-gate 	case HCI1394_IOCTL_READ_REG:
120*0Sstevel@tonic-gate 		status = hci1394_ioctl_rdreg(soft_state, (void *)arg, mode);
121*0Sstevel@tonic-gate 		break;
122*0Sstevel@tonic-gate 	case HCI1394_IOCTL_READ_VREG:
123*0Sstevel@tonic-gate 		status = hci1394_ioctl_rdvreg(soft_state, (void *)arg, mode);
124*0Sstevel@tonic-gate 		break;
125*0Sstevel@tonic-gate 	case HCI1394_IOCTL_WRITE_VREG:
126*0Sstevel@tonic-gate 		status = hci1394_ioctl_wrvreg(soft_state, (void *)arg, mode);
127*0Sstevel@tonic-gate 		break;
128*0Sstevel@tonic-gate 	case HCI1394_IOCTL_RESET_BUS:
129*0Sstevel@tonic-gate 		status = hci1394_ohci_bus_reset(soft_state->ohci);
130*0Sstevel@tonic-gate 		break;
131*0Sstevel@tonic-gate 	case HCI1394_IOCTL_SELFID_CNT:
132*0Sstevel@tonic-gate 		status = hci1394_ioctl_selfid_cnt(soft_state, (void *)arg,
133*0Sstevel@tonic-gate 		    mode);
134*0Sstevel@tonic-gate 		break;
135*0Sstevel@tonic-gate 	case HCI1394_IOCTL_BUSGEN_CNT:
136*0Sstevel@tonic-gate 		status = hci1394_ioctl_busgen_cnt(soft_state, (void *)arg,
137*0Sstevel@tonic-gate 		    mode);
138*0Sstevel@tonic-gate 		break;
139*0Sstevel@tonic-gate 	case HCI1394_IOCTL_READ_SELFID:
140*0Sstevel@tonic-gate 		status = hci1394_ioctl_read_selfid(soft_state, (void *)arg,
141*0Sstevel@tonic-gate 		    mode);
142*0Sstevel@tonic-gate 		break;
143*0Sstevel@tonic-gate 	case HCI1394_IOCTL_READ_PHY:
144*0Sstevel@tonic-gate 		status = hci1394_ioctl_rdphy(soft_state, (void *)arg, mode);
145*0Sstevel@tonic-gate 		break;
146*0Sstevel@tonic-gate 	case HCI1394_IOCTL_WRITE_PHY:
147*0Sstevel@tonic-gate 		status = hci1394_ioctl_wrphy(soft_state, (void *)arg, mode);
148*0Sstevel@tonic-gate 		break;
149*0Sstevel@tonic-gate 	case HCI1394_IOCTL_HBA_INFO:
150*0Sstevel@tonic-gate 		status = hci1394_ioctl_hbainfo(soft_state, (void *)arg, mode);
151*0Sstevel@tonic-gate 		break;
152*0Sstevel@tonic-gate 	default:
153*0Sstevel@tonic-gate 		/*
154*0Sstevel@tonic-gate 		 * if we don't know what the ioctl is, forward it on to the
155*0Sstevel@tonic-gate 		 * services layer.  The services layer will handle the devctl
156*0Sstevel@tonic-gate 		 * ioctl's along with any services layer private ioctls that
157*0Sstevel@tonic-gate 		 * it has defined.
158*0Sstevel@tonic-gate 		 */
159*0Sstevel@tonic-gate 		status = h1394_ioctl(soft_state->drvinfo.di_sl_private, cmd,
160*0Sstevel@tonic-gate 		    arg, mode, credp, rvalp);
161*0Sstevel@tonic-gate 		break;
162*0Sstevel@tonic-gate 	}
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_exit, HCI1394_TNF_HAL_STACK, "");
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 	return (status);
167*0Sstevel@tonic-gate }
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate static int
hci1394_ioctl_wrreg(hci1394_state_t * soft_state,void * arg,int mode)171*0Sstevel@tonic-gate hci1394_ioctl_wrreg(hci1394_state_t *soft_state, void *arg, int mode)
172*0Sstevel@tonic-gate {
173*0Sstevel@tonic-gate 	hci1394_ioctl_wrreg_t wrreg;
174*0Sstevel@tonic-gate 	int status;
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
178*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
179*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrreg_enter, HCI1394_TNF_HAL_STACK, "");
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &wrreg, sizeof (hci1394_ioctl_wrreg_t), mode);
182*0Sstevel@tonic-gate 	if (status != 0) {
183*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_wrreg_ci_fail, HCI1394_TNF_HAL_ERROR,
184*0Sstevel@tonic-gate 		    "");
185*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_wrreg_exit,
186*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
187*0Sstevel@tonic-gate 		return (EFAULT);
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	hci1394_ohci_reg_write(soft_state->ohci, wrreg.addr, wrreg.data);
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrreg_exit, HCI1394_TNF_HAL_STACK, "");
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 	return (0);
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate static int
hci1394_ioctl_rdreg(hci1394_state_t * soft_state,void * arg,int mode)199*0Sstevel@tonic-gate hci1394_ioctl_rdreg(hci1394_state_t *soft_state, void *arg, int mode)
200*0Sstevel@tonic-gate {
201*0Sstevel@tonic-gate 	hci1394_ioctl_rdreg_t rdreg;
202*0Sstevel@tonic-gate 	int status;
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
206*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
207*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_enter, HCI1394_TNF_HAL_STACK, "");
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &rdreg, sizeof (hci1394_ioctl_rdreg_t), mode);
210*0Sstevel@tonic-gate 	if (status != 0) {
211*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdreg_ci_fail, HCI1394_TNF_HAL_ERROR,
212*0Sstevel@tonic-gate 		    "");
213*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit,
214*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
215*0Sstevel@tonic-gate 		return (EFAULT);
216*0Sstevel@tonic-gate 	}
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 	hci1394_ohci_reg_read(soft_state->ohci, rdreg.addr, &rdreg.data);
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate 	status = ddi_copyout(&rdreg, arg, sizeof (hci1394_ioctl_rdreg_t), mode);
221*0Sstevel@tonic-gate 	if (status != 0) {
222*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdreg_c0_fail, HCI1394_TNF_HAL_ERROR,
223*0Sstevel@tonic-gate 		    "");
224*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit,
225*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
226*0Sstevel@tonic-gate 		return (EFAULT);
227*0Sstevel@tonic-gate 	}
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit, HCI1394_TNF_HAL_STACK, "");
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	return (0);
232*0Sstevel@tonic-gate }
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate static int
hci1394_ioctl_wrvreg(hci1394_state_t * soft_state,void * arg,int mode)236*0Sstevel@tonic-gate hci1394_ioctl_wrvreg(hci1394_state_t *soft_state, void *arg, int mode)
237*0Sstevel@tonic-gate {
238*0Sstevel@tonic-gate 	hci1394_ioctl_wrvreg_t wrvreg;
239*0Sstevel@tonic-gate 	int status;
240*0Sstevel@tonic-gate 
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
243*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
244*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrvreg_enter, HCI1394_TNF_HAL_STACK,
245*0Sstevel@tonic-gate 	    "");
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &wrvreg, sizeof (hci1394_ioctl_wrvreg_t),
248*0Sstevel@tonic-gate 	    mode);
249*0Sstevel@tonic-gate 	if (status != 0) {
250*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_wrvreg_ci_fail, HCI1394_TNF_HAL_ERROR,
251*0Sstevel@tonic-gate 		    "");
252*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_wrvreg_exit,
253*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
254*0Sstevel@tonic-gate 		return (EFAULT);
255*0Sstevel@tonic-gate 	}
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 	status = hci1394_vendor_reg_write(soft_state->vendor,
258*0Sstevel@tonic-gate 	    wrvreg.regset, wrvreg.addr, wrvreg.data);
259*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
260*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_wrvreg_vrw_fail,
261*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
262*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_wrvreg_exit,
263*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
264*0Sstevel@tonic-gate 		return (EINVAL);
265*0Sstevel@tonic-gate 	}
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrvreg_exit, HCI1394_TNF_HAL_STACK, "");
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 	return (0);
270*0Sstevel@tonic-gate }
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate static int
hci1394_ioctl_rdvreg(hci1394_state_t * soft_state,void * arg,int mode)274*0Sstevel@tonic-gate hci1394_ioctl_rdvreg(hci1394_state_t *soft_state, void *arg, int mode)
275*0Sstevel@tonic-gate {
276*0Sstevel@tonic-gate 	hci1394_ioctl_rdvreg_t rdvreg;
277*0Sstevel@tonic-gate 	int status;
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
281*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
282*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_enter, HCI1394_TNF_HAL_STACK,
283*0Sstevel@tonic-gate 	    "");
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &rdvreg, sizeof (hci1394_ioctl_rdvreg_t),
286*0Sstevel@tonic-gate 	    mode);
287*0Sstevel@tonic-gate 	if (status != 0) {
288*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdvreg_ci_fail, HCI1394_TNF_HAL_ERROR,
289*0Sstevel@tonic-gate 		    "");
290*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
291*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
292*0Sstevel@tonic-gate 		return (EFAULT);
293*0Sstevel@tonic-gate 	}
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 	status = hci1394_vendor_reg_read(soft_state->vendor,
296*0Sstevel@tonic-gate 	    rdvreg.regset, rdvreg.addr, &rdvreg.data);
297*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
298*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdvreg_vrr_fail,
299*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
300*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
301*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
302*0Sstevel@tonic-gate 		return (EINVAL);
303*0Sstevel@tonic-gate 	}
304*0Sstevel@tonic-gate 
305*0Sstevel@tonic-gate 	status = ddi_copyout(&rdvreg, arg, sizeof (hci1394_ioctl_rdvreg_t),
306*0Sstevel@tonic-gate 	    mode);
307*0Sstevel@tonic-gate 	if (status != 0) {
308*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdvreg_co_fail,
309*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
310*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
311*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
312*0Sstevel@tonic-gate 		return (EFAULT);
313*0Sstevel@tonic-gate 	}
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, "");
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	return (0);
318*0Sstevel@tonic-gate }
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate 
321*0Sstevel@tonic-gate static int
hci1394_ioctl_selfid_cnt(hci1394_state_t * soft_state,void * arg,int mode)322*0Sstevel@tonic-gate hci1394_ioctl_selfid_cnt(hci1394_state_t *soft_state, void *arg, int mode)
323*0Sstevel@tonic-gate {
324*0Sstevel@tonic-gate 	hci1394_ioctl_selfid_cnt_t selfid_cnt;
325*0Sstevel@tonic-gate 	int status;
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
329*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
330*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_enter,
331*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	selfid_cnt.count = soft_state->drvinfo.di_stats.st_selfid_count;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate 	status = ddi_copyout(&selfid_cnt, arg,
336*0Sstevel@tonic-gate 	    sizeof (hci1394_ioctl_selfid_cnt_t), mode);
337*0Sstevel@tonic-gate 	if (status != 0) {
338*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_selfid_cnt_co_fail,
339*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
340*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit,
341*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
342*0Sstevel@tonic-gate 		return (EFAULT);
343*0Sstevel@tonic-gate 	}
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit,
346*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
347*0Sstevel@tonic-gate 
348*0Sstevel@tonic-gate 	return (0);
349*0Sstevel@tonic-gate }
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate static int
hci1394_ioctl_busgen_cnt(hci1394_state_t * soft_state,void * arg,int mode)353*0Sstevel@tonic-gate hci1394_ioctl_busgen_cnt(hci1394_state_t *soft_state, void *arg, int mode)
354*0Sstevel@tonic-gate {
355*0Sstevel@tonic-gate 	hci1394_ioctl_busgen_cnt_t busgen_cnt;
356*0Sstevel@tonic-gate 	int status;
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
360*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
361*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_enter,
362*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
363*0Sstevel@tonic-gate 
364*0Sstevel@tonic-gate 	busgen_cnt.count = hci1394_ohci_current_busgen(soft_state->ohci);
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	status = ddi_copyout(&busgen_cnt, arg,
367*0Sstevel@tonic-gate 	    sizeof (hci1394_ioctl_busgen_cnt_t), mode);
368*0Sstevel@tonic-gate 	if (status != 0) {
369*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_busgen_cnt_co_fail,
370*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
371*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit,
372*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
373*0Sstevel@tonic-gate 		return (EFAULT);
374*0Sstevel@tonic-gate 	}
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit,
377*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 	return (0);
380*0Sstevel@tonic-gate }
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate static int
hci1394_ioctl_wrphy(hci1394_state_t * soft_state,void * arg,int mode)384*0Sstevel@tonic-gate hci1394_ioctl_wrphy(hci1394_state_t *soft_state, void *arg, int mode)
385*0Sstevel@tonic-gate {
386*0Sstevel@tonic-gate 	hci1394_ioctl_wrphy_t wrphy;
387*0Sstevel@tonic-gate 	int status;
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 
390*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
391*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
392*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrphy_enter, HCI1394_TNF_HAL_STACK, "");
393*0Sstevel@tonic-gate 
394*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &wrphy, sizeof (hci1394_ioctl_wrphy_t), mode);
395*0Sstevel@tonic-gate 	if (status != 0) {
396*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_wrphy_ci_fail, HCI1394_TNF_HAL_ERROR,
397*0Sstevel@tonic-gate 		    "");
398*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_wrphy_exit,
399*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
400*0Sstevel@tonic-gate 		return (EFAULT);
401*0Sstevel@tonic-gate 	}
402*0Sstevel@tonic-gate 
403*0Sstevel@tonic-gate 	status = hci1394_ohci_phy_write(soft_state->ohci, wrphy.addr,
404*0Sstevel@tonic-gate 	    wrphy.data);
405*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
406*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_wrphy_pw_fail,
407*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
408*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_wrphy_exit,
409*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
410*0Sstevel@tonic-gate 		return (EINVAL);
411*0Sstevel@tonic-gate 	}
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_wrphy_exit, HCI1394_TNF_HAL_STACK, "");
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate 	return (0);
416*0Sstevel@tonic-gate }
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate static int
hci1394_ioctl_rdphy(hci1394_state_t * soft_state,void * arg,int mode)420*0Sstevel@tonic-gate hci1394_ioctl_rdphy(hci1394_state_t *soft_state, void *arg, int mode)
421*0Sstevel@tonic-gate {
422*0Sstevel@tonic-gate 	hci1394_ioctl_rdphy_t rdphy;
423*0Sstevel@tonic-gate 	int status;
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
427*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
428*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_enter, HCI1394_TNF_HAL_STACK, "");
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &rdphy, sizeof (hci1394_ioctl_rdphy_t), mode);
431*0Sstevel@tonic-gate 	if (status != 0) {
432*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdphy_ci_fail, HCI1394_TNF_HAL_ERROR,
433*0Sstevel@tonic-gate 		    "");
434*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
435*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
436*0Sstevel@tonic-gate 		return (EFAULT);
437*0Sstevel@tonic-gate 	}
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 	status = hci1394_ohci_phy_read(soft_state->ohci, rdphy.addr,
440*0Sstevel@tonic-gate 	    &rdphy.data);
441*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
442*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdphy_pr_fail, HCI1394_TNF_HAL_ERROR,
443*0Sstevel@tonic-gate 		    "");
444*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
445*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
446*0Sstevel@tonic-gate 		return (EINVAL);
447*0Sstevel@tonic-gate 	}
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 	status = ddi_copyout(&rdphy, arg, sizeof (hci1394_ioctl_rdphy_t), mode);
450*0Sstevel@tonic-gate 	if (status != 0) {
451*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_rdphy_co_fail, HCI1394_TNF_HAL_ERROR,
452*0Sstevel@tonic-gate 		    "");
453*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
454*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
455*0Sstevel@tonic-gate 		return (EFAULT);
456*0Sstevel@tonic-gate 	}
457*0Sstevel@tonic-gate 
458*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, "");
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	return (0);
461*0Sstevel@tonic-gate }
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate static int
hci1394_ioctl_hbainfo(hci1394_state_t * soft_state,void * arg,int mode)465*0Sstevel@tonic-gate hci1394_ioctl_hbainfo(hci1394_state_t *soft_state, void *arg, int mode)
466*0Sstevel@tonic-gate {
467*0Sstevel@tonic-gate 	hci1394_ioctl_hbainfo_t hbainfo;
468*0Sstevel@tonic-gate 	int status;
469*0Sstevel@tonic-gate 
470*0Sstevel@tonic-gate 
471*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
472*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
473*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_enter,
474*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 	hbainfo.pci_vendor_id = soft_state->vendor_info.vendor_id;
477*0Sstevel@tonic-gate 	hbainfo.pci_device_id = soft_state->vendor_info.device_id;
478*0Sstevel@tonic-gate 	hbainfo.pci_revision_id = soft_state->vendor_info.revision_id;
479*0Sstevel@tonic-gate 	hbainfo.ohci_version = soft_state->vendor_info.ohci_version;
480*0Sstevel@tonic-gate 	hbainfo.ohci_vendor_id = soft_state->vendor_info.ohci_vendor_id;
481*0Sstevel@tonic-gate 	hbainfo.ohci_vregset_cnt = soft_state->vendor_info.vendor_reg_count;
482*0Sstevel@tonic-gate 
483*0Sstevel@tonic-gate 	status = ddi_copyout(&hbainfo, arg, sizeof (hci1394_ioctl_hbainfo_t),
484*0Sstevel@tonic-gate 	    mode);
485*0Sstevel@tonic-gate 	if (status != 0) {
486*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_hbainfo_co_fail,
487*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
488*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit,
489*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
490*0Sstevel@tonic-gate 		return (EFAULT);
491*0Sstevel@tonic-gate 	}
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit,
494*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
495*0Sstevel@tonic-gate 
496*0Sstevel@tonic-gate 	return (0);
497*0Sstevel@tonic-gate }
498*0Sstevel@tonic-gate 
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate static int
hci1394_ioctl_read_selfid(hci1394_state_t * soft_state,void * arg,int mode)501*0Sstevel@tonic-gate hci1394_ioctl_read_selfid(hci1394_state_t *soft_state, void *arg, int mode)
502*0Sstevel@tonic-gate {
503*0Sstevel@tonic-gate 	hci1394_ioctl_read_selfid_t read_selfid;
504*0Sstevel@tonic-gate 	int status;
505*0Sstevel@tonic-gate 	uint_t offset;
506*0Sstevel@tonic-gate 	uint32_t data;
507*0Sstevel@tonic-gate #ifdef	_MULTI_DATAMODEL
508*0Sstevel@tonic-gate 	hci1394_ioctl_readselfid32_t read_selfid32;
509*0Sstevel@tonic-gate #endif
510*0Sstevel@tonic-gate 
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
513*0Sstevel@tonic-gate 	ASSERT(arg != NULL);
514*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_enter,
515*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate #ifdef	_MULTI_DATAMODEL
518*0Sstevel@tonic-gate 	switch (ddi_model_convert_from(mode & FMODELS)) {
519*0Sstevel@tonic-gate 
520*0Sstevel@tonic-gate 		/* 32-bit app in 64-bit kernel */
521*0Sstevel@tonic-gate 	case DDI_MODEL_ILP32:
522*0Sstevel@tonic-gate 		/* copy in the 32-bit version of the args */
523*0Sstevel@tonic-gate 		status = ddi_copyin(arg, &read_selfid32,
524*0Sstevel@tonic-gate 		    sizeof (hci1394_ioctl_readselfid32_t), mode);
525*0Sstevel@tonic-gate 		if (status != 0) {
526*0Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_ioctl_read_selfid_ci_fail,
527*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
528*0Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
529*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
530*0Sstevel@tonic-gate 			return (EFAULT);
531*0Sstevel@tonic-gate 		}
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate 		/*
534*0Sstevel@tonic-gate 		 * Use a special function to process the 32-bit user address
535*0Sstevel@tonic-gate 		 * pointer embedded in the structure we pass in arg.
536*0Sstevel@tonic-gate 		 */
537*0Sstevel@tonic-gate 		status = hci1394_ioctl_read_selfid32(soft_state,
538*0Sstevel@tonic-gate 		    &read_selfid32, mode);
539*0Sstevel@tonic-gate 		return (status);
540*0Sstevel@tonic-gate 	default:
541*0Sstevel@tonic-gate 		break;
542*0Sstevel@tonic-gate 	}
543*0Sstevel@tonic-gate #endif
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate 	/*
546*0Sstevel@tonic-gate 	 * if we got here, we either are a 64-bit app in a 64-bit kernel or a
547*0Sstevel@tonic-gate 	 * 32-bit app in a 32-bit kernel
548*0Sstevel@tonic-gate 	 */
549*0Sstevel@tonic-gate 
550*0Sstevel@tonic-gate 	/* copy in the args. We don't need to do any special conversions */
551*0Sstevel@tonic-gate 	status = ddi_copyin(arg, &read_selfid,
552*0Sstevel@tonic-gate 	    sizeof (hci1394_ioctl_read_selfid_t), mode);
553*0Sstevel@tonic-gate 	if (status != 0) {
554*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_read_selfid_ci_fail,
555*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
556*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
557*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
558*0Sstevel@tonic-gate 		return (EFAULT);
559*0Sstevel@tonic-gate 	}
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	/*
562*0Sstevel@tonic-gate 	 * make sure we are not trying to copy more data than the selfid buffer
563*0Sstevel@tonic-gate 	 * can hold.  count is in quadlets and max_selfid_size is in bytes.
564*0Sstevel@tonic-gate 	 */
565*0Sstevel@tonic-gate 	if ((read_selfid.count * 4) > OHCI_MAX_SELFID_SIZE) {
566*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_read_selfid_cnt_fail,
567*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
568*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_exit,
569*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
570*0Sstevel@tonic-gate 		return (EINVAL);
571*0Sstevel@tonic-gate 	}
572*0Sstevel@tonic-gate 
573*0Sstevel@tonic-gate 	/*
574*0Sstevel@tonic-gate 	 * copy the selfid buffer one word at a time into the user buffer. The
575*0Sstevel@tonic-gate 	 * combination between having to do ddi_get32's (for endian reasons)
576*0Sstevel@tonic-gate 	 * and a ddi_copyout() make it easier to do it one word at a time.
577*0Sstevel@tonic-gate 	 */
578*0Sstevel@tonic-gate 	for (offset = 0; offset < read_selfid.count; offset++) {
579*0Sstevel@tonic-gate 		/* read word from selfid buffer */
580*0Sstevel@tonic-gate 		hci1394_ohci_selfid_read(soft_state->ohci, offset, &data);
581*0Sstevel@tonic-gate 
582*0Sstevel@tonic-gate 		/* copy the selfid word into the user buffer */
583*0Sstevel@tonic-gate 		status = ddi_copyout(&data, &read_selfid.buf[offset], 4, mode);
584*0Sstevel@tonic-gate 		if (status != 0) {
585*0Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_ioctl_read_selfid_co_fail,
586*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
587*0Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
588*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
589*0Sstevel@tonic-gate 			return (EFAULT);
590*0Sstevel@tonic-gate 		}
591*0Sstevel@tonic-gate 	}
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
594*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
595*0Sstevel@tonic-gate 
596*0Sstevel@tonic-gate 	return (0);
597*0Sstevel@tonic-gate }
598*0Sstevel@tonic-gate 
599*0Sstevel@tonic-gate 
600*0Sstevel@tonic-gate #ifdef	_MULTI_DATAMODEL
601*0Sstevel@tonic-gate static int
hci1394_ioctl_read_selfid32(hci1394_state_t * soft_state,hci1394_ioctl_readselfid32_t * read_selfid,int mode)602*0Sstevel@tonic-gate hci1394_ioctl_read_selfid32(hci1394_state_t *soft_state,
603*0Sstevel@tonic-gate     hci1394_ioctl_readselfid32_t *read_selfid, int mode)
604*0Sstevel@tonic-gate {
605*0Sstevel@tonic-gate 	int status;
606*0Sstevel@tonic-gate 	uint_t offset;
607*0Sstevel@tonic-gate 	uint32_t data;
608*0Sstevel@tonic-gate 
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate 	ASSERT(soft_state != NULL);
611*0Sstevel@tonic-gate 	ASSERT(read_selfid != NULL);
612*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_enter,
613*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
614*0Sstevel@tonic-gate 
615*0Sstevel@tonic-gate 	/*
616*0Sstevel@tonic-gate 	 * make sure we are not trying to copy more data than the selfid buffer
617*0Sstevel@tonic-gate 	 * can hold.  count is in quadlets and max_selfid_size is in bytes.
618*0Sstevel@tonic-gate 	 */
619*0Sstevel@tonic-gate 	if ((read_selfid->count * 4) > OHCI_MAX_SELFID_SIZE) {
620*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_ioctl_read_selfid32_cnt_fail,
621*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "");
622*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
623*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
624*0Sstevel@tonic-gate 		return (EINVAL);
625*0Sstevel@tonic-gate 	}
626*0Sstevel@tonic-gate 
627*0Sstevel@tonic-gate 	/*
628*0Sstevel@tonic-gate 	 * copy the selfid buffer one word at a time into the user buffer. The
629*0Sstevel@tonic-gate 	 * combination between having to do ddi_get32's (for endian reasons) and
630*0Sstevel@tonic-gate 	 * a ddi_copyout() make it easier to do it one word at a time.
631*0Sstevel@tonic-gate 	 */
632*0Sstevel@tonic-gate 	for (offset = 0; offset < read_selfid->count; offset++) {
633*0Sstevel@tonic-gate 		/* read word from selfid buffer */
634*0Sstevel@tonic-gate 		hci1394_ohci_selfid_read(soft_state->ohci, offset, &data);
635*0Sstevel@tonic-gate 		/* copy the selfid word into the user buffer */
636*0Sstevel@tonic-gate 		status = ddi_copyout(&data,
637*0Sstevel@tonic-gate 		    (void *)(uintptr_t)(read_selfid->buf + (offset * 4)),
638*0Sstevel@tonic-gate 		    4, mode);
639*0Sstevel@tonic-gate 		if (status != 0) {
640*0Sstevel@tonic-gate 			TNF_PROBE_0(hci1394_ioctl_read_selfid32_co_fail,
641*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR, "");
642*0Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
643*0Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK, "");
644*0Sstevel@tonic-gate 			return (EFAULT);
645*0Sstevel@tonic-gate 		}
646*0Sstevel@tonic-gate 	}
647*0Sstevel@tonic-gate 
648*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
649*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
650*0Sstevel@tonic-gate 
651*0Sstevel@tonic-gate 	return (0);
652*0Sstevel@tonic-gate }
653*0Sstevel@tonic-gate #endif
654