aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/cam_compat.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-10-05 18:54:03 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-10-05 18:54:03 +0000
commit8f9be1eed11c27c66386c3d72cd6c6aef597fa0d (patch)
treea91e9060ef4d8492ea56cfd9f40bf0d1d9c1e619 /sys/cam/cam_compat.c
parent7835b2cb4a1ae57f403739a2f1076ec7188f18c9 (diff)
downloadsrc-8f9be1eed11c27c66386c3d72cd6c6aef597fa0d.tar.gz
src-8f9be1eed11c27c66386c3d72cd6c6aef597fa0d.zip
cam(4): Improve XPT_DEV_MATCH
Remove *_MATCH_NONE enums, making no sense and so never used. Make *_MATCH_ANY enums 0 (no any match flags set), previously used by *_MATCH_NONE. Bump CAM_VERSION to 0x1a reflecting those changes and add compat shims. When traversing through buses and devices do not descend if we can already see that requested pattern does not match the bus or device. It allows to save significant amount of time on system with thousands of disks when doing limited searches. Reviewed by: imp MFC after: 2 weeks Sponsored by: iXsystems, Inc. Differential Revision: https://reviews.freebsd.org/D32304
Diffstat (limited to 'sys/cam/cam_compat.c')
-rw-r--r--sys/cam/cam_compat.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c
index 4c89072fa389..6893402a3d9c 100644
--- a/sys/cam/cam_compat.c
+++ b/sys/cam/cam_compat.c
@@ -58,6 +58,8 @@ static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
int flag, struct thread *td, d_ioctl_t *cbfnp);
static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr,
int flag, struct thread *td, d_ioctl_t *cbfnp);
+static int cam_compat_handle_0x19(struct cdev *dev, u_long cmd, caddr_t addr,
+ int flag, struct thread *td, d_ioctl_t *cbfnp);
static int cam_compat_translate_dev_match_0x18(union ccb *ccb);
int
@@ -108,6 +110,22 @@ cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
cmd = CAMGETPASSTHRU;
error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
break;
+ case CAMIOCOMMAND_0x19:
+ cmd = CAMIOCOMMAND;
+ error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
+ break;
+ case CAMGETPASSTHRU_0x19:
+ cmd = CAMGETPASSTHRU;
+ error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
+ break;
+ case CAMIOQUEUE_0x19:
+ cmd = CAMIOQUEUE;
+ error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
+ break;
+ case CAMIOGET_0x19:
+ cmd = CAMIOGET;
+ error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
+ break;
default:
error = ENOTTY;
}
@@ -170,7 +188,7 @@ cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
}
- error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
+ error = cam_compat_handle_0x19(dev, cmd, (caddr_t)ccb, flag, td, cbfnp);
hdr17->pinfo = hdr->pinfo;
hdr17->xpt_links = hdr->xpt_links;
@@ -310,7 +328,7 @@ cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
}
- error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
+ error = cam_compat_handle_0x19(dev, cmd, (caddr_t)ccb, flag, td, cbfnp);
hdr18->pinfo = hdr->pinfo;
hdr18->xpt_links = hdr->xpt_links;
@@ -420,3 +438,31 @@ cam_compat_translate_dev_match_0x18(union ccb *ccb)
return (0);
}
+
+static int
+cam_compat_handle_0x19(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
+ struct thread *td, d_ioctl_t *cbfnp)
+{
+ union ccb *ccb = (union ccb *)addr;
+ struct cam_periph_map_info mapinfo;
+
+ if (cmd == CAMIOCOMMAND && ccb->ccb_h.func_code == XPT_DEV_MATCH) {
+ bzero(&mapinfo, sizeof(mapinfo));
+ cam_periph_mapmem(ccb, &mapinfo, maxphys);
+ for (int i = 0; i < ccb->cdm.num_patterns; i++) {
+ struct dev_match_pattern *p = &ccb->cdm.patterns[i];
+
+ if (p->type == DEV_MATCH_BUS &&
+ p->pattern.bus_pattern.flags == 0x00f)
+ p->pattern.bus_pattern.flags = BUS_MATCH_ANY;
+ if (p->type == DEV_MATCH_DEVICE &&
+ p->pattern.device_pattern.flags == 0x00f)
+ p->pattern.device_pattern.flags = DEV_MATCH_ANY;
+ if (p->type == DEV_MATCH_PERIPH &&
+ p->pattern.periph_pattern.flags == 0x01f)
+ p->pattern.periph_pattern.flags = PERIPH_MATCH_ANY;
+ }
+ cam_periph_unmapmem(ccb, &mapinfo);
+ }
+ return ((cbfnp)(dev, cmd, addr, flag, td));
+}