summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-03-06 06:35:02 +0000
committermav <mav@FreeBSD.org>2017-03-06 06:35:02 +0000
commit82a38e61e4095ee55774d7461b4e5e136ea5eae0 (patch)
treec21062637ebace780f7998d115030b1a5b791dd1 /sys/cam
parent95bd01c95693700e893c0e6e1ad91d2d784c9c28 (diff)
downloadFreeBSD-src-82a38e61e4095ee55774d7461b4e5e136ea5eae0.zip
FreeBSD-src-82a38e61e4095ee55774d7461b4e5e136ea5eae0.tar.gz
MFC r314255: Reenable CTL_WITH_CA, optimizing it for lower memory usage.
This code was disabled due to its high memory usage. But now we need this functionality for cfumass(4) frontend, since USB MS BBB transport does not support autosense.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c86
-rw-r--r--sys/cam/ctl/ctl_private.h5
2 files changed, 45 insertions, 46 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index e5ca93a..d02301f 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -2146,8 +2146,8 @@ ctl_add_initiator(struct ctl_port *port, int iid, uint64_t wwpn, char *name)
port->wwpn_iid[iid].name);
/*
- * XXX KDM clear have_ca and ua_pending on each LUN for
- * this initiator.
+ * XXX KDM clear pending_sense and pending_ua on each LUN
+ * for this initiator.
*/
}
take:
@@ -9145,7 +9145,7 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
struct ctl_softc *softc = CTL_SOFTC(ctsio);
struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_request_sense *cdb;
- struct scsi_sense_data *sense_ptr;
+ struct scsi_sense_data *sense_ptr, *ps;
uint32_t initidx;
int have_error;
u_int sense_len = SSD_FULL_SIZE;
@@ -9201,15 +9201,17 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
* Pending sense gets returned first, then pending unit attentions.
*/
mtx_lock(&lun->lun_lock);
-#ifdef CTL_WITH_CA
- if (ctl_is_set(lun->have_ca, initidx)) {
+ ps = lun->pending_sense[initidx / CTL_MAX_INIT_PER_PORT];
+ if (ps != NULL)
+ ps += initidx % CTL_MAX_INIT_PER_PORT;
+ if (ps != NULL && ps->error_code != 0) {
scsi_sense_data_type stored_format;
/*
* Check to see which sense format was used for the stored
* sense data.
*/
- stored_format = scsi_sense_type(&lun->pending_sense[initidx]);
+ stored_format = scsi_sense_type(ps);
/*
* If the user requested a different sense format than the
@@ -9224,23 +9226,17 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
if ((stored_format == SSD_TYPE_FIXED)
&& (sense_format == SSD_TYPE_DESC))
ctl_sense_to_desc((struct scsi_sense_data_fixed *)
- &lun->pending_sense[initidx],
- (struct scsi_sense_data_desc *)sense_ptr);
+ ps, (struct scsi_sense_data_desc *)sense_ptr);
else if ((stored_format == SSD_TYPE_DESC)
&& (sense_format == SSD_TYPE_FIXED))
ctl_sense_to_fixed((struct scsi_sense_data_desc *)
- &lun->pending_sense[initidx],
- (struct scsi_sense_data_fixed *)sense_ptr);
+ ps, (struct scsi_sense_data_fixed *)sense_ptr);
else
- memcpy(sense_ptr, &lun->pending_sense[initidx],
- MIN(sizeof(*sense_ptr),
- sizeof(lun->pending_sense[initidx])));
+ memcpy(sense_ptr, ps, sizeof(*sense_ptr));
- ctl_clear_mask(lun->have_ca, initidx);
+ ps->error_code = 0;
have_error = 1;
- } else
-#endif
- if (have_error == 0) {
+ } else {
ua_type = ctl_build_ua(lun, initidx, sense_ptr, &sense_len,
sense_format);
if (ua_type != CTL_UA_NONE)
@@ -11357,17 +11353,19 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
-#ifdef CTL_WITH_CA
/*
* If we've got a request sense, it'll clear the contingent
* allegiance condition. Otherwise, if we have a CA condition for
* this initiator, clear it, because it sent down a command other
* than request sense.
*/
- if ((ctsio->cdb[0] != REQUEST_SENSE)
- && (ctl_is_set(lun->have_ca, initidx)))
- ctl_clear_mask(lun->have_ca, initidx);
-#endif
+ if (ctsio->cdb[0] != REQUEST_SENSE) {
+ struct scsi_sense_data *ps;
+
+ ps = lun->pending_sense[initidx / CTL_MAX_INIT_PER_PORT];
+ if (ps != NULL)
+ ps[initidx % CTL_MAX_INIT_PER_PORT].error_code = 0;
+ }
/*
* If the command has this flag set, it handles its own unit
@@ -11705,10 +11703,10 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type)
*/
lun->flags &= ~CTL_LUN_RESERVED;
-#ifdef CTL_WITH_CA
- for (i = 0; i < CTL_MAX_INITIATORS; i++)
- ctl_clear_mask(lun->have_ca, i);
-#endif
+ for (i = 0; i < CTL_MAX_PORTS; i++) {
+ free(lun->pending_sense[i], M_CTL);
+ lun->pending_sense[i] = NULL;
+ }
lun->prevent_count = 0;
if (lun->prevent) {
for (i = 0; i < CTL_MAX_INITIATORS; i++)
@@ -11834,6 +11832,7 @@ ctl_i_t_nexus_reset(union ctl_io *io)
{
struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_lun *lun;
+ struct scsi_sense_data *ps;
uint32_t initidx;
if (!(io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)) {
@@ -11854,9 +11853,9 @@ ctl_i_t_nexus_reset(union ctl_io *io)
mtx_lock(&lun->lun_lock);
ctl_abort_tasks_lun(lun, io->io_hdr.nexus.targ_port,
io->io_hdr.nexus.initid, 1);
-#ifdef CTL_WITH_CA
- ctl_clear_mask(lun->have_ca, initidx);
-#endif
+ ps = lun->pending_sense[initidx / CTL_MAX_INIT_PER_PORT];
+ if (ps != NULL)
+ ps[initidx % CTL_MAX_INIT_PER_PORT].error_code = 0;
if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx))
lun->flags &= ~CTL_LUN_RESERVED;
if (lun->prevent && ctl_is_set(lun->prevent, initidx)) {
@@ -13114,7 +13113,6 @@ bailout:
fe_done(io);
}
-#ifdef CTL_WITH_CA
/*
* Front end should call this if it doesn't do autosense. When the request
* sense comes back in from the initiator, we'll dequeue this and send it.
@@ -13125,7 +13123,8 @@ ctl_queue_sense(union ctl_io *io)
struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_port *port = CTL_PORT(io);
struct ctl_lun *lun;
- uint32_t initidx, targ_lun;
+ struct scsi_sense_data *ps;
+ uint32_t initidx, p, targ_lun;
CTL_DEBUG_PRINT(("ctl_queue_sense\n"));
@@ -13148,26 +13147,29 @@ ctl_queue_sense(union ctl_io *io)
mtx_lock(&lun->lun_lock);
mtx_unlock(&softc->ctl_lock);
- /*
- * Already have CA set for this LUN...toss the sense information.
- */
initidx = ctl_get_initindex(&io->io_hdr.nexus);
- if (ctl_is_set(lun->have_ca, initidx)) {
+ p = initidx / CTL_MAX_INIT_PER_PORT;
+ if ((ps = lun->pending_sense[p]) == NULL) {
mtx_unlock(&lun->lun_lock);
- goto bailout;
+ ps = malloc(sizeof(*ps) * CTL_MAX_INIT_PER_PORT, M_CTL,
+ M_WAITOK | M_ZERO);
+ mtx_lock(&lun->lun_lock);
+ if (lun->pending_sense[p] == NULL) {
+ lun->pending_sense[p] = ps;
+ } else {
+ free(ps, M_CTL);
+ ps = lun->pending_sense[p];
+ }
}
-
- memcpy(&lun->pending_sense[initidx], &io->scsiio.sense_data,
- MIN(sizeof(lun->pending_sense[initidx]),
- sizeof(io->scsiio.sense_data)));
- ctl_set_mask(lun->have_ca, initidx);
+ ps += initidx % CTL_MAX_INIT_PER_PORT;
+ memset(ps, 0, sizeof(*ps));
+ memcpy(ps, &io->scsiio.sense_data, io->scsiio.sense_len);
mtx_unlock(&lun->lun_lock);
bailout:
ctl_free_io(io);
return (CTL_RETVAL_COMPLETE);
}
-#endif
/*
* Primary command inlet from frontend ports. All SCSI and task I/O
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 40f0e61..d451244 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -390,10 +390,7 @@ struct ctl_lun {
TAILQ_HEAD(ctl_ooaq, ctl_io_hdr) ooa_queue;
TAILQ_HEAD(ctl_blockq,ctl_io_hdr) blocked_queue;
STAILQ_ENTRY(ctl_lun) links;
-#ifdef CTL_WITH_CA
- uint32_t have_ca[CTL_MAX_INITIATORS >> 5];
- struct scsi_sense_data pending_sense[CTL_MAX_INITIATORS];
-#endif
+ struct scsi_sense_data *pending_sense[CTL_MAX_PORTS];
ctl_ua_type *pending_ua[CTL_MAX_PORTS];
uint8_t ua_tpt_info[8];
time_t lasttpt;
OpenPOWER on IntegriCloud