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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright 2023 Oxide Computer Company 28 */ 29 30 /* 31 * 1394 mass storage HBA driver 32 */ 33 34 #include <sys/param.h> 35 #include <sys/errno.h> 36 #include <sys/cred.h> 37 #include <sys/conf.h> 38 #include <sys/modctl.h> 39 #include <sys/stat.h> 40 #include <sys/byteorder.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 44 #include <sys/1394/targets/scsa1394/impl.h> 45 #include <sys/1394/targets/scsa1394/cmd.h> 46 47 /* DDI/DKI entry points */ 48 static int scsa1394_attach(dev_info_t *, ddi_attach_cmd_t); 49 static int scsa1394_detach(dev_info_t *, ddi_detach_cmd_t); 50 static int scsa1394_power(dev_info_t *, int, int); 51 static int scsa1394_cpr_suspend(dev_info_t *); 52 static void scsa1394_cpr_resume(dev_info_t *); 53 54 /* configuration routines */ 55 static void scsa1394_cleanup(scsa1394_state_t *, int); 56 static int scsa1394_attach_1394(scsa1394_state_t *); 57 static void scsa1394_detach_1394(scsa1394_state_t *); 58 static int scsa1394_attach_threads(scsa1394_state_t *); 59 static void scsa1394_detach_threads(scsa1394_state_t *); 60 static int scsa1394_attach_scsa(scsa1394_state_t *); 61 static void scsa1394_detach_scsa(scsa1394_state_t *); 62 static int scsa1394_create_cmd_cache(scsa1394_state_t *); 63 static void scsa1394_destroy_cmd_cache(scsa1394_state_t *); 64 static int scsa1394_add_events(scsa1394_state_t *); 65 static void scsa1394_remove_events(scsa1394_state_t *); 66 67 /* device configuration */ 68 static int scsa1394_scsi_bus_config(dev_info_t *, uint_t, 69 ddi_bus_config_op_t, void *, dev_info_t **); 70 static int scsa1394_scsi_bus_unconfig(dev_info_t *, uint_t, 71 ddi_bus_config_op_t, void *); 72 static void scsa1394_create_children(scsa1394_state_t *); 73 static void scsa1394_bus_reset(dev_info_t *, ddi_eventcookie_t, void *, 74 void *); 75 static void scsa1394_disconnect(dev_info_t *, ddi_eventcookie_t, void *, 76 void *); 77 static void scsa1394_reconnect(dev_info_t *, ddi_eventcookie_t, void *, 78 void *); 79 80 /* SCSA HBA entry points */ 81 static int scsa1394_scsi_tgt_init(dev_info_t *, dev_info_t *, 82 scsi_hba_tran_t *, struct scsi_device *); 83 static void scsa1394_scsi_tgt_free(dev_info_t *, dev_info_t *, 84 scsi_hba_tran_t *, struct scsi_device *); 85 static int scsa1394_scsi_tgt_probe(struct scsi_device *, int (*)()); 86 static int scsa1394_probe_g0_nodata(struct scsi_device *, int (*)(), 87 uchar_t, uint_t, uint_t); 88 static int scsa1394_probe_tran(struct scsi_pkt *); 89 static struct scsi_pkt *scsa1394_scsi_init_pkt(struct scsi_address *, 90 struct scsi_pkt *, struct buf *, int, int, int, int, 91 int (*)(), caddr_t arg); 92 static void scsa1394_scsi_destroy_pkt(struct scsi_address *, 93 struct scsi_pkt *); 94 static int scsa1394_scsi_start(struct scsi_address *, struct scsi_pkt *); 95 static int scsa1394_scsi_abort(struct scsi_address *, struct scsi_pkt *); 96 static int scsa1394_scsi_reset(struct scsi_address *, int); 97 static int scsa1394_scsi_getcap(struct scsi_address *, char *, int); 98 static int scsa1394_scsi_setcap(struct scsi_address *, char *, int, int); 99 static void scsa1394_scsi_dmafree(struct scsi_address *, struct scsi_pkt *); 100 static void scsa1394_scsi_sync_pkt(struct scsi_address *, 101 struct scsi_pkt *); 102 103 /* pkt resource allocation routines */ 104 static int scsa1394_cmd_cache_constructor(void *, void *, int); 105 static void scsa1394_cmd_cache_destructor(void *, void *); 106 static int scsa1394_cmd_ext_alloc(scsa1394_state_t *, scsa1394_cmd_t *, 107 int); 108 static void scsa1394_cmd_ext_free(scsa1394_state_t *, scsa1394_cmd_t *); 109 static int scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *, 110 int, int (*)(), caddr_t); 111 static void scsa1394_cmd_cdb_dma_free(scsa1394_state_t *, scsa1394_cmd_t *); 112 static int scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *, 113 int, int (*)(), caddr_t, struct buf *); 114 static void scsa1394_cmd_buf_dma_free(scsa1394_state_t *, scsa1394_cmd_t *); 115 static int scsa1394_cmd_dmac2seg(scsa1394_state_t *, scsa1394_cmd_t *, 116 ddi_dma_cookie_t *, uint_t, int); 117 static void scsa1394_cmd_seg_free(scsa1394_state_t *, scsa1394_cmd_t *); 118 static int scsa1394_cmd_pt_dma_alloc(scsa1394_state_t *, scsa1394_cmd_t *, 119 int (*)(), caddr_t, int); 120 static void scsa1394_cmd_pt_dma_free(scsa1394_state_t *, scsa1394_cmd_t *); 121 static int scsa1394_cmd_buf_addr_alloc(scsa1394_state_t *, 122 scsa1394_cmd_t *); 123 static void scsa1394_cmd_buf_addr_free(scsa1394_state_t *, 124 scsa1394_cmd_t *); 125 static int scsa1394_cmd_buf_dma_move(scsa1394_state_t *, scsa1394_cmd_t *); 126 127 128 /* pkt and data transfer routines */ 129 static void scsa1394_prepare_pkt(scsa1394_state_t *, struct scsi_pkt *); 130 static void scsa1394_cmd_fill_cdb(scsa1394_lun_t *, scsa1394_cmd_t *); 131 static void scsa1394_cmd_fill_cdb_rbc(scsa1394_lun_t *, scsa1394_cmd_t *); 132 static void scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *, scsa1394_cmd_t *); 133 static void scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *, int); 134 static void scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *, int); 135 static void scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *, int); 136 static void scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *, int); 137 static int scsa1394_cmd_read_cd_blk_size(uchar_t); 138 static int scsa1394_cmd_fake_mode_sense(scsa1394_state_t *, 139 scsa1394_cmd_t *); 140 static int scsa1394_cmd_fake_inquiry(scsa1394_state_t *, scsa1394_cmd_t *); 141 static int scsa1394_cmd_fake_comp(scsa1394_state_t *, scsa1394_cmd_t *); 142 static int scsa1394_cmd_setup_next_xfer(scsa1394_lun_t *, 143 scsa1394_cmd_t *); 144 static void scsa1394_cmd_adjust_cdb(scsa1394_lun_t *, scsa1394_cmd_t *); 145 static void scsa1394_cmd_status_wrka(scsa1394_lun_t *, scsa1394_cmd_t *); 146 147 /* other routines */ 148 static boolean_t scsa1394_is_my_child(dev_info_t *); 149 static void * scsa1394_kmem_realloc(void *, int, int, size_t, int); 150 151 static void *scsa1394_statep; 152 #define SCSA1394_INST2STATE(inst) (ddi_get_soft_state(scsa1394_statep, inst)) 153 154 static struct cb_ops scsa1394_cb_ops = { 155 nodev, /* open */ 156 nodev, /* close */ 157 nodev, /* strategy */ 158 nodev, /* print */ 159 nodev, /* dump */ 160 nodev, /* read */ 161 nodev, /* write */ 162 NULL, /* ioctl */ 163 nodev, /* devmap */ 164 nodev, /* mmap */ 165 nodev, /* segmap */ 166 nochpoll, /* poll */ 167 ddi_prop_op, /* prop_op */ 168 NULL, /* stream */ 169 D_MP, /* cb_flag */ 170 CB_REV, /* rev */ 171 nodev, /* aread */ 172 nodev /* awrite */ 173 }; 174 175 static struct dev_ops scsa1394_ops = { 176 DEVO_REV, /* devo_rev, */ 177 0, /* refcnt */ 178 ddi_no_info, /* info */ 179 nulldev, /* identify */ 180 nulldev, /* probe */ 181 scsa1394_attach, /* attach */ 182 scsa1394_detach, /* detach */ 183 nodev, /* reset */ 184 &scsa1394_cb_ops, /* driver operations */ 185 NULL, /* bus operations */ 186 scsa1394_power, /* power */ 187 ddi_quiesce_not_supported, /* devo_quiesce */ 188 }; 189 190 static struct modldrv scsa1394_modldrv = { 191 &mod_driverops, /* module type */ 192 "1394 Mass Storage HBA Driver", /* name of the module */ 193 &scsa1394_ops, /* driver ops */ 194 }; 195 196 static struct modlinkage scsa1394_modlinkage = { 197 MODREV_1, (void *)&scsa1394_modldrv, NULL 198 }; 199 200 /* tunables */ 201 int scsa1394_bus_config_debug = 0; 202 int scsa1394_start_stop_fail_max = SCSA1394_START_STOP_FAIL_MAX; 203 int scsa1394_mode_sense_fail_max = SCSA1394_MODE_SENSE_FAIL_MAX; 204 int scsa1394_start_stop_timeout_max = SCSA1394_START_STOP_TIMEOUT_MAX; 205 206 /* workarounds */ 207 int scsa1394_wrka_rbc2direct = 1; 208 int scsa1394_wrka_fake_rmb = 0; 209 int scsa1394_wrka_fake_prin = 1; 210 211 int scsa1394_wrka_symbios = 1; 212 int scsa1394_symbios_page_size = 4 * 1024; /* must be <= _pagesize */ 213 int scsa1394_symbios_size_max = 512 * 248; /* multiple of page size */ 214 215 /* 216 * 217 * --- DDI/DKI entry points 218 * 219 */ 220 int 221 _init(void) 222 { 223 int ret; 224 225 if (((ret = ddi_soft_state_init(&scsa1394_statep, 226 sizeof (scsa1394_state_t), 1)) != 0)) { 227 return (ret); 228 } 229 230 if ((ret = scsi_hba_init(&scsa1394_modlinkage)) != 0) { 231 ddi_soft_state_fini(&scsa1394_statep); 232 return (ret); 233 } 234 235 if ((ret = mod_install(&scsa1394_modlinkage)) != 0) { 236 scsi_hba_fini(&scsa1394_modlinkage); 237 ddi_soft_state_fini(&scsa1394_statep); 238 return (ret); 239 } 240 241 return (ret); 242 } 243 244 int 245 _fini(void) 246 { 247 int ret; 248 249 if ((ret = mod_remove(&scsa1394_modlinkage)) == 0) { 250 scsi_hba_fini(&scsa1394_modlinkage); 251 ddi_soft_state_fini(&scsa1394_statep); 252 } 253 254 return (ret); 255 } 256 257 int 258 _info(struct modinfo *modinfop) 259 { 260 return (mod_info(&scsa1394_modlinkage, modinfop)); 261 } 262 263 static int 264 scsa1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 265 { 266 int instance = ddi_get_instance(dip); 267 scsa1394_state_t *sp; 268 269 switch (cmd) { 270 case DDI_ATTACH: 271 break; 272 case DDI_RESUME: 273 scsa1394_cpr_resume(dip); 274 return (DDI_SUCCESS); 275 default: 276 return (DDI_FAILURE); 277 } 278 279 if (ddi_soft_state_zalloc(scsa1394_statep, instance) != 0) { 280 return (DDI_FAILURE); 281 } 282 sp = SCSA1394_INST2STATE(instance); 283 284 #ifndef __lock_lint 285 sp->s_dip = dip; 286 sp->s_instance = instance; 287 #endif 288 mutex_init(&sp->s_mutex, NULL, MUTEX_DRIVER, 289 sp->s_attachinfo.iblock_cookie); 290 cv_init(&sp->s_event_cv, NULL, CV_DRIVER, NULL); 291 292 if (scsa1394_attach_1394(sp) != DDI_SUCCESS) { 293 scsa1394_cleanup(sp, 1); 294 return (DDI_FAILURE); 295 } 296 297 if (scsa1394_sbp2_attach(sp) != DDI_SUCCESS) { 298 scsa1394_cleanup(sp, 2); 299 return (DDI_FAILURE); 300 } 301 302 if (scsa1394_attach_threads(sp) != DDI_SUCCESS) { 303 scsa1394_cleanup(sp, 3); 304 return (DDI_FAILURE); 305 } 306 307 if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) { 308 scsa1394_cleanup(sp, 4); 309 return (DDI_FAILURE); 310 } 311 312 if (scsa1394_create_cmd_cache(sp) != DDI_SUCCESS) { 313 scsa1394_cleanup(sp, 5); 314 return (DDI_FAILURE); 315 } 316 317 if (scsa1394_add_events(sp) != DDI_SUCCESS) { 318 scsa1394_cleanup(sp, 6); 319 return (DDI_FAILURE); 320 } 321 322 /* prevent async PM changes until we are done */ 323 (void) pm_busy_component(dip, 0); 324 325 /* Set power to full on */ 326 (void) pm_raise_power(dip, 0, PM_LEVEL_D0); 327 328 /* we are done */ 329 (void) pm_idle_component(dip, 0); 330 331 #ifndef __lock_lint 332 sp->s_dev_state = SCSA1394_DEV_ONLINE; 333 #endif 334 335 ddi_report_dev(dip); 336 337 return (DDI_SUCCESS); 338 } 339 340 static int 341 scsa1394_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 342 { 343 int instance = ddi_get_instance(dip); 344 scsa1394_state_t *sp; 345 346 if ((sp = SCSA1394_INST2STATE(instance)) == NULL) { 347 return (DDI_FAILURE); 348 } 349 350 switch (cmd) { 351 case DDI_DETACH: 352 /* Cycle power state to off and idle where done/gone */ 353 (void) pm_lower_power(dip, 0, PM_LEVEL_D3); 354 355 scsa1394_cleanup(sp, SCSA1394_CLEANUP_LEVEL_MAX); 356 return (DDI_SUCCESS); 357 case DDI_SUSPEND: 358 return (scsa1394_cpr_suspend(dip)); 359 default: 360 return (DDI_FAILURE); 361 } 362 } 363 364 /*ARGSUSED*/ 365 static int 366 scsa1394_power(dev_info_t *dip, int comp, int level) 367 { 368 return (DDI_SUCCESS); 369 } 370 371 /* 372 * scsa1394_cpr_suspend 373 * determine if the device's state can be changed to SUSPENDED 374 */ 375 /* ARGSUSED */ 376 static int 377 scsa1394_cpr_suspend(dev_info_t *dip) 378 { 379 int instance = ddi_get_instance(dip); 380 scsa1394_state_t *sp; 381 int rval = DDI_FAILURE; 382 383 sp = SCSA1394_INST2STATE(instance); 384 385 ASSERT(sp != NULL); 386 387 388 mutex_enter(&sp->s_mutex); 389 switch (sp->s_dev_state) { 390 case SCSA1394_DEV_ONLINE: 391 case SCSA1394_DEV_PWRED_DOWN: 392 case SCSA1394_DEV_DISCONNECTED: 393 sp->s_dev_state = SCSA1394_DEV_SUSPENDED; 394 395 /* Power down and make device idle */ 396 (void) pm_lower_power(dip, 0, PM_LEVEL_D3); 397 398 rval = DDI_SUCCESS; 399 break; 400 case SCSA1394_DEV_SUSPENDED: 401 default: 402 if (scsa1394_bus_config_debug) 403 cmn_err(CE_WARN, 404 "scsa1304_cpr_suspend: Illegal dev state: %d", 405 sp->s_dev_state); 406 407 rval = DDI_SUCCESS; 408 break; 409 } 410 mutex_exit(&sp->s_mutex); 411 412 return (rval); 413 } 414 415 /* 416 * scsa2usb_cpr_resume: 417 * restore device's state 418 */ 419 static void 420 scsa1394_cpr_resume(dev_info_t *dip) 421 { 422 int instance = ddi_get_instance(dip); 423 scsa1394_state_t *sp; 424 int i; 425 scsa1394_lun_t *lp; 426 427 sp = SCSA1394_INST2STATE(instance); 428 429 ASSERT(sp != NULL); 430 431 if (sp->s_dev_state != SCSA1394_DEV_SUSPENDED) 432 return; 433 434 /* 435 * Go through each lun and reset it to force a reconnect. 436 */ 437 for (i = 0; i < sp->s_nluns; i++) { 438 lp = &sp->s_lun[i]; 439 if (lp->l_ses != NULL) { /* Are we loged in? */ 440 scsa1394_sbp2_req_bus_reset(lp); 441 scsa1394_sbp2_req_reconnect(lp); 442 } 443 } 444 445 /* we are down so let the power get managed */ 446 (void) pm_idle_component(dip, 0); 447 } 448 449 450 451 /* 452 * 453 * --- configuration routines 454 * 455 */ 456 static void 457 scsa1394_cleanup(scsa1394_state_t *sp, int level) 458 { 459 ASSERT((level > 0) && (level <= SCSA1394_CLEANUP_LEVEL_MAX)); 460 461 switch (level) { 462 default: 463 scsa1394_remove_events(sp); 464 /* FALLTHRU */ 465 case 6: 466 scsa1394_detach_scsa(sp); 467 /* FALLTHRU */ 468 case 5: 469 scsa1394_destroy_cmd_cache(sp); 470 /* FALLTHRU */ 471 case 4: 472 scsa1394_detach_threads(sp); 473 /* FALLTHRU */ 474 case 3: 475 scsa1394_sbp2_detach(sp); 476 /* FALLTHRU */ 477 case 2: 478 scsa1394_detach_1394(sp); 479 /* FALLTHRU */ 480 case 1: 481 cv_destroy(&sp->s_event_cv); 482 mutex_destroy(&sp->s_mutex); 483 ddi_soft_state_free(scsa1394_statep, sp->s_instance); 484 } 485 } 486 487 static int 488 scsa1394_attach_1394(scsa1394_state_t *sp) 489 { 490 int ret; 491 492 if ((ret = t1394_attach(sp->s_dip, T1394_VERSION_V1, 0, 493 &sp->s_attachinfo, &sp->s_t1394_hdl)) != DDI_SUCCESS) { 494 return (ret); 495 } 496 497 /* DMA attributes for data buffers */ 498 sp->s_buf_dma_attr = sp->s_attachinfo.dma_attr; 499 500 /* DMA attributes for page tables */ 501 sp->s_pt_dma_attr = sp->s_attachinfo.dma_attr; 502 sp->s_pt_dma_attr.dma_attr_sgllen = 1; /* pt must be contiguous */ 503 504 if ((ret = t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0, 505 &sp->s_targetinfo)) != DDI_SUCCESS) { 506 (void) t1394_detach(&sp->s_t1394_hdl, 0); 507 return (ret); 508 } 509 510 return (DDI_SUCCESS); 511 } 512 513 static void 514 scsa1394_detach_1394(scsa1394_state_t *sp) 515 { 516 (void) t1394_detach(&sp->s_t1394_hdl, 0); 517 } 518 519 static int 520 scsa1394_attach_threads(scsa1394_state_t *sp) 521 { 522 char name[16]; 523 int nthr; 524 525 nthr = sp->s_nluns; 526 (void) snprintf(name, sizeof (name), "scsa1394%d", sp->s_instance); 527 if ((sp->s_taskq = ddi_taskq_create(sp->s_dip, name, nthr, 528 TASKQ_DEFAULTPRI, 0)) == NULL) { 529 return (DDI_FAILURE); 530 } 531 532 if (scsa1394_sbp2_threads_init(sp) != DDI_SUCCESS) { 533 ddi_taskq_destroy(sp->s_taskq); 534 return (DDI_FAILURE); 535 } 536 537 return (DDI_SUCCESS); 538 } 539 540 static void 541 scsa1394_detach_threads(scsa1394_state_t *sp) 542 { 543 scsa1394_sbp2_threads_fini(sp); 544 ddi_taskq_destroy(sp->s_taskq); 545 } 546 547 static int 548 scsa1394_attach_scsa(scsa1394_state_t *sp) 549 { 550 scsi_hba_tran_t *tran; 551 int ret; 552 553 sp->s_tran = tran = scsi_hba_tran_alloc(sp->s_dip, SCSI_HBA_CANSLEEP); 554 555 tran->tran_hba_private = sp; 556 tran->tran_tgt_private = NULL; 557 tran->tran_tgt_init = scsa1394_scsi_tgt_init; 558 tran->tran_tgt_probe = scsa1394_scsi_tgt_probe; 559 tran->tran_tgt_free = scsa1394_scsi_tgt_free; 560 tran->tran_start = scsa1394_scsi_start; 561 tran->tran_abort = scsa1394_scsi_abort; 562 tran->tran_reset = scsa1394_scsi_reset; 563 tran->tran_getcap = scsa1394_scsi_getcap; 564 tran->tran_setcap = scsa1394_scsi_setcap; 565 tran->tran_init_pkt = scsa1394_scsi_init_pkt; 566 tran->tran_destroy_pkt = scsa1394_scsi_destroy_pkt; 567 tran->tran_dmafree = scsa1394_scsi_dmafree; 568 tran->tran_sync_pkt = scsa1394_scsi_sync_pkt; 569 tran->tran_reset_notify = NULL; 570 tran->tran_get_bus_addr = NULL; 571 tran->tran_get_name = NULL; 572 tran->tran_bus_reset = NULL; 573 tran->tran_quiesce = NULL; 574 tran->tran_unquiesce = NULL; 575 tran->tran_get_eventcookie = NULL; 576 tran->tran_add_eventcall = NULL; 577 tran->tran_remove_eventcall = NULL; 578 tran->tran_post_event = NULL; 579 tran->tran_bus_config = scsa1394_scsi_bus_config; 580 tran->tran_bus_unconfig = scsa1394_scsi_bus_unconfig; 581 582 if ((ret = scsi_hba_attach_setup(sp->s_dip, &sp->s_attachinfo.dma_attr, 583 tran, 0)) != DDI_SUCCESS) { 584 scsi_hba_tran_free(tran); 585 return (ret); 586 } 587 588 return (DDI_SUCCESS); 589 } 590 591 static void 592 scsa1394_detach_scsa(scsa1394_state_t *sp) 593 { 594 int ret; 595 596 ret = scsi_hba_detach(sp->s_dip); 597 ASSERT(ret == DDI_SUCCESS); 598 599 scsi_hba_tran_free(sp->s_tran); 600 } 601 602 static int 603 scsa1394_create_cmd_cache(scsa1394_state_t *sp) 604 { 605 char name[64]; 606 607 (void) sprintf(name, "scsa1394%d_cache", sp->s_instance); 608 sp->s_cmd_cache = kmem_cache_create(name, 609 SCSA1394_CMD_SIZE, sizeof (void *), 610 scsa1394_cmd_cache_constructor, scsa1394_cmd_cache_destructor, 611 NULL, (void *)sp, NULL, 0); 612 613 return ((sp->s_cmd_cache == NULL) ? DDI_FAILURE : DDI_SUCCESS); 614 } 615 616 static void 617 scsa1394_destroy_cmd_cache(scsa1394_state_t *sp) 618 { 619 kmem_cache_destroy(sp->s_cmd_cache); 620 } 621 622 static int 623 scsa1394_add_events(scsa1394_state_t *sp) 624 { 625 ddi_eventcookie_t br_evc, rem_evc, ins_evc; 626 627 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_BUS_RESET_EVENT, 628 &br_evc) != DDI_SUCCESS) { 629 return (DDI_FAILURE); 630 } 631 if (ddi_add_event_handler(sp->s_dip, br_evc, scsa1394_bus_reset, 632 sp, &sp->s_reset_cb_id) != DDI_SUCCESS) { 633 return (DDI_FAILURE); 634 } 635 636 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_REMOVE_EVENT, 637 &rem_evc) != DDI_SUCCESS) { 638 (void) ddi_remove_event_handler(sp->s_reset_cb_id); 639 return (DDI_FAILURE); 640 } 641 if (ddi_add_event_handler(sp->s_dip, rem_evc, scsa1394_disconnect, 642 sp, &sp->s_remove_cb_id) != DDI_SUCCESS) { 643 (void) ddi_remove_event_handler(sp->s_reset_cb_id); 644 return (DDI_FAILURE); 645 } 646 647 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_INSERT_EVENT, 648 &ins_evc) != DDI_SUCCESS) { 649 (void) ddi_remove_event_handler(sp->s_remove_cb_id); 650 (void) ddi_remove_event_handler(sp->s_reset_cb_id); 651 return (DDI_FAILURE); 652 } 653 if (ddi_add_event_handler(sp->s_dip, ins_evc, scsa1394_reconnect, 654 sp, &sp->s_insert_cb_id) != DDI_SUCCESS) { 655 (void) ddi_remove_event_handler(sp->s_remove_cb_id); 656 (void) ddi_remove_event_handler(sp->s_reset_cb_id); 657 return (DDI_FAILURE); 658 } 659 660 return (DDI_SUCCESS); 661 } 662 663 static void 664 scsa1394_remove_events(scsa1394_state_t *sp) 665 { 666 ddi_eventcookie_t evc; 667 668 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_INSERT_EVENT, 669 &evc) == DDI_SUCCESS) { 670 (void) ddi_remove_event_handler(sp->s_insert_cb_id); 671 } 672 673 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_REMOVE_EVENT, 674 &evc) == DDI_SUCCESS) { 675 (void) ddi_remove_event_handler(sp->s_remove_cb_id); 676 } 677 678 if (ddi_get_eventcookie(sp->s_dip, DDI_DEVI_BUS_RESET_EVENT, 679 &evc) == DDI_SUCCESS) { 680 (void) ddi_remove_event_handler(sp->s_reset_cb_id); 681 } 682 } 683 684 /* 685 * 686 * --- device configuration 687 * 688 */ 689 static int 690 scsa1394_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op, 691 void *arg, dev_info_t **child) 692 { 693 scsa1394_state_t *sp = SCSA1394_INST2STATE(ddi_get_instance(dip)); 694 int ret; 695 696 if (scsa1394_bus_config_debug) { 697 flag |= NDI_DEVI_DEBUG; 698 } 699 700 ndi_devi_enter(dip); 701 if (DEVI(dip)->devi_child == NULL) { 702 scsa1394_create_children(sp); 703 } 704 ret = ndi_busop_bus_config(dip, flag, op, arg, child, 0); 705 ndi_devi_exit(dip); 706 707 return (ret); 708 } 709 710 static int 711 scsa1394_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op, 712 void *arg) 713 { 714 scsa1394_state_t *sp = SCSA1394_INST2STATE(ddi_get_instance(dip)); 715 int ret; 716 uint_t saved_flag = flag; 717 718 if (scsa1394_bus_config_debug) { 719 flag |= NDI_DEVI_DEBUG; 720 } 721 722 /* 723 * First offline and if offlining successful, then remove children. 724 */ 725 if (op == BUS_UNCONFIG_ALL) { 726 flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG); 727 } 728 729 ndi_devi_enter(dip); 730 731 ret = ndi_busop_bus_unconfig(dip, flag, op, arg); 732 733 /* 734 * If previous step was successful and not part of modunload daemon, 735 * attempt to remove children. 736 */ 737 if ((op == BUS_UNCONFIG_ALL) && (ret == NDI_SUCCESS) && 738 ((flag & NDI_AUTODETACH) == 0)) { 739 flag |= NDI_DEVI_REMOVE; 740 ret = ndi_busop_bus_unconfig(dip, flag, op, arg); 741 } 742 ndi_devi_exit(dip); 743 744 if ((ret != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) && 745 ((saved_flag & NDI_DEVI_REMOVE) != 0)) { 746 mutex_enter(&sp->s_mutex); 747 if (!sp->s_disconnect_warned) { 748 cmn_err(CE_WARN, "scsa1394(%d): " 749 "Disconnected device was busy, please reconnect.\n", 750 sp->s_instance); 751 sp->s_disconnect_warned = B_TRUE; 752 } 753 mutex_exit(&sp->s_mutex); 754 } 755 756 return (ret); 757 } 758 759 void 760 scsa1394_dtype2name(int dtype, char **node_name, char **driver_name) 761 { 762 static struct { 763 char *node_name; 764 char *driver_name; 765 } dtype2name[] = { 766 { "disk", "sd" }, /* DTYPE_DIRECT 0x00 */ 767 { "tape", "st" }, /* DTYPE_SEQUENTIAL 0x01 */ 768 { "printer", NULL }, /* DTYPE_PRINTER 0x02 */ 769 { "processor", NULL }, /* DTYPE_PROCESSOR 0x03 */ 770 { "worm", NULL }, /* DTYPE_WORM 0x04 */ 771 { "disk", "sd" }, /* DTYPE_RODIRECT 0x05 */ 772 { "scanner", NULL }, /* DTYPE_SCANNER 0x06 */ 773 { "disk", "sd" }, /* DTYPE_OPTICAL 0x07 */ 774 { "changer", NULL }, /* DTYPE_CHANGER 0x08 */ 775 { "comm", NULL }, /* DTYPE_COMM 0x09 */ 776 { "generic", NULL }, /* DTYPE_??? 0x0A */ 777 { "generic", NULL }, /* DTYPE_??? 0x0B */ 778 { "array_ctrl", NULL }, /* DTYPE_ARRAY_CTRL 0x0C */ 779 { "esi", "ses" }, /* DTYPE_ESI 0x0D */ 780 { "disk", "sd" } /* DTYPE_RBC 0x0E */ 781 }; 782 783 if (dtype < NELEM(dtype2name)) { 784 *node_name = dtype2name[dtype].node_name; 785 *driver_name = dtype2name[dtype].driver_name; 786 } else { 787 *node_name = "generic"; 788 *driver_name = NULL; 789 } 790 } 791 792 static void 793 scsa1394_create_children(scsa1394_state_t *sp) 794 { 795 char name[SCSA1394_COMPAT_MAX][16]; 796 char *compatible[SCSA1394_COMPAT_MAX]; 797 dev_info_t *cdip; 798 int i; 799 int dtype; 800 char *node_name; 801 char *driver_name; 802 int ret; 803 804 bzero(name, sizeof (name)); 805 (void) strcpy(name[0], "sd"); 806 for (i = 0; i < SCSA1394_COMPAT_MAX; i++) { 807 compatible[i] = name[i]; 808 } 809 810 for (i = 0; i < sp->s_nluns; i++) { 811 dtype = scsa1394_sbp2_get_lun_type(&sp->s_lun[i]); 812 scsa1394_dtype2name(dtype, &node_name, &driver_name); 813 814 ndi_devi_alloc_sleep(sp->s_dip, node_name, 815 (pnode_t)DEVI_SID_NODEID, &cdip); 816 817 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 818 SCSI_ADDR_PROP_TARGET, 0); 819 if (ret != DDI_PROP_SUCCESS) { 820 (void) ndi_devi_free(cdip); 821 continue; 822 } 823 824 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 825 SCSI_ADDR_PROP_LUN, i); 826 if (ret != DDI_PROP_SUCCESS) { 827 ddi_prop_remove_all(cdip); 828 (void) ndi_devi_free(cdip); 829 continue; 830 } 831 832 /* 833 * Some devices don't support LOG SENSE, so tell 834 * sd driver not to send this command. 835 */ 836 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 837 "pm-capable", 1); 838 if (ret != DDI_PROP_SUCCESS) { 839 ddi_prop_remove_all(cdip); 840 (void) ndi_devi_free(cdip); 841 continue; 842 } 843 844 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, 845 "hotpluggable"); 846 if (ret != DDI_PROP_SUCCESS) { 847 ddi_prop_remove_all(cdip); 848 (void) ndi_devi_free(cdip); 849 continue; 850 } 851 852 if (driver_name) { 853 compatible[0] = driver_name; 854 ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, 855 "compatible", (char **)compatible, 856 SCSA1394_COMPAT_MAX); 857 if (ret != DDI_PROP_SUCCESS) { 858 ddi_prop_remove_all(cdip); 859 (void) ndi_devi_free(cdip); 860 continue; 861 } 862 } 863 864 /* 865 * add property "scsa1394" to distinguish from others' children 866 */ 867 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394"); 868 if (ret != DDI_PROP_SUCCESS) { 869 ddi_prop_remove_all(cdip); 870 (void) ndi_devi_free(cdip); 871 continue; 872 } 873 874 (void) ddi_initchild(sp->s_dip, cdip); 875 } 876 } 877 878 /*ARGSUSED*/ 879 static void 880 scsa1394_bus_reset(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 881 void *data) 882 { 883 scsa1394_state_t *sp = arg; 884 885 if (sp != NULL) { 886 mutex_enter(&sp->s_mutex); 887 if (sp->s_dev_state == SCSA1394_DEV_DISCONNECTED) { 888 mutex_exit(&sp->s_mutex); 889 return; 890 } 891 sp->s_stat.stat_bus_reset_cnt++; 892 sp->s_dev_state = SCSA1394_DEV_BUS_RESET; 893 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data; 894 mutex_exit(&sp->s_mutex); 895 896 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_BUS_RESET); 897 } 898 } 899 900 /*ARGSUSED*/ 901 static void 902 scsa1394_disconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 903 void *data) 904 { 905 scsa1394_state_t *sp = arg; 906 dev_info_t *cdip, *cdip_next; 907 908 if (sp == NULL) { 909 return; 910 } 911 912 mutex_enter(&sp->s_mutex); 913 sp->s_stat.stat_disconnect_cnt++; 914 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED; 915 mutex_exit(&sp->s_mutex); 916 917 scsa1394_sbp2_disconnect(sp); 918 919 ndi_devi_enter(dip); 920 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) { 921 cdip_next = ddi_get_next_sibling(cdip); 922 923 mutex_enter(&DEVI(cdip)->devi_lock); 924 DEVI_SET_DEVICE_REMOVED(cdip); 925 mutex_exit(&DEVI(cdip)->devi_lock); 926 } 927 ndi_devi_exit(dip); 928 } 929 930 /*ARGSUSED*/ 931 static void 932 scsa1394_reconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 933 void *data) 934 { 935 scsa1394_state_t *sp = arg; 936 dev_info_t *cdip, *cdip_next; 937 938 if (sp == NULL) { 939 return; 940 } 941 942 mutex_enter(&sp->s_mutex); 943 sp->s_stat.stat_reconnect_cnt++; 944 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data; 945 sp->s_disconnect_warned = B_FALSE; 946 mutex_exit(&sp->s_mutex); 947 948 ndi_devi_enter(dip); 949 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) { 950 cdip_next = ddi_get_next_sibling(cdip); 951 952 mutex_enter(&DEVI(cdip)->devi_lock); 953 DEVI_SET_DEVICE_REINSERTED(cdip); 954 mutex_exit(&DEVI(cdip)->devi_lock); 955 } 956 ndi_devi_exit(dip); 957 958 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_RECONNECT); 959 } 960 961 /* 962 * 963 * --- SCSA entry points 964 * 965 */ 966 /*ARGSUSED*/ 967 static int 968 scsa1394_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran, 969 struct scsi_device *sd) 970 { 971 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 972 int lun; 973 int plen = sizeof (int); 974 int ret = DDI_FAILURE; 975 976 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF, 977 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, SCSI_ADDR_PROP_LUN, 978 (caddr_t)&lun, &plen) != DDI_PROP_SUCCESS) { 979 return (DDI_FAILURE); 980 } 981 982 if (!scsa1394_is_my_child(cdip)) { 983 /* 984 * add property "scsa1394" to distinguish from others' children 985 */ 986 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394"); 987 if (ret != DDI_PROP_SUCCESS) { 988 return (DDI_FAILURE); 989 } 990 991 if (scsa1394_dev_is_online(sp)) { 992 return (scsa1394_sbp2_login(sp, lun)); 993 } else { 994 return (DDI_FAILURE); 995 } 996 } 997 998 if ((lun >= sp->s_nluns) || (sp->s_lun[lun].l_cdip != NULL) || 999 !scsa1394_dev_is_online(sp)) { 1000 return (DDI_FAILURE); 1001 } 1002 1003 if ((ret = scsa1394_sbp2_login(sp, lun)) == DDI_SUCCESS) { 1004 sp->s_lun[lun].l_cdip = cdip; 1005 } 1006 return (ret); 1007 } 1008 1009 /*ARGSUSED*/ 1010 static void 1011 scsa1394_scsi_tgt_free(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran, 1012 struct scsi_device *sd) 1013 { 1014 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 1015 int lun; 1016 int plen = sizeof (int); 1017 1018 if (!scsa1394_is_my_child(cdip)) { 1019 return; 1020 } 1021 1022 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF, 1023 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, SCSI_ADDR_PROP_LUN, 1024 (caddr_t)&lun, &plen) != DDI_PROP_SUCCESS) { 1025 return; 1026 } 1027 1028 if ((lun < sp->s_nluns) && (sp->s_lun[lun].l_cdip == cdip)) { 1029 if (scsa1394_dev_is_online(sp)) { 1030 scsa1394_sbp2_logout(sp, lun, B_TRUE); 1031 } 1032 sp->s_lun[lun].l_cdip = NULL; 1033 } 1034 } 1035 1036 static int 1037 scsa1394_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)()) 1038 { 1039 dev_info_t *dip = ddi_get_parent(sd->sd_dev); 1040 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip); 1041 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 1042 scsa1394_lun_t *lp; 1043 1044 if (!scsa1394_dev_is_online(sp)) { 1045 return (SCSIPROBE_FAILURE); 1046 } 1047 lp = &sp->s_lun[sd->sd_address.a_lun]; 1048 1049 if (scsa1394_probe_g0_nodata(sd, waitfunc, 1050 SCMD_TEST_UNIT_READY, 0, 0) != SCSIPROBE_EXISTS) { 1051 lp->l_nosup_tur = B_TRUE; 1052 (void) scsa1394_sbp2_reset(lp, RESET_LUN, NULL); 1053 } 1054 if (scsa1394_probe_g0_nodata(sd, waitfunc, 1055 SCMD_START_STOP, 0, 1) != SCSIPROBE_EXISTS) { 1056 lp->l_nosup_start_stop = B_TRUE; 1057 } 1058 1059 /* standard probe issues INQUIRY, which some devices may not support */ 1060 if (scsi_hba_probe(sd, waitfunc) != SCSIPROBE_EXISTS) { 1061 lp->l_nosup_inquiry = B_TRUE; 1062 scsa1394_sbp2_fake_inquiry(sp, &lp->l_fake_inq); 1063 bcopy(&lp->l_fake_inq, sd->sd_inq, SUN_INQSIZE); 1064 #ifndef __lock_lint 1065 lp->l_rmb_orig = 1; 1066 #endif 1067 } 1068 1069 if (scsa1394_wrka_fake_rmb) { 1070 sd->sd_inq->inq_rmb = 1; 1071 } 1072 1073 return (SCSIPROBE_EXISTS); 1074 } 1075 1076 static int 1077 scsa1394_probe_g0_nodata(struct scsi_device *sd, int (*waitfunc)(), 1078 uchar_t cmd, uint_t addr, uint_t cnt) 1079 { 1080 struct scsi_pkt *pkt; 1081 int ret = SCSIPROBE_EXISTS; 1082 1083 pkt = scsi_init_pkt(&sd->sd_address, NULL, NULL, CDB_GROUP0, 1084 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, waitfunc, NULL); 1085 1086 if (pkt == NULL) { 1087 return (SCSIPROBE_NOMEM); 1088 } 1089 1090 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, cmd, addr, cnt, 1091 0); 1092 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = sd->sd_address.a_lun; 1093 pkt->pkt_flags = FLAG_NOINTR; 1094 1095 if (scsa1394_probe_tran(pkt) < 0) { 1096 if (pkt->pkt_reason == CMD_INCOMPLETE) { 1097 ret = SCSIPROBE_NORESP; 1098 } else if ((pkt->pkt_reason == CMD_TRAN_ERR) && 1099 ((*(pkt->pkt_scbp) & STATUS_MASK) == STATUS_CHECK) && 1100 (pkt->pkt_state & STATE_ARQ_DONE)) { 1101 ret = SCSIPROBE_EXISTS; 1102 } else { 1103 ret = SCSIPROBE_FAILURE; 1104 } 1105 } 1106 1107 scsi_destroy_pkt(pkt); 1108 1109 return (ret); 1110 } 1111 1112 static int 1113 scsa1394_probe_tran(struct scsi_pkt *pkt) 1114 { 1115 pkt->pkt_time = SCSA1394_PROBE_TIMEOUT; 1116 1117 if (scsi_transport(pkt) != TRAN_ACCEPT) { 1118 return (-1); 1119 } else if ((pkt->pkt_reason == CMD_INCOMPLETE) && 1120 (pkt->pkt_state == 0)) { 1121 return (-1); 1122 } else if (pkt->pkt_reason != CMD_CMPLT) { 1123 return (-1); 1124 } else if (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_BUSY) { 1125 return (0); 1126 } 1127 return (0); 1128 } 1129 1130 /*ARGSUSED*/ 1131 static int 1132 scsa1394_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 1133 { 1134 return (0); 1135 } 1136 1137 static int 1138 scsa1394_scsi_reset(struct scsi_address *ap, int level) 1139 { 1140 scsa1394_state_t *sp = ADDR2STATE(ap); 1141 scsa1394_lun_t *lp; 1142 int ret; 1143 1144 switch (level) { 1145 case RESET_ALL: 1146 case RESET_TARGET: 1147 lp = &sp->s_lun[0]; 1148 break; 1149 case RESET_LUN: 1150 lp = &sp->s_lun[ap->a_lun]; 1151 break; 1152 default: 1153 return (DDI_FAILURE); 1154 } 1155 1156 ret = scsa1394_sbp2_reset(lp, level, NULL); 1157 1158 return ((ret == SBP2_SUCCESS) ? 1 : 0); 1159 } 1160 1161 /*ARGSUSED*/ 1162 static int 1163 scsa1394_scsi_getcap(struct scsi_address *ap, char *cap, int whom) 1164 { 1165 scsa1394_state_t *sp = ADDR2STATE(ap); 1166 size_t dev_bsize_cap; 1167 int ret = -1; 1168 1169 if (!scsa1394_dev_is_online(sp)) { 1170 return (-1); 1171 } 1172 1173 if (cap == NULL) { 1174 return (-1); 1175 } 1176 1177 switch (scsi_hba_lookup_capstr(cap)) { 1178 case SCSI_CAP_DMA_MAX: 1179 ret = sp->s_attachinfo.dma_attr.dma_attr_maxxfer; 1180 break; 1181 case SCSI_CAP_SCSI_VERSION: 1182 ret = SCSI_VERSION_2; 1183 break; 1184 case SCSI_CAP_ARQ: 1185 ret = 1; 1186 break; 1187 case SCSI_CAP_UNTAGGED_QING: 1188 ret = 1; 1189 break; 1190 case SCSI_CAP_GEOMETRY: 1191 dev_bsize_cap = sp->s_totalsec; 1192 1193 if (sp->s_secsz > DEV_BSIZE) { 1194 dev_bsize_cap *= sp->s_secsz / DEV_BSIZE; 1195 } else if (sp->s_secsz < DEV_BSIZE) { 1196 dev_bsize_cap /= DEV_BSIZE / sp->s_secsz; 1197 } 1198 1199 if (dev_bsize_cap < 65536 * 2 * 18) { /* < ~1GB */ 1200 /* unlabeled floppy, 18k per cylinder */ 1201 ret = ((2 << 16) | 18); 1202 } else if (dev_bsize_cap < 65536 * 64 * 32) { /* < 64GB */ 1203 /* 1024k per cylinder */ 1204 ret = ((64 << 16) | 32); 1205 } else if (dev_bsize_cap < 65536 * 255 * 63) { /* < ~500GB */ 1206 /* ~8m per cylinder */ 1207 ret = ((255 << 16) | 63); 1208 } else { /* .. 8TB */ 1209 /* 64m per cylinder */ 1210 ret = ((512 << 16) | 256); 1211 } 1212 break; 1213 default: 1214 break; 1215 } 1216 1217 return (ret); 1218 } 1219 1220 /*ARGSUSED*/ 1221 static int 1222 scsa1394_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom) 1223 { 1224 scsa1394_state_t *sp = ADDR2STATE(ap); 1225 int ret = -1; 1226 1227 if (!scsa1394_dev_is_online(sp)) { 1228 return (-1); 1229 } 1230 1231 switch (scsi_hba_lookup_capstr(cap)) { 1232 case SCSI_CAP_ARQ: 1233 ret = 1; 1234 break; 1235 case SCSI_CAP_DMA_MAX: 1236 case SCSI_CAP_SCSI_VERSION: 1237 case SCSI_CAP_UNTAGGED_QING: 1238 /* supported but not settable */ 1239 ret = 0; 1240 break; 1241 case SCSI_CAP_SECTOR_SIZE: 1242 if (value) { 1243 sp->s_secsz = value; 1244 } 1245 break; 1246 case SCSI_CAP_TOTAL_SECTORS: 1247 if (value) { 1248 sp->s_totalsec = value; 1249 } 1250 break; 1251 default: 1252 break; 1253 } 1254 1255 return (ret); 1256 } 1257 1258 /*ARGSUSED*/ 1259 static void 1260 scsa1394_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1261 { 1262 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1263 1264 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1265 (void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0, 1266 (cmd->sc_flags & SCSA1394_CMD_READ) ? 1267 DDI_DMA_SYNC_FORCPU : DDI_DMA_SYNC_FORDEV); 1268 } 1269 } 1270 1271 /* 1272 * 1273 * --- pkt resource allocation routines 1274 * 1275 */ 1276 static struct scsi_pkt * 1277 scsa1394_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 1278 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 1279 int (*callback)(), caddr_t arg) 1280 { 1281 scsa1394_state_t *sp = ADDR2STATE(ap); 1282 scsa1394_lun_t *lp; 1283 scsa1394_cmd_t *cmd; 1284 boolean_t is_new; /* new cmd is being allocated */ 1285 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 1286 1287 if (ap->a_lun >= sp->s_nluns) { 1288 return (NULL); 1289 } 1290 lp = &sp->s_lun[ap->a_lun]; 1291 1292 /* 1293 * allocate cmd space 1294 */ 1295 if (pkt == NULL) { 1296 is_new = B_TRUE; 1297 if ((cmd = kmem_cache_alloc(sp->s_cmd_cache, kf)) == NULL) { 1298 return (NULL); 1299 } 1300 1301 /* initialize cmd */ 1302 pkt = &cmd->sc_scsi_pkt; 1303 pkt->pkt_ha_private = cmd; 1304 pkt->pkt_address = *ap; 1305 pkt->pkt_private = cmd->sc_priv; 1306 pkt->pkt_scbp = (uchar_t *)&cmd->sc_scb; 1307 pkt->pkt_cdbp = (uchar_t *)&cmd->sc_pkt_cdb; 1308 pkt->pkt_resid = 0; 1309 1310 cmd->sc_lun = lp; 1311 cmd->sc_pkt = pkt; 1312 cmd->sc_cdb_len = cmdlen; 1313 cmd->sc_scb_len = statuslen; 1314 cmd->sc_priv_len = tgtlen; 1315 1316 /* need external space? */ 1317 if ((cmdlen > sizeof (cmd->sc_pkt_cdb)) || 1318 (statuslen > sizeof (cmd->sc_scb)) || 1319 (tgtlen > sizeof (cmd->sc_priv))) { 1320 if (scsa1394_cmd_ext_alloc(sp, cmd, kf) != 1321 DDI_SUCCESS) { 1322 kmem_cache_free(sp->s_cmd_cache, cmd); 1323 lp->l_stat.stat_err_pkt_kmem_alloc++; 1324 return (NULL); 1325 } 1326 } 1327 1328 /* allocate DMA resources for CDB */ 1329 if (scsa1394_cmd_cdb_dma_alloc(sp, cmd, flags, callback, arg) != 1330 DDI_SUCCESS) { 1331 scsa1394_scsi_destroy_pkt(ap, pkt); 1332 return (NULL); 1333 } 1334 } else { 1335 is_new = B_FALSE; 1336 cmd = PKT2CMD(pkt); 1337 } 1338 1339 cmd->sc_flags &= ~SCSA1394_CMD_RDWR; 1340 1341 /* allocate/move DMA resources for data buffer */ 1342 if ((bp != NULL) && (bp->b_bcount > 0)) { 1343 if ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) == 0) { 1344 if (scsa1394_cmd_buf_dma_alloc(sp, cmd, flags, callback, 1345 arg, bp) != DDI_SUCCESS) { 1346 if (is_new) { 1347 scsa1394_scsi_destroy_pkt(ap, pkt); 1348 } 1349 return (NULL); 1350 } 1351 } else { 1352 if (scsa1394_cmd_buf_dma_move(sp, cmd) != DDI_SUCCESS) { 1353 return (NULL); 1354 } 1355 } 1356 1357 ASSERT(cmd->sc_win_len > 0); 1358 pkt->pkt_resid = bp->b_bcount - cmd->sc_win_len; 1359 } 1360 1361 /* 1362 * kernel virtual address may be required for certain workarounds 1363 * and in case of B_PHYS or B_PAGEIO, bp_mapin() will get it for us 1364 */ 1365 if ((bp != NULL) && ((bp->b_flags & (B_PAGEIO | B_PHYS)) != 0) && 1366 (bp->b_bcount < SCSA1394_MAPIN_SIZE_MAX) && 1367 ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) == 0)) { 1368 bp_mapin(bp); 1369 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_MAPIN; 1370 } 1371 1372 return (pkt); 1373 } 1374 1375 static void 1376 scsa1394_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1377 { 1378 scsa1394_state_t *sp = ADDR2STATE(ap); 1379 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1380 1381 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1382 scsa1394_cmd_buf_dma_free(sp, cmd); 1383 } 1384 if (cmd->sc_flags & SCSA1394_CMD_DMA_CDB_VALID) { 1385 scsa1394_cmd_cdb_dma_free(sp, cmd); 1386 } 1387 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) { 1388 bp_mapout(cmd->sc_bp); 1389 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN; 1390 } 1391 if (cmd->sc_flags & SCSA1394_CMD_EXT) { 1392 scsa1394_cmd_ext_free(sp, cmd); 1393 } 1394 1395 kmem_cache_free(sp->s_cmd_cache, cmd); 1396 } 1397 1398 static void 1399 scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 1400 { 1401 scsa1394_state_t *sp = ADDR2STATE(ap); 1402 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1403 1404 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1405 scsa1394_cmd_buf_dma_free(sp, cmd); 1406 } 1407 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) { 1408 bp_mapout(cmd->sc_bp); 1409 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN; 1410 } 1411 } 1412 1413 /*ARGSUSED*/ 1414 static int 1415 scsa1394_cmd_cache_constructor(void *buf, void *cdrarg, int kf) 1416 { 1417 scsa1394_cmd_t *cmd = buf; 1418 1419 bzero(buf, SCSA1394_CMD_SIZE); 1420 cmd->sc_task.ts_drv_priv = cmd; 1421 1422 return (0); 1423 } 1424 1425 /*ARGSUSED*/ 1426 static void 1427 scsa1394_cmd_cache_destructor(void *buf, void *cdrarg) 1428 { 1429 } 1430 1431 /* 1432 * allocate and deallocate external cmd space (ie. not part of scsa1394_cmd_t) 1433 * for non-standard length cdb, pkt_private, status areas 1434 */ 1435 static int 1436 scsa1394_cmd_ext_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, int kf) 1437 { 1438 struct scsi_pkt *pkt = cmd->sc_pkt; 1439 void *buf; 1440 1441 if (cmd->sc_cdb_len > sizeof (cmd->sc_pkt_cdb)) { 1442 if ((buf = kmem_zalloc(cmd->sc_cdb_len, kf)) == NULL) { 1443 return (DDI_FAILURE); 1444 } 1445 pkt->pkt_cdbp = buf; 1446 cmd->sc_flags |= SCSA1394_CMD_CDB_EXT; 1447 } 1448 1449 if (cmd->sc_scb_len > sizeof (cmd->sc_scb)) { 1450 if ((buf = kmem_zalloc(cmd->sc_scb_len, kf)) == NULL) { 1451 scsa1394_cmd_ext_free(sp, cmd); 1452 return (DDI_FAILURE); 1453 } 1454 pkt->pkt_scbp = buf; 1455 cmd->sc_flags |= SCSA1394_CMD_SCB_EXT; 1456 } 1457 1458 if (cmd->sc_priv_len > sizeof (cmd->sc_priv)) { 1459 if ((buf = kmem_zalloc(cmd->sc_priv_len, kf)) == NULL) { 1460 scsa1394_cmd_ext_free(sp, cmd); 1461 return (DDI_FAILURE); 1462 } 1463 pkt->pkt_private = buf; 1464 cmd->sc_flags |= SCSA1394_CMD_PRIV_EXT; 1465 } 1466 1467 return (DDI_SUCCESS); 1468 } 1469 1470 /*ARGSUSED*/ 1471 static void 1472 scsa1394_cmd_ext_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1473 { 1474 struct scsi_pkt *pkt = cmd->sc_pkt; 1475 1476 if (cmd->sc_flags & SCSA1394_CMD_CDB_EXT) { 1477 kmem_free(pkt->pkt_cdbp, cmd->sc_cdb_len); 1478 } 1479 if (cmd->sc_flags & SCSA1394_CMD_SCB_EXT) { 1480 kmem_free(pkt->pkt_scbp, cmd->sc_scb_len); 1481 } 1482 if (cmd->sc_flags & SCSA1394_CMD_PRIV_EXT) { 1483 kmem_free(pkt->pkt_private, cmd->sc_priv_len); 1484 } 1485 cmd->sc_flags &= ~SCSA1394_CMD_EXT; 1486 } 1487 1488 /*ARGSUSED*/ 1489 static int 1490 scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1491 int flags, int (*callback)(), caddr_t arg) 1492 { 1493 if (sbp2_task_orb_alloc(cmd->sc_lun->l_lun, &cmd->sc_task, 1494 sizeof (scsa1394_cmd_orb_t)) != SBP2_SUCCESS) { 1495 return (DDI_FAILURE); 1496 } 1497 1498 cmd->sc_flags |= SCSA1394_CMD_DMA_CDB_VALID; 1499 return (DDI_SUCCESS); 1500 } 1501 1502 /*ARGSUSED*/ 1503 static void 1504 scsa1394_cmd_cdb_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1505 { 1506 sbp2_task_orb_free(cmd->sc_lun->l_lun, &cmd->sc_task); 1507 cmd->sc_flags &= ~SCSA1394_CMD_DMA_CDB_VALID; 1508 } 1509 1510 /* 1511 * buffer resources 1512 */ 1513 static int 1514 scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1515 int flags, int (*callback)(), caddr_t arg, struct buf *bp) 1516 { 1517 scsa1394_lun_t *lp = cmd->sc_lun; 1518 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 1519 int dma_flags; 1520 ddi_dma_cookie_t dmac; 1521 uint_t ccount; 1522 int error; 1523 int ret; 1524 1525 cmd->sc_bp = bp; 1526 1527 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_buf_dma_attr, callback, 1528 NULL, &cmd->sc_buf_dma_hdl)) != DDI_SUCCESS) { 1529 bioerror(bp, 0); 1530 return (DDI_FAILURE); 1531 } 1532 1533 cmd->sc_flags &= ~SCSA1394_CMD_RDWR; 1534 if (bp->b_flags & B_READ) { 1535 dma_flags = DDI_DMA_READ; 1536 cmd->sc_flags |= SCSA1394_CMD_READ; 1537 } else { 1538 dma_flags = DDI_DMA_WRITE; 1539 cmd->sc_flags |= SCSA1394_CMD_WRITE; 1540 } 1541 if (flags & PKT_CONSISTENT) { 1542 dma_flags |= DDI_DMA_CONSISTENT; 1543 } 1544 if (flags & PKT_DMA_PARTIAL) { 1545 dma_flags |= DDI_DMA_PARTIAL; 1546 } 1547 1548 ret = ddi_dma_buf_bind_handle(cmd->sc_buf_dma_hdl, bp, dma_flags, 1549 callback, arg, &dmac, &ccount); 1550 1551 switch (ret) { 1552 case DDI_DMA_MAPPED: 1553 cmd->sc_nwin = 1; 1554 cmd->sc_curwin = 0; 1555 cmd->sc_win_offset = 0; 1556 cmd->sc_win_len = bp->b_bcount; 1557 break; 1558 1559 case DDI_DMA_PARTIAL_MAP: 1560 /* retrieve number of windows and first window cookie */ 1561 cmd->sc_curwin = 0; 1562 if ((ddi_dma_numwin(cmd->sc_buf_dma_hdl, &cmd->sc_nwin) != 1563 DDI_SUCCESS) || 1564 (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin, 1565 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) != 1566 DDI_SUCCESS)) { 1567 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl); 1568 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1569 return (DDI_FAILURE); 1570 } 1571 lp->l_stat.stat_cmd_buf_dma_partial++; 1572 break; 1573 1574 case DDI_DMA_NORESOURCES: 1575 error = 0; 1576 goto map_error; 1577 1578 case DDI_DMA_BADATTR: 1579 case DDI_DMA_NOMAPPING: 1580 error = EFAULT; 1581 goto map_error; 1582 1583 default: 1584 error = EINVAL; 1585 1586 map_error: 1587 bioerror(bp, error); 1588 lp->l_stat.stat_err_cmd_buf_dbind++; 1589 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1590 return (DDI_FAILURE); 1591 } 1592 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_BIND_VALID; 1593 1594 /* 1595 * setup page table if needed 1596 */ 1597 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) && 1598 (!sp->s_symbios || 1599 (dmac.dmac_size <= scsa1394_symbios_page_size))) { 1600 cmd->sc_buf_nsegs = 1; 1601 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size; 1602 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address; 1603 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem; 1604 } else { 1605 /* break window into segments */ 1606 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, kf) != 1607 DDI_SUCCESS) { 1608 scsa1394_cmd_buf_dma_free(sp, cmd); 1609 bioerror(bp, 0); 1610 return (DDI_FAILURE); 1611 } 1612 1613 /* allocate DMA resources for page table */ 1614 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, callback, arg, 1615 cmd->sc_buf_nsegs) != DDI_SUCCESS) { 1616 scsa1394_cmd_buf_dma_free(sp, cmd); 1617 bioerror(bp, 0); 1618 return (DDI_FAILURE); 1619 } 1620 } 1621 1622 /* allocate 1394 addresses for segments */ 1623 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) { 1624 scsa1394_cmd_buf_dma_free(sp, cmd); 1625 bioerror(bp, 0); 1626 return (DDI_FAILURE); 1627 } 1628 1629 return (DDI_SUCCESS); 1630 } 1631 1632 static void 1633 scsa1394_cmd_buf_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1634 { 1635 scsa1394_cmd_buf_addr_free(sp, cmd); 1636 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1637 scsa1394_cmd_pt_dma_free(sp, cmd); 1638 } 1639 scsa1394_cmd_seg_free(sp, cmd); 1640 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_BIND_VALID) { 1641 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl); 1642 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1643 } 1644 cmd->sc_flags &= ~(SCSA1394_CMD_DMA_BUF_VALID | SCSA1394_CMD_RDWR); 1645 } 1646 1647 /* 1648 * Break a set DMA cookies into segments suitable for SBP-2 page table. 1649 * This routine can reuse/reallocate segment array from previous calls. 1650 */ 1651 static int 1652 scsa1394_cmd_dmac2seg(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1653 ddi_dma_cookie_t *dmac, uint_t ccount, int kf) 1654 { 1655 scsa1394_lun_t *lp = cmd->sc_lun; 1656 int i; 1657 int nsegs; 1658 size_t segsize_max; 1659 size_t dmac_resid; 1660 uint32_t dmac_addr; 1661 scsa1394_cmd_seg_t *seg; 1662 1663 if (!sp->s_symbios) { 1664 /* 1665 * Number of segments is unknown at this point. Start with 1666 * a reasonable estimate and grow it later if needed. 1667 */ 1668 nsegs = max(ccount, cmd->sc_win_len / SBP2_PT_SEGSIZE_MAX) * 2; 1669 segsize_max = SBP2_PT_SEGSIZE_MAX; 1670 } else { 1671 /* 1672 * For Symbios workaround we know exactly the number of segments 1673 * Additional segment may be needed if buffer is not aligned. 1674 */ 1675 nsegs = 1676 howmany(cmd->sc_win_len, scsa1394_symbios_page_size) + 1; 1677 segsize_max = scsa1394_symbios_page_size; 1678 } 1679 1680 if (nsegs > cmd->sc_buf_nsegs_alloc) { 1681 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc(cmd->sc_buf_seg, 1682 cmd->sc_buf_nsegs_alloc, nsegs, 1683 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) { 1684 cmd->sc_buf_nsegs_alloc = 0; 1685 return (DDI_FAILURE); 1686 } 1687 cmd->sc_buf_nsegs_alloc = nsegs; 1688 } 1689 1690 /* each cookie maps into one or more segments */ 1691 cmd->sc_buf_nsegs = 0; 1692 i = ccount; 1693 for (;;) { 1694 dmac_resid = dmac->dmac_size; 1695 dmac_addr = dmac->dmac_address; 1696 while (dmac_resid > 0) { 1697 /* grow array if needed */ 1698 if (cmd->sc_buf_nsegs >= cmd->sc_buf_nsegs_alloc) { 1699 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc( 1700 cmd->sc_buf_seg, 1701 cmd->sc_buf_nsegs_alloc, 1702 cmd->sc_buf_nsegs_alloc + ccount, 1703 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) { 1704 return (DDI_FAILURE); 1705 } 1706 cmd->sc_buf_nsegs_alloc += ccount; 1707 } 1708 1709 seg = &cmd->sc_buf_seg[cmd->sc_buf_nsegs]; 1710 seg->ss_len = min(dmac_resid, segsize_max); 1711 seg->ss_daddr = (uint64_t)dmac_addr; 1712 dmac_addr += seg->ss_len; 1713 dmac_resid -= seg->ss_len; 1714 cmd->sc_buf_nsegs++; 1715 } 1716 ASSERT(dmac_resid == 0); 1717 1718 /* grab next cookie */ 1719 if (--i <= 0) { 1720 break; 1721 } 1722 ddi_dma_nextcookie(cmd->sc_buf_dma_hdl, dmac); 1723 } 1724 1725 if (cmd->sc_buf_nsegs > lp->l_stat.stat_cmd_buf_max_nsegs) { 1726 lp->l_stat.stat_cmd_buf_max_nsegs = cmd->sc_buf_nsegs; 1727 } 1728 1729 return (DDI_SUCCESS); 1730 } 1731 1732 /*ARGSUSED*/ 1733 static void 1734 scsa1394_cmd_seg_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1735 { 1736 if (cmd->sc_buf_nsegs_alloc > 0) { 1737 kmem_free(cmd->sc_buf_seg, cmd->sc_buf_nsegs_alloc * 1738 sizeof (scsa1394_cmd_seg_t)); 1739 } 1740 cmd->sc_buf_seg = NULL; 1741 cmd->sc_buf_nsegs = 0; 1742 cmd->sc_buf_nsegs_alloc = 0; 1743 } 1744 1745 static int 1746 scsa1394_cmd_pt_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1747 int (*callback)(), caddr_t arg, int cnt) 1748 { 1749 scsa1394_lun_t *lp = cmd->sc_lun; 1750 size_t len, rlen; 1751 uint_t ccount; 1752 t1394_alloc_addr_t aa; 1753 int result; 1754 1755 /* allocate DMA memory for page table */ 1756 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_pt_dma_attr, 1757 callback, NULL, &cmd->sc_pt_dma_hdl)) != DDI_SUCCESS) { 1758 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1759 return (DDI_FAILURE); 1760 } 1761 1762 cmd->sc_pt_ent_alloc = cnt; 1763 len = cmd->sc_pt_ent_alloc * SBP2_PT_ENT_SIZE; 1764 if (ddi_dma_mem_alloc(cmd->sc_pt_dma_hdl, len, 1765 &sp->s_attachinfo.acc_attr, DDI_DMA_CONSISTENT, callback, arg, 1766 &cmd->sc_pt_kaddr, &rlen, &cmd->sc_pt_acc_hdl) != DDI_SUCCESS) { 1767 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1768 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1769 return (DDI_FAILURE); 1770 } 1771 1772 if (ddi_dma_addr_bind_handle(cmd->sc_pt_dma_hdl, NULL, 1773 cmd->sc_pt_kaddr, len, DDI_DMA_READ | DDI_DMA_CONSISTENT, 1774 callback, arg, &cmd->sc_pt_dmac, &ccount) != DDI_DMA_MAPPED) { 1775 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1776 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1777 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1778 return (DDI_FAILURE); 1779 } 1780 ASSERT(ccount == 1); /* because dma_attr_sgllen is 1 */ 1781 1782 /* allocate 1394 address for page table */ 1783 aa.aa_type = T1394_ADDR_FIXED; 1784 aa.aa_length = len; 1785 aa.aa_address = cmd->sc_pt_dmac.dmac_address; 1786 aa.aa_evts.recv_read_request = NULL; 1787 aa.aa_evts.recv_write_request = NULL; 1788 aa.aa_evts.recv_lock_request = NULL; 1789 aa.aa_arg = NULL; 1790 aa.aa_kmem_bufp = NULL; 1791 aa.aa_enable = T1394_ADDR_RDENBL; 1792 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != DDI_SUCCESS) { 1793 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl); 1794 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1795 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1796 lp->l_stat.stat_err_cmd_pt_addr_alloc++; 1797 return (DDI_FAILURE); 1798 } 1799 ASSERT(aa.aa_address != 0); 1800 cmd->sc_pt_baddr = aa.aa_address; 1801 cmd->sc_pt_addr_hdl = aa.aa_hdl; 1802 1803 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_PT_VALID; 1804 1805 return (DDI_SUCCESS); 1806 } 1807 1808 static void 1809 scsa1394_cmd_pt_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1810 { 1811 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl); 1812 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1813 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1814 (void) t1394_free_addr(sp->s_t1394_hdl, &cmd->sc_pt_addr_hdl, 0); 1815 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_PT_VALID; 1816 } 1817 1818 /* 1819 * allocate 1394 addresses for all buffer segments 1820 */ 1821 static int 1822 scsa1394_cmd_buf_addr_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1823 { 1824 scsa1394_lun_t *lp = cmd->sc_lun; 1825 t1394_alloc_addr_t aa; 1826 scsa1394_cmd_seg_t *seg; 1827 int result; 1828 int i; 1829 1830 aa.aa_type = T1394_ADDR_FIXED; 1831 aa.aa_evts.recv_read_request = NULL; 1832 aa.aa_evts.recv_write_request = NULL; 1833 aa.aa_evts.recv_lock_request = NULL; 1834 aa.aa_arg = NULL; 1835 aa.aa_kmem_bufp = NULL; 1836 if (cmd->sc_flags & SCSA1394_CMD_READ) { 1837 aa.aa_enable = T1394_ADDR_RDENBL; 1838 } else { 1839 aa.aa_enable = T1394_ADDR_WRENBL; 1840 } 1841 1842 for (i = 0; i < cmd->sc_buf_nsegs; i++) { 1843 seg = &cmd->sc_buf_seg[i]; 1844 1845 /* segment bus address */ 1846 aa.aa_length = seg->ss_len; 1847 aa.aa_address = seg->ss_daddr; 1848 1849 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != 1850 DDI_SUCCESS) { 1851 lp->l_stat.stat_err_cmd_buf_addr_alloc++; 1852 return (DDI_FAILURE); 1853 } 1854 ASSERT(aa.aa_address != 0); 1855 seg->ss_baddr = aa.aa_address; 1856 seg->ss_addr_hdl = aa.aa_hdl; 1857 } 1858 1859 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_ADDR_VALID; 1860 1861 return (DDI_SUCCESS); 1862 } 1863 1864 static void 1865 scsa1394_cmd_buf_addr_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1866 { 1867 int i; 1868 1869 for (i = 0; i < cmd->sc_buf_nsegs; i++) { 1870 if (cmd->sc_buf_seg[i].ss_addr_hdl) { 1871 (void) t1394_free_addr(sp->s_t1394_hdl, 1872 &cmd->sc_buf_seg[i].ss_addr_hdl, 0); 1873 } 1874 } 1875 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_ADDR_VALID; 1876 } 1877 1878 /* 1879 * move to next DMA window 1880 */ 1881 static int 1882 scsa1394_cmd_buf_dma_move(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1883 { 1884 /* scsa1394_lun_t *lp = cmd->sc_lun; */ 1885 ddi_dma_cookie_t dmac; 1886 uint_t ccount; 1887 1888 /* for small pkts, leave things where they are (says WDD) */ 1889 if ((cmd->sc_curwin == cmd->sc_nwin) && (cmd->sc_nwin == 1)) { 1890 return (DDI_SUCCESS); 1891 } 1892 if (++cmd->sc_curwin >= cmd->sc_nwin) { 1893 return (DDI_FAILURE); 1894 } 1895 if (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin, 1896 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) != 1897 DDI_SUCCESS) { 1898 return (DDI_FAILURE); 1899 } 1900 1901 scsa1394_cmd_buf_addr_free(sp, cmd); 1902 1903 /* 1904 * setup page table if needed 1905 */ 1906 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) && 1907 (!sp->s_symbios || 1908 (dmac.dmac_size <= scsa1394_symbios_page_size))) { 1909 /* but first, free old resources */ 1910 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1911 scsa1394_cmd_pt_dma_free(sp, cmd); 1912 } 1913 scsa1394_cmd_seg_free(sp, cmd); 1914 1915 cmd->sc_buf_nsegs = 1; 1916 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size; 1917 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address; 1918 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem; 1919 } else { 1920 /* break window into segments */ 1921 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, KM_NOSLEEP) != 1922 DDI_SUCCESS) { 1923 return (DDI_FAILURE); 1924 } 1925 1926 /* allocate DMA resources */ 1927 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, NULL_FUNC, NULL, 1928 cmd->sc_buf_nsegs) != DDI_SUCCESS) { 1929 return (DDI_FAILURE); 1930 } 1931 } 1932 1933 /* allocate 1394 addresses for segments */ 1934 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) { 1935 return (DDI_FAILURE); 1936 } 1937 1938 return (DDI_SUCCESS); 1939 } 1940 1941 /* 1942 * 1943 * --- pkt and data transfer routines 1944 * 1945 */ 1946 static int 1947 scsa1394_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 1948 { 1949 scsa1394_state_t *sp = ADDR2STATE(ap); 1950 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1951 scsa1394_lun_t *lp = cmd->sc_lun; 1952 int ret; 1953 1954 /* 1955 * since we don't support polled I/O, just accept the packet 1956 * so the rest of the file systems get synced properly 1957 */ 1958 if (ddi_in_panic()) { 1959 scsa1394_prepare_pkt(sp, pkt); 1960 return (TRAN_ACCEPT); 1961 } 1962 1963 /* polling not supported yet */ 1964 if (pkt->pkt_flags & FLAG_NOINTR) { 1965 return (TRAN_BADPKT); 1966 } 1967 1968 mutex_enter(&sp->s_mutex); 1969 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { 1970 /* 1971 * If device is temporarily gone due to bus reset, 1972 * return busy to prevent prevent scary console messages. 1973 * If permanently gone, leave it to scsa1394_cmd_fake_comp(). 1974 */ 1975 if (sp->s_dev_state == SCSA1394_DEV_BUS_RESET) { 1976 mutex_exit(&sp->s_mutex); 1977 return (TRAN_BUSY); 1978 } 1979 } 1980 mutex_exit(&sp->s_mutex); 1981 1982 if ((ap->a_lun >= sp->s_nluns) || 1983 (ap->a_lun != pkt->pkt_address.a_lun)) { 1984 return (TRAN_BADPKT); 1985 } 1986 1987 scsa1394_prepare_pkt(sp, pkt); 1988 1989 /* some commands may require fake completion */ 1990 if ((ret = scsa1394_cmd_fake_comp(sp, cmd)) == DDI_SUCCESS) { 1991 return (TRAN_ACCEPT); 1992 } 1993 1994 scsa1394_cmd_fill_cdb(lp, cmd); 1995 1996 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1997 scsa1394_sbp2_seg2pt(lp, cmd); 1998 } 1999 2000 scsa1394_sbp2_cmd2orb(lp, cmd); /* convert into ORB */ 2001 2002 if ((ret = scsa1394_sbp2_start(lp, cmd)) != TRAN_BUSY) { 2003 scsa1394_sbp2_nudge(lp); 2004 } 2005 2006 return (ret); 2007 } 2008 2009 /*ARGSUSED*/ 2010 static void 2011 scsa1394_prepare_pkt(scsa1394_state_t *sp, struct scsi_pkt *pkt) 2012 { 2013 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 2014 2015 pkt->pkt_reason = CMD_CMPLT; 2016 pkt->pkt_state = 0; 2017 pkt->pkt_statistics = 0; 2018 *(pkt->pkt_scbp) = STATUS_GOOD; 2019 2020 if (cmd) { 2021 cmd->sc_timeout = pkt->pkt_time; 2022 2023 /* workarounds */ 2024 switch (pkt->pkt_cdbp[0]) { 2025 /* 2026 * sd does START_STOP_UNIT during attach with a 200 sec timeout. 2027 * at this time devi_lock is held, prtconf will be stuck. 2028 * reduce timeout for the time being. 2029 */ 2030 case SCMD_START_STOP: 2031 cmd->sc_timeout = min(cmd->sc_timeout, 2032 scsa1394_start_stop_timeout_max); 2033 break; 2034 default: 2035 break; 2036 } 2037 } 2038 } 2039 2040 static void 2041 scsa1394_cmd_fill_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2042 { 2043 cmd->sc_cdb_actual_len = cmd->sc_cdb_len; 2044 2045 mutex_enter(&lp->l_mutex); 2046 2047 switch (lp->l_dtype_orig) { 2048 case DTYPE_DIRECT: 2049 case DTYPE_RODIRECT: 2050 case DTYPE_OPTICAL: 2051 case SCSA1394_DTYPE_RBC: 2052 scsa1394_cmd_fill_cdb_rbc(lp, cmd); 2053 break; 2054 default: 2055 scsa1394_cmd_fill_cdb_other(lp, cmd); 2056 break; 2057 } 2058 2059 mutex_exit(&lp->l_mutex); 2060 } 2061 2062 static void 2063 scsa1394_cmd_fill_cdb_rbc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2064 { 2065 scsa1394_state_t *sp = lp->l_sp; 2066 struct scsi_pkt *pkt = CMD2PKT(cmd); 2067 int lba, opcode; 2068 struct buf *bp = cmd->sc_bp; 2069 size_t len; 2070 size_t blk_size; 2071 int sz; 2072 2073 opcode = pkt->pkt_cdbp[0]; 2074 blk_size = lp->l_lba_size; 2075 2076 switch (opcode) { 2077 case SCMD_READ: 2078 /* RBC only supports 10-byte read/write */ 2079 lba = SCSA1394_LBA_6BYTE(pkt); 2080 len = SCSA1394_LEN_6BYTE(pkt); 2081 opcode = SCMD_READ_G1; 2082 cmd->sc_cdb_actual_len = CDB_GROUP1; 2083 break; 2084 case SCMD_WRITE: 2085 lba = SCSA1394_LBA_6BYTE(pkt); 2086 len = SCSA1394_LEN_6BYTE(pkt); 2087 opcode = SCMD_WRITE_G1; 2088 cmd->sc_cdb_actual_len = CDB_GROUP1; 2089 break; 2090 case SCMD_READ_G1: 2091 case SCMD_READ_LONG: 2092 lba = SCSA1394_LBA_10BYTE(pkt); 2093 len = SCSA1394_LEN_10BYTE(pkt); 2094 break; 2095 case SCMD_WRITE_G1: 2096 case SCMD_WRITE_LONG: 2097 lba = SCSA1394_LBA_10BYTE(pkt); 2098 len = SCSA1394_LEN_10BYTE(pkt); 2099 if ((lp->l_dtype_orig == DTYPE_RODIRECT) && 2100 (bp != NULL) && (len != 0)) { 2101 sz = SCSA1394_CDRW_BLKSZ(bp->b_bcount, len); 2102 if (SCSA1394_VALID_CDRW_BLKSZ(sz)) { 2103 blk_size = sz; 2104 } 2105 } 2106 break; 2107 case SCMD_READ_CD: 2108 lba = SCSA1394_LBA_10BYTE(pkt); 2109 len = SCSA1394_LEN_READ_CD(pkt); 2110 blk_size = scsa1394_cmd_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2); 2111 break; 2112 case SCMD_READ_G5: 2113 lba = SCSA1394_LBA_12BYTE(pkt); 2114 len = SCSA1394_LEN_12BYTE(pkt); 2115 break; 2116 case SCMD_WRITE_G5: 2117 lba = SCSA1394_LBA_12BYTE(pkt); 2118 len = SCSA1394_LEN_12BYTE(pkt); 2119 break; 2120 default: 2121 /* no special mapping for other commands */ 2122 scsa1394_cmd_fill_cdb_other(lp, cmd); 2123 return; 2124 } 2125 cmd->sc_blk_size = blk_size; 2126 2127 /* limit xfer length for Symbios workaround */ 2128 if (sp->s_symbios && (len * blk_size > scsa1394_symbios_size_max)) { 2129 cmd->sc_flags |= SCSA1394_CMD_SYMBIOS_BREAKUP; 2130 2131 cmd->sc_total_blks = cmd->sc_resid_blks = len; 2132 2133 len = scsa1394_symbios_size_max / blk_size; 2134 } 2135 cmd->sc_xfer_blks = len; 2136 cmd->sc_xfer_bytes = len * blk_size; 2137 2138 /* finalize new CDB */ 2139 switch (pkt->pkt_cdbp[0]) { 2140 case SCMD_READ: 2141 case SCMD_WRITE: 2142 /* 2143 * We rewrite READ/WRITE G0 commands as READ/WRITE G1. 2144 * Build new cdb from scatch. 2145 * The lba and length fields is updated below. 2146 */ 2147 bzero(cmd->sc_cdb, cmd->sc_cdb_actual_len); 2148 break; 2149 default: 2150 /* 2151 * Copy the non lba/len fields. 2152 * The lba and length fields is updated below. 2153 */ 2154 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_actual_len); 2155 break; 2156 } 2157 2158 cmd->sc_cdb[0] = (uchar_t)opcode; 2159 scsa1394_cmd_fill_cdb_lba(cmd, lba); 2160 switch (opcode) { 2161 case SCMD_READ_CD: 2162 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len); 2163 break; 2164 case SCMD_WRITE_G5: 2165 case SCMD_READ_G5: 2166 scsa1394_cmd_fill_12byte_cdb_len(cmd, len); 2167 break; 2168 default: 2169 scsa1394_cmd_fill_cdb_len(cmd, len); 2170 break; 2171 } 2172 } 2173 2174 /*ARGSUSED*/ 2175 static void 2176 scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2177 { 2178 struct scsi_pkt *pkt = CMD2PKT(cmd); 2179 2180 cmd->sc_xfer_bytes = cmd->sc_win_len; 2181 cmd->sc_xfer_blks = cmd->sc_xfer_bytes / lp->l_lba_size; 2182 cmd->sc_total_blks = cmd->sc_xfer_blks; 2183 cmd->sc_lba = 0; 2184 2185 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len); 2186 } 2187 2188 /* 2189 * fill up parts of CDB 2190 */ 2191 static void 2192 scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *cmd, int len) 2193 { 2194 cmd->sc_cdb[7] = len >> 8; 2195 cmd->sc_cdb[8] = (uchar_t)len; 2196 } 2197 2198 static void 2199 scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *cmd, int lba) 2200 { 2201 cmd->sc_cdb[2] = lba >> 24; 2202 cmd->sc_cdb[3] = lba >> 16; 2203 cmd->sc_cdb[4] = lba >> 8; 2204 cmd->sc_cdb[5] = (uchar_t)lba; 2205 cmd->sc_lba = lba; 2206 } 2207 2208 static void 2209 scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *cmd, int len) 2210 { 2211 cmd->sc_cdb[6] = len >> 24; 2212 cmd->sc_cdb[7] = len >> 16; 2213 cmd->sc_cdb[8] = len >> 8; 2214 cmd->sc_cdb[9] = (uchar_t)len; 2215 } 2216 2217 static void 2218 scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *cmd, int len) 2219 { 2220 cmd->sc_cdb[6] = len >> 16; 2221 cmd->sc_cdb[7] = len >> 8; 2222 cmd->sc_cdb[8] = (uchar_t)len; 2223 } 2224 2225 /* 2226 * For SCMD_READ_CD, figure out the block size based on expected sector type. 2227 * See MMC SCSI Specs section 6.1.15 2228 */ 2229 static int 2230 scsa1394_cmd_read_cd_blk_size(uchar_t expected_sector_type) 2231 { 2232 int blk_size; 2233 2234 switch (expected_sector_type) { 2235 case READ_CD_EST_CDDA: 2236 blk_size = CDROM_BLK_2352; 2237 break; 2238 case READ_CD_EST_MODE2: 2239 blk_size = CDROM_BLK_2336; 2240 break; 2241 case READ_CD_EST_MODE2FORM2: 2242 blk_size = CDROM_BLK_2324; 2243 break; 2244 case READ_CD_EST_MODE2FORM1: 2245 case READ_CD_EST_ALLTYPE: 2246 case READ_CD_EST_MODE1: 2247 default: 2248 blk_size = CDROM_BLK_2048; 2249 } 2250 2251 return (blk_size); 2252 } 2253 2254 /*ARGSUSED*/ 2255 static int 2256 scsa1394_cmd_fake_mode_sense(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2257 { 2258 struct scsi_pkt *pkt = CMD2PKT(cmd); 2259 struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp; 2260 struct scsi_extended_sense *esp = &arqp->sts_sensedata; 2261 2262 *(pkt->pkt_scbp) = STATUS_CHECK; 2263 *(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD; 2264 arqp->sts_rqpkt_reason = CMD_CMPLT; 2265 arqp->sts_rqpkt_resid = 0; 2266 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA; 2267 arqp->sts_rqpkt_statistics = 0; 2268 2269 bzero(esp, sizeof (struct scsi_extended_sense)); 2270 2271 esp->es_class = CLASS_EXTENDED_SENSE; 2272 2273 esp->es_key = KEY_ILLEGAL_REQUEST; 2274 2275 pkt->pkt_reason = CMD_CMPLT; 2276 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2277 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2278 2279 if (pkt->pkt_comp) { 2280 (*pkt->pkt_comp)(pkt); 2281 } 2282 return (DDI_SUCCESS); 2283 } 2284 2285 /*ARGSUSED*/ 2286 static int 2287 scsa1394_cmd_fake_inquiry(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2288 { 2289 scsa1394_lun_t *lp = cmd->sc_lun; 2290 struct scsi_pkt *pkt = CMD2PKT(cmd); 2291 struct scsi_inquiry *inq; 2292 2293 /* copy fabricated inquiry data */ 2294 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr; 2295 bcopy(&lp->l_fake_inq, inq, sizeof (struct scsi_inquiry)); 2296 2297 pkt->pkt_resid -= sizeof (struct scsi_inquiry); 2298 pkt->pkt_reason = CMD_CMPLT; 2299 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2300 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2301 2302 if (pkt->pkt_comp) { 2303 (*pkt->pkt_comp)(pkt); 2304 } 2305 return (DDI_SUCCESS); 2306 } 2307 2308 /* 2309 * If command allows fake completion (without actually being transported), 2310 * call completion callback and return DDI_SUCCESS. 2311 * Otherwise return DDI_FAILURE. 2312 */ 2313 static int 2314 scsa1394_cmd_fake_comp(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2315 { 2316 struct scsi_pkt *pkt = CMD2PKT(cmd); 2317 scsa1394_lun_t *lp = cmd->sc_lun; 2318 int ret = DDI_SUCCESS; 2319 2320 /* 2321 * agreement with sd in case of device hot removal 2322 * is to fake completion with CMD_DEV_GONE 2323 */ 2324 mutex_enter(&sp->s_mutex); 2325 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { 2326 mutex_exit(&sp->s_mutex); 2327 pkt->pkt_reason = CMD_DEV_GONE; 2328 if (pkt->pkt_comp) { 2329 (*pkt->pkt_comp)(pkt); 2330 } 2331 return (DDI_SUCCESS); 2332 } 2333 mutex_exit(&sp->s_mutex); 2334 2335 mutex_enter(&lp->l_mutex); 2336 2337 switch (pkt->pkt_cdbp[0]) { 2338 /* 2339 * RBC support for PRIN/PROUT is optional 2340 */ 2341 case SCMD_PRIN: 2342 case SCMD_PROUT: 2343 if (!scsa1394_wrka_fake_prin) { 2344 ret = DDI_FAILURE; 2345 } 2346 break; 2347 /* 2348 * Some fixed disks don't like doorlock cmd. And they don't need it. 2349 */ 2350 case SCMD_DOORLOCK: 2351 if (lp->l_rmb_orig != 0) { 2352 ret = DDI_FAILURE; 2353 } 2354 break; 2355 case SCMD_TEST_UNIT_READY: 2356 if (!lp->l_nosup_tur) { 2357 ret = DDI_FAILURE; 2358 } 2359 break; 2360 case SCMD_START_STOP: 2361 if (!lp->l_nosup_start_stop) { 2362 ret = DDI_FAILURE; 2363 } 2364 break; 2365 case SCMD_INQUIRY: 2366 if (!lp->l_nosup_inquiry) { 2367 ret = DDI_FAILURE; 2368 } else { 2369 mutex_exit(&lp->l_mutex); 2370 return (scsa1394_cmd_fake_inquiry(sp, cmd)); 2371 } 2372 break; 2373 case SCMD_MODE_SENSE: 2374 if (!lp->l_mode_sense_fake) { 2375 ret = DDI_FAILURE; 2376 } else { 2377 mutex_exit(&lp->l_mutex); 2378 return (scsa1394_cmd_fake_mode_sense(sp, cmd)); 2379 } 2380 break; 2381 default: 2382 ret = DDI_FAILURE; 2383 } 2384 2385 mutex_exit(&lp->l_mutex); 2386 2387 if (ret != DDI_SUCCESS) { 2388 return (ret); 2389 } 2390 2391 ASSERT(*(pkt->pkt_scbp) == STATUS_GOOD); 2392 ASSERT(pkt->pkt_reason == CMD_CMPLT); 2393 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2394 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2395 2396 if (pkt->pkt_comp) { 2397 (*pkt->pkt_comp)(pkt); 2398 } 2399 return (DDI_SUCCESS); 2400 } 2401 2402 /* 2403 * Returns DDI_SUCCESS if next xfer setup successfully, DDI_FAILURE otherwise. 2404 */ 2405 static int 2406 scsa1394_cmd_setup_next_xfer(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2407 { 2408 struct scsi_pkt *pkt = CMD2PKT(cmd); 2409 2410 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP); 2411 2412 cmd->sc_resid_blks -= cmd->sc_xfer_blks; 2413 if (cmd->sc_resid_blks <= 0) { 2414 pkt->pkt_resid = 0; 2415 return (DDI_FAILURE); 2416 } 2417 2418 scsa1394_cmd_adjust_cdb(lp, cmd); 2419 2420 scsa1394_sbp2_seg2pt(lp, cmd); 2421 2422 scsa1394_sbp2_cmd2orb(lp, cmd); 2423 2424 if (scsa1394_sbp2_start(lp, cmd) != TRAN_ACCEPT) { 2425 pkt->pkt_resid = cmd->sc_resid_blks * cmd->sc_blk_size; 2426 return (DDI_FAILURE); 2427 } 2428 2429 return (DDI_SUCCESS); 2430 } 2431 2432 /* 2433 * new lba = current lba + previous xfer len 2434 */ 2435 /*ARGSUSED*/ 2436 static void 2437 scsa1394_cmd_adjust_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2438 { 2439 int len; 2440 2441 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP); 2442 2443 cmd->sc_lba += cmd->sc_xfer_blks; 2444 len = cmd->sc_resid_blks; 2445 2446 /* limit xfer length for Symbios workaround */ 2447 if (len * cmd->sc_blk_size > scsa1394_symbios_size_max) { 2448 len = scsa1394_symbios_size_max / cmd->sc_blk_size; 2449 } 2450 2451 switch (cmd->sc_cdb[0]) { 2452 case SCMD_READ_CD: 2453 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len); 2454 break; 2455 case SCMD_WRITE_G5: 2456 case SCMD_READ_G5: 2457 scsa1394_cmd_fill_12byte_cdb_len(cmd, len); 2458 break; 2459 case SCMD_WRITE_G1: 2460 case SCMD_WRITE_LONG: 2461 default: 2462 scsa1394_cmd_fill_cdb_len(cmd, len); 2463 } 2464 2465 scsa1394_cmd_fill_cdb_lba(cmd, cmd->sc_lba); 2466 2467 cmd->sc_xfer_blks = len; 2468 cmd->sc_xfer_bytes = len * cmd->sc_blk_size; 2469 } 2470 2471 void 2472 scsa1394_cmd_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2473 { 2474 struct scsi_pkt *pkt = CMD2PKT(cmd); 2475 2476 /* next iteration of partial xfer? */ 2477 if ((pkt->pkt_reason == CMD_CMPLT) && 2478 (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP)) { 2479 if (scsa1394_cmd_setup_next_xfer(lp, cmd) == DDI_SUCCESS) { 2480 return; 2481 } 2482 } 2483 cmd->sc_flags &= ~SCSA1394_CMD_SYMBIOS_BREAKUP; 2484 2485 /* apply workarounds */ 2486 if (pkt->pkt_reason == CMD_CMPLT) { 2487 scsa1394_cmd_status_wrka(lp, cmd); 2488 } 2489 2490 mutex_enter(&lp->l_mutex); 2491 2492 /* mode sense workaround */ 2493 if (pkt->pkt_cdbp[0] == SCMD_MODE_SENSE) { 2494 if (pkt->pkt_reason == CMD_CMPLT) { 2495 lp->l_mode_sense_fail_cnt = 0; 2496 } else if (++lp->l_mode_sense_fail_cnt >= 2497 scsa1394_mode_sense_fail_max) { 2498 lp->l_mode_sense_fake = B_TRUE; 2499 } 2500 } else { 2501 lp->l_mode_sense_fail_cnt = 0; 2502 } 2503 2504 mutex_exit(&lp->l_mutex); 2505 2506 if (pkt->pkt_comp) { 2507 (*pkt->pkt_comp)(pkt); 2508 } 2509 } 2510 2511 static void 2512 scsa1394_cmd_status_wrka(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2513 { 2514 struct scsi_pkt *pkt = CMD2PKT(cmd); 2515 2516 mutex_enter(&lp->l_mutex); 2517 2518 switch (pkt->pkt_cdbp[0]) { 2519 case SCMD_INQUIRY: { 2520 struct scsi_inquiry *inq; 2521 2522 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr; 2523 2524 /* change dtype RBC to DIRECT, sd doesn't support RBC */ 2525 lp->l_dtype_orig = inq->inq_dtype; 2526 if ((inq->inq_dtype == SCSA1394_DTYPE_RBC) && 2527 scsa1394_wrka_rbc2direct) { 2528 inq->inq_dtype = DTYPE_DIRECT; 2529 } 2530 2531 /* force RMB to 1 */ 2532 lp->l_rmb_orig = inq->inq_rmb; 2533 if (scsa1394_wrka_fake_rmb) { 2534 inq->inq_rmb = 1; 2535 } 2536 break; 2537 } 2538 case SCMD_READ_CAPACITY: { 2539 uint32_t *capacity_buf; 2540 2541 capacity_buf = (uint32_t *)cmd->sc_bp->b_un.b_addr; 2542 2543 if (lp->l_dtype_orig != DTYPE_RODIRECT) { 2544 lp->l_lba_size = min(BE_32(capacity_buf[1]), DEV_BSIZE); 2545 if (lp->l_lba_size == 0) { 2546 cmn_err(CE_WARN, "zero LBA size reported, " 2547 "possibly broken device"); 2548 lp->l_lba_size = DEV_BSIZE; 2549 } 2550 } else { 2551 lp->l_lba_size = 2048; 2552 } 2553 } 2554 default: 2555 break; 2556 } 2557 2558 mutex_exit(&lp->l_mutex); 2559 } 2560 2561 /* 2562 * --- thread management 2563 * 2564 * dispatch a thread 2565 */ 2566 int 2567 scsa1394_thr_dispatch(scsa1394_thread_t *thr) 2568 { 2569 scsa1394_lun_t *lp = thr->thr_lun; 2570 scsa1394_state_t *sp = lp->l_sp; 2571 int ret; 2572 2573 ASSERT(mutex_owned(&lp->l_mutex)); 2574 ASSERT(thr->thr_state == SCSA1394_THR_INIT); 2575 2576 thr->thr_state = SCSA1394_THR_RUN; 2577 2578 ret = ddi_taskq_dispatch(sp->s_taskq, thr->thr_func, thr->thr_arg, 2579 KM_SLEEP); 2580 return (ret); 2581 } 2582 2583 /* 2584 * cancel thread 2585 */ 2586 void 2587 scsa1394_thr_cancel(scsa1394_thread_t *thr) 2588 { 2589 scsa1394_lun_t *lp = thr->thr_lun; 2590 2591 ASSERT(mutex_owned(&lp->l_mutex)); 2592 2593 thr->thr_req |= SCSA1394_THREQ_EXIT; 2594 cv_signal(&thr->thr_cv); 2595 2596 /* wait until the thread actually exits */ 2597 do { 2598 if (cv_wait_sig(&thr->thr_cv, &lp->l_mutex) == 0) { 2599 break; 2600 } 2601 } while (thr->thr_state != SCSA1394_THR_EXIT); 2602 } 2603 2604 /* 2605 * wake thread 2606 */ 2607 void 2608 scsa1394_thr_wake(scsa1394_thread_t *thr, int req) 2609 { 2610 scsa1394_lun_t *lp = thr->thr_lun; 2611 2612 ASSERT(mutex_owned(&lp->l_mutex)); 2613 2614 thr->thr_req |= req; 2615 cv_signal(&thr->thr_cv); 2616 } 2617 2618 void 2619 scsa1394_thr_clear_req(scsa1394_thread_t *thr, int mask) 2620 { 2621 scsa1394_lun_t *lp = thr->thr_lun; 2622 2623 mutex_enter(&lp->l_mutex); 2624 thr->thr_req &= ~mask; 2625 mutex_exit(&lp->l_mutex); 2626 } 2627 2628 /* 2629 * 2630 * --- other routines 2631 * 2632 */ 2633 static boolean_t 2634 scsa1394_is_my_child(dev_info_t *dip) 2635 { 2636 return ((dip != NULL) && (ddi_prop_exists(DDI_DEV_T_ANY, dip, 2637 DDI_PROP_DONTPASS, "scsa1394") == 1)); 2638 } 2639 2640 boolean_t 2641 scsa1394_dev_is_online(scsa1394_state_t *sp) 2642 { 2643 boolean_t ret; 2644 2645 mutex_enter(&sp->s_mutex); 2646 ret = (sp->s_dev_state == SCSA1394_DEV_ONLINE); 2647 mutex_exit(&sp->s_mutex); 2648 2649 return (ret); 2650 } 2651 2652 static void * 2653 scsa1394_kmem_realloc(void *old_buf, int old_size, int new_size, size_t elsize, 2654 int kf) 2655 { 2656 void *new_buf; 2657 2658 new_buf = kmem_zalloc(new_size * elsize, kf); 2659 2660 if (old_size > 0) { 2661 if (new_buf != NULL) { 2662 bcopy(old_buf, new_buf, old_size * elsize); 2663 } 2664 kmem_free(old_buf, old_size * elsize); 2665 } 2666 2667 return (new_buf); 2668 } 2669