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