aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2013-08-24 01:50:31 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2013-08-24 01:50:31 +0000
commit81a2151d5c8f2a1cf1cdf4078b4071e1779aea40 (patch)
tree52dcb94d89496617616c044e5b34ab0f832f6721 /sys/cam/ctl
parent83b6a67e66d3bcf5fc9f0f767409a7109356f1e0 (diff)
downloadsrc-81a2151d5c8f2a1cf1cdf4078b4071e1779aea40.tar.gz
src-81a2151d5c8f2a1cf1cdf4078b4071e1779aea40.zip
CTL changes required for iSCSI target, most notably LUN remapping
and a mechanism to allow CTL frontends for retrieving LUN options. Reviewed by: ken (earlier version)
Notes
Notes: svn path=/head/; revision=254759
Diffstat (limited to 'sys/cam/ctl')
-rw-r--r--sys/cam/ctl/ctl.c184
-rw-r--r--sys/cam/ctl/ctl.h1
-rw-r--r--sys/cam/ctl/ctl_backend.h7
-rw-r--r--sys/cam/ctl/ctl_backend_block.c11
-rw-r--r--sys/cam/ctl/ctl_backend_ramdisk.c14
-rw-r--r--sys/cam/ctl/ctl_frontend.h5
-rw-r--r--sys/cam/ctl/ctl_io.h2
7 files changed, 160 insertions, 64 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 6d6edf7812f6..215f1cd1074c 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -894,8 +894,13 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
struct ctl_lun *lun;
struct ctl_page_index *page_index;
struct copan_aps_subpage *current_sp;
+ uint32_t targ_lun;
- lun = ctl_softc->ctl_luns[msg_info.hdr.nexus.targ_lun];
+ targ_lun = msg_info.hdr.nexus.targ_lun;
+ if (msg_info.hdr.nexus.lun_map_fn != NULL)
+ targ_lun = msg_info.hdr.nexus.lun_map_fn(msg_info.hdr.nexus.lun_map_arg, targ_lun);
+
+ lun = ctl_softc->ctl_luns[targ_lun];
page_index = &lun->mode_pages.index[index_to_aps_page];
current_sp = (struct copan_aps_subpage *)
(page_index->page_data +
@@ -1098,7 +1103,8 @@ ctl_init(void)
mtx_unlock(&softc->ctl_lock);
return (error);
}
- printf("ctl: CAM Target Layer loaded\n");
+ if (bootverbose)
+ printf("ctl: CAM Target Layer loaded\n");
/*
* Initialize the initiator and portname mappings
@@ -1194,7 +1200,8 @@ ctl_shutdown(void)
free(control_softc, M_DEVBUF);
control_softc = NULL;
- printf("ctl: CAM Target Layer unloaded\n");
+ if (bootverbose)
+ printf("ctl: CAM Target Layer unloaded\n");
}
static int
@@ -1678,12 +1685,16 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio, int have_lock)
union ctl_ha_msg msg_info;
struct ctl_lun *lun;
int retval = 0;
+ uint32_t targ_lun;
ctl_softc = control_softc;
if (have_lock == 0)
mtx_lock(&ctl_softc->ctl_lock);
- lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
+ targ_lun = ctsio->io_hdr.nexus.targ_lun;
+ if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
+ lun = ctl_softc->ctl_luns[targ_lun];
if (lun==NULL)
{
/*
@@ -2980,6 +2991,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct sbuf *sb;
struct ctl_lun *lun;
struct ctl_lun_list *list;
+ struct ctl_be_lun_option *opt;
list = (struct ctl_lun_list *)addr;
@@ -3097,17 +3109,16 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
if (retval != 0)
break;
- if (lun->backend->lun_info == NULL) {
- retval = sbuf_printf(sb, "</lun>\n");
+ if (lun->backend->lun_info != NULL) {
+ retval = lun->backend->lun_info(lun->be_lun->be_lun, sb);
+ if (retval != 0)
+ break;
+ }
+ STAILQ_FOREACH(opt, &lun->be_lun->options, links) {
+ retval = sbuf_printf(sb, "<%s>%s</%s>", opt->name, opt->value, opt->name);
if (retval != 0)
break;
- continue;
}
-
- retval =lun->backend->lun_info(lun->be_lun->be_lun, sb);
-
- if (retval != 0)
- break;
retval = sbuf_printf(sb, "</lun>\n");
@@ -4432,9 +4443,14 @@ ctl_free_lun(struct ctl_lun *lun)
*/
for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue); io != NULL;
io = next_io) {
+ uint32_t targ_lun;
+
next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links);
+ targ_lun = io->io_hdr.nexus.targ_lun;
+ if (io->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((io->io_hdr.nexus.targ_target.id == lun->target.id)
- && (io->io_hdr.nexus.targ_lun == lun->lun))
+ && (targ_lun == lun->lun))
STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr,
ctl_io_hdr, links);
}
@@ -8247,12 +8263,16 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
struct ctl_lun *lun;
struct ctl_softc *softc;
int i;
+ uint32_t targ_lun;
softc = control_softc;
mtx_lock(&softc->ctl_lock);
- lun = softc->ctl_luns[msg->hdr.nexus.targ_lun];
+ targ_lun = msg->hdr.nexus.targ_lun;
+ if (msg->hdr.nexus.lun_map_fn != NULL)
+ targ_lun = msg->hdr.nexus.lun_map_fn(msg->hdr.nexus.lun_map_arg, targ_lun);
+ lun = softc->ctl_luns[targ_lun];
switch(msg->pr.pr_info.action) {
case CTL_PR_REG_KEY:
if (!lun->per_res[msg->pr.pr_info.residx].registered) {
@@ -8601,7 +8621,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
int num_luns, retval;
uint32_t alloc_len, lun_datalen;
int num_filled, well_known;
- uint32_t initidx;
+ uint32_t initidx, targ_lun_id, lun_id;
retval = CTL_RETVAL_COMPLETE;
well_known = 0;
@@ -8662,63 +8682,47 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
lun_data = (struct scsi_report_luns_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
- if (lun_datalen < alloc_len) {
- ctsio->residual = alloc_len - lun_datalen;
- ctsio->kern_data_len = lun_datalen;
- ctsio->kern_total_len = lun_datalen;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
- ctsio->kern_data_resid = 0;
- ctsio->kern_rel_offset = 0;
- ctsio->kern_sg_entries = 0;
-
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
- /*
- * We set this to the actual data length, regardless of how much
- * space we actually have to return results. If the user looks at
- * this value, he'll know whether or not he allocated enough space
- * and reissue the command if necessary. We don't support well
- * known logical units, so if the user asks for that, return none.
- */
- scsi_ulto4b(lun_datalen - 8, lun_data->length);
-
mtx_lock(&control_softc->ctl_lock);
- for (num_filled = 0, lun = STAILQ_FIRST(&control_softc->lun_list);
- (lun != NULL) && (num_filled < num_luns);
- lun = STAILQ_NEXT(lun, links)) {
+ for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
+ lun_id = targ_lun_id;
+ if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
+ lun_id = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, lun_id);
+ if (lun_id >= CTL_MAX_LUNS)
+ continue;
+ lun = control_softc->ctl_luns[lun_id];
+ if (lun == NULL)
+ continue;
- if (lun->lun <= 0xff) {
+ if (targ_lun_id <= 0xff) {
/*
* Peripheral addressing method, bus number 0.
*/
lun_data->luns[num_filled].lundata[0] =
RPL_LUNDATA_ATYP_PERIPH;
- lun_data->luns[num_filled].lundata[1] = lun->lun;
+ lun_data->luns[num_filled].lundata[1] = targ_lun_id;
num_filled++;
- } else if (lun->lun <= 0x3fff) {
+ } else if (targ_lun_id <= 0x3fff) {
/*
* Flat addressing method.
*/
lun_data->luns[num_filled].lundata[0] =
RPL_LUNDATA_ATYP_FLAT |
- (lun->lun & RPL_LUNDATA_FLAT_LUN_MASK);
+ (targ_lun_id & RPL_LUNDATA_FLAT_LUN_MASK);
#ifdef OLDCTLHEADERS
(SRLD_ADDR_FLAT << SRLD_ADDR_SHIFT) |
- (lun->lun & SRLD_BUS_LUN_MASK);
+ (targ_lun_id & SRLD_BUS_LUN_MASK);
#endif
lun_data->luns[num_filled].lundata[1] =
#ifdef OLDCTLHEADERS
- lun->lun >> SRLD_BUS_LUN_BITS;
+ targ_lun_id >> SRLD_BUS_LUN_BITS;
#endif
- lun->lun >> RPL_LUNDATA_FLAT_LUN_BITS;
+ targ_lun_id >> RPL_LUNDATA_FLAT_LUN_BITS;
num_filled++;
} else {
printf("ctl_report_luns: bogus LUN number %jd, "
- "skipping\n", (intmax_t)lun->lun);
+ "skipping\n", (intmax_t)targ_lun_id);
}
/*
* According to SPC-3, rev 14 section 6.21:
@@ -8743,6 +8747,35 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
mtx_unlock(&control_softc->ctl_lock);
/*
+ * It's quite possible that we've returned fewer LUNs than we allocated
+ * space for. Trim it.
+ */
+ lun_datalen = sizeof(*lun_data) +
+ (num_filled * sizeof(struct scsi_report_luns_lundata));
+
+ if (lun_datalen < alloc_len) {
+ ctsio->residual = alloc_len - lun_datalen;
+ ctsio->kern_data_len = lun_datalen;
+ ctsio->kern_total_len = lun_datalen;
+ } else {
+ ctsio->residual = 0;
+ ctsio->kern_data_len = alloc_len;
+ ctsio->kern_total_len = alloc_len;
+ }
+ ctsio->kern_data_resid = 0;
+ ctsio->kern_rel_offset = 0;
+ ctsio->kern_sg_entries = 0;
+
+ /*
+ * We set this to the actual data length, regardless of how much
+ * space we actually have to return results. If the user looks at
+ * this value, he'll know whether or not he allocated enough space
+ * and reissue the command if necessary. We don't support well
+ * known logical units, so if the user asks for that, return none.
+ */
+ scsi_ulto4b(lun_datalen - 8, lun_data->length);
+
+ /*
* We can only return SCSI_STATUS_CHECK_COND when we can't satisfy
* this request.
*/
@@ -9077,6 +9110,14 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
int devid_len;
ctl_softc = control_softc;
+
+ mtx_lock(&ctl_softc->ctl_lock);
+ fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
+ mtx_unlock(&ctl_softc->ctl_lock);
+
+ if (fe->devid != NULL)
+ return ((fe->devid)(ctsio, alloc_len));
+
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
devid_len = sizeof(struct scsi_vpd_device_id) +
@@ -9130,8 +9171,6 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
mtx_lock(&ctl_softc->ctl_lock);
- fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
-
/*
* For Fibre channel,
*/
@@ -10350,7 +10389,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
struct ctl_lun *lun;
struct ctl_cmd_entry *entry;
uint8_t opcode;
- uint32_t initidx;
+ uint32_t initidx, targ_lun;
int retval;
retval = 0;
@@ -10361,9 +10400,12 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
mtx_lock(&ctl_softc->ctl_lock);
- if ((ctsio->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun] != NULL)) {
- lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
+ targ_lun = ctsio->io_hdr.nexus.targ_lun;
+ if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
+ if ((targ_lun < CTL_MAX_LUNS)
+ && (ctl_softc->ctl_luns[targ_lun] != NULL)) {
+ lun = ctl_softc->ctl_luns[targ_lun];
/*
* If the LUN is invalid, pretend that it doesn't exist.
* It will go away as soon as all pending I/O has been
@@ -10403,6 +10445,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
ctl_set_unsupported_lun(ctsio);
mtx_unlock(&ctl_softc->ctl_lock);
ctl_done((union ctl_io *)ctsio);
+ CTL_DEBUG_PRINT(("ctl_scsiio_precheck: bailing out due to invalid LUN\n"));
goto bailout;
} else {
/*
@@ -10769,6 +10812,7 @@ ctl_abort_task(union ctl_io *io)
char printbuf[128];
#endif
int found;
+ uint32_t targ_lun;
ctl_softc = control_softc;
found = 0;
@@ -10776,9 +10820,12 @@ ctl_abort_task(union ctl_io *io)
/*
* Look up the LUN.
*/
- if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
- lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
+ targ_lun = io->io_hdr.nexus.targ_lun;
+ if (io->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
+ if ((targ_lun < CTL_MAX_LUNS)
+ && (ctl_softc->ctl_luns[targ_lun] != NULL))
+ lun = ctl_softc->ctl_luns[targ_lun];
else
goto bailout;
@@ -10968,6 +11015,8 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
int retval;
targ_lun = io->io_hdr.nexus.targ_lun;
+ if (io->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
@@ -11042,7 +11091,7 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
(uintmax_t)io->io_hdr.nexus.initid.id,
io->io_hdr.nexus.targ_port,
(uintmax_t)io->io_hdr.nexus.targ_target.id,
- io->io_hdr.nexus.targ_lun,
+ io->io_hdr.nexus.targ_lun /* XXX */,
(io->io_hdr.io_type == CTL_IO_TASK) ?
io->taskio.tag_num : io->scsiio.tag_num);
STAILQ_REMOVE(&ctl_softc->task_queue, &io->io_hdr,
@@ -11066,10 +11115,14 @@ ctl_handle_isc(union ctl_io *io)
int free_io;
struct ctl_lun *lun;
struct ctl_softc *ctl_softc;
+ uint32_t targ_lun;
ctl_softc = control_softc;
- lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
+ targ_lun = io->io_hdr.nexus.targ_lun;
+ if (io->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
+ lun = ctl_softc->ctl_luns[targ_lun];
switch (io->io_hdr.msg_type) {
case CTL_MSG_SERIALIZE:
@@ -12625,7 +12678,7 @@ ctl_queue_sense(union ctl_io *io)
{
struct ctl_lun *lun;
struct ctl_softc *ctl_softc;
- uint32_t initidx;
+ uint32_t initidx, targ_lun;
ctl_softc = control_softc;
@@ -12644,9 +12697,12 @@ ctl_queue_sense(union ctl_io *io)
* If we don't have a LUN for this, just toss the sense
* information.
*/
- if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
- lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
+ targ_lun = io->io_hdr.nexus.targ_lun;
+ if (io->io_hdr.nexus.lun_map_fn != NULL)
+ targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
+ if ((targ_lun < CTL_MAX_LUNS)
+ && (ctl_softc->ctl_luns[targ_lun] != NULL))
+ lun = ctl_softc->ctl_luns[targ_lun];
else
goto bailout;
@@ -13047,6 +13103,8 @@ ctl_isc_start(struct ctl_ha_component *c, ctl_ha_state state)
{
ctl_ha_comp_status ret = CTL_HA_COMP_STATUS_OK;
+ printf("%s: go\n", __func__);
+
// UNKNOWN->HA or UNKNOWN->SINGLE (bootstrap)
if (c->state == CTL_HA_STATE_UNKNOWN ) {
ctl_is_single = 0;
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index da382e6dbf3b..07c82bac1bf5 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -52,6 +52,7 @@ typedef enum {
CTL_PORT_SCSI = 0x02,
CTL_PORT_IOCTL = 0x04,
CTL_PORT_INTERNAL = 0x08,
+ CTL_PORT_ISCSI = 0x10,
CTL_PORT_ALL = 0xff,
CTL_PORT_ISC = 0x100 // FC port for inter-shelf communication
} ctl_port_type;
diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h
index c3798e423f4e..56fb8a59482b 100644
--- a/sys/cam/ctl/ctl_backend.h
+++ b/sys/cam/ctl/ctl_backend.h
@@ -173,6 +173,12 @@ typedef void (*be_lun_config_t)(void *be_lun,
* The links field is for CTL internal use only, and should not be used by
* the backend.
*/
+struct ctl_be_lun_option {
+ STAILQ_ENTRY(ctl_be_lun_option) links;
+ char *name;
+ char *value;
+};
+
struct ctl_be_lun {
uint8_t lun_type; /* passed to CTL */
ctl_backend_lun_flags flags; /* passed to CTL */
@@ -187,6 +193,7 @@ struct ctl_be_lun {
be_lun_config_t lun_config_status; /* passed to CTL */
struct ctl_backend_driver *be; /* passed to CTL */
void *ctl_lun; /* used by CTL */
+ STAILQ_HEAD(, ctl_be_lun_option) options; /* passed to CTL */
STAILQ_ENTRY(ctl_be_lun) links; /* used by CTL */
};
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 9a13fb53e367..d2d42876399b 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -1639,6 +1639,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
STAILQ_INIT(&be_lun->input_queue);
STAILQ_INIT(&be_lun->config_write_queue);
STAILQ_INIT(&be_lun->datamove_queue);
+ STAILQ_INIT(&be_lun->ctl_be_lun.options);
sprintf(be_lun->lunname, "cblk%d", softc->num_luns);
mtx_init(&be_lun->lock, be_lun->lunname, NULL, MTX_DEF);
@@ -1740,6 +1741,16 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
}
num_threads = tmp_num_threads;
+ } else if (strcmp(req->kern_be_args[i].kname, "file") != 0 &&
+ strcmp(req->kern_be_args[i].kname, "dev") != 0) {
+ struct ctl_be_lun_option *opt;
+
+ opt = malloc(sizeof(*opt), M_CTLBLK, M_WAITOK);
+ opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_CTLBLK, M_WAITOK);
+ strcpy(opt->name, req->kern_be_args[i].kname);
+ opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_CTLBLK, M_WAITOK);
+ strcpy(opt->value, req->kern_be_args[i].kvalue);
+ STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links);
}
}
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
index 63cc4e053396..191e8e4ab6e5 100644
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -491,7 +491,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
struct ctl_lun_create_params *params;
uint32_t blocksize;
char tmpstr[32];
- int retval;
+ int i, retval;
retval = 0;
params = &req->reqdata.create;
@@ -509,6 +509,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
sizeof(*be_lun));
goto bailout_error;
}
+ STAILQ_INIT(&be_lun->ctl_be_lun.options);
if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
be_lun->ctl_be_lun.lun_type = params->device_type;
@@ -545,6 +546,17 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
be_lun->softc = softc;
+ for (i = 0; i < req->num_be_args; i++) {
+ struct ctl_be_lun_option *opt;
+
+ opt = malloc(sizeof(*opt), M_RAMDISK, M_WAITOK);
+ opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_RAMDISK, M_WAITOK);
+ strcpy(opt->name, req->kern_be_args[i].kname);
+ opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_RAMDISK, M_WAITOK);
+ strcpy(opt->value, req->kern_be_args[i].kvalue);
+ STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links);
+ }
+
be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
be_lun->ctl_be_lun.be_lun = be_lun;
diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h
index b286476c06bf..23f91b4a810e 100644
--- a/sys/cam/ctl/ctl_frontend.h
+++ b/sys/cam/ctl/ctl_frontend.h
@@ -49,6 +49,9 @@ typedef enum {
typedef void (*port_func_t)(void *onoff_arg);
typedef int (*targ_func_t)(void *arg, struct ctl_id targ_id);
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
+typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
+ struct thread *td);
+typedef int (*fe_devid_t)(struct ctl_scsiio *ctsio, int alloc_len);
/*
* The ctl_frontend structure is the registration mechanism between a FETD
@@ -213,6 +216,8 @@ struct ctl_frontend {
targ_func_t targ_disable; /* passed to CTL */
lun_func_t lun_enable; /* passed to CTL */
lun_func_t lun_disable; /* passed to CTL */
+ fe_ioctl_t ioctl; /* passed to CTL */
+ fe_devid_t devid; /* passed to CTL */
void *targ_lun_arg; /* passed to CTL */
void (*fe_datamove)(union ctl_io *io); /* passed to CTL */
void (*fe_done)(union ctl_io *io); /* passed to CTL */
diff --git a/sys/cam/ctl/ctl_io.h b/sys/cam/ctl/ctl_io.h
index aa00a0634907..8981b358e3c5 100644
--- a/sys/cam/ctl/ctl_io.h
+++ b/sys/cam/ctl/ctl_io.h
@@ -204,6 +204,8 @@ struct ctl_nexus {
uint32_t targ_port; /* Target port, filled in by PORT */
struct ctl_id targ_target; /* Destination target */
uint32_t targ_lun; /* Destination lun */
+ uint32_t (*lun_map_fn)(void *arg, uint32_t lun);
+ void *lun_map_arg;
};
typedef enum {