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