コード例 #1
0
static int
vhci_tpgs_inquiry(struct scsi_address *ap, struct buf *bp, int *mode)
{
	struct scsi_pkt		*pkt;
	struct scsi_inquiry	inq;
	int			retval;

	*mode = 0;
	bp->b_un.b_addr = (caddr_t)&inq;
	bp->b_flags = B_READ;
	bp->b_bcount = sizeof (inq);
	bp->b_resid = 0;

	pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP0,
	    sizeof (struct scsi_arq_status), 0, 0, SLEEP_FUNC, NULL);
	pkt->pkt_cdbp[0] = SCMD_INQUIRY;
	pkt->pkt_cdbp[4] = sizeof (inq);
	pkt->pkt_time = 60;

	retval = vhci_do_scsi_cmd(pkt);
	scsi_destroy_pkt(pkt);
	if (retval == 0) {
		VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_inquiry: Failure"
		    " returned from vhci_do_scsi_cmd"));
		return (1);
	}

	if (inq.inq_tpgs == TPGS_FAILOVER_NONE) {
		VHCI_DEBUG(1, (CE_WARN, NULL,
		    "!vhci_tpgs_inquiry: zero tpgs_bits"));
		return (1);
	}
	retval = 0;
	if (inq.inq_tpgs == TPGS_FAILOVER_IMPLICIT) {
		*mode = SCSI_IMPLICIT_FAILOVER;
	} else if (inq.inq_tpgs == TPGS_FAILOVER_EXPLICIT) {
		*mode = SCSI_EXPLICIT_FAILOVER;
	} else if (inq.inq_tpgs == TPGS_FAILOVER_BOTH) {
		*mode = SCSI_BOTH_FAILOVER;
	} else {
		VHCI_DEBUG(1, (CE_WARN, NULL,
		    "!vhci_tpgs_inquiry: Illegal mode returned: %x mode: %x",
		    inq.inq_tpgs, *mode));
		retval = 1;
	}

	return (retval);
}
コード例 #2
0
int
vhci_tpgs_set_target_groups(struct scsi_address *ap, int set_state,
    int tpg_id)
{
	struct scsi_pkt			*pkt;
	struct buf			*bp;
	int				len, rval, ss = SCSI_SENSE_UNKNOWN;
	char				*bufp;
	uint8_t				*sns, skey, asc, ascq;

	len = 8;

	bp = getrbuf(KM_NOSLEEP);
	if (bp == NULL) {
		VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_set_target_groups: "
		    " failed getrbuf"));
		return (1);
	}

	bufp = kmem_zalloc(len, KM_NOSLEEP);
	if (bufp == NULL) {
		VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_set_target_groups: "
		    "request packet allocation for %d failed....", len));
		freerbuf(bp);
		return (1);
	}

	bp->b_un.b_addr = bufp;
	bp->b_flags = B_WRITE;
	bp->b_bcount = len;
	bp->b_resid = 0;

	bufp[4] = (0x0f & set_state);
	bufp[6] = (0xff00 & tpg_id) >> 8;
	bufp[7] = (0x00ff & tpg_id);

	pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP5,
	    sizeof (struct scsi_arq_status), 0, 0, NULL, NULL);

	if (pkt == NULL) {
		VHCI_DEBUG(1, (CE_NOTE, NULL,
		    "!vhci_tpgs_set_target_groups: scsi_init_pkt error\n"));
		freerbuf(bp);
		kmem_free((void *)bufp, len);
		return (1);
	}

	/*
	 * Sends 1 TPG descriptor only. Hence Parameter list length pkt_cdbp[9]
	 * is set to 8 bytes - Refer SPC3 for details.
	 */
	pkt->pkt_cdbp[0] = SCMD_MAINTENANCE_OUT;
	pkt->pkt_cdbp[1] = SSVC_ACTION_SET_TARGET_PORT_GROUPS;
	pkt->pkt_cdbp[9] = 8;
	pkt->pkt_time = 90;

	VHCI_DEBUG(1, (CE_NOTE, NULL,
	    "!vhci_tpgs_set_target_groups: sending set target port group:"
	    " cdb[0/1/6/7/8/9]: %x/%x/%x/%x/%x/%x\n", pkt->pkt_cdbp[0],
	    pkt->pkt_cdbp[1], pkt->pkt_cdbp[6], pkt->pkt_cdbp[7],
	    pkt->pkt_cdbp[8], pkt->pkt_cdbp[9]));

#ifdef DEBUG
	print_buf(bufp, len);
#endif
	rval = vhci_do_scsi_cmd(pkt);

	if (rval == 0) {
		VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_set_target_groups:"
		    " vhci_do_scsi_cmd failed\n"));
		freerbuf(bp);
		kmem_free((void *)bufp, len);
		scsi_destroy_pkt(pkt);
		return (-1);
	} else if ((pkt->pkt_reason == CMD_CMPLT) &&
	    (SCBP_C(pkt) == STATUS_CHECK) &&
	    (pkt->pkt_state & STATE_ARQ_DONE)) {
		sns = (uint8_t *)
		    &(((struct scsi_arq_status *)(uintptr_t)
		    (pkt->pkt_scbp))->sts_sensedata);
		skey = scsi_sense_key(sns);
		asc = scsi_sense_asc(sns);
		ascq = scsi_sense_ascq(sns);

		if ((skey == KEY_UNIT_ATTENTION) &&
		    (asc == STD_SCSI_ASC_STATE_CHG) &&
		    (ascq == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
			ss = SCSI_SENSE_STATE_CHANGED;
			VHCI_DEBUG(4, (CE_NOTE, NULL,
			    "!vhci_tpgs_set_target_groups:"
			    " sense:%x, add_code: %x, qual_code:%x"
			    " sense:%x\n", skey, asc, ascq, ss));
		} else if ((skey == KEY_ILLEGAL_REQUEST) &&
		    (asc == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
			ss = SCSI_SENSE_NOFAILOVER;
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_set_target_groups:"
			    " sense:%x, add_code: %x, qual_code:%x"
			    " sense:%x\n", skey, asc, ascq, ss));
		} else if ((skey == KEY_ILLEGAL_REQUEST) &&
		    (asc == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
			ss = SCSI_SENSE_NOFAILOVER;
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_set_target_groups:"
			    " sense_key:%x, add_code: %x, qual_code:%x"
			    " sense:%x\n", skey, asc, ascq, rval));
		} else {
			/*
			 * At this point sns data may be for power-on-reset
			 * UNIT ATTN hardware errors, vendor unqiue sense etc.
			 * For all these cases, sense is unknown.
			 */
			ss = SCSI_SENSE_NOFAILOVER;
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_set_target_groups: "
			    " sense UNKNOWN: sense key:%x, ASC:%x, ASCQ:%x\n",
			    skey, asc, ascq));
		}

		if (ss == SCSI_SENSE_STATE_CHANGED) {
			freerbuf(bp);
			kmem_free((void *)bufp, len);
			scsi_destroy_pkt(pkt);
			return (0);
		}
	} else if ((pkt->pkt_reason == CMD_CMPLT) &&
	    (SCBP_C(pkt) == STATUS_GOOD)) {
		freerbuf(bp);
		kmem_free((void *)bufp, len);
		scsi_destroy_pkt(pkt);
		return (0);
	}

	freerbuf(bp);
	kmem_free((void *)bufp, len);
	scsi_destroy_pkt(pkt);
	return (1);
}
コード例 #3
0
static int
vhci_tpgs_report_target_groups(struct scsi_address *ap, struct buf *bp,
	int rel_tgt_port, int tgt_port, int *pstate, int *preferred)
{
	struct scsi_pkt		*pkt;
	char			*ptr, *end, *bufp, *mpapi_ptr;
	unsigned int		rtpg_len = 0;
	unsigned int		l_tgt_port = 0, tpgs_state = 0;
	unsigned int		tgt_port_cnt = 0, lr_tgt_port = 0;
	int			i, len;

	/*
	 * Start with buffer size of 512.
	 * If this is found to be insufficient, required size
	 * will be allocated and the command will be retried.
	 */
	len = 512;

try_again:
	bufp = kmem_zalloc(len, KM_NOSLEEP);
	if (bufp == NULL) {
		VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_report_target_groups:"
		    " request packet allocation for %d failed....", len));
		return (1);
	}

	bp->b_un.b_addr = bufp;
	bp->b_flags = B_READ;
	bp->b_bcount = len;
	bp->b_resid = 0;

	pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP5,
	    sizeof (struct scsi_arq_status), 0, 0, NULL, NULL);

	if (pkt == NULL) {
		VHCI_DEBUG(1, (CE_NOTE, NULL,
		    "!vhci_tpgs_report_target_groups: scsi_init_pkt error\n"));
		kmem_free((void *)bufp, len);
		return (1);
	}

	pkt->pkt_cdbp[0] = SCMD_MAINTENANCE_IN;
	pkt->pkt_cdbp[1] = SSVC_ACTION_GET_TARGET_PORT_GROUPS;
	pkt->pkt_cdbp[6] = ((len >>  24) & 0xff);
	pkt->pkt_cdbp[7] = ((len >> 16) & 0xff);
	pkt->pkt_cdbp[8] = ((len >> 8) & 0xff);
	pkt->pkt_cdbp[9] = len & 0xff;
	pkt->pkt_time = 90;

	VHCI_DEBUG(6, (CE_NOTE, NULL,
	    "!vhci_tpgs_report_target_groups: sending target port group:"
	    " cdb[6/7/8/9]: %x/%x/%x/%x\n", pkt->pkt_cdbp[6],
	    pkt->pkt_cdbp[7], pkt->pkt_cdbp[8], pkt->pkt_cdbp[9]));
	if (vhci_do_scsi_cmd(pkt) == 0) {
		VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
		    " vhci_do_scsi_cmd failed\n"));
		kmem_free((void *)bufp, len);
		scsi_destroy_pkt(pkt);
		return (1);
	}
	ptr = bufp;
	VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
	    " returned from target"
	    " port group: buf[0/1/2/3]: %x/%x/%x/%x\n",
	    ptr[0], ptr[1], ptr[2], ptr[3]));
	rtpg_len = (unsigned int)((0xff & ptr[0]) << 24);
	rtpg_len |= (unsigned int)((0xff & ptr[1]) << 16);
	rtpg_len |= (unsigned int)((0xff & ptr[2]) << 8);
	rtpg_len |= (unsigned int)(0xff & ptr[3]);
	rtpg_len += 4;
	if (rtpg_len > len) {
		VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
		    " bufsize: %d greater than allocated buf: %d\n",
		    rtpg_len, len));
		VHCI_DEBUG(4, (CE_NOTE, NULL, "Retrying for size %d\n",
		    rtpg_len));
		kmem_free((void *)bufp, len);
		len = (unsigned int)(rtpg_len + 1);
		goto try_again;
	}
#ifdef DEBUG
	print_buf(bufp, rtpg_len);
#endif
	end = ptr + rtpg_len;
	ptr += 4;
	while (ptr < end) {
		mpapi_ptr = ptr;
		l_tgt_port = ((ptr[2] & 0xff) << 8) + (ptr[3] & 0xff);
		tpgs_state = ptr[0] & 0x0f;
		tgt_port_cnt = (ptr[7] & 0xff);
		VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_tgt_groups:"
		    " tpgs state: %x"
		    " tgt_group: %x count: %x\n", tpgs_state,
		    l_tgt_port, tgt_port_cnt));
		ptr += 8;
		for (i = 0; i < tgt_port_cnt; i++) {
			lr_tgt_port = 0;
			lr_tgt_port |= ((ptr[2] & 0Xff) << 8);
			lr_tgt_port |= (ptr[3] & 0xff);

			if ((lr_tgt_port == rel_tgt_port) &&
			    (l_tgt_port == tgt_port)) {
				VHCI_DEBUG(4, (CE_NOTE, NULL,
				    "!vhci_tpgs_report_tgt_groups:"
				    " found tgt_port: %x rel_tgt_port:%x"
				    " tpgs_state: %x\n", tgt_port, rel_tgt_port,
				    tpgs_state));
				/*
				 * once we have the preferred flag
				 * and a non-optimized state flag
				 * we will get preferred flag  from the
				 * report target groups
				 */
				if (tpgs_state == STD_ACTIVE_OPTIMIZED) {
					*pstate = STD_ACTIVE_OPTIMIZED;
					*preferred = PCLASS_PREFERRED;
				} else if (tpgs_state ==
				    STD_ACTIVE_NONOPTIMIZED) {
					*pstate = STD_ACTIVE_NONOPTIMIZED;
					*preferred = PCLASS_NONPREFERRED;
				} else if (tpgs_state == STD_STANDBY) {
					*pstate = STD_STANDBY;
					*preferred = PCLASS_NONPREFERRED;
				} else {
					*pstate = STD_UNAVAILABLE;
					*preferred = PCLASS_NONPREFERRED;
				}
				vhci_mpapi_update_tpg_data(ap, mpapi_ptr,
				    rel_tgt_port);
				kmem_free((void *)bufp, len);
				scsi_destroy_pkt(pkt);
				return (0);
			}
			VHCI_DEBUG(4, (CE_NOTE, NULL,
			    "!vhci_tpgs_report_tgt_groups:"
			    " tgt_port: %x rel_tgt_port:%x\n", tgt_port,
			    rel_tgt_port));
			ptr += 4;
		}
	}
	*pstate = SCSI_PATH_INACTIVE;
	*preferred = PCLASS_NONPREFERRED;
	VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_report_tgt_groups: "
	    "NO rel_TGTPRT MATCH!!! Assigning Default: state: %x "
	    "preferred: %d\n", *pstate, *preferred));
	kmem_free((void *)bufp, len);
	scsi_destroy_pkt(pkt);
	return (1);
}
コード例 #4
0
static int
vhci_tpgs_page83(struct scsi_address *ap, struct buf *bp,
	int *rel_tgt_port, int *tgt_port, int *lu)
{
	char			*ptr, *end;
	struct scsi_pkt		*pkt;
	char			*bufp;
	unsigned int		buf_len, rx_bsize;

	/*
	 * lets start the buf size with 512 bytes. If this
	 * if found to be insufficient, we can allocate
	 * appropriate size in the next iteration.
	 */
	buf_len = 512;

once_again:
	bufp = kmem_zalloc(buf_len, KM_NOSLEEP);
	if (bufp == NULL) {
		VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_page83: "
		    "request packet allocation for %d failed....",
		    buf_len));
		return (1);
	}


	bp->b_un.b_addr = bufp;
	bp->b_flags = B_READ;
	bp->b_bcount = buf_len;
	bp->b_resid = 0;

	pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP0,
	    sizeof (struct scsi_arq_status), 0, 0, NULL, NULL);
	if (pkt == NULL) {
		VHCI_DEBUG(1, (CE_WARN, NULL,
		    "!vhci_tpgs_page83: Failure returned from scsi_init_pkt"));
		kmem_free((void *)bufp, buf_len);
		return (1);
	}

	pkt->pkt_cdbp[0] = SCMD_INQUIRY;
	pkt->pkt_cdbp[1] = 0x1;
	pkt->pkt_cdbp[2] = 0x83;
	pkt->pkt_cdbp[3] = (unsigned char)((buf_len >> 8) & 0xff);
	pkt->pkt_cdbp[4] = (unsigned char)(buf_len & 0xff);
	pkt->pkt_time = 90;

	if (vhci_do_scsi_cmd(pkt) == 0) {
		VHCI_DEBUG(1, (CE_NOTE, NULL,
		    "!vhci_tpgs_page83: vhci_do_scsi_cmd failed\n"));
		kmem_free((void *)bufp, buf_len);
		scsi_destroy_pkt(pkt);
		return (1);
	}

	/*
	 * Now lets check if the size that was provided was
	 * sufficient. If not, allocate the appropriate size
	 * and retry the command again.
	 */
	rx_bsize = (((bufp[2] & 0xff) << 8) | (bufp[3] & 0xff));
	rx_bsize += 4;
	if (rx_bsize > buf_len) {
		/*
		 * Need to allocate more buf and retry again
		 */
		VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_page83: "
		    "bufsize: %d greater than allocated buf: %d\n",
		    rx_bsize, buf_len));
		VHCI_DEBUG(1, (CE_NOTE, NULL, "Retrying for size %d\n",
		    rx_bsize));
		kmem_free((void *)bufp, buf_len);
		buf_len = (unsigned int)(rx_bsize);
		goto once_again;
	}

	ptr = bufp;
	ptr += 4; /* identification descriptor 0 */
	end = bufp + rx_bsize;
	while (ptr < end) {
		VHCI_DEBUG(1, (CE_NOTE, NULL, "vhci_tpgs_page83: "
		    "desc[1/4/5/6/7]:%x %x %x %x %x\n",
		    ptr[1], ptr[4], ptr[5], ptr[6], ptr[7]));
		if ((ptr[1] & 0x0f) == 0x04) {
			*rel_tgt_port = 0;
			*rel_tgt_port |= ((ptr[6] & 0xff) << 8);
			*rel_tgt_port |= (ptr[7] & 0xff);
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_page83: relative target port: %x\n",
			    *rel_tgt_port));
		} else if ((ptr[1] & 0x0f) == 0x05) {
			*tgt_port = 0;
			*tgt_port = ((ptr[6] & 0xff) << 8);
			*tgt_port |= (ptr[7] & 0xff);
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_page83: target port: %x\n", *tgt_port));
		} else if ((ptr[1] & 0x0f) == 0x06) {
			*lu = 0;
			*lu |= ((ptr[6] & 0xff)<< 8);
			*lu |= (ptr[7] & 0xff);
			VHCI_DEBUG(1, (CE_NOTE, NULL,
			    "!vhci_tpgs_page83: logical unit: %x\n", *lu));
		}
		ptr += ptr[3] + 4;  /* next identification descriptor */
	}
	kmem_free((void *)bufp, buf_len);
	scsi_destroy_pkt(pkt);
	return (0);
}
コード例 #5
0
ファイル: tpgs.c プロジェクト: apprisi/illumos-gate
/* ARGSUSED */
static int
std_path_activate(struct scsi_device *sd, char *pathclass,
    void *ctpriv)
{
	struct buf			*bp;
	struct scsi_pkt			*pkt;
	struct scsi_address		*ap;
	int				err, retry_cnt, retry_cmd_cnt;
	int				mode, state, retval, xlf, preferred;

	ap = &sd->sd_address;

	mode = state = 0;

	if (vhci_tpgs_get_target_fo_mode(sd, &mode, &state, &xlf, &preferred)) {
		VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_path_activate:"
		    " failed vhci_tpgs_get_target_fo_mode\n"));
		return (1);
	}
	if ((state == STD_ACTIVE_OPTIMIZED) ||
	    (state == STD_ACTIVE_NONOPTIMIZED)) {
		VHCI_DEBUG(4, (CE_NOTE, NULL, "!path already active for %p\n",
		    (void *)sd));
		return (0);
	}

	if (mode == SCSI_EXPLICIT_FAILOVER) {
		VHCI_DEBUG(4, (CE_NOTE, NULL,
		    "!mode is EXPLICIT for %p xlf %x\n",
		    (void *)sd, xlf));
		retval = std_activate_explicit(sd, xlf);
		if (retval != 0) {
			VHCI_DEBUG(4, (CE_NOTE, NULL,
			    "!(sd:%p)std_path_activate failed(1)\n",
			    (void *)sd));
			return (1);
		}
	} else {
		VHCI_DEBUG(4, (CE_NOTE, NULL, "STD mode is IMPLICIT for %p\n",
		    (void *)sd));
	}

	bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL, DEV_BSIZE,
	    B_READ, NULL, NULL);
	if (!bp) {
		VHCI_DEBUG(4, (CE_WARN, NULL,
		    "!(sd:%p)std_path_activate failed to alloc buffer",
		    (void *)sd));
		return (1);
	}

	pkt = scsi_init_pkt(ap, NULL, bp, CDB_GROUP1,
	    sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, NULL, NULL);
	if (!pkt) {
		VHCI_DEBUG(4, (CE_WARN, NULL,
		    "!(sd:%p)std_path_activate failed to initialize packet",
		    (void *)sd));
		scsi_free_consistent_buf(bp);
		return (1);
	}

	(void) scsi_setup_cdb((union scsi_cdb *)(uintptr_t)pkt->pkt_cdbp,
	    SCMD_READ, 1, 1, 0);
	pkt->pkt_time = 3*30;
	pkt->pkt_flags |= FLAG_NOINTR;

	retry_cnt = 0;
	retry_cmd_cnt = 0;
retry:
	err = scsi_transport(pkt);
	if (err != TRAN_ACCEPT) {
		/*
		 * Retry TRAN_BUSY till STD_FO_MAX_RETRIES is exhausted.
		 * All other errors are fatal and should not be retried.
		 */
		if ((err == TRAN_BUSY) &&
		    (retry_cnt++ < STD_FO_MAX_RETRIES)) {
			drv_usecwait(STD_FO_RETRY_DELAY);
			goto retry;
		}
		cmn_err(CE_WARN, "Failover failed, "
		    "couldn't transport packet");
		scsi_destroy_pkt(pkt);
		scsi_free_consistent_buf(bp);
		return (1);
	}
	switch (pkt->pkt_reason) {
		case CMD_CMPLT:
			/*
			 * Re-initialize retry_cmd_cnt. Allow transport and
			 * cmd errors to go through a full retry count when
			 * these are encountered.  This way TRAN/CMD errors
			 * retry count is not exhausted due to CMD_CMPLTs
			 * delay. This allows the system
			 * to brave a hick-up on the link at any given time,
			 * while waiting for the fo to complete.
			 */
			retry_cmd_cnt = 0;
			if (std_process_cmplt_pkt(sd, pkt, &retry_cnt,
			    &retval) != 0) {
				goto retry;
			}
			break;
		case CMD_TIMEOUT:
			cmn_err(CE_WARN, "!Failover failed: timed out ");
			retval = 1;
			break;
		case CMD_INCOMPLETE:
		case CMD_RESET:
		case CMD_ABORTED:
		case CMD_TRAN_ERR:
			/*
			 * Increased the number of retries when these error
			 * cases are encountered.  Also added a 1 sec wait
			 * before retrying.
			 */
			if (retry_cmd_cnt++ < STD_FO_MAX_CMD_RETRIES) {
				drv_usecwait(STD_FO_CMD_RETRY_DELAY);
				VHCI_DEBUG(4, (CE_WARN, NULL,
				    "!Retrying path activation due to "
				    "pkt reason:%x, retry cnt:%d",
				    pkt->pkt_reason, retry_cmd_cnt));
				goto retry;
			}
			/* FALLTHROUGH */
		default:
			cmn_err(CE_WARN, "!Path activation did not "
			    "complete successfully,"
			    "(pkt reason %x)", pkt->pkt_reason);
			retval = 1;
			break;
	}

	scsi_destroy_pkt(pkt);
	scsi_free_consistent_buf(bp);
	return (retval);
}