summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/examples/scsi_target/scsi_target.c16
-rw-r--r--share/man/man4/targ.418
-rw-r--r--sys/cam/scsi/scsi_target.c159
3 files changed, 53 insertions, 140 deletions
diff --git a/share/examples/scsi_target/scsi_target.c b/share/examples/scsi_target/scsi_target.c
index e6ff5c71..6f665af 100644
--- a/share/examples/scsi_target/scsi_target.c
+++ b/share/examples/scsi_target/scsi_target.c
@@ -100,8 +100,8 @@ static void usage(void);
int
main(int argc, char *argv[])
{
- int ch, unit;
- char *file_name, targname[16];
+ int ch;
+ char *file_name;
u_int16_t req_flags, sim_flags;
off_t user_size;
@@ -283,17 +283,11 @@ main(int argc, char *argv[])
warnx("aio support tested ok");
}
- /* Go through all the control devices and find one that isn't busy. */
- unit = 0;
- do {
- snprintf(targname, sizeof(targname), "/dev/targ%d", unit++);
- targ_fd = open(targname, O_RDWR);
- } while (targ_fd < 0 && errno == EBUSY);
-
+ targ_fd = open("/dev/targ", O_RDWR);
if (targ_fd < 0)
- errx(1, "Tried to open %d devices, none available", unit);
+ err(1, "/dev/targ");
else
- warnx("opened %s", targname);
+ warnx("opened /dev/targ");
/* The first three are handled by kevent() later */
signal(SIGHUP, SIG_IGN);
diff --git a/share/man/man4/targ.4 b/share/man/man4/targ.4
index 5e78200..6c61735 100644
--- a/share/man/man4/targ.4
+++ b/share/man/man4/targ.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 15, 2002
+.Dd December 13, 2011
.Dt TARG 4
.Os
.Sh NAME
@@ -49,16 +49,8 @@ can be found in
.Pp
The
.Nm
-driver supplies control devices,
-.Pa /dev/targ0 ,
-.Pa /dev/targ1 ,
-etc.
-If a device is already in use,
-.Xr open 2
-will fail and
-.Va errno
-will be set to
-.Er EBUSY .
+driver supplies the control device
+.Pa /dev/targ .
After opening the device, the file descriptor must be bound to a
specific bus/target/LUN and enabled to process CCBs using the
.Dv TARGIOCENABLE
@@ -123,8 +115,8 @@ it.
describes the usermode interface.
.It Pa /sys/cam/scsi/scsi_target.c
is the driver source file.
-.It Pa /dev/targ*
-are the control devices.
+.It Pa /dev/targ
+is the control device.
.El
.Sh SEE ALSO
.Pa /usr/share/examples/scsi_target ,
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index e16186a..65f2388 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -96,12 +96,9 @@ struct targ_softc {
targ_state state;
struct selinfo read_select;
struct devstat device_stats;
- struct callout destroy_dev_callout;
- struct mtx destroy_mtx;
};
static d_open_t targopen;
-static d_close_t targclose;
static d_read_t targread;
static d_write_t targwrite;
static d_ioctl_t targioctl;
@@ -119,7 +116,6 @@ static struct cdevsw targ_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = targopen,
- .d_close = targclose,
.d_read = targread,
.d_write = targwrite,
.d_ioctl = targioctl,
@@ -152,15 +148,12 @@ static void targfreeccb(struct targ_softc *softc, union ccb *ccb);
static struct targ_cmd_descr *
targgetdescr(struct targ_softc *softc);
static periph_init_t targinit;
-static void targclone(void *arg, struct ucred *cred, char *name,
- int namelen, struct cdev **dev);
static void targasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg);
static void abort_all_pending(struct targ_softc *softc);
static void notify_user(struct targ_softc *softc);
static int targcamstatus(cam_status status);
static size_t targccblen(xpt_opcode func_code);
-static void targdestroy(void *);
static struct periph_driver targdriver =
{
@@ -171,66 +164,18 @@ PERIPHDRIVER_DECLARE(targ, targdriver);
static MALLOC_DEFINE(M_TARG, "TARG", "TARG data");
-/*
- * Create softc and initialize it. Only one proc can open each targ device.
- * There is no locking here because a periph doesn't get created until an
- * ioctl is issued to do so, and that can't happen until this method returns.
- */
-static int
-targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- struct targ_softc *softc;
-
- if (dev->si_drv1 != 0) {
- return (EBUSY);
- }
-
- /* Mark device busy before any potentially blocking operations */
- dev->si_drv1 = (void *)~0;
-
- /* Create the targ device, allocate its softc, initialize it */
- if ((dev->si_flags & SI_NAMED) == 0) {
- make_dev(&targ_cdevsw, dev2unit(dev), UID_ROOT, GID_WHEEL, 0600,
- "targ%d", dev2unit(dev));
- }
- softc = malloc(sizeof(*softc), M_TARG,
- M_WAITOK | M_ZERO);
- dev->si_drv1 = softc;
- softc->state = TARG_STATE_OPENED;
- softc->periph = NULL;
- softc->path = NULL;
-
- TAILQ_INIT(&softc->pending_ccb_queue);
- TAILQ_INIT(&softc->work_queue);
- TAILQ_INIT(&softc->abort_queue);
- TAILQ_INIT(&softc->user_ccb_queue);
- knlist_init_mtx(&softc->read_select.si_note, NULL);
-
- return (0);
-}
-
/* Disable LUN if enabled and teardown softc */
-static int
-targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
+static void
+targcdevdtor(void *data)
{
- struct targ_softc *softc;
- struct cam_periph *periph;
- int error;
+ struct targ_softc *softc;
+ struct cam_periph *periph;
- softc = (struct targ_softc *)dev->si_drv1;
- mtx_init(&softc->destroy_mtx, "targ_destroy", "SCSI Target dev destroy", MTX_DEF);
- callout_init_mtx(&softc->destroy_dev_callout, &softc->destroy_mtx, CALLOUT_RETURNUNLOCKED);
+ softc = data;
if (softc->periph == NULL) {
-#if 0
- destroy_dev(dev);
- free(softc, M_TARG);
-#endif
printf("%s: destroying non-enabled target\n", __func__);
- mtx_lock(&softc->destroy_mtx);
- callout_reset(&softc->destroy_dev_callout, hz / 2,
- (void *)targdestroy, (void *)dev);
- mtx_unlock(&softc->destroy_mtx);
- return (0);
+ free(softc, M_TARG);
+ return;
}
/*
@@ -240,25 +185,41 @@ targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
periph = softc->periph;
cam_periph_acquire(periph);
cam_periph_lock(periph);
- error = targdisable(softc);
+ (void)targdisable(softc);
if (softc->periph != NULL) {
cam_periph_invalidate(softc->periph);
softc->periph = NULL;
}
cam_periph_unlock(periph);
cam_periph_release(periph);
-
-#if 0
- destroy_dev(dev);
free(softc, M_TARG);
-#endif
+}
- printf("%s: close finished error(%d)\n", __func__, error);
- mtx_lock(&softc->destroy_mtx);
- callout_reset(&softc->destroy_dev_callout, hz / 2,
- (void *)targdestroy, (void *)dev);
- mtx_unlock(&softc->destroy_mtx);
- return (error);
+/*
+ * Create softc and initialize it. There is no locking here because a
+ * periph doesn't get created until an ioctl is issued to do so, and
+ * that can't happen until this method returns.
+ */
+static int
+targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
+{
+ struct targ_softc *softc;
+
+ /* Allocate its softc, initialize it */
+ softc = malloc(sizeof(*softc), M_TARG,
+ M_WAITOK | M_ZERO);
+ softc->state = TARG_STATE_OPENED;
+ softc->periph = NULL;
+ softc->path = NULL;
+
+ TAILQ_INIT(&softc->pending_ccb_queue);
+ TAILQ_INIT(&softc->work_queue);
+ TAILQ_INIT(&softc->abort_queue);
+ TAILQ_INIT(&softc->user_ccb_queue);
+ knlist_init_mtx(&softc->read_select.si_note, NULL);
+
+ devfs_set_cdevpriv(softc, targcdevdtor);
+ return (0);
}
/* Enable/disable LUNs, set debugging level */
@@ -268,7 +229,7 @@ targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t
struct targ_softc *softc;
cam_status status;
- softc = (struct targ_softc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&softc);
switch (cmd) {
case TARGIOCENABLE:
@@ -346,7 +307,7 @@ targpoll(struct cdev *dev, int poll_events, struct thread *td)
struct targ_softc *softc;
int revents;
- softc = (struct targ_softc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&softc);
/* Poll for write() is always ok. */
revents = poll_events & (POLLOUT | POLLWRNORM);
@@ -371,7 +332,7 @@ targkqfilter(struct cdev *dev, struct knote *kn)
{
struct targ_softc *softc;
- softc = (struct targ_softc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&softc);
kn->kn_hook = (caddr_t)softc;
kn->kn_fop = &targread_filtops;
knlist_add(&softc->read_select.si_note, kn, 0);
@@ -572,7 +533,7 @@ targwrite(struct cdev *dev, struct uio *uio, int ioflag)
int write_len, error;
int func_code, priority;
- softc = (struct targ_softc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&softc);
write_len = error = 0;
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
("write - uio_resid %zd\n", uio->uio_resid));
@@ -866,7 +827,7 @@ targread(struct cdev *dev, struct uio *uio, int ioflag)
error = 0;
read_len = 0;
- softc = (struct targ_softc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&softc);
user_queue = &softc->user_ccb_queue;
abort_queue = &softc->abort_queue;
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targread\n"));
@@ -1051,23 +1012,11 @@ targgetdescr(struct targ_softc *softc)
static void
targinit(void)
{
- EVENTHANDLER_REGISTER(dev_clone, targclone, 0, 1000);
-}
-
-static void
-targclone(void *arg, struct ucred *cred, char *name, int namelen,
- struct cdev **dev)
-{
- int u;
+ struct cdev *dev;
- if (*dev != NULL)
- return;
- if (dev_stdclone(name, NULL, "targ", &u) != 1)
- return;
- *dev = make_dev(&targ_cdevsw, u, UID_ROOT, GID_WHEEL,
- 0600, "targ%d", u);
- dev_ref(*dev);
- (*dev)->si_flags |= SI_CHEAPCLONE;
+ /* Add symbolic link to targ0 for compatibility. */
+ dev = make_dev(&targ_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "targ");
+ make_dev_alias(dev, "targ0");
}
static void
@@ -1221,25 +1170,3 @@ targccblen(xpt_opcode func_code)
return (len);
}
-
-/*
- * work around to destroy targ device
- * outside of targclose
- */
-static void
-targdestroy(void *dev)
-{
- struct cdev *device = (struct cdev *)dev;
- struct targ_softc *softc = (struct targ_softc *)device->si_drv1;
-
-#if 0
- callout_stop(&softc->destroy_dev_callout);
-#endif
-
- mtx_unlock(&softc->destroy_mtx);
- mtx_destroy(&softc->destroy_mtx);
- free(softc, M_TARG);
- device->si_drv1 = 0;
- destroy_dev(device);
- printf("%s: destroyed dev\n", __func__);
-}
OpenPOWER on IntegriCloud