git: fd02926a68c9 - main - cam: Properly mask out the status bits to get completion code
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 15 Apr 2023 22:32:45 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=fd02926a68c9570f00f7e50d64c1d0673581fb35 commit fd02926a68c9570f00f7e50d64c1d0673581fb35 Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2023-04-14 14:32:20 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2023-04-15 22:32:41 +0000 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 --- sys/cam/ata/ata_xpt.c | 4 ++-- sys/cam/cam_ccb.h | 6 ++++++ sys/cam/cam_xpt.c | 2 +- sys/cam/nvme/nvme_da.c | 3 +-- 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);