summaryrefslogtreecommitdiffstats
path: root/sys/cam/ctl/ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/ctl/ctl.c')
-rw-r--r--sys/cam/ctl/ctl.c1598
1 files changed, 678 insertions, 920 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 1a24641..1b3a57f 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2003-2009 Silicon Graphics International Corp.
* Copyright (c) 2012 The FreeBSD Foundation
- * Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
+ * Copyright (c) 2014-2017 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Portions of this software were developed by Edward Tomasz Napierala
@@ -409,6 +409,9 @@ static int ctl_debug = CTL_DEBUG_NONE;
TUNABLE_INT("kern.cam.ctl.debug", &ctl_debug);
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN,
&ctl_debug, 0, "Enabled debug flags");
+static int ctl_lun_map_size = 1024;
+SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN,
+ &ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)");
/*
* Supported pages (0x00), Serial number (0x80), Device ID (0x83),
@@ -423,10 +426,10 @@ static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest);
static void ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest);
static int ctl_init(void);
-void ctl_shutdown(void);
+static int ctl_shutdown(void);
static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td);
static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td);
-static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio);
+static void ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio);
static void ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num,
struct ctl_ooa *ooa_hdr,
struct ctl_ooa_entry *kern_entries);
@@ -436,7 +439,6 @@ static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
struct ctl_be_lun *be_lun);
static int ctl_free_lun(struct ctl_lun *lun);
static void ctl_create_lun(struct ctl_be_lun *be_lun);
-static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr);
static int ctl_do_mode_select(union ctl_io *io);
static int ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun,
@@ -447,7 +449,7 @@ static int ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun,
struct scsi_per_res_out_parms* param);
static void ctl_pro_preempt_other(struct ctl_lun *lun,
union ctl_ha_msg *msg);
-static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg);
+static void ctl_hndl_per_res_out_on_other_sc(union ctl_io *io);
static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len);
static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len);
static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len);
@@ -520,6 +522,8 @@ static const struct ctl_cmd_entry *
ctl_validate_command(struct ctl_scsiio *ctsio);
static int ctl_cmd_applicable(uint8_t lun_type,
const struct ctl_cmd_entry *entry);
+static int ctl_ha_init(void);
+static int ctl_ha_shutdown(void);
static uint64_t ctl_get_prkey(struct ctl_lun *lun, uint32_t residx);
static void ctl_clr_prkey(struct ctl_lun *lun, uint32_t residx);
@@ -561,18 +565,60 @@ MODULE_VERSION(ctl, 1);
static struct ctl_frontend ha_frontend =
{
.name = "ha",
+ .init = ctl_ha_init,
+ .shutdown = ctl_ha_shutdown,
+};
+
+static int
+ctl_ha_init(void)
+{
+ struct ctl_softc *softc = control_softc;
+
+ if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC,
+ &softc->othersc_pool) != 0)
+ return (ENOMEM);
+ if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) {
+ ctl_pool_free(softc->othersc_pool);
+ return (EIO);
+ }
+ if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
+ != CTL_HA_STATUS_SUCCESS) {
+ ctl_ha_msg_destroy(softc);
+ ctl_pool_free(softc->othersc_pool);
+ return (EIO);
+ }
+ return (0);
+};
+
+static int
+ctl_ha_shutdown(void)
+{
+ struct ctl_softc *softc = control_softc;
+ struct ctl_port *port;
+
+ ctl_ha_msg_shutdown(softc);
+ if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL) != CTL_HA_STATUS_SUCCESS)
+ return (EIO);
+ if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
+ return (EIO);
+ ctl_pool_free(softc->othersc_pool);
+ while ((port = STAILQ_FIRST(&ha_frontend.port_list)) != NULL) {
+ ctl_port_deregister(port);
+ free(port->port_name, M_CTL);
+ free(port, M_CTL);
+ }
+ return (0);
};
static void
ctl_ha_datamove(union ctl_io *io)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(io);
struct ctl_sg_entry *sgl;
union ctl_ha_msg msg;
uint32_t sg_entries_sent;
int do_sg_copy, i, j;
- lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
memset(&msg.dt, 0, sizeof(msg.dt));
msg.hdr.msg_type = CTL_MSG_DATAMOVE;
msg.hdr.original_sc = io->io_hdr.original_sc;
@@ -697,8 +743,6 @@ ctl_ha_done(union ctl_io *io)
msg.scsi.tag_num = io->scsiio.tag_num;
msg.scsi.tag_type = io->scsiio.tag_type;
msg.scsi.sense_len = io->scsiio.sense_len;
- msg.scsi.sense_residual = io->scsiio.sense_residual;
- msg.scsi.residual = io->scsiio.residual;
memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data,
io->scsiio.sense_len);
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
@@ -726,8 +770,6 @@ ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc,
ctsio->io_hdr.status = msg_info->hdr.status;
ctsio->scsi_status = msg_info->scsi.scsi_status;
ctsio->sense_len = msg_info->scsi.sense_len;
- ctsio->sense_residual = msg_info->scsi.sense_residual;
- ctsio->residual = msg_info->scsi.residual;
memcpy(&ctsio->sense_data, &msg_info->scsi.sense_data,
msg_info->scsi.sense_len);
ctl_enqueue_isc((union ctl_io *)ctsio);
@@ -828,7 +870,7 @@ ctl_isc_announce_port(struct ctl_port *port)
return;
i = sizeof(msg->port) + strlen(port->port_name) + 1;
if (port->lun_map)
- i += sizeof(uint32_t) * CTL_MAX_LUNS;
+ i += port->lun_map_size * sizeof(uint32_t);
if (port->port_devid)
i += port->port_devid->len;
if (port->target_devid)
@@ -848,7 +890,7 @@ ctl_isc_announce_port(struct ctl_port *port)
"%d:%s", softc->ha_id, port->port_name) + 1;
i += msg->port.name_len;
if (port->lun_map) {
- msg->port.lun_map_len = sizeof(uint32_t) * CTL_MAX_LUNS;
+ msg->port.lun_map_len = port->lun_map_size * sizeof(uint32_t);
memcpy(&msg->port.data[i], port->lun_map,
msg->port.lun_map_len);
i += msg->port.lun_map_len;
@@ -1026,27 +1068,27 @@ ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
uint32_t iid = ctl_get_initindex(&msg->hdr.nexus);
mtx_lock(&softc->ctl_lock);
- if (msg->hdr.nexus.targ_lun < CTL_MAX_LUNS &&
- (lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) != NULL) {
- mtx_lock(&lun->lun_lock);
- mtx_unlock(&softc->ctl_lock);
- if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES &&
- msg->ua.ua_set)
- memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8);
- if (msg->ua.ua_all) {
- if (msg->ua.ua_set)
- ctl_est_ua_all(lun, iid, msg->ua.ua_type);
- else
- ctl_clr_ua_all(lun, iid, msg->ua.ua_type);
- } else {
- if (msg->ua.ua_set)
- ctl_est_ua(lun, iid, msg->ua.ua_type);
- else
- ctl_clr_ua(lun, iid, msg->ua.ua_type);
- }
- mtx_unlock(&lun->lun_lock);
- } else
+ if (msg->hdr.nexus.targ_mapped_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
+ return;
+ }
+ mtx_lock(&lun->lun_lock);
+ mtx_unlock(&softc->ctl_lock);
+ if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set)
+ memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8);
+ if (msg->ua.ua_all) {
+ if (msg->ua.ua_set)
+ ctl_est_ua_all(lun, iid, msg->ua.ua_type);
+ else
+ ctl_clr_ua_all(lun, iid, msg->ua.ua_type);
+ } else {
+ if (msg->ua.ua_set)
+ ctl_est_ua(lun, iid, msg->ua.ua_type);
+ else
+ ctl_clr_ua(lun, iid, msg->ua.ua_type);
+ }
+ mtx_unlock(&lun->lun_lock);
}
static void
@@ -1060,8 +1102,8 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
- ((lun = softc->ctl_luns[targ_lun]) == NULL)) {
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
}
@@ -1076,7 +1118,7 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
memcmp(&msg->lun.data[0], lun->lun_devid->data, i) != 0)) {
mtx_unlock(&lun->lun_lock);
printf("%s: Received conflicting HA LUN %d\n",
- __func__, msg->hdr.nexus.targ_lun);
+ __func__, targ_lun);
return;
} else {
/* Record whether peer is primary. */
@@ -1110,7 +1152,7 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
mtx_unlock(&lun->lun_lock);
CTL_DEBUG_PRINT(("%s: Known LUN %d, peer is %s\n",
- __func__, msg->hdr.nexus.targ_lun,
+ __func__, targ_lun,
(msg->lun.flags & CTL_LUN_PRIMARY_SC) ?
"primary" : "secondary"));
@@ -1157,19 +1199,25 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
M_CTL);
i += msg->port.name_len;
if (msg->port.lun_map_len != 0) {
- if (port->lun_map == NULL)
- port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+ if (port->lun_map == NULL ||
+ port->lun_map_size * sizeof(uint32_t) <
+ msg->port.lun_map_len) {
+ port->lun_map_size = 0;
+ free(port->lun_map, M_CTL);
+ port->lun_map = malloc(msg->port.lun_map_len,
M_CTL, M_WAITOK);
- memcpy(port->lun_map, &msg->port.data[i],
- sizeof(uint32_t) * CTL_MAX_LUNS);
+ }
+ memcpy(port->lun_map, &msg->port.data[i], msg->port.lun_map_len);
+ port->lun_map_size = msg->port.lun_map_len / sizeof(uint32_t);
i += msg->port.lun_map_len;
} else {
+ port->lun_map_size = 0;
free(port->lun_map, M_CTL);
port->lun_map = NULL;
}
if (msg->port.port_devid_len != 0) {
if (port->port_devid == NULL ||
- port->port_devid->len != msg->port.port_devid_len) {
+ port->port_devid->len < msg->port.port_devid_len) {
free(port->port_devid, M_CTL);
port->port_devid = malloc(sizeof(struct ctl_devid) +
msg->port.port_devid_len, M_CTL, M_WAITOK);
@@ -1184,7 +1232,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
}
if (msg->port.target_devid_len != 0) {
if (port->target_devid == NULL ||
- port->target_devid->len != msg->port.target_devid_len) {
+ port->target_devid->len < msg->port.target_devid_len) {
free(port->target_devid, M_CTL);
port->target_devid = malloc(sizeof(struct ctl_devid) +
msg->port.target_devid_len, M_CTL, M_WAITOK);
@@ -1199,7 +1247,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
}
if (msg->port.init_devid_len != 0) {
if (port->init_devid == NULL ||
- port->init_devid->len != msg->port.init_devid_len) {
+ port->init_devid->len < msg->port.init_devid_len) {
free(port->init_devid, M_CTL);
port->init_devid = malloc(sizeof(struct ctl_devid) +
msg->port.init_devid_len, M_CTL, M_WAITOK);
@@ -1220,7 +1268,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
}
mtx_lock(&softc->ctl_lock);
STAILQ_FOREACH(lun, &softc->lun_list, links) {
- if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
mtx_lock(&lun->lun_lock);
ctl_est_ua_all(lun, -1, CTL_UA_INQ_CHANGE);
@@ -1291,8 +1339,8 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
- ((lun = softc->ctl_luns[targ_lun]) == NULL)) {
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
}
@@ -1490,13 +1538,12 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
io->io_hdr.msg_type = CTL_MSG_DATAMOVE_DONE;
io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE;
- io->io_hdr.port_status = msg->scsi.fetd_status;
- io->scsiio.residual = msg->scsi.residual;
+ io->io_hdr.port_status = msg->scsi.port_status;
+ io->scsiio.kern_data_resid = msg->scsi.kern_data_resid;
if (msg->hdr.status != CTL_STATUS_NONE) {
io->io_hdr.status = msg->hdr.status;
io->scsiio.scsi_status = msg->scsi.scsi_status;
io->scsiio.sense_len = msg->scsi.sense_len;
- io->scsiio.sense_residual =msg->scsi.sense_residual;
memcpy(&io->scsiio.sense_data,
&msg->scsi.sense_data,
msg->scsi.sense_len);
@@ -1782,7 +1829,6 @@ ctl_init(void)
{
struct make_dev_args args;
struct ctl_softc *softc;
- void *other_pool;
int i, error;
softc = control_softc = malloc(sizeof(*control_softc), M_DEVBUF,
@@ -1796,7 +1842,8 @@ ctl_init(void)
args.mda_si_drv1 = softc;
error = make_dev_s(&args, &softc->dev, "cam/ctl");
if (error != 0) {
- free(control_softc, M_DEVBUF);
+ free(softc, M_DEVBUF);
+ control_softc = NULL;
return (error);
}
@@ -1808,7 +1855,7 @@ ctl_init(void)
if (softc->sysctl_tree == NULL) {
printf("%s: unable to allocate sysctl tree\n", __func__);
destroy_dev(softc->dev);
- free(control_softc, M_DEVBUF);
+ free(softc, M_DEVBUF);
control_softc = NULL;
return (ENOMEM);
}
@@ -1856,15 +1903,6 @@ ctl_init(void)
STAILQ_INIT(&softc->be_list);
ctl_tpc_init(softc);
- if (ctl_pool_create(softc, "othersc", CTL_POOL_ENTRIES_OTHER_SC,
- &other_pool) != 0)
- {
- printf("ctl: can't allocate %d entry other SC pool, "
- "exiting\n", CTL_POOL_ENTRIES_OTHER_SC);
- return (ENOMEM);
- }
- softc->othersc_pool = other_pool;
-
if (worker_threads <= 0)
worker_threads = max(1, mp_ncpus / 4);
if (worker_threads > CTL_MAX_THREADS)
@@ -1884,22 +1922,19 @@ ctl_init(void)
&softc->ctl_proc, &thr->thread, 0, 0, "ctl", "work%d", i);
if (error != 0) {
printf("error creating CTL work thread!\n");
- ctl_pool_free(other_pool);
return (error);
}
}
error = kproc_kthread_add(ctl_lun_thread, softc,
- &softc->ctl_proc, NULL, 0, 0, "ctl", "lun");
+ &softc->ctl_proc, &softc->lun_thread, 0, 0, "ctl", "lun");
if (error != 0) {
printf("error creating CTL lun thread!\n");
- ctl_pool_free(other_pool);
return (error);
}
error = kproc_kthread_add(ctl_thresh_thread, softc,
- &softc->ctl_proc, NULL, 0, 0, "ctl", "thresh");
+ &softc->ctl_proc, &softc->thresh_thread, 0, 0, "ctl", "thresh");
if (error != 0) {
printf("error creating CTL threshold thread!\n");
- ctl_pool_free(other_pool);
return (error);
}
@@ -1908,58 +1943,54 @@ ctl_init(void)
softc, 0, ctl_ha_role_sysctl, "I", "HA role for this head");
if (softc->is_single == 0) {
- ctl_frontend_register(&ha_frontend);
- if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) {
- printf("ctl_init: ctl_ha_msg_init failed.\n");
- softc->is_single = 1;
- } else
- if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
- != CTL_HA_STATUS_SUCCESS) {
- printf("ctl_init: ctl_ha_msg_register failed.\n");
+ if (ctl_frontend_register(&ha_frontend) != 0)
softc->is_single = 1;
- }
}
return (0);
}
-void
+static int
ctl_shutdown(void)
{
struct ctl_softc *softc = control_softc;
- struct ctl_lun *lun, *next_lun;
+ int i;
- if (softc->is_single == 0) {
- ctl_ha_msg_shutdown(softc);
- if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL)
- != CTL_HA_STATUS_SUCCESS)
- printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
- if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
- printf("%s: ctl_ha_msg_destroy failed.\n", __func__);
+ if (softc->is_single == 0)
ctl_frontend_deregister(&ha_frontend);
- }
- mtx_lock(&softc->ctl_lock);
-
- STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun)
- ctl_free_lun(lun);
-
- mtx_unlock(&softc->ctl_lock);
+ destroy_dev(softc->dev);
-#if 0
- ctl_shutdown_thread(softc->work_thread);
- mtx_destroy(&softc->queue_lock);
-#endif
+ /* Shutdown CTL threads. */
+ softc->shutdown = 1;
+ for (i = 0; i < worker_threads; i++) {
+ struct ctl_thread *thr = &softc->threads[i];
+ while (thr->thread != NULL) {
+ wakeup(thr);
+ if (thr->thread != NULL)
+ pause("CTL thr shutdown", 1);
+ }
+ mtx_destroy(&thr->queue_lock);
+ }
+ while (softc->lun_thread != NULL) {
+ wakeup(&softc->pending_lun_queue);
+ if (softc->lun_thread != NULL)
+ pause("CTL thr shutdown", 1);
+ }
+ while (softc->thresh_thread != NULL) {
+ wakeup(softc->thresh_thread);
+ if (softc->thresh_thread != NULL)
+ pause("CTL thr shutdown", 1);
+ }
ctl_tpc_shutdown(softc);
uma_zdestroy(softc->io_zone);
mtx_destroy(&softc->ctl_lock);
- destroy_dev(softc->dev);
-
sysctl_ctx_free(&softc->sysctl_ctx);
- free(control_softc, M_DEVBUF);
+ free(softc, M_DEVBUF);
control_softc = NULL;
+ return (0);
}
static int
@@ -1970,7 +2001,7 @@ ctl_module_event_handler(module_t mod, int what, void *arg)
case MOD_LOAD:
return (ctl_init());
case MOD_UNLOAD:
- return (EBUSY);
+ return (ctl_shutdown());
default:
return (EOPNOTSUPP);
}
@@ -2197,22 +2228,19 @@ ctl_create_iid(struct ctl_port *port, int iid, uint8_t *buf)
* command on this side (XFER mode) or tell the other side to execute it
* (SER_ONLY mode).
*/
-static int
+static void
ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_port *port = CTL_PORT(ctsio);
union ctl_ha_msg msg_info;
- struct ctl_port *port;
struct ctl_lun *lun;
const struct ctl_cmd_entry *entry;
- int retval = 0;
uint32_t targ_lun;
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun;
- mtx_lock(&softc->ctl_lock);
/* Make sure that we know about this port. */
- port = ctl_io_port(&ctsio->io_hdr);
if (port == NULL || (port->status & CTL_PORT_STATUS_ONLINE) == 0) {
ctl_set_internal_failure(ctsio, /*sks_valid*/ 0,
/*retry_count*/ 1);
@@ -2220,24 +2248,11 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
}
/* Make sure that we know about this LUN. */
- if ((targ_lun < CTL_MAX_LUNS) &&
- ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
- mtx_lock(&lun->lun_lock);
- mtx_unlock(&softc->ctl_lock);
- /*
- * If the LUN is invalid, pretend that it doesn't exist.
- * It will go away as soon as all pending I/O has been
- * completed.
- */
- if (lun->flags & CTL_LUN_DISABLED) {
- mtx_unlock(&lun->lun_lock);
- lun = NULL;
- }
- } else {
+ mtx_lock(&softc->ctl_lock);
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
- lun = NULL;
- }
- if (lun == NULL) {
+
/*
* The other node would not send this request to us unless
* received announce that we are primary node for this LUN.
@@ -2247,6 +2262,18 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
ctl_set_busy(ctsio);
goto badjuju;
}
+ mtx_lock(&lun->lun_lock);
+ mtx_unlock(&softc->ctl_lock);
+
+ /*
+ * If the LUN is invalid, pretend that it doesn't exist.
+ * It will go away as soon as all pending I/Os completed.
+ */
+ if (lun->flags & CTL_LUN_DISABLED) {
+ mtx_unlock(&lun->lun_lock);
+ ctl_set_busy(ctsio);
+ goto badjuju;
+ }
entry = ctl_get_cmd_entry(ctsio, NULL);
if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) {
@@ -2254,8 +2281,8 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
goto badjuju;
}
- ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun;
- ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = lun->be_lun;
+ CTL_LUN(ctsio) = lun;
+ CTL_BACKEND_LUN(ctsio) = lun->be_lun;
/*
* Every I/O goes into the OOA queue for a
@@ -2318,10 +2345,9 @@ badjuju:
msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
sizeof(msg_info.scsi), M_WAITOK);
- retval = 1;
+ ctl_free_io((union ctl_io *)ctsio);
break;
}
- return (retval);
}
/*
@@ -2555,6 +2581,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td)
{
struct ctl_softc *softc = dev->si_drv1;
+ struct ctl_port *port;
struct ctl_lun *lun;
int retval;
@@ -2676,9 +2703,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
mtx_lock(&softc->ctl_lock);
- if (((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0)
- && ((ooa_hdr->lun_num >= CTL_MAX_LUNS)
- || (softc->ctl_luns[ooa_hdr->lun_num] == NULL))) {
+ if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 &&
+ (ooa_hdr->lun_num >= CTL_MAX_LUNS ||
+ softc->ctl_luns[ooa_hdr->lun_num] == NULL)) {
mtx_unlock(&softc->ctl_lock);
free(entries, M_CTL);
printf("%s: CTL_GET_OOA: invalid LUN %ju\n",
@@ -2730,89 +2757,75 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
#ifdef CTL_IO_DELAY
mtx_lock(&softc->ctl_lock);
-
- if ((delay_info->lun_id >= CTL_MAX_LUNS)
- || (softc->ctl_luns[delay_info->lun_id] == NULL)) {
+ if (delay_info->lun_id >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[delay_info->lun_id]) == NULL) {
+ mtx_unlock(&softc->ctl_lock);
delay_info->status = CTL_DELAY_STATUS_INVALID_LUN;
- } else {
- lun = softc->ctl_luns[delay_info->lun_id];
- mtx_lock(&lun->lun_lock);
-
- delay_info->status = CTL_DELAY_STATUS_OK;
-
- switch (delay_info->delay_type) {
- case CTL_DELAY_TYPE_CONT:
- break;
- case CTL_DELAY_TYPE_ONESHOT:
- break;
- default:
- delay_info->status =
- CTL_DELAY_STATUS_INVALID_TYPE;
- break;
- }
-
- switch (delay_info->delay_loc) {
- case CTL_DELAY_LOC_DATAMOVE:
- lun->delay_info.datamove_type =
- delay_info->delay_type;
- lun->delay_info.datamove_delay =
- delay_info->delay_secs;
- break;
- case CTL_DELAY_LOC_DONE:
- lun->delay_info.done_type =
- delay_info->delay_type;
- lun->delay_info.done_delay =
- delay_info->delay_secs;
- break;
- default:
- delay_info->status =
- CTL_DELAY_STATUS_INVALID_LOC;
- break;
- }
- mtx_unlock(&lun->lun_lock);
+ break;
}
-
+ mtx_lock(&lun->lun_lock);
mtx_unlock(&softc->ctl_lock);
+ delay_info->status = CTL_DELAY_STATUS_OK;
+ switch (delay_info->delay_type) {
+ case CTL_DELAY_TYPE_CONT:
+ case CTL_DELAY_TYPE_ONESHOT:
+ break;
+ default:
+ delay_info->status = CTL_DELAY_STATUS_INVALID_TYPE;
+ break;
+ }
+ switch (delay_info->delay_loc) {
+ case CTL_DELAY_LOC_DATAMOVE:
+ lun->delay_info.datamove_type = delay_info->delay_type;
+ lun->delay_info.datamove_delay = delay_info->delay_secs;
+ break;
+ case CTL_DELAY_LOC_DONE:
+ lun->delay_info.done_type = delay_info->delay_type;
+ lun->delay_info.done_delay = delay_info->delay_secs;
+ break;
+ default:
+ delay_info->status = CTL_DELAY_STATUS_INVALID_LOC;
+ break;
+ }
+ mtx_unlock(&lun->lun_lock);
#else
delay_info->status = CTL_DELAY_STATUS_NOT_IMPLEMENTED;
#endif /* CTL_IO_DELAY */
break;
}
+#ifdef CTL_LEGACY_STATS
case CTL_GETSTATS: {
- struct ctl_stats *stats;
+ struct ctl_stats *stats = (struct ctl_stats *)addr;
int i;
- stats = (struct ctl_stats *)addr;
-
- if ((sizeof(struct ctl_lun_io_stats) * softc->num_luns) >
- stats->alloc_len) {
- stats->status = CTL_SS_NEED_MORE_SPACE;
- stats->num_luns = softc->num_luns;
- break;
- }
/*
* XXX KDM no locking here. If the LUN list changes,
* things can blow up.
*/
i = 0;
+ stats->status = CTL_SS_OK;
+ stats->fill_len = 0;
STAILQ_FOREACH(lun, &softc->lun_list, links) {
- retval = copyout(&lun->stats, &stats->lun_stats[i++],
- sizeof(lun->stats));
+ if (stats->fill_len + sizeof(lun->legacy_stats) >
+ stats->alloc_len) {
+ stats->status = CTL_SS_NEED_MORE_SPACE;
+ break;
+ }
+ retval = copyout(&lun->legacy_stats, &stats->lun_stats[i++],
+ sizeof(lun->legacy_stats));
if (retval != 0)
break;
+ stats->fill_len += sizeof(lun->legacy_stats);
}
stats->num_luns = softc->num_luns;
- stats->fill_len = sizeof(struct ctl_lun_io_stats) *
- softc->num_luns;
- stats->status = CTL_SS_OK;
-#ifdef CTL_TIME_IO
- stats->flags = CTL_STATS_FLAG_TIME_VALID;
-#else
stats->flags = CTL_STATS_FLAG_NONE;
+#ifdef CTL_TIME_IO
+ stats->flags |= CTL_STATS_FLAG_TIME_VALID;
#endif
getnanouptime(&stats->timestamp);
break;
}
+#endif /* CTL_LEGACY_STATS */
case CTL_ERROR_INJECT: {
struct ctl_error_desc *err_desc, *new_err_desc;
@@ -2823,8 +2836,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
bcopy(err_desc, new_err_desc, sizeof(*new_err_desc));
mtx_lock(&softc->ctl_lock);
- lun = softc->ctl_luns[err_desc->lun_id];
- if (lun == NULL) {
+ if (err_desc->lun_id >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[err_desc->lun_id]) == NULL) {
mtx_unlock(&softc->ctl_lock);
free(new_err_desc, M_CTL);
printf("%s: CTL_ERROR_INJECT: invalid LUN %ju\n",
@@ -2867,8 +2880,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
delete_done = 0;
mtx_lock(&softc->ctl_lock);
- lun = softc->ctl_luns[delete_desc->lun_id];
- if (lun == NULL) {
+ if (delete_desc->lun_id >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[delete_desc->lun_id]) == NULL) {
mtx_unlock(&softc->ctl_lock);
printf("%s: CTL_ERROR_INJECT_DELETE: invalid LUN %ju\n",
__func__, (uintmax_t)delete_desc->lun_id);
@@ -2897,18 +2910,18 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
break;
}
case CTL_DUMP_STRUCTS: {
- int i, j, k;
+ int j, k;
struct ctl_port *port;
struct ctl_frontend *fe;
mtx_lock(&softc->ctl_lock);
printf("CTL Persistent Reservation information start:\n");
- for (i = 0; i < CTL_MAX_LUNS; i++) {
- lun = softc->ctl_luns[i];
-
- if ((lun == NULL)
- || ((lun->flags & CTL_LUN_DISABLED) != 0))
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ mtx_lock(&lun->lun_lock);
+ if ((lun->flags & CTL_LUN_DISABLED) != 0) {
+ mtx_unlock(&lun->lun_lock);
continue;
+ }
for (j = 0; j < CTL_MAX_PORTS; j++) {
if (lun->pr_keys[j] == NULL)
@@ -2916,11 +2929,12 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){
if (lun->pr_keys[j][k] == 0)
continue;
- printf(" LUN %d port %d iid %d key "
- "%#jx\n", i, j, k,
+ printf(" LUN %ju port %d iid %d key "
+ "%#jx\n", lun->lun, j, k,
(uintmax_t)lun->pr_keys[j][k]);
}
}
+ mtx_unlock(&lun->lun_lock);
}
printf("CTL Persistent Reservation information end\n");
printf("CTL Ports:\n");
@@ -3301,9 +3315,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
if (port->lun_map != NULL) {
sbuf_printf(sb, "\t<lun_map>on</lun_map>\n");
- for (j = 0; j < CTL_MAX_LUNS; j++) {
+ for (j = 0; j < port->lun_map_size; j++) {
plun = ctl_lun_map_from_port(port, j);
- if (plun >= CTL_MAX_LUNS)
+ if (plun == UINT32_MAX)
continue;
sbuf_printf(sb,
"\t<lun id=\"%u\">%u</lun>\n",
@@ -3371,8 +3385,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
if (port->status & CTL_PORT_STATUS_ONLINE) {
STAILQ_FOREACH(lun, &softc->lun_list, links) {
- if (ctl_lun_map_to_port(port, lun->lun) >=
- CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) ==
+ UINT32_MAX)
continue;
mtx_lock(&lun->lun_lock);
ctl_est_ua_port(lun, lm->port, -1,
@@ -3381,7 +3395,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
}
mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps
- if (lm->plun < CTL_MAX_LUNS) {
+ if (lm->plun != UINT32_MAX) {
if (lm->lun == UINT32_MAX)
retval = ctl_lun_map_unset(port, lm->plun);
else if (lm->lun < CTL_MAX_LUNS &&
@@ -3389,17 +3403,82 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
retval = ctl_lun_map_set(port, lm->plun, lm->lun);
else
return (ENXIO);
- } else if (lm->plun == UINT32_MAX) {
+ } else {
if (lm->lun == UINT32_MAX)
retval = ctl_lun_map_deinit(port);
else
retval = ctl_lun_map_init(port);
- } else
- return (ENXIO);
+ }
if (port->status & CTL_PORT_STATUS_ONLINE)
ctl_isc_announce_port(port);
break;
}
+ case CTL_GET_LUN_STATS: {
+ struct ctl_get_io_stats *stats = (struct ctl_get_io_stats *)addr;
+ int i;
+
+ /*
+ * XXX KDM no locking here. If the LUN list changes,
+ * things can blow up.
+ */
+ i = 0;
+ stats->status = CTL_SS_OK;
+ stats->fill_len = 0;
+ STAILQ_FOREACH(lun, &softc->lun_list, links) {
+ if (lun->lun < stats->first_item)
+ continue;
+ if (stats->fill_len + sizeof(lun->stats) >
+ stats->alloc_len) {
+ stats->status = CTL_SS_NEED_MORE_SPACE;
+ break;
+ }
+ retval = copyout(&lun->stats, &stats->stats[i++],
+ sizeof(lun->stats));
+ if (retval != 0)
+ break;
+ stats->fill_len += sizeof(lun->stats);
+ }
+ stats->num_items = softc->num_luns;
+ stats->flags = CTL_STATS_FLAG_NONE;
+#ifdef CTL_TIME_IO
+ stats->flags |= CTL_STATS_FLAG_TIME_VALID;
+#endif
+ getnanouptime(&stats->timestamp);
+ break;
+ }
+ case CTL_GET_PORT_STATS: {
+ struct ctl_get_io_stats *stats = (struct ctl_get_io_stats *)addr;
+ int i;
+
+ /*
+ * XXX KDM no locking here. If the LUN list changes,
+ * things can blow up.
+ */
+ i = 0;
+ stats->status = CTL_SS_OK;
+ stats->fill_len = 0;
+ STAILQ_FOREACH(port, &softc->port_list, links) {
+ if (port->targ_port < stats->first_item)
+ continue;
+ if (stats->fill_len + sizeof(port->stats) >
+ stats->alloc_len) {
+ stats->status = CTL_SS_NEED_MORE_SPACE;
+ break;
+ }
+ retval = copyout(&port->stats, &stats->stats[i++],
+ sizeof(port->stats));
+ if (retval != 0)
+ break;
+ stats->fill_len += sizeof(port->stats);
+ }
+ stats->num_items = softc->num_ports;
+ stats->flags = CTL_STATS_FLAG_NONE;
+#ifdef CTL_TIME_IO
+ stats->flags |= CTL_STATS_FLAG_TIME_VALID;
+#endif
+ getnanouptime(&stats->timestamp);
+ break;
+ }
default: {
/* XXX KDM should we fix this? */
#if 0
@@ -3448,15 +3527,20 @@ ctl_lun_map_init(struct ctl_port *port)
{
struct ctl_softc *softc = port->ctl_softc;
struct ctl_lun *lun;
+ int size = ctl_lun_map_size;
uint32_t i;
- if (port->lun_map == NULL)
- port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+ if (port->lun_map == NULL || port->lun_map_size < size) {
+ port->lun_map_size = 0;
+ free(port->lun_map, M_CTL);
+ port->lun_map = malloc(size * sizeof(uint32_t),
M_CTL, M_NOWAIT);
+ }
if (port->lun_map == NULL)
return (ENOMEM);
- for (i = 0; i < CTL_MAX_LUNS; i++)
+ for (i = 0; i < size; i++)
port->lun_map[i] = UINT32_MAX;
+ port->lun_map_size = size;
if (port->status & CTL_PORT_STATUS_ONLINE) {
if (port->lun_disable != NULL) {
STAILQ_FOREACH(lun, &softc->lun_list, links)
@@ -3475,6 +3559,7 @@ ctl_lun_map_deinit(struct ctl_port *port)
if (port->lun_map == NULL)
return (0);
+ port->lun_map_size = 0;
free(port->lun_map, M_CTL);
port->lun_map = NULL;
if (port->status & CTL_PORT_STATUS_ONLINE) {
@@ -3498,9 +3583,11 @@ ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun)
if (status != 0)
return (status);
}
+ if (plun >= port->lun_map_size)
+ return (EINVAL);
old = port->lun_map[plun];
port->lun_map[plun] = glun;
- if ((port->status & CTL_PORT_STATUS_ONLINE) && old >= CTL_MAX_LUNS) {
+ if ((port->status & CTL_PORT_STATUS_ONLINE) && old == UINT32_MAX) {
if (port->lun_enable != NULL)
port->lun_enable(port->targ_lun_arg, plun);
ctl_isc_announce_port(port);
@@ -3513,11 +3600,11 @@ ctl_lun_map_unset(struct ctl_port *port, uint32_t plun)
{
uint32_t old;
- if (port->lun_map == NULL)
+ if (port->lun_map == NULL || plun >= port->lun_map_size)
return (0);
old = port->lun_map[plun];
port->lun_map[plun] = UINT32_MAX;
- if ((port->status & CTL_PORT_STATUS_ONLINE) && old < CTL_MAX_LUNS) {
+ if ((port->status & CTL_PORT_STATUS_ONLINE) && old != UINT32_MAX) {
if (port->lun_disable != NULL)
port->lun_disable(port->targ_lun_arg, plun);
ctl_isc_announce_port(port);
@@ -3531,8 +3618,10 @@ ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id)
if (port == NULL)
return (UINT32_MAX);
- if (port->lun_map == NULL || lun_id >= CTL_MAX_LUNS)
+ if (port->lun_map == NULL)
return (lun_id);
+ if (lun_id > port->lun_map_size)
+ return (UINT32_MAX);
return (port->lun_map[lun_id]);
}
@@ -3545,7 +3634,7 @@ ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id)
return (UINT32_MAX);
if (port->lun_map == NULL)
return (lun_id);
- for (i = 0; i < CTL_MAX_LUNS; i++) {
+ for (i = 0; i < port->lun_map_size; i++) {
if (port->lun_map[i] == lun_id)
return (i);
}
@@ -3613,13 +3702,6 @@ ctl_encode_lun(uint32_t decoded)
return ((((uint64_t)RPL_LUNDATA_ATYP_EXTLUN | 0x22) << 56) | (l << 16));
}
-static struct ctl_port *
-ctl_io_port(struct ctl_io_hdr *io_hdr)
-{
-
- return (control_softc->ctl_ports[io_hdr->nexus.targ_port]);
-}
-
int
ctl_ffz(uint32_t *mask, uint32_t first, uint32_t last)
{
@@ -3737,7 +3819,6 @@ int
ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name,
uint32_t total_ctl_io, void **npool)
{
-#ifdef IO_POOLS
struct ctl_io_pool *pool;
pool = (struct ctl_io_pool *)malloc(sizeof(*pool), M_CTL,
@@ -3747,14 +3828,15 @@ ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name,
snprintf(pool->name, sizeof(pool->name), "CTL IO %s", pool_name);
pool->ctl_softc = ctl_softc;
+#ifdef IO_POOLS
pool->zone = uma_zsecond_create(pool->name, NULL,
NULL, NULL, NULL, ctl_softc->io_zone);
/* uma_prealloc(pool->zone, total_ctl_io); */
-
- *npool = pool;
#else
- *npool = ctl_softc->io_zone;
+ pool->zone = ctl_softc->io_zone;
#endif
+
+ *npool = pool;
return (0);
}
@@ -3767,64 +3849,54 @@ ctl_pool_free(struct ctl_io_pool *pool)
#ifdef IO_POOLS
uma_zdestroy(pool->zone);
- free(pool, M_CTL);
#endif
+ free(pool, M_CTL);
}
union ctl_io *
ctl_alloc_io(void *pool_ref)
{
- union ctl_io *io;
-#ifdef IO_POOLS
struct ctl_io_pool *pool = (struct ctl_io_pool *)pool_ref;
+ union ctl_io *io;
io = uma_zalloc(pool->zone, M_WAITOK);
-#else
- io = uma_zalloc((uma_zone_t)pool_ref, M_WAITOK);
-#endif
- if (io != NULL)
+ if (io != NULL) {
io->io_hdr.pool = pool_ref;
+ CTL_SOFTC(io) = pool->ctl_softc;
+ }
return (io);
}
union ctl_io *
ctl_alloc_io_nowait(void *pool_ref)
{
- union ctl_io *io;
-#ifdef IO_POOLS
struct ctl_io_pool *pool = (struct ctl_io_pool *)pool_ref;
+ union ctl_io *io;
io = uma_zalloc(pool->zone, M_NOWAIT);
-#else
- io = uma_zalloc((uma_zone_t)pool_ref, M_NOWAIT);
-#endif
- if (io != NULL)
+ if (io != NULL) {
io->io_hdr.pool = pool_ref;
+ CTL_SOFTC(io) = pool->ctl_softc;
+ }
return (io);
}
void
ctl_free_io(union ctl_io *io)
{
-#ifdef IO_POOLS
struct ctl_io_pool *pool;
-#endif
if (io == NULL)
return;
-#ifdef IO_POOLS
pool = (struct ctl_io_pool *)io->io_hdr.pool;
uma_zfree(pool->zone, io);
-#else
- uma_zfree((uma_zone_t)io->io_hdr.pool, io);
-#endif
}
void
ctl_zero_io(union ctl_io *io)
{
- void *pool_ref;
+ struct ctl_io_pool *pool;
if (io == NULL)
return;
@@ -3832,9 +3904,10 @@ ctl_zero_io(union ctl_io *io)
/*
* May need to preserve linked list pointers at some point too.
*/
- pool_ref = io->io_hdr.pool;
+ pool = io->io_hdr.pool;
memset(io, 0, sizeof(*io));
- io->io_hdr.pool = pool_ref;
+ io->io_hdr.pool = pool;
+ CTL_SOFTC(io) = pool->ctl_softc;
}
int
@@ -4400,7 +4473,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
struct scsi_vpd_id_descriptor *desc;
struct scsi_vpd_id_t10 *t10id;
const char *eui, *naa, *scsiname, *uuid, *vendor, *value;
- int lun_number, i, lun_malloced;
+ int lun_number, lun_malloced;
int devidlen, idlen1, idlen2 = 0, len;
if (be_lun == NULL)
@@ -4534,6 +4607,8 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
printf("ctl: requested LUN ID %d is already "
"in use\n", be_lun->req_lun_id);
}
+fail:
+ free(lun->lun_devid, M_CTL);
if (lun->flags & CTL_LUN_MALLOCED)
free(lun, M_CTL);
be_lun->lun_config_status(be_lun->be_lun,
@@ -4546,14 +4621,11 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
if (lun_number == -1) {
mtx_unlock(&ctl_softc->ctl_lock);
printf("ctl: can't allocate LUN, out of LUNs\n");
- if (lun->flags & CTL_LUN_MALLOCED)
- free(lun, M_CTL);
- be_lun->lun_config_status(be_lun->be_lun,
- CTL_LUN_CONFIG_FAILURE);
- return (ENOSPC);
+ goto fail;
}
}
ctl_set_mask(ctl_softc->ctl_lun_mask, lun_number);
+ mtx_unlock(&ctl_softc->ctl_lock);
mtx_init(&lun->lun_lock, "CTL LUN", NULL, MTX_DEF);
lun->lun = lun_number;
@@ -4594,6 +4666,10 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
lun->ie_reported = 1;
callout_init_mtx(&lun->ie_callout, &lun->lun_lock, 0);
ctl_tpc_lun_init(lun);
+ if (lun->flags & CTL_LUN_REMOVABLE) {
+ lun->prevent = malloc((CTL_MAX_INITIATORS + 31) / 32 * 4,
+ M_CTL, M_WAITOK);
+ }
/*
* Initialize the mode and log page index.
@@ -4601,31 +4677,31 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
ctl_init_page_index(lun);
ctl_init_log_page_index(lun);
+ /* Setup statistics gathering */
+#ifdef CTL_LEGACY_STATS
+ lun->legacy_stats.device_type = be_lun->lun_type;
+ lun->legacy_stats.lun_number = lun_number;
+ lun->legacy_stats.blocksize = be_lun->blocksize;
+ if (be_lun->blocksize == 0)
+ lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE;
+ for (len = 0; len < CTL_MAX_PORTS; len++)
+ lun->legacy_stats.ports[len].targ_port = len;
+#endif /* CTL_LEGACY_STATS */
+ lun->stats.item = lun_number;
+
/*
* Now, before we insert this lun on the lun list, set the lun
* inventory changed UA for all other luns.
*/
+ mtx_lock(&ctl_softc->ctl_lock);
STAILQ_FOREACH(nlun, &ctl_softc->lun_list, links) {
mtx_lock(&nlun->lun_lock);
ctl_est_ua_all(nlun, -1, CTL_UA_LUN_CHANGE);
mtx_unlock(&nlun->lun_lock);
}
-
STAILQ_INSERT_TAIL(&ctl_softc->lun_list, lun, links);
-
ctl_softc->ctl_luns[lun_number] = lun;
-
ctl_softc->num_luns++;
-
- /* Setup statistics gathering */
- lun->stats.device_type = be_lun->lun_type;
- lun->stats.lun_number = lun_number;
- lun->stats.blocksize = be_lun->blocksize;
- if (be_lun->blocksize == 0)
- lun->stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE;
- for (i = 0;i < CTL_MAX_PORTS;i++)
- lun->stats.ports[i].targ_port = i;
-
mtx_unlock(&ctl_softc->ctl_lock);
lun->be_lun->lun_config_status(lun->be_lun->be_lun, CTL_LUN_CONFIG_OK);
@@ -4641,12 +4717,10 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
static int
ctl_free_lun(struct ctl_lun *lun)
{
- struct ctl_softc *softc;
+ struct ctl_softc *softc = lun->ctl_softc;
struct ctl_lun *nlun;
int i;
- softc = lun->ctl_softc;
-
mtx_assert(&softc->ctl_lock, MA_OWNED);
STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links);
@@ -4677,6 +4751,7 @@ ctl_free_lun(struct ctl_lun *lun)
for (i = 0; i < CTL_MAX_PORTS; i++)
free(lun->pr_keys[i], M_CTL);
free(lun->write_buffer, M_CTL);
+ free(lun->prevent, M_CTL);
if (lun->flags & CTL_LUN_MALLOCED)
free(lun, M_CTL);
@@ -4992,18 +5067,13 @@ ctl_config_move_done(union ctl_io *io)
if ((io->io_hdr.port_status != 0) &&
((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE ||
(io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) {
- /*
- * For hardware error sense keys, the sense key
- * specific value is defined to be a retry count,
- * but we use it to pass back an internal FETD
- * error code. XXX KDM Hopefully the FETD is only
- * using 16 bits for an error code, since that's
- * all the space we have in the sks field.
- */
- ctl_set_internal_failure(&io->scsiio,
- /*sks_valid*/ 1,
- /*retry_count*/
- io->io_hdr.port_status);
+ ctl_set_internal_failure(&io->scsiio, /*sks_valid*/ 1,
+ /*retry_count*/ io->io_hdr.port_status);
+ } else if (io->scsiio.kern_data_resid != 0 &&
+ (io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT &&
+ ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE ||
+ (io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)) {
+ ctl_set_invalid_field_ciu(&io->scsiio);
}
if (ctl_debug & CTL_DEBUG_CDB_DATA)
@@ -5147,13 +5217,12 @@ ctl_config_read_done(union ctl_io *io)
int
ctl_scsi_release(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
uint32_t residx;
CTL_DEBUG_PRINT(("ctl_scsi_release\n"));
residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
/*
* XXX KDM right now, we only support LUN reservation. We don't
@@ -5185,13 +5254,12 @@ ctl_scsi_release(struct ctl_scsiio *ctsio)
int
ctl_scsi_reserve(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
uint32_t residx;
CTL_DEBUG_PRINT(("ctl_reserve\n"));
residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
/*
* XXX KDM right now, we only support LUN reservation. We don't
@@ -5226,13 +5294,12 @@ bailout:
int
ctl_start_stop(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_start_stop_unit *cdb;
- struct ctl_lun *lun;
int retval;
CTL_DEBUG_PRINT(("ctl_start_stop\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_start_stop_unit *)ctsio->cdb;
if ((cdb->how & SSS_PC_MASK) == 0) {
@@ -5281,17 +5348,16 @@ ctl_start_stop(struct ctl_scsiio *ctsio)
int
ctl_prevent_allow(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_prevent *cdb;
int retval;
uint32_t initidx;
CTL_DEBUG_PRINT(("ctl_prevent_allow\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_prevent *)ctsio->cdb;
- if ((lun->flags & CTL_LUN_REMOVABLE) == 0) {
+ if ((lun->flags & CTL_LUN_REMOVABLE) == 0 || lun->prevent == NULL) {
ctl_set_invalid_opcode(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
@@ -5322,8 +5388,7 @@ ctl_prevent_allow(struct ctl_scsiio *ctsio)
int
ctl_sync_cache(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
- struct ctl_softc *softc;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
uint64_t starting_lba;
uint32_t block_count;
@@ -5332,8 +5397,6 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_sync_cache\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- softc = lun->ctl_softc;
retval = 0;
switch (ctsio->cdb[0]) {
@@ -5389,13 +5452,10 @@ int
ctl_format(struct ctl_scsiio *ctsio)
{
struct scsi_format *cdb;
- struct ctl_lun *lun;
int length, defect_list_len;
CTL_DEBUG_PRINT(("ctl_format\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
cdb = (struct scsi_format *)ctsio->cdb;
length = 0;
@@ -5411,7 +5471,6 @@ ctl_format(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(length, M_CTL, M_WAITOK);
ctsio->kern_data_len = length;
ctsio->kern_total_len = length;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -5474,7 +5533,7 @@ bailout:
int
ctl_read_buffer(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
uint64_t buffer_offset;
uint32_t len;
uint8_t byte2;
@@ -5482,7 +5541,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
static uint8_t echo_descr[4] = { 0 };
CTL_DEBUG_PRINT(("ctl_read_buffer\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+
switch (ctsio->cdb[0]) {
case READ_BUFFER: {
struct scsi_read_buffer *cdb;
@@ -5537,7 +5596,6 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
}
ctsio->kern_data_len = len;
ctsio->kern_total_len = len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctl_set_success(ctsio);
@@ -5549,13 +5607,12 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
int
ctl_write_buffer(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_write_buffer *cdb;
- struct ctl_lun *lun;
int buffer_offset, len;
CTL_DEBUG_PRINT(("ctl_write_buffer\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_write_buffer *)ctsio->cdb;
len = scsi_3btoul(cdb->length);
@@ -5584,7 +5641,6 @@ ctl_write_buffer(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = lun->write_buffer + buffer_offset;
ctsio->kern_data_len = len;
ctsio->kern_total_len = len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -5602,7 +5658,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsio)
int
ctl_write_same(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
uint64_t lba;
uint32_t num_blocks;
@@ -5611,8 +5667,6 @@ ctl_write_same(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_write_same\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
switch (ctsio->cdb[0]) {
case WRITE_SAME_10: {
struct scsi_write_same_10 *cdb;
@@ -5694,7 +5748,6 @@ ctl_write_same(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK);
ctsio->kern_data_len = len;
ctsio->kern_total_len = len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -5716,7 +5769,7 @@ ctl_write_same(struct ctl_scsiio *ctsio)
int
ctl_unmap(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_unmap *cdb;
struct ctl_ptr_len_flags *ptrlen;
struct scsi_unmap_header *hdr;
@@ -5728,9 +5781,7 @@ ctl_unmap(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_unmap\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_unmap *)ctsio->cdb;
-
len = scsi_2btoul(cdb->length);
byte2 = cdb->byte2;
@@ -5742,7 +5793,6 @@ ctl_unmap(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(len, M_CTL, M_WAITOK);
ctsio->kern_data_len = len;
ctsio->kern_total_len = len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -5820,24 +5870,20 @@ int
ctl_default_page_handler(struct ctl_scsiio *ctsio,
struct ctl_page_index *page_index, uint8_t *page_ptr)
{
- struct ctl_lun *lun;
- uint8_t *current_cp, *saved_cp;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
+ uint8_t *current_cp;
int set_ua;
uint32_t initidx;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
set_ua = 0;
current_cp = (page_index->page_data + (page_index->page_len *
CTL_PAGE_CURRENT));
- saved_cp = (page_index->page_data + (page_index->page_len *
- CTL_PAGE_SAVED));
mtx_lock(&lun->lun_lock);
if (memcmp(current_cp, page_ptr, page_index->page_len)) {
memcpy(current_cp, page_ptr, page_index->page_len);
- memcpy(saved_cp, page_ptr, page_index->page_len);
set_ua = 1;
}
if (set_ua != 0)
@@ -5878,13 +5924,12 @@ int
ctl_ie_page_handler(struct ctl_scsiio *ctsio,
struct ctl_page_index *page_index, uint8_t *page_ptr)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_info_exceptions_page *pg;
- struct ctl_lun *lun;
uint64_t t;
(void)ctl_default_page_handler(ctsio, page_index, page_ptr);
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
pg = (struct scsi_info_exceptions_page *)page_ptr;
mtx_lock(&lun->lun_lock);
if (pg->info_flags & SIEP_FLAGS_TEST) {
@@ -5921,19 +5966,18 @@ ctl_ie_page_handler(struct ctl_scsiio *ctsio,
static int
ctl_do_mode_select(union ctl_io *io)
{
+ struct ctl_lun *lun = CTL_LUN(io);
struct scsi_mode_page_header *page_header;
struct ctl_page_index *page_index;
struct ctl_scsiio *ctsio;
int page_len, page_len_offset, page_len_size;
union ctl_modepage_info *modepage_info;
- struct ctl_lun *lun;
- int *len_left, *len_used;
+ uint16_t *len_left, *len_used;
int retval, i;
ctsio = &io->scsiio;
page_index = NULL;
page_len = 0;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
modepage_info = (union ctl_modepage_info *)
ctsio->io_hdr.ctl_private[CTL_PRIV_MODEPAGE].bytes;
@@ -6146,10 +6190,12 @@ bailout_no_done:
int
ctl_mode_select(struct ctl_scsiio *ctsio)
{
- int param_len, pf, sp;
- int header_size, bd_len;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
union ctl_modepage_info *modepage_info;
+ int bd_len, i, header_size, param_len, pf, rtd, sp;
+ uint32_t initidx;
+ initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
switch (ctsio->cdb[0]) {
case MODE_SELECT_6: {
struct scsi_mode_select_6 *cdb;
@@ -6157,6 +6203,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio)
cdb = (struct scsi_mode_select_6 *)ctsio->cdb;
pf = (cdb->byte2 & SMS_PF) ? 1 : 0;
+ rtd = (cdb->byte2 & SMS_RTD) ? 1 : 0;
sp = (cdb->byte2 & SMS_SP) ? 1 : 0;
param_len = cdb->length;
header_size = sizeof(struct scsi_mode_header_6);
@@ -6168,6 +6215,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio)
cdb = (struct scsi_mode_select_10 *)ctsio->cdb;
pf = (cdb->byte2 & SMS_PF) ? 1 : 0;
+ rtd = (cdb->byte2 & SMS_RTD) ? 1 : 0;
sp = (cdb->byte2 & SMS_SP) ? 1 : 0;
param_len = scsi_2btoul(cdb->length);
header_size = sizeof(struct scsi_mode_header_10);
@@ -6179,6 +6227,30 @@ ctl_mode_select(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
+ if (rtd) {
+ if (param_len != 0) {
+ ctl_set_invalid_field(ctsio, /*sks_valid*/ 0,
+ /*command*/ 1, /*field*/ 0,
+ /*bit_valid*/ 0, /*bit*/ 0);
+ ctl_done((union ctl_io *)ctsio);
+ return (CTL_RETVAL_COMPLETE);
+ }
+
+ /* Revert to defaults. */
+ ctl_init_page_index(lun);
+ mtx_lock(&lun->lun_lock);
+ ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE);
+ mtx_unlock(&lun->lun_lock);
+ for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
+ ctl_isc_announce_mode(lun, -1,
+ lun->mode_pages.index[i].page_code & SMPH_PC_MASK,
+ lun->mode_pages.index[i].subpage);
+ }
+ ctl_set_success(ctsio);
+ ctl_done((union ctl_io *)ctsio);
+ return (CTL_RETVAL_COMPLETE);
+ }
+
/*
* From SPC-3:
* "A parameter list length of zero indicates that the Data-Out Buffer
@@ -6210,7 +6282,6 @@ ctl_mode_select(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(param_len, M_CTL, M_WAITOK);
ctsio->kern_data_len = param_len;
ctsio->kern_total_len = param_len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -6267,7 +6338,7 @@ ctl_mode_select(struct ctl_scsiio *ctsio)
int
ctl_mode_sense(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
int pc, page_code, dbd, llba, subpage;
int alloc_len, page_len, header_len, total_len;
struct scsi_mode_block_descr *block_desc;
@@ -6279,7 +6350,6 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_mode_sense\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
switch (ctsio->cdb[0]) {
case MODE_SENSE_6: {
struct scsi_mode_sense_6 *cdb;
@@ -6441,17 +6511,9 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
switch (ctsio->cdb[0]) {
case MODE_SENSE_6: {
@@ -6615,12 +6677,11 @@ ctl_lbp_log_sense_handler(struct ctl_scsiio *ctsio,
struct ctl_page_index *page_index,
int pc)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_log_param_header *phdr;
uint8_t *data;
uint64_t val;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
data = page_index->page_data;
if (lun->backend->lun_attr != NULL &&
@@ -6684,41 +6745,31 @@ ctl_sap_log_sense_handler(struct ctl_scsiio *ctsio,
struct ctl_page_index *page_index,
int pc)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct stat_page *data;
- uint64_t rn, wn, rb, wb;
- struct bintime rt, wt;
- int i;
+ struct bintime *t;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
data = (struct stat_page *)page_index->page_data;
scsi_ulto2b(SLP_SAP, data->sap.hdr.param_code);
data->sap.hdr.param_control = SLP_LBIN;
data->sap.hdr.param_len = sizeof(struct scsi_log_stat_and_perf) -
sizeof(struct scsi_log_param_header);
- rn = wn = rb = wb = 0;
- bintime_clear(&rt);
- bintime_clear(&wt);
- for (i = 0; i < CTL_MAX_PORTS; i++) {
- rn += lun->stats.ports[i].operations[CTL_STATS_READ];
- wn += lun->stats.ports[i].operations[CTL_STATS_WRITE];
- rb += lun->stats.ports[i].bytes[CTL_STATS_READ];
- wb += lun->stats.ports[i].bytes[CTL_STATS_WRITE];
- bintime_add(&rt, &lun->stats.ports[i].time[CTL_STATS_READ]);
- bintime_add(&wt, &lun->stats.ports[i].time[CTL_STATS_WRITE]);
- }
- scsi_u64to8b(rn, data->sap.read_num);
- scsi_u64to8b(wn, data->sap.write_num);
- if (lun->stats.blocksize > 0) {
- scsi_u64to8b(wb / lun->stats.blocksize,
- data->sap.recvieved_lba);
- scsi_u64to8b(rb / lun->stats.blocksize,
- data->sap.transmitted_lba);
- }
- scsi_u64to8b((uint64_t)rt.sec * 1000 + rt.frac / (UINT64_MAX / 1000),
+ scsi_u64to8b(lun->stats.operations[CTL_STATS_READ],
+ data->sap.read_num);
+ scsi_u64to8b(lun->stats.operations[CTL_STATS_WRITE],
+ data->sap.write_num);
+ if (lun->be_lun->blocksize > 0) {
+ scsi_u64to8b(lun->stats.bytes[CTL_STATS_WRITE] /
+ lun->be_lun->blocksize, data->sap.recvieved_lba);
+ scsi_u64to8b(lun->stats.bytes[CTL_STATS_READ] /
+ lun->be_lun->blocksize, data->sap.transmitted_lba);
+ }
+ t = &lun->stats.time[CTL_STATS_READ];
+ scsi_u64to8b((uint64_t)t->sec * 1000 + t->frac / (UINT64_MAX / 1000),
data->sap.read_int);
- scsi_u64to8b((uint64_t)wt.sec * 1000 + wt.frac / (UINT64_MAX / 1000),
+ t = &lun->stats.time[CTL_STATS_WRITE];
+ scsi_u64to8b((uint64_t)t->sec * 1000 + t->frac / (UINT64_MAX / 1000),
data->sap.write_int);
scsi_u64to8b(0, data->sap.weighted_num);
scsi_u64to8b(0, data->sap.weighted_int);
@@ -6743,10 +6794,9 @@ ctl_ie_log_sense_handler(struct ctl_scsiio *ctsio,
struct ctl_page_index *page_index,
int pc)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_log_informational_exceptions *data;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
data = (struct scsi_log_informational_exceptions *)page_index->page_data;
scsi_ulto2b(SLP_IE_GEN, data->hdr.param_code);
@@ -6762,7 +6812,7 @@ ctl_ie_log_sense_handler(struct ctl_scsiio *ctsio,
int
ctl_log_sense(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
int i, pc, page_code, subpage;
int alloc_len, total_len;
struct ctl_page_index *page_index;
@@ -6771,7 +6821,6 @@ ctl_log_sense(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_log_sense\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_log_sense *)ctsio->cdb;
pc = (cdb->page & SLS_PAGE_CTRL_MASK) >> 6;
page_code = cdb->page & SLS_PAGE_CODE;
@@ -6807,17 +6856,9 @@ ctl_log_sense(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
header = (struct scsi_log_header *)ctsio->kern_data_ptr;
header->page = page_index->page_code;
@@ -6848,9 +6889,9 @@ ctl_log_sense(struct ctl_scsiio *ctsio)
int
ctl_read_capacity(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_read_capacity *cdb;
struct scsi_read_capacity_data *data;
- struct ctl_lun *lun;
uint32_t lba;
CTL_DEBUG_PRINT(("ctl_read_capacity\n"));
@@ -6870,14 +6911,10 @@ ctl_read_capacity(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO);
data = (struct scsi_read_capacity_data *)ctsio->kern_data_ptr;
- ctsio->residual = 0;
ctsio->kern_data_len = sizeof(*data);
ctsio->kern_total_len = sizeof(*data);
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
@@ -6906,9 +6943,9 @@ ctl_read_capacity(struct ctl_scsiio *ctsio)
int
ctl_read_capacity_16(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_read_capacity_16 *cdb;
struct scsi_read_capacity_data_long *data;
- struct ctl_lun *lun;
uint64_t lba;
uint32_t alloc_len;
@@ -6931,23 +6968,12 @@ ctl_read_capacity_16(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
ctsio->kern_data_ptr = malloc(sizeof(*data), M_CTL, M_WAITOK | M_ZERO);
data = (struct scsi_read_capacity_data_long *)ctsio->kern_data_ptr;
-
- if (sizeof(*data) < alloc_len) {
- ctsio->residual = alloc_len - sizeof(*data);
- ctsio->kern_data_len = sizeof(*data);
- ctsio->kern_total_len = sizeof(*data);
- } 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;
+ ctsio->kern_data_len = min(sizeof(*data), alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
scsi_u64to8b(lun->be_lun->maxlba, data->addr);
/* XXX KDM this may not be 512 bytes... */
@@ -6967,9 +6993,9 @@ ctl_read_capacity_16(struct ctl_scsiio *ctsio)
int
ctl_get_lba_status(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_get_lba_status *cdb;
struct scsi_get_lba_status_data *data;
- struct ctl_lun *lun;
struct ctl_lba_len_flags *lbalen;
uint64_t lba;
uint32_t alloc_len, total_len;
@@ -6977,7 +7003,6 @@ ctl_get_lba_status(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_get_lba_status\n"));
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_get_lba_status *)ctsio->cdb;
lba = scsi_8btou64(cdb->addr);
alloc_len = scsi_4btoul(cdb->alloc_len);
@@ -6991,19 +7016,10 @@ ctl_get_lba_status(struct ctl_scsiio *ctsio)
total_len = sizeof(*data) + sizeof(data->descr[0]);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
data = (struct scsi_get_lba_status_data *)ctsio->kern_data_ptr;
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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;
+ ctsio->kern_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/* Fill dummy data in case backend can't tell anything. */
scsi_ulto4b(4 + sizeof(data->descr[0]), data->length);
@@ -7054,18 +7070,10 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
}
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
data10 = (struct scsi_read_defect_data_hdr_10 *)
@@ -7090,12 +7098,12 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
int
ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_maintenance_in *cdb;
int retval;
int alloc_len, ext, total_len = 0, g, pc, pg, ts, os;
int num_ha_groups, num_target_ports, shared_group;
- struct ctl_lun *lun;
- struct ctl_softc *softc;
struct ctl_port *port;
struct scsi_target_group_data *rtg_ptr;
struct scsi_target_group_data_extended *rtg_ext_ptr;
@@ -7104,9 +7112,6 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_report_tagret_port_groups\n"));
cdb = (struct scsi_maintenance_in *)ctsio->cdb;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- softc = lun->ctl_softc;
-
retval = CTL_RETVAL_COMPLETE;
switch (cdb->byte2 & STG_PDF_MASK) {
@@ -7133,7 +7138,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
STAILQ_FOREACH(port, &softc->port_list, links) {
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
- if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
num_target_ports++;
if (port->status & CTL_PORT_STATUS_HA_SHARED)
@@ -7153,20 +7158,10 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
alloc_len = scsi_4btoul(cdb->length);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
ctsio->kern_sg_entries = 0;
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
if (ext) {
rtg_ext_ptr = (struct scsi_target_group_data_extended *)
@@ -7225,7 +7220,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
if (!softc->is_single &&
(port->status & CTL_PORT_STATUS_HA_SHARED) == 0)
continue;
- if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
scsi_ulto2b(port->targ_port, tpg_desc->descriptors[pc].
relative_target_port_identifier);
@@ -7250,7 +7245,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
continue;
if (port->status & CTL_PORT_STATUS_HA_SHARED)
continue;
- if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ if (ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
scsi_ulto2b(port->targ_port, tpg_desc->descriptors[pc].
relative_target_port_identifier);
@@ -7272,7 +7267,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
int
ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_report_supported_opcodes *cdb;
const struct ctl_cmd_entry *entry, *sentry;
struct scsi_report_supported_opcodes_all *all;
@@ -7285,8 +7280,6 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_report_supported_opcodes\n"));
cdb = (struct scsi_report_supported_opcodes *)ctsio->cdb;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
retval = CTL_RETVAL_COMPLETE;
opcode = cdb->requested_opcode;
@@ -7356,20 +7349,10 @@ ctl_report_supported_opcodes(struct ctl_scsiio *ctsio)
alloc_len = scsi_4btoul(cdb->length);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
ctsio->kern_sg_entries = 0;
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
switch (cdb->options & RSO_OPTIONS_MASK) {
case RSO_OPTIONS_ALL:
@@ -7470,20 +7453,10 @@ ctl_report_supported_tmf(struct ctl_scsiio *ctsio)
alloc_len = scsi_4btoul(cdb->length);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
ctsio->kern_sg_entries = 0;
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
data = (struct scsi_report_supported_tmf_ext_data *)ctsio->kern_data_ptr;
data->byte1 |= RST_ATS | RST_ATSS | RST_CTSS | RST_LURS | RST_QTS |
@@ -7518,20 +7491,10 @@ ctl_report_timestamp(struct ctl_scsiio *ctsio)
alloc_len = scsi_4btoul(cdb->length);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
ctsio->kern_sg_entries = 0;
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
data = (struct scsi_report_timestamp_data *)ctsio->kern_data_ptr;
scsi_ulto2b(sizeof(*data) - 2, data->length);
@@ -7551,11 +7514,11 @@ ctl_report_timestamp(struct ctl_scsiio *ctsio)
int
ctl_persistent_reserve_in(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_per_res_in *cdb;
int alloc_len, total_len = 0;
/* struct scsi_per_res_in_rsrv in_data; */
- struct ctl_lun *lun;
- struct ctl_softc *softc;
uint64_t key;
CTL_DEBUG_PRINT(("ctl_persistent_reserve_in\n"));
@@ -7564,9 +7527,6 @@ ctl_persistent_reserve_in(struct ctl_scsiio *ctsio)
alloc_len = scsi_2btoul(cdb->length);
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- softc = lun->ctl_softc;
-
retry:
mtx_lock(&lun->lun_lock);
switch (cdb->action) {
@@ -7595,20 +7555,10 @@ retry:
mtx_unlock(&lun->lun_lock);
ctsio->kern_data_ptr = malloc(total_len, M_CTL, M_WAITOK | M_ZERO);
-
- if (total_len < alloc_len) {
- ctsio->residual = alloc_len - total_len;
- ctsio->kern_data_len = total_len;
- ctsio->kern_total_len = total_len;
- } 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;
+ ctsio->kern_data_len = min(total_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
mtx_lock(&lun->lun_lock);
switch (cdb->action) {
@@ -8129,12 +8079,12 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg)
int
ctl_persistent_reserve_out(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
int retval;
u_int32_t param_len;
struct scsi_per_res_out *cdb;
- struct ctl_lun *lun;
struct scsi_per_res_out_parms* param;
- struct ctl_softc *softc;
uint32_t residx;
uint64_t res_key, sa_res_key, key;
uint8_t type;
@@ -8143,11 +8093,8 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_persistent_reserve_out\n"));
- retval = CTL_RETVAL_COMPLETE;
-
cdb = (struct scsi_per_res_out *)ctsio->cdb;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- softc = lun->ctl_softc;
+ retval = CTL_RETVAL_COMPLETE;
/*
* We only support whole-LUN scope. The scope & type are ignored for
@@ -8187,7 +8134,6 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(param_len, M_CTL, M_WAITOK);
ctsio->kern_data_len = param_len;
ctsio->kern_total_len = param_len;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -8521,17 +8467,18 @@ done:
* in sync.
*/
static void
-ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
+ctl_hndl_per_res_out_on_other_sc(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
+ union ctl_ha_msg *msg = (union ctl_ha_msg *)&io->presio.pr_msg;
struct ctl_lun *lun;
int i;
uint32_t residx, targ_lun;
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
- ((lun = softc->ctl_luns[targ_lun]) == NULL)) {
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
}
@@ -8642,15 +8589,13 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
int
ctl_read_write(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
uint64_t lba;
uint32_t num_blocks;
int flags, retval;
int isread;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
CTL_DEBUG_PRINT(("ctl_read_write: command: %#x\n", ctsio->cdb[0]));
flags = 0;
@@ -8835,15 +8780,14 @@ ctl_read_write(struct ctl_scsiio *ctsio)
static int
ctl_cnw_cont(union ctl_io *io)
{
+ struct ctl_lun *lun = CTL_LUN(io);
struct ctl_scsiio *ctsio;
- struct ctl_lun *lun;
struct ctl_lba_len_flags *lbalen;
int retval;
ctsio = &io->scsiio;
ctsio->io_hdr.status = CTL_STATUS_NONE;
ctsio->io_hdr.flags &= ~CTL_FLAG_IO_CONT;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
lbalen = (struct ctl_lba_len_flags *)
&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
lbalen->flags &= ~CTL_LLF_COMPARE;
@@ -8857,14 +8801,12 @@ ctl_cnw_cont(union ctl_io *io)
int
ctl_cnw(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
uint64_t lba;
uint32_t num_blocks;
int flags, retval;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
CTL_DEBUG_PRINT(("ctl_cnw: command: %#x\n", ctsio->cdb[0]));
flags = 0;
@@ -8945,15 +8887,13 @@ ctl_cnw(struct ctl_scsiio *ctsio)
int
ctl_verify(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct ctl_lba_len_flags *lbalen;
uint64_t lba;
uint32_t num_blocks;
int bytchk, flags;
int retval;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
CTL_DEBUG_PRINT(("ctl_verify: command: %#x\n", ctsio->cdb[0]));
bytchk = 0;
@@ -9049,27 +8989,25 @@ ctl_verify(struct ctl_scsiio *ctsio)
int
ctl_report_luns(struct ctl_scsiio *ctsio)
{
- struct ctl_softc *softc;
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_port *port = CTL_PORT(ctsio);
+ struct ctl_lun *lun, *request_lun = CTL_LUN(ctsio);
struct scsi_report_luns *cdb;
struct scsi_report_luns_data *lun_data;
- struct ctl_lun *lun, *request_lun;
- struct ctl_port *port;
- int num_luns, retval;
+ int num_filled, num_luns, num_port_luns, retval;
uint32_t alloc_len, lun_datalen;
- int num_filled;
uint32_t initidx, targ_lun_id, lun_id;
retval = CTL_RETVAL_COMPLETE;
cdb = (struct scsi_report_luns *)ctsio->cdb;
- port = ctl_io_port(&ctsio->io_hdr);
- softc = port->ctl_softc;
CTL_DEBUG_PRINT(("ctl_report_luns\n"));
- mtx_lock(&softc->ctl_lock);
num_luns = 0;
- for (targ_lun_id = 0; targ_lun_id < CTL_MAX_LUNS; targ_lun_id++) {
- if (ctl_lun_map_from_port(port, targ_lun_id) < CTL_MAX_LUNS)
+ num_port_luns = port->lun_map ? port->lun_map_size : CTL_MAX_LUNS;
+ mtx_lock(&softc->ctl_lock);
+ for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) {
+ if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX)
num_luns++;
}
mtx_unlock(&softc->ctl_lock);
@@ -9114,9 +9052,6 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
return (retval);
}
- request_lun = (struct ctl_lun *)
- ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
lun_datalen = sizeof(*lun_data) +
(num_luns * sizeof(struct scsi_report_luns_lundata));
@@ -9127,9 +9062,11 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
mtx_lock(&softc->ctl_lock);
- for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
+ for (targ_lun_id = 0, num_filled = 0;
+ targ_lun_id < num_port_luns && num_filled < num_luns;
+ targ_lun_id++) {
lun_id = ctl_lun_map_from_port(port, targ_lun_id);
- if (lun_id >= CTL_MAX_LUNS)
+ if (lun_id == UINT32_MAX)
continue;
lun = softc->ctl_luns[lun_id];
if (lun == NULL)
@@ -9168,19 +9105,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
*/
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;
+ ctsio->kern_data_len = min(lun_datalen, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* We set this to the actual data length, regardless of how much
@@ -9205,10 +9133,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
int
ctl_request_sense(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_request_sense *cdb;
struct scsi_sense_data *sense_ptr;
- struct ctl_softc *softc;
- struct ctl_lun *lun;
uint32_t initidx;
int have_error;
u_int sense_len = SSD_FULL_SIZE;
@@ -9218,9 +9146,6 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
cdb = (struct scsi_request_sense *)ctsio->cdb;
- softc = control_softc;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
CTL_DEBUG_PRINT(("ctl_request_sense\n"));
/*
@@ -9234,20 +9159,16 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(sizeof(*sense_ptr), M_CTL, M_WAITOK);
sense_ptr = (struct scsi_sense_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
+ ctsio->kern_rel_offset = 0;
/*
* struct scsi_sense_data, which is currently set to 256 bytes, is
* larger than the largest allowed value for the length field in the
* REQUEST SENSE CDB, which is 252 bytes as of SPC-4.
*/
- ctsio->residual = 0;
ctsio->kern_data_len = cdb->length;
ctsio->kern_total_len = cdb->length;
- ctsio->kern_data_resid = 0;
- ctsio->kern_rel_offset = 0;
- ctsio->kern_sg_entries = 0;
-
/*
* If we don't have a LUN, we don't have any pending sense.
*/
@@ -9363,31 +9284,19 @@ ctl_tur(struct ctl_scsiio *ctsio)
static int
ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_supported_pages *pages;
int sup_page_size;
- struct ctl_lun *lun;
int p;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
sup_page_size = sizeof(struct scsi_vpd_supported_pages) *
SCSI_EVPD_NUM_SUPPORTED_PAGES;
ctsio->kern_data_ptr = malloc(sup_page_size, M_CTL, M_WAITOK | M_ZERO);
pages = (struct scsi_vpd_supported_pages *)ctsio->kern_data_ptr;
- ctsio->kern_sg_entries = 0;
-
- if (sup_page_size < alloc_len) {
- ctsio->residual = alloc_len - sup_page_size;
- ctsio->kern_data_len = sup_page_size;
- ctsio->kern_total_len = sup_page_size;
- } 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;
+ ctsio->kern_data_len = min(sup_page_size, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9438,27 +9347,17 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_unit_serial_number *sn_ptr;
- struct ctl_lun *lun;
int data_len;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
data_len = 4 + CTL_SN_LEN;
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr;
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9497,29 +9396,17 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_extended_inquiry_data *eid_ptr;
- struct ctl_lun *lun;
int data_len;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
data_len = sizeof(struct scsi_vpd_extended_inquiry_data);
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
eid_ptr = (struct scsi_vpd_extended_inquiry_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9549,6 +9436,11 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
eid_ptr->flags4 = SVPD_EID_LUICLR;
/*
+ * We support revert to defaults (RTD) bit in MODE SELECT.
+ */
+ eid_ptr->flags5 = SVPD_EID_RTD_SUP;
+
+ /*
* XXX KDM in order to correctly answer this, we would need
* information from the SIM to determine how much sense data it
* can send. So this would really be a path inquiry field, most
@@ -9568,31 +9460,19 @@ ctl_inquiry_evpd_eid(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_mode_page_policy *mpp_ptr;
- struct ctl_lun *lun;
int data_len;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
data_len = sizeof(struct scsi_vpd_mode_page_policy) +
sizeof(struct scsi_vpd_mode_page_policy_descr);
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
mpp_ptr = (struct scsi_vpd_mode_page_policy *)ctsio->kern_data_ptr;
- ctsio->kern_sg_entries = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9622,19 +9502,14 @@ ctl_inquiry_evpd_mpp(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_port *port = CTL_PORT(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_device_id *devid_ptr;
struct scsi_vpd_id_descriptor *desc;
- struct ctl_softc *softc;
- struct ctl_lun *lun;
- struct ctl_port *port;
int data_len, g;
uint8_t proto;
- softc = control_softc;
-
- port = ctl_io_port(&ctsio->io_hdr);
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
data_len = sizeof(struct scsi_vpd_device_id) +
sizeof(struct scsi_vpd_id_descriptor) +
sizeof(struct scsi_vpd_id_rel_trgt_port_id) +
@@ -9650,19 +9525,10 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9747,16 +9613,14 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_scsi_ports *sp;
struct scsi_vpd_port_designation *pd;
struct scsi_vpd_port_designation_cont *pdc;
- struct ctl_lun *lun;
struct ctl_port *port;
int data_len, num_target_ports, iid_len, id_len;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
num_target_ports = 0;
iid_len = 0;
id_len = 0;
@@ -9765,7 +9629,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
num_target_ports++;
if (port->init_devid)
@@ -9781,19 +9645,10 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
sp = (struct scsi_vpd_scsi_ports *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } 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;
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9816,7 +9671,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
scsi_ulto2b(port->targ_port, pd->relative_port_id);
if (port->init_devid) {
@@ -9850,28 +9705,17 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_block_limits *bl_ptr;
- struct ctl_lun *lun;
uint64_t ival;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
ctsio->kern_data_ptr = malloc(sizeof(*bl_ptr), M_CTL, M_WAITOK | M_ZERO);
bl_ptr = (struct scsi_vpd_block_limits *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (sizeof(*bl_ptr) < alloc_len) {
- ctsio->residual = alloc_len - sizeof(*bl_ptr);
- ctsio->kern_data_len = sizeof(*bl_ptr);
- ctsio->kern_total_len = sizeof(*bl_ptr);
- } 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;
+ ctsio->kern_data_len = min(sizeof(*bl_ptr), alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9927,29 +9771,17 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_block_device_characteristics *bdc_ptr;
- struct ctl_lun *lun;
const char *value;
u_int i;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
ctsio->kern_data_ptr = malloc(sizeof(*bdc_ptr), M_CTL, M_WAITOK | M_ZERO);
bdc_ptr = (struct scsi_vpd_block_device_characteristics *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (sizeof(*bdc_ptr) < alloc_len) {
- ctsio->residual = alloc_len - sizeof(*bdc_ptr);
- ctsio->kern_data_len = sizeof(*bdc_ptr);
- ctsio->kern_total_len = sizeof(*bdc_ptr);
- } 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;
+ ctsio->kern_data_len = min(sizeof(*bdc_ptr), alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -9987,28 +9819,16 @@ ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_logical_block_prov *lbp_ptr;
- struct ctl_lun *lun;
const char *value;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
-
ctsio->kern_data_ptr = malloc(sizeof(*lbp_ptr), M_CTL, M_WAITOK | M_ZERO);
lbp_ptr = (struct scsi_vpd_logical_block_prov *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
-
- if (sizeof(*lbp_ptr) < alloc_len) {
- ctsio->residual = alloc_len - sizeof(*lbp_ptr);
- ctsio->kern_data_len = sizeof(*lbp_ptr);
- ctsio->kern_total_len = sizeof(*lbp_ptr);
- } 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;
+ ctsio->kern_data_len = min(sizeof(*lbp_ptr), alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
/*
* The control device is always connected. The disk device, on the
@@ -10050,11 +9870,10 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_inquiry *cdb;
int alloc_len, retval;
- lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_inquiry *)ctsio->cdb;
alloc_len = scsi_2btoul(cdb->length);
@@ -10117,21 +9936,19 @@ err:
static int
ctl_inquiry_std(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = CTL_SOFTC(ctsio);
+ struct ctl_port *port = CTL_PORT(ctsio);
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_inquiry_data *inq_ptr;
struct scsi_inquiry *cdb;
- struct ctl_softc *softc = control_softc;
- struct ctl_port *port;
- struct ctl_lun *lun;
char *val;
uint32_t alloc_len, data_len;
ctl_port_type port_type;
- port = ctl_io_port(&ctsio->io_hdr);
port_type = port->port_type;
if (port_type == CTL_PORT_IOCTL || port_type == CTL_PORT_INTERNAL)
port_type = CTL_PORT_SCSI;
- lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_inquiry *)ctsio->cdb;
alloc_len = scsi_2btoul(cdb->length);
@@ -10144,18 +9961,9 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
inq_ptr = (struct scsi_inquiry_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
if (lun != NULL) {
if ((lun->flags & CTL_LUN_PRIMARY_SC) ||
@@ -10345,14 +10153,13 @@ ctl_inquiry(struct ctl_scsiio *ctsio)
int
ctl_get_config(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_get_config_header *hdr;
struct scsi_get_config_feature *feature;
struct scsi_get_config *cdb;
- struct ctl_lun *lun;
uint32_t alloc_len, data_len;
int rt, starting;
- lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_get_config *)ctsio->cdb;
rt = (cdb->rt & SGC_RT_MASK);
starting = scsi_2btoul(cdb->starting_feature);
@@ -10373,7 +10180,6 @@ ctl_get_config(struct ctl_scsiio *ctsio)
sizeof(struct scsi_get_config_feature) + 4;
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
hdr = (struct scsi_get_config_header *)ctsio->kern_data_ptr;
@@ -10541,15 +10347,8 @@ done:
data_len = (uint8_t *)feature - (uint8_t *)hdr;
}
scsi_ulto4b(data_len - 4, hdr->data_length);
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
ctl_set_success(ctsio);
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -10563,11 +10362,9 @@ ctl_get_event_status(struct ctl_scsiio *ctsio)
{
struct scsi_get_event_status_header *hdr;
struct scsi_get_event_status *cdb;
- struct ctl_lun *lun;
uint32_t alloc_len, data_len;
int notif_class;
- lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_get_event_status *)ctsio->cdb;
if ((cdb->byte2 & SGESN_POLLED) == 0) {
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1,
@@ -10581,18 +10378,9 @@ ctl_get_event_status(struct ctl_scsiio *ctsio)
data_len = sizeof(struct scsi_get_event_status_header);
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr;
scsi_ulto2b(0, hdr->descr_length);
@@ -10611,28 +10399,17 @@ ctl_mechanism_status(struct ctl_scsiio *ctsio)
{
struct scsi_mechanism_status_header *hdr;
struct scsi_mechanism_status *cdb;
- struct ctl_lun *lun;
uint32_t alloc_len, data_len;
- lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_mechanism_status *)ctsio->cdb;
alloc_len = scsi_2btoul(cdb->length);
data_len = sizeof(struct scsi_mechanism_status_header);
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr;
hdr->state1 = 0x00;
@@ -10662,14 +10439,13 @@ ctl_ultomsf(uint32_t lba, uint8_t *buf)
int
ctl_read_toc(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_read_toc_hdr *hdr;
struct scsi_read_toc_type01_descr *descr;
struct scsi_read_toc *cdb;
- struct ctl_lun *lun;
uint32_t alloc_len, data_len;
int format, msf;
- lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_read_toc *)ctsio->cdb;
msf = (cdb->byte2 & CD_MSF) != 0;
format = cdb->format;
@@ -10682,18 +10458,9 @@ ctl_read_toc(struct ctl_scsiio *ctsio)
data_len += sizeof(struct scsi_read_toc_type01_descr);
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
ctsio->kern_sg_entries = 0;
- ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
-
- if (data_len < alloc_len) {
- ctsio->residual = alloc_len - data_len;
- ctsio->kern_data_len = data_len;
- ctsio->kern_total_len = data_len;
- } else {
- ctsio->residual = 0;
- ctsio->kern_data_len = alloc_len;
- ctsio->kern_total_len = alloc_len;
- }
+ ctsio->kern_data_len = min(data_len, alloc_len);
+ ctsio->kern_total_len = ctsio->kern_data_len;
hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr;
if (format == 0) {
@@ -11416,7 +11183,7 @@ ctl_failover_io(union ctl_io *io, int have_lock)
static void
ctl_failover_lun(union ctl_io *rio)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(rio);
struct ctl_lun *lun;
struct ctl_io_hdr *io, *next_io;
uint32_t targ_lun;
@@ -11426,18 +11193,17 @@ ctl_failover_lun(union ctl_io *rio)
/* Find and lock the LUN. */
mtx_lock(&softc->ctl_lock);
- if ((targ_lun < CTL_MAX_LUNS) &&
- ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
- mtx_lock(&lun->lun_lock);
- mtx_unlock(&softc->ctl_lock);
- if (lun->flags & CTL_LUN_DISABLED) {
- mtx_unlock(&lun->lun_lock);
- return;
- }
- } else {
+ if (targ_lun > CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
}
+ mtx_lock(&lun->lun_lock);
+ mtx_unlock(&softc->ctl_lock);
+ if (lun->flags & CTL_LUN_DISABLED) {
+ mtx_unlock(&lun->lun_lock);
+ return;
+ }
if (softc->ha_mode == CTL_HA_MODE_XFER) {
TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) {
@@ -11505,15 +11271,13 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
struct ctl_lun *lun;
const struct ctl_cmd_entry *entry;
uint32_t initidx, targ_lun;
- int retval;
-
- retval = 0;
+ int retval = 0;
lun = NULL;
-
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun;
- if ((targ_lun < CTL_MAX_LUNS)
- && ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
+ if (targ_lun < CTL_MAX_LUNS)
+ lun = softc->ctl_luns[targ_lun];
+ if (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
@@ -11523,29 +11287,21 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
if (lun->flags & CTL_LUN_DISABLED) {
mtx_unlock(&lun->lun_lock);
lun = NULL;
- ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = NULL;
- ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = NULL;
- } else {
- ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun;
- ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr =
- lun->be_lun;
+ }
+ }
+ CTL_LUN(ctsio) = lun;
+ if (lun) {
+ CTL_BACKEND_LUN(ctsio) = lun->be_lun;
- /*
- * Every I/O goes into the OOA queue for a
- * particular LUN, and stays there until completion.
- */
+ /*
+ * Every I/O goes into the OOA queue for a particular LUN,
+ * and stays there until completion.
+ */
#ifdef CTL_TIME_IO
- if (TAILQ_EMPTY(&lun->ooa_queue)) {
- lun->idle_time += getsbinuptime() -
- lun->last_busy;
- }
+ if (TAILQ_EMPTY(&lun->ooa_queue))
+ lun->idle_time += getsbinuptime() - lun->last_busy;
#endif
- TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr,
- ooa_links);
- }
- } else {
- ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = NULL;
- ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = NULL;
+ TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
}
/* Get command entry and return error if it is unsuppotyed. */
@@ -11849,7 +11605,7 @@ static int
ctl_target_reset(struct ctl_softc *softc, union ctl_io *io,
ctl_ua_type ua_type)
{
- struct ctl_port *port;
+ struct ctl_port *port = CTL_PORT(io);
struct ctl_lun *lun;
int retval;
@@ -11870,10 +11626,9 @@ ctl_target_reset(struct ctl_softc *softc, union ctl_io *io,
retval = 0;
mtx_lock(&softc->ctl_lock);
- port = ctl_io_port(&io->io_hdr);
STAILQ_FOREACH(lun, &softc->lun_list, links) {
if (port != NULL &&
- ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
+ ctl_lun_map_to_port(port, lun->lun) == UINT32_MAX)
continue;
retval += ctl_do_lun_reset(lun, io, ua_type);
}
@@ -11946,8 +11701,10 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type)
ctl_clear_mask(lun->have_ca, i);
#endif
lun->prevent_count = 0;
- for (i = 0; i < CTL_MAX_INITIATORS; i++)
- ctl_clear_mask(lun->prevent, i);
+ if (lun->prevent) {
+ for (i = 0; i < CTL_MAX_INITIATORS; i++)
+ ctl_clear_mask(lun->prevent, i);
+ }
mtx_unlock(&lun->lun_lock);
return (0);
@@ -11962,7 +11719,7 @@ ctl_lun_reset(struct ctl_softc *softc, union ctl_io *io)
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
+ if (targ_lun >= CTL_MAX_LUNS ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@@ -12032,7 +11789,7 @@ ctl_abort_tasks_lun(struct ctl_lun *lun, uint32_t targ_port, uint32_t init_id,
static int
ctl_abort_task_set(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_lun *lun;
uint32_t targ_lun;
@@ -12041,7 +11798,7 @@ ctl_abort_task_set(union ctl_io *io)
*/
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
+ if (targ_lun >= CTL_MAX_LUNS ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@@ -12066,7 +11823,7 @@ ctl_abort_task_set(union ctl_io *io)
static int
ctl_i_t_nexus_reset(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_lun *lun;
uint32_t initidx;
@@ -12093,7 +11850,7 @@ ctl_i_t_nexus_reset(union ctl_io *io)
#endif
if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx))
lun->flags &= ~CTL_LUN_RESERVED;
- if (ctl_is_set(lun->prevent, initidx)) {
+ if (lun->prevent && ctl_is_set(lun->prevent, initidx)) {
ctl_clear_mask(lun->prevent, initidx);
lun->prevent_count--;
}
@@ -12108,9 +11865,9 @@ ctl_i_t_nexus_reset(union ctl_io *io)
static int
ctl_abort_task(union ctl_io *io)
{
+ struct ctl_softc *softc = CTL_SOFTC(io);
union ctl_io *xio;
struct ctl_lun *lun;
- struct ctl_softc *softc;
#if 0
struct sbuf sb;
char printbuf[128];
@@ -12118,7 +11875,6 @@ ctl_abort_task(union ctl_io *io)
int found;
uint32_t targ_lun;
- softc = control_softc;
found = 0;
/*
@@ -12126,7 +11882,7 @@ ctl_abort_task(union ctl_io *io)
*/
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
+ if (targ_lun >= CTL_MAX_LUNS ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@@ -12242,16 +11998,15 @@ ctl_abort_task(union ctl_io *io)
static int
ctl_query_task(union ctl_io *io, int task_set)
{
+ struct ctl_softc *softc = CTL_SOFTC(io);
union ctl_io *xio;
struct ctl_lun *lun;
- struct ctl_softc *softc;
int found = 0;
uint32_t targ_lun;
- softc = control_softc;
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
+ if (targ_lun >= CTL_MAX_LUNS ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@@ -12283,15 +12038,14 @@ ctl_query_task(union ctl_io *io, int task_set)
static int
ctl_query_async_event(union ctl_io *io)
{
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_lun *lun;
- struct ctl_softc *softc;
ctl_ua_type ua;
uint32_t targ_lun, initidx;
- softc = control_softc;
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
- if ((targ_lun >= CTL_MAX_LUNS) ||
+ if (targ_lun >= CTL_MAX_LUNS ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@@ -12312,7 +12066,7 @@ ctl_query_async_event(union ctl_io *io)
static void
ctl_run_task(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
int retval = 1;
CTL_DEBUG_PRINT(("ctl_run_task\n"));
@@ -12374,29 +12128,25 @@ ctl_run_task(union ctl_io *io)
static void
ctl_handle_isc(union ctl_io *io)
{
- int free_io;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_lun *lun;
- struct ctl_softc *softc = control_softc;
+ const struct ctl_cmd_entry *entry;
uint32_t targ_lun;
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
- lun = softc->ctl_luns[targ_lun];
-
switch (io->io_hdr.msg_type) {
case CTL_MSG_SERIALIZE:
- free_io = ctl_serialize_other_sc_cmd(&io->scsiio);
+ ctl_serialize_other_sc_cmd(&io->scsiio);
break;
- case CTL_MSG_R2R: {
- const struct ctl_cmd_entry *entry;
-
- /*
- * This is only used in SER_ONLY mode.
- */
- free_io = 0;
+ case CTL_MSG_R2R: /* Only used in SER_ONLY mode. */
entry = ctl_get_cmd_entry(&io->scsiio, NULL);
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
+ ctl_done(io);
+ break;
+ }
mtx_lock(&lun->lun_lock);
- if (ctl_scsiio_lun_check(lun,
- entry, (struct ctl_scsiio *)io) != 0) {
+ if (ctl_scsiio_lun_check(lun, entry, &io->scsiio) != 0) {
mtx_unlock(&lun->lun_lock);
ctl_done(io);
break;
@@ -12405,51 +12155,45 @@ ctl_handle_isc(union ctl_io *io)
mtx_unlock(&lun->lun_lock);
ctl_enqueue_rtr(io);
break;
- }
case CTL_MSG_FINISH_IO:
if (softc->ha_mode == CTL_HA_MODE_XFER) {
- free_io = 0;
ctl_done(io);
- } else {
- free_io = 1;
- mtx_lock(&lun->lun_lock);
- TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr,
- ooa_links);
- ctl_check_blocked(lun);
- mtx_unlock(&lun->lun_lock);
+ break;
+ }
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
+ ctl_free_io(io);
+ break;
}
+ mtx_lock(&lun->lun_lock);
+ TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, ooa_links);
+ ctl_check_blocked(lun);
+ mtx_unlock(&lun->lun_lock);
+ ctl_free_io(io);
break;
case CTL_MSG_PERS_ACTION:
- ctl_hndl_per_res_out_on_other_sc(
- (union ctl_ha_msg *)&io->presio.pr_msg);
- free_io = 1;
+ ctl_hndl_per_res_out_on_other_sc(io);
+ ctl_free_io(io);
break;
case CTL_MSG_BAD_JUJU:
- free_io = 0;
ctl_done(io);
break;
- case CTL_MSG_DATAMOVE:
- /* Only used in XFER mode */
- free_io = 0;
+ case CTL_MSG_DATAMOVE: /* Only used in XFER mode */
ctl_datamove_remote(io);
break;
- case CTL_MSG_DATAMOVE_DONE:
- /* Only used in XFER mode */
- free_io = 0;
+ case CTL_MSG_DATAMOVE_DONE: /* Only used in XFER mode */
io->scsiio.be_move_done(io);
break;
case CTL_MSG_FAILOVER:
ctl_failover_lun(io);
- free_io = 1;
+ ctl_free_io(io);
break;
default:
- free_io = 1;
printf("%s: Invalid message type %d\n",
__func__, io->io_hdr.msg_type);
+ ctl_free_io(io);
break;
}
- if (free_io)
- ctl_free_io(io);
}
@@ -12601,14 +12345,15 @@ ctl_datamove_timer_wakeup(void *arg)
void
ctl_datamove(union ctl_io *io)
{
- struct ctl_lun *lun;
void (*fe_datamove)(union ctl_io *io);
- mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED);
+ mtx_assert(&((struct ctl_softc *)CTL_SOFTC(io))->ctl_lock, MA_NOTOWNED);
CTL_DEBUG_PRINT(("ctl_datamove\n"));
- lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ /* No data transferred yet. Frontend must update this when done. */
+ io->scsiio.kern_data_resid = io->scsiio.kern_data_len;
+
#ifdef CTL_TIME_IO
if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) {
char str[256];
@@ -12689,7 +12434,7 @@ ctl_datamove(union ctl_io *io)
return;
}
- fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
+ fe_datamove = CTL_PORT(io)->fe_datamove;
fe_datamove(io);
}
@@ -12707,15 +12452,14 @@ ctl_send_datamove_done(union ctl_io *io, int have_lock)
msg.hdr.serializing_sc = io->io_hdr.serializing_sc;
msg.hdr.nexus = io->io_hdr.nexus;
msg.hdr.status = io->io_hdr.status;
+ msg.scsi.kern_data_resid = io->scsiio.kern_data_resid;
msg.scsi.tag_num = io->scsiio.tag_num;
msg.scsi.tag_type = io->scsiio.tag_type;
msg.scsi.scsi_status = io->scsiio.scsi_status;
memcpy(&msg.scsi.sense_data, &io->scsiio.sense_data,
io->scsiio.sense_len);
msg.scsi.sense_len = io->scsiio.sense_len;
- msg.scsi.sense_residual = io->scsiio.sense_residual;
- msg.scsi.fetd_status = io->io_hdr.port_status;
- msg.scsi.residual = io->scsiio.residual;
+ msg.scsi.port_status = io->io_hdr.port_status;
io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
ctl_failover_io(io, /*have_lock*/ have_lock);
@@ -12807,7 +12551,7 @@ ctl_datamove_remote_write(union ctl_io *io)
*/
io->scsiio.be_move_done = ctl_datamove_remote_dm_write_cb;
- fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
+ fe_datamove = CTL_PORT(io)->fe_datamove;
fe_datamove(io);
}
@@ -12882,7 +12626,7 @@ ctl_datamove_remote_read_cb(struct ctl_ha_dt_req *rq)
/* XXX KDM add checks like the ones in ctl_datamove? */
- fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
+ fe_datamove = CTL_PORT(io)->fe_datamove;
fe_datamove(io);
}
@@ -13098,7 +12842,7 @@ static void
ctl_datamove_remote(union ctl_io *io)
{
- mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED);
+ mtx_assert(&((struct ctl_softc *)CTL_SOFTC(io))->ctl_lock, MA_NOTOWNED);
if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
ctl_failover_io(io, /*have_lock*/ 0);
@@ -13134,14 +12878,14 @@ ctl_datamove_remote(union ctl_io *io)
static void
ctl_process_done(union ctl_io *io)
{
- struct ctl_lun *lun;
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
+ struct ctl_port *port = CTL_PORT(io);
+ struct ctl_lun *lun = CTL_LUN(io);
void (*fe_done)(union ctl_io *io);
union ctl_ha_msg msg;
- uint32_t targ_port = io->io_hdr.nexus.targ_port;
CTL_DEBUG_PRINT(("ctl_process_done\n"));
- fe_done = softc->ctl_ports[targ_port]->fe_done;
+ fe_done = port->fe_done;
#ifdef CTL_TIME_IO
if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) {
@@ -13191,7 +12935,6 @@ ctl_process_done(union ctl_io *io)
__func__, io->io_hdr.io_type);
}
- lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
if (lun == NULL) {
CTL_DEBUG_PRINT(("NULL LUN for lun %d\n",
io->io_hdr.nexus.targ_mapped_lun));
@@ -13245,11 +12988,13 @@ ctl_process_done(union ctl_io *io)
*/
if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS &&
io->io_hdr.io_type == CTL_IO_SCSI) {
-#ifdef CTL_TIME_IO
- struct bintime cur_bt;
-#endif
int type;
+#ifdef CTL_TIME_IO
+ struct bintime bt;
+ getbinuptime(&bt);
+ bintime_sub(&bt, &io->io_hdr.start_bt);
+#endif
if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
CTL_FLAG_DATA_IN)
type = CTL_STATS_READ;
@@ -13259,18 +13004,38 @@ ctl_process_done(union ctl_io *io)
else
type = CTL_STATS_NO_IO;
- lun->stats.ports[targ_port].bytes[type] +=
+#ifdef CTL_LEGACY_STATS
+ uint32_t targ_port = port->targ_port;
+ lun->legacy_stats.ports[targ_port].bytes[type] +=
io->scsiio.kern_total_len;
- lun->stats.ports[targ_port].operations[type]++;
+ lun->legacy_stats.ports[targ_port].operations[type] ++;
+ lun->legacy_stats.ports[targ_port].num_dmas[type] +=
+ io->io_hdr.num_dmas;
#ifdef CTL_TIME_IO
- bintime_add(&lun->stats.ports[targ_port].dma_time[type],
+ bintime_add(&lun->legacy_stats.ports[targ_port].dma_time[type],
&io->io_hdr.dma_bt);
- getbinuptime(&cur_bt);
- bintime_sub(&cur_bt, &io->io_hdr.start_bt);
- bintime_add(&lun->stats.ports[targ_port].time[type], &cur_bt);
+ bintime_add(&lun->legacy_stats.ports[targ_port].time[type],
+ &bt);
#endif
- lun->stats.ports[targ_port].num_dmas[type] +=
- io->io_hdr.num_dmas;
+#endif /* CTL_LEGACY_STATS */
+
+ lun->stats.bytes[type] += io->scsiio.kern_total_len;
+ lun->stats.operations[type] ++;
+ lun->stats.dmas[type] += io->io_hdr.num_dmas;
+#ifdef CTL_TIME_IO
+ bintime_add(&lun->stats.dma_time[type], &io->io_hdr.dma_bt);
+ bintime_add(&lun->stats.time[type], &bt);
+#endif
+
+ mtx_lock(&port->port_lock);
+ port->stats.bytes[type] += io->scsiio.kern_total_len;
+ port->stats.operations[type] ++;
+ port->stats.dmas[type] += io->io_hdr.num_dmas;
+#ifdef CTL_TIME_IO
+ bintime_add(&port->stats.dma_time[type], &io->io_hdr.dma_bt);
+ bintime_add(&port->stats.time[type], &bt);
+#endif
+ mtx_unlock(&port->port_lock);
}
/*
@@ -13345,42 +13110,36 @@ bailout:
int
ctl_queue_sense(union ctl_io *io)
{
+ struct ctl_softc *softc = CTL_SOFTC(io);
+ struct ctl_port *port = CTL_PORT(io);
struct ctl_lun *lun;
- struct ctl_port *port;
- struct ctl_softc *softc;
uint32_t initidx, targ_lun;
- softc = control_softc;
-
CTL_DEBUG_PRINT(("ctl_queue_sense\n"));
+ targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
+
/*
* LUN lookup will likely move to the ctl_work_thread() once we
* have our new queueing infrastructure (that doesn't put things on
* a per-LUN queue initially). That is so that we can handle
* things like an INQUIRY to a LUN that we don't have enabled. We
* can't deal with that right now.
+ * If we don't have a LUN for this, just toss the sense information.
*/
mtx_lock(&softc->ctl_lock);
-
- /*
- * If we don't have a LUN for this, just toss the sense
- * information.
- */
- port = ctl_io_port(&ctsio->io_hdr);
- targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
- if ((targ_lun < CTL_MAX_LUNS)
- && (softc->ctl_luns[targ_lun] != NULL))
- lun = softc->ctl_luns[targ_lun];
- else
+ if (targ_lun >= CTL_MAX_LUNS ||
+ (lun = softc->ctl_luns[targ_lun]) == NULL) {
+ mtx_unlock(&softc->ctl_lock);
goto bailout;
-
- initidx = ctl_get_initindex(&io->io_hdr.nexus);
-
+ }
mtx_lock(&lun->lun_lock);
+ mtx_unlock(&softc->ctl_lock);
+
/*
* Already have CA set for this LUN...toss the sense information.
*/
+ initidx = ctl_get_initindex(&io->io_hdr.nexus);
if (ctl_is_set(lun->have_ca, initidx)) {
mtx_unlock(&lun->lun_lock);
goto bailout;
@@ -13393,10 +13152,7 @@ ctl_queue_sense(union ctl_io *io)
mtx_unlock(&lun->lun_lock);
bailout:
- mtx_unlock(&softc->ctl_lock);
-
ctl_free_io(io);
-
return (CTL_RETVAL_COMPLETE);
}
#endif
@@ -13408,7 +13164,7 @@ bailout:
int
ctl_queue(union ctl_io *io)
{
- struct ctl_port *port;
+ struct ctl_port *port = CTL_PORT(io);
CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0]));
@@ -13418,7 +13174,6 @@ ctl_queue(union ctl_io *io)
#endif /* CTL_TIME_IO */
/* Map FE-specific LUN ID into global one. */
- port = ctl_io_port(&io->io_hdr);
io->io_hdr.nexus.targ_mapped_lun =
ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun);
@@ -13451,9 +13206,8 @@ ctl_done_timer_wakeup(void *arg)
void
ctl_serseq_done(union ctl_io *io)
{
- struct ctl_lun *lun;
+ struct ctl_lun *lun = CTL_LUN(io);;
- lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
if (lun->be_lun == NULL ||
lun->be_lun->serseq == CTL_LUN_SERSEQ_OFF)
return;
@@ -13503,9 +13257,7 @@ ctl_done(union ctl_io *io)
if (io->io_hdr.flags & CTL_FLAG_DELAY_DONE) {
io->io_hdr.flags &= ~CTL_FLAG_DELAY_DONE;
} else {
- struct ctl_lun *lun;
-
- lun =(struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ struct ctl_lun *lun = CTL_LUN(io);
if ((lun != NULL)
&& (lun->delay_info.done_delay > 0)) {
@@ -13535,7 +13287,7 @@ ctl_work_thread(void *arg)
CTL_DEBUG_PRINT(("ctl_work_thread starting\n"));
- for (;;) {
+ while (!softc->shutdown) {
/*
* We handle the queues in this order:
* - ISC
@@ -13585,6 +13337,8 @@ ctl_work_thread(void *arg)
/* Sleep until we have something to do. */
mtx_sleep(thr, &thr->queue_lock, PDROP | PRIBIO, "-", 0);
}
+ thr->thread = NULL;
+ kthread_exit();
}
static void
@@ -13595,7 +13349,7 @@ ctl_lun_thread(void *arg)
CTL_DEBUG_PRINT(("ctl_lun_thread starting\n"));
- for (;;) {
+ while (!softc->shutdown) {
mtx_lock(&softc->ctl_lock);
be_lun = STAILQ_FIRST(&softc->pending_lun_queue);
if (be_lun != NULL) {
@@ -13609,6 +13363,8 @@ ctl_lun_thread(void *arg)
mtx_sleep(&softc->pending_lun_queue, &softc->ctl_lock,
PDROP | PRIBIO, "-", 0);
}
+ softc->lun_thread = NULL;
+ kthread_exit();
}
static void
@@ -13624,7 +13380,7 @@ ctl_thresh_thread(void *arg)
CTL_DEBUG_PRINT(("ctl_thresh_thread starting\n"));
- for (;;) {
+ while (!softc->shutdown) {
mtx_lock(&softc->ctl_lock);
STAILQ_FOREACH(lun, &softc->lun_list, links) {
if ((lun->flags & CTL_LUN_DISABLED) ||
@@ -13709,15 +13465,17 @@ ctl_thresh_thread(void *arg)
mtx_lock(&softc->ctl_lock);
}
}
- mtx_unlock(&softc->ctl_lock);
- pause("-", CTL_LBP_PERIOD * hz);
+ mtx_sleep(&softc->thresh_thread, &softc->ctl_lock,
+ PDROP | PRIBIO, "-", CTL_LBP_PERIOD * hz);
}
+ softc->thresh_thread = NULL;
+ kthread_exit();
}
static void
ctl_enqueue_incoming(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_thread *thr;
u_int idx;
@@ -13733,7 +13491,7 @@ ctl_enqueue_incoming(union ctl_io *io)
static void
ctl_enqueue_rtr(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_thread *thr;
thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads];
@@ -13746,7 +13504,7 @@ ctl_enqueue_rtr(union ctl_io *io)
static void
ctl_enqueue_done(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_thread *thr;
thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads];
@@ -13759,7 +13517,7 @@ ctl_enqueue_done(union ctl_io *io)
static void
ctl_enqueue_isc(union ctl_io *io)
{
- struct ctl_softc *softc = control_softc;
+ struct ctl_softc *softc = CTL_SOFTC(io);
struct ctl_thread *thr;
thr = &softc->threads[io->io_hdr.nexus.targ_mapped_lun % worker_threads];
OpenPOWER on IntegriCloud