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 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 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 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 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 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 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 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 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 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 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 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 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