aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2023-06-27 03:33:25 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2023-06-27 03:36:06 +0000
commite932f0d2a3c3ccbdf6c72745a75488022662f80c (patch)
tree10240bf7059bffd572272f9240edf8656e5c31d6 /sys/cam
parent9c2203a691baaa52f2045d0ae69eb108509284e8 (diff)
downloadsrc-e932f0d2a3c3ccbdf6c72745a75488022662f80c.tar.gz
src-e932f0d2a3c3ccbdf6c72745a75488022662f80c.zip
cam_xpt: Properly fail if a sim uses an unsupported transport.
The default xport ops for a new bus is xport_default, not NULL, so check for that when determining if a bus failed to find a suitable transport. In addition, the path needs to be freed with xpt_free_path instead of a plain free so that the path's reference on the sim is dropped; otherwise, cam_sim_free in the caller after xpt_bus_register returns failure will hang forever. Note that we have to exempt the xpt bus from this check as it uses xport_default on purpose. Reviewed by: mav, imp Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D40617
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/cam_xpt.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 7bca42cb553e..9eb42a8f9141 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -4018,7 +4018,14 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, uint32_t bus)
xpt_path_inq(&cpi, path);
- if (cam_ccb_success((union ccb *)&cpi)) {
+ /*
+ * Use the results of PATH_INQ to pick a transport. Note that
+ * the xpt bus (which uses XPORT_UNSPECIFIED) always uses
+ * xport_default instead of a transport from
+ * cam_xpt_port_set.
+ */
+ if (cam_ccb_success((union ccb *)&cpi) &&
+ cpi.transport != XPORT_UNSPECIFIED) {
struct xpt_xport **xpt;
SET_FOREACH(xpt, cam_xpt_xport_set) {
@@ -4027,11 +4034,11 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, uint32_t bus)
break;
}
}
- if (new_bus->xport == NULL) {
+ if (new_bus->xport == &xport_default) {
xpt_print(path,
"No transport found for %d\n", cpi.transport);
xpt_release_bus(new_bus);
- free(path, M_CAMXPT);
+ xpt_free_path(path);
return (EINVAL);
}
}