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 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) 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 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) 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 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) } xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } case PROBE_IDENTIFY: { @@ -864,7 +862,7 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) } 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) 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; + struct camq *drvq; - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n")); - devq = bus->sim->devq; - - 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")); + CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_devq\n")); - devq = bus->sim->devq; - - 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); + mtx_assert(path->bus->sim->mtx, MA_OWNED); + xpt_release_devq_device(path->device, 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); -} - -static void -xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queue) +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]; + count = dev->ccbq.queue.qfrozen_cnt; } - 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); - } - 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 @@ probestart(struct cam_periph *periph, union ccb *start_ccb) 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 @@ 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, /*count*/1, @@ -1585,7 +1585,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) */ 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 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) 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 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) 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 @@ probedone(struct cam_periph *periph, union ccb *done_ccb) 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; } }