svn commit: r254759 - head/sys/cam/ctl

Edward Tomasz Napierala trasz at FreeBSD.org
Sat Aug 24 01:50:33 UTC 2013


Author: trasz
Date: Sat Aug 24 01:50:31 2013
New Revision: 254759
URL: http://svnweb.freebsd.org/changeset/base/254759

Log:
  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)

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl.h
  head/sys/cam/ctl/ctl_backend.h
  head/sys/cam/ctl/ctl_backend_block.c
  head/sys/cam/ctl/ctl_backend_ramdisk.c
  head/sys/cam/ctl/ctl_frontend.h
  head/sys/cam/ctl/ctl_io.h

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl.c	Sat Aug 24 01:50:31 2013	(r254759)
@@ -894,8 +894,13 @@ ctl_isc_event_handler(ctl_ha_channel cha
 			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_sc
 	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, 
 		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, 
 			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 c
 	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
 	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
 
 	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 *ct
 	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 *ct
 
 	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 *ct
 		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
 				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
 			       (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_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;

Modified: head/sys/cam/ctl/ctl.h
==============================================================================
--- head/sys/cam/ctl/ctl.h	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl.h	Sat Aug 24 01:50:31 2013	(r254759)
@@ -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;

Modified: head/sys/cam/ctl/ctl_backend.h
==============================================================================
--- head/sys/cam/ctl/ctl_backend.h	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl_backend.h	Sat Aug 24 01:50:31 2013	(r254759)
@@ -173,6 +173,12 @@ typedef void (*be_lun_config_t)(void *be
  * 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 */
 };
 

Modified: head/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_block.c	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl_backend_block.c	Sat Aug 24 01:50:31 2013	(r254759)
@@ -1639,6 +1639,7 @@ ctl_be_block_create(struct ctl_be_block_
 	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_
 			}
 
 			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);
 		}
 	}
 

Modified: head/sys/cam/ctl/ctl_backend_ramdisk.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_ramdisk.c	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl_backend_ramdisk.c	Sat Aug 24 01:50:31 2013	(r254759)
@@ -491,7 +491,7 @@ ctl_backend_ramdisk_create(struct ctl_be
 	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
 			 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
 
 	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;

Modified: head/sys/cam/ctl/ctl_frontend.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend.h	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl_frontend.h	Sat Aug 24 01:50:31 2013	(r254759)
@@ -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 */

Modified: head/sys/cam/ctl/ctl_io.h
==============================================================================
--- head/sys/cam/ctl/ctl_io.h	Sat Aug 24 00:54:47 2013	(r254758)
+++ head/sys/cam/ctl/ctl_io.h	Sat Aug 24 01:50:31 2013	(r254759)
@@ -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 {


More information about the svn-src-all mailing list