Skip to content

Commit

Permalink
Make it possible to build CTL as a module.
Browse files Browse the repository at this point in the history
Reviewed by:	ken
Sponsored by:	FreeBSD Foundation
  • Loading branch information
trasz committed Apr 2, 2013
1 parent bd84789 commit 124d4c1
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 32 deletions.
1 change: 1 addition & 0 deletions share/man/man4/Makefile
Expand Up @@ -99,6 +99,7 @@ MAN= aac.4 \
${_cpuctl.4} \
cpufreq.4 \
crypto.4 \
ctl.4 \
cue.4 \
cxgb.4 \
cxgbe.4 \
Expand Down
90 changes: 90 additions & 0 deletions share/man/man4/ctl.4
@@ -0,0 +1,90 @@
.\" Copyright (c) 2013 Edward Tomasz Napierala
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.Dd March 8, 2013
.Dt CTL 4
.Os
.Sh NAME
.Nm ctl
.Nd CAM Target Layer
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following line in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device ctl"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
ctl_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
subsystem provides SCSI disk and processor emulation.
It supports features such as:
.Pp
.Bl -bullet -compact
.It
Disk and processor device emulation
.It
Tagged queueing
.It
SCSI task attribute support (ordered, head of queue, simple tags)
.It
SCSI implicit command ordering support.
.It
Full task management support (abort, LUN reset, target reset, etc.)
.It
Support for multiple ports
.It
Support for multiple simultaneous initiators
.It
Support for multiple simultaneous backing stores
.It
Persistent reservation support
.It
Mode sense/select support
.It
Error injection support
.It
All I/O handled in-kernel, no userland context switch overhead
.El
.Sh SEE ALSO
.Xr ctladm 8 ,
.Xr ctlstat 8
.Sh HISTORY
The
.Nm
subsystem first appeared in
.Fx 9.1 .
.Sh AUTHORS
The
.Nm
subsystem was written by
.An Kenneth Merry Aq ken@FreeBSD.org .
3 changes: 0 additions & 3 deletions sys/cam/ctl/README.ctl.txt
Expand Up @@ -227,9 +227,6 @@ Revision 1.2 Changes
To Do List:
==========

- Make CTL buildable as a module. Work needs to be done on initialization,
and on freeing resources and LUNs when it is built as a module.

- Use devstat(9) for CTL's statistics collection. CTL uses a home-grown
statistics collection system that is similar to devstat(9). ctlstat
should be retired in favor of iostat, etc., once aggregation modes are
Expand Down
56 changes: 39 additions & 17 deletions sys/cam/ctl/ctl.c
Expand Up @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bio.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/malloc.h>
Expand Down Expand Up @@ -338,7 +339,7 @@ TUNABLE_INT("kern.cam.ctl.disable", &ctl_disable);
static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event,
int param);
static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest);
static void ctl_init(void);
static int ctl_init(void);
void 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);
Expand Down Expand Up @@ -458,11 +459,16 @@ static struct cdevsw ctl_cdevsw = {

MALLOC_DEFINE(M_CTL, "ctlmem", "Memory used for CTL");

/*
* If we have the CAM SIM, we may or may not have another SIM that will
* cause CTL to get initialized. If not, we need to initialize it.
*/
SYSINIT(ctl_init, SI_SUB_CONFIGURE, SI_ORDER_THIRD, ctl_init, NULL);
static int ctl_module_event_handler(module_t, int /*modeventtype_t*/, void *);

static moduledata_t ctl_moduledata = {
"ctl",
ctl_module_event_handler,
NULL
};

DECLARE_MODULE(ctl, ctl_moduledata, SI_SUB_CONFIGURE, SI_ORDER_THIRD);
MODULE_VERSION(ctl, 1);

static void
ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc,
Expand Down Expand Up @@ -942,7 +948,7 @@ ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest)
dest->io_hdr.status = src->hdr.status;
}

static void
static int
ctl_init(void)
{
struct ctl_softc *softc;
Expand All @@ -953,7 +959,7 @@ ctl_init(void)
#if 0
int i;
#endif
int retval;
int error, retval;
//int isc_retval;

retval = 0;
Expand All @@ -962,7 +968,7 @@ ctl_init(void)

/* If we're disabled, don't initialize. */
if (ctl_disable != 0)
return;
return (0);

control_softc = malloc(sizeof(*control_softc), M_DEVBUF,
M_WAITOK | M_ZERO);
Expand Down Expand Up @@ -991,7 +997,7 @@ ctl_init(void)
destroy_dev(softc->dev);
free(control_softc, M_DEVBUF);
control_softc = NULL;
return;
return (ENOMEM);
}

SYSCTL_ADD_INT(&softc->sysctl_ctx,
Expand Down Expand Up @@ -1053,15 +1059,15 @@ ctl_init(void)
&internal_pool)!= 0){
printf("ctl: can't allocate %d entry internal pool, "
"exiting\n", CTL_POOL_ENTRIES_INTERNAL);
return;
return (ENOMEM);
}

if (ctl_pool_create(softc, CTL_POOL_EMERGENCY,
CTL_POOL_ENTRIES_EMERGENCY, &emergency_pool) != 0) {
printf("ctl: can't allocate %d entry emergency pool, "
"exiting\n", CTL_POOL_ENTRIES_EMERGENCY);
ctl_pool_free(softc, internal_pool);
return;
return (ENOMEM);
}

if (ctl_pool_create(softc, CTL_POOL_4OTHERSC, CTL_POOL_ENTRIES_OTHER_SC,
Expand All @@ -1071,7 +1077,7 @@ ctl_init(void)
"exiting\n", CTL_POOL_ENTRIES_OTHER_SC);
ctl_pool_free(softc, internal_pool);
ctl_pool_free(softc, emergency_pool);
return;
return (ENOMEM);
}

softc->internal_pool = internal_pool;
Expand All @@ -1092,14 +1098,15 @@ ctl_init(void)
mtx_unlock(&softc->ctl_lock);
#endif

if (kproc_create(ctl_work_thread, softc, &softc->work_thread, 0, 0,
"ctl_thrd") != 0) {
error = kproc_create(ctl_work_thread, softc, &softc->work_thread, 0, 0,
"ctl_thrd");
if (error != 0) {
printf("error creating CTL work thread!\n");
ctl_free_lun(lun);
ctl_pool_free(softc, internal_pool);
ctl_pool_free(softc, emergency_pool);
ctl_pool_free(softc, other_pool);
return;
return (error);
}
printf("ctl: CAM Target Layer loaded\n");

Expand Down Expand Up @@ -1139,10 +1146,11 @@ ctl_init(void)
if (sizeof(struct callout) > CTL_TIMER_BYTES) {
printf("sizeof(struct callout) %zd > CTL_TIMER_BYTES %zd\n",
sizeof(struct callout), CTL_TIMER_BYTES);
return;
return (EINVAL);
}
#endif /* CTL_IO_DELAY */

return (0);
}

void
Expand Down Expand Up @@ -1199,6 +1207,20 @@ ctl_shutdown(void)
printf("ctl: CAM Target Layer unloaded\n");
}

static int
ctl_module_event_handler(module_t mod, int what, void *arg)
{

switch (what) {
case MOD_LOAD:
return (ctl_init());
case MOD_UNLOAD:
return (EBUSY);
default:
return (EOPNOTSUPP);
}
}

/*
* XXX KDM should we do some access checks here? Bump a reference count to
* prevent a CTL module from being unloaded while someone has it open?
Expand Down
31 changes: 28 additions & 3 deletions sys/cam/ctl/ctl_frontend_cam_sim.c
Expand Up @@ -121,12 +121,23 @@ struct cfcs_softc cfcs_softc;
static int cfcs_max_sense = sizeof(struct scsi_sense_data);
extern int ctl_disable;

SYSINIT(cfcs_init, SI_SUB_CONFIGURE, SI_ORDER_FOURTH, cfcs_init, NULL);
SYSCTL_NODE(_kern_cam, OID_AUTO, ctl2cam, CTLFLAG_RD, 0,
"CAM Target Layer SIM frontend");
SYSCTL_INT(_kern_cam_ctl2cam, OID_AUTO, max_sense, CTLFLAG_RW,
&cfcs_max_sense, 0, "Maximum sense data size");

static int cfcs_module_event_handler(module_t, int /*modeventtype_t*/, void *);

static moduledata_t cfcs_moduledata = {
"ctlcfcs",
cfcs_module_event_handler,
NULL
};

DECLARE_MODULE(ctlcfcs, cfcs_moduledata, SI_SUB_CONFIGURE, SI_ORDER_FOURTH);
MODULE_VERSION(ctlcfcs, 1);
MODULE_DEPEND(ctlcfi, ctl, 1, 1, 1);
MODULE_DEPEND(ctlcfi, cam, 1, 1, 1);

int
cfcs_init(void)
Expand Down Expand Up @@ -176,7 +187,7 @@ cfcs_init(void)
printf("%s: ctl_frontend_register() failed with error %d!\n",
__func__, retval);
mtx_destroy(&softc->lock);
return (1);
return (retval);
}

/*
Expand Down Expand Up @@ -236,7 +247,7 @@ cfcs_init(void)
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
printf("%s: error creating path\n", __func__);
xpt_bus_deregister(cam_sim_path(softc->sim));
retval = 1;
retval = EINVAL;
goto bailout;
}

Expand Down Expand Up @@ -274,6 +285,20 @@ cfcs_shutdown(void)

}

static int
cfcs_module_event_handler(module_t mod, int what, void *arg)
{

switch (what) {
case MOD_LOAD:
return (cfcs_init());
case MOD_UNLOAD:
return (EBUSY);
default:
return (EOPNOTSUPP);
}
}

static void
cfcs_onoffline(void *arg, int online)
{
Expand Down

0 comments on commit 124d4c1

Please sign in to comment.