/* handles CDC Ethernet and many other network "bulk data" interfaces */ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) { int tmp; struct usb_host_interface *alt = NULL; struct usb_host_endpoint *in = NULL, *out = NULL; struct usb_host_endpoint *status = NULL; for (tmp = 0; tmp < intf->num_altsetting; tmp++) { unsigned ep; in = out = status = NULL; alt = intf->altsetting + tmp; /* take the first altsetting with in-bulk + out-bulk; * remember any status endpoint, just in case; * ignore other endpoints and altsetttings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; int intr = 0; e = alt->endpoint + ep; switch (e->desc.bmAttributes) { case USB_ENDPOINT_XFER_INT: if (!usb_endpoint_dir_in(&e->desc)) continue; intr = 1; /* FALLTHROUGH */ case USB_ENDPOINT_XFER_BULK: break; default: continue; } if (usb_endpoint_dir_in(&e->desc)) { if (!intr && !in) in = e; else if (intr && !status) status = e; } else { if (!out) out = e; } } if (in && out) break; } if (!alt || !in || !out) return -EINVAL; if (alt->desc.bAlternateSetting != 0 || !(dev->driver_info->flags & FLAG_NO_SETINT)) { tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); if (tmp < 0) return tmp; } dev->in = usb_rcvbulkpipe (dev->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe (dev->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->status = status; return 0; }
/* handles CDC Ethernet and many other network "bulk data" interfaces */ int usbnet_get_endpoints(struct usbnet *dev) { struct usb_device *udev = dev->udev; int tmp; struct usb_interface_descriptor *alt = NULL; struct usb_endpoint_descriptor *in = NULL, *out = NULL; struct usb_endpoint_descriptor *status = NULL; for (tmp = 0; tmp < udev->config.no_of_if; tmp++) { unsigned ep; in = out = status = NULL; alt = &udev->config.if_desc[tmp]; /* take the first altsetting with in-bulk + out-bulk; * remember any status endpoint, just in case; * ignore other endpoints and altsetttings. */ for (ep = 0; ep < alt->bNumEndpoints; ep++) { struct usb_endpoint_descriptor *e; int intr = 0; e = &alt->ep_desc[ep]; switch (e->bmAttributes) { case USB_ENDPOINT_XFER_INT: if (!usb_endpoint_dir_in(e)) continue; intr = 1; /* FALLTHROUGH */ case USB_ENDPOINT_XFER_BULK: break; default: continue; } if (usb_endpoint_dir_in(e)) { if (!intr && !in) in = e; else if (intr && !status) status = e; } else { if (!out) out = e; } } if (in && out) break; } if (!alt || !in || !out) return -EINVAL; if (alt->bAlternateSetting != 0 || !(dev->driver_info->flags & FLAG_NO_SETINT)) { tmp = usb_set_interface (dev->udev, alt->bInterfaceNumber, alt->bAlternateSetting); if (tmp < 0) return tmp; } dev->in = usb_rcvbulkpipe (dev->udev, in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe (dev->udev, out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev_dbg(&dev->edev.dev, "found endpoints: IN=%d OUT=%d\n", in->bEndpointAddress, out->bEndpointAddress); return 0; }