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