OpenGrok

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