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