summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2001-07-30 00:21:29 +0000
committermjacob <mjacob@FreeBSD.org>2001-07-30 00:21:29 +0000
commit92a303b01ec8836b5335f612e5396b03fd0e5e7d (patch)
tree54d46e1d21b9f9f3dc0519d5e0c6e0de7357de5b /sys/cam
parente082eeba8dbddaecba7fb025c178f9b45da9bedd (diff)
downloadFreeBSD-src-92a303b01ec8836b5335f612e5396b03fd0e5e7d.zip
FreeBSD-src-92a303b01ec8836b5335f612e5396b03fd0e5e7d.tar.gz
scsi_targetio.h
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_sa.c117
-rw-r--r--sys/cam/scsi/scsi_target.c174
-rw-r--r--sys/cam/scsi/scsi_targetio.h10
3 files changed, 198 insertions, 103 deletions
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c
index ae1ed57..b1862ef 100644
--- a/sys/cam/scsi/scsi_sa.c
+++ b/sys/cam/scsi/scsi_sa.c
@@ -1917,6 +1917,10 @@ samount(struct cam_periph *periph, int oflags, dev_t dev)
xpt_release_ccb(ccb);
goto exit;
}
+ /*
+ * Clear I/O residual.
+ */
+ softc->last_io_resid = 0;
}
/*
@@ -2286,20 +2290,24 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
struct scsi_sense_data *sense;
u_int32_t resid = 0;
int32_t info = 0;
- int error_code, sense_key, asc, ascq;
- int error, defer_action, no_actual_error = FALSE;
+ cam_status status;
+ int error_code, sense_key, asc, ascq, error, defer_action, aqvalid;
periph = xpt_path_periph(ccb->ccb_h.path);
softc = (struct sa_softc *)periph->softc;
csio = &ccb->csio;
sense = &csio->sense_data;
scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
+ aqvalid = sense->extra_len >= 6;
error = 0;
+ status = csio->ccb_h.status & CAM_STATUS_MASK;
+
/*
- * Calculate/latch up, any residuals...
+ * Calculate/latch up, any residuals... We do this in a funny 2-step
+ * so we can print stuff locally.
*/
- if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) {
+ if (status == CAM_SCSI_STATUS_ERROR) {
if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
info = (int32_t) scsi_4btoul(sense->info);
resid = info;
@@ -2328,21 +2336,49 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
softc->last_ctl_resid = resid;
softc->last_resid_was_io = 0;
}
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Key 0x%x ASC/ASCQ "
- "0x%x 0x%x flags 0x%x resid %d dxfer_len %d\n", sense_key,
- asc, ascq, sense->flags & ~SSD_KEY_RESERVED, resid,
- csio->dxfer_len));
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
+ "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d "
+ "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
+ sense_key, asc, ascq, status,
+ sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len));
} else {
- CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Cam Status 0x%x\n",
- csio->ccb_h.status & CAM_STATUS_MASK));
+ CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
+ ("Cam Status 0x%x\n", status));
}
+ switch (status) {
+ case CAM_REQ_CMP:
+ return (0);
+ case CAM_SCSI_STATUS_ERROR:
+ /*
+ * If a read/write command, we handle it here.
+ */
+ if (CCB_Type(csio) != SA_CCB_WAITING) {
+ break;
+ }
+ /*
+ * If this was just EOM/EOP, Filemark, Setmark or ILI detected
+ * on a non read/write command, we assume it's not an error.
+ */
+ if ((aqvalid && asc == 0 && ascq > 0 && ascq <= 5) ||
+ (aqvalid == 0 && sense_key == SSD_KEY_NO_SENSE)) {
+ csio->resid = resid;
+ QFRLS(ccb);
+ return (0);
+ }
+ return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
/*
- * If it's neither a SCSI Check Condition Error nor a non-read/write
- * command, let the common code deal with it the error setting.
+ * We can no longer depend upon CAM honoring retry counts for these.
*/
- if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR ||
- (CCB_Type(csio) == SA_CCB_WAITING)) {
+ case CAM_SCSI_BUS_RESET:
+ case CAM_BDR_SENT:
+ case CAM_REQUEUE_REQ:
+ if (ccb->ccb_h.retry_count <= 0) {
+ return (EIO);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
}
@@ -2362,29 +2398,26 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
* From this point out, we're only handling read/write cases.
* Handle writes && reads differently.
*/
-
+
if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
- if (sense->flags & SSD_FILEMARK) {
- xpt_print_path(csio->ccb_h.path);
- printf("filemark detected on write?\n");
- if (softc->fileno != (daddr_t) -1) {
- softc->fileno++;
- softc->blkno = 0;
- csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
- }
- }
- if (sense->flags & SSD_EOM) {
+ if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
csio->resid = resid;
+ error = ENOSPC;
+ } else if (sense->flags & SSD_EOM) {
if (defer_action) {
error = -1;
softc->flags |= SA_FLAG_EOM_PENDING;
} else {
- error = ENOSPC;
+printf("EOM at %u.%u info %d resid %d\n", softc->fileno, softc->blkno, info, resid);
+ /* experiment */
+ softc->flags |= SA_FLAG_EOM_PENDING;
+/* csio->resid = resid; */
+ csio->resid = 0;
}
}
} else {
+ csio->resid = resid;
if (sense_key == SSD_KEY_BLANK_CHECK) {
- csio->resid = resid;
if (defer_action) {
error = -1;
softc->flags |= SA_FLAG_EOM_PENDING;
@@ -2393,12 +2426,9 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
}
}
if (sense->flags & SSD_FILEMARK) {
- csio->resid = resid;
if (defer_action) {
error = -1;
softc->flags |= SA_FLAG_EOF_PENDING;
- } else {
- no_actual_error = TRUE;
}
/*
* Unconditionally, if we detected a filemark on a read,
@@ -2427,8 +2457,6 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
softc->flags |= SA_FLAG_EIO_PENDING;
else
error = EIO;
- } else {
- no_actual_error = TRUE;
}
/*
* Bump the block number if we hadn't seen a filemark.
@@ -2443,22 +2471,17 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
}
}
}
- if (error == 0 && !no_actual_error)
- return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb));
- if (no_actual_error) {
- if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(ccb->ccb_h.path,
- /* relsim_flags */0,
- /* openings */0,
- /* timeout */0,
- /* getcount_only */ FALSE);
- return (0);
- }
- if (error == -1)
- return (0);
- else
- return (error);
+ if (error <= 0) {
+ /*
+ * Unfreeze the queue if frozen as we're not returning anything
+ * to our waiters that would indicate an I/O error has occurred
+ * (yet).
+ */
+ QFRLS(ccb);
+ error = 0;
+ }
+ return (error);
}
static int
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 93338ff..48fa268 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -1,7 +1,7 @@
/*
* Implementation of a simple Target Mode SCSI Proccessor Target driver for CAM.
*
- * Copyright (c) 1998, 1999 Justin T. Gibbs.
+ * Copyright (c) 1998, 1999, 2001 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -93,6 +93,11 @@ typedef enum {
/* We stick a pointer to the originating accept TIO in each continue I/O CCB */
#define ccb_atio ppriv_ptr1
+/*
+ * When we're constructing a unit, we point to passed in user inquiry data here.
+ */
+#define ccb_inq ppriv_ptr1
+
struct targ_softc {
/* CTIOs pending on the controller */
struct ccb_queue pending_queue;
@@ -154,7 +159,9 @@ struct targ_cmd_desc {
struct bio *bp; /* Buffer for this transfer */
u_int max_size; /* Size of backing_store */
u_int32_t timeout;
- u_int8_t status; /* Status to return to initiator */
+ u_int32_t
+ user_atio : 1, /* user ATIO (will define last CTIO) */
+ status : 8; /* Status to return to initiator */
};
static d_open_t targopen;
@@ -187,8 +194,8 @@ static int targsendccb(struct cam_periph *periph, union ccb *ccb,
static periph_init_t targinit;
static void targasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
-static int targallocinstance(struct ioc_alloc_unit *alloc_unit);
-static int targfreeinstance(struct ioc_alloc_unit *alloc_unit);
+static int targallocinstance(void *, u_long);
+static int targfreeinstance(struct ioc_alloc_unit *);
static cam_status targenlun(struct cam_periph *periph);
static cam_status targdislun(struct cam_periph *periph);
static periph_ctor_t targctor;
@@ -472,8 +479,8 @@ targctor(struct cam_periph *periph, void *arg)
softc->istate[i].pending_ua = UA_POWER_ON;
/*
- * Allocate an initial inquiry data buffer. We might allow the
- * user to override this later via an ioctl.
+ * Allocate an inquiry data buffer.
+ * We let the user to override this if desired.
*/
softc->inq_data_len = sizeof(*softc->inq_data);
softc->inq_data = malloc(softc->inq_data_len, M_DEVBUF, M_NOWAIT);
@@ -482,19 +489,35 @@ targctor(struct cam_periph *periph, void *arg)
targdtor(periph);
return (CAM_RESRC_UNAVAIL);
}
- bzero(softc->inq_data, softc->inq_data_len);
- softc->inq_data->device = T_PROCESSOR | (SID_QUAL_LU_CONNECTED << 5);
- softc->inq_data->version = 2;
- softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */
- softc->inq_data->flags =
- cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE);
- softc->inq_data->additional_length = softc->inq_data_len - 4;
- strncpy(softc->inq_data->vendor, "FreeBSD ", SID_VENDOR_SIZE);
- strncpy(softc->inq_data->product, "TM-PT ", SID_PRODUCT_SIZE);
- strncpy(softc->inq_data->revision, "0.0 ", SID_REVISION_SIZE);
+ if (cpi->ccb_h.ccb_inq) {
+ bcopy(cpi->ccb_h.ccb_inq, softc->inq_data, softc->inq_data_len);
+ } else {
+ bzero(softc->inq_data, softc->inq_data_len);
+ softc->inq_data->device =
+ T_PROCESSOR | (SID_QUAL_LU_CONNECTED << 5);
+ softc->inq_data->version = 2;
+ softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */
+ softc->inq_data->additional_length = softc->inq_data_len - 4;
+ strncpy(softc->inq_data->vendor, "FreeBSD ", SID_VENDOR_SIZE);
+ strncpy(softc->inq_data->product,
+ "TM-PT ", SID_PRODUCT_SIZE);
+ strncpy(softc->inq_data->revision, "0.0 ", SID_REVISION_SIZE);
+ }
+
+ /*
+ * Preserve the SIM's capabilities here. Don't let user applications
+ * do something dumb.
+ */
+ if (softc->inq_data->version >= 2) {
+ softc->inq_data->flags &=
+ ~(PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE);
+ softc->inq_data->flags |= (cpi->hba_inquiry &
+ (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32|PI_TAG_ABLE));
+ }
softc->targ_dev = make_dev(&targ_cdevsw, periph->unit_number, UID_ROOT,
GID_OPERATOR, 0600, "%s%d",
periph->periph_name, periph->unit_number);
+
softc->init_level++;
return (CAM_REQ_CMP);
}
@@ -621,8 +644,10 @@ targclose(dev_t dev, int flag, int fmt, struct proc *p)
}
static int
-targallocinstance(struct ioc_alloc_unit *alloc_unit)
+targallocinstance(void *arg, u_long cmd)
{
+ struct ioc_alloc_unit *alloc_unit = arg;
+ struct scsi_inquiry_data local;
struct ccb_pathinq cpi;
struct cam_path *path;
struct cam_periph *periph;
@@ -642,7 +667,6 @@ targallocinstance(struct ioc_alloc_unit *alloc_unit)
free_path_on_return++;
-
xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
cpi.ccb_h.func_code = XPT_PATH_INQ;
xpt_action((union ccb *)&cpi);
@@ -655,7 +679,8 @@ targallocinstance(struct ioc_alloc_unit *alloc_unit)
/* Can only alloc units on controllers that support target mode */
if ((cpi.target_sprt & PIT_PROCESSOR) == 0) {
- printf("Controller does not support target mode%x\n", status);
+ printf("Controller does not support target mode - status %x\n",
+ status);
status = CAM_PATH_INVALID;
goto fail;
}
@@ -666,6 +691,16 @@ targallocinstance(struct ioc_alloc_unit *alloc_unit)
goto fail;
}
+ if (cmd == TARGCTLIOALLOCUNIT) {
+ status = copyin(alloc_unit->inquiry_data, &local, sizeof local);
+ if (status)
+ goto fail;
+ cpi.ccb_h.ccb_inq = &local;
+ } else {
+ cpi.ccb_h.ccb_inq = NULL;
+ }
+
+
/*
* Allocate a peripheral instance for
* this target instance.
@@ -783,10 +818,17 @@ targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = 0;
if (TARG_IS_CONTROL_DEV(unit)) {
switch (cmd) {
+ case OTARGCTLIOALLOCUNIT:
case TARGCTLIOALLOCUNIT:
- error = targallocinstance((struct ioc_alloc_unit*)addr);
+ error = targallocinstance(addr, cmd);
break;
+ case OTARGCTLIOFREEUNIT:
case TARGCTLIOFREEUNIT:
+ /*
+ * Old_ioc_alloc_unit and ioc_alloc_unit are the
+ * same with respect to what we need from the structure
+ * for this function.
+ */
error = targfreeinstance((struct ioc_alloc_unit*)addr);
break;
default:
@@ -888,9 +930,9 @@ targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
}
break;
}
-#ifdef CAMDEBUG
case TARGIODEBUG:
{
+#ifdef CAMDEBUG
union ccb ccb;
bzero (&ccb, sizeof ccb);
if (xpt_create_path(&ccb.ccb_h.path, periph,
@@ -918,9 +960,11 @@ targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = 0;
}
xpt_free_path(ccb.ccb_h.path);
+#else
+ error = 0;
+#endif
break;
}
-#endif
default:
error = ENOTTY;
break;
@@ -1337,22 +1381,24 @@ targstart(struct cam_periph *periph, union ccb *start_ccb)
desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr;
/* Is this a tagged request? */
- flags = atio->ccb_h.flags &
- (CAM_DIS_DISCONNECT|CAM_TAG_ACTION_VALID|CAM_DIR_MASK);
+ flags = atio->ccb_h.flags & (CAM_DIS_DISCONNECT |
+ CAM_TAG_ACTION_VALID | CAM_DIR_MASK | CAM_SEND_STATUS);
/*
* If we are done with the transaction, tell the
* controller to send status and perform a CMD_CMPLT.
*/
- if (desc->data_resid == desc->data_increment)
+ if (desc->user_atio == 0 &&
+ desc->data_resid == desc->data_increment) {
flags |= CAM_SEND_STATUS;
+ }
csio = &start_ccb->csio;
cam_fill_ctio(csio,
/*retries*/2,
targdone,
flags,
- (flags & CAM_TAG_ACTION_VALID)?
+ (flags & CAM_TAG_ACTION_VALID) ?
MSG_SIMPLE_Q_TAG : 0,
atio->tag_id,
atio->init_id,
@@ -1390,13 +1436,13 @@ targstart(struct cam_periph *periph, union ccb *start_ccb)
* to this ATIO (for instance disconnection was disallowed),
* then release it now that our response has been queued.
*/
- if ((atio->ccb_h.flags & CAM_DEV_QFRZN) != 0) {
+ if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
cam_release_devq(periph->path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
- atio->ccb_h.flags &= ~CAM_DEV_QFRZN;
+ atio->ccb_h.status &= ~CAM_DEV_QFRZN;
}
s = splbio();
ccbh = TAILQ_FIRST(&softc->work_queue);
@@ -1441,6 +1487,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
free(done_ccb, M_DEVBUF);
return;
}
+ descr->data_resid = 0;
+ descr->data_increment = 0;
+ descr->user_atio = 0;
#ifdef CAMDEBUG
{
@@ -1450,8 +1499,8 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
snprintf(dcb, sizeof dcb,
"%s %02x", dcb, cdb[i] & 0xff);
}
- CAM_DEBUG(periph->path,
- CAM_DEBUG_PERIPH, ("cdb:%s\n", dcb));
+ CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
+ ("flags %x cdb:%s\n", atio->ccb_h.flags, dcb));
}
#endif
if (atio->sense_len != 0) {
@@ -1464,8 +1513,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
*/
atio->ccb_h.flags &= ~CAM_DIR_MASK;
atio->ccb_h.flags |= CAM_DIR_NONE;
- descr->data_resid = 0;
- descr->data_increment = 0;
descr->timeout = 5 * 1000;
descr->status = SCSI_STATUS_CHECK_COND;
copy_sense(softc, istate, (u_int8_t *)&atio->sense_data,
@@ -1483,8 +1530,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
/* Direction is always relative to the initator */
atio->ccb_h.flags &= ~CAM_DIR_MASK;
atio->ccb_h.flags |= CAM_DIR_NONE;
- descr->data_resid = 0;
- descr->data_increment = 0;
descr->timeout = 5 * 1000;
descr->status = SCSI_STATUS_CHECK_COND;
fill_sense(softc, atio->init_id,
@@ -1538,8 +1583,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
|| inq->page_code != 0) {
atio->ccb_h.flags &= ~CAM_DIR_MASK;
atio->ccb_h.flags |= CAM_DIR_NONE;
- descr->data_resid = 0;
- descr->data_increment = 0;
descr->timeout = 5 * 1000;
descr->status = SCSI_STATUS_CHECK_COND;
fill_sense(softc, atio->init_id,
@@ -1591,8 +1634,6 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
case TEST_UNIT_READY:
atio->ccb_h.flags &= ~CAM_DIR_MASK;
atio->ccb_h.flags |= CAM_DIR_NONE;
- descr->data_resid = 0;
- descr->data_increment = 0;
descr->timeout = 5 * 1000;
descr->status = SCSI_STATUS_OK;
break;
@@ -1633,7 +1674,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
}
case RECEIVE:
case SEND:
- {
+ if (SID_TYPE(softc->inq_data) == T_PROCESSOR) {
struct scsi_send_receive *sr;
sr = (struct scsi_send_receive *)cdb;
@@ -1679,6 +1720,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
* counterpart and transition to the exception
* state.
*/
+ descr->data_resid = 0;
+ descr->data_increment = 0;
+ descr->user_atio = 1;
TAILQ_INSERT_TAIL(&softc->unknown_atio_queue,
&atio->ccb_h,
periph_links.tqe);
@@ -1707,7 +1751,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
struct ccb_accept_tio *atio;
struct targ_cmd_desc *desc;
struct bio *bp;
- int error;
+ int error, lastctio;
CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
("Received completed CTIO\n"));
@@ -1725,7 +1769,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
break;
/*
* Right now we don't need to do anything
- * prior to unfreezing the queue...
+ * prior to unfreezing the queue. This may
+ * change if certain errors are reported while
+ * we are in a connected state.
*/
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
printf("Releasing Queue\n");
@@ -1734,6 +1780,7 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
/*reduction*/0,
/*timeout*/0,
/*getcount_only*/0);
+ done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
}
} else
error = 0;
@@ -1753,8 +1800,22 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.status &= ~CAM_SENT_SENSE;
CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
("Sent Sense\n"));
+ done_ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
+ }
+
+ if (done_ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
+ struct initiator_state *istate;
+
+ istate = &softc->istate[csio->init_id];
+ copy_sense(softc, istate, (u_int8_t *)&csio->sense_data,
+ csio->sense_len);
+ set_ca_condition(periph, csio->init_id, CA_CMD_SENSE);
+ done_ccb->ccb_h.status &= ~CAM_AUTOSNS_VALID;
}
- done_ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
+ /*
+ * Was this the last CTIO?
+ */
+ lastctio = done_ccb->ccb_h.status & CAM_SEND_STATUS;
desc->data_increment -= csio->resid;
desc->data_resid -= desc->data_increment;
@@ -1785,10 +1846,11 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
}
}
+ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
+ atio->ccb_h.status |= CAM_DEV_QFRZN;
xpt_release_ccb(done_ccb);
if (softc->state != TARG_STATE_TEARDOWN) {
-
- if (desc->data_resid == 0) {
+ if (lastctio) {
/*
* Send the original accept TIO back to the
* controller to handle more work.
@@ -1800,25 +1862,25 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
break;
}
- /* Queue us up for another buffer */
- if (atio->cdb_io.cdb_bytes[0] == SEND) {
- if (desc->bp != NULL)
- TAILQ_INSERT_HEAD(
- &softc->snd_bio_queue.queue,
- bp, bio_queue);
+ if (SID_TYPE(softc->inq_data) == T_PROCESSOR) {
+ /* Queue us up for another buffer */
+ if (atio->cdb_io.cdb_bytes[0] == SEND) {
+ if (desc->bp != NULL)
+ TAILQ_INSERT_HEAD(&softc->snd_bio_queue.queue,
+ bp, bio_queue);
TAILQ_INSERT_HEAD(&softc->snd_ccb_queue,
&atio->ccb_h,
periph_links.tqe);
- } else {
- if (desc->bp != NULL)
- TAILQ_INSERT_HEAD(
- &softc->rcv_bio_queue.queue,
- bp, bio_queue);
+ } else {
+ if (desc->bp != NULL)
+ TAILQ_INSERT_HEAD(&softc->rcv_bio_queue.queue,
+ bp, bio_queue);
TAILQ_INSERT_HEAD(&softc->rcv_ccb_queue,
&atio->ccb_h,
periph_links.tqe);
+ }
+ desc->bp = NULL;
}
- desc->bp = NULL;
targrunqueue(periph, softc);
} else {
if (desc->bp != NULL) {
diff --git a/sys/cam/scsi/scsi_targetio.h b/sys/cam/scsi/scsi_targetio.h
index 02cd32c..953655c 100644
--- a/sys/cam/scsi/scsi_targetio.h
+++ b/sys/cam/scsi/scsi_targetio.h
@@ -106,11 +106,19 @@ struct ioc_initiator_state {
#define TARGIOCGETISTATE _IOWR('C', 6, struct ioc_initiator_state)
#define TARGIOCSETISTATE _IOW('C', 5, struct ioc_initiator_state)
+struct old_ioc_alloc_unit {
+ path_id_t path_id;
+ target_id_t target_id;
+ lun_id_t lun_id;
+ u_int unit;
+};
+
struct ioc_alloc_unit {
path_id_t path_id;
target_id_t target_id;
lun_id_t lun_id;
u_int unit;
+ struct scsi_inquiry_data *inquiry_data;
};
/*
@@ -120,6 +128,8 @@ struct ioc_alloc_unit {
* newly created instance. For de-allocation, all fields must match
* an instance in the inactive (i.e. closed) state.
*/
+#define OTARGCTLIOALLOCUNIT _IOWR('C', 7, struct old_ioc_alloc_unit)
+#define OTARGCTLIOFREEUNIT _IOW('C', 8, struct old_ioc_alloc_unit)
#define TARGCTLIOALLOCUNIT _IOWR('C', 7, struct ioc_alloc_unit)
#define TARGCTLIOFREEUNIT _IOW('C', 8, struct ioc_alloc_unit)
OpenPOWER on IntegriCloud