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