PERFORCE change 145227 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jul 14 13:46:28 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145227
Change 145227 by hselasky at 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)
More information about the p4-projects
mailing list