aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/cam/ata/ata_da.c39
-rw-r--r--sys/cam/ata/ata_xpt.c59
-rw-r--r--sys/cam/cam.h3
-rw-r--r--sys/cam/cam_ccb.h3
-rw-r--r--sys/cam/cam_periph.c19
-rw-r--r--sys/cam/cam_periph.h2
-rw-r--r--sys/cam/cam_queue.c21
-rw-r--r--sys/cam/cam_queue.h91
-rw-r--r--sys/cam/cam_xpt.c273
-rw-r--r--sys/cam/cam_xpt_internal.h3
-rw-r--r--sys/cam/cam_xpt_sim.h4
-rw-r--r--sys/cam/ctl/scsi_ctl.c9
-rw-r--r--sys/cam/scsi/scsi_cd.c8
-rw-r--r--sys/cam/scsi/scsi_pass.c4
-rw-r--r--sys/cam/scsi/scsi_xpt.c55
15 files changed, 171 insertions, 422 deletions
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index bf3e68321737..5c5827726cbe 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -972,8 +972,6 @@ adaasync(void *callback_arg, u_int32_t code,
else
break;
cam_periph_acquire(periph);
- cam_freeze_devq_arg(periph->path,
- RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
xpt_schedule(periph, CAM_PRIORITY_DEV);
}
default:
@@ -1297,15 +1295,11 @@ adaregister(struct cam_periph *periph, void *arg)
cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD) {
softc->state = ADA_STATE_RAHEAD;
cam_periph_acquire(periph);
- cam_freeze_devq_arg(periph->path,
- RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
xpt_schedule(periph, CAM_PRIORITY_DEV);
} else if (ADA_WC >= 0 &&
cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) {
softc->state = ADA_STATE_WCACHE;
cam_periph_acquire(periph);
- cam_freeze_devq_arg(periph->path,
- RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
xpt_schedule(periph, CAM_PRIORITY_DEV);
} else
softc->state = ADA_STATE_NORMAL;
@@ -1587,8 +1581,6 @@ out:
if (softc->flags & ADA_FLAG_PACK_INVALID) {
softc->state = ADA_STATE_NORMAL;
xpt_release_ccb(start_ccb);
- cam_release_devq(periph->path,
- RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
adaschedule(periph);
cam_periph_release_locked(periph);
return;
@@ -1612,6 +1604,7 @@ out:
ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0);
start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE;
}
+ start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
xpt_action(start_ccb);
break;
}
@@ -1624,11 +1617,13 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
struct ada_softc *softc;
struct ccb_ataio *ataio;
struct ccb_getdev *cgd;
+ struct cam_path *path;
softc = (struct ada_softc *)periph->softc;
ataio = &done_ccb->ataio;
+ path = done_ccb->ccb_h.path;
- CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adadone\n"));
+ CAM_DEBUG(path, CAM_DEBUG_TRACE, ("adadone\n"));
switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
case ADA_CCB_BUFFER_IO:
@@ -1656,8 +1651,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
* XXX See if this is really a media
* XXX change first?
*/
- xpt_print(periph->path,
- "Invalidating pack\n");
+ xpt_print(path, "Invalidating pack\n");
softc->flags |= ADA_FLAG_PACK_INVALID;
}
bp->bio_error = error;
@@ -1670,7 +1664,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
bp->bio_flags |= BIO_ERROR;
}
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
- cam_release_devq(done_ccb->ccb_h.path,
+ cam_release_devq(path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
@@ -1711,9 +1705,12 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
{
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (adaerror(done_ccb, 0, 0) == ERESTART) {
+out:
+ /* Drop freeze taken due to CAM_DEV_QFREEZE */
+ cam_release_devq(path, 0, 0, 0, FALSE);
return;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
- cam_release_devq(done_ccb->ccb_h.path,
+ cam_release_devq(path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
@@ -1730,7 +1727,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
* operation.
*/
cgd = (struct ccb_getdev *)done_ccb;
- xpt_setup_ccb(&cgd->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+ xpt_setup_ccb(&cgd->ccb_h, path, CAM_PRIORITY_NORMAL);
cgd->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)cgd);
if (ADA_WC >= 0 &&
@@ -1738,12 +1735,12 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
softc->state = ADA_STATE_WCACHE;
xpt_release_ccb(done_ccb);
xpt_schedule(periph, CAM_PRIORITY_DEV);
- return;
+ goto out;
}
softc->state = ADA_STATE_NORMAL;
xpt_release_ccb(done_ccb);
- cam_release_devq(periph->path,
- RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
+ /* Drop freeze taken due to CAM_DEV_QFREEZE */
+ cam_release_devq(path, 0, 0, 0, FALSE);
adaschedule(periph);
cam_periph_release_locked(periph);
return;
@@ -1752,9 +1749,9 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
{
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (adaerror(done_ccb, 0, 0) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
- cam_release_devq(done_ccb->ccb_h.path,
+ cam_release_devq(path,
/*relsim_flags*/0,
/*reduction*/0,
/*timeout*/0,
@@ -1772,8 +1769,8 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
* operation.
*/
xpt_release_ccb(done_ccb);
- cam_release_devq(periph->path,
- RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
+ /* Drop freeze taken due to CAM_DEV_QFREEZE */
+ cam_release_devq(path, 0, 0, 0, FALSE);
adaschedule(periph);
cam_periph_release_locked(periph);
return;
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index a9100cdd7aa8..2a3b0f48b4a5 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -249,12 +249,6 @@ proberegister(struct cam_periph *periph, void *arg)
return (status);
}
CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n"));
-
- /*
- * Ensure nobody slip in until probe finish.
- */
- cam_freeze_devq_arg(periph->path,
- RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1);
probeschedule(periph);
return(CAM_REQ_CMP);
}
@@ -661,6 +655,7 @@ negotiate:
default:
panic("probestart: invalid action state 0x%x\n", softc->action);
}
+ start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
xpt_action(start_ccb);
}
@@ -708,12 +703,15 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (cam_periph_error(done_ccb,
0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0,
- NULL) == ERESTART)
+ NULL) == ERESTART) {
+out:
+ /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
+ cam_release_devq(path, 0, 0, 0, FALSE);
return;
+ }
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
- xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
- /*run_queue*/TRUE);
+ xpt_release_devq(path, /*count*/1, /*run_queue*/TRUE);
}
status = done_ccb->ccb_h.status & CAM_STATUS_MASK;
if (softc->restart) {
@@ -768,7 +766,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
/*
@@ -830,7 +828,7 @@ noerror:
}
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
case PROBE_IDENTIFY:
{
@@ -864,7 +862,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SPINUP);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
ident_buf = &path->device->ident_data;
if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
@@ -954,7 +952,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SETMODE);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
case PROBE_SPINUP:
if (bootverbose)
@@ -963,7 +961,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
case PROBE_SETMODE:
/* Set supported bits. */
bzero(&cts, sizeof(cts));
@@ -1034,7 +1032,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SETPM);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
/* FALLTHROUGH */
case PROBE_SETPM:
@@ -1045,7 +1043,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SETAPST);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
/* FALLTHROUGH */
case PROBE_SETAPST:
@@ -1055,7 +1053,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SETDMAAA);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
/* FALLTHROUGH */
case PROBE_SETDMAAA:
@@ -1065,7 +1063,7 @@ noerror:
PROBE_SET_ACTION(softc, PROBE_SETAN);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
/* FALLTHROUGH */
case PROBE_SETAN:
@@ -1077,15 +1075,14 @@ notsata:
}
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
case PROBE_SET_MULTI:
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
xpt_acquire_device(path->device);
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
- xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
- done_ccb);
+ xpt_async(AC_FOUND_DEVICE, path, done_ccb);
}
PROBE_SET_ACTION(softc, PROBE_DONE);
break;
@@ -1118,7 +1115,7 @@ notsata:
PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
ata_device_transport(path);
@@ -1127,7 +1124,7 @@ notsata:
xpt_acquire_device(path->device);
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
- xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+ xpt_async(AC_FOUND_DEVICE, path, done_ccb);
}
PROBE_SET_ACTION(softc, PROBE_DONE);
break;
@@ -1145,7 +1142,7 @@ notsata:
PROBE_SET_ACTION(softc, PROBE_PM_PRV);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
case PROBE_PM_PRV:
softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
(done_ccb->ataio.res.lba_mid << 16) +
@@ -1200,12 +1197,11 @@ notsata:
xpt_acquire_device(path->device);
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
- xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
- done_ccb);
+ xpt_async(AC_FOUND_DEVICE, path, done_ccb);
} else {
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
- xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb);
+ xpt_async(AC_SCSI_AEN, path, done_ccb);
}
PROBE_SET_ACTION(softc, PROBE_DONE);
break;
@@ -1250,8 +1246,7 @@ notsata:
xpt_acquire_device(path->device);
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action(done_ccb);
- xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
- done_ccb);
+ xpt_async(AC_FOUND_DEVICE, path, done_ccb);
}
PROBE_SET_ACTION(softc, PROBE_DONE);
break;
@@ -1263,7 +1258,7 @@ done:
softc->restart = 0;
xpt_release_ccb(done_ccb);
probeschedule(periph);
- return;
+ goto out;
}
xpt_release_ccb(done_ccb);
CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
@@ -1273,9 +1268,9 @@ done:
done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR;
xpt_done(done_ccb);
}
+ /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
+ cam_release_devq(path, 0, 0, 0, FALSE);
cam_periph_invalidate(periph);
- cam_release_devq(periph->path,
- RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
cam_periph_release_locked(periph);
}
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index 20fc7a37dea6..9e5320632030 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -80,10 +80,9 @@ typedef struct {
#define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80)
#define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80)
#define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80)
+#define CAM_PRIORITY_OOB (CAM_RL_DEV << 8)
#define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80)
#define CAM_PRIORITY_NONE (u_int32_t)-1
-#define CAM_PRIORITY_TO_RL(x) ((x) >> 8)
-#define CAM_RL_TO_PRIORITY(x) ((x) << 8)
u_int32_t generation;
int index;
#define CAM_UNQUEUED_INDEX -1
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index a2c041a9edad..006b4e0dc7e5 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -145,8 +145,6 @@ typedef enum {
/* Path statistics (error counts, etc.) */
XPT_GDEV_STATS = 0x0c,
/* Device statistics (error counts, etc.) */
- XPT_FREEZE_QUEUE = 0x0d,
- /* Freeze device queue */
XPT_DEV_ADVINFO = 0x0e,
/* Get/Set Device advanced information */
/* SCSI Control Functions: 0x10->0x1F */
@@ -749,7 +747,6 @@ struct ccb_relsim {
#define RELSIM_RELEASE_AFTER_TIMEOUT 0x02
#define RELSIM_RELEASE_AFTER_CMDCMPLT 0x04
#define RELSIM_RELEASE_AFTER_QEMPTY 0x08
-#define RELSIM_RELEASE_RUNLEVEL 0x10
u_int32_t openings;
u_int32_t release_timeout; /* Abstract argument. */
u_int32_t qfrozen_cnt;
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 428220a6ffe0..8f7a37b09d77 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1117,21 +1117,12 @@ cam_periph_runccb(union ccb *ccb,
void
cam_freeze_devq(struct cam_path *path)
{
+ struct ccb_hdr ccb_h;
- cam_freeze_devq_arg(path, 0, 0);
-}
-
-void
-cam_freeze_devq_arg(struct cam_path *path, uint32_t flags, uint32_t arg)
-{
- struct ccb_relsim crs;
-
- xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NONE);
- crs.ccb_h.func_code = XPT_FREEZE_QUEUE;
- crs.release_flags = flags;
- crs.openings = arg;
- crs.release_timeout = arg;
- xpt_action((union ccb *)&crs);
+ xpt_setup_ccb(&ccb_h, path, /*priority*/1);
+ ccb_h.func_code = XPT_NOOP;
+ ccb_h.flags = CAM_DEV_QFREEZE;
+ xpt_action((union ccb *)&ccb_h);
}
u_int32_t
diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h
index 102dc3c30d4c..48aea0cdbee3 100644
--- a/sys/cam/cam_periph.h
+++ b/sys/cam/cam_periph.h
@@ -171,8 +171,6 @@ int cam_periph_ioctl(struct cam_periph *periph, u_long cmd,
cam_flags camflags,
u_int32_t sense_flags));
void cam_freeze_devq(struct cam_path *path);
-void cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags,
- uint32_t arg);
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
u_int32_t opening_reduction, u_int32_t arg,
int getcount_only);
diff --git a/sys/cam/cam_queue.c b/sys/cam/cam_queue.c
index 359e7f491e8c..41d01674c710 100644
--- a/sys/cam/cam_queue.c
+++ b/sys/cam/cam_queue.c
@@ -230,15 +230,8 @@ int
cam_devq_init(struct cam_devq *devq, int devices, int openings)
{
bzero(devq, sizeof(*devq));
- if (camq_init(&devq->alloc_queue, devices) != 0) {
+ if (camq_init(&devq->send_queue, devices) != 0)
return (1);
- }
- if (camq_init(&devq->send_queue, devices) != 0) {
- camq_fini(&devq->alloc_queue);
- return (1);
- }
- devq->alloc_openings = openings;
- devq->alloc_active = 0;
devq->send_openings = openings;
devq->send_active = 0;
return (0);
@@ -247,7 +240,6 @@ cam_devq_init(struct cam_devq *devq, int devices, int openings)
void
cam_devq_free(struct cam_devq *devq)
{
- camq_fini(&devq->alloc_queue);
camq_fini(&devq->send_queue);
free(devq, M_CAMDEVQ);
}
@@ -257,11 +249,7 @@ cam_devq_resize(struct cam_devq *camq, int devices)
{
u_int32_t retval;
- retval = camq_resize(&camq->alloc_queue, devices);
-
- if (retval == CAM_REQ_CMP)
- retval = camq_resize(&camq->send_queue, devices);
-
+ retval = camq_resize(&camq->send_queue, devices);
return (retval);
}
@@ -328,11 +316,10 @@ int
cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
{
bzero(ccbq, sizeof(*ccbq));
- if (camq_init(&ccbq->queue, openings + (CAM_RL_VALUES - 1)) != 0) {
+ if (camq_init(&ccbq->queue, openings + (CAM_RL_VALUES - 1)) != 0)
return (1);
- }
ccbq->devq_openings = openings;
- ccbq->dev_openings = openings;
+ ccbq->dev_openings = openings;
return (0);
}
diff --git a/sys/cam/cam_queue.h b/sys/cam/cam_queue.h
index dd9f9a7306e7..a000fe48dd9e 100644
--- a/sys/cam/cam_queue.h
+++ b/sys/cam/cam_queue.h
@@ -48,7 +48,7 @@ struct camq {
int array_size;
int entries;
u_int32_t generation;
- u_int32_t qfrozen_cnt[CAM_RL_VALUES];
+ u_int32_t qfrozen_cnt;
};
TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr);
@@ -58,7 +58,8 @@ SLIST_HEAD(ccb_hdr_slist, ccb_hdr);
struct cam_ccbq {
struct camq queue;
int devq_openings;
- int dev_openings;
+ int devq_allocating;
+ int dev_openings;
int dev_active;
int held;
};
@@ -66,11 +67,7 @@ struct cam_ccbq {
struct cam_ed;
struct cam_devq {
- struct camq alloc_queue;
struct camq send_queue;
- struct cam_ed *active_dev;
- int alloc_openings;
- int alloc_active;
int send_openings;
int send_active;
};
@@ -195,8 +192,7 @@ cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb)
{
ccbq->held--;
camq_insert(&ccbq->queue, &new_ccb->ccb_h.pinfo);
- if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL(
- new_ccb->ccb_h.pinfo.priority)] > 0) {
+ if (ccbq->queue.qfrozen_cnt > 0) {
ccbq->devq_openings++;
ccbq->held++;
return (1);
@@ -208,8 +204,7 @@ static __inline int
cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb)
{
camq_remove(&ccbq->queue, ccb->ccb_h.pinfo.index);
- if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL(
- ccb->ccb_h.pinfo.priority)] > 0) {
+ if (ccbq->queue.qfrozen_cnt > 0) {
ccbq->devq_openings--;
ccbq->held--;
return (1);
@@ -248,81 +243,5 @@ cam_ccbq_release_opening(struct cam_ccbq *ccbq)
ccbq->devq_openings++;
}
-static __inline int
-cam_ccbq_freeze(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt)
-{
- int i, frozen = 0;
- cam_rl p, n;
-
- /* Find pevious run level. */
- for (p = 0; p < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[p] == 0; p++);
- /* Find new run level. */
- n = min(rl, p);
- /* Apply new run level. */
- for (i = rl; i < CAM_RL_VALUES; i++)
- ccbq->queue.qfrozen_cnt[i] += cnt;
- /* Update ccbq statistics. */
- if (n == p)
- return (0);
- for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) {
- cam_rl rrl =
- CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority);
- if (rrl < n)
- continue;
- if (rrl >= p)
- break;
- ccbq->devq_openings++;
- ccbq->held++;
- frozen++;
- }
- return (frozen);
-}
-
-static __inline int
-cam_ccbq_release(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt)
-{
- int i, released = 0;
- cam_rl p, n;
-
- /* Apply new run level. */
- for (i = rl; i < CAM_RL_VALUES; i++)
- ccbq->queue.qfrozen_cnt[i] -= cnt;
- /* Find new run level. */
- for (n = 0; n < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[n] == 0; n++);
- /* Find previous run level. */
- p = min(rl, n);
- /* Update ccbq statistics. */
- if (n == p)
- return (0);
- for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) {
- cam_rl rrl =
- CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority);
- if (rrl < p)
- continue;
- if (rrl >= n)
- break;
- ccbq->devq_openings--;
- ccbq->held--;
- released++;
- }
- return (released);
-}
-
-static __inline u_int32_t
-cam_ccbq_frozen(struct cam_ccbq *ccbq, cam_rl rl)
-{
-
- return (ccbq->queue.qfrozen_cnt[rl]);
-}
-
-static __inline u_int32_t
-cam_ccbq_frozen_top(struct cam_ccbq *ccbq)
-{
- cam_rl rl;
-
- rl = CAM_PRIORITY_TO_RL(CAMQ_GET_PRIO(&ccbq->queue));
- return (ccbq->queue.qfrozen_cnt[rl]);
-}
-
#endif /* _KERNEL */
#endif /* _CAM_CAM_QUEUE_H */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index a9182629284c..ce246c00797f 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -223,13 +223,13 @@ static void xpt_async_bcast(struct async_list *async_head,
static path_id_t xptnextfreepathid(void);
static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus);
static union ccb *xpt_get_ccb(struct cam_ed *device);
-static void xpt_run_dev_allocq(struct cam_eb *bus);
-static void xpt_run_dev_sendq(struct cam_eb *bus);
+static void xpt_run_dev_allocq(struct cam_ed *device);
+static void xpt_run_devq(struct cam_devq *devq);
static timeout_t xpt_release_devq_timeout;
static void xpt_release_simq_timeout(void *arg) __unused;
static void xpt_release_bus(struct cam_eb *bus);
-static void xpt_release_devq_device(struct cam_ed *dev, cam_rl rl,
- u_int count, int run_queue);
+static void xpt_release_devq_device(struct cam_ed *dev, u_int count,
+ int run_queue);
static struct cam_et*
xpt_alloc_target(struct cam_eb *bus, target_id_t target_id);
static void xpt_release_target(struct cam_et *target);
@@ -296,49 +296,24 @@ static xpt_busfunc_t xptsetasyncbusfunc;
static cam_status xptregister(struct cam_periph *periph,
void *arg);
static __inline int periph_is_queued(struct cam_periph *periph);
-static __inline int device_is_alloc_queued(struct cam_ed *device);
-static __inline int device_is_send_queued(struct cam_ed *device);
+static __inline int device_is_queued(struct cam_ed *device);
static __inline int
-xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
-{
- int retval;
-
- if ((dev->drvq.entries > 0) &&
- (dev->ccbq.devq_openings > 0) &&
- (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
- CAMQ_GET_PRIO(&dev->drvq))) == 0)) {
- /*
- * The priority of a device waiting for CCB resources
- * is that of the highest priority peripheral driver
- * enqueued.
- */
- retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
- &dev->alloc_ccb_entry.pinfo,
- CAMQ_GET_PRIO(&dev->drvq));
- } else {
- retval = 0;
- }
-
- return (retval);
-}
-
-static __inline int
-xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
+xpt_schedule_devq(struct cam_devq *devq, struct cam_ed *dev)
{
int retval;
if ((dev->ccbq.queue.entries > 0) &&
(dev->ccbq.dev_openings > 0) &&
- (cam_ccbq_frozen_top(&dev->ccbq) == 0)) {
+ (dev->ccbq.queue.qfrozen_cnt == 0)) {
/*
* The priority of a device waiting for controller
* resources is that of the highest priority CCB
* enqueued.
*/
retval =
- xpt_schedule_dev(&bus->sim->devq->send_queue,
- &dev->send_ccb_entry.pinfo,
+ xpt_schedule_dev(&devq->send_queue,
+ &dev->devq_entry.pinfo,
CAMQ_GET_PRIO(&dev->ccbq.queue));
} else {
retval = 0;
@@ -353,15 +328,9 @@ periph_is_queued(struct cam_periph *periph)
}
static __inline int
-device_is_alloc_queued(struct cam_ed *device)
+device_is_queued(struct cam_ed *device)
{
- return (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
-}
-
-static __inline int
-device_is_send_queued(struct cam_ed *device)
-{
- return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
+ return (device->devq_entry.pinfo.index != CAM_UNQUEUED_INDEX);
}
static void
@@ -2487,17 +2456,10 @@ xpt_action_default(union ccb *start_ccb)
case XPT_RESET_DEV:
case XPT_ENG_EXEC:
case XPT_SMP_IO:
- {
- int frozen;
-
- frozen = cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
- path->device->sim->devq->alloc_openings += frozen;
- if (frozen > 0)
- xpt_run_dev_allocq(path->bus);
- if (xpt_schedule_dev_sendq(path->bus, path->device))
- xpt_run_dev_sendq(path->bus);
+ cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
+ if (xpt_schedule_devq(path->bus->sim->devq, path->device))
+ xpt_run_devq(path->bus->sim->devq);
break;
- }
case XPT_CALC_GEOMETRY:
{
struct cam_sim *sim;
@@ -2546,8 +2508,7 @@ xpt_action_default(union ccb *start_ccb)
device = abort_ccb->ccb_h.path->device;
ccbq = &device->ccbq;
- device->sim->devq->alloc_openings -=
- cam_ccbq_remove_ccb(ccbq, abort_ccb);
+ cam_ccbq_remove_ccb(ccbq, abort_ccb);
abort_ccb->ccb_h.status =
CAM_REQ_ABORTED|CAM_DEV_QFRZN;
xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
@@ -2928,13 +2889,9 @@ xpt_action_default(union ccb *start_ccb)
}
}
- if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) {
- xpt_release_devq_rl(path, /*runlevel*/
- (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ?
- crs->release_timeout : 0,
- /*count*/1, /*run_queue*/TRUE);
- }
- start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt[0];
+ if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0)
+ xpt_release_devq(path, /*count*/1, /*run_queue*/TRUE);
+ start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt;
start_ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
@@ -2977,16 +2934,6 @@ xpt_action_default(union ccb *start_ccb)
start_ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
- case XPT_FREEZE_QUEUE:
- {
- struct ccb_relsim *crs = &start_ccb->crs;
-
- xpt_freeze_devq_rl(path, /*runlevel*/
- (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ?
- crs->release_timeout : 0, /*count*/1);
- start_ccb->ccb_h.status = CAM_REQ_CMP;
- break;
- }
case XPT_NOOP:
if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0)
xpt_freeze_devq(path, 1);
@@ -3092,7 +3039,7 @@ xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
camq_change_priority(&device->drvq,
perph->pinfo.index,
new_priority);
- runq = xpt_schedule_dev_allocq(perph->path->bus, device);
+ runq = 1;
}
} else {
/* New entry on the queue */
@@ -3101,12 +3048,12 @@ xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
perph->pinfo.priority = new_priority;
perph->pinfo.generation = ++device->drvq.generation;
camq_insert(&device->drvq, &perph->pinfo);
- runq = xpt_schedule_dev_allocq(perph->path->bus, device);
+ runq = 1;
}
if (runq != 0) {
CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
- (" calling xpt_run_devq\n"));
- xpt_run_dev_allocq(perph->path->bus);
+ (" calling xpt_run_dev_allocq\n"));
+ xpt_run_dev_allocq(device);
}
}
@@ -3159,43 +3106,25 @@ xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo,
}
static void
-xpt_run_dev_allocq(struct cam_eb *bus)
+xpt_run_dev_allocq(struct cam_ed *device)
{
- struct cam_devq *devq;
-
- CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n"));
- devq = bus->sim->devq;
+ struct camq *drvq;
- CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
- (" qfrozen_cnt == 0x%x, entries == %d, "
- "openings == %d, active == %d\n",
- devq->alloc_queue.qfrozen_cnt[0],
- devq->alloc_queue.entries,
- devq->alloc_openings,
- devq->alloc_active));
-
- devq->alloc_queue.qfrozen_cnt[0]++;
- while ((devq->alloc_queue.entries > 0)
- && (devq->alloc_openings > 0)
- && (devq->alloc_queue.qfrozen_cnt[0] <= 1)) {
- struct cam_ed_qinfo *qinfo;
- struct cam_ed *device;
+ if (device->ccbq.devq_allocating)
+ return;
+ device->ccbq.devq_allocating = 1;
+ CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq(%p)\n", device));
+ drvq = &device->drvq;
+ while ((drvq->entries > 0) &&
+ (device->ccbq.devq_openings > 0 ||
+ CAMQ_GET_PRIO(drvq) <= CAM_PRIORITY_OOB) &&
+ (device->ccbq.queue.qfrozen_cnt == 0)) {
union ccb *work_ccb;
struct cam_periph *drv;
- struct camq *drvq;
- qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
- CAMQ_HEAD);
- device = qinfo->device;
- CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
- ("running device %p\n", device));
-
- drvq = &device->drvq;
KASSERT(drvq->entries > 0, ("xpt_run_dev_allocq: "
"Device on queue without any work to do"));
if ((work_ccb = xpt_get_ccb(device)) != NULL) {
- devq->alloc_openings--;
- devq->alloc_active++;
drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD);
xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
drv->pinfo.priority);
@@ -3214,27 +3143,21 @@ xpt_run_dev_allocq(struct cam_eb *bus)
*/
break;
}
-
- /* We may have more work. Attempt to reschedule. */
- xpt_schedule_dev_allocq(bus, device);
}
- devq->alloc_queue.qfrozen_cnt[0]--;
+ device->ccbq.devq_allocating = 0;
}
static void
-xpt_run_dev_sendq(struct cam_eb *bus)
+xpt_run_devq(struct cam_devq *devq)
{
- struct cam_devq *devq;
char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
- CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_sendq\n"));
-
- devq = bus->sim->devq;
+ CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_devq\n"));
- devq->send_queue.qfrozen_cnt[0]++;
+ devq->send_queue.qfrozen_cnt++;
while ((devq->send_queue.entries > 0)
&& (devq->send_openings > 0)
- && (devq->send_queue.qfrozen_cnt[0] <= 1)) {
+ && (devq->send_queue.qfrozen_cnt <= 1)) {
struct cam_ed_qinfo *qinfo;
struct cam_ed *device;
union ccb *work_ccb;
@@ -3284,9 +3207,9 @@ xpt_run_dev_sendq(struct cam_eb *bus)
devq->send_openings--;
devq->send_active++;
- xpt_schedule_dev_sendq(bus, device);
+ xpt_schedule_devq(devq, device);
- if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
+ if ((work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0) {
/*
* The client wants to freeze the queue
* after this CCB is sent.
@@ -3336,7 +3259,7 @@ xpt_run_dev_sendq(struct cam_eb *bus)
sim = work_ccb->ccb_h.path->bus->sim;
(*(sim->sim_action))(sim, work_ccb);
}
- devq->send_queue.qfrozen_cnt[0]--;
+ devq->send_queue.qfrozen_cnt--;
}
/*
@@ -3799,14 +3722,7 @@ xpt_release_ccb(union ccb *free_ccb)
SLIST_INSERT_HEAD(&sim->ccb_freeq, &free_ccb->ccb_h,
xpt_links.sle);
}
- if (sim->devq == NULL) {
- return;
- }
- sim->devq->alloc_openings++;
- sim->devq->alloc_active--;
- if (device_is_alloc_queued(device) == 0)
- xpt_schedule_dev_allocq(bus, device);
- xpt_run_dev_allocq(bus);
+ xpt_run_dev_allocq(device);
}
/* Functions accessed by SIM drivers */
@@ -4153,34 +4069,18 @@ xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
}
u_int32_t
-xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, u_int count)
+xpt_freeze_devq(struct cam_path *path, u_int count)
{
struct cam_ed *dev = path->device;
mtx_assert(path->bus->sim->mtx, MA_OWNED);
- dev->sim->devq->alloc_openings +=
- cam_ccbq_freeze(&dev->ccbq, rl, count);
- /* Remove frozen device from allocq. */
- if (device_is_alloc_queued(dev) &&
- cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
- CAMQ_GET_PRIO(&dev->drvq)))) {
- camq_remove(&dev->sim->devq->alloc_queue,
- dev->alloc_ccb_entry.pinfo.index);
- }
+ dev->ccbq.queue.qfrozen_cnt += count;
/* Remove frozen device from sendq. */
- if (device_is_send_queued(dev) &&
- cam_ccbq_frozen_top(&dev->ccbq)) {
+ if (device_is_queued(dev)) {
camq_remove(&dev->sim->devq->send_queue,
- dev->send_ccb_entry.pinfo.index);
+ dev->devq_entry.pinfo.index);
}
- return (dev->ccbq.queue.qfrozen_cnt[rl]);
-}
-
-u_int32_t
-xpt_freeze_devq(struct cam_path *path, u_int count)
-{
-
- return (xpt_freeze_devq_rl(path, 0, count));
+ return (dev->ccbq.queue.qfrozen_cnt);
}
u_int32_t
@@ -4188,8 +4088,8 @@ xpt_freeze_simq(struct cam_sim *sim, u_int count)
{
mtx_assert(sim->mtx, MA_OWNED);
- sim->devq->send_queue.qfrozen_cnt[0] += count;
- return (sim->devq->send_queue.qfrozen_cnt[0]);
+ sim->devq->send_queue.qfrozen_cnt += count;
+ return (sim->devq->send_queue.qfrozen_cnt);
}
static void
@@ -4198,45 +4098,30 @@ xpt_release_devq_timeout(void *arg)
struct cam_ed *device;
device = (struct cam_ed *)arg;
-
- xpt_release_devq_device(device, /*rl*/0, /*count*/1, /*run_queue*/TRUE);
+ xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE);
}
void
xpt_release_devq(struct cam_path *path, u_int count, int run_queue)
{
- mtx_assert(path->bus->sim->mtx, MA_OWNED);
- xpt_release_devq_device(path->device, /*rl*/0, count, run_queue);
-}
-
-void
-xpt_release_devq_rl(struct cam_path *path, cam_rl rl, u_int count, int run_queue)
-{
mtx_assert(path->bus->sim->mtx, MA_OWNED);
-
- xpt_release_devq_device(path->device, rl, count, run_queue);
+ xpt_release_devq_device(path->device, count, run_queue);
}
-static void
-xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queue)
+void
+xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
{
- if (count > dev->ccbq.queue.qfrozen_cnt[rl]) {
+ if (count > dev->ccbq.queue.qfrozen_cnt) {
#ifdef INVARIANTS
- printf("xpt_release_devq(%d): requested %u > present %u\n",
- rl, count, dev->ccbq.queue.qfrozen_cnt[rl]);
+ printf("xpt_release_devq(): requested %u > present %u\n",
+ count, dev->ccbq.queue.qfrozen_cnt);
#endif
- count = dev->ccbq.queue.qfrozen_cnt[rl];
- }
- dev->sim->devq->alloc_openings -=
- cam_ccbq_release(&dev->ccbq, rl, count);
- if (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
- CAMQ_GET_PRIO(&dev->drvq))) == 0) {
- if (xpt_schedule_dev_allocq(dev->target->bus, dev))
- xpt_run_dev_allocq(dev->target->bus);
+ count = dev->ccbq.queue.qfrozen_cnt;
}
- if (cam_ccbq_frozen_top(&dev->ccbq) == 0) {
+ dev->ccbq.queue.qfrozen_cnt -= count;
+ if (dev->ccbq.queue.qfrozen_cnt == 0) {
/*
* No longer need to wait for a successful
* command completion.
@@ -4250,6 +4135,7 @@ xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queu
callout_stop(&dev->callout);
dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING;
}
+ xpt_run_dev_allocq(dev);
if (run_queue == 0)
return;
/*
@@ -4257,8 +4143,8 @@ xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queu
* device so any pending transactions are
* run.
*/
- if (xpt_schedule_dev_sendq(dev->target->bus, dev))
- xpt_run_dev_sendq(dev->target->bus);
+ if (xpt_schedule_devq(dev->sim->devq, dev))
+ xpt_run_devq(dev->sim->devq);
}
}
@@ -4269,14 +4155,14 @@ xpt_release_simq(struct cam_sim *sim, int run_queue)
mtx_assert(sim->mtx, MA_OWNED);
sendq = &(sim->devq->send_queue);
- if (sendq->qfrozen_cnt[0] <= 0) {
+ if (sendq->qfrozen_cnt <= 0) {
#ifdef INVARIANTS
printf("xpt_release_simq: requested 1 > present %u\n",
- sendq->qfrozen_cnt[0]);
+ sendq->qfrozen_cnt);
#endif
} else
- sendq->qfrozen_cnt[0]--;
- if (sendq->qfrozen_cnt[0] == 0) {
+ sendq->qfrozen_cnt--;
+ if (sendq->qfrozen_cnt == 0) {
/*
* If there is a timeout scheduled to release this
* sim queue, remove it. The queue frozen count is
@@ -4287,14 +4173,10 @@ xpt_release_simq(struct cam_sim *sim, int run_queue)
sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING;
}
if (run_queue) {
- struct cam_eb *bus;
-
/*
* Now that we are unfrozen run the send queue.
*/
- bus = xpt_find_bus(sim->path_id);
- xpt_run_dev_sendq(bus);
- xpt_release_bus(bus);
+ xpt_run_devq(sim->devq);
}
}
}
@@ -4518,7 +4400,7 @@ xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
mtx_assert(target->bus->sim->mtx, MA_OWNED);
/* Make space for us in the device queue on our bus */
devq = bus->sim->devq;
- status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
+ status = cam_devq_resize(devq, devq->send_queue.array_size + 1);
if (status != CAM_REQ_CMP)
return (NULL);
@@ -4527,10 +4409,8 @@ xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
if (device == NULL)
return (NULL);
- cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
- device->alloc_ccb_entry.device = device;
- cam_init_pinfo(&device->send_ccb_entry.pinfo);
- device->send_ccb_entry.device = device;
+ cam_init_pinfo(&device->devq_entry.pinfo);
+ device->devq_entry.device = device;
device->target = target;
device->lun_id = lun_id;
device->sim = bus->sim;
@@ -4586,8 +4466,7 @@ xpt_release_device(struct cam_ed *device)
KASSERT(SLIST_EMPTY(&device->periphs),
("refcount is zero, but periphs list is not empty"));
- if (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX
- || device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX)
+ if (device->devq_entry.pinfo.index != CAM_UNQUEUED_INDEX)
panic("Removing device while still queued for ccbs");
if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0)
@@ -4598,7 +4477,7 @@ xpt_release_device(struct cam_ed *device)
device->target->bus->sim->max_ccbs -= device->ccbq.devq_openings;
/* Release our slot in the devq */
devq = device->target->bus->sim->devq;
- cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
+ cam_devq_resize(devq, devq->send_queue.array_size - 1);
camq_fini(&device->drvq);
cam_ccbq_fini(&device->ccbq);
/*
@@ -5064,9 +4943,9 @@ camisr_runqueue(void *V_queue)
if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
&& (--dev->tag_delay_count == 0))
xpt_start_tags(ccb_h->path);
- if (!device_is_send_queued(dev)) {
- (void)xpt_schedule_dev_sendq(ccb_h->path->bus,
- dev);
+ if (!device_is_queued(dev)) {
+ (void)xpt_schedule_devq(
+ ccb_h->path->bus->sim->devq, dev);
}
}
@@ -5083,7 +4962,7 @@ camisr_runqueue(void *V_queue)
/*run_queue*/TRUE);
ccb_h->status &= ~CAM_DEV_QFRZN;
} else if (runq) {
- xpt_run_dev_sendq(ccb_h->path->bus);
+ xpt_run_devq(ccb_h->path->bus->sim->devq);
}
/* Call the peripheral driver's callback */
diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h
index 8c62c4ef3893..6d2aeccce467 100644
--- a/sys/cam/cam_xpt_internal.h
+++ b/sys/cam/cam_xpt_internal.h
@@ -71,8 +71,7 @@ struct cam_ed_qinfo {
*/
struct cam_ed {
TAILQ_ENTRY(cam_ed) links;
- struct cam_ed_qinfo alloc_ccb_entry;
- struct cam_ed_qinfo send_ccb_entry;
+ struct cam_ed_qinfo devq_entry;
struct cam_et *target;
struct cam_sim *sim;
lun_id_t lun_id;
diff --git a/sys/cam/cam_xpt_sim.h b/sys/cam/cam_xpt_sim.h
index c2227b4251a5..09126cf6dd53 100644
--- a/sys/cam/cam_xpt_sim.h
+++ b/sys/cam/cam_xpt_sim.h
@@ -43,12 +43,8 @@ int32_t xpt_bus_deregister(path_id_t path_id);
u_int32_t xpt_freeze_simq(struct cam_sim *sim, u_int count);
void xpt_release_simq(struct cam_sim *sim, int run_queue);
u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count);
-u_int32_t xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl,
- u_int count);
void xpt_release_devq(struct cam_path *path,
u_int count, int run_queue);
-void xpt_release_devq_rl(struct cam_path *path, cam_rl rl,
- u_int count, int run_queue);
void xpt_done(union ccb *done_ccb);
void xpt_batch_start(struct cam_sim *sim);
void xpt_batch_done(struct cam_sim *sim);
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index f065e3b7e6ee..3fcd40916972 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -2060,7 +2060,6 @@ ctlfe_lun_disable(void *arg, struct ctl_id targ_id, int lun_id)
static void
ctlfe_dump_sim(struct cam_sim *sim)
{
- int i;
printf("%s%d: max tagged openings: %d, max dev openings: %d\n",
sim->sim_name, sim->unit_number,
@@ -2071,14 +2070,6 @@ ctlfe_dump_sim(struct cam_sim *sim)
printf("%s%d: ccb_freeq is %sempty\n",
sim->sim_name, sim->unit_number,
(SLIST_FIRST(&sim->ccb_freeq) == NULL) ? "" : "NOT ");
- printf("%s%d: alloc_queue.entries %d, alloc_openings %d\n",
- sim->sim_name, sim->unit_number,
- sim->devq->alloc_queue.entries, sim->devq->alloc_openings);
- printf("%s%d: qfrozen_cnt:", sim->sim_name, sim->unit_number);
- for (i = 0; i < CAM_RL_VALUES; i++) {
- printf("%s%u", (i != 0) ? ":" : "",
- sim->devq->alloc_queue.qfrozen_cnt[i]);
- }
printf("\n");
}
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 8e698cf45c1e..ba903a1d71b9 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -464,7 +464,7 @@ cdcleanup(struct cam_periph *periph)
callout_stop(&softc->changer->short_handle);
softc->changer->flags &= ~CHANGER_SHORT_TMOUT_SCHED;
}
- softc->changer->devq.qfrozen_cnt[0]--;
+ softc->changer->devq.qfrozen_cnt--;
softc->changer->flags |= CHANGER_MANUAL_CALL;
cdrunchangerqueue(softc->changer);
}
@@ -1249,13 +1249,13 @@ cdrunchangerqueue(void *arg)
* If the changer queue is frozen, that means we have an active
* device.
*/
- if (changer->devq.qfrozen_cnt[0] > 0) {
+ if (changer->devq.qfrozen_cnt > 0) {
/*
* We always need to reset the frozen count and clear the
* active flag.
*/
- changer->devq.qfrozen_cnt[0]--;
+ changer->devq.qfrozen_cnt--;
changer->cur_device->flags &= ~CD_FLAG_ACTIVE;
changer->cur_device->flags &= ~CD_FLAG_SCHED_ON_COMP;
@@ -1290,7 +1290,7 @@ cdrunchangerqueue(void *arg)
changer->cur_device = softc;
- changer->devq.qfrozen_cnt[0]++;
+ changer->devq.qfrozen_cnt++;
softc->flags |= CD_FLAG_ACTIVE;
/* Just in case this device is waiting */
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index cd4182b3bf04..56bb17ca26f8 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -613,8 +613,8 @@ passioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t
/* Compatibility for RL/priority-unaware code. */
priority = inccb->ccb_h.pinfo.priority;
- if (priority < CAM_RL_TO_PRIORITY(CAM_RL_NORMAL))
- priority += CAM_RL_TO_PRIORITY(CAM_RL_NORMAL);
+ if (priority <= CAM_PRIORITY_OOB)
+ priority += CAM_PRIORITY_OOB + 1;
/*
* Non-immediate CCBs need a CCB from the per-device pool
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index 0856922dc623..5d0512eeb869 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -648,11 +648,6 @@ proberegister(struct cam_periph *periph, void *arg)
*/
cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
scsi_delay);
- /*
- * Ensure nobody slip in until probe finish.
- */
- cam_freeze_devq_arg(periph->path,
- RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1);
probeschedule(periph);
return(CAM_REQ_CMP);
}
@@ -981,6 +976,7 @@ again:
default:
panic("probestart: invalid action state 0x%x\n", softc->action);
}
+ start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
xpt_action(start_ccb);
}
@@ -1127,8 +1123,12 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (cam_periph_error(done_ccb, 0,
- SF_NO_PRINT, NULL) == ERESTART)
+ SF_NO_PRINT, NULL) == ERESTART) {
+out:
+ /* Drop freeze taken due to CAM_DEV_QFREEZE */
+ cam_release_devq(path, 0, 0, 0, FALSE);
return;
+ }
else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path,
@@ -1138,7 +1138,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
PROBE_SET_ACTION(softc, PROBE_INQUIRY);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
case PROBE_INQUIRY:
case PROBE_FULL_INQUIRY:
@@ -1173,7 +1173,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
scsi_find_quirk(path->device);
@@ -1203,7 +1203,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
}
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
} else if (path->device->lun_id == 0 &&
SID_ANSI_REV(inq_buf) > SCSI_REV_SPC2 &&
(SCSI_QUIRK(path->device)->quirks &
@@ -1218,14 +1218,14 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
periph->path->target->rpl_size = 16;
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
} else if (cam_periph_error(done_ccb, 0,
done_ccb->ccb_h.target_lun > 0
? SF_RETRY_UA|SF_QUIET_IR
: SF_RETRY_UA,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1266,7 +1266,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
done_ccb->ccb_h.target_lun > 0 ?
SF_RETRY_UA|SF_QUIET_IR : SF_RETRY_UA,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
}
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
xpt_release_devq(done_ccb->ccb_h.path, 1,
@@ -1285,7 +1285,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
path->target->rpl_size = (nlun << 3) + 8;
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
} else if (nlun == 0) {
/*
* If there don't appear to be any luns, bail.
@@ -1358,7 +1358,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
PROBE_SUPPORTED_VPD_LIST);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
if (lp) {
free(lp, M_CAMXPT);
@@ -1383,7 +1383,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA|SF_NO_PRINT,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path,
@@ -1393,7 +1393,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
free(mode_hdr, M_CAMXPT);
PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
case PROBE_SUPPORTED_VPD_LIST:
{
@@ -1422,11 +1422,11 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
xpt_release_ccb(done_ccb);
PROBE_SET_ACTION(softc, PROBE_DEVICE_ID);
xpt_schedule(periph, priority);
- return;
+ goto out;
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA|SF_NO_PRINT,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1471,7 +1471,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1484,7 +1484,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
xpt_release_ccb(done_ccb);
PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
probe_device_check:
@@ -1526,7 +1526,7 @@ probe_device_check:
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA|SF_NO_PRINT,
&softc->saved_ccb) == ERESTART) {
- return;
+ goto out;
} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
/* Don't wedge the queue */
xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
@@ -1585,7 +1585,7 @@ probe_device_check:
*/
PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
xpt_release_ccb(done_ccb);
break;
@@ -1615,7 +1615,7 @@ probe_device_check:
xpt_release_ccb(done_ccb);
PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV1);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
if (softc->action == PROBE_DV_EXIT) {
CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
@@ -1668,14 +1668,14 @@ probe_device_check:
free(nbuf, M_CAMXPT);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
free(nbuf, M_CAMXPT);
if (softc->action == PROBE_INQUIRY_BASIC_DV1) {
PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV2);
xpt_release_ccb(done_ccb);
xpt_schedule(periph, priority);
- return;
+ goto out;
}
if (softc->action == PROBE_INQUIRY_BASIC_DV2) {
CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
@@ -1707,12 +1707,13 @@ probe_device_check:
xpt_done(done_ccb);
if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
+ /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
+ cam_release_devq(path, 0, 0, 0, FALSE);
cam_periph_invalidate(periph);
- cam_release_devq(periph->path,
- RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
cam_periph_release_locked(periph);
} else {
probeschedule(periph);
+ goto out;
}
}