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

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

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

usb: fixes for v3.4-rc cycle

Here are the fixes I have queued for v3.4-rc cycle so far.

It includes fixes on many of the gadget drivers and a few
of the UDC controller drivers.

For musb we have a fix for a kernel oops when unloading
omap2430.ko glue layer, proper error checking for pm_runtime_*,
fix for the ULPI transfer block, and a bug fix in musb_cleanup_urb
routine.

For s3c-hsotg we have mostly FIFO-related fixes (proper TX FIFO
allocation, TX FIFO corruption fix in DMA mode) but also a couple
of minor fixes (fixing maximum packet size for ep0 and fix for
big transfers with DMA).

For the dwc3 driver we have a memory leak fix, a very important
fix for USB30CV with SetFeature tests and the hability to handle
ep0 requests bigger than wMaxPacketSize.

On top of that there's a bunch of gadget driver minor fixes adding
proper section annotations, and fixing up the sysfs interface for
doing device-initiated connect/disconnect and so on.

All patches have been pending on the mailing list for quite a while
and look good for your for-linus branch.
parents e816b57a 92b0abf8
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)

	for (i = 0; i < dwc->num_event_buffers; i++) {
		evt = dwc->ev_buffs[i];
		if (evt) {
		if (evt)
			dwc3_free_one_event_buffer(dwc, evt);
			dwc->ev_buffs[i] = NULL;
		}
	}

	kfree(dwc->ev_buffs);
}

/**
+10 −2
Original line number Diff line number Diff line
@@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,

			dwc->test_mode_nr = wIndex >> 8;
			dwc->test_mode = true;
			break;
		default:
			return -EINVAL;
		}
		break;

@@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
	length = trb->size & DWC3_TRB_SIZE_MASK;

	if (dwc->ep0_bounced) {
		unsigned transfer_size = ur->length;
		unsigned maxp = ep0->endpoint.maxpacket;

		transfer_size += (maxp - (transfer_size % maxp));
		transferred = min_t(u32, ur->length,
				ep0->endpoint.maxpacket - length);
				transfer_size - length);
		memcpy(ur->buf, dwc->ep0_bounce, transferred);
		dwc->ep0_bounced = false;
	} else {
		transferred = ur->length - length;
		ur->actual += transferred;
	}

	ur->actual += transferred;

	if ((epnum & 1) && ur->actual < ur->length) {
		/* for some reason we did not get everything out */

+2 −1
Original line number Diff line number Diff line
@@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
	if (code == FUNCTIONFS_INTERFACE_REVMAP) {
		struct ffs_function *func = ffs->func;
		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
	} else if (gadget->ops->ioctl) {
	} else if (gadget && gadget->ops->ioctl) {
		ret = gadget->ops->ioctl(gadget, code, value);
	} else {
		ret = -ENOTTY;
@@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
		ffs->ep0req = NULL;
		ffs->gadget = NULL;
		ffs_data_put(ffs);
		clear_bit(FFS_FL_BOUND, &ffs->flags);
	}
}

+1 −0
Original line number Diff line number Diff line
@@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
			if (buf) {
				memcpy(req->buf, buf, n);
				req->complete = rndis_response_complete;
				req->context = rndis;
				rndis_free_response(rndis->config, buf);
				value = n;
			}
+16 −9
Original line number Diff line number Diff line
@@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
		: (1 << (ep_index(ep)));

	/* check if the pipe is empty */
	if (!(list_empty(&ep->queue))) {
	if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
		/* Add td to the end */
		struct fsl_req *lastreq;
		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
		return -ENOMEM;
	}

	/* Update ep0 state */
	if ((ep_index(ep) == 0))
		udc->ep0_state = DATA_STATE_XMIT;

	/* irq handler advances the queue */
	if (req != NULL)
		list_add_tail(&req->queue, &ep->queue);
@@ -1279,6 +1275,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
		udc->ep0_dir = USB_DIR_OUT;

	ep = &udc->eps[0];
	if (udc->ep0_state != DATA_STATE_XMIT)
		udc->ep0_state = WAIT_FOR_OUT_STATUS;

	req->ep = ep;
@@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,

	list_add_tail(&req->queue, &ep->queue);
	udc->ep0_state = DATA_STATE_XMIT;
	if (ep0_prime_status(udc, EP_DIR_OUT))
		ep0stall(udc);

	return;
stall:
	ep0stall(udc);
@@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
		spin_lock(&udc->lock);
		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
				?  DATA_STATE_XMIT : DATA_STATE_RECV;
		/*
		 * If the data stage is IN, send status prime immediately.
		 * See 2.0 Spec chapter 8.5.3.3 for detail.
		 */
		if (udc->ep0_state == DATA_STATE_XMIT)
			if (ep0_prime_status(udc, EP_DIR_OUT))
				ep0stall(udc);

	} else {
		/* No data phase, IN status from gadget */
		udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,

	switch (udc->ep0_state) {
	case DATA_STATE_XMIT:
		/* receive status phase */
		if (ep0_prime_status(udc, EP_DIR_OUT))
			ep0stall(udc);
		/* already primed at setup_received_irq */
		udc->ep0_state = WAIT_FOR_OUT_STATUS;
		break;
	case DATA_STATE_RECV:
		/* send status phase */
Loading