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, "target", 0); 817 if (ret != DDI_PROP_SUCCESS) { 818 (void) ndi_devi_free(cdip); 819 continue; 820 } 821 822 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", i); 823 if (ret != DDI_PROP_SUCCESS) { 824 ddi_prop_remove_all(cdip); 825 (void) ndi_devi_free(cdip); 826 continue; 827 } 828 829 /* 830 * Some devices don't support LOG SENSE, so tell 831 * sd driver not to send this command. 832 */ 833 ret = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 834 "pm-capable", 1); 835 if (ret != DDI_PROP_SUCCESS) { 836 ddi_prop_remove_all(cdip); 837 (void) ndi_devi_free(cdip); 838 continue; 839 } 840 841 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, 842 "hotpluggable"); 843 if (ret != DDI_PROP_SUCCESS) { 844 ddi_prop_remove_all(cdip); 845 (void) ndi_devi_free(cdip); 846 continue; 847 } 848 849 if (driver_name) { 850 compatible[0] = driver_name; 851 ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, 852 "compatible", (char **)compatible, 853 SCSA1394_COMPAT_MAX); 854 if (ret != DDI_PROP_SUCCESS) { 855 ddi_prop_remove_all(cdip); 856 (void) ndi_devi_free(cdip); 857 continue; 858 } 859 } 860 861 /* 862 * add property "scsa1394" to distinguish from others' children 863 */ 864 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394"); 865 if (ret != DDI_PROP_SUCCESS) { 866 ddi_prop_remove_all(cdip); 867 (void) ndi_devi_free(cdip); 868 continue; 869 } 870 871 (void) ddi_initchild(sp->s_dip, cdip); 872 } 873 } 874 875 /*ARGSUSED*/ 876 static void 877 scsa1394_bus_reset(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 878 void *data) 879 { 880 scsa1394_state_t *sp = arg; 881 882 if (sp != NULL) { 883 mutex_enter(&sp->s_mutex); 884 if (sp->s_dev_state == SCSA1394_DEV_DISCONNECTED) { 885 mutex_exit(&sp->s_mutex); 886 return; 887 } 888 sp->s_stat.stat_bus_reset_cnt++; 889 sp->s_dev_state = SCSA1394_DEV_BUS_RESET; 890 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data; 891 mutex_exit(&sp->s_mutex); 892 893 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_BUS_RESET); 894 } 895 } 896 897 /*ARGSUSED*/ 898 static void 899 scsa1394_disconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 900 void *data) 901 { 902 scsa1394_state_t *sp = arg; 903 int circ; 904 dev_info_t *cdip, *cdip_next; 905 906 if (sp == NULL) { 907 return; 908 } 909 910 mutex_enter(&sp->s_mutex); 911 sp->s_stat.stat_disconnect_cnt++; 912 sp->s_dev_state = SCSA1394_DEV_DISCONNECTED; 913 mutex_exit(&sp->s_mutex); 914 915 scsa1394_sbp2_disconnect(sp); 916 917 ndi_devi_enter(dip, &circ); 918 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) { 919 cdip_next = ddi_get_next_sibling(cdip); 920 921 mutex_enter(&DEVI(cdip)->devi_lock); 922 DEVI_SET_DEVICE_REMOVED(cdip); 923 mutex_exit(&DEVI(cdip)->devi_lock); 924 } 925 ndi_devi_exit(dip, circ); 926 } 927 928 /*ARGSUSED*/ 929 static void 930 scsa1394_reconnect(dev_info_t *dip, ddi_eventcookie_t evc, void *arg, 931 void *data) 932 { 933 scsa1394_state_t *sp = arg; 934 int circ; 935 dev_info_t *cdip, *cdip_next; 936 937 if (sp == NULL) { 938 return; 939 } 940 941 mutex_enter(&sp->s_mutex); 942 sp->s_stat.stat_reconnect_cnt++; 943 sp->s_attachinfo.localinfo = *(t1394_localinfo_t *)data; 944 sp->s_disconnect_warned = B_FALSE; 945 mutex_exit(&sp->s_mutex); 946 947 ndi_devi_enter(dip, &circ); 948 for (cdip = ddi_get_child(dip); cdip != NULL; cdip = cdip_next) { 949 cdip_next = ddi_get_next_sibling(cdip); 950 951 mutex_enter(&DEVI(cdip)->devi_lock); 952 DEVI_SET_DEVICE_REINSERTED(cdip); 953 mutex_exit(&DEVI(cdip)->devi_lock); 954 } 955 ndi_devi_exit(dip, circ); 956 957 scsa1394_sbp2_req(sp, 0, SCSA1394_THREQ_RECONNECT); 958 } 959 960 /* 961 * 962 * --- SCSA entry points 963 * 964 */ 965 /*ARGSUSED*/ 966 static int 967 scsa1394_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran, 968 struct scsi_device *sd) 969 { 970 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 971 int lun; 972 int plen = sizeof (int); 973 int ret = DDI_FAILURE; 974 975 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF, 976 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun, 977 &plen) != DDI_PROP_SUCCESS) { 978 return (DDI_FAILURE); 979 } 980 981 if (!scsa1394_is_my_child(cdip)) { 982 /* 983 * add property "scsa1394" to distinguish from others' children 984 */ 985 ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "scsa1394"); 986 if (ret != DDI_PROP_SUCCESS) { 987 return (DDI_FAILURE); 988 } 989 990 if (scsa1394_dev_is_online(sp)) { 991 return (scsa1394_sbp2_login(sp, lun)); 992 } else { 993 return (DDI_FAILURE); 994 } 995 } 996 997 if ((lun >= sp->s_nluns) || (sp->s_lun[lun].l_cdip != NULL) || 998 !scsa1394_dev_is_online(sp)) { 999 return (DDI_FAILURE); 1000 } 1001 1002 if ((ret = scsa1394_sbp2_login(sp, lun)) == DDI_SUCCESS) { 1003 sp->s_lun[lun].l_cdip = cdip; 1004 } 1005 return (ret); 1006 } 1007 1008 /*ARGSUSED*/ 1009 static void 1010 scsa1394_scsi_tgt_free(dev_info_t *dip, dev_info_t *cdip, scsi_hba_tran_t *tran, 1011 struct scsi_device *sd) 1012 { 1013 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 1014 int lun; 1015 int plen = sizeof (int); 1016 1017 if (!scsa1394_is_my_child(cdip)) { 1018 return; 1019 } 1020 1021 if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF, 1022 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun, 1023 &plen) != DDI_PROP_SUCCESS) { 1024 return; 1025 } 1026 1027 if ((lun < sp->s_nluns) && (sp->s_lun[lun].l_cdip == cdip)) { 1028 if (scsa1394_dev_is_online(sp)) { 1029 scsa1394_sbp2_logout(sp, lun, B_TRUE); 1030 } 1031 sp->s_lun[lun].l_cdip = NULL; 1032 } 1033 } 1034 1035 static int 1036 scsa1394_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)()) 1037 { 1038 dev_info_t *dip = ddi_get_parent(sd->sd_dev); 1039 scsi_hba_tran_t *tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip); 1040 scsa1394_state_t *sp = (scsa1394_state_t *)tran->tran_hba_private; 1041 scsa1394_lun_t *lp; 1042 1043 if (!scsa1394_dev_is_online(sp)) { 1044 return (SCSIPROBE_FAILURE); 1045 } 1046 lp = &sp->s_lun[sd->sd_address.a_lun]; 1047 1048 if (scsa1394_probe_g0_nodata(sd, waitfunc, 1049 SCMD_TEST_UNIT_READY, 0, 0) != SCSIPROBE_EXISTS) { 1050 lp->l_nosup_tur = B_TRUE; 1051 (void) scsa1394_sbp2_reset(lp, RESET_LUN, NULL); 1052 } 1053 if (scsa1394_probe_g0_nodata(sd, waitfunc, 1054 SCMD_START_STOP, 0, 1) != SCSIPROBE_EXISTS) { 1055 lp->l_nosup_start_stop = B_TRUE; 1056 } 1057 1058 /* standard probe issues INQUIRY, which some devices may not support */ 1059 if (scsi_hba_probe(sd, waitfunc) != SCSIPROBE_EXISTS) { 1060 lp->l_nosup_inquiry = B_TRUE; 1061 scsa1394_sbp2_fake_inquiry(sp, &lp->l_fake_inq); 1062 bcopy(&lp->l_fake_inq, sd->sd_inq, SUN_INQSIZE); 1063 #ifndef __lock_lint 1064 lp->l_rmb_orig = 1; 1065 #endif 1066 } 1067 1068 if (scsa1394_wrka_fake_rmb) { 1069 sd->sd_inq->inq_rmb = 1; 1070 } 1071 1072 return (SCSIPROBE_EXISTS); 1073 } 1074 1075 static int 1076 scsa1394_probe_g0_nodata(struct scsi_device *sd, int (*waitfunc)(), 1077 uchar_t cmd, uint_t addr, uint_t cnt) 1078 { 1079 struct scsi_pkt *pkt; 1080 int ret = SCSIPROBE_EXISTS; 1081 1082 pkt = scsi_init_pkt(&sd->sd_address, NULL, NULL, CDB_GROUP0, 1083 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, waitfunc, NULL); 1084 1085 if (pkt == NULL) { 1086 return (SCSIPROBE_NOMEM); 1087 } 1088 1089 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, cmd, addr, cnt, 1090 0); 1091 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = sd->sd_address.a_lun; 1092 pkt->pkt_flags = FLAG_NOINTR; 1093 1094 if (scsa1394_probe_tran(pkt) < 0) { 1095 if (pkt->pkt_reason == CMD_INCOMPLETE) { 1096 ret = SCSIPROBE_NORESP; 1097 } else if ((pkt->pkt_reason == CMD_TRAN_ERR) && 1098 ((*(pkt->pkt_scbp) & STATUS_MASK) == STATUS_CHECK) && 1099 (pkt->pkt_state & STATE_ARQ_DONE)) { 1100 ret = SCSIPROBE_EXISTS; 1101 } else { 1102 ret = SCSIPROBE_FAILURE; 1103 } 1104 } 1105 1106 scsi_destroy_pkt(pkt); 1107 1108 return (ret); 1109 } 1110 1111 static int 1112 scsa1394_probe_tran(struct scsi_pkt *pkt) 1113 { 1114 pkt->pkt_time = SCSA1394_PROBE_TIMEOUT; 1115 1116 if (scsi_transport(pkt) != TRAN_ACCEPT) { 1117 return (-1); 1118 } else if ((pkt->pkt_reason == CMD_INCOMPLETE) && 1119 (pkt->pkt_state == 0)) { 1120 return (-1); 1121 } else if (pkt->pkt_reason != CMD_CMPLT) { 1122 return (-1); 1123 } else if (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_BUSY) { 1124 return (0); 1125 } 1126 return (0); 1127 } 1128 1129 /*ARGSUSED*/ 1130 static int 1131 scsa1394_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 1132 { 1133 return (0); 1134 } 1135 1136 static int 1137 scsa1394_scsi_reset(struct scsi_address *ap, int level) 1138 { 1139 scsa1394_state_t *sp = ADDR2STATE(ap); 1140 scsa1394_lun_t *lp; 1141 int ret; 1142 1143 switch (level) { 1144 case RESET_ALL: 1145 case RESET_TARGET: 1146 lp = &sp->s_lun[0]; 1147 break; 1148 case RESET_LUN: 1149 lp = &sp->s_lun[ap->a_lun]; 1150 break; 1151 default: 1152 return (DDI_FAILURE); 1153 } 1154 1155 ret = scsa1394_sbp2_reset(lp, level, NULL); 1156 1157 return ((ret == SBP2_SUCCESS) ? 1 : 0); 1158 } 1159 1160 /*ARGSUSED*/ 1161 static int 1162 scsa1394_scsi_getcap(struct scsi_address *ap, char *cap, int whom) 1163 { 1164 scsa1394_state_t *sp = ADDR2STATE(ap); 1165 size_t dev_bsize_cap; 1166 int ret = -1; 1167 1168 if (!scsa1394_dev_is_online(sp)) { 1169 return (-1); 1170 } 1171 1172 if (cap == NULL) { 1173 return (-1); 1174 } 1175 1176 switch (scsi_hba_lookup_capstr(cap)) { 1177 case SCSI_CAP_DMA_MAX: 1178 ret = sp->s_attachinfo.dma_attr.dma_attr_maxxfer; 1179 break; 1180 case SCSI_CAP_SCSI_VERSION: 1181 ret = SCSI_VERSION_2; 1182 break; 1183 case SCSI_CAP_ARQ: 1184 ret = 1; 1185 break; 1186 case SCSI_CAP_UNTAGGED_QING: 1187 ret = 1; 1188 break; 1189 case SCSI_CAP_GEOMETRY: 1190 dev_bsize_cap = sp->s_totalsec; 1191 1192 if (sp->s_secsz > DEV_BSIZE) { 1193 dev_bsize_cap *= sp->s_secsz / DEV_BSIZE; 1194 } else if (sp->s_secsz < DEV_BSIZE) { 1195 dev_bsize_cap /= DEV_BSIZE / sp->s_secsz; 1196 } 1197 1198 if (dev_bsize_cap < 65536 * 2 * 18) { /* < ~1GB */ 1199 /* unlabeled floppy, 18k per cylinder */ 1200 ret = ((2 << 16) | 18); 1201 } else if (dev_bsize_cap < 65536 * 64 * 32) { /* < 64GB */ 1202 /* 1024k per cylinder */ 1203 ret = ((64 << 16) | 32); 1204 } else if (dev_bsize_cap < 65536 * 255 * 63) { /* < ~500GB */ 1205 /* ~8m per cylinder */ 1206 ret = ((255 << 16) | 63); 1207 } else { /* .. 8TB */ 1208 /* 64m per cylinder */ 1209 ret = ((512 << 16) | 256); 1210 } 1211 break; 1212 default: 1213 break; 1214 } 1215 1216 return (ret); 1217 } 1218 1219 /*ARGSUSED*/ 1220 static int 1221 scsa1394_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom) 1222 { 1223 scsa1394_state_t *sp = ADDR2STATE(ap); 1224 int ret = -1; 1225 1226 if (!scsa1394_dev_is_online(sp)) { 1227 return (-1); 1228 } 1229 1230 switch (scsi_hba_lookup_capstr(cap)) { 1231 case SCSI_CAP_ARQ: 1232 ret = 1; 1233 break; 1234 case SCSI_CAP_DMA_MAX: 1235 case SCSI_CAP_SCSI_VERSION: 1236 case SCSI_CAP_UNTAGGED_QING: 1237 /* supported but not settable */ 1238 ret = 0; 1239 break; 1240 case SCSI_CAP_SECTOR_SIZE: 1241 if (value) { 1242 sp->s_secsz = value; 1243 } 1244 break; 1245 case SCSI_CAP_TOTAL_SECTORS: 1246 if (value) { 1247 sp->s_totalsec = value; 1248 } 1249 break; 1250 default: 1251 break; 1252 } 1253 1254 return (ret); 1255 } 1256 1257 /*ARGSUSED*/ 1258 static void 1259 scsa1394_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1260 { 1261 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1262 1263 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1264 (void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0, 1265 (cmd->sc_flags & SCSA1394_CMD_READ) ? 1266 DDI_DMA_SYNC_FORCPU : DDI_DMA_SYNC_FORDEV); 1267 } 1268 } 1269 1270 /* 1271 * 1272 * --- pkt resource allocation routines 1273 * 1274 */ 1275 static struct scsi_pkt * 1276 scsa1394_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 1277 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 1278 int (*callback)(), caddr_t arg) 1279 { 1280 scsa1394_state_t *sp = ADDR2STATE(ap); 1281 scsa1394_lun_t *lp; 1282 scsa1394_cmd_t *cmd; 1283 boolean_t is_new; /* new cmd is being allocated */ 1284 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 1285 1286 if (ap->a_lun >= sp->s_nluns) { 1287 return (NULL); 1288 } 1289 lp = &sp->s_lun[ap->a_lun]; 1290 1291 /* 1292 * allocate cmd space 1293 */ 1294 if (pkt == NULL) { 1295 is_new = B_TRUE; 1296 if ((cmd = kmem_cache_alloc(sp->s_cmd_cache, kf)) == NULL) { 1297 return (NULL); 1298 } 1299 1300 /* initialize cmd */ 1301 pkt = &cmd->sc_scsi_pkt; 1302 pkt->pkt_ha_private = cmd; 1303 pkt->pkt_address = *ap; 1304 pkt->pkt_private = cmd->sc_priv; 1305 pkt->pkt_scbp = (uchar_t *)&cmd->sc_scb; 1306 pkt->pkt_cdbp = (uchar_t *)&cmd->sc_pkt_cdb; 1307 pkt->pkt_resid = 0; 1308 1309 cmd->sc_lun = lp; 1310 cmd->sc_pkt = pkt; 1311 cmd->sc_cdb_len = cmdlen; 1312 cmd->sc_scb_len = statuslen; 1313 cmd->sc_priv_len = tgtlen; 1314 1315 /* need external space? */ 1316 if ((cmdlen > sizeof (cmd->sc_pkt_cdb)) || 1317 (statuslen > sizeof (cmd->sc_scb)) || 1318 (tgtlen > sizeof (cmd->sc_priv))) { 1319 if (scsa1394_cmd_ext_alloc(sp, cmd, kf) != 1320 DDI_SUCCESS) { 1321 kmem_cache_free(sp->s_cmd_cache, cmd); 1322 lp->l_stat.stat_err_pkt_kmem_alloc++; 1323 return (NULL); 1324 } 1325 } 1326 1327 /* allocate DMA resources for CDB */ 1328 if (scsa1394_cmd_cdb_dma_alloc(sp, cmd, flags, callback, arg) != 1329 DDI_SUCCESS) { 1330 scsa1394_scsi_destroy_pkt(ap, pkt); 1331 return (NULL); 1332 } 1333 } else { 1334 is_new = B_FALSE; 1335 cmd = PKT2CMD(pkt); 1336 } 1337 1338 cmd->sc_flags &= ~SCSA1394_CMD_RDWR; 1339 1340 /* allocate/move DMA resources for data buffer */ 1341 if ((bp != NULL) && (bp->b_bcount > 0)) { 1342 if ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) == 0) { 1343 if (scsa1394_cmd_buf_dma_alloc(sp, cmd, flags, callback, 1344 arg, bp) != DDI_SUCCESS) { 1345 if (is_new) { 1346 scsa1394_scsi_destroy_pkt(ap, pkt); 1347 } 1348 return (NULL); 1349 } 1350 } else { 1351 if (scsa1394_cmd_buf_dma_move(sp, cmd) != DDI_SUCCESS) { 1352 return (NULL); 1353 } 1354 } 1355 1356 ASSERT(cmd->sc_win_len > 0); 1357 pkt->pkt_resid = bp->b_bcount - cmd->sc_win_len; 1358 } 1359 1360 /* 1361 * kernel virtual address may be required for certain workarounds 1362 * and in case of B_PHYS or B_PAGEIO, bp_mapin() will get it for us 1363 */ 1364 if ((bp != NULL) && ((bp->b_flags & (B_PAGEIO | B_PHYS)) != 0) && 1365 (bp->b_bcount < SCSA1394_MAPIN_SIZE_MAX) && 1366 ((cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) == 0)) { 1367 bp_mapin(bp); 1368 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_MAPIN; 1369 } 1370 1371 return (pkt); 1372 } 1373 1374 static void 1375 scsa1394_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1376 { 1377 scsa1394_state_t *sp = ADDR2STATE(ap); 1378 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1379 1380 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1381 scsa1394_cmd_buf_dma_free(sp, cmd); 1382 } 1383 if (cmd->sc_flags & SCSA1394_CMD_DMA_CDB_VALID) { 1384 scsa1394_cmd_cdb_dma_free(sp, cmd); 1385 } 1386 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) { 1387 bp_mapout(cmd->sc_bp); 1388 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN; 1389 } 1390 if (cmd->sc_flags & SCSA1394_CMD_EXT) { 1391 scsa1394_cmd_ext_free(sp, cmd); 1392 } 1393 1394 kmem_cache_free(sp->s_cmd_cache, cmd); 1395 } 1396 1397 static void 1398 scsa1394_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 1399 { 1400 scsa1394_state_t *sp = ADDR2STATE(ap); 1401 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1402 1403 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_VALID) { 1404 scsa1394_cmd_buf_dma_free(sp, cmd); 1405 } 1406 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_MAPIN) { 1407 bp_mapout(cmd->sc_bp); 1408 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_MAPIN; 1409 } 1410 } 1411 1412 /*ARGSUSED*/ 1413 static int 1414 scsa1394_cmd_cache_constructor(void *buf, void *cdrarg, int kf) 1415 { 1416 scsa1394_cmd_t *cmd = buf; 1417 1418 bzero(buf, SCSA1394_CMD_SIZE); 1419 cmd->sc_task.ts_drv_priv = cmd; 1420 1421 return (0); 1422 } 1423 1424 /*ARGSUSED*/ 1425 static void 1426 scsa1394_cmd_cache_destructor(void *buf, void *cdrarg) 1427 { 1428 } 1429 1430 /* 1431 * allocate and deallocate external cmd space (ie. not part of scsa1394_cmd_t) 1432 * for non-standard length cdb, pkt_private, status areas 1433 */ 1434 static int 1435 scsa1394_cmd_ext_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, int kf) 1436 { 1437 struct scsi_pkt *pkt = cmd->sc_pkt; 1438 void *buf; 1439 1440 if (cmd->sc_cdb_len > sizeof (cmd->sc_pkt_cdb)) { 1441 if ((buf = kmem_zalloc(cmd->sc_cdb_len, kf)) == NULL) { 1442 return (DDI_FAILURE); 1443 } 1444 pkt->pkt_cdbp = buf; 1445 cmd->sc_flags |= SCSA1394_CMD_CDB_EXT; 1446 } 1447 1448 if (cmd->sc_scb_len > sizeof (cmd->sc_scb)) { 1449 if ((buf = kmem_zalloc(cmd->sc_scb_len, kf)) == NULL) { 1450 scsa1394_cmd_ext_free(sp, cmd); 1451 return (DDI_FAILURE); 1452 } 1453 pkt->pkt_scbp = buf; 1454 cmd->sc_flags |= SCSA1394_CMD_SCB_EXT; 1455 } 1456 1457 if (cmd->sc_priv_len > sizeof (cmd->sc_priv)) { 1458 if ((buf = kmem_zalloc(cmd->sc_priv_len, kf)) == NULL) { 1459 scsa1394_cmd_ext_free(sp, cmd); 1460 return (DDI_FAILURE); 1461 } 1462 pkt->pkt_private = buf; 1463 cmd->sc_flags |= SCSA1394_CMD_PRIV_EXT; 1464 } 1465 1466 return (DDI_SUCCESS); 1467 } 1468 1469 /*ARGSUSED*/ 1470 static void 1471 scsa1394_cmd_ext_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1472 { 1473 struct scsi_pkt *pkt = cmd->sc_pkt; 1474 1475 if (cmd->sc_flags & SCSA1394_CMD_CDB_EXT) { 1476 kmem_free(pkt->pkt_cdbp, cmd->sc_cdb_len); 1477 } 1478 if (cmd->sc_flags & SCSA1394_CMD_SCB_EXT) { 1479 kmem_free(pkt->pkt_scbp, cmd->sc_scb_len); 1480 } 1481 if (cmd->sc_flags & SCSA1394_CMD_PRIV_EXT) { 1482 kmem_free(pkt->pkt_private, cmd->sc_priv_len); 1483 } 1484 cmd->sc_flags &= ~SCSA1394_CMD_EXT; 1485 } 1486 1487 /*ARGSUSED*/ 1488 static int 1489 scsa1394_cmd_cdb_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1490 int flags, int (*callback)(), caddr_t arg) 1491 { 1492 if (sbp2_task_orb_alloc(cmd->sc_lun->l_lun, &cmd->sc_task, 1493 sizeof (scsa1394_cmd_orb_t)) != SBP2_SUCCESS) { 1494 return (DDI_FAILURE); 1495 } 1496 1497 cmd->sc_flags |= SCSA1394_CMD_DMA_CDB_VALID; 1498 return (DDI_SUCCESS); 1499 } 1500 1501 /*ARGSUSED*/ 1502 static void 1503 scsa1394_cmd_cdb_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1504 { 1505 sbp2_task_orb_free(cmd->sc_lun->l_lun, &cmd->sc_task); 1506 cmd->sc_flags &= ~SCSA1394_CMD_DMA_CDB_VALID; 1507 } 1508 1509 /* 1510 * buffer resources 1511 */ 1512 static int 1513 scsa1394_cmd_buf_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1514 int flags, int (*callback)(), caddr_t arg, struct buf *bp) 1515 { 1516 scsa1394_lun_t *lp = cmd->sc_lun; 1517 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 1518 int dma_flags; 1519 ddi_dma_cookie_t dmac; 1520 uint_t ccount; 1521 int error; 1522 int ret; 1523 1524 cmd->sc_bp = bp; 1525 1526 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_buf_dma_attr, callback, 1527 NULL, &cmd->sc_buf_dma_hdl)) != DDI_SUCCESS) { 1528 bioerror(bp, 0); 1529 return (DDI_FAILURE); 1530 } 1531 1532 cmd->sc_flags &= ~SCSA1394_CMD_RDWR; 1533 if (bp->b_flags & B_READ) { 1534 dma_flags = DDI_DMA_READ; 1535 cmd->sc_flags |= SCSA1394_CMD_READ; 1536 } else { 1537 dma_flags = DDI_DMA_WRITE; 1538 cmd->sc_flags |= SCSA1394_CMD_WRITE; 1539 } 1540 if (flags & PKT_CONSISTENT) { 1541 dma_flags |= DDI_DMA_CONSISTENT; 1542 } 1543 if (flags & PKT_DMA_PARTIAL) { 1544 dma_flags |= DDI_DMA_PARTIAL; 1545 } 1546 1547 ret = ddi_dma_buf_bind_handle(cmd->sc_buf_dma_hdl, bp, dma_flags, 1548 callback, arg, &dmac, &ccount); 1549 1550 switch (ret) { 1551 case DDI_DMA_MAPPED: 1552 cmd->sc_nwin = 1; 1553 cmd->sc_curwin = 0; 1554 cmd->sc_win_offset = 0; 1555 cmd->sc_win_len = bp->b_bcount; 1556 break; 1557 1558 case DDI_DMA_PARTIAL_MAP: 1559 /* retrieve number of windows and first window cookie */ 1560 cmd->sc_curwin = 0; 1561 if ((ddi_dma_numwin(cmd->sc_buf_dma_hdl, &cmd->sc_nwin) != 1562 DDI_SUCCESS) || 1563 (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin, 1564 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) != 1565 DDI_SUCCESS)) { 1566 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl); 1567 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1568 return (DDI_FAILURE); 1569 } 1570 lp->l_stat.stat_cmd_buf_dma_partial++; 1571 break; 1572 1573 case DDI_DMA_NORESOURCES: 1574 error = 0; 1575 goto map_error; 1576 1577 case DDI_DMA_BADATTR: 1578 case DDI_DMA_NOMAPPING: 1579 error = EFAULT; 1580 goto map_error; 1581 1582 default: 1583 error = EINVAL; 1584 1585 map_error: 1586 bioerror(bp, error); 1587 lp->l_stat.stat_err_cmd_buf_dbind++; 1588 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1589 return (DDI_FAILURE); 1590 } 1591 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_BIND_VALID; 1592 1593 /* 1594 * setup page table if needed 1595 */ 1596 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) && 1597 (!sp->s_symbios || 1598 (dmac.dmac_size <= scsa1394_symbios_page_size))) { 1599 cmd->sc_buf_nsegs = 1; 1600 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size; 1601 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address; 1602 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem; 1603 } else { 1604 /* break window into segments */ 1605 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, kf) != 1606 DDI_SUCCESS) { 1607 scsa1394_cmd_buf_dma_free(sp, cmd); 1608 bioerror(bp, 0); 1609 return (DDI_FAILURE); 1610 } 1611 1612 /* allocate DMA resources for page table */ 1613 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, callback, arg, 1614 cmd->sc_buf_nsegs) != DDI_SUCCESS) { 1615 scsa1394_cmd_buf_dma_free(sp, cmd); 1616 bioerror(bp, 0); 1617 return (DDI_FAILURE); 1618 } 1619 } 1620 1621 /* allocate 1394 addresses for segments */ 1622 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) { 1623 scsa1394_cmd_buf_dma_free(sp, cmd); 1624 bioerror(bp, 0); 1625 return (DDI_FAILURE); 1626 } 1627 1628 return (DDI_SUCCESS); 1629 } 1630 1631 static void 1632 scsa1394_cmd_buf_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1633 { 1634 scsa1394_cmd_buf_addr_free(sp, cmd); 1635 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1636 scsa1394_cmd_pt_dma_free(sp, cmd); 1637 } 1638 scsa1394_cmd_seg_free(sp, cmd); 1639 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_BIND_VALID) { 1640 (void) ddi_dma_unbind_handle(cmd->sc_buf_dma_hdl); 1641 ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); 1642 } 1643 cmd->sc_flags &= ~(SCSA1394_CMD_DMA_BUF_VALID | SCSA1394_CMD_RDWR); 1644 } 1645 1646 /* 1647 * Break a set DMA cookies into segments suitable for SBP-2 page table. 1648 * This routine can reuse/reallocate segment array from previous calls. 1649 */ 1650 static int 1651 scsa1394_cmd_dmac2seg(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1652 ddi_dma_cookie_t *dmac, uint_t ccount, int kf) 1653 { 1654 scsa1394_lun_t *lp = cmd->sc_lun; 1655 int i; 1656 int nsegs; 1657 size_t segsize_max; 1658 size_t dmac_resid; 1659 uint32_t dmac_addr; 1660 scsa1394_cmd_seg_t *seg; 1661 1662 if (!sp->s_symbios) { 1663 /* 1664 * Number of segments is unknown at this point. Start with 1665 * a reasonable estimate and grow it later if needed. 1666 */ 1667 nsegs = max(ccount, cmd->sc_win_len / SBP2_PT_SEGSIZE_MAX) * 2; 1668 segsize_max = SBP2_PT_SEGSIZE_MAX; 1669 } else { 1670 /* 1671 * For Symbios workaround we know exactly the number of segments 1672 * Additional segment may be needed if buffer is not aligned. 1673 */ 1674 nsegs = 1675 howmany(cmd->sc_win_len, scsa1394_symbios_page_size) + 1; 1676 segsize_max = scsa1394_symbios_page_size; 1677 } 1678 1679 if (nsegs > cmd->sc_buf_nsegs_alloc) { 1680 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc(cmd->sc_buf_seg, 1681 cmd->sc_buf_nsegs_alloc, nsegs, 1682 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) { 1683 cmd->sc_buf_nsegs_alloc = 0; 1684 return (DDI_FAILURE); 1685 } 1686 cmd->sc_buf_nsegs_alloc = nsegs; 1687 } 1688 1689 /* each cookie maps into one or more segments */ 1690 cmd->sc_buf_nsegs = 0; 1691 i = ccount; 1692 for (;;) { 1693 dmac_resid = dmac->dmac_size; 1694 dmac_addr = dmac->dmac_address; 1695 while (dmac_resid > 0) { 1696 /* grow array if needed */ 1697 if (cmd->sc_buf_nsegs >= cmd->sc_buf_nsegs_alloc) { 1698 if ((cmd->sc_buf_seg = scsa1394_kmem_realloc( 1699 cmd->sc_buf_seg, 1700 cmd->sc_buf_nsegs_alloc, 1701 cmd->sc_buf_nsegs_alloc + ccount, 1702 sizeof (scsa1394_cmd_seg_t), kf)) == NULL) { 1703 return (DDI_FAILURE); 1704 } 1705 cmd->sc_buf_nsegs_alloc += ccount; 1706 } 1707 1708 seg = &cmd->sc_buf_seg[cmd->sc_buf_nsegs]; 1709 seg->ss_len = min(dmac_resid, segsize_max); 1710 seg->ss_daddr = (uint64_t)dmac_addr; 1711 dmac_addr += seg->ss_len; 1712 dmac_resid -= seg->ss_len; 1713 cmd->sc_buf_nsegs++; 1714 } 1715 ASSERT(dmac_resid == 0); 1716 1717 /* grab next cookie */ 1718 if (--i <= 0) { 1719 break; 1720 } 1721 ddi_dma_nextcookie(cmd->sc_buf_dma_hdl, dmac); 1722 } 1723 1724 if (cmd->sc_buf_nsegs > lp->l_stat.stat_cmd_buf_max_nsegs) { 1725 lp->l_stat.stat_cmd_buf_max_nsegs = cmd->sc_buf_nsegs; 1726 } 1727 1728 return (DDI_SUCCESS); 1729 } 1730 1731 /*ARGSUSED*/ 1732 static void 1733 scsa1394_cmd_seg_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1734 { 1735 if (cmd->sc_buf_nsegs_alloc > 0) { 1736 kmem_free(cmd->sc_buf_seg, cmd->sc_buf_nsegs_alloc * 1737 sizeof (scsa1394_cmd_seg_t)); 1738 } 1739 cmd->sc_buf_seg = NULL; 1740 cmd->sc_buf_nsegs = 0; 1741 cmd->sc_buf_nsegs_alloc = 0; 1742 } 1743 1744 static int 1745 scsa1394_cmd_pt_dma_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd, 1746 int (*callback)(), caddr_t arg, int cnt) 1747 { 1748 scsa1394_lun_t *lp = cmd->sc_lun; 1749 size_t len, rlen; 1750 uint_t ccount; 1751 t1394_alloc_addr_t aa; 1752 int result; 1753 1754 /* allocate DMA memory for page table */ 1755 if ((ddi_dma_alloc_handle(sp->s_dip, &sp->s_pt_dma_attr, 1756 callback, NULL, &cmd->sc_pt_dma_hdl)) != DDI_SUCCESS) { 1757 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1758 return (DDI_FAILURE); 1759 } 1760 1761 cmd->sc_pt_ent_alloc = cnt; 1762 len = cmd->sc_pt_ent_alloc * SBP2_PT_ENT_SIZE; 1763 if (ddi_dma_mem_alloc(cmd->sc_pt_dma_hdl, len, 1764 &sp->s_attachinfo.acc_attr, DDI_DMA_CONSISTENT, callback, arg, 1765 &cmd->sc_pt_kaddr, &rlen, &cmd->sc_pt_acc_hdl) != DDI_SUCCESS) { 1766 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1767 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1768 return (DDI_FAILURE); 1769 } 1770 1771 if (ddi_dma_addr_bind_handle(cmd->sc_pt_dma_hdl, NULL, 1772 cmd->sc_pt_kaddr, len, DDI_DMA_READ | DDI_DMA_CONSISTENT, 1773 callback, arg, &cmd->sc_pt_dmac, &ccount) != DDI_DMA_MAPPED) { 1774 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1775 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1776 lp->l_stat.stat_err_cmd_pt_dmem_alloc++; 1777 return (DDI_FAILURE); 1778 } 1779 ASSERT(ccount == 1); /* because dma_attr_sgllen is 1 */ 1780 1781 /* allocate 1394 address for page table */ 1782 aa.aa_type = T1394_ADDR_FIXED; 1783 aa.aa_length = len; 1784 aa.aa_address = cmd->sc_pt_dmac.dmac_address; 1785 aa.aa_evts.recv_read_request = NULL; 1786 aa.aa_evts.recv_write_request = NULL; 1787 aa.aa_evts.recv_lock_request = NULL; 1788 aa.aa_arg = NULL; 1789 aa.aa_kmem_bufp = NULL; 1790 aa.aa_enable = T1394_ADDR_RDENBL; 1791 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != DDI_SUCCESS) { 1792 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl); 1793 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1794 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1795 lp->l_stat.stat_err_cmd_pt_addr_alloc++; 1796 return (DDI_FAILURE); 1797 } 1798 ASSERT(aa.aa_address != 0); 1799 cmd->sc_pt_baddr = aa.aa_address; 1800 cmd->sc_pt_addr_hdl = aa.aa_hdl; 1801 1802 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_PT_VALID; 1803 1804 return (DDI_SUCCESS); 1805 } 1806 1807 static void 1808 scsa1394_cmd_pt_dma_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1809 { 1810 (void) ddi_dma_unbind_handle(cmd->sc_pt_dma_hdl); 1811 ddi_dma_mem_free(&cmd->sc_pt_acc_hdl); 1812 ddi_dma_free_handle(&cmd->sc_pt_dma_hdl); 1813 (void) t1394_free_addr(sp->s_t1394_hdl, &cmd->sc_pt_addr_hdl, 0); 1814 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_PT_VALID; 1815 } 1816 1817 /* 1818 * allocate 1394 addresses for all buffer segments 1819 */ 1820 static int 1821 scsa1394_cmd_buf_addr_alloc(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1822 { 1823 scsa1394_lun_t *lp = cmd->sc_lun; 1824 t1394_alloc_addr_t aa; 1825 scsa1394_cmd_seg_t *seg; 1826 int result; 1827 int i; 1828 1829 aa.aa_type = T1394_ADDR_FIXED; 1830 aa.aa_evts.recv_read_request = NULL; 1831 aa.aa_evts.recv_write_request = NULL; 1832 aa.aa_evts.recv_lock_request = NULL; 1833 aa.aa_arg = NULL; 1834 aa.aa_kmem_bufp = NULL; 1835 if (cmd->sc_flags & SCSA1394_CMD_READ) { 1836 aa.aa_enable = T1394_ADDR_RDENBL; 1837 } else { 1838 aa.aa_enable = T1394_ADDR_WRENBL; 1839 } 1840 1841 for (i = 0; i < cmd->sc_buf_nsegs; i++) { 1842 seg = &cmd->sc_buf_seg[i]; 1843 1844 /* segment bus address */ 1845 aa.aa_length = seg->ss_len; 1846 aa.aa_address = seg->ss_daddr; 1847 1848 if (t1394_alloc_addr(sp->s_t1394_hdl, &aa, 0, &result) != 1849 DDI_SUCCESS) { 1850 lp->l_stat.stat_err_cmd_buf_addr_alloc++; 1851 return (DDI_FAILURE); 1852 } 1853 ASSERT(aa.aa_address != 0); 1854 seg->ss_baddr = aa.aa_address; 1855 seg->ss_addr_hdl = aa.aa_hdl; 1856 } 1857 1858 cmd->sc_flags |= SCSA1394_CMD_DMA_BUF_ADDR_VALID; 1859 1860 return (DDI_SUCCESS); 1861 } 1862 1863 static void 1864 scsa1394_cmd_buf_addr_free(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1865 { 1866 int i; 1867 1868 for (i = 0; i < cmd->sc_buf_nsegs; i++) { 1869 if (cmd->sc_buf_seg[i].ss_addr_hdl) { 1870 (void) t1394_free_addr(sp->s_t1394_hdl, 1871 &cmd->sc_buf_seg[i].ss_addr_hdl, 0); 1872 } 1873 } 1874 cmd->sc_flags &= ~SCSA1394_CMD_DMA_BUF_ADDR_VALID; 1875 } 1876 1877 /* 1878 * move to next DMA window 1879 */ 1880 static int 1881 scsa1394_cmd_buf_dma_move(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 1882 { 1883 /* scsa1394_lun_t *lp = cmd->sc_lun; */ 1884 ddi_dma_cookie_t dmac; 1885 uint_t ccount; 1886 1887 /* for small pkts, leave things where they are (says WDD) */ 1888 if ((cmd->sc_curwin == cmd->sc_nwin) && (cmd->sc_nwin == 1)) { 1889 return (DDI_SUCCESS); 1890 } 1891 if (++cmd->sc_curwin >= cmd->sc_nwin) { 1892 return (DDI_FAILURE); 1893 } 1894 if (ddi_dma_getwin(cmd->sc_buf_dma_hdl, cmd->sc_curwin, 1895 &cmd->sc_win_offset, &cmd->sc_win_len, &dmac, &ccount) != 1896 DDI_SUCCESS) { 1897 return (DDI_FAILURE); 1898 } 1899 1900 scsa1394_cmd_buf_addr_free(sp, cmd); 1901 1902 /* 1903 * setup page table if needed 1904 */ 1905 if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) && 1906 (!sp->s_symbios || 1907 (dmac.dmac_size <= scsa1394_symbios_page_size))) { 1908 /* but first, free old resources */ 1909 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1910 scsa1394_cmd_pt_dma_free(sp, cmd); 1911 } 1912 scsa1394_cmd_seg_free(sp, cmd); 1913 1914 cmd->sc_buf_nsegs = 1; 1915 cmd->sc_buf_seg_mem.ss_len = dmac.dmac_size; 1916 cmd->sc_buf_seg_mem.ss_daddr = dmac.dmac_address; 1917 cmd->sc_buf_seg = &cmd->sc_buf_seg_mem; 1918 } else { 1919 /* break window into segments */ 1920 if (scsa1394_cmd_dmac2seg(sp, cmd, &dmac, ccount, KM_NOSLEEP) != 1921 DDI_SUCCESS) { 1922 return (DDI_FAILURE); 1923 } 1924 1925 /* allocate DMA resources */ 1926 if (scsa1394_cmd_pt_dma_alloc(sp, cmd, NULL_FUNC, NULL, 1927 cmd->sc_buf_nsegs) != DDI_SUCCESS) { 1928 return (DDI_FAILURE); 1929 } 1930 } 1931 1932 /* allocate 1394 addresses for segments */ 1933 if (scsa1394_cmd_buf_addr_alloc(sp, cmd) != DDI_SUCCESS) { 1934 return (DDI_FAILURE); 1935 } 1936 1937 return (DDI_SUCCESS); 1938 } 1939 1940 /* 1941 * 1942 * --- pkt and data transfer routines 1943 * 1944 */ 1945 static int 1946 scsa1394_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 1947 { 1948 scsa1394_state_t *sp = ADDR2STATE(ap); 1949 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 1950 scsa1394_lun_t *lp = cmd->sc_lun; 1951 int ret; 1952 1953 /* 1954 * since we don't support polled I/O, just accept the packet 1955 * so the rest of the file systems get synced properly 1956 */ 1957 if (ddi_in_panic()) { 1958 scsa1394_prepare_pkt(sp, pkt); 1959 return (TRAN_ACCEPT); 1960 } 1961 1962 /* polling not supported yet */ 1963 if (pkt->pkt_flags & FLAG_NOINTR) { 1964 return (TRAN_BADPKT); 1965 } 1966 1967 mutex_enter(&sp->s_mutex); 1968 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { 1969 /* 1970 * If device is temporarily gone due to bus reset, 1971 * return busy to prevent prevent scary console messages. 1972 * If permanently gone, leave it to scsa1394_cmd_fake_comp(). 1973 */ 1974 if (sp->s_dev_state == SCSA1394_DEV_BUS_RESET) { 1975 mutex_exit(&sp->s_mutex); 1976 return (TRAN_BUSY); 1977 } 1978 } 1979 mutex_exit(&sp->s_mutex); 1980 1981 if ((ap->a_lun >= sp->s_nluns) || 1982 (ap->a_lun != pkt->pkt_address.a_lun)) { 1983 return (TRAN_BADPKT); 1984 } 1985 1986 scsa1394_prepare_pkt(sp, pkt); 1987 1988 /* some commands may require fake completion */ 1989 if ((ret = scsa1394_cmd_fake_comp(sp, cmd)) == DDI_SUCCESS) { 1990 return (TRAN_ACCEPT); 1991 } 1992 1993 scsa1394_cmd_fill_cdb(lp, cmd); 1994 1995 if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { 1996 scsa1394_sbp2_seg2pt(lp, cmd); 1997 } 1998 1999 scsa1394_sbp2_cmd2orb(lp, cmd); /* convert into ORB */ 2000 2001 if ((ret = scsa1394_sbp2_start(lp, cmd)) != TRAN_BUSY) { 2002 scsa1394_sbp2_nudge(lp); 2003 } 2004 2005 return (ret); 2006 } 2007 2008 /*ARGSUSED*/ 2009 static void 2010 scsa1394_prepare_pkt(scsa1394_state_t *sp, struct scsi_pkt *pkt) 2011 { 2012 scsa1394_cmd_t *cmd = PKT2CMD(pkt); 2013 2014 pkt->pkt_reason = CMD_CMPLT; 2015 pkt->pkt_state = 0; 2016 pkt->pkt_statistics = 0; 2017 *(pkt->pkt_scbp) = STATUS_GOOD; 2018 2019 if (cmd) { 2020 cmd->sc_timeout = pkt->pkt_time; 2021 2022 /* workarounds */ 2023 switch (pkt->pkt_cdbp[0]) { 2024 /* 2025 * sd does START_STOP_UNIT during attach with a 200 sec timeout. 2026 * at this time devi_lock is held, prtconf will be stuck. 2027 * reduce timeout for the time being. 2028 */ 2029 case SCMD_START_STOP: 2030 cmd->sc_timeout = min(cmd->sc_timeout, 2031 scsa1394_start_stop_timeout_max); 2032 break; 2033 default: 2034 break; 2035 } 2036 } 2037 } 2038 2039 static void 2040 scsa1394_cmd_fill_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2041 { 2042 cmd->sc_cdb_actual_len = cmd->sc_cdb_len; 2043 2044 mutex_enter(&lp->l_mutex); 2045 2046 switch (lp->l_dtype_orig) { 2047 case DTYPE_DIRECT: 2048 case DTYPE_RODIRECT: 2049 case DTYPE_OPTICAL: 2050 case SCSA1394_DTYPE_RBC: 2051 scsa1394_cmd_fill_cdb_rbc(lp, cmd); 2052 break; 2053 default: 2054 scsa1394_cmd_fill_cdb_other(lp, cmd); 2055 break; 2056 } 2057 2058 mutex_exit(&lp->l_mutex); 2059 } 2060 2061 static void 2062 scsa1394_cmd_fill_cdb_rbc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2063 { 2064 scsa1394_state_t *sp = lp->l_sp; 2065 struct scsi_pkt *pkt = CMD2PKT(cmd); 2066 int lba, opcode; 2067 struct buf *bp = cmd->sc_bp; 2068 size_t len; 2069 size_t blk_size; 2070 int sz; 2071 2072 opcode = pkt->pkt_cdbp[0]; 2073 blk_size = lp->l_lba_size; 2074 2075 switch (opcode) { 2076 case SCMD_READ: 2077 /* RBC only supports 10-byte read/write */ 2078 lba = SCSA1394_LBA_6BYTE(pkt); 2079 len = SCSA1394_LEN_6BYTE(pkt); 2080 opcode = SCMD_READ_G1; 2081 cmd->sc_cdb_actual_len = CDB_GROUP1; 2082 break; 2083 case SCMD_WRITE: 2084 lba = SCSA1394_LBA_6BYTE(pkt); 2085 len = SCSA1394_LEN_6BYTE(pkt); 2086 opcode = SCMD_WRITE_G1; 2087 cmd->sc_cdb_actual_len = CDB_GROUP1; 2088 break; 2089 case SCMD_READ_G1: 2090 case SCMD_READ_LONG: 2091 lba = SCSA1394_LBA_10BYTE(pkt); 2092 len = SCSA1394_LEN_10BYTE(pkt); 2093 break; 2094 case SCMD_WRITE_G1: 2095 case SCMD_WRITE_LONG: 2096 lba = SCSA1394_LBA_10BYTE(pkt); 2097 len = SCSA1394_LEN_10BYTE(pkt); 2098 if ((lp->l_dtype_orig == DTYPE_RODIRECT) && 2099 (bp != NULL) && (len != 0)) { 2100 sz = SCSA1394_CDRW_BLKSZ(bp->b_bcount, len); 2101 if (SCSA1394_VALID_CDRW_BLKSZ(sz)) { 2102 blk_size = sz; 2103 } 2104 } 2105 break; 2106 case SCMD_READ_CD: 2107 lba = SCSA1394_LBA_10BYTE(pkt); 2108 len = SCSA1394_LEN_READ_CD(pkt); 2109 blk_size = scsa1394_cmd_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2); 2110 break; 2111 case SCMD_READ_G5: 2112 lba = SCSA1394_LBA_12BYTE(pkt); 2113 len = SCSA1394_LEN_12BYTE(pkt); 2114 break; 2115 case SCMD_WRITE_G5: 2116 lba = SCSA1394_LBA_12BYTE(pkt); 2117 len = SCSA1394_LEN_12BYTE(pkt); 2118 break; 2119 default: 2120 /* no special mapping for other commands */ 2121 scsa1394_cmd_fill_cdb_other(lp, cmd); 2122 return; 2123 } 2124 cmd->sc_blk_size = blk_size; 2125 2126 /* limit xfer length for Symbios workaround */ 2127 if (sp->s_symbios && (len * blk_size > scsa1394_symbios_size_max)) { 2128 cmd->sc_flags |= SCSA1394_CMD_SYMBIOS_BREAKUP; 2129 2130 cmd->sc_total_blks = cmd->sc_resid_blks = len; 2131 2132 len = scsa1394_symbios_size_max / blk_size; 2133 } 2134 cmd->sc_xfer_blks = len; 2135 cmd->sc_xfer_bytes = len * blk_size; 2136 2137 /* finalize new CDB */ 2138 switch (pkt->pkt_cdbp[0]) { 2139 case SCMD_READ: 2140 case SCMD_WRITE: 2141 /* 2142 * We rewrite READ/WRITE G0 commands as READ/WRITE G1. 2143 * Build new cdb from scatch. 2144 * The lba and length fields is updated below. 2145 */ 2146 bzero(cmd->sc_cdb, cmd->sc_cdb_actual_len); 2147 break; 2148 default: 2149 /* 2150 * Copy the non lba/len fields. 2151 * The lba and length fields is updated below. 2152 */ 2153 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_actual_len); 2154 break; 2155 } 2156 2157 cmd->sc_cdb[0] = (uchar_t)opcode; 2158 scsa1394_cmd_fill_cdb_lba(cmd, lba); 2159 switch (opcode) { 2160 case SCMD_READ_CD: 2161 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len); 2162 break; 2163 case SCMD_WRITE_G5: 2164 case SCMD_READ_G5: 2165 scsa1394_cmd_fill_12byte_cdb_len(cmd, len); 2166 break; 2167 default: 2168 scsa1394_cmd_fill_cdb_len(cmd, len); 2169 break; 2170 } 2171 } 2172 2173 /*ARGSUSED*/ 2174 static void 2175 scsa1394_cmd_fill_cdb_other(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2176 { 2177 struct scsi_pkt *pkt = CMD2PKT(cmd); 2178 2179 cmd->sc_xfer_bytes = cmd->sc_win_len; 2180 cmd->sc_xfer_blks = cmd->sc_xfer_bytes / lp->l_lba_size; 2181 cmd->sc_total_blks = cmd->sc_xfer_blks; 2182 cmd->sc_lba = 0; 2183 2184 bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len); 2185 } 2186 2187 /* 2188 * fill up parts of CDB 2189 */ 2190 static void 2191 scsa1394_cmd_fill_cdb_len(scsa1394_cmd_t *cmd, int len) 2192 { 2193 cmd->sc_cdb[7] = len >> 8; 2194 cmd->sc_cdb[8] = (uchar_t)len; 2195 } 2196 2197 static void 2198 scsa1394_cmd_fill_cdb_lba(scsa1394_cmd_t *cmd, int lba) 2199 { 2200 cmd->sc_cdb[2] = lba >> 24; 2201 cmd->sc_cdb[3] = lba >> 16; 2202 cmd->sc_cdb[4] = lba >> 8; 2203 cmd->sc_cdb[5] = (uchar_t)lba; 2204 cmd->sc_lba = lba; 2205 } 2206 2207 static void 2208 scsa1394_cmd_fill_12byte_cdb_len(scsa1394_cmd_t *cmd, int len) 2209 { 2210 cmd->sc_cdb[6] = len >> 24; 2211 cmd->sc_cdb[7] = len >> 16; 2212 cmd->sc_cdb[8] = len >> 8; 2213 cmd->sc_cdb[9] = (uchar_t)len; 2214 } 2215 2216 static void 2217 scsa1394_cmd_fill_read_cd_cdb_len(scsa1394_cmd_t *cmd, int len) 2218 { 2219 cmd->sc_cdb[6] = len >> 16; 2220 cmd->sc_cdb[7] = len >> 8; 2221 cmd->sc_cdb[8] = (uchar_t)len; 2222 } 2223 2224 /* 2225 * For SCMD_READ_CD, figure out the block size based on expected sector type. 2226 * See MMC SCSI Specs section 6.1.15 2227 */ 2228 static int 2229 scsa1394_cmd_read_cd_blk_size(uchar_t expected_sector_type) 2230 { 2231 int blk_size; 2232 2233 switch (expected_sector_type) { 2234 case READ_CD_EST_CDDA: 2235 blk_size = CDROM_BLK_2352; 2236 break; 2237 case READ_CD_EST_MODE2: 2238 blk_size = CDROM_BLK_2336; 2239 break; 2240 case READ_CD_EST_MODE2FORM2: 2241 blk_size = CDROM_BLK_2324; 2242 break; 2243 case READ_CD_EST_MODE2FORM1: 2244 case READ_CD_EST_ALLTYPE: 2245 case READ_CD_EST_MODE1: 2246 default: 2247 blk_size = CDROM_BLK_2048; 2248 } 2249 2250 return (blk_size); 2251 } 2252 2253 /*ARGSUSED*/ 2254 static int 2255 scsa1394_cmd_fake_mode_sense(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2256 { 2257 struct scsi_pkt *pkt = CMD2PKT(cmd); 2258 struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp; 2259 struct scsi_extended_sense *esp = &arqp->sts_sensedata; 2260 2261 *(pkt->pkt_scbp) = STATUS_CHECK; 2262 *(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD; 2263 arqp->sts_rqpkt_reason = CMD_CMPLT; 2264 arqp->sts_rqpkt_resid = 0; 2265 arqp->sts_rqpkt_state |= STATE_XFERRED_DATA; 2266 arqp->sts_rqpkt_statistics = 0; 2267 2268 bzero(esp, sizeof (struct scsi_extended_sense)); 2269 2270 esp->es_class = CLASS_EXTENDED_SENSE; 2271 2272 esp->es_key = KEY_ILLEGAL_REQUEST; 2273 2274 pkt->pkt_reason = CMD_CMPLT; 2275 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2276 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2277 2278 if (pkt->pkt_comp) { 2279 (*pkt->pkt_comp)(pkt); 2280 } 2281 return (DDI_SUCCESS); 2282 } 2283 2284 /*ARGSUSED*/ 2285 static int 2286 scsa1394_cmd_fake_inquiry(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2287 { 2288 scsa1394_lun_t *lp = cmd->sc_lun; 2289 struct scsi_pkt *pkt = CMD2PKT(cmd); 2290 struct scsi_inquiry *inq; 2291 2292 /* copy fabricated inquiry data */ 2293 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr; 2294 bcopy(&lp->l_fake_inq, inq, sizeof (struct scsi_inquiry)); 2295 2296 pkt->pkt_resid -= sizeof (struct scsi_inquiry); 2297 pkt->pkt_reason = CMD_CMPLT; 2298 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2299 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2300 2301 if (pkt->pkt_comp) { 2302 (*pkt->pkt_comp)(pkt); 2303 } 2304 return (DDI_SUCCESS); 2305 } 2306 2307 /* 2308 * If command allows fake completion (without actually being transported), 2309 * call completion callback and return DDI_SUCCESS. 2310 * Otherwise return DDI_FAILURE. 2311 */ 2312 static int 2313 scsa1394_cmd_fake_comp(scsa1394_state_t *sp, scsa1394_cmd_t *cmd) 2314 { 2315 struct scsi_pkt *pkt = CMD2PKT(cmd); 2316 scsa1394_lun_t *lp = cmd->sc_lun; 2317 int ret = DDI_SUCCESS; 2318 2319 /* 2320 * agreement with sd in case of device hot removal 2321 * is to fake completion with CMD_DEV_GONE 2322 */ 2323 mutex_enter(&sp->s_mutex); 2324 if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { 2325 mutex_exit(&sp->s_mutex); 2326 pkt->pkt_reason = CMD_DEV_GONE; 2327 if (pkt->pkt_comp) { 2328 (*pkt->pkt_comp)(pkt); 2329 } 2330 return (DDI_SUCCESS); 2331 } 2332 mutex_exit(&sp->s_mutex); 2333 2334 mutex_enter(&lp->l_mutex); 2335 2336 switch (pkt->pkt_cdbp[0]) { 2337 /* 2338 * RBC support for PRIN/PROUT is optional 2339 */ 2340 case SCMD_PRIN: 2341 case SCMD_PROUT: 2342 if (!scsa1394_wrka_fake_prin) { 2343 ret = DDI_FAILURE; 2344 } 2345 break; 2346 /* 2347 * Some fixed disks don't like doorlock cmd. And they don't need it. 2348 */ 2349 case SCMD_DOORLOCK: 2350 if (lp->l_rmb_orig != 0) { 2351 ret = DDI_FAILURE; 2352 } 2353 break; 2354 case SCMD_TEST_UNIT_READY: 2355 if (!lp->l_nosup_tur) { 2356 ret = DDI_FAILURE; 2357 } 2358 break; 2359 case SCMD_START_STOP: 2360 if (!lp->l_nosup_start_stop) { 2361 ret = DDI_FAILURE; 2362 } 2363 break; 2364 case SCMD_INQUIRY: 2365 if (!lp->l_nosup_inquiry) { 2366 ret = DDI_FAILURE; 2367 } else { 2368 mutex_exit(&lp->l_mutex); 2369 return (scsa1394_cmd_fake_inquiry(sp, cmd)); 2370 } 2371 break; 2372 case SCMD_MODE_SENSE: 2373 if (!lp->l_mode_sense_fake) { 2374 ret = DDI_FAILURE; 2375 } else { 2376 mutex_exit(&lp->l_mutex); 2377 return (scsa1394_cmd_fake_mode_sense(sp, cmd)); 2378 } 2379 default: 2380 ret = DDI_FAILURE; 2381 } 2382 2383 mutex_exit(&lp->l_mutex); 2384 2385 if (ret != DDI_SUCCESS) { 2386 return (ret); 2387 } 2388 2389 ASSERT(*(pkt->pkt_scbp) == STATUS_GOOD); 2390 ASSERT(pkt->pkt_reason == CMD_CMPLT); 2391 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 2392 STATE_XFERRED_DATA | STATE_GOT_STATUS); 2393 2394 if (pkt->pkt_comp) { 2395 (*pkt->pkt_comp)(pkt); 2396 } 2397 return (DDI_SUCCESS); 2398 } 2399 2400 /* 2401 * Returns DDI_SUCCESS if next xfer setup successfully, DDI_FAILURE otherwise. 2402 */ 2403 static int 2404 scsa1394_cmd_setup_next_xfer(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2405 { 2406 struct scsi_pkt *pkt = CMD2PKT(cmd); 2407 2408 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP); 2409 2410 cmd->sc_resid_blks -= cmd->sc_xfer_blks; 2411 if (cmd->sc_resid_blks <= 0) { 2412 pkt->pkt_resid = 0; 2413 return (DDI_FAILURE); 2414 } 2415 2416 scsa1394_cmd_adjust_cdb(lp, cmd); 2417 2418 scsa1394_sbp2_seg2pt(lp, cmd); 2419 2420 scsa1394_sbp2_cmd2orb(lp, cmd); 2421 2422 if (scsa1394_sbp2_start(lp, cmd) != TRAN_ACCEPT) { 2423 pkt->pkt_resid = cmd->sc_resid_blks * cmd->sc_blk_size; 2424 return (DDI_FAILURE); 2425 } 2426 2427 return (DDI_SUCCESS); 2428 } 2429 2430 /* 2431 * new lba = current lba + previous xfer len 2432 */ 2433 /*ARGSUSED*/ 2434 static void 2435 scsa1394_cmd_adjust_cdb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2436 { 2437 int len; 2438 2439 ASSERT(cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP); 2440 2441 cmd->sc_lba += cmd->sc_xfer_blks; 2442 len = cmd->sc_resid_blks; 2443 2444 /* limit xfer length for Symbios workaround */ 2445 if (len * cmd->sc_blk_size > scsa1394_symbios_size_max) { 2446 len = scsa1394_symbios_size_max / cmd->sc_blk_size; 2447 } 2448 2449 switch (cmd->sc_cdb[0]) { 2450 case SCMD_READ_CD: 2451 scsa1394_cmd_fill_read_cd_cdb_len(cmd, len); 2452 break; 2453 case SCMD_WRITE_G5: 2454 case SCMD_READ_G5: 2455 scsa1394_cmd_fill_12byte_cdb_len(cmd, len); 2456 break; 2457 case SCMD_WRITE_G1: 2458 case SCMD_WRITE_LONG: 2459 default: 2460 scsa1394_cmd_fill_cdb_len(cmd, len); 2461 } 2462 2463 scsa1394_cmd_fill_cdb_lba(cmd, cmd->sc_lba); 2464 2465 cmd->sc_xfer_blks = len; 2466 cmd->sc_xfer_bytes = len * cmd->sc_blk_size; 2467 } 2468 2469 void 2470 scsa1394_cmd_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2471 { 2472 struct scsi_pkt *pkt = CMD2PKT(cmd); 2473 2474 /* next iteration of partial xfer? */ 2475 if ((pkt->pkt_reason == CMD_CMPLT) && 2476 (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP)) { 2477 if (scsa1394_cmd_setup_next_xfer(lp, cmd) == DDI_SUCCESS) { 2478 return; 2479 } 2480 } 2481 cmd->sc_flags &= ~SCSA1394_CMD_SYMBIOS_BREAKUP; 2482 2483 /* apply workarounds */ 2484 if (pkt->pkt_reason == CMD_CMPLT) { 2485 scsa1394_cmd_status_wrka(lp, cmd); 2486 } 2487 2488 mutex_enter(&lp->l_mutex); 2489 2490 /* mode sense workaround */ 2491 if (pkt->pkt_cdbp[0] == SCMD_MODE_SENSE) { 2492 if (pkt->pkt_reason == CMD_CMPLT) { 2493 lp->l_mode_sense_fail_cnt = 0; 2494 } else if (++lp->l_mode_sense_fail_cnt >= 2495 scsa1394_mode_sense_fail_max) { 2496 lp->l_mode_sense_fake = B_TRUE; 2497 } 2498 } else { 2499 lp->l_mode_sense_fail_cnt = 0; 2500 } 2501 2502 mutex_exit(&lp->l_mutex); 2503 2504 if (pkt->pkt_comp) { 2505 (*pkt->pkt_comp)(pkt); 2506 } 2507 } 2508 2509 static void 2510 scsa1394_cmd_status_wrka(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) 2511 { 2512 struct scsi_pkt *pkt = CMD2PKT(cmd); 2513 2514 mutex_enter(&lp->l_mutex); 2515 2516 switch (pkt->pkt_cdbp[0]) { 2517 case SCMD_INQUIRY: { 2518 struct scsi_inquiry *inq; 2519 2520 inq = (struct scsi_inquiry *)cmd->sc_bp->b_un.b_addr; 2521 2522 /* change dtype RBC to DIRECT, sd doesn't support RBC */ 2523 lp->l_dtype_orig = inq->inq_dtype; 2524 if ((inq->inq_dtype == SCSA1394_DTYPE_RBC) && 2525 scsa1394_wrka_rbc2direct) { 2526 inq->inq_dtype = DTYPE_DIRECT; 2527 } 2528 2529 /* force RMB to 1 */ 2530 lp->l_rmb_orig = inq->inq_rmb; 2531 if (scsa1394_wrka_fake_rmb) { 2532 inq->inq_rmb = 1; 2533 } 2534 break; 2535 } 2536 case SCMD_READ_CAPACITY: { 2537 uint32_t *capacity_buf; 2538 2539 capacity_buf = (uint32_t *)cmd->sc_bp->b_un.b_addr; 2540 2541 if (lp->l_dtype_orig != DTYPE_RODIRECT) { 2542 lp->l_lba_size = min(BE_32(capacity_buf[1]), DEV_BSIZE); 2543 if (lp->l_lba_size == 0) { 2544 cmn_err(CE_WARN, "zero LBA size reported, " 2545 "possibly broken device"); 2546 lp->l_lba_size = DEV_BSIZE; 2547 } 2548 } else { 2549 lp->l_lba_size = 2048; 2550 } 2551 } 2552 default: 2553 break; 2554 } 2555 2556 mutex_exit(&lp->l_mutex); 2557 } 2558 2559 /* 2560 * --- thread management 2561 * 2562 * dispatch a thread 2563 */ 2564 int 2565 scsa1394_thr_dispatch(scsa1394_thread_t *thr) 2566 { 2567 scsa1394_lun_t *lp = thr->thr_lun; 2568 scsa1394_state_t *sp = lp->l_sp; 2569 int ret; 2570 2571 ASSERT(mutex_owned(&lp->l_mutex)); 2572 ASSERT(thr->thr_state == SCSA1394_THR_INIT); 2573 2574 thr->thr_state = SCSA1394_THR_RUN; 2575 2576 ret = ddi_taskq_dispatch(sp->s_taskq, thr->thr_func, thr->thr_arg, 2577 KM_SLEEP); 2578 return (ret); 2579 } 2580 2581 /* 2582 * cancel thread 2583 */ 2584 void 2585 scsa1394_thr_cancel(scsa1394_thread_t *thr) 2586 { 2587 scsa1394_lun_t *lp = thr->thr_lun; 2588 2589 ASSERT(mutex_owned(&lp->l_mutex)); 2590 2591 thr->thr_req |= SCSA1394_THREQ_EXIT; 2592 cv_signal(&thr->thr_cv); 2593 2594 /* wait until the thread actually exits */ 2595 do { 2596 if (cv_wait_sig(&thr->thr_cv, &lp->l_mutex) == 0) { 2597 break; 2598 } 2599 } while (thr->thr_state != SCSA1394_THR_EXIT); 2600 } 2601 2602 /* 2603 * wake thread 2604 */ 2605 void 2606 scsa1394_thr_wake(scsa1394_thread_t *thr, int req) 2607 { 2608 scsa1394_lun_t *lp = thr->thr_lun; 2609 2610 ASSERT(mutex_owned(&lp->l_mutex)); 2611 2612 thr->thr_req |= req; 2613 cv_signal(&thr->thr_cv); 2614 } 2615 2616 void 2617 scsa1394_thr_clear_req(scsa1394_thread_t *thr, int mask) 2618 { 2619 scsa1394_lun_t *lp = thr->thr_lun; 2620 2621 mutex_enter(&lp->l_mutex); 2622 thr->thr_req &= ~mask; 2623 mutex_exit(&lp->l_mutex); 2624 } 2625 2626 /* 2627 * 2628 * --- other routines 2629 * 2630 */ 2631 static boolean_t 2632 scsa1394_is_my_child(dev_info_t *dip) 2633 { 2634 return ((dip != NULL) && (ddi_prop_exists(DDI_DEV_T_ANY, dip, 2635 DDI_PROP_DONTPASS, "scsa1394") == 1)); 2636 } 2637 2638 boolean_t 2639 scsa1394_dev_is_online(scsa1394_state_t *sp) 2640 { 2641 boolean_t ret; 2642 2643 mutex_enter(&sp->s_mutex); 2644 ret = (sp->s_dev_state == SCSA1394_DEV_ONLINE); 2645 mutex_exit(&sp->s_mutex); 2646 2647 return (ret); 2648 } 2649 2650 static void * 2651 scsa1394_kmem_realloc(void *old_buf, int old_size, int new_size, size_t elsize, 2652 int kf) 2653 { 2654 void *new_buf; 2655 2656 new_buf = kmem_zalloc(new_size * elsize, kf); 2657 2658 if (old_size > 0) { 2659 if (new_buf != NULL) { 2660 bcopy(old_buf, new_buf, old_size * elsize); 2661 } 2662 kmem_free(old_buf, old_size * elsize); 2663 } 2664 2665 return (new_buf); 2666 } 2667