- Remove the usb interface number from the device nodes as it is not needed.
- Do not recreate the device nodes in set_alt_interface as the endpoints do not change. Submitted by: Hans Petter Selasky
This commit is contained in:
parent
802cb57e34
commit
f5f145ba07
@ -82,7 +82,7 @@ static int usb2_fifo_uiomove(struct usb2_fifo *, void *, int,
|
||||
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 @@ usb2_loc_fill(struct usb2_fs_privdata* pd, struct usb2_cdev_privdata *cpd)
|
||||
{
|
||||
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 @@ usb2_ref_device(struct usb2_cdev_privdata* cpd, int need_uref)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
/* 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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
/* 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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
(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 @@ usb2_fifo_create(struct usb2_cdev_privdata *cpd)
|
||||
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 @@ usb2_fifo_free(struct usb2_fifo *f)
|
||||
|
||||
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 @@ usb2_dev_get_pipe(struct usb2_device *udev,
|
||||
/* 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 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
|
||||
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 @@ usb2_fifo_attach(struct usb2_device *udev, void *priv_sc,
|
||||
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;
|
||||
|
@ -92,7 +92,6 @@ struct usb2_cdev_privdata {
|
||||
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_cdev_privdata {
|
||||
struct usb2_fs_privdata {
|
||||
int bus_index;
|
||||
int dev_index;
|
||||
int iface_index;
|
||||
int ep_addr;
|
||||
int mode;
|
||||
int fifo_index;
|
||||
|
@ -74,7 +74,7 @@ static usb2_error_t usb2_fill_iface_data(struct usb2_device *, uint8_t,
|
||||
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 @@ usb2_fill_iface_data(struct usb2_device *udev,
|
||||
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 @@ usb2_fill_iface_data(struct usb2_device *udev,
|
||||
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 @@ usb2_set_alt_interface_index(struct usb2_device *udev,
|
||||
* 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 @@ usb2_set_alt_interface_index(struct usb2_device *udev,
|
||||
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 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
|
||||
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 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
|
||||
}
|
||||
|
||||
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,14 +1717,13 @@ usb2_make_dev(struct usb2_device *udev, int iface_index, int ep, int mode)
|
||||
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;
|
||||
@ -1748,20 +1734,18 @@ usb2_make_dev(struct usb2_device *udev, int iface_index, int ep, int mode)
|
||||
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, outmode, inmask, outmask, 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,24 +1754,40 @@ usb2_cdev_create(struct usb2_device *udev)
|
||||
outmode = FWRITE;
|
||||
}
|
||||
|
||||
for (i = 0; i < niface; i++) {
|
||||
iface = usb2_get_iface(udev, i);
|
||||
if (iface == NULL)
|
||||
break;
|
||||
inmask = 0;
|
||||
outmask = 0;
|
||||
desc = NULL;
|
||||
|
||||
/* 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 */
|
||||
/*
|
||||
* 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;
|
||||
|
||||
dev = usb2_make_dev(udev, i , ep, mode);
|
||||
pd = dev->si_drv1;
|
||||
LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next);
|
||||
/* update masks */
|
||||
ep = ed->bEndpointAddress;
|
||||
if (UE_GET_DIR(ep) == UE_DIR_OUT)
|
||||
outmask |= 1 << UE_GET_ADDR(ep);
|
||||
else
|
||||
inmask |= 1 << UE_GET_ADDR(ep);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, ep, mode);
|
||||
pd = dev->si_drv1;
|
||||
LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -65,8 +65,6 @@ struct usb2_interface {
|
||||
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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user