Date: Sat, 24 Aug 2013 01:50:31 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254759 - head/sys/cam/ctl Message-ID: <201308240150.r7O1oVKk036604@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308240150.r7O1oVKk036604>