aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_da.c85
-rw-r--r--sys/cam/cam_xpt.c8
-rw-r--r--sys/cam/ctl/ctl.c2
-rw-r--r--sys/cam/nvme/nvme_da.c5
-rw-r--r--sys/cam/scsi/scsi_all.c6
-rw-r--r--sys/cam/scsi/scsi_da.c25
-rw-r--r--sys/cam/scsi/scsi_enc.c2
-rw-r--r--sys/cam/scsi/scsi_enc_ses.c8
-rw-r--r--sys/cam/scsi/scsi_pass.c3
-rw-r--r--sys/cam/scsi/scsi_target.c1
10 files changed, 122 insertions, 23 deletions
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 1facab47473c..9434756b87f9 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <sys/endian.h>
#include <sys/cons.h>
+#include <sys/power.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sbuf.h>
@@ -878,8 +879,8 @@ static int adaerror(union ccb *ccb, uint32_t cam_flags,
uint32_t sense_flags);
static callout_func_t adasendorderedtag;
static void adashutdown(void *arg, int howto);
-static void adasuspend(void *arg);
-static void adaresume(void *arg);
+static void adasuspend(void *arg, enum power_stype stype);
+static void adaresume(void *arg, enum power_stype stype);
#ifndef ADA_DEFAULT_TIMEOUT
#define ADA_DEFAULT_TIMEOUT 30 /* Timeout in seconds */
@@ -1556,11 +1557,11 @@ adasysctlinit(void *context, int pending)
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "unmapped_io", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&softc->flags, (u_int)ADA_FLAG_UNMAPPEDIO, adabitsysctl, "I",
- "Use unmapped I/O. This sysctl is *DEPRECATED*, gone in FreeBSD 15");
+ "Use unmapped I/O. This sysctl is *DEPRECATED*, gone in FreeBSD 16");
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "rotating", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&softc->flags, (u_int)ADA_FLAG_ROTATING, adabitsysctl, "I",
- "Rotating media. This sysctl is *DEPRECATED*, gone in FreeBSD 15");
+ "Rotating media. This sysctl is *DEPRECATED*, gone in FreeBSD 16");
#ifdef CAM_TEST_FAILURE
/*
@@ -2327,15 +2328,38 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
{
struct ada_softc *softc = (struct ada_softc *)periph->softc;
struct ccb_ataio *ataio = &start_ccb->ataio;
+ uint32_t priority = start_ccb->ccb_h.pinfo.priority;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
+ /*
+ * When we're running the state machine, we should only accept DEV CCBs.
+ * When we're doing normal I/O we should only accept NORMAL CCBs.
+ *
+ * While in the state machine, we carefully single step the queue, but
+ * there's no protection for 'extra' calls to xpt_schedule() at the
+ * wrong priority. Guard against that so that we filter any CCBs that
+ * are offered at the wrong priority. This avoids generating requests
+ * that are at normal priority.
+` */
+ if ((softc->state != ADA_STATE_NORMAL && priority != CAM_PRIORITY_DEV) ||
+ (softc->state == ADA_STATE_NORMAL && priority != CAM_PRIORITY_NORMAL)) {
+ xpt_print(periph->path, "Bad priority for state %d prio %d\n",
+ softc->state, priority);
+ xpt_release_ccb(start_ccb);
+ return;
+ }
+
switch (softc->state) {
case ADA_STATE_NORMAL:
{
struct bio *bp;
uint8_t tag_code;
+ KASSERT(priority == CAM_PRIORITY_NORMAL,
+ ("Expected priority %d, found %d in state normal",
+ CAM_PRIORITY_NORMAL, priority));
+
bp = cam_iosched_next_bio(softc->cam_iosched);
if (bp == NULL) {
xpt_release_ccb(start_ccb);
@@ -2554,6 +2578,11 @@ out:
case ADA_STATE_RAHEAD:
case ADA_STATE_WCACHE:
{
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in state %s",
+ CAM_PRIORITY_DEV, priority,
+ softc->state == ADA_STATE_RAHEAD ? "rahead" : "wcache"));
+
cam_fill_ataio(ataio,
1,
adadone,
@@ -2580,6 +2609,10 @@ out:
{
struct ata_gp_log_dir *log_dir;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in state logdir",
+ CAM_PRIORITY_DEV, priority));
+
if ((softc->flags & ADA_FLAG_CAN_LOG) == 0) {
adaprobedone(periph, start_ccb);
break;
@@ -2614,6 +2647,10 @@ out:
{
struct ata_identify_log_pages *id_dir;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in state iddir",
+ CAM_PRIORITY_DEV, priority));
+
id_dir = malloc(sizeof(*id_dir), M_ATADA, M_NOWAIT | M_ZERO);
if (id_dir == NULL) {
xpt_print(periph->path, "Couldn't malloc id_dir "
@@ -2642,6 +2679,10 @@ out:
{
struct ata_identify_log_sup_cap *sup_cap;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in state sup_cap",
+ CAM_PRIORITY_DEV, priority));
+
sup_cap = malloc(sizeof(*sup_cap), M_ATADA, M_NOWAIT|M_ZERO);
if (sup_cap == NULL) {
xpt_print(periph->path, "Couldn't malloc sup_cap "
@@ -2670,6 +2711,10 @@ out:
{
struct ata_zoned_info_log *ata_zone;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in state zone",
+ CAM_PRIORITY_DEV, priority));
+
ata_zone = malloc(sizeof(*ata_zone), M_ATADA, M_NOWAIT|M_ZERO);
if (ata_zone == NULL) {
xpt_print(periph->path, "Couldn't malloc ata_zone "
@@ -2895,6 +2940,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
struct bio *bp;
int error;
+ KASSERT(priority == CAM_PRIORITY_NORMAL,
+ ("Expected priority %d, found %d for normal I/O",
+ CAM_PRIORITY_NORMAL, priority));
+
cam_periph_lock(periph);
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
@@ -2999,6 +3048,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
}
case ADA_CCB_RAHEAD:
{
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state rahead",
+ CAM_PRIORITY_DEV, priority));
+
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (adaerror(done_ccb, 0, 0) == ERESTART) {
/* Drop freeze taken due to CAM_DEV_QFREEZE */
@@ -3022,6 +3075,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
}
case ADA_CCB_WCACHE:
{
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state wcache",
+ CAM_PRIORITY_DEV, priority));
+
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (adaerror(done_ccb, 0, 0) == ERESTART) {
/* Drop freeze taken due to CAM_DEV_QFREEZE */
@@ -3053,6 +3110,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
{
int error;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state logdir",
+ CAM_PRIORITY_DEV, priority));
+
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
error = 0;
softc->valid_logdir_len = 0;
@@ -3122,6 +3183,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
case ADA_CCB_IDDIR: {
int error;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state iddir",
+ CAM_PRIORITY_DEV, priority));
+
if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
off_t entries_offset, max_entries;
error = 0;
@@ -3207,6 +3272,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
case ADA_CCB_SUP_CAP: {
int error;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state sup_cap",
+ CAM_PRIORITY_DEV, priority));
+
if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
uint32_t valid_len;
size_t needed_size;
@@ -3311,6 +3380,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
case ADA_CCB_ZONE: {
int error;
+ KASSERT(priority == CAM_PRIORITY_DEV,
+ ("Expected priority %d, found %d in ccb state zone",
+ CAM_PRIORITY_DEV, priority));
+
if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
struct ata_zoned_info_log *zi_log;
uint32_t valid_len;
@@ -3747,7 +3820,7 @@ adashutdown(void *arg, int howto)
}
static void
-adasuspend(void *arg)
+adasuspend(void *arg, enum power_stype stype)
{
adaflush();
@@ -3760,7 +3833,7 @@ adasuspend(void *arg)
}
static void
-adaresume(void *arg)
+adaresume(void *arg, enum power_stype stype)
{
struct cam_periph *periph;
struct ada_softc *softc;
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index cae29226d13c..a11b688c4456 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -1046,6 +1046,7 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string)
sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
xpt_announce_periph_sbuf(periph, &sb, announce_string);
(void)sbuf_finish(&sb);
+ (void)sbuf_delete(&sb);
}
void
@@ -1122,6 +1123,7 @@ xpt_denounce_periph(struct cam_periph *periph)
sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
xpt_denounce_periph_sbuf(periph, &sb);
(void)sbuf_finish(&sb);
+ (void)sbuf_delete(&sb);
}
void
@@ -5547,7 +5549,7 @@ xpt_cam_path_debug(struct cam_path *path, const char *fmt, ...)
{
struct sbuf sbuf;
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
- struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
+ struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
va_list ap;
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
@@ -5566,7 +5568,7 @@ xpt_cam_dev_debug(struct cam_ed *dev, const char *fmt, ...)
{
struct sbuf sbuf;
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
- struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
+ struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
va_list ap;
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
@@ -5585,7 +5587,7 @@ xpt_cam_debug(const char *fmt, ...)
{
struct sbuf sbuf;
char buf[XPT_PRINT_LEN]; /* balance to not eat too much stack */
- struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN);
+ struct sbuf *sb = sbuf_new(&sbuf, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
va_list ap;
sbuf_set_drain(sb, sbuf_printf_drain, NULL);
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index e110281f7c85..442ef1d30542 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -2123,7 +2123,7 @@ ctl_remove_initiator(struct ctl_port *port, int iid)
mtx_assert(&softc->ctl_lock, MA_NOTOWNED);
if (iid > CTL_MAX_INIT_PER_PORT) {
- printf("%s: initiator ID %u > maximun %u!\n",
+ printf("%s: initiator ID %u > maximum %u!\n",
__func__, iid, CTL_MAX_INIT_PER_PORT);
return (-1);
}
diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 1c0d5e8381d8..9c4707da482c 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -43,6 +43,7 @@
#include <sys/eventhandler.h>
#include <sys/malloc.h>
#include <sys/cons.h>
+#include <sys/power.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/sbuf.h>
@@ -159,7 +160,7 @@ static void ndadone(struct cam_periph *periph,
static int ndaerror(union ccb *ccb, uint32_t cam_flags,
uint32_t sense_flags);
static void ndashutdown(void *arg, int howto);
-static void ndasuspend(void *arg);
+static void ndasuspend(void *arg, enum power_stype stype);
#ifndef NDA_DEFAULT_SEND_ORDERED
#define NDA_DEFAULT_SEND_ORDERED 1
@@ -1365,7 +1366,7 @@ ndashutdown(void *arg, int howto)
}
static void
-ndasuspend(void *arg)
+ndasuspend(void *arg, enum power_stype stype)
{
ndaflush();
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index b518f84454ad..fd128e69f1f1 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -112,7 +112,7 @@ static void fetchtableentries(int sense_key, int asc, int ascq,
const struct asc_table_entry **);
#ifdef _KERNEL
-static void init_scsi_delay(void);
+static void init_scsi_delay(void *);
static int sysctl_scsi_delay(SYSCTL_HANDLER_ARGS);
static int set_scsi_delay(int delay);
#endif
@@ -686,7 +686,7 @@ scsi_op_desc(uint16_t opcode, struct scsi_inquiry_data *inq_data)
opmask = 1 << pd_type;
for (j = 0; j < num_tables; j++) {
- for (i = 0;i < num_ops[j] && table[j][i].opcode <= opcode; i++){
+ for (i = 0; i < num_ops[j] && table[j][i].opcode <= opcode; i++) {
if ((table[j][i].opcode == opcode)
&& ((table[j][i].opmask & opmask) != 0))
return(table[j][i].desc);
@@ -9379,7 +9379,7 @@ scsi_vpd_supported_page(struct cam_periph *periph, uint8_t page_id)
}
static void
-init_scsi_delay(void)
+init_scsi_delay(void *dummy __unused)
{
int delay;
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index fc8c0413448d..773a786d08f7 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -2408,11 +2408,11 @@ dasysctlinit(void *context, int pending)
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "rotating", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&softc->flags, (u_int)DA_FLAG_ROTATING, dabitsysctl, "I",
- "Rotating media *DEPRECATED* gone in FreeBSD 15");
+ "Rotating media *DEPRECATED* gone in FreeBSD 16");
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "unmapped_io", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
&softc->flags, (u_int)DA_FLAG_UNMAPPEDIO, dabitsysctl, "I",
- "Unmapped I/O support *DEPRECATED* gone in FreeBSD 15");
+ "Unmapped I/O support *DEPRECATED* gone in FreeBSD 16");
#ifdef CAM_TEST_FAILURE
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
@@ -3369,12 +3369,33 @@ static void
dastart(struct cam_periph *periph, union ccb *start_ccb)
{
struct da_softc *softc;
+ uint32_t priority = start_ccb->ccb_h.pinfo.priority;
cam_periph_assert(periph, MA_OWNED);
softc = (struct da_softc *)periph->softc;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n"));
+ /*
+ * When we're running the state machine, we should only accept DEV CCBs.
+ * When we're doing normal I/O we should only accept NORMAL CCBs.
+ *
+ * While in the state machine, we carefully single step the queue, but
+ * there's no protection for 'extra' calls to xpt_schedule() at the
+ * wrong priority. Guard against that so that we filter any CCBs that
+ * are offered at the wrong priority. This avoids generating requests
+ * that are at normal priority. In addition, though we can't easily
+ * enforce it, one must not transition to the NORMAL state via the
+ * skipstate mechanism.
+` */
+ if ((softc->state != DA_STATE_NORMAL && priority != CAM_PRIORITY_DEV) ||
+ (softc->state == DA_STATE_NORMAL && priority != CAM_PRIORITY_NORMAL)) {
+ xpt_print(periph->path, "Bad priority for state %d prio %d\n",
+ softc->state, priority);
+ xpt_release_ccb(start_ccb);
+ return;
+ }
+
skipstate:
switch (softc->state) {
case DA_STATE_NORMAL:
diff --git a/sys/cam/scsi/scsi_enc.c b/sys/cam/scsi/scsi_enc.c
index 9705a0b890b4..65df32ead371 100644
--- a/sys/cam/scsi/scsi_enc.c
+++ b/sys/cam/scsi/scsi_enc.c
@@ -732,7 +732,7 @@ enc_update_request(enc_softc_t *enc, uint32_t action)
{
if ((enc->pending_actions & (0x1 << action)) == 0) {
enc->pending_actions |= (0x1 << action);
- ENC_DLOG(enc, "%s: queing requested action %d\n",
+ ENC_DLOG(enc, "%s: queueing requested action %d\n",
__func__, action);
if (enc->current_action == ENC_UPDATE_NONE)
wakeup(enc->enc_daemon);
diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c
index 435874a9874a..838eecf78ad6 100644
--- a/sys/cam/scsi/scsi_enc_ses.c
+++ b/sys/cam/scsi/scsi_enc_ses.c
@@ -1623,7 +1623,7 @@ ses_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
} else {
if (cur_stat <= last_stat)
ENC_VLOG(enc, "Status page, exhausted objects before "
- "exhausing page\n");
+ "exhausting page\n");
enc_update_request(enc, SES_PUBLISH_CACHE);
err = 0;
}
@@ -2302,7 +2302,7 @@ ses_print_addl_data_sas_type0(char *sesname, struct sbuf *sbp,
sbuf_putc(sbp, '\n');
if (addl->proto_data.sasdev_phys == NULL)
return;
- for (i = 0;i < addl->proto_hdr.sas->base_hdr.num_phys;i++) {
+ for (i = 0; i < addl->proto_hdr.sas->base_hdr.num_phys; i++) {
phy = &addl->proto_data.sasdev_phys[i];
sbuf_printf(sbp, "%s: phy %d:", sesname, i);
if (ses_elm_sas_dev_phy_sata_dev(phy))
@@ -2349,7 +2349,7 @@ ses_print_addl_data_sas_type1(char *sesname, struct sbuf *sbp,
sbuf_printf(sbp, "Expander: %d phys", num_phys);
if (addl->proto_data.sasexp_phys == NULL)
return;
- for (i = 0;i < num_phys;i++) {
+ for (i = 0; i < num_phys; i++) {
exp_phy = &addl->proto_data.sasexp_phys[i];
sbuf_printf(sbp, "%s: phy %d: connector %d other %d\n",
sesname, i, exp_phy->connector_index,
@@ -2360,7 +2360,7 @@ ses_print_addl_data_sas_type1(char *sesname, struct sbuf *sbp,
sbuf_printf(sbp, "Port: %d phys", num_phys);
if (addl->proto_data.sasport_phys == NULL)
return;
- for (i = 0;i < num_phys;i++) {
+ for (i = 0; i < num_phys; i++) {
port_phy = &addl->proto_data.sasport_phys[i];
sbuf_printf(sbp,
"%s: phy %d: id %d connector %d other %d\n",
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index c3587421c176..b44ab866dfe7 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -206,7 +206,8 @@ static struct cdevsw pass_cdevsw = {
static const struct filterops passread_filtops = {
.f_isfd = 1,
.f_detach = passreadfiltdetach,
- .f_event = passreadfilt
+ .f_event = passreadfilt,
+ .f_copy = knote_triv_copy,
};
static MALLOC_DEFINE(M_SCSIPASS, "scsi_pass", "scsi passthrough buffers");
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 21c78e35dadc..39ce2bcea8f4 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -108,6 +108,7 @@ static const struct filterops targread_filtops = {
.f_isfd = 1,
.f_detach = targreadfiltdetach,
.f_event = targreadfilt,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw targ_cdevsw = {