Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb9cae03 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: update Kconfig help text for CONFIG_USB_SUSPEND
  usb: musb: gadget: restart request on clearing endpoint halt
  usb: musb: host: Issue a memory barrier before starting DMA
  usb: musb: gadget: fix dma length in txstate
  usb: musb: gadget: complete request only if data is transfered over
  usb: musb: gadget: fix DMA length for OUT transfer
  usb: musb: gadget: enable autoclear for OUT transfer in both DMA 0 and DMA 1
  usb: musb: gadget: fix bulk IN infinit hangs in double buffer case
  usb: musb: gadget: fix kernel panic if using out ep with FIFO_TXRX style
  USB: fix bug in initialization of interface minor numbers
parents 06706b58 2dab3948
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -91,12 +91,12 @@ config USB_DYNAMIC_MINORS
	  If you are unsure about this, say N here.

config USB_SUSPEND
	bool "USB runtime power management (suspend/resume and wakeup)"
	bool "USB runtime power management (autosuspend) and wakeup"
	depends on USB && PM_RUNTIME
	help
	  If you say Y here, you can use driver calls or the sysfs
	  "power/level" file to suspend or resume individual USB
	  peripherals and to enable or disable autosuspend (see
	  "power/control" file to enable or disable autosuspend for
	  individual USB peripherals (see
	  Documentation/usb/power-management.txt for more details).

	  Also, USB "remote wakeup" signaling is supported, whereby some
+16 −19
Original line number Diff line number Diff line
@@ -159,9 +159,9 @@ void usb_major_cleanup(void)
int usb_register_dev(struct usb_interface *intf,
		     struct usb_class_driver *class_driver)
{
	int retval = -EINVAL;
	int retval;
	int minor_base = class_driver->minor_base;
	int minor = 0;
	int minor;
	char name[20];
	char *temp;

@@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf,
	 */
	minor_base = 0;
#endif
	intf->minor = -1;

	dbg ("looking for a minor, starting at %d", minor_base);

	if (class_driver->fops == NULL)
		goto exit;
		return -EINVAL;
	if (intf->minor >= 0)
		return -EADDRINUSE;

	retval = init_usb_class();
	if (retval)
		return retval;

	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);

	down_write(&minor_rwsem);
	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
@@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf,
			continue;

		usb_minors[minor] = class_driver->fops;

		retval = 0;
		intf->minor = minor;
		break;
	}
	up_write(&minor_rwsem);

	if (retval)
		goto exit;

	retval = init_usb_class();
	if (retval)
		goto exit;

	intf->minor = minor;
	if (intf->minor < 0)
		return -EXFULL;

	/* create a usb class device for this usb interface */
	snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
@@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf,
				      "%s", temp);
	if (IS_ERR(intf->usb_dev)) {
		down_write(&minor_rwsem);
		usb_minors[intf->minor] = NULL;
		usb_minors[minor] = NULL;
		intf->minor = -1;
		up_write(&minor_rwsem);
		retval = PTR_ERR(intf->usb_dev);
	}
exit:
	return retval;
}
EXPORT_SYMBOL_GPL(usb_register_dev);
+1 −0
Original line number Diff line number Diff line
@@ -1802,6 +1802,7 @@ free_interfaces:
		intf->dev.groups = usb_interface_groups;
		intf->dev.dma_mask = dev->dev.dma_mask;
		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
		intf->minor = -1;
		device_initialize(&intf->dev);
		dev_set_name(&intf->dev, "%d-%s:%d.%d",
			dev->bus->busnum, dev->devpath,
+1 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ cppi_channel_allocate(struct dma_controller *c,
				index, transmit ? 'T' : 'R', cppi_ch);
	cppi_ch->hw_ep = ep;
	cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;
	cppi_ch->channel.max_len = 0x7fffffff;

	DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');
	return &cppi_ch->channel;
+39 −36
Original line number Diff line number Diff line
@@ -300,6 +300,11 @@ static void txstate(struct musb *musb, struct musb_request *req)
#ifndef	CONFIG_MUSB_PIO_ONLY
	if (is_dma_capable() && musb_ep->dma) {
		struct dma_controller	*c = musb->dma_controller;
		size_t request_size;

		/* setup DMA, then program endpoint CSR */
		request_size = min_t(size_t, request->length - request->actual,
					musb_ep->dma->max_len);

		use_dma = (request->dma != DMA_ADDR_INVALID);

@@ -307,11 +312,6 @@ static void txstate(struct musb *musb, struct musb_request *req)

#ifdef CONFIG_USB_INVENTRA_DMA
		{
			size_t request_size;

			/* setup DMA, then program endpoint CSR */
			request_size = min_t(size_t, request->length,
						musb_ep->dma->max_len);
			if (request_size < musb_ep->packet_sz)
				musb_ep->dma->desired_mode = 0;
			else
@@ -373,8 +373,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
		use_dma = use_dma && c->channel_program(
				musb_ep->dma, musb_ep->packet_sz,
				0,
				request->dma,
				request->length);
				request->dma + request->actual,
				request_size);
		if (!use_dma) {
			c->channel_release(musb_ep->dma);
			musb_ep->dma = NULL;
@@ -386,8 +386,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
		use_dma = use_dma && c->channel_program(
				musb_ep->dma, musb_ep->packet_sz,
				request->zero,
				request->dma,
				request->length);
				request->dma + request->actual,
				request_size);
#endif
	}
#endif
@@ -501,21 +501,8 @@ void musb_g_tx(struct musb *musb, u8 epnum)
				request->zero = 0;
			}

			/* ... or if not, then complete it. */
			if (request->actual == request->length) {
				musb_g_giveback(musb_ep, request, 0);

			/*
			 * Kickstart next transfer if appropriate;
			 * the packet that just completed might not
			 * be transmitted for hours or days.
			 * REVISIT for double buffering...
			 * FIXME revisit for stalls too...
			 */
			musb_ep_select(mbase, epnum);
			csr = musb_readw(epio, MUSB_TXCSR);
			if (csr & MUSB_TXCSR_FIFONOTEMPTY)
				return;

				request = musb_ep->desc ? next_request(musb_ep) : NULL;
				if (!request) {
					DBG(4, "%s idle now\n",
@@ -523,6 +510,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)
					return;
				}
			}
		}

		txstate(musb, to_musb_request(request));
	}
@@ -568,11 +556,19 @@ static void rxstate(struct musb *musb, struct musb_request *req)
{
	const u8		epnum = req->epnum;
	struct usb_request	*request = &req->request;
	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_out;
	struct musb_ep		*musb_ep;
	void __iomem		*epio = musb->endpoints[epnum].regs;
	unsigned		fifo_count = 0;
	u16			len = musb_ep->packet_sz;
	u16			len;
	u16			csr = musb_readw(epio, MUSB_RXCSR);
	struct musb_hw_ep	*hw_ep = &musb->endpoints[epnum];

	if (hw_ep->is_shared_fifo)
		musb_ep = &hw_ep->ep_in;
	else
		musb_ep = &hw_ep->ep_out;

	len = musb_ep->packet_sz;

	/* We shouldn't get here while DMA is active, but we do... */
	if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
@@ -647,8 +643,8 @@ static void rxstate(struct musb *musb, struct musb_request *req)
	 */

				csr |= MUSB_RXCSR_DMAENAB;
#ifdef USE_MODE1
				csr |= MUSB_RXCSR_AUTOCLEAR;
#ifdef USE_MODE1
				/* csr |= MUSB_RXCSR_DMAMODE; */

				/* this special sequence (enabling and then
@@ -663,10 +659,11 @@ static void rxstate(struct musb *musb, struct musb_request *req)
				if (request->actual < request->length) {
					int transfer_size = 0;
#ifdef USE_MODE1
					transfer_size = min(request->length,
					transfer_size = min(request->length - request->actual,
							channel->max_len);
#else
					transfer_size = len;
					transfer_size = min(request->length - request->actual,
							(unsigned)len);
#endif
					if (transfer_size <= musb_ep->packet_sz)
						musb_ep->dma->desired_mode = 0;
@@ -740,9 +737,15 @@ void musb_g_rx(struct musb *musb, u8 epnum)
	u16			csr;
	struct usb_request	*request;
	void __iomem		*mbase = musb->mregs;
	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_out;
	struct musb_ep		*musb_ep;
	void __iomem		*epio = musb->endpoints[epnum].regs;
	struct dma_channel	*dma;
	struct musb_hw_ep	*hw_ep = &musb->endpoints[epnum];

	if (hw_ep->is_shared_fifo)
		musb_ep = &hw_ep->ep_in;
	else
		musb_ep = &hw_ep->ep_out;

	musb_ep_select(mbase, epnum);

@@ -1081,7 +1084,7 @@ struct free_record {
/*
 * Context: controller locked, IRQs blocked.
 */
static void musb_ep_restart(struct musb *musb, struct musb_request *req)
void musb_ep_restart(struct musb *musb, struct musb_request *req)
{
	DBG(3, "<== %s request %p len %u on hw_ep%d\n",
		req->tx ? "TX/IN" : "RX/OUT",
Loading