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