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