Author: ed
Date: Tue Dec 13 21:26:33 2011
New Revision: 228481
URL: http://svn.freebsd.org/changeset/base/228481

Log:
  Change targ(4) to use cdevpriv, instead of multiple character devices.
  
  Also update the manpage and the scsi_target example program accordingly.
  
  Discussed on: scsi@
  Tested by:    Chuck Tuffli <chuck tuffli net>

Modified:
  head/share/examples/scsi_target/scsi_target.c
  head/share/man/man4/targ.4
  head/sys/cam/scsi/scsi_target.c

Modified: head/share/examples/scsi_target/scsi_target.c
==============================================================================
--- head/share/examples/scsi_target/scsi_target.c       Tue Dec 13 20:31:57 
2011        (r228480)
+++ head/share/examples/scsi_target/scsi_target.c       Tue Dec 13 21:26:33 
2011        (r228481)
@@ -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);

Modified: head/share/man/man4/targ.4
==============================================================================
--- head/share/man/man4/targ.4  Tue Dec 13 20:31:57 2011        (r228480)
+++ head/share/man/man4/targ.4  Tue Dec 13 21:26:33 2011        (r228481)
@@ -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 ,

Modified: head/sys/cam/scsi/scsi_target.c
==============================================================================
--- head/sys/cam/scsi/scsi_target.c     Tue Dec 13 20:31:57 2011        
(r228480)
+++ head/sys/cam/scsi/scsi_target.c     Tue Dec 13 21:26:33 2011        
(r228481)
@@ -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_sof
 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, in
        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, 
        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_even
        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 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 *
        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 *u
 
        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__);
-}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to