From ded2b70617bc77cc5542033563c92b05414e4621 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 28 Jul 2016 22:55:14 +0000 Subject: [PATCH] Switch to linker sets to find the xport callback object. This eliminates the need to special case everything in cam_xpt for new transports. It is now a failure to not have a transport object when registering the bus as well. You can still, however, create a transport that's unspecified (XPT_) Differential Revision: https://reviews.freebsd.org/D7289 --- sys/cam/ata/ata_xpt.c | 20 +++++++++----- sys/cam/cam_xpt.c | 55 +++++++++++++++++++------------------- sys/cam/cam_xpt_internal.h | 16 +++++++---- sys/cam/nvme/nvme_xpt.c | 16 ++++++----- sys/cam/scsi/scsi_xpt.c | 25 ++++++++++++----- 5 files changed, 80 insertions(+), 52 deletions(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 3dab055ced6..a51b5fa3241 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -195,18 +195,24 @@ static int atapi_dma = 1; TUNABLE_INT("hw.ata.ata_dma", &ata_dma); TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); -static struct xpt_xport ata_xport = { +static struct xpt_xport_ops ata_xport_ops = { .alloc_device = ata_alloc_device, .action = ata_action, .async = ata_dev_async, .announce = ata_announce_periph, }; - -struct xpt_xport * -ata_get_xport(void) -{ - return (&ata_xport); -} +#define ATA_XPT_XPORT(x, X) \ +static struct xpt_xport ata_xport_ ## x = { \ + .xport = XPORT_ ## X, \ + .name = #x, \ + .ops = &ata_xport_ops, \ +}; \ +CAM_XPT_XPORT(ata_xport_ ## x); + +ATA_XPT_XPORT(ata, ATA); +ATA_XPT_XPORT(sata, SATA); + +#undef ATA_XPORT_XPORT static void probe_periph_init() diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 9943f4a1a18..52e7f92e9a6 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -1043,7 +1043,7 @@ xpt_announce_periph(struct cam_periph *periph, char *announce_string) periph->unit_number, path->device->serial_num); } /* Announce transport details. */ - (*(path->bus->xport->announce))(periph); + (*(path->bus->xport->ops->announce))(periph); /* Announce command queueing. */ if (path->device->inq_flags & SID_CmdQue || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) { @@ -2464,7 +2464,7 @@ xpt_action(union ccb *start_ccb) xpt_action_name(start_ccb->ccb_h.func_code))); start_ccb->ccb_h.status = CAM_REQ_INPROG; - (*(start_ccb->ccb_h.path->bus->xport->action))(start_ccb); + (*(start_ccb->ccb_h.path->bus->xport->ops->action))(start_ccb); } void @@ -3482,9 +3482,9 @@ xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph, struct cam_ed *new_device; new_device = - (*(bus->xport->alloc_device))(bus, - target, - lun_id); + (*(bus->xport->ops->alloc_device))(bus, + target, + lun_id); if (new_device == NULL) { status = CAM_RESRC_UNAVAIL; } else { @@ -3832,11 +3832,18 @@ xpt_release_ccb(union ccb *free_ccb) /* Functions accessed by SIM drivers */ -static struct xpt_xport xport_default = { +static struct xpt_xport_ops xport_default_ops = { .alloc_device = xpt_alloc_device_default, .action = xpt_action_default, .async = xpt_dev_async_default, }; +static struct xpt_xport xport_default = { + .xport = XPORT_UNKNOWN, + .name = "unknown", + .ops = &xport_default_ops, +}; + +CAM_XPT_XPORT(xport_default); /* * A sim structure, listing the SIM entry points and instance @@ -3909,26 +3916,20 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus) xpt_action((union ccb *)&cpi); if (cpi.ccb_h.status == CAM_REQ_CMP) { - switch (cpi.transport) { - case XPORT_SPI: - case XPORT_SAS: - case XPORT_FC: - case XPORT_USB: - case XPORT_ISCSI: - case XPORT_SRP: - case XPORT_PPB: - new_bus->xport = scsi_get_xport(); - break; - case XPORT_ATA: - case XPORT_SATA: - new_bus->xport = ata_get_xport(); - break; - case XPORT_NVME: - new_bus->xport = nvme_get_xport(); - break; - default: - new_bus->xport = &xport_default; - break; + struct xpt_xport **xpt; + + SET_FOREACH(xpt, cam_xpt_xport_set) { + if ((*xpt)->xport == cpi.transport) { + new_bus->xport = *xpt; + break; + } + } + if (new_bus->xport == NULL) { + xpt_print_path(path); + printf("No transport found for %d\n", cpi.transport); + xpt_release_bus(new_bus); + free(path, M_CAMXPT); + return (CAM_RESRC_UNAVAIL); } } @@ -4138,7 +4139,7 @@ xpt_async_process_dev(struct cam_ed *device, void *arg) } else relock = 0; - (*(device->target->bus->xport->async))(async_code, + (*(device->target->bus->xport->ops->async))(async_code, device->target->bus, device->target, device, async_arg); xpt_async_bcast(&device->asyncs, async_code, path, async_arg); diff --git a/sys/cam/cam_xpt_internal.h b/sys/cam/cam_xpt_internal.h index b0624af88db..59a0d92f936 100644 --- a/sys/cam/cam_xpt_internal.h +++ b/sys/cam/cam_xpt_internal.h @@ -48,7 +48,7 @@ typedef void (*xpt_dev_async_func)(u_int32_t async_code, void *async_arg); typedef void (*xpt_announce_periph_func)(struct cam_periph *periph); -struct xpt_xport { +struct xpt_xport_ops { xpt_alloc_device_func alloc_device; xpt_release_device_func reldev; xpt_action_func action; @@ -56,6 +56,16 @@ struct xpt_xport { xpt_announce_periph_func announce; }; +struct xpt_xport { + cam_xport xport; + const char *name; + struct xpt_xport_ops *ops; +}; + +SET_DECLARE(cam_xpt_xport_set, struct xpt_xport); +#define CAM_XPT_XPORT(data) \ + DATA_SET(cam_xpt_xport_set, data) + /* * The CAM EDT (Existing Device Table) contains the device information for * all devices for all busses in the system. The table contains a @@ -167,10 +177,6 @@ struct cam_path { struct cam_ed *device; }; -struct xpt_xport * scsi_get_xport(void); -struct xpt_xport * ata_get_xport(void); -struct xpt_xport * nvme_get_xport(void); - struct cam_ed * xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id); diff --git a/sys/cam/nvme/nvme_xpt.c b/sys/cam/nvme/nvme_xpt.c index 57d04a528c0..03cbc6f07d2 100644 --- a/sys/cam/nvme/nvme_xpt.c +++ b/sys/cam/nvme/nvme_xpt.c @@ -153,19 +153,23 @@ static void nvme_dev_async(u_int32_t async_code, static void nvme_action(union ccb *start_ccb); static void nvme_announce_periph(struct cam_periph *periph); -static struct xpt_xport nvme_xport = { +static struct xpt_xport_ops nvme_xport_ops = { .alloc_device = nvme_alloc_device, .action = nvme_action, .async = nvme_dev_async, .announce = nvme_announce_periph, }; +#define NVME_XPT_XPORT(x, X) \ +static struct xpt_xport nvme_xport_ ## x = { \ + .xport = XPORT_ ## X, \ + .name = #x, \ + .ops = &nvme_xport_ops, \ +}; \ +CAM_XPT_XPORT(nvme_xport_ ## x); -struct xpt_xport * -nvme_get_xport(void) -{ +NVME_XPT_XPORT(nvme, NVME); - return (&nvme_xport); -} +#undef NVME_XPT_XPORT static void nvme_probe_periph_init() diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index a8684c185aa..94aabc42249 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -590,18 +590,29 @@ static void scsi_dev_async(u_int32_t async_code, static void scsi_action(union ccb *start_ccb); static void scsi_announce_periph(struct cam_periph *periph); -static struct xpt_xport scsi_xport = { +static struct xpt_xport_ops scsi_xport_ops = { .alloc_device = scsi_alloc_device, .action = scsi_action, .async = scsi_dev_async, .announce = scsi_announce_periph, }; - -struct xpt_xport * -scsi_get_xport(void) -{ - return (&scsi_xport); -} +#define SCSI_XPT_XPORT(x, X) \ +static struct xpt_xport scsi_xport_ ## x = { \ + .xport = XPORT_ ## X, \ + .name = #x, \ + .ops = &scsi_xport_ops, \ +}; \ +CAM_XPT_XPORT(scsi_xport_ ## x); + +SCSI_XPT_XPORT(spi, SPI); +SCSI_XPT_XPORT(sas, SAS); +SCSI_XPT_XPORT(fc, FC); +SCSI_XPT_XPORT(usb, USB); +SCSI_XPT_XPORT(iscsi, ISCSI); +SCSI_XPT_XPORT(srp, SRP); +SCSI_XPT_XPORT(ppb, PPB); + +#undef SCSI_XPORT_XPORT static void probe_periph_init() -- 2.45.2