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