Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jul 2008 13:46:27 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 145227 for review
Message-ID:  <200807141346.m6EDkR76017081@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145227

Change 145227 by hselasky@hselasky_laptop001 on 2008/07/14 13:45:42

	
	Implement new way to read out USB devices present after
	advice from PHK.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#12 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#17 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#10 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#5 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#10 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#12 (text+ko) ====

@@ -376,7 +376,6 @@
 MALLOC_DECLARE(M_USBHC);
 
 extern struct mtx usb2_ref_lock;
-extern struct mtx usb2_sym_lock;
 
 /* typedefs */
 

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#17 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -87,6 +87,7 @@
 
 static d_fdopen_t usb2_fdopen;
 static d_close_t usb2_close;
+static d_ioctl_t usb2_ioctl;
 
 static fo_rdwr_t usb2_read_f;
 static fo_rdwr_t usb2_write_f;
@@ -113,6 +114,7 @@
 	.d_version = D_VERSION,
 	.d_fdopen = usb2_fdopen,
 	.d_close = usb2_close,
+	.d_ioctl = usb2_ioctl,
 	.d_name = "usb",
 	.d_flags = D_TRACKCLOSE,
 };
@@ -136,9 +138,9 @@
 static void *usb2_old_f_data;
 static struct fileops *usb2_old_f_ops;
 static TAILQ_HEAD(, usb2_symlink) usb2_sym_head;
+static struct sx usb2_sym_lock;
 
 struct mtx usb2_ref_lock;
-struct mtx usb2_sym_lock;
 
 static uint32_t
 usb2_path_convert_one(const char **pp)
@@ -984,7 +986,8 @@
  *	usb2_fdopen - cdev callback
  *------------------------------------------------------------------------*/
 static int
-usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td, struct file *fp)
+usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td,
+    struct file *fp)
 {
 	struct usb2_location loc;
 	uint32_t devloc;
@@ -994,7 +997,7 @@
 	DPRINTF(1, "oflags=0x%08x\n", xxx_oflags);
 
 	devloc = usb2_last_devloc;
-	usb2_last_devloc = (0 - 1);	/* reset "usb2_devloc" */
+	usb2_last_devloc = (0 - 1);	/* reset "usb2_last_devloc" */
 
 	if (fp == NULL) {
 		DPRINTF(1, "fp == NULL\n");
@@ -1021,8 +1024,11 @@
 		/* should not happen */
 		return (EPERM);
 	}
-	if (devloc == (uint32_t)(0 - 1)) {
-		/* tried to open /dev/usb */
+	if (devloc == (uint32_t)(0 - 2)) {
+		/* tried to open "/dev/usb" */
+		return (0);
+	} else if (devloc == (uint32_t)(0 - 1)) {
+		/* tried to open "/dev/usb " */
 		DPRINTF(1, "no devloc\n");
 		return (ENXIO);
 	}
@@ -1090,6 +1096,30 @@
 }
 
 /*------------------------------------------------------------------------*
+ *	usb2_close - cdev callback
+ *------------------------------------------------------------------------*/
+static int
+usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
+    int fflag, struct thread *td)
+{
+	int err;
+
+	switch (cmd) {
+	case USB_READ_DIR:{
+			struct usb2_read_dir *urd = (void *)data;
+
+			err = usb2_read_symlink(urd->urd_data,
+			    urd->urd_startentry, urd->urd_maxlen);
+			break;
+		}
+	default:
+		err = ENOTTY;
+		break;
+	}
+	return (err);
+}
+
+/*------------------------------------------------------------------------*
  *      usb2_clone - cdev callback
  *
  * This function is the kernel clone callback for "/dev/usbX.Y".
@@ -1116,8 +1146,12 @@
 		usb2_last_devloc =
 		    usb2_lookup_symlink(name, namelen);
 	} else {
-		usb2_last_devloc =
-		    usb2_path_convert(name + USB_DNAME_LEN);
+		if (namelen == USB_DNAME_LEN) {
+			usb2_last_devloc = (uint32_t)(0 - 2);
+		} else {
+			usb2_last_devloc =
+			    usb2_path_convert(name + USB_DNAME_LEN);
+		}
 	}
 
 	if (usb2_last_devloc == (uint32_t)(0 - 1)) {
@@ -1133,7 +1167,7 @@
 usb2_dev_init(void *arg)
 {
 	mtx_init(&usb2_ref_lock, "USB ref mutex", NULL, MTX_DEF);
-	mtx_init(&usb2_sym_lock, "USB sym mutex", NULL, MTX_DEF);
+	sx_init(&usb2_sym_lock, "USB sym mutex");
 	TAILQ_INIT(&usb2_sym_head);
 
 	/* check the UGEN methods */
@@ -1146,7 +1180,11 @@
 static void
 usb2_dev_init_post(void *arg)
 {
-	/* create a dummy device so that we are visible */
+	/*
+	 * Create a dummy device so that we are visible. This device
+	 * should never be opened. Therefore a space character is
+	 * appended after the USB device name.
+	 */
 	usb2_dev = make_dev(&usb2_devsw, 0, UID_ROOT, GID_OPERATOR,
 	    0000, USB_DEVICE_NAME " ");
 	if (usb2_dev == NULL) {
@@ -1173,6 +1211,7 @@
 		usb2_dev = NULL;
 	}
 	mtx_destroy(&usb2_ref_lock);
+	sx_destroy(&usb2_sym_lock);
 	return;
 }
 
@@ -2298,9 +2337,9 @@
 	va_end(ap);
 	ps->src_len = strlen(ps->src_path);
 
-	mtx_lock(&usb2_sym_lock);
+	sx_xlock(&usb2_sym_lock);
 	TAILQ_INSERT_TAIL(&usb2_sym_head, ps, sym_entry);
-	mtx_unlock(&usb2_sym_lock);
+	sx_unlock(&usb2_sym_lock);
 	return (ps);
 }
 
@@ -2313,9 +2352,9 @@
 	if (ps == NULL) {
 		return;
 	}
-	mtx_lock(&usb2_sym_lock);
+	sx_xlock(&usb2_sym_lock);
 	TAILQ_REMOVE(&usb2_sym_head, ps, sym_entry);
-	mtx_unlock(&usb2_sym_lock);
+	sx_unlock(&usb2_sym_lock);
 
 	free(ps, M_USBDEV);
 	return;
@@ -2336,7 +2375,7 @@
 	struct usb2_symlink *ps;
 	uint32_t temp;
 
-	mtx_lock(&usb2_sym_lock);
+	sx_xlock(&usb2_sym_lock);
 
 	TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) {
 
@@ -2349,14 +2388,109 @@
 		if (USB_DNAME_LEN > ps->dst_len)
 			continue;
 
-		if (strncmp(ps->dst_path, USB_DEVICE_NAME, USB_DNAME_LEN))
+		if (memcmp(ps->dst_path, USB_DEVICE_NAME, USB_DNAME_LEN))
 			continue;
 
 		temp = usb2_path_convert(ps->dst_path + USB_DNAME_LEN);
-		mtx_unlock(&usb2_sym_lock);
+		sx_unlock(&usb2_sym_lock);
 
 		return (temp);
 	}
-	mtx_unlock(&usb2_sym_lock);
+	sx_unlock(&usb2_sym_lock);
 	return (0 - 1);
 }
+
+/*------------------------------------------------------------------------*
+ *	usb2_read_symlink
+ *
+ * Return value:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+int
+usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len)
+{
+	struct usb2_symlink *ps;
+	uint32_t curoff = 0;
+	uint32_t temp;
+	uint32_t delta = 0;
+	uint8_t len;
+	int error = 0;
+
+	sx_xlock(&usb2_sym_lock);
+
+	TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) {
+
+		temp = ps->src_len + ps->dst_len + 3;
+
+		if (temp > 255) {
+			continue;
+		}
+		if (startentry != 0) {
+			startentry--;
+			curoff += temp;
+			continue;
+		}
+		if (temp > user_len) {
+			/* out of buffer space */
+			break;
+		}
+		len = temp;
+
+		/* copy out total length */
+
+		error = copyout(&len,
+		    USB_ADD_BYTES(user_ptr, delta), 1);
+		if (error) {
+			break;
+		}
+		delta += 1;
+
+		/* copy out source string */
+
+		error = copyout(ps->src_path,
+		    USB_ADD_BYTES(user_ptr, delta), ps->src_len);
+		if (error) {
+			break;
+		}
+		len = 0;
+		delta += ps->src_len;
+		error = copyout(&len,
+		    USB_ADD_BYTES(user_ptr, delta), 1);
+		if (error) {
+			break;
+		}
+		delta += 1;
+
+		/* copy out destination string */
+
+		error = copyout(ps->dst_path,
+		    USB_ADD_BYTES(user_ptr, delta), ps->dst_len);
+		if (error) {
+			break;
+		}
+		len = 0;
+		delta += ps->dst_len;
+		error = copyout(&len,
+		    USB_ADD_BYTES(user_ptr, delta), 1);
+		if (error) {
+			break;
+		}
+		delta += 1;
+
+		curoff += temp;
+		user_len -= temp;
+	}
+
+	/* a zero length entry indicates the end */
+
+	if ((user_len != 0) && (error == 0)) {
+
+		len = 0;
+
+		error = copyout(&len,
+		    USB_ADD_BYTES(user_ptr, delta), 1);
+	}
+	sx_unlock(&usb2_sym_lock);
+	return (error);
+}

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#10 (text+ko) ====

@@ -140,5 +140,6 @@
 struct usb2_symlink *usb2_alloc_symlink(const char *target, const char *fmt,...);
 void	usb2_free_symlink(struct usb2_symlink *ps);
 uint32_t usb2_lookup_symlink(const char *src_ptr, uint8_t src_len);
+int	usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len);
 
 #endif					/* _USB2_DEV_H_ */

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#14 (text+ko) ====

@@ -1327,6 +1327,7 @@
 	udev->depth = depth;
 	udev->bus = bus;
 	udev->address = USB_START_ADDR;	/* default value */
+	udev->plugtime = (uint32_t)ticks;
 
 	/* we are not ready yet */
 	udev->refcount = 1;
@@ -1614,7 +1615,7 @@
 		/* ignore */
 	}
 	udev->ugen_symlink =
-	    make_dev_symlink(scratch_ptr, "ugen%u.%u",
+	    usb2_alloc_symlink(scratch_ptr, "ugen%u.%u",
 	    device_get_unit(udev->bus->bdev),
 	    udev->device_index);
 
@@ -1653,7 +1654,7 @@
 	 * Destroy UGEN symlink, if any
 	 */
 	if (udev->ugen_symlink) {
-		destroy_dev(udev->ugen_symlink);
+		usb2_free_symlink(udev->ugen_symlink);
 		udev->ugen_symlink = NULL;
 	}
 	/*

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#5 (text+ko) ====

@@ -26,6 +26,8 @@
 #ifndef _USB2_DEVICE_H_
 #define	_USB2_DEVICE_H_
 
+struct usb2_symlink;
+
 #define	USB_DEFAULT_XFER_MAX 2
 
 struct usb2_clear_stall_msg {
@@ -108,7 +110,9 @@
 	struct usb2_temp_data *usb2_template_ptr;
 	struct usb2_pipe *pipe_curr;	/* current clear stall pipe */
 	struct usb2_fifo *fifo[USB_FIFO_MAX];
-	struct cdev *ugen_symlink;	/* our generic symlink */
+	struct usb2_symlink *ugen_symlink;	/* our generic symlink */
+
+	uint32_t plugtime;		/* copy of "ticks" */
 
 	uint16_t refcount;
 #define	USB_DEV_REF_MAX 0xffff

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#14 (text+ko) ====

@@ -1890,6 +1890,13 @@
 		error = ugen_re_enumerate(f);
 		break;
 
+	case USB_GET_PLUGTIME:{
+			uint32_t *ptime = addr;
+
+			*ptime = f->udev->plugtime;
+			break;
+		}
+
 		/* ... more IOCTL's to come ! ... --hps */
 
 	default:

==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#10 (text+ko) ====

@@ -32,6 +32,12 @@
 
 #define	USB_DEVICE_NAME "usb"
 
+struct usb2_read_dir {
+	void   *urd_data;
+	uint32_t urd_startentry;
+	uint32_t urd_maxlen;
+};
+
 struct usb2_ctl_request {
 	void   *ucr_data;
 	uint16_t ucr_flags;
@@ -214,6 +220,8 @@
 #define	USB_RELEASE_INTERFACE	_IOW ('U', 123, int)
 #define	USB_IFACE_DRIVER_ACTIVE	_IOW ('U', 124, int)
 #define	USB_IFACE_DRIVER_DETACH	_IOW ('U', 125, int)
+#define	USB_GET_PLUGTIME	_IOR ('U', 126, uint32_t)
+#define	USB_READ_DIR		_IOW ('U', 127, struct usb2_read_dir)
 
 /* Modem device */
 #define	USB_GET_CM_OVER_DATA	_IOR ('U', 130, int)



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