Commit 75dfea53 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'fixes-for-v3.17-rc3' of...

Merge tag 'fixes-for-v3.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb

 into usb-linus

Felipe writes:

usb: fixes for v3.17-rc3

A new set of fixes which have been pending for a while. All patches
have been randconfig build-tested and boot tested where applicable.

The most important fixes are MUSB on AM335x learned how to transfer
ZLPs, and net2280 got a fix for reset IRQ handling.

Signed-of-by: default avatarFelipe Balbi <balbi@ti.com>
parents c156bf2c 9ce9ec95
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ Required properties:
	* "fsl,imx23-usbphy" for imx23 and imx28
	* "fsl,imx6q-usbphy" for imx6dq and imx6dl
	* "fsl,imx6sl-usbphy" for imx6sl
	* "fsl,imx6sx-usbphy" for imx6sx
  "fsl,imx23-usbphy" is still a fallback for other strings
- reg: Should contain registers location and length
- interrupts: Should contain phy interrupt
+55 −11
Original line number Diff line number Diff line
@@ -155,6 +155,12 @@ struct ffs_io_data {
	struct usb_request *req;
};

struct ffs_desc_helper {
	struct ffs_data *ffs;
	unsigned interfaces_count;
	unsigned eps_count;
};

static int  __must_check ffs_epfiles_create(struct ffs_data *ffs);
static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count);

@@ -1830,7 +1836,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
				u8 *valuep, struct usb_descriptor_header *desc,
				void *priv)
{
	struct ffs_data *ffs = priv;
	struct ffs_desc_helper *helper = priv;
	struct usb_endpoint_descriptor *d;

	ENTER();

@@ -1844,8 +1851,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
		 * encountered interface "n" then there are at least
		 * "n+1" interfaces.
		 */
		if (*valuep >= ffs->interfaces_count)
			ffs->interfaces_count = *valuep + 1;
		if (*valuep >= helper->interfaces_count)
			helper->interfaces_count = *valuep + 1;
		break;

	case FFS_STRING:
@@ -1853,14 +1860,22 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
		 * Strings are indexed from 1 (0 is magic ;) reserved
		 * for languages list or some such)
		 */
		if (*valuep > ffs->strings_count)
			ffs->strings_count = *valuep;
		if (*valuep > helper->ffs->strings_count)
			helper->ffs->strings_count = *valuep;
		break;

	case FFS_ENDPOINT:
		/* Endpoints are indexed from 1 as well. */
		if ((*valuep & USB_ENDPOINT_NUMBER_MASK) > ffs->eps_count)
			ffs->eps_count = (*valuep & USB_ENDPOINT_NUMBER_MASK);
		d = (void *)desc;
		helper->eps_count++;
		if (helper->eps_count >= 15)
			return -EINVAL;
		/* Check if descriptors for any speed were already parsed */
		if (!helper->ffs->eps_count && !helper->ffs->interfaces_count)
			helper->ffs->eps_addrmap[helper->eps_count] =
				d->bEndpointAddress;
		else if (helper->ffs->eps_addrmap[helper->eps_count] !=
				d->bEndpointAddress)
			return -EINVAL;
		break;
	}

@@ -2053,6 +2068,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
	char *data = _data, *raw_descs;
	unsigned os_descs_count = 0, counts[3], flags;
	int ret = -EINVAL, i;
	struct ffs_desc_helper helper;

	ENTER();

@@ -2101,13 +2117,29 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,

	/* Read descriptors */
	raw_descs = data;
	helper.ffs = ffs;
	for (i = 0; i < 3; ++i) {
		if (!counts[i])
			continue;
		helper.interfaces_count = 0;
		helper.eps_count = 0;
		ret = ffs_do_descs(counts[i], data, len,
				   __ffs_data_do_entity, ffs);
				   __ffs_data_do_entity, &helper);
		if (ret < 0)
			goto error;
		if (!ffs->eps_count && !ffs->interfaces_count) {
			ffs->eps_count = helper.eps_count;
			ffs->interfaces_count = helper.interfaces_count;
		} else {
			if (ffs->eps_count != helper.eps_count) {
				ret = -EINVAL;
				goto error;
			}
			if (ffs->interfaces_count != helper.interfaces_count) {
				ret = -EINVAL;
				goto error;
			}
		}
		data += ret;
		len  -= ret;
	}
@@ -2342,9 +2374,18 @@ static void ffs_event_add(struct ffs_data *ffs,
	spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
}


/* Bind/unbind USB function hooks *******************************************/

static int ffs_ep_addr2idx(struct ffs_data *ffs, u8 endpoint_address)
{
	int i;

	for (i = 1; i < ARRAY_SIZE(ffs->eps_addrmap); ++i)
		if (ffs->eps_addrmap[i] == endpoint_address)
			return i;
	return -ENOENT;
}

static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
				    struct usb_descriptor_header *desc,
				    void *priv)
@@ -2378,7 +2419,10 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
	if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT)
		return 0;

	idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1;
	idx = ffs_ep_addr2idx(func->ffs, ds->bEndpointAddress) - 1;
	if (idx < 0)
		return idx;

	ffs_ep = func->eps + idx;

	if (unlikely(ffs_ep->descs[ep_desc_id])) {
+2 −0
Original line number Diff line number Diff line
@@ -224,6 +224,8 @@ struct ffs_data {
	void				*ms_os_descs_ext_prop_name_avail;
	void				*ms_os_descs_ext_prop_data_avail;

	u8				eps_addrmap[15];

	unsigned short			strings_count;
	unsigned short			interfaces_count;
	unsigned short			eps_count;
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@


#ifndef __FUSB300_UDC_H__
#define __FUSB300_UDC_H_
#define __FUSB300_UDC_H__

#include <linux/kernel.h>

+1 −1
Original line number Diff line number Diff line
@@ -3320,7 +3320,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
	if (stat & tmp) {
		writel(tmp, &dev->regs->irqstat1);
		if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
				(readl(&dev->usb->usbstat) & mask)) ||
				((readl(&dev->usb->usbstat) & mask) == 0)) ||
				((readl(&dev->usb->usbctl) &
					BIT(VBUS_PIN)) == 0)) &&
				(dev->gadget.speed != USB_SPEED_UNKNOWN)) {
Loading