diff options
author | Warner Losh <imp@FreeBSD.org> | 2023-04-14 14:32:20 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2023-04-15 22:32:41 +0000 |
commit | fd02926a68c9570f00f7e50d64c1d0673581fb35 (patch) | |
tree | 542fddc96c9211dddad3c1a05b44bdb2a922ad6f | |
parent | 63ee747febbf024be0aace61161241b53245449e (diff) | |
download | src-fd02926a68c9570f00f7e50d64c1d0673581fb35.tar.gz src-fd02926a68c9570f00f7e50d64c1d0673581fb35.zip |
cam: Properly mask out the status bits to get completion code
ccb_h.status has two parts: the actual status and some addition bits to
indicate additional information. It must be masked before comparing
against completion codes. Add new inline function cam_ccb_success to
simplify this to test whether or not the request succeeded. Most of the
code already does this, but a few places don't (the rest likely should
be converted to use cam_ccb_status and/or cam_ccb_success, but that's
for another day). This caused at least one bug in recognizing devices
behind a SATA port multiplexer, though some of these checks were
fine with the special knowledge of the code paths involved.
PR: 270459
Sponsored by: Netflix
MFC After: 1 week (and maybe a EN requst)
Reviewed by: ken, mav
Differential Revision: https://reviews.freebsd.org/D39572
-rw-r--r-- | sys/cam/ata/ata_xpt.c | 4 | ||||
-rw-r--r-- | sys/cam/cam_ccb.h | 6 | ||||
-rw-r--r-- | sys/cam/cam_xpt.c | 2 | ||||
-rw-r--r-- | sys/cam/nvme/nvme_da.c | 3 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_enc_ses.c | 4 |
5 files changed, 12 insertions, 7 deletions
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 2b299412b48e..643508c5d395 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -1003,7 +1003,7 @@ noerror: path->bus->sim->max_tagged_dev_openings != 0) { /* Check if the SIM does not want queued commands. */ xpt_path_inq(&cpi, path); - if (cpi.ccb_h.status == CAM_REQ_CMP && + if (cam_ccb_success((union ccb *)&cpi) && (cpi.hba_inquiry & PI_TAG_ABLE)) { /* Report SIM which tags are allowed. */ bzero(&cts, sizeof(cts)); @@ -1481,7 +1481,7 @@ ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) /* If there is PMP... */ if ((scan_info->cpi->hba_inquiry & PI_SATAPM) && (scan_info->counter == scan_info->cpi->max_target)) { - if (work_ccb->ccb_h.status == CAM_REQ_CMP) { + if (cam_ccb_success(work_ccb)) { /* everything else will be probed by it */ /* Free the current request path- we're done with it. */ xpt_free_path(work_ccb->ccb_h.path); diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 1ae310d399b7..a6b12b6a3584 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -1516,6 +1516,12 @@ cam_ccb_status(union ccb *ccb) return ((cam_status)(ccb->ccb_h.status & CAM_STATUS_MASK)); } +static inline bool +cam_ccb_success(union ccb *ccb) +{ + return (cam_ccb_status(ccb) == CAM_REQ_CMP); +} + void cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended); static __inline void diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index f3e9f2772e62..efedcaf5cf92 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -4018,7 +4018,7 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, uint32_t bus) xpt_path_inq(&cpi, path); - if (cpi.ccb_h.status == CAM_REQ_CMP) { + if (cam_ccb_success((union ccb *)&cpi)) { struct xpt_xport **xpt; SET_FOREACH(xpt, cam_xpt_xport_set) { diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c index 51689d0e4a23..94915ec6a726 100644 --- a/sys/cam/nvme/nvme_da.c +++ b/sys/cam/nvme/nvme_da.c @@ -441,8 +441,7 @@ ndaioctl(struct disk *dp, u_long cmd, void *data, int fflag, */ cam_periph_unlock(periph); cam_periph_unmapmem(ccb, &mapinfo); - error = (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP ? - 0 : EIO; + error = cam_ccb_success(ccb) ? 0 : EIO; out: cam_periph_lock(periph); xpt_release_ccb(ccb); diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c index 557038d9b9f6..58b0a5af74cd 100644 --- a/sys/cam/scsi/scsi_enc_ses.c +++ b/sys/cam/scsi/scsi_enc_ses.c @@ -986,7 +986,7 @@ ses_paths_iter(enc_softc_t *enc, enc_element_t *elm, xpt_setup_ccb(&cgd.ccb_h, path, CAM_PRIORITY_NORMAL); cgd.ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)&cgd); - if (cgd.ccb_h.status == CAM_REQ_CMP) + if (cam_ccb_success((union ccb *)&cgd)) callback(enc, elm, path, callback_arg); xpt_free_path(path); @@ -1065,7 +1065,7 @@ ses_setphyspath_callback(enc_softc_t *enc, enc_element_t *elm, xpt_action((union ccb *)&cdai); if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE); - if (cdai.ccb_h.status == CAM_REQ_CMP) + if (cam_ccb_success((union ccb *)&cdai)) args->num_set++; } xpt_path_unlock(path); |