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