Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Dec 2011 20:57:02 +0100
From:      Ed Schouten <ed@80386.nl>
To:        scsi@freebsd.org
Subject:   Use cdevpriv in targ(4)
Message-ID:  <20111206195702.GF59489@hoeg.nl>

next in thread | raw e-mail | index | archive | help

--9sSKoi6Rw660DLir
Content-Type: multipart/mixed; boundary="bO4vSxwwZtUjUWHo"
Content-Disposition: inline


--bO4vSxwwZtUjUWHo
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hello all,

I sent this patch to mjacob@ previously, but he redirected me to this
list, so here it goes.

The other day I spent some time grepping through character device/devfs
code and I noticed we can make the targ(4) driver a lot more beautiful
if we simply change the code to use a single device node (/dev/targ) and
use per-file descriptor data, instead of hacking around with clonelists.

As I have no idea how to actually test and use targ(4), so is there a
way I can persuade any of you to test/debug this patch for me?

Thanks,
--=20
 Ed Schouten <ed@80386.nl>
 WWW: http://80386.nl/

--bO4vSxwwZtUjUWHo
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="targ.diff"
Content-Transfer-Encoding: quoted-printable

Index: sys/cam/scsi/scsi_target.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- sys/cam/scsi/scsi_target.c	(revision 228283)
+++ sys/cam/scsi/scsi_target.c	(working copy)
@@ -96,12 +96,9 @@
 	targ_state		 state;
 	struct selinfo		 read_select;
 	struct devstat		 device_stats;
-	struct callout		destroy_dev_callout;
-	struct mtx		destroy_mtx;
 };
=20
 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 @@
 	.d_version =3D	D_VERSION,
 	.d_flags =3D	D_NEEDGIANT,
 	.d_open =3D	targopen,
-	.d_close =3D	targclose,
 	.d_read =3D	targread,
 	.d_write =3D	targwrite,
 	.d_ioctl =3D	targioctl,
@@ -152,15 +148,12 @@
 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 *);
=20
 static struct periph_driver targdriver =3D
 {
@@ -171,66 +164,18 @@
=20
 static MALLOC_DEFINE(M_TARG, "TARG", "TARG data");
=20
-/*
- * 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 retur=
ns.
- */
-static int
-targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
+/* Disable LUN if enabled and teardown softc */
+static void
+targcdevdtor(void *data)
 {
 	struct targ_softc *softc;
+	struct cam_periph *periph;
=20
-	if (dev->si_drv1 !=3D 0) {
-		return (EBUSY);
-	}
-=09
-	/* Mark device busy before any potentially blocking operations */
-	dev->si_drv1 =3D (void *)~0;
-
-	/* Create the targ device, allocate its softc, initialize it */
-	if ((dev->si_flags & SI_NAMED) =3D=3D 0) {
-		make_dev(&targ_cdevsw, dev2unit(dev), UID_ROOT, GID_WHEEL, 0600,
-			 "targ%d", dev2unit(dev));
-	}
-	softc =3D malloc(sizeof(*softc), M_TARG,
-	       M_WAITOK | M_ZERO);
-	dev->si_drv1 =3D softc;
-	softc->state =3D TARG_STATE_OPENED;
-	softc->periph =3D NULL;
-	softc->path =3D 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)
-{
-	struct targ_softc     *softc;
-	struct cam_periph     *periph;
-	int    error;
-
-	softc =3D (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, CALLO=
UT_RETURNUNLOCKED);
+	softc =3D data;
 	if (softc->periph =3D=3D NULL) {
-#if 0
-		destroy_dev(dev);
+		printf("%s: destroying non-enabled target\n", __func__);
 		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);
+		return;
 	}
=20
 	/*
@@ -240,25 +185,41 @@
 	periph =3D softc->periph;
 	cam_periph_acquire(periph);
 	cam_periph_lock(periph);
-	error =3D targdisable(softc);
+	(void)targdisable(softc);
 	if (softc->periph !=3D NULL) {
 		cam_periph_invalidate(softc->periph);
 		softc->periph =3D NULL;
 	}
 	cam_periph_unlock(periph);
 	cam_periph_release(periph);
-
-#if 0
-	destroy_dev(dev);
 	free(softc, M_TARG);
-#endif
+}
=20
-	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 =3D malloc(sizeof(*softc), M_TARG,
+	       M_WAITOK | M_ZERO);
+	softc->state =3D TARG_STATE_OPENED;
+	softc->periph =3D NULL;
+	softc->path =3D 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);
 }
=20
 /* Enable/disable LUNs, set debugging level */
@@ -268,7 +229,7 @@
 	struct targ_softc *softc;
 	cam_status	   status;
=20
-	softc =3D (struct targ_softc *)dev->si_drv1;
+	devfs_get_cdevpriv((void **)&softc);
=20
 	switch (cmd) {
 	case TARGIOCENABLE:
@@ -346,7 +307,7 @@
 	struct targ_softc *softc;
 	int	revents;
=20
-	softc =3D (struct targ_softc *)dev->si_drv1;
+	devfs_get_cdevpriv((void **)&softc);
=20
 	/* Poll for write() is always ok. */
 	revents =3D poll_events & (POLLOUT | POLLWRNORM);
@@ -371,7 +332,7 @@
 {
 	struct  targ_softc *softc;
=20
-	softc =3D (struct targ_softc *)dev->si_drv1;
+	devfs_get_cdevpriv((void **)&softc);
 	kn->kn_hook =3D (caddr_t)softc;
 	kn->kn_fop =3D &targread_filtops;
 	knlist_add(&softc->read_select.si_note, kn, 0);
@@ -572,7 +533,7 @@
 	int write_len, error;
 	int func_code, priority;
=20
-	softc =3D (struct targ_softc *)dev->si_drv1;
+	devfs_get_cdevpriv((void **)&softc);
 	write_len =3D error =3D 0;
 	CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
 		  ("write - uio_resid %zd\n", uio->uio_resid));
@@ -866,7 +827,7 @@
=20
 	error =3D 0;
 	read_len =3D 0;
-	softc =3D (struct targ_softc *)dev->si_drv1;
+	devfs_get_cdevpriv((void **)&softc);
 	user_queue =3D &softc->user_ccb_queue;
 	abort_queue =3D &softc->abort_queue;
 	CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targread\n"));
@@ -1051,23 +1012,11 @@
 static void
 targinit(void)
 {
-	EVENTHANDLER_REGISTER(dev_clone, targclone, 0, 1000);
-}
+	struct cdev *dev;
=20
-static void
-targclone(void *arg, struct ucred *cred, char *name, int namelen,
-    struct cdev **dev)
-{
-	int u;
-
-	if (*dev !=3D NULL)
-		return;
-	if (dev_stdclone(name, NULL, "targ", &u) !=3D 1)
-		return;
-	*dev =3D make_dev(&targ_cdevsw, u, UID_ROOT, GID_WHEEL,
-			0600, "targ%d", u);
-	dev_ref(*dev);
-	(*dev)->si_flags |=3D SI_CHEAPCLONE;
+	/* Add symbolic link to targ0 for compatibility. */
+	dev =3D make_dev(&targ_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "targ");
+	make_dev_alias(dev, "targ0");
 }
=20
 static void
@@ -1221,25 +1170,3 @@
=20
 	return (len);
 }
-
-/*
- * work around to destroy targ device
- * outside of targclose
- */
-static void
-targdestroy(void *dev)
-{
-	struct cdev *device =3D (struct cdev *)dev;
-	struct targ_softc *softc =3D (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 =3D 0;
-	destroy_dev(device);
-	printf("%s: destroyed dev\n", __func__);
-}

--bO4vSxwwZtUjUWHo--

--9sSKoi6Rw660DLir
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iQIcBAEBAgAGBQJO3nOOAAoJEG5e2P40kaK77/8QAKSa9NSr8zLik8pk40h5jPgu
wTgN6HCDx0pmVAmLWIMavTdF4hI8b17KMPPXHLSjq2f906LJKN4XUU9qsddbSWWo
SICc5gHZbM4DOAQ3x7PIhgNP8tYvufcHlaxdPCg3jr1N3RG6qCCwXxEgiTvDTY7a
ii+oupE7QV/rIy8qyGdm4nGg5RQ5qZZ1L7Jv1c3RTk/pwIx8Yd9kc4iZc3Bw7V3P
NyrHgxk7lZuIHj/LYT6l5fc6XRdwILgD94kgPIRb9lbZLhgP7UAHfXaDK2YWgMVO
BBEtkIE58/d+9SinxMt6SpzuI+Fiy5kgFWTa3aJS3wL/ezH1DldovaXxg88D9ANm
6Tnp09DIap/vnnmJsI1N7jkVm0axxAr7i/bZr7kW5Nk9aCBII07AZ3zhg+fjuMPT
Kn/Z61UornBZSN9li6KredCEpiXD9HlKOpdkSyEAlF/2EUD4IiW6KhlFq8a4ikik
zujBIYZ49b1dbircZWqD1plWiPX4XewTro0c8J7aY2muLUJiOT3S+BzJnXE2FWCM
U41RQ2/BdtE4G6H10jCsRNGFcgHgfE8S6iXtpILtpfBO5z2Nt7F3aZ4WQVm0rRd7
S088mi93Qj7yGu7fzj/fbVRUvHXGlSjuksquKt27UtisYmU7ngkFCbu+xPUte2Yt
y/0oShRgRG5n3wiD0Lrp
=f6Rg
-----END PGP SIGNATURE-----

--9sSKoi6Rw660DLir--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111206195702.GF59489>