PERFORCE change 158443 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Feb 28 03:36:07 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=158443
Change 158443 by hselasky at hselasky_laptop001 on 2009/02/28 11:35:07
USB CORE:
- remove redundant iface_index parameter.
- /dev/usb/x.y.z.v is now /dev/usb/x.y.v
- add some extra NULL checks
- simplify /dev/usb/xxx device generation
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_dev.c#4 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_dev.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_device.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_device.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_generic.c#4 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_dev.c#4 (text+ko) ====
@@ -82,7 +82,7 @@
static void usb2_fifo_check_methods(struct usb2_fifo_methods *);
static struct usb2_fifo *usb2_fifo_alloc(void);
static struct usb2_pipe *usb2_dev_get_pipe(struct usb2_device *, uint8_t,
- uint8_t, uint8_t);
+ uint8_t);
static void usb2_loc_fill(struct usb2_fs_privdata *,
struct usb2_cdev_privdata *);
static void usb2_close(void *);
@@ -140,7 +140,6 @@
{
cpd->bus_index = pd->bus_index;
cpd->dev_index = pd->dev_index;
- cpd->iface_index = pd->iface_index;
cpd->ep_addr = pd->ep_addr;
cpd->fifo_index = pd->fifo_index;
}
@@ -238,19 +237,6 @@
}
}
- /* check if we require an interface */
- cpd->iface = usb2_get_iface(cpd->udev, cpd->iface_index);
- if (dev_ep_index != 0) {
- /* non control endpoint - we need an interface */
- if (cpd->iface == NULL) {
- DPRINTFN(2, "no iface\n");
- goto error;
- }
- if (cpd->iface->idesc == NULL) {
- DPRINTFN(2, "no idesc\n");
- goto error;
- }
- }
/* when everything is OK we increment the refcounts */
if (cpd->is_write) {
DPRINTFN(2, "ref write\n");
@@ -394,7 +380,6 @@
struct usb2_device *udev = cpd->udev;
struct usb2_fifo *f;
struct usb2_pipe *pipe;
- uint8_t iface_index = cpd->iface_index;
uint8_t n;
uint8_t is_tx;
uint8_t is_rx;
@@ -449,11 +434,6 @@
/* wrong endpoint index */
continue;
}
- if (ep != 0 &&
- f->iface_index != iface_index) {
- /* wrong interface index */
- continue;
- }
if (f->opened) {
/* FIFO is opened */
is_busy = 1;
@@ -471,11 +451,6 @@
/* wrong endpoint index */
continue;
}
- if (ep != 0 &&
- f->iface_index != iface_index) {
- /* wrong interface index */
- continue;
- }
if (f->opened) {
/* FIFO is opened */
is_busy = 1;
@@ -499,8 +474,8 @@
if (is_tx &&
(udev->fifo[n + USB_FIFO_TX] == NULL)) {
pipe = usb2_dev_get_pipe(udev,
- iface_index, ep, USB_FIFO_TX);
- DPRINTFN(5, "dev_get_pipe(%d, 0x%x, 0x%x)\n", iface_index, ep, USB_FIFO_TX);
+ ep, USB_FIFO_TX);
+ DPRINTFN(5, "dev_get_pipe(%d, 0x%x)\n", ep, USB_FIFO_TX);
if (pipe == NULL) {
DPRINTFN(5, "dev_get_pipe returned NULL\n");
return (EINVAL);
@@ -516,7 +491,7 @@
f->priv_mtx = udev->default_mtx;
f->priv_sc0 = pipe;
f->methods = &usb2_ugen_methods;
- f->iface_index = iface_index;
+ f->iface_index = pipe->iface_index;
f->udev = udev;
mtx_lock(&usb2_ref_lock);
udev->fifo[n + USB_FIFO_TX] = f;
@@ -527,8 +502,8 @@
(udev->fifo[n + USB_FIFO_RX] == NULL)) {
pipe = usb2_dev_get_pipe(udev,
- iface_index, ep, USB_FIFO_RX);
- DPRINTFN(5, "dev_get_pipe(%d, 0x%x, 0x%x)\n", iface_index, ep, USB_FIFO_RX);
+ ep, USB_FIFO_RX);
+ DPRINTFN(5, "dev_get_pipe(%d, 0x%x)\n", ep, USB_FIFO_RX);
if (pipe == NULL) {
DPRINTFN(5, "dev_get_pipe returned NULL\n");
return (EINVAL);
@@ -544,7 +519,7 @@
f->priv_mtx = udev->default_mtx;
f->priv_sc0 = pipe;
f->methods = &usb2_ugen_methods;
- f->iface_index = iface_index;
+ f->iface_index = pipe->iface_index;
f->udev = udev;
mtx_lock(&usb2_ref_lock);
udev->fifo[n + USB_FIFO_RX] = f;
@@ -624,7 +599,7 @@
static struct usb2_pipe *
usb2_dev_get_pipe(struct usb2_device *udev,
- uint8_t iface_index, uint8_t ep_index, uint8_t dir)
+ uint8_t ep_index, uint8_t dir)
{
struct usb2_pipe *pipe;
uint8_t ep_dir;
@@ -656,15 +631,6 @@
/* invalid pipe */
return (NULL);
}
- if (ep_index != 0) {
- if (pipe->iface_index != iface_index) {
- /*
- * Permissions violation - trying to access a
- * pipe that does not belong to the interface.
- */
- return (NULL);
- }
- }
return (pipe); /* success */
}
@@ -1059,7 +1025,12 @@
if (err != 0)
return (err);
- err = usb2_ref_device(cpd, 1);
+ /*
+ * Performance optimistaion: We try to check for IOCTL's that
+ * don't need the USB reference first. Then we grab the USB
+ * reference if we need it!
+ */
+ err = usb2_ref_device(cpd, 0 /* no uref */ );
if (err) {
return (ENXIO);
}
@@ -1719,7 +1690,6 @@
pd = malloc(sizeof(struct usb2_fs_privdata), M_USBDEV, M_WAITOK | M_ZERO);
pd->bus_index = device_get_unit(udev->bus->bdev);
pd->dev_index = udev->device_index;
- pd->iface_index = iface_index;
pd->ep_addr = -1; /* not an endpoint */
pd->fifo_index = f_tx->fifo_index;
pd->mode = FREAD|FWRITE;
==== //depot/projects/usb/src/sys/dev/usb/usb_dev.h#3 (text+ko) ====
@@ -92,7 +92,6 @@
struct usb2_fifo *txfifo;
int bus_index; /* bus index */
int dev_index; /* device index */
- int iface_index; /* interface index */
int ep_addr; /* endpoint address */
uint8_t fifo_index; /* FIFO index */
uint8_t is_read; /* location has read access */
@@ -105,7 +104,6 @@
struct usb2_fs_privdata {
int bus_index;
int dev_index;
- int iface_index;
int ep_addr;
int mode;
int fifo_index;
==== //depot/projects/usb/src/sys/dev/usb/usb_device.c#3 (text+ko) ====
@@ -74,7 +74,7 @@
uint8_t);
static void usb2_notify_addq(const char *type, struct usb2_device *);
static void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t);
-static struct cdev *usb2_make_dev(struct usb2_device *, int, int, int);
+static struct cdev *usb2_make_dev(struct usb2_device *, int, int);
static void usb2_cdev_create(struct usb2_device *);
static void usb2_cdev_free(struct usb2_device *);
static void usb2_cdev_cleanup(void *);
@@ -421,7 +421,6 @@
iface->idesc = id;
iface->alt_index = alt_index;
iface->parent_iface_index = USB_IFACE_INDEX_ANY;
- iface->ep_in_mask = iface->ep_out_mask = 0;
nendpt = id->bNumEndpoints;
DPRINTFN(5, "found idesc nendpt=%d\n", nendpt);
@@ -445,14 +444,6 @@
found:
ed = (void *)desc;
- /* Fill in the endpoint bitmasks */
- if (ed->bEndpointAddress & UE_DIR_IN)
- iface->ep_in_mask |=
- 1 << UE_GET_ADDR(ed->bEndpointAddress);
- else
- iface->ep_out_mask |=
- 1 << UE_GET_ADDR(ed->bEndpointAddress);
-
/* find a free pipe */
while (pipe != pipe_end) {
if (pipe->edesc == NULL) {
@@ -730,7 +721,6 @@
* Free all generic FIFOs for this interface, except control
* endpoint FIFOs:
*/
- usb2_cdev_free(udev);
usb2_fifo_free_wrap(udev, iface_index, 0);
err = usb2_fill_iface_data(udev, iface_index, alt_index);
@@ -740,9 +730,6 @@
err = usb2_req_set_alt_interface_no(udev, NULL, iface_index,
iface->idesc->bAlternateSetting);
- /* create device nodes for each endpoint */
- usb2_cdev_create(udev);
-
done:
if (do_unlock) {
sx_unlock(udev->default_sx + 1);
@@ -1447,7 +1434,7 @@
udev->device_index = device_index;
/* Create the control endpoint device */
- udev->default_dev = usb2_make_dev(udev, 0 , 0, FREAD|FWRITE);
+ udev->default_dev = usb2_make_dev(udev, 0, FREAD|FWRITE);
/* Create a link from /dev/ugenX.X to the default endpoint */
snprintf(udev->ugen_name, sizeof(udev->ugen_name),
USB_GENERIC_NAME "%u.%u", device_get_unit(bus->bdev),
@@ -1720,7 +1707,7 @@
}
static struct cdev *
-usb2_make_dev(struct usb2_device *udev, int iface_index, int ep, int mode)
+usb2_make_dev(struct usb2_device *udev, int ep, int mode)
{
struct usb2_fs_privdata* pd;
char devname[20];
@@ -1730,17 +1717,17 @@
M_WAITOK | M_ZERO);
pd->bus_index = device_get_unit(udev->bus->bdev);
pd->dev_index = udev->device_index;
- pd->iface_index = iface_index;
pd->ep_addr = ep;
pd->mode = mode;
/* Now, create the device itself */
- snprintf(devname, sizeof(devname), "%u.%u.%u.%u",
+ snprintf(devname, sizeof(devname), "%u.%u.%u",
pd->bus_index, pd->dev_index,
- pd->iface_index, pd->ep_addr);
+ pd->ep_addr);
pd->cdev = make_dev(&usb2_devsw, 0, UID_ROOT,
GID_OPERATOR, 0600, USB_DEVICE_DIR "/%s", devname);
- pd->cdev->si_drv1 = pd;
+ if (pd->cdev != NULL)
+ pd->cdev->si_drv1 = pd;
return (pd->cdev);
}
@@ -1748,20 +1735,22 @@
static void
usb2_cdev_create(struct usb2_device *udev)
{
- struct usb2_interface *iface;
+ struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev);
+ struct usb2_endpoint_descriptor *ed;
+ struct usb2_descriptor *desc;
struct usb2_fs_privdata* pd;
struct cdev *dev;
- uint8_t niface;
- int i, ep, mode, inmode, outmode;
+ int inmode;
+ int outmode;
+ int inmask;
+ int outmask;
+ int mode;
+ uint8_t ep;
KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("stale cdev entries"));
DPRINTFN(2, "Creating device nodes\n");
- usb2_interface_count(udev, &niface);
- if (niface == 0)
- return; /* nothing to do */
-
if (usb2_get_mode(udev) == USB_MODE_DEVICE) {
inmode = FWRITE;
outmode = FREAD;
@@ -1770,20 +1759,38 @@
outmode = FWRITE;
}
- for (i = 0; i < niface; i++) {
- iface = usb2_get_iface(udev, i);
- if (iface == NULL)
- break;
+ inmask = 0;
+ outmask = 0;
+ desc = NULL;
+
+ /*
+ * Collect all used endpoint numbers instead of just
+ * generating 16 static endpoints.
+ */
+ while ((desc = usb2_desc_foreach(cd, desc))) {
+ /* filter out all endpoint descriptors */
+ if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
+ (desc->bLength >= sizeof(*ed))) {
+ ed = (struct usb2_endpoint_descriptor *)desc;
+
+ /* update masks */
+ ep = ed->bEndpointAddress;
+ if ((ep & (UE_DIR_OUT|UE_DIR_IN)) == UE_DIR_OUT)
+ outmask |= (1 << (ep & 0x0F));
+ else
+ inmask |= (1 << (ep & 0x0F));
+ }
+ }
- /* Create all available endpoints except EP0 */
- for (ep = 1; ep < 16; ep++) {
- mode = 0;
- mode |= iface->ep_in_mask & (1 << ep) ? inmode : 0;
- mode |= iface->ep_out_mask & (1 << ep) ? outmode : 0;
- if (mode == 0)
- continue; /* no IN or OUT endpoint */
+ /* Create all available endpoints except EP0 */
+ for (ep = 1; ep != 16; ep++) {
+ mode = (inmask & (1 << ep)) ? inmode : 0;
+ mode |= (outmask & (1 << ep)) ? outmode : 0;
+ if (mode == 0)
+ continue; /* no IN or OUT endpoint */
- dev = usb2_make_dev(udev, i , ep, mode);
+ dev = usb2_make_dev(udev, ep, mode);
+ if (dev != NULL) {
pd = dev->si_drv1;
LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next);
}
==== //depot/projects/usb/src/sys/dev/usb/usb_device.h#3 (text+ko) ====
@@ -65,8 +65,6 @@
device_t subdev;
uint8_t alt_index;
uint8_t parent_iface_index;
- uint16_t ep_in_mask; /* bitmask of IN endpoints */
- uint16_t ep_out_mask; /* bitmask of OUT endpoints */
};
/*
==== //depot/projects/usb/src/sys/dev/usb/usb_generic.c#4 (text+ko) ====
More information about the p4-projects
mailing list