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
This commit is contained in:
parent
34dc8f1bb4
commit
ded2b70617
@ -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,
|
||||
};
|
||||
#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);
|
||||
|
||||
struct xpt_xport *
|
||||
ata_get_xport(void)
|
||||
{
|
||||
return (&ata_xport);
|
||||
}
|
||||
ATA_XPT_XPORT(ata, ATA);
|
||||
ATA_XPT_XPORT(sata, SATA);
|
||||
|
||||
#undef ATA_XPORT_XPORT
|
||||
|
||||
static void
|
||||
probe_periph_init()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
};
|
||||
#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);
|
||||
|
||||
struct xpt_xport *
|
||||
scsi_get_xport(void)
|
||||
{
|
||||
return (&scsi_xport);
|
||||
}
|
||||
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()
|
||||
|
Loading…
Reference in New Issue
Block a user