aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2008-09-11 03:11:24 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-09-11 03:11:24 -0700
commit48413f29c85b608d373870ddd2ffedabc6f109f7 (patch)
tree4bc7a800324694c815f4d8a0118972820e0eca5a /usb
parentc4c7f685d1b2434cb5974d09fc5f3238d2092114 (diff)
downloadpatches-48413f29c85b608d373870ddd2ffedabc6f109f7.tar.gz
usb and driver core patches
Diffstat (limited to 'usb')
-rw-r--r--usb/ohci-allow-broken-controllers-to-auto-stop.patch151
-rw-r--r--usb/usb-add-freescale-qe-cpm-usb-peripheral-controller-driver.patch3257
-rw-r--r--usb/usb-drivers-usb-misc-use-an-is_err-test-rather-than-a-null-test.patch49
-rw-r--r--usb/usb-remove-unused-include-version.h.patch32
-rw-r--r--usb/usb-storage-report-underflow-with-no-sense-data.patch39
5 files changed, 3528 insertions, 0 deletions
diff --git a/usb/ohci-allow-broken-controllers-to-auto-stop.patch b/usb/ohci-allow-broken-controllers-to-auto-stop.patch
new file mode 100644
index 00000000000000..9277efe10e2402
--- /dev/null
+++ b/usb/ohci-allow-broken-controllers-to-auto-stop.patch
@@ -0,0 +1,151 @@
+From stern+48acf28e@rowland.harvard.edu Thu Sep 11 02:39:45 2008
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 3 Sep 2008 16:38:32 -0400 (EDT)
+Subject: OHCI: Allow broken controllers to auto-stop
+To: Greg KH <greg@kroah.com>
+Message-ID: <Pine.LNX.4.44L0.0809031637430.2281-100000@iolanthe.rowland.org>
+
+
+This patch (as1134) attempts to improve the way we handle OHCI
+controllers with broken Root Hub Status Change interrupt support. In
+these controllers the RHSC interrupt bit essentially never turns off,
+making RHSC interrupts useless -- they have to remain permanently
+disabled.
+
+Such controllers should still be allowed to turn off their root hubs
+when no devices are attached. Polling for new connections can
+continue while the root hub is suspended. The patch implements this
+feature. (It won't have much effect unless CONFIG_PM is enabled and
+CONFIG_USB_SUSPEND is disabled, but since the overhead is very small
+we may as well do it.)
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ohci-hub.c | 60 +++++++++++++++++++++++---------------------
+ 1 file changed, 32 insertions(+), 28 deletions(-)
+
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -362,18 +362,23 @@ static int ohci_root_hub_state_changes(s
+ int any_connected)
+ {
+ int poll_rh = 1;
+- int rhsc;
++ int rhsc_status, rhsc_enable;
+
+- rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
+- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
++ /* Some broken controllers never turn off RHCS in the interrupt
++ * status register. For their sake we won't re-enable RHSC
++ * interrupts if the interrupt bit is already active.
++ */
++ rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
++ OHCI_INTR_RHSC;
++ rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
++ OHCI_INTR_RHSC;
+
++ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+- /* If no status changes are pending, enable status-change
+- * interrupts.
+- */
+- if (!rhsc && !changed) {
+- rhsc = OHCI_INTR_RHSC;
+- ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
++ /* If no status changes are pending, enable RHSC interrupts. */
++ if (!rhsc_enable && !rhsc_status && !changed) {
++ rhsc_enable = OHCI_INTR_RHSC;
++ ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
+ }
+
+ /* Keep on polling until we know a device is connected
+@@ -383,7 +388,7 @@ static int ohci_root_hub_state_changes(s
+ if (any_connected ||
+ !device_may_wakeup(&ohci_to_hcd(ohci)
+ ->self.root_hub->dev)) {
+- if (rhsc)
++ if (rhsc_enable)
+ poll_rh = 0;
+ } else {
+ ohci->autostop = 1;
+@@ -396,34 +401,36 @@ static int ohci_root_hub_state_changes(s
+ ohci->autostop = 0;
+ ohci->next_statechange = jiffies +
+ STATECHANGE_DELAY;
+- } else if (rhsc && time_after_eq(jiffies,
++ } else if (time_after_eq(jiffies,
+ ohci->next_statechange)
+ && !ohci->ed_rm_list
+ && !(ohci->hc_control &
+ OHCI_SCHED_ENABLES)) {
+ ohci_rh_suspend(ohci, 1);
+- poll_rh = 0;
++ if (rhsc_enable)
++ poll_rh = 0;
+ }
+ }
+ break;
+
+- /* if there is a port change, autostart or ask to be resumed */
+ case OHCI_USB_SUSPEND:
+ case OHCI_USB_RESUME:
++ /* if there is a port change, autostart or ask to be resumed */
+ if (changed) {
+ if (ohci->autostop)
+ ohci_rh_resume(ohci);
+ else
+ usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
+ } else {
+- if (!rhsc && (ohci->autostop ||
++ if (!rhsc_enable && !rhsc_status && (ohci->autostop ||
+ ohci_to_hcd(ohci)->self.root_hub->
+- do_remote_wakeup))
+- ohci_writel(ohci, OHCI_INTR_RHSC,
++ do_remote_wakeup)) {
++ rhsc_enable = OHCI_INTR_RHSC;
++ ohci_writel(ohci, rhsc_enable,
+ &ohci->regs->intrenable);
+-
+- /* everything is idle, no need for polling */
+- poll_rh = 0;
++ }
++ if (rhsc_enable)
++ poll_rh = 0;
+ }
+ break;
+ }
+@@ -443,12 +450,16 @@ static inline int ohci_rh_resume(struct
+ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+ int any_connected)
+ {
++ int rhsc_status;
++
+ /* If RHSC is enabled, don't poll */
+ if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
+ return 0;
+
+- /* If no status changes are pending, enable status-change interrupts */
+- if (!changed) {
++ /* If no status changes are pending, enable RHSC interrupts */
++ rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
++ OHCI_INTR_RHSC;
++ if (!changed && !rhsc_status) {
+ ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+ return 0;
+ }
+@@ -492,13 +503,6 @@ ohci_hub_status_data (struct usb_hcd *hc
+ length++;
+ }
+
+- /* Some broken controllers never turn off RHCS in the interrupt
+- * status register. For their sake we won't re-enable RHSC
+- * interrupts if the flag is already set.
+- */
+- if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
+- changed = 1;
+-
+ /* look at each port */
+ for (i = 0; i < ohci->num_ports; i++) {
+ u32 status = roothub_portstatus (ohci, i);
diff --git a/usb/usb-add-freescale-qe-cpm-usb-peripheral-controller-driver.patch b/usb/usb-add-freescale-qe-cpm-usb-peripheral-controller-driver.patch
new file mode 100644
index 00000000000000..7e8da39812a6ab
--- /dev/null
+++ b/usb/usb-add-freescale-qe-cpm-usb-peripheral-controller-driver.patch
@@ -0,0 +1,3257 @@
+From LeoLi@freescale.com Thu Sep 11 02:35:47 2008
+From: Li Yang <leoli@freescale.com>
+Date: Tue, 2 Sep 2008 19:58:10 +0800
+Subject: usb: add Freescale QE/CPM USB peripheral controller driver
+To: greg@kroah.com, dbrownell@users.sourceforge.net
+Cc: <avorontsov@ru.mvista.com>, <arnd@arndb.de>, Li Yang <leoli@freescale.com>
+Message-ID: <1220356690-8028-1-git-send-email-leoli@freescale.com>
+
+
+Some of Freescale SoC chips have a QE or CPM co-processor which
+supports full speed USB. The driver adds device mode support
+of both QE and CPM USB controller to Linux USB gadget. The
+driver is tested with MPC8360 and MPC8272, and should work with
+other models having QE/CPM given minor tweaks.
+
+Signed-off-by: Xie Xiaobo <X.Xie@freescale.com>
+Signed-off-by: Li Yang <leoli@freescale.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/Kconfig | 19
+ drivers/usb/gadget/Makefile | 1
+ drivers/usb/gadget/fsl_qe_udc.c | 2723 ++++++++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/fsl_qe_udc.h | 436 ++++++
+ drivers/usb/gadget/gadget_chips.h | 9
+ 5 files changed, 3188 insertions(+)
+
+--- /dev/null
++++ b/drivers/usb/gadget/fsl_qe_udc.c
+@@ -0,0 +1,2723 @@
++/*
++ * driver/usb/gadget/fsl_qe_udc.c
++ *
++ * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
++ *
++ * Xie Xiaobo <X.Xie@freescale.com>
++ * Li Yang <leoli@freescale.com>
++ * Based on bareboard code from Shlomi Gridish.
++ *
++ * Description:
++ * Freescle QE/CPM USB Pheripheral Controller Driver
++ * The controller can be found on MPC8360, MPC8272, and etc.
++ * MPC8360 Rev 1.1 may need QE mircocode update
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#undef USB_TRACE
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/moduleparam.h>
++#include <linux/of_platform.h>
++#include <linux/dma-mapping.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/gadget.h>
++#include <linux/usb/otg.h>
++#include <asm/qe.h>
++#include <asm/cpm.h>
++#include <asm/dma.h>
++#include <asm/reg.h>
++#include "fsl_qe_udc.h"
++
++#define DRIVER_DESC "Freescale QE/CPM USB Device Controller driver"
++#define DRIVER_AUTHOR "Xie XiaoBo"
++#define DRIVER_VERSION "1.0"
++
++#define DMA_ADDR_INVALID (~(dma_addr_t)0)
++
++static const char driver_name[] = "fsl_qe_udc";
++static const char driver_desc[] = DRIVER_DESC;
++
++/*ep name is important in gadget, it should obey the convention of ep_match()*/
++static const char *const ep_name[] = {
++ "ep0-control", /* everyone has ep0 */
++ /* 3 configurable endpoints */
++ "ep1",
++ "ep2",
++ "ep3",
++};
++
++static struct usb_endpoint_descriptor qe_ep0_desc = {
++ .bLength = USB_DT_ENDPOINT_SIZE,
++ .bDescriptorType = USB_DT_ENDPOINT,
++
++ .bEndpointAddress = 0,
++ .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
++ .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD,
++};
++
++/* it is initialized in probe() */
++static struct qe_udc *udc_controller;
++
++/********************************************************************
++ * Internal Used Function Start
++********************************************************************/
++/*-----------------------------------------------------------------
++ * done() - retire a request; caller blocked irqs
++ *--------------------------------------------------------------*/
++static void done(struct qe_ep *ep, struct qe_req *req, int status)
++{
++ struct qe_udc *udc = ep->udc;
++ unsigned char stopped = ep->stopped;
++
++ /* the req->queue pointer is used by ep_queue() func, in which
++ * the request will be added into a udc_ep->queue 'd tail
++ * so here the req will be dropped from the ep->queue
++ */
++ list_del_init(&req->queue);
++
++ /* req.status should be set as -EINPROGRESS in ep_queue() */
++ if (req->req.status == -EINPROGRESS)
++ req->req.status = status;
++ else
++ status = req->req.status;
++
++ if (req->mapped) {
++ dma_unmap_single(udc->gadget.dev.parent,
++ req->req.dma, req->req.length,
++ ep_is_in(ep)
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++ req->req.dma = DMA_ADDR_INVALID;
++ req->mapped = 0;
++ } else
++ dma_sync_single_for_cpu(udc->gadget.dev.parent,
++ req->req.dma, req->req.length,
++ ep_is_in(ep)
++ ? DMA_TO_DEVICE
++ : DMA_FROM_DEVICE);
++
++ if (status && (status != -ESHUTDOWN))
++ dev_vdbg(udc->dev, "complete %s req %p stat %d len %u/%u\n",
++ ep->ep.name, &req->req, status,
++ req->req.actual, req->req.length);
++
++ /* don't modify queue heads during completion callback */
++ ep->stopped = 1;
++ spin_unlock(&udc->lock);
++
++ /* this complete() should a func implemented by gadget layer,
++ * eg fsg->bulk_in_complete() */
++ if (req->req.complete)
++ req->req.complete(&ep->ep, &req->req);
++
++ spin_lock(&udc->lock);
++
++ ep->stopped = stopped;
++}
++
++/*-----------------------------------------------------------------
++ * nuke(): delete all requests related to this ep
++ *--------------------------------------------------------------*/
++static void nuke(struct qe_ep *ep, int status)
++{
++ /* Whether this eq has request linked */
++ while (!list_empty(&ep->queue)) {
++ struct qe_req *req = NULL;
++ req = list_entry(ep->queue.next, struct qe_req, queue);
++
++ done(ep, req, status);
++ }
++}
++
++/*---------------------------------------------------------------------------*
++ * USB and Endpoint manipulate process, include parameter and register *
++ *---------------------------------------------------------------------------*/
++/* @value: 1--set stall 0--clean stall */
++static int qe_eprx_stall_change(struct qe_ep *ep, int value)
++{
++ u16 tem_usep;
++ u8 epnum = ep->epnum;
++ struct qe_udc *udc = ep->udc;
++
++ tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
++ tem_usep = tem_usep & ~USB_RHS_MASK;
++ if (value == 1)
++ tem_usep |= USB_RHS_STALL;
++ else if (ep->dir == USB_DIR_IN)
++ tem_usep |= USB_RHS_IGNORE_OUT;
++
++ out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
++ return 0;
++}
++
++static int qe_eptx_stall_change(struct qe_ep *ep, int value)
++{
++ u16 tem_usep;
++ u8 epnum = ep->epnum;
++ struct qe_udc *udc = ep->udc;
++
++ tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
++ tem_usep = tem_usep & ~USB_THS_MASK;
++ if (value == 1)
++ tem_usep |= USB_THS_STALL;
++ else if (ep->dir == USB_DIR_OUT)
++ tem_usep |= USB_THS_IGNORE_IN;
++
++ out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
++
++ return 0;
++}
++
++static int qe_ep0_stall(struct qe_udc *udc)
++{
++ qe_eptx_stall_change(&udc->eps[0], 1);
++ qe_eprx_stall_change(&udc->eps[0], 1);
++ udc_controller->ep0_state = WAIT_FOR_SETUP;
++ udc_controller->ep0_dir = 0;
++ return 0;
++}
++
++static int qe_eprx_nack(struct qe_ep *ep)
++{
++ u8 epnum = ep->epnum;
++ struct qe_udc *udc = ep->udc;
++
++ if (ep->state == EP_STATE_IDLE) {
++ /* Set the ep's nack */
++ clrsetbits_be16(&udc->usb_regs->usb_usep[epnum],
++ USB_RHS_MASK, USB_RHS_NACK);
++
++ /* Mask Rx and Busy interrupts */
++ clrbits16(&udc->usb_regs->usb_usbmr,
++ (USB_E_RXB_MASK | USB_E_BSY_MASK));
++
++ ep->state = EP_STATE_NACK;
++ }
++ return 0;
++}
++
++static int qe_eprx_normal(struct qe_ep *ep)
++{
++ struct qe_udc *udc = ep->udc;
++
++ if (ep->state == EP_STATE_NACK) {
++ clrsetbits_be16(&udc->usb_regs->usb_usep[ep->epnum],
++ USB_RTHS_MASK, USB_THS_IGNORE_IN);
++
++ /* Unmask RX interrupts */
++ out_be16(&udc->usb_regs->usb_usber,
++ USB_E_BSY_MASK | USB_E_RXB_MASK);
++ setbits16(&udc->usb_regs->usb_usbmr,
++ (USB_E_RXB_MASK | USB_E_BSY_MASK));
++
++ ep->state = EP_STATE_IDLE;
++ ep->has_data = 0;
++ }
++
++ return 0;
++}
++
++static int qe_ep_cmd_stoptx(struct qe_ep *ep)
++{
++ if (ep->udc->soc_type == PORT_CPM)
++ cpm_command(CPM_USB_STOP_TX | (ep->epnum << CPM_USB_EP_SHIFT),
++ CPM_USB_STOP_TX_OPCODE);
++ else
++ qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB,
++ ep->epnum, 0);
++
++ return 0;
++}
++
++static int qe_ep_cmd_restarttx(struct qe_ep *ep)
++{
++ if (ep->udc->soc_type == PORT_CPM)
++ cpm_command(CPM_USB_RESTART_TX | (ep->epnum <<
++ CPM_USB_EP_SHIFT), CPM_USB_RESTART_TX_OPCODE);
++ else
++ qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB,
++ ep->epnum, 0);
++
++ return 0;
++}
++
++static int qe_ep_flushtxfifo(struct qe_ep *ep)
++{
++ struct qe_udc *udc = ep->udc;
++ int i;
++
++ i = (int)ep->epnum;
++
++ qe_ep_cmd_stoptx(ep);
++ out_8(&udc->usb_regs->usb_uscom,
++ USB_CMD_FLUSH_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
++ out_be16(&udc->ep_param[i]->tbptr, in_be16(&udc->ep_param[i]->tbase));
++ out_be32(&udc->ep_param[i]->tstate, 0);
++ out_be16(&udc->ep_param[i]->tbcnt, 0);
++
++ ep->c_txbd = ep->txbase;
++ ep->n_txbd = ep->txbase;
++ qe_ep_cmd_restarttx(ep);
++ return 0;
++}
++
++static int qe_ep_filltxfifo(struct qe_ep *ep)
++{
++ struct qe_udc *udc = ep->udc;
++
++ out_8(&udc->usb_regs->usb_uscom,
++ USB_CMD_STR_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
++ return 0;
++}
++
++static int qe_epbds_reset(struct qe_udc *udc, int pipe_num)
++{
++ struct qe_ep *ep;
++ u32 bdring_len;
++ struct qe_bd __iomem *bd;
++ int i;
++
++ ep = &udc->eps[pipe_num];
++
++ if (ep->dir == USB_DIR_OUT)
++ bdring_len = USB_BDRING_LEN_RX;
++ else
++ bdring_len = USB_BDRING_LEN;
++
++ bd = ep->rxbase;
++ for (i = 0; i < (bdring_len - 1); i++) {
++ out_be32((u32 __iomem *)bd, R_E | R_I);
++ bd++;
++ }
++ out_be32((u32 __iomem *)bd, R_E | R_I | R_W);
++
++ bd = ep->txbase;
++ for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
++ out_be32(&bd->buf, 0);
++ out_be32((u32 __iomem *)bd, 0);
++ bd++;
++ }
++ out_be32((u32 __iomem *)bd, T_W);
++
++ return 0;
++}
++
++static int qe_ep_reset(struct qe_udc *udc, int pipe_num)
++{
++ struct qe_ep *ep;
++ u16 tmpusep;
++
++ ep = &udc->eps[pipe_num];
++ tmpusep = in_be16(&udc->usb_regs->usb_usep[pipe_num]);
++ tmpusep &= ~USB_RTHS_MASK;
++
++ switch (ep->dir) {
++ case USB_DIR_BOTH:
++ qe_ep_flushtxfifo(ep);
++ break;
++ case USB_DIR_OUT:
++ tmpusep |= USB_THS_IGNORE_IN;
++ break;
++ case USB_DIR_IN:
++ qe_ep_flushtxfifo(ep);
++ tmpusep |= USB_RHS_IGNORE_OUT;
++ break;
++ default:
++ break;
++ }
++ out_be16(&udc->usb_regs->usb_usep[pipe_num], tmpusep);
++
++ qe_epbds_reset(udc, pipe_num);
++
++ return 0;
++}
++
++static int qe_ep_toggledata01(struct qe_ep *ep)
++{
++ ep->data01 ^= 0x1;
++ return 0;
++}
++
++static int qe_ep_bd_init(struct qe_udc *udc, unsigned char pipe_num)
++{
++ struct qe_ep *ep = &udc->eps[pipe_num];
++ unsigned long tmp_addr = 0;
++ struct usb_ep_para __iomem *epparam;
++ int i;
++ struct qe_bd __iomem *bd;
++ int bdring_len;
++
++ if (ep->dir == USB_DIR_OUT)
++ bdring_len = USB_BDRING_LEN_RX;
++ else
++ bdring_len = USB_BDRING_LEN;
++
++ epparam = udc->ep_param[pipe_num];
++ /* alloc multi-ram for BD rings and set the ep parameters */
++ tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len +
++ USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD);
++ out_be16(&epparam->rbase, (u16)tmp_addr);
++ out_be16(&epparam->tbase, (u16)(tmp_addr +
++ (sizeof(struct qe_bd) * bdring_len)));
++
++ out_be16(&epparam->rbptr, in_be16(&epparam->rbase));
++ out_be16(&epparam->tbptr, in_be16(&epparam->tbase));
++
++ ep->rxbase = cpm_muram_addr(tmp_addr);
++ ep->txbase = cpm_muram_addr(tmp_addr + (sizeof(struct qe_bd)
++ * bdring_len));
++ ep->n_rxbd = ep->rxbase;
++ ep->e_rxbd = ep->rxbase;
++ ep->n_txbd = ep->txbase;
++ ep->c_txbd = ep->txbase;
++ ep->data01 = 0; /* data0 */
++
++ /* Init TX and RX bds */
++ bd = ep->rxbase;
++ for (i = 0; i < bdring_len - 1; i++) {
++ out_be32(&bd->buf, 0);
++ out_be32((u32 __iomem *)bd, 0);
++ bd++;
++ }
++ out_be32(&bd->buf, 0);
++ out_be32((u32 __iomem *)bd, R_W);
++
++ bd = ep->txbase;
++ for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
++ out_be32(&bd->buf, 0);
++ out_be32((u32 __iomem *)bd, 0);
++ bd++;
++ }
++ out_be32(&bd->buf, 0);
++ out_be32((u32 __iomem *)bd, T_W);
++
++ return 0;
++}
++
++static int qe_ep_rxbd_update(struct qe_ep *ep)
++{
++ unsigned int size;
++ int i;
++ unsigned int tmp;
++ struct qe_bd __iomem *bd;
++ unsigned int bdring_len;
++
++ if (ep->rxbase == NULL)
++ return -EINVAL;
++
++ bd = ep->rxbase;
++
++ ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC);
++ if (ep->rxframe == NULL) {
++ dev_err(ep->udc->dev, "malloc rxframe failed\n");
++ return -ENOMEM;
++ }
++
++ qe_frame_init(ep->rxframe);
++
++ if (ep->dir == USB_DIR_OUT)
++ bdring_len = USB_BDRING_LEN_RX;
++ else
++ bdring_len = USB_BDRING_LEN;
++
++ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1);
++ ep->rxbuffer = kzalloc(size, GFP_ATOMIC);
++ if (ep->rxbuffer == NULL) {
++ dev_err(ep->udc->dev, "malloc rxbuffer failed,size=%d\n",
++ size);
++ kfree(ep->rxframe);
++ return -ENOMEM;
++ }
++
++ ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer);
++ if (ep->rxbuf_d == DMA_ADDR_INVALID) {
++ ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent,
++ ep->rxbuffer,
++ size,
++ DMA_FROM_DEVICE);
++ ep->rxbufmap = 1;
++ } else {
++ dma_sync_single_for_device(udc_controller->gadget.dev.parent,
++ ep->rxbuf_d, size,
++ DMA_FROM_DEVICE);
++ ep->rxbufmap = 0;
++ }
++
++ size = ep->ep.maxpacket + USB_CRC_SIZE + 2;
++ tmp = ep->rxbuf_d;
++ tmp = (u32)(((tmp >> 2) << 2) + 4);
++
++ for (i = 0; i < bdring_len - 1; i++) {
++ out_be32(&bd->buf, tmp);
++ out_be32((u32 __iomem *)bd, (R_E | R_I));
++ tmp = tmp + size;
++ bd++;
++ }
++ out_be32(&bd->buf, tmp);
++ out_be32((u32 __iomem *)bd, (R_E | R_I | R_W));
++
++ return 0;
++}
++
++static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num)
++{
++ struct qe_ep *ep = &udc->eps[pipe_num];
++ struct usb_ep_para __iomem *epparam;
++ u16 usep, logepnum;
++ u16 tmp;
++ u8 rtfcr = 0;
++
++ epparam = udc->ep_param[pipe_num];
++
++ usep = 0;
++ logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
++ usep |= (logepnum << USB_EPNUM_SHIFT);
++
++ switch (ep->desc->bmAttributes & 0x03) {
++ case USB_ENDPOINT_XFER_BULK:
++ usep |= USB_TRANS_BULK;
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ usep |= USB_TRANS_ISO;
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ usep |= USB_TRANS_INT;
++ break;
++ default:
++ usep |= USB_TRANS_CTR;
++ break;
++ }
++
++ switch (ep->dir) {
++ case USB_DIR_OUT:
++ usep |= USB_THS_IGNORE_IN;
++ break;
++ case USB_DIR_IN:
++ usep |= USB_RHS_IGNORE_OUT;
++ break;
++ default:
++ break;
++ }
++ out_be16(&udc->usb_regs->usb_usep[pipe_num], usep);
++
++ rtfcr = 0x30;
++ out_8(&epparam->rbmr, rtfcr);
++ out_8(&epparam->tbmr, rtfcr);
++
++ tmp = (u16)(ep->ep.maxpacket + USB_CRC_SIZE);
++ /* MRBLR must be divisble by 4 */
++ tmp = (u16)(((tmp >> 2) << 2) + 4);
++ out_be16(&epparam->mrblr, tmp);
++
++ return 0;
++}
++
++static int qe_ep_init(struct qe_udc *udc,
++ unsigned char pipe_num,
++ const struct usb_endpoint_descriptor *desc)
++{
++ struct qe_ep *ep = &udc->eps[pipe_num];
++ unsigned long flags;
++ int reval = 0;
++ u16 max = 0;
++
++ max = le16_to_cpu(desc->wMaxPacketSize);
++
++ /* check the max package size validate for this endpoint */
++ /* Refer to USB2.0 spec table 9-13,
++ */
++ if (pipe_num != 0) {
++ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
++ case USB_ENDPOINT_XFER_BULK:
++ if (strstr(ep->ep.name, "-iso")
++ || strstr(ep->ep.name, "-int"))
++ goto en_done;
++ switch (udc->gadget.speed) {
++ case USB_SPEED_HIGH:
++ if ((max == 128) || (max == 256) || (max == 512))
++ break;
++ default:
++ switch (max) {
++ case 4:
++ case 8:
++ case 16:
++ case 32:
++ case 64:
++ break;
++ default:
++ case USB_SPEED_LOW:
++ goto en_done;
++ }
++ }
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ if (strstr(ep->ep.name, "-iso")) /* bulk is ok */
++ goto en_done;
++ switch (udc->gadget.speed) {
++ case USB_SPEED_HIGH:
++ if (max <= 1024)
++ break;
++ case USB_SPEED_FULL:
++ if (max <= 64)
++ break;
++ default:
++ if (max <= 8)
++ break;
++ goto en_done;
++ }
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ if (strstr(ep->ep.name, "-bulk")
++ || strstr(ep->ep.name, "-int"))
++ goto en_done;
++ switch (udc->gadget.speed) {
++ case USB_SPEED_HIGH:
++ if (max <= 1024)
++ break;
++ case USB_SPEED_FULL:
++ if (max <= 1023)
++ break;
++ default:
++ goto en_done;
++ }
++ break;
++ case USB_ENDPOINT_XFER_CONTROL:
++ if (strstr(ep->ep.name, "-iso")
++ || strstr(ep->ep.name, "-int"))
++ goto en_done;
++ switch (udc->gadget.speed) {
++ case USB_SPEED_HIGH:
++ case USB_SPEED_FULL:
++ switch (max) {
++ case 1:
++ case 2:
++ case 4:
++ case 8:
++ case 16:
++ case 32:
++ case 64:
++ break;
++ default:
++ goto en_done;
++ }
++ case USB_SPEED_LOW:
++ switch (max) {
++ case 1:
++ case 2:
++ case 4:
++ case 8:
++ break;
++ default:
++ goto en_done;
++ }
++ default:
++ goto en_done;
++ }
++ break;
++
++ default:
++ goto en_done;
++ }
++ } /* if ep0*/
++
++ spin_lock_irqsave(&udc->lock, flags);
++
++ /* initialize ep structure */
++ ep->ep.maxpacket = max;
++ ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
++ ep->desc = desc;
++ ep->stopped = 0;
++ ep->init = 1;
++
++ if (pipe_num == 0) {
++ ep->dir = USB_DIR_BOTH;
++ udc->ep0_dir = USB_DIR_OUT;
++ udc->ep0_state = WAIT_FOR_SETUP;
++ } else {
++ switch (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
++ case USB_DIR_OUT:
++ ep->dir = USB_DIR_OUT;
++ break;
++ case USB_DIR_IN:
++ ep->dir = USB_DIR_IN;
++ default:
++ break;
++ }
++ }
++
++ /* hardware special operation */
++ qe_ep_bd_init(udc, pipe_num);
++ if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_OUT)) {
++ reval = qe_ep_rxbd_update(ep);
++ if (reval)
++ goto en_done1;
++ }
++
++ if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) {
++ ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC);
++ if (ep->txframe == NULL) {
++ dev_err(udc->dev, "malloc txframe failed\n");
++ goto en_done2;
++ }
++ qe_frame_init(ep->txframe);
++ }
++
++ qe_ep_register_init(udc, pipe_num);
++
++ /* Now HW will be NAKing transfers to that EP,
++ * until a buffer is queued to it. */
++ spin_unlock_irqrestore(&udc->lock, flags);
++
++ return 0;
++en_done2:
++ kfree(ep->rxbuffer);
++ kfree(ep->rxframe);
++en_done1:
++ spin_unlock_irqrestore(&udc->lock, flags);
++en_done:
++ dev_dbg(udc->dev, "failed to initialize %s\n", ep->ep.name);
++ return -ENODEV;
++}
++
++static inline void qe_usb_enable(void)
++{
++ setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
++}
++
++static inline void qe_usb_disable(void)
++{
++ clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
++}
++
++/*----------------------------------------------------------------------------*
++ * USB and EP basic manipulate function end *
++ *----------------------------------------------------------------------------*/
++
++
++/******************************************************************************
++ UDC transmit and receive process
++ ******************************************************************************/
++static void recycle_one_rxbd(struct qe_ep *ep)
++{
++ u32 bdstatus;
++
++ bdstatus = in_be32((u32 __iomem *)ep->e_rxbd);
++ bdstatus = R_I | R_E | (bdstatus & R_W);
++ out_be32((u32 __iomem *)ep->e_rxbd, bdstatus);
++
++ if (bdstatus & R_W)
++ ep->e_rxbd = ep->rxbase;
++ else
++ ep->e_rxbd++;
++}
++
++static void recycle_rxbds(struct qe_ep *ep, unsigned char stopatnext)
++{
++ u32 bdstatus;
++ struct qe_bd __iomem *bd, *nextbd;
++ unsigned char stop = 0;
++
++ nextbd = ep->n_rxbd;
++ bd = ep->e_rxbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++
++ while (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK) && !stop) {
++ bdstatus = R_E | R_I | (bdstatus & R_W);
++ out_be32((u32 __iomem *)bd, bdstatus);
++
++ if (bdstatus & R_W)
++ bd = ep->rxbase;
++ else
++ bd++;
++
++ bdstatus = in_be32((u32 __iomem *)bd);
++ if (stopatnext && (bd == nextbd))
++ stop = 1;
++ }
++
++ ep->e_rxbd = bd;
++}
++
++static void ep_recycle_rxbds(struct qe_ep *ep)
++{
++ struct qe_bd __iomem *bd = ep->n_rxbd;
++ u32 bdstatus;
++ u8 epnum = ep->epnum;
++ struct qe_udc *udc = ep->udc;
++
++ bdstatus = in_be32((u32 __iomem *)bd);
++ if (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK)) {
++ bd = ep->rxbase +
++ ((in_be16(&udc->ep_param[epnum]->rbptr) -
++ in_be16(&udc->ep_param[epnum]->rbase))
++ >> 3);
++ bdstatus = in_be32((u32 __iomem *)bd);
++
++ if (bdstatus & R_W)
++ bd = ep->rxbase;
++ else
++ bd++;
++
++ ep->e_rxbd = bd;
++ recycle_rxbds(ep, 0);
++ ep->e_rxbd = ep->n_rxbd;
++ } else
++ recycle_rxbds(ep, 1);
++
++ if (in_be16(&udc->usb_regs->usb_usber) & USB_E_BSY_MASK)
++ out_be16(&udc->usb_regs->usb_usber, USB_E_BSY_MASK);
++
++ if (ep->has_data <= 0 && (!list_empty(&ep->queue)))
++ qe_eprx_normal(ep);
++
++ ep->localnack = 0;
++}
++
++static void setup_received_handle(struct qe_udc *udc,
++ struct usb_ctrlrequest *setup);
++static int qe_ep_rxframe_handle(struct qe_ep *ep);
++static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req);
++/* when BD PID is setup, handle the packet */
++static int ep0_setup_handle(struct qe_udc *udc)
++{
++ struct qe_ep *ep = &udc->eps[0];
++ struct qe_frame *pframe;
++ unsigned int fsize;
++ u8 *cp;
++
++ pframe = ep->rxframe;
++ if ((frame_get_info(pframe) & PID_SETUP)
++ && (udc->ep0_state == WAIT_FOR_SETUP)) {
++ fsize = frame_get_length(pframe);
++ if (unlikely(fsize != 8))
++ return -EINVAL;
++ cp = (u8 *)&udc->local_setup_buff;
++ memcpy(cp, pframe->data, fsize);
++ ep->data01 = 1;
++
++ /* handle the usb command base on the usb_ctrlrequest */
++ setup_received_handle(udc, &udc->local_setup_buff);
++ return 0;
++ }
++ return -EINVAL;
++}
++
++static int qe_ep0_rx(struct qe_udc *udc)
++{
++ struct qe_ep *ep = &udc->eps[0];
++ struct qe_frame *pframe;
++ struct qe_bd __iomem *bd;
++ u32 bdstatus, length;
++ u32 vaddr;
++
++ pframe = ep->rxframe;
++
++ if (ep->dir == USB_DIR_IN) {
++ dev_err(udc->dev, "ep0 not a control endpoint\n");
++ return -EINVAL;
++ }
++
++ bd = ep->n_rxbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++
++ while (!(bdstatus & R_E) && length) {
++ if ((bdstatus & R_F) && (bdstatus & R_L)
++ && !(bdstatus & R_ERROR)) {
++ if (length == USB_CRC_SIZE) {
++ udc->ep0_state = WAIT_FOR_SETUP;
++ dev_vdbg(udc->dev,
++ "receive a ZLP in status phase\n");
++ } else {
++ qe_frame_clean(pframe);
++ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
++ frame_set_data(pframe, (u8 *)vaddr);
++ frame_set_length(pframe,
++ (length - USB_CRC_SIZE));
++ frame_set_status(pframe, FRAME_OK);
++ switch (bdstatus & R_PID) {
++ case R_PID_SETUP:
++ frame_set_info(pframe, PID_SETUP);
++ break;
++ case R_PID_DATA1:
++ frame_set_info(pframe, PID_DATA1);
++ break;
++ default:
++ frame_set_info(pframe, PID_DATA0);
++ break;
++ }
++
++ if ((bdstatus & R_PID) == R_PID_SETUP)
++ ep0_setup_handle(udc);
++ else
++ qe_ep_rxframe_handle(ep);
++ }
++ } else {
++ dev_err(udc->dev, "The receive frame with error!\n");
++ }
++
++ /* note: don't clear the rxbd's buffer address */
++ recycle_one_rxbd(ep);
++
++ /* Get next BD */
++ if (bdstatus & R_W)
++ bd = ep->rxbase;
++ else
++ bd++;
++
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++
++ }
++
++ ep->n_rxbd = bd;
++
++ return 0;
++}
++
++static int qe_ep_rxframe_handle(struct qe_ep *ep)
++{
++ struct qe_frame *pframe;
++ u8 framepid = 0;
++ unsigned int fsize;
++ u8 *cp;
++ struct qe_req *req;
++
++ pframe = ep->rxframe;
++
++ if (frame_get_info(pframe) & PID_DATA1)
++ framepid = 0x1;
++
++ if (framepid != ep->data01) {
++ dev_err(ep->udc->dev, "the data01 error!\n");
++ return -EIO;
++ }
++
++ fsize = frame_get_length(pframe);
++ if (list_empty(&ep->queue)) {
++ dev_err(ep->udc->dev, "the %s have no requeue!\n", ep->name);
++ } else {
++ req = list_entry(ep->queue.next, struct qe_req, queue);
++
++ cp = (u8 *)(req->req.buf) + req->req.actual;
++ if (cp) {
++ memcpy(cp, pframe->data, fsize);
++ req->req.actual += fsize;
++ if ((fsize < ep->ep.maxpacket) ||
++ (req->req.actual >= req->req.length)) {
++ if (ep->epnum == 0)
++ ep0_req_complete(ep->udc, req);
++ else
++ done(ep, req, 0);
++ if (list_empty(&ep->queue) && ep->epnum != 0)
++ qe_eprx_nack(ep);
++ }
++ }
++ }
++
++ qe_ep_toggledata01(ep);
++
++ return 0;
++}
++
++static void ep_rx_tasklet(unsigned long data)
++{
++ struct qe_udc *udc = (struct qe_udc *)data;
++ struct qe_ep *ep;
++ struct qe_frame *pframe;
++ struct qe_bd __iomem *bd;
++ unsigned long flags;
++ u32 bdstatus, length;
++ u32 vaddr, i;
++
++ spin_lock_irqsave(&udc->lock, flags);
++
++ for (i = 1; i < USB_MAX_ENDPOINTS; i++) {
++ ep = &udc->eps[i];
++
++ if (ep->dir == USB_DIR_IN || ep->enable_tasklet == 0) {
++ dev_dbg(udc->dev,
++ "This is a transmit ep or disable tasklet!\n");
++ continue;
++ }
++
++ pframe = ep->rxframe;
++ bd = ep->n_rxbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++
++ while (!(bdstatus & R_E) && length) {
++ if (list_empty(&ep->queue)) {
++ qe_eprx_nack(ep);
++ dev_dbg(udc->dev,
++ "The rxep have noreq %d\n",
++ ep->has_data);
++ break;
++ }
++
++ if ((bdstatus & R_F) && (bdstatus & R_L)
++ && !(bdstatus & R_ERROR)) {
++ qe_frame_clean(pframe);
++ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
++ frame_set_data(pframe, (u8 *)vaddr);
++ frame_set_length(pframe,
++ (length - USB_CRC_SIZE));
++ frame_set_status(pframe, FRAME_OK);
++ switch (bdstatus & R_PID) {
++ case R_PID_DATA1:
++ frame_set_info(pframe, PID_DATA1);
++ break;
++ case R_PID_SETUP:
++ frame_set_info(pframe, PID_SETUP);
++ break;
++ default:
++ frame_set_info(pframe, PID_DATA0);
++ break;
++ }
++ /* handle the rx frame */
++ qe_ep_rxframe_handle(ep);
++ } else {
++ dev_err(udc->dev,
++ "error in received frame\n");
++ }
++ /* note: don't clear the rxbd's buffer address */
++ /*clear the length */
++ out_be32((u32 __iomem *)bd, bdstatus & BD_STATUS_MASK);
++ ep->has_data--;
++ if (!(ep->localnack))
++ recycle_one_rxbd(ep);
++
++ /* Get next BD */
++ if (bdstatus & R_W)
++ bd = ep->rxbase;
++ else
++ bd++;
++
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++ }
++
++ ep->n_rxbd = bd;
++
++ if (ep->localnack)
++ ep_recycle_rxbds(ep);
++
++ ep->enable_tasklet = 0;
++ } /* for i=1 */
++
++ spin_unlock_irqrestore(&udc->lock, flags);
++}
++
++static int qe_ep_rx(struct qe_ep *ep)
++{
++ struct qe_udc *udc;
++ struct qe_frame *pframe;
++ struct qe_bd __iomem *bd;
++ u16 swoffs, ucoffs, emptybds;
++
++ udc = ep->udc;
++ pframe = ep->rxframe;
++
++ if (ep->dir == USB_DIR_IN) {
++ dev_err(udc->dev, "transmit ep in rx function\n");
++ return -EINVAL;
++ }
++
++ bd = ep->n_rxbd;
++
++ swoffs = (u16)(bd - ep->rxbase);
++ ucoffs = (u16)((in_be16(&udc->ep_param[ep->epnum]->rbptr) -
++ in_be16(&udc->ep_param[ep->epnum]->rbase)) >> 3);
++ if (swoffs < ucoffs)
++ emptybds = USB_BDRING_LEN_RX - ucoffs + swoffs;
++ else
++ emptybds = swoffs - ucoffs;
++
++ if (emptybds < MIN_EMPTY_BDS) {
++ qe_eprx_nack(ep);
++ ep->localnack = 1;
++ dev_vdbg(udc->dev, "%d empty bds, send NACK\n", emptybds);
++ }
++ ep->has_data = USB_BDRING_LEN_RX - emptybds;
++
++ if (list_empty(&ep->queue)) {
++ qe_eprx_nack(ep);
++ dev_vdbg(udc->dev, "The rxep have no req queued with %d BDs\n",
++ ep->has_data);
++ return 0;
++ }
++
++ tasklet_schedule(&udc->rx_tasklet);
++ ep->enable_tasklet = 1;
++
++ return 0;
++}
++
++/* send data from a frame, no matter what tx_req */
++static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame)
++{
++ struct qe_udc *udc = ep->udc;
++ struct qe_bd __iomem *bd;
++ u16 saveusbmr;
++ u32 bdstatus, pidmask;
++ u32 paddr;
++
++ if (ep->dir == USB_DIR_OUT) {
++ dev_err(udc->dev, "receive ep passed to tx function\n");
++ return -EINVAL;
++ }
++
++ /* Disable the Tx interrupt */
++ saveusbmr = in_be16(&udc->usb_regs->usb_usbmr);
++ out_be16(&udc->usb_regs->usb_usbmr,
++ saveusbmr & ~(USB_E_TXB_MASK | USB_E_TXE_MASK));
++
++ bd = ep->n_txbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++
++ if (!(bdstatus & (T_R | BD_LENGTH_MASK))) {
++ if (frame_get_length(frame) == 0) {
++ frame_set_data(frame, udc->nullbuf);
++ frame_set_length(frame, 2);
++ frame->info |= (ZLP | NO_CRC);
++ dev_vdbg(udc->dev, "the frame size = 0\n");
++ }
++ paddr = virt_to_phys((void *)frame->data);
++ out_be32(&bd->buf, paddr);
++ bdstatus = (bdstatus&T_W);
++ if (!(frame_get_info(frame) & NO_CRC))
++ bdstatus |= T_R | T_I | T_L | T_TC
++ | frame_get_length(frame);
++ else
++ bdstatus |= T_R | T_I | T_L | frame_get_length(frame);
++
++ /* if the packet is a ZLP in status phase */
++ if ((ep->epnum == 0) && (udc->ep0_state == DATA_STATE_NEED_ZLP))
++ ep->data01 = 0x1;
++
++ if (ep->data01) {
++ pidmask = T_PID_DATA1;
++ frame->info |= PID_DATA1;
++ } else {
++ pidmask = T_PID_DATA0;
++ frame->info |= PID_DATA0;
++ }
++ bdstatus |= T_CNF;
++ bdstatus |= pidmask;
++ out_be32((u32 __iomem *)bd, bdstatus);
++ qe_ep_filltxfifo(ep);
++
++ /* enable the TX interrupt */
++ out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
++
++ qe_ep_toggledata01(ep);
++ if (bdstatus & T_W)
++ ep->n_txbd = ep->txbase;
++ else
++ ep->n_txbd++;
++
++ return 0;
++ } else {
++ out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
++ dev_vdbg(udc->dev, "The tx bd is not ready!\n");
++ return -EBUSY;
++ }
++}
++
++/* when an bd was transmitted, the function can *
++ * handle the tx_req, not include ep0 */
++static int txcomplete(struct qe_ep *ep, unsigned char restart)
++{
++ if (ep->tx_req != NULL) {
++ if (!restart) {
++ int asent = ep->last;
++ ep->sent += asent;
++ ep->last -= asent;
++ } else {
++ ep->last = 0;
++ }
++
++ /* a request already were transmitted completely */
++ if ((ep->tx_req->req.length - ep->sent) <= 0) {
++ ep->tx_req->req.actual = (unsigned int)ep->sent;
++ done(ep, ep->tx_req, 0);
++ ep->tx_req = NULL;
++ ep->last = 0;
++ ep->sent = 0;
++ }
++ }
++
++ /* we should gain a new tx_req fot this endpoint */
++ if (ep->tx_req == NULL) {
++ if (!list_empty(&ep->queue)) {
++ ep->tx_req = list_entry(ep->queue.next, struct qe_req,
++ queue);
++ ep->last = 0;
++ ep->sent = 0;
++ }
++ }
++
++ return 0;
++}
++
++/* give a frame and a tx_req,send some data */
++static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame)
++{
++ unsigned int size;
++ u8 *buf;
++
++ qe_frame_clean(frame);
++ size = min_t(u32, (ep->tx_req->req.length - ep->sent),
++ ep->ep.maxpacket);
++ buf = (u8 *)ep->tx_req->req.buf + ep->sent;
++ if (buf && size) {
++ ep->last = size;
++ frame_set_data(frame, buf);
++ frame_set_length(frame, size);
++ frame_set_status(frame, FRAME_OK);
++ frame_set_info(frame, 0);
++ return qe_ep_tx(ep, frame);
++ }
++ return -EIO;
++}
++
++/* give a frame struct,send a ZLP */
++static int sendnulldata(struct qe_ep *ep, struct qe_frame *frame, uint infor)
++{
++ struct qe_udc *udc = ep->udc;
++
++ if (frame == NULL)
++ return -ENODEV;
++
++ qe_frame_clean(frame);
++ frame_set_data(frame, (u8 *)udc->nullbuf);
++ frame_set_length(frame, 2);
++ frame_set_status(frame, FRAME_OK);
++ frame_set_info(frame, (ZLP | NO_CRC | infor));
++
++ return qe_ep_tx(ep, frame);
++}
++
++static int frame_create_tx(struct qe_ep *ep, struct qe_frame *frame)
++{
++ struct qe_req *req = ep->tx_req;
++ int reval;
++
++ if (req == NULL)
++ return -ENODEV;
++
++ if ((req->req.length - ep->sent) > 0)
++ reval = qe_usb_senddata(ep, frame);
++ else
++ reval = sendnulldata(ep, frame, 0);
++
++ return reval;
++}
++
++/* if direction is DIR_IN, the status is Device->Host
++ * if direction is DIR_OUT, the status transaction is Device<-Host
++ * in status phase, udc create a request and gain status */
++static int ep0_prime_status(struct qe_udc *udc, int direction)
++{
++
++ struct qe_ep *ep = &udc->eps[0];
++
++ if (direction == USB_DIR_IN) {
++ udc->ep0_state = DATA_STATE_NEED_ZLP;
++ udc->ep0_dir = USB_DIR_IN;
++ sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
++ } else {
++ udc->ep0_dir = USB_DIR_OUT;
++ udc->ep0_state = WAIT_FOR_OUT_STATUS;
++ }
++
++ return 0;
++}
++
++/* a request complete in ep0, whether gadget request or udc request */
++static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req)
++{
++ struct qe_ep *ep = &udc->eps[0];
++ /* because usb and ep's status already been set in ch9setaddress() */
++
++ switch (udc->ep0_state) {
++ case DATA_STATE_XMIT:
++ done(ep, req, 0);
++ /* receive status phase */
++ if (ep0_prime_status(udc, USB_DIR_OUT))
++ qe_ep0_stall(udc);
++ break;
++
++ case DATA_STATE_NEED_ZLP:
++ done(ep, req, 0);
++ udc->ep0_state = WAIT_FOR_SETUP;
++ break;
++
++ case DATA_STATE_RECV:
++ done(ep, req, 0);
++ /* send status phase */
++ if (ep0_prime_status(udc, USB_DIR_IN))
++ qe_ep0_stall(udc);
++ break;
++
++ case WAIT_FOR_OUT_STATUS:
++ done(ep, req, 0);
++ udc->ep0_state = WAIT_FOR_SETUP;
++ break;
++
++ case WAIT_FOR_SETUP:
++ dev_vdbg(udc->dev, "Unexpected interrupt\n");
++ break;
++
++ default:
++ qe_ep0_stall(udc);
++ break;
++ }
++}
++
++static int ep0_txcomplete(struct qe_ep *ep, unsigned char restart)
++{
++ struct qe_req *tx_req = NULL;
++ struct qe_frame *frame = ep->txframe;
++
++ if ((frame_get_info(frame) & (ZLP | NO_REQ)) == (ZLP | NO_REQ)) {
++ if (!restart)
++ ep->udc->ep0_state = WAIT_FOR_SETUP;
++ else
++ sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
++ return 0;
++ }
++
++ tx_req = ep->tx_req;
++ if (tx_req != NULL) {
++ if (!restart) {
++ int asent = ep->last;
++ ep->sent += asent;
++ ep->last -= asent;
++ } else {
++ ep->last = 0;
++ }
++
++ /* a request already were transmitted completely */
++ if ((ep->tx_req->req.length - ep->sent) <= 0) {
++ ep->tx_req->req.actual = (unsigned int)ep->sent;
++ ep0_req_complete(ep->udc, ep->tx_req);
++ ep->tx_req = NULL;
++ ep->last = 0;
++ ep->sent = 0;
++ }
++ } else {
++ dev_vdbg(ep->udc->dev, "the ep0_controller have no req\n");
++ }
++
++ return 0;
++}
++
++static int ep0_txframe_handle(struct qe_ep *ep)
++{
++ /* if have error, transmit again */
++ if (frame_get_status(ep->txframe) & FRAME_ERROR) {
++ qe_ep_flushtxfifo(ep);
++ dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
++ if (frame_get_info(ep->txframe) & PID_DATA0)
++ ep->data01 = 0;
++ else
++ ep->data01 = 1;
++
++ ep0_txcomplete(ep, 1);
++ } else
++ ep0_txcomplete(ep, 0);
++
++ frame_create_tx(ep, ep->txframe);
++ return 0;
++}
++
++static int qe_ep0_txconf(struct qe_ep *ep)
++{
++ struct qe_bd __iomem *bd;
++ struct qe_frame *pframe;
++ u32 bdstatus;
++
++ bd = ep->c_txbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
++ pframe = ep->txframe;
++
++ /* clear and recycle the BD */
++ out_be32((u32 __iomem *)bd, bdstatus & T_W);
++ out_be32(&bd->buf, 0);
++ if (bdstatus & T_W)
++ ep->c_txbd = ep->txbase;
++ else
++ ep->c_txbd++;
++
++ if (ep->c_txbd == ep->n_txbd) {
++ if (bdstatus & DEVICE_T_ERROR) {
++ frame_set_status(pframe, FRAME_ERROR);
++ if (bdstatus & T_TO)
++ pframe->status |= TX_ER_TIMEOUT;
++ if (bdstatus & T_UN)
++ pframe->status |= TX_ER_UNDERUN;
++ }
++ ep0_txframe_handle(ep);
++ }
++
++ bd = ep->c_txbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ }
++
++ return 0;
++}
++
++static int ep_txframe_handle(struct qe_ep *ep)
++{
++ if (frame_get_status(ep->txframe) & FRAME_ERROR) {
++ qe_ep_flushtxfifo(ep);
++ dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
++ if (frame_get_info(ep->txframe) & PID_DATA0)
++ ep->data01 = 0;
++ else
++ ep->data01 = 1;
++
++ txcomplete(ep, 1);
++ } else
++ txcomplete(ep, 0);
++
++ frame_create_tx(ep, ep->txframe); /* send the data */
++ return 0;
++}
++
++/* confirm the already trainsmited bd */
++static int qe_ep_txconf(struct qe_ep *ep)
++{
++ struct qe_bd __iomem *bd;
++ struct qe_frame *pframe = NULL;
++ u32 bdstatus;
++ unsigned char breakonrxinterrupt = 0;
++
++ bd = ep->c_txbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
++ pframe = ep->txframe;
++ if (bdstatus & DEVICE_T_ERROR) {
++ frame_set_status(pframe, FRAME_ERROR);
++ if (bdstatus & T_TO)
++ pframe->status |= TX_ER_TIMEOUT;
++ if (bdstatus & T_UN)
++ pframe->status |= TX_ER_UNDERUN;
++ }
++
++ /* clear and recycle the BD */
++ out_be32((u32 __iomem *)bd, bdstatus & T_W);
++ out_be32(&bd->buf, 0);
++ if (bdstatus & T_W)
++ ep->c_txbd = ep->txbase;
++ else
++ ep->c_txbd++;
++
++ /* handle the tx frame */
++ ep_txframe_handle(ep);
++ bd = ep->c_txbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ }
++ if (breakonrxinterrupt)
++ return -EIO;
++ else
++ return 0;
++}
++
++/* Add a request in queue, and try to transmit a packet */
++static int ep_req_send(struct qe_ep *ep, struct qe_req *req)
++{
++ int reval = 0;
++
++ if (ep->tx_req == NULL) {
++ ep->sent = 0;
++ ep->last = 0;
++ txcomplete(ep, 0); /* can gain a new tx_req */
++ reval = frame_create_tx(ep, ep->txframe);
++ }
++ return reval;
++}
++
++/* Maybe this is a good ideal */
++static int ep_req_rx(struct qe_ep *ep, struct qe_req *req)
++{
++ struct qe_udc *udc = ep->udc;
++ struct qe_frame *pframe = NULL;
++ struct qe_bd __iomem *bd;
++ u32 bdstatus, length;
++ u32 vaddr, fsize;
++ u8 *cp;
++ u8 finish_req = 0;
++ u8 framepid;
++
++ if (list_empty(&ep->queue)) {
++ dev_vdbg(udc->dev, "the req already finish!\n");
++ return 0;
++ }
++ pframe = ep->rxframe;
++
++ bd = ep->n_rxbd;
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++
++ while (!(bdstatus & R_E) && length) {
++ if (finish_req)
++ break;
++ if ((bdstatus & R_F) && (bdstatus & R_L)
++ && !(bdstatus & R_ERROR)) {
++ qe_frame_clean(pframe);
++ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
++ frame_set_data(pframe, (u8 *)vaddr);
++ frame_set_length(pframe, (length - USB_CRC_SIZE));
++ frame_set_status(pframe, FRAME_OK);
++ switch (bdstatus & R_PID) {
++ case R_PID_DATA1:
++ frame_set_info(pframe, PID_DATA1); break;
++ default:
++ frame_set_info(pframe, PID_DATA0); break;
++ }
++ /* handle the rx frame */
++
++ if (frame_get_info(pframe) & PID_DATA1)
++ framepid = 0x1;
++ else
++ framepid = 0;
++
++ if (framepid != ep->data01) {
++ dev_vdbg(udc->dev, "the data01 error!\n");
++ } else {
++ fsize = frame_get_length(pframe);
++
++ cp = (u8 *)(req->req.buf) + req->req.actual;
++ if (cp) {
++ memcpy(cp, pframe->data, fsize);
++ req->req.actual += fsize;
++ if ((fsize < ep->ep.maxpacket)
++ || (req->req.actual >=
++ req->req.length)) {
++ finish_req = 1;
++ done(ep, req, 0);
++ if (list_empty(&ep->queue))
++ qe_eprx_nack(ep);
++ }
++ }
++ qe_ep_toggledata01(ep);
++ }
++ } else {
++ dev_err(udc->dev, "The receive frame with error!\n");
++ }
++
++ /* note: don't clear the rxbd's buffer address *
++ * only Clear the length */
++ out_be32((u32 __iomem *)bd, (bdstatus & BD_STATUS_MASK));
++ ep->has_data--;
++
++ /* Get next BD */
++ if (bdstatus & R_W)
++ bd = ep->rxbase;
++ else
++ bd++;
++
++ bdstatus = in_be32((u32 __iomem *)bd);
++ length = bdstatus & BD_LENGTH_MASK;
++ }
++
++ ep->n_rxbd = bd;
++ ep_recycle_rxbds(ep);
++
++ return 0;
++}
++
++/* only add the request in queue */
++static int ep_req_receive(struct qe_ep *ep, struct qe_req *req)
++{
++ if (ep->state == EP_STATE_NACK) {
++ if (ep->has_data <= 0) {
++ /* Enable rx and unmask rx interrupt */
++ qe_eprx_normal(ep);
++ } else {
++ /* Copy the exist BD data */
++ ep_req_rx(ep, req);
++ }
++ }
++
++ return 0;
++}
++
++/********************************************************************
++ Internal Used Function End
++********************************************************************/
++
++/*-----------------------------------------------------------------------
++ Endpoint Management Functions For Gadget
++ -----------------------------------------------------------------------*/
++static int qe_ep_enable(struct usb_ep *_ep,
++ const struct usb_endpoint_descriptor *desc)
++{
++ struct qe_udc *udc;
++ struct qe_ep *ep;
++ int retval = 0;
++ unsigned char epnum;
++
++ ep = container_of(_ep, struct qe_ep, ep);
++
++ /* catch various bogus parameters */
++ if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] ||
++ (desc->bDescriptorType != USB_DT_ENDPOINT))
++ return -EINVAL;
++
++ udc = ep->udc;
++ if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN))
++ return -ESHUTDOWN;
++
++ epnum = (u8)desc->bEndpointAddress & 0xF;
++
++ retval = qe_ep_init(udc, epnum, desc);
++ if (retval != 0) {
++ cpm_muram_free(cpm_muram_offset(ep->rxbase));
++ dev_dbg(udc->dev, "enable ep%d failed\n", ep->epnum);
++ return -EINVAL;
++ }
++ dev_dbg(udc->dev, "enable ep%d successful\n", ep->epnum);
++ return 0;
++}
++
++static int qe_ep_disable(struct usb_ep *_ep)
++{
++ struct qe_udc *udc;
++ struct qe_ep *ep;
++ unsigned long flags;
++ unsigned int size;
++
++ ep = container_of(_ep, struct qe_ep, ep);
++ udc = ep->udc;
++
++ if (!_ep || !ep->desc) {
++ dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL);
++ return -EINVAL;
++ }
++
++ spin_lock_irqsave(&udc->lock, flags);
++ /* Nuke all pending requests (does flush) */
++ nuke(ep, -ESHUTDOWN);
++ ep->desc = NULL;
++ ep->stopped = 1;
++ spin_unlock_irqrestore(&udc->lock, flags);
++
++ cpm_muram_free(cpm_muram_offset(ep->rxbase));
++
++ if (ep->dir == USB_DIR_OUT)
++ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
++ (USB_BDRING_LEN_RX + 1);
++ else
++ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
++ (USB_BDRING_LEN + 1);
++
++ if (ep->dir != USB_DIR_IN) {
++ kfree(ep->rxframe);
++ if (ep->rxbufmap) {
++ dma_unmap_single(udc_controller->gadget.dev.parent,
++ ep->rxbuf_d, size,
++ DMA_FROM_DEVICE);
++ ep->rxbuf_d = DMA_ADDR_INVALID;
++ } else {
++ dma_sync_single_for_cpu(
++ udc_controller->gadget.dev.parent,
++ ep->rxbuf_d, size,
++ DMA_FROM_DEVICE);
++ }
++ kfree(ep->rxbuffer);
++ }
++
++ if (ep->dir != USB_DIR_OUT)
++ kfree(ep->txframe);
++
++ dev_dbg(udc->dev, "disabled %s OK\n", _ep->name);
++ return 0;
++}
++
++static struct usb_request *qe_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
++{
++ struct qe_req *req;
++
++ req = kzalloc(sizeof(*req), gfp_flags);
++ if (!req)
++ return NULL;
++
++ req->req.dma = DMA_ADDR_INVALID;
++
++ INIT_LIST_HEAD(&req->queue);
++
++ return &req->req;
++}
++
++static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct qe_req *req;
++
++ req = container_of(_req, struct qe_req, req);
++
++ if (_req)
++ kfree(req);
++}
++
++/* queues (submits) an I/O request to an endpoint */
++static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
++ gfp_t gfp_flags)
++{
++ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
++ struct qe_req *req = container_of(_req, struct qe_req, req);
++ struct qe_udc *udc;
++ unsigned long flags;
++ int reval;
++
++ udc = ep->udc;
++ /* catch various bogus parameters */
++ if (!_req || !req->req.complete || !req->req.buf
++ || !list_empty(&req->queue)) {
++ dev_dbg(udc->dev, "bad params\n");
++ return -EINVAL;
++ }
++ if (!_ep || (!ep->desc && ep_index(ep))) {
++ dev_dbg(udc->dev, "bad ep\n");
++ return -EINVAL;
++ }
++
++ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
++ return -ESHUTDOWN;
++
++ req->ep = ep;
++
++ /* map virtual address to hardware */
++ if (req->req.dma == DMA_ADDR_INVALID) {
++ req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
++ req->req.buf,
++ req->req.length,
++ ep_is_in(ep)
++ ? DMA_TO_DEVICE :
++ DMA_FROM_DEVICE);
++ req->mapped = 1;
++ } else {
++ dma_sync_single_for_device(ep->udc->gadget.dev.parent,
++ req->req.dma, req->req.length,
++ ep_is_in(ep)
++ ? DMA_TO_DEVICE :
++ DMA_FROM_DEVICE);
++ req->mapped = 0;
++ }
++
++ req->req.status = -EINPROGRESS;
++ req->req.actual = 0;
++
++ list_add_tail(&req->queue, &ep->queue);
++ dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
++ ep->name, req->req.length);
++ spin_lock_irqsave(&udc->lock, flags);
++ /* push the request to device */
++ if (ep_is_in(ep))
++ reval = ep_req_send(ep, req);
++
++ /* EP0 */
++ if (ep_index(ep) == 0 && req->req.length > 0) {
++ if (ep_is_in(ep))
++ udc->ep0_state = DATA_STATE_XMIT;
++ else
++ udc->ep0_state = DATA_STATE_RECV;
++ }
++
++ if (ep->dir == USB_DIR_OUT)
++ reval = ep_req_receive(ep, req);
++
++ spin_unlock_irqrestore(&udc->lock, flags);
++
++ return 0;
++}
++
++/* dequeues (cancels, unlinks) an I/O request from an endpoint */
++static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
++ struct qe_req *req;
++ unsigned long flags;
++
++ if (!_ep || !_req)
++ return -EINVAL;
++
++ spin_lock_irqsave(&ep->udc->lock, flags);
++
++ /* make sure it's actually queued on this endpoint */
++ list_for_each_entry(req, &ep->queue, queue) {
++ if (&req->req == _req)
++ break;
++ }
++
++ if (&req->req != _req) {
++ spin_unlock_irqrestore(&ep->udc->lock, flags);
++ return -EINVAL;
++ }
++
++ done(ep, req, -ECONNRESET);
++
++ spin_unlock_irqrestore(&ep->udc->lock, flags);
++ return 0;
++}
++
++/*-----------------------------------------------------------------
++ * modify the endpoint halt feature
++ * @ep: the non-isochronous endpoint being stalled
++ * @value: 1--set halt 0--clear halt
++ * Returns zero, or a negative error code.
++*----------------------------------------------------------------*/
++static int qe_ep_set_halt(struct usb_ep *_ep, int value)
++{
++ struct qe_ep *ep;
++ unsigned long flags;
++ int status = -EOPNOTSUPP;
++ struct qe_udc *udc;
++
++ ep = container_of(_ep, struct qe_ep, ep);
++ if (!_ep || !ep->desc) {
++ status = -EINVAL;
++ goto out;
++ }
++
++ if (ep->epnum != 0) {
++ status = 0;
++ goto out;
++ }
++
++ udc = ep->udc;
++ /* Attempt to halt IN ep will fail if any transfer requests
++ * are still queue */
++ if (value && ep_is_in(ep) && !list_empty(&ep->queue)) {
++ status = -EAGAIN;
++ goto out;
++ }
++
++ status = 0;
++ spin_lock_irqsave(&ep->udc->lock, flags);
++ qe_eptx_stall_change(ep, value);
++ qe_eprx_stall_change(ep, value);
++ spin_unlock_irqrestore(&ep->udc->lock, flags);
++
++ if (ep->epnum == 0) {
++ udc->ep0_state = WAIT_FOR_SETUP;
++ udc->ep0_dir = 0;
++ }
++out:
++ dev_vdbg(udc->dev, " %s %s halt stat %d\n", ep->ep.name,
++ value ? "set" : "clear", status);
++
++ return status;
++}
++
++static struct usb_ep_ops qe_ep_ops = {
++ .enable = qe_ep_enable,
++ .disable = qe_ep_disable,
++
++ .alloc_request = qe_alloc_request,
++ .free_request = qe_free_request,
++
++ .queue = qe_ep_queue,
++ .dequeue = qe_ep_dequeue,
++
++ .set_halt = qe_ep_set_halt,
++};
++
++/*------------------------------------------------------------------------
++ Gadget Driver Layer Operations
++ ------------------------------------------------------------------------*/
++
++/* Get the current frame number */
++static int qe_get_frame(struct usb_gadget *gadget)
++{
++ u16 tmp;
++
++ tmp = in_be16(&udc_controller->usb_param->frame_n);
++ if (tmp & 0x8000)
++ tmp = tmp & 0x07ff;
++ else
++ tmp = -EINVAL;
++
++ return (int)tmp;
++}
++
++/* Tries to wake up the host connected to this gadget
++ *
++ * Return : 0-success
++ * Negative-this feature not enabled by host or not supported by device hw
++ */
++static int qe_wakeup(struct usb_gadget *gadget)
++{
++ return -ENOTSUPP;
++}
++
++/* Notify controller that VBUS is powered, Called by whatever
++ detects VBUS sessions */
++static int qe_vbus_session(struct usb_gadget *gadget, int is_active)
++{
++ return -ENOTSUPP;
++}
++
++/* constrain controller's VBUS power usage
++ * This call is used by gadget drivers during SET_CONFIGURATION calls,
++ * reporting how much power the device may consume. For example, this
++ * could affect how quickly batteries are recharged.
++ *
++ * Returns zero on success, else negative errno.
++ */
++static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA)
++{
++ return -ENOTSUPP;
++}
++
++/* Change Data+ pullup status
++ * this func is used by usb_gadget_connect/disconnect
++ */
++static int qe_pullup(struct usb_gadget *gadget, int is_on)
++{
++ return -ENOTSUPP;
++}
++
++/* defined in usb_gadget.h */
++static struct usb_gadget_ops qe_gadget_ops = {
++ .get_frame = qe_get_frame,
++ .wakeup = qe_wakeup,
++/* .set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */
++ .vbus_session = qe_vbus_session,
++ .vbus_draw = qe_vbus_draw,
++ .pullup = qe_pullup,
++};
++
++/*-------------------------------------------------------------------------
++ USB ep0 Setup process in BUS Enumeration
++ -------------------------------------------------------------------------*/
++static int udc_reset_ep_queue(struct qe_udc *udc, u8 pipe)
++{
++ struct qe_ep *ep = &udc->eps[pipe];
++
++ nuke(ep, -ECONNRESET);
++ ep->tx_req = NULL;
++ return 0;
++}
++
++static int reset_queues(struct qe_udc *udc)
++{
++ u8 pipe;
++
++ for (pipe = 0; pipe < USB_MAX_ENDPOINTS; pipe++)
++ udc_reset_ep_queue(udc, pipe);
++
++ /* report disconnect; the driver is already quiesced */
++ spin_unlock(&udc->lock);
++ udc->driver->disconnect(&udc->gadget);
++ spin_lock(&udc->lock);
++
++ return 0;
++}
++
++static void ch9setaddress(struct qe_udc *udc, u16 value, u16 index,
++ u16 length)
++{
++ /* Save the new address to device struct */
++ udc->device_address = (u8) value;
++ /* Update usb state */
++ udc->usb_state = USB_STATE_ADDRESS;
++
++ /* Status phase , send a ZLP */
++ if (ep0_prime_status(udc, USB_DIR_IN))
++ qe_ep0_stall(udc);
++}
++
++static void ownercomplete(struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct qe_req *req = container_of(_req, struct qe_req, req);
++
++ req->req.buf = NULL;
++ kfree(req);
++}
++
++static void ch9getstatus(struct qe_udc *udc, u16 value, u16 index,
++ u16 length)
++{
++ u16 usb_status = 0; /* fix me to give correct status */
++
++ struct qe_req *req;
++ struct qe_ep *ep;
++ int status = 0;
++
++ ep = &udc->eps[0];
++
++ req = container_of(qe_alloc_request(&ep->ep, GFP_KERNEL),
++ struct qe_req, req);
++ req->req.length = 2;
++ req->req.buf = udc->nullbuf;
++ memcpy(req->req.buf, (u8 *)&usb_status, 2);
++ req->req.status = -EINPROGRESS;
++ req->req.actual = 0;
++ req->req.complete = ownercomplete;
++
++ udc->ep0_dir = USB_DIR_IN;
++
++ /* data phase */
++ status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
++
++ if (status) {
++ dev_err(udc->dev, "Can't respond to getstatus request \n");
++ qe_ep0_stall(udc);
++ }
++}
++
++/* only handle the setup request, suppose the device in normal status */
++static void setup_received_handle(struct qe_udc *udc,
++ struct usb_ctrlrequest *setup)
++{
++ /* Fix Endian (udc->local_setup_buff is cpu Endian now)*/
++ u16 wValue = le16_to_cpu(setup->wValue);
++ u16 wIndex = le16_to_cpu(setup->wIndex);
++ u16 wLength = le16_to_cpu(setup->wLength);
++
++ /* clear the previous request in the ep0 */
++ udc_reset_ep_queue(udc, 0);
++
++ if (setup->bRequestType & USB_DIR_IN)
++ udc->ep0_dir = USB_DIR_IN;
++ else
++ udc->ep0_dir = USB_DIR_OUT;
++
++ switch (setup->bRequest) {
++ case USB_REQ_GET_STATUS:
++ /* Data+Status phase form udc */
++ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
++ != (USB_DIR_IN | USB_TYPE_STANDARD))
++ break;
++ ch9getstatus(udc, wValue, wIndex, wLength);
++ return;
++
++ case USB_REQ_SET_ADDRESS:
++ /* Status phase from udc */
++ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
++ USB_RECIP_DEVICE))
++ break;
++ ch9setaddress(udc, wValue, wIndex, wLength);
++ return;
++
++ case USB_REQ_CLEAR_FEATURE:
++ case USB_REQ_SET_FEATURE:
++ /* Requests with no data phase, status phase from udc */
++ if ((setup->bRequestType & USB_TYPE_MASK)
++ != USB_TYPE_STANDARD)
++ break;
++
++ if ((setup->bRequestType & USB_RECIP_MASK)
++ == USB_RECIP_ENDPOINT) {
++ int pipe = wIndex & USB_ENDPOINT_NUMBER_MASK;
++ struct qe_ep *ep;
++
++ if (wValue != 0 || wLength != 0
++ || pipe > USB_MAX_ENDPOINTS)
++ break;
++ ep = &udc->eps[pipe];
++
++ spin_unlock(&udc->lock);
++ qe_ep_set_halt(&ep->ep,
++ (setup->bRequest == USB_REQ_SET_FEATURE)
++ ? 1 : 0);
++ spin_lock(&udc->lock);
++ }
++
++ ep0_prime_status(udc, USB_DIR_IN);
++
++ return;
++
++ default:
++ break;
++ }
++
++ if (wLength) {
++ /* Data phase from gadget, status phase from udc */
++ if (setup->bRequestType & USB_DIR_IN) {
++ udc->ep0_state = DATA_STATE_XMIT;
++ udc->ep0_dir = USB_DIR_IN;
++ } else{
++ udc->ep0_state = DATA_STATE_RECV;
++ udc->ep0_dir = USB_DIR_OUT;
++ }
++ spin_unlock(&udc->lock);
++ if (udc->driver->setup(&udc->gadget,
++ &udc->local_setup_buff) < 0)
++ qe_ep0_stall(udc);
++ spin_lock(&udc->lock);
++ } else {
++ /* No data phase, IN status from gadget */
++ udc->ep0_dir = USB_DIR_IN;
++ spin_unlock(&udc->lock);
++ if (udc->driver->setup(&udc->gadget,
++ &udc->local_setup_buff) < 0)
++ qe_ep0_stall(udc);
++ spin_lock(&udc->lock);
++ udc->ep0_state = DATA_STATE_NEED_ZLP;
++ }
++}
++
++/*-------------------------------------------------------------------------
++ USB Interrupt handlers
++ -------------------------------------------------------------------------*/
++static void suspend_irq(struct qe_udc *udc)
++{
++ udc->resume_state = udc->usb_state;
++ udc->usb_state = USB_STATE_SUSPENDED;
++
++ /* report suspend to the driver ,serial.c not support this*/
++ if (udc->driver->suspend)
++ udc->driver->suspend(&udc->gadget);
++}
++
++static void resume_irq(struct qe_udc *udc)
++{
++ udc->usb_state = udc->resume_state;
++ udc->resume_state = 0;
++
++ /* report resume to the driver , serial.c not support this*/
++ if (udc->driver->resume)
++ udc->driver->resume(&udc->gadget);
++}
++
++static void idle_irq(struct qe_udc *udc)
++{
++ u8 usbs;
++
++ usbs = in_8(&udc->usb_regs->usb_usbs);
++ if (usbs & USB_IDLE_STATUS_MASK) {
++ if ((udc->usb_state) != USB_STATE_SUSPENDED)
++ suspend_irq(udc);
++ } else {
++ if (udc->usb_state == USB_STATE_SUSPENDED)
++ resume_irq(udc);
++ }
++}
++
++static int reset_irq(struct qe_udc *udc)
++{
++ unsigned char i;
++
++ qe_usb_disable();
++ out_8(&udc->usb_regs->usb_usadr, 0);
++
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
++ if (udc->eps[i].init)
++ qe_ep_reset(udc, i);
++ }
++
++ reset_queues(udc);
++ udc->usb_state = USB_STATE_DEFAULT;
++ udc->ep0_state = WAIT_FOR_SETUP;
++ udc->ep0_dir = USB_DIR_OUT;
++ qe_usb_enable();
++ return 0;
++}
++
++static int bsy_irq(struct qe_udc *udc)
++{
++ return 0;
++}
++
++static int txe_irq(struct qe_udc *udc)
++{
++ return 0;
++}
++
++/* ep0 tx interrupt also in here */
++static int tx_irq(struct qe_udc *udc)
++{
++ struct qe_ep *ep;
++ struct qe_bd __iomem *bd;
++ int i, res = 0;
++
++ if ((udc->usb_state == USB_STATE_ADDRESS)
++ && (in_8(&udc->usb_regs->usb_usadr) == 0))
++ out_8(&udc->usb_regs->usb_usadr, udc->device_address);
++
++ for (i = (USB_MAX_ENDPOINTS-1); ((i >= 0) && (res == 0)); i--) {
++ ep = &udc->eps[i];
++ if (ep && ep->init && (ep->dir != USB_DIR_OUT)) {
++ bd = ep->c_txbd;
++ if (!(in_be32((u32 __iomem *)bd) & T_R)
++ && (in_be32(&bd->buf))) {
++ /* Disable the TX Interrupt */
++ /*confirm the transmitted bd*/
++ if (ep->epnum == 0)
++ res = qe_ep0_txconf(ep);
++ else
++ res = qe_ep_txconf(ep);
++ /* Enable the TX Interrupt */
++ }
++ }
++ }
++ return res;
++}
++
++
++/* setup packect's rx is handle in the function too */
++static void rx_irq(struct qe_udc *udc)
++{
++ struct qe_ep *ep;
++ struct qe_bd __iomem *bd;
++ int i;
++
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
++ ep = &udc->eps[i];
++ if (ep && ep->init && (ep->dir != USB_DIR_IN)) {
++ bd = ep->n_rxbd;
++ if (!(in_be32((u32 __iomem *)bd) & R_E)
++ && (in_be32(&bd->buf))) {
++ if (ep->epnum == 0) {
++ qe_ep0_rx(udc);
++ } else {
++ /*non-setup package receive*/
++ qe_ep_rx(ep);
++ }
++ }
++ }
++ }
++}
++
++static irqreturn_t qe_udc_irq(int irq, void *_udc)
++{
++ struct qe_udc *udc = (struct qe_udc *)_udc;
++ u16 irq_src;
++ irqreturn_t status = IRQ_NONE;
++ unsigned long flags;
++
++
++ spin_lock_irqsave(&udc->lock, flags);
++
++ irq_src = in_be16(&udc->usb_regs->usb_usber) &
++ in_be16(&udc->usb_regs->usb_usbmr);
++ /* Clear notification bits */
++ out_be16(&udc->usb_regs->usb_usber, irq_src);
++ /* USB Interrupt */
++ if (irq_src & USB_E_IDLE_MASK) {
++ idle_irq(udc);
++ irq_src &= ~USB_E_IDLE_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ if (irq_src & USB_E_TXB_MASK) {
++ tx_irq(udc);
++ irq_src &= ~USB_E_TXB_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ if (irq_src & USB_E_RXB_MASK) {
++ rx_irq(udc);
++ irq_src &= ~USB_E_RXB_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ if (irq_src & USB_E_RESET_MASK) {
++ reset_irq(udc);
++ irq_src &= ~USB_E_RESET_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ if (irq_src & USB_E_BSY_MASK) {
++ bsy_irq(udc);
++ irq_src &= ~USB_E_BSY_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ if (irq_src & USB_E_TXE_MASK) {
++ txe_irq(udc);
++ irq_src &= ~USB_E_TXE_MASK;
++ status = IRQ_HANDLED;
++ }
++
++ spin_unlock_irqrestore(&udc->lock, flags);
++
++ return status;
++}
++
++/*-------------------------------------------------------------------------
++ Gadget driver register and unregister.
++ --------------------------------------------------------------------------*/
++int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++{
++ int retval;
++ unsigned long flags = 0;
++
++ /* standard operations */
++ if (!udc_controller)
++ return -ENODEV;
++
++ if (!driver || (driver->speed != USB_SPEED_FULL
++ && driver->speed != USB_SPEED_HIGH)
++ || !driver->bind || !driver->disconnect
++ || !driver->setup)
++ return -EINVAL;
++
++ if (udc_controller->driver)
++ return -EBUSY;
++
++ /* lock is needed but whether should use this lock or another */
++ spin_lock_irqsave(&udc_controller->lock, flags);
++
++ driver->driver.bus = NULL;
++ /* hook up the driver */
++ udc_controller->driver = driver;
++ udc_controller->gadget.dev.driver = &driver->driver;
++ udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
++ spin_unlock_irqrestore(&udc_controller->lock, flags);
++
++ retval = driver->bind(&udc_controller->gadget);
++ if (retval) {
++ dev_err(udc_controller->dev, "bind to %s --> %d",
++ driver->driver.name, retval);
++ udc_controller->gadget.dev.driver = NULL;
++ udc_controller->driver = NULL;
++ return retval;
++ }
++
++ /* Enable IRQ reg and Set usbcmd reg EN bit */
++ qe_usb_enable();
++
++ out_be16(&udc_controller->usb_regs->usb_usber, 0xffff);
++ out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
++ udc_controller->usb_state = USB_STATE_ATTACHED;
++ udc_controller->ep0_state = WAIT_FOR_SETUP;
++ udc_controller->ep0_dir = USB_DIR_OUT;
++ dev_info(udc_controller->dev, "%s bind to driver %s \n",
++ udc_controller->gadget.name, driver->driver.name);
++ return 0;
++}
++EXPORT_SYMBOL(usb_gadget_register_driver);
++
++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
++{
++ struct qe_ep *loop_ep;
++ unsigned long flags;
++
++ if (!udc_controller)
++ return -ENODEV;
++
++ if (!driver || driver != udc_controller->driver)
++ return -EINVAL;
++
++ /* stop usb controller, disable intr */
++ qe_usb_disable();
++
++ /* in fact, no needed */
++ udc_controller->usb_state = USB_STATE_ATTACHED;
++ udc_controller->ep0_state = WAIT_FOR_SETUP;
++ udc_controller->ep0_dir = 0;
++
++ /* stand operation */
++ spin_lock_irqsave(&udc_controller->lock, flags);
++ udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
++ nuke(&udc_controller->eps[0], -ESHUTDOWN);
++ list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
++ ep.ep_list)
++ nuke(loop_ep, -ESHUTDOWN);
++ spin_unlock_irqrestore(&udc_controller->lock, flags);
++
++ /* unbind gadget and unhook driver. */
++ driver->unbind(&udc_controller->gadget);
++ udc_controller->gadget.dev.driver = NULL;
++ udc_controller->driver = NULL;
++
++ dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n",
++ driver->driver.name);
++ return 0;
++}
++EXPORT_SYMBOL(usb_gadget_unregister_driver);
++
++/* udc structure's alloc and setup, include ep-param alloc */
++static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev)
++{
++ struct qe_udc *udc;
++ struct device_node *np = ofdev->node;
++ unsigned int tmp_addr = 0;
++ struct usb_device_para __iomem *usbpram;
++ unsigned int i;
++ u64 size;
++ u32 offset;
++
++ udc = kzalloc(sizeof(*udc), GFP_KERNEL);
++ if (udc == NULL) {
++ dev_err(&ofdev->dev, "malloc udc failed\n");
++ goto cleanup;
++ }
++
++ udc->dev = &ofdev->dev;
++
++ /* get default address of usb parameter in MURAM from device tree */
++ offset = *of_get_address(np, 1, &size, NULL);
++ udc->usb_param = cpm_muram_addr(offset);
++ memset_io(udc->usb_param, 0, size);
++
++ usbpram = udc->usb_param;
++ out_be16(&usbpram->frame_n, 0);
++ out_be32(&usbpram->rstate, 0);
++
++ tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS *
++ sizeof(struct usb_ep_para)),
++ USB_EP_PARA_ALIGNMENT);
++
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
++ out_be16(&usbpram->epptr[i], (u16)tmp_addr);
++ udc->ep_param[i] = cpm_muram_addr(tmp_addr);
++ tmp_addr += 32;
++ }
++
++ memset_io(udc->ep_param[0], 0,
++ USB_MAX_ENDPOINTS * sizeof(struct usb_ep_para));
++
++ udc->resume_state = USB_STATE_NOTATTACHED;
++ udc->usb_state = USB_STATE_POWERED;
++ udc->ep0_dir = 0;
++
++ spin_lock_init(&udc->lock);
++ return udc;
++
++cleanup:
++ kfree(udc);
++ return NULL;
++}
++
++/* USB Controller register init */
++static int __devinit qe_udc_reg_init(struct qe_udc *udc)
++{
++ struct usb_ctlr __iomem *qe_usbregs;
++ qe_usbregs = udc->usb_regs;
++
++ /* Init the usb register */
++ out_8(&qe_usbregs->usb_usmod, 0x01);
++ out_be16(&qe_usbregs->usb_usbmr, 0);
++ out_8(&qe_usbregs->usb_uscom, 0);
++ out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
++
++ return 0;
++}
++
++static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
++{
++ struct qe_ep *ep = &udc->eps[pipe_num];
++
++ ep->udc = udc;
++ strcpy(ep->name, ep_name[pipe_num]);
++ ep->ep.name = ep_name[pipe_num];
++
++ ep->ep.ops = &qe_ep_ops;
++ ep->stopped = 1;
++ ep->ep.maxpacket = (unsigned short) ~0;
++ ep->desc = NULL;
++ ep->dir = 0xff;
++ ep->epnum = (u8)pipe_num;
++ ep->sent = 0;
++ ep->last = 0;
++ ep->init = 0;
++ ep->rxframe = NULL;
++ ep->txframe = NULL;
++ ep->tx_req = NULL;
++ ep->state = EP_STATE_IDLE;
++ ep->has_data = 0;
++
++ /* the queue lists any req for this ep */
++ INIT_LIST_HEAD(&ep->queue);
++
++ /* gagdet.ep_list used for ep_autoconfig so no ep0*/
++ if (pipe_num != 0)
++ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
++
++ ep->gadget = &udc->gadget;
++
++ return 0;
++}
++
++/*-----------------------------------------------------------------------
++ * UDC device Driver operation functions *
++ *----------------------------------------------------------------------*/
++static void qe_udc_release(struct device *dev)
++{
++ int i = 0;
++
++ complete(udc_controller->done);
++ cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0]));
++ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
++ udc_controller->ep_param[i] = NULL;
++
++ kfree(udc_controller);
++ udc_controller = NULL;
++}
++
++/* Driver probe functions */
++static int __devinit qe_udc_probe(struct of_device *ofdev,
++ const struct of_device_id *match)
++{
++ struct device_node *np = ofdev->node;
++ struct qe_ep *ep;
++ unsigned int ret = 0;
++ unsigned int i;
++ const void *prop;
++
++ prop = of_get_property(np, "mode", NULL);
++ if (!prop || strcmp(prop, "peripheral"))
++ return -ENODEV;
++
++ /* Initialize the udc structure including QH member and other member */
++ udc_controller = qe_udc_config(ofdev);
++ if (!udc_controller) {
++ dev_dbg(&ofdev->dev, "udc_controll is NULL\n");
++ return -ENOMEM;
++ }
++
++ udc_controller->soc_type = (unsigned long)np->data;
++ udc_controller->usb_regs = of_iomap(np, 0);
++ if (!udc_controller->usb_regs) {
++ ret = -ENOMEM;
++ goto err1;
++ }
++
++ /* initialize usb hw reg except for regs for EP,
++ * leave usbintr reg untouched*/
++ qe_udc_reg_init(udc_controller);
++
++ /* here comes the stand operations for probe
++ * set the qe_udc->gadget.xxx */
++ udc_controller->gadget.ops = &qe_gadget_ops;
++
++ /* gadget.ep0 is a pointer */
++ udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
++
++ INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
++
++ /* modify in register gadget process */
++ udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
++
++ /* name: Identifies the controller hardware type. */
++ udc_controller->gadget.name = driver_name;
++
++ device_initialize(&udc_controller->gadget.dev);
++
++ strcpy(udc_controller->gadget.dev.bus_id, "gadget");
++
++ udc_controller->gadget.dev.release = qe_udc_release;
++ udc_controller->gadget.dev.parent = &ofdev->dev;
++
++
++ /* EP:intialization qe_ep struct */
++ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) {
++ /*because the ep type isn't decide here so
++ * qe_ep_init() should be called in ep_enable() */
++
++ /* setup the qe_ep struct and link ep.ep.list
++ * into gadget.ep_list */
++ qe_ep_config(udc_controller, (unsigned char)i);
++ }
++
++ /* ep0 initialization in here */
++ ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc);
++ if (ret)
++ goto err2;
++
++ /* create a buf for ZLP send */
++ udc_controller->nullbuf = kzalloc(256, GFP_KERNEL);
++ if (udc_controller->nullbuf == NULL) {
++ dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n");
++ ret = -ENOMEM;
++ goto err3;
++ }
++
++ udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf);
++ if (udc_controller->nullp == DMA_ADDR_INVALID) {
++ udc_controller->nullp = dma_map_single(
++ udc_controller->gadget.dev.parent,
++ udc_controller->nullbuf,
++ 256,
++ DMA_TO_DEVICE);
++ udc_controller->nullmap = 1;
++ } else {
++ dma_sync_single_for_device(udc_controller->gadget.dev.parent,
++ udc_controller->nullp, 256,
++ DMA_TO_DEVICE);
++ }
++
++ tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet,
++ (unsigned long)udc_controller);
++ /* request irq and disable DR */
++ udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
++
++ ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
++ driver_name, udc_controller);
++ if (ret) {
++ dev_err(udc_controller->dev, "cannot request irq %d err %d \n",
++ udc_controller->usb_irq, ret);
++ goto err4;
++ }
++
++ ret = device_add(&udc_controller->gadget.dev);
++ if (ret)
++ goto err5;
++
++ dev_info(udc_controller->dev,
++ "QE/CPM USB controller initialized as device\n");
++ return 0;
++
++err5:
++ free_irq(udc_controller->usb_irq, udc_controller);
++err4:
++ if (udc_controller->nullmap) {
++ dma_unmap_single(udc_controller->gadget.dev.parent,
++ udc_controller->nullp, 256,
++ DMA_TO_DEVICE);
++ udc_controller->nullp = DMA_ADDR_INVALID;
++ } else {
++ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
++ udc_controller->nullp, 256,
++ DMA_TO_DEVICE);
++ }
++ kfree(udc_controller->nullbuf);
++err3:
++ ep = &udc_controller->eps[0];
++ cpm_muram_free(cpm_muram_offset(ep->rxbase));
++ kfree(ep->rxframe);
++ kfree(ep->rxbuffer);
++ kfree(ep->txframe);
++err2:
++ iounmap(udc_controller->usb_regs);
++err1:
++ kfree(udc_controller);
++
++ return ret;
++}
++
++#ifdef CONFIG_PM
++static int qe_udc_suspend(struct of_device *dev, pm_message_t state)
++{
++ return -ENOTSUPP;
++}
++
++static int qe_udc_resume(struct of_device *dev)
++{
++ return -ENOTSUPP;
++}
++#endif
++
++static int __devexit qe_udc_remove(struct of_device *ofdev)
++{
++ struct qe_ep *ep;
++ unsigned int size;
++
++ DECLARE_COMPLETION(done);
++
++ if (!udc_controller)
++ return -ENODEV;
++
++ udc_controller->done = &done;
++ tasklet_disable(&udc_controller->rx_tasklet);
++
++ if (udc_controller->nullmap) {
++ dma_unmap_single(udc_controller->gadget.dev.parent,
++ udc_controller->nullp, 256,
++ DMA_TO_DEVICE);
++ udc_controller->nullp = DMA_ADDR_INVALID;
++ } else {
++ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
++ udc_controller->nullp, 256,
++ DMA_TO_DEVICE);
++ }
++ kfree(udc_controller->nullbuf);
++
++ ep = &udc_controller->eps[0];
++ cpm_muram_free(cpm_muram_offset(ep->rxbase));
++ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1);
++
++ kfree(ep->rxframe);
++ if (ep->rxbufmap) {
++ dma_unmap_single(udc_controller->gadget.dev.parent,
++ ep->rxbuf_d, size,
++ DMA_FROM_DEVICE);
++ ep->rxbuf_d = DMA_ADDR_INVALID;
++ } else {
++ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
++ ep->rxbuf_d, size,
++ DMA_FROM_DEVICE);
++ }
++
++ kfree(ep->rxbuffer);
++ kfree(ep->txframe);
++
++ free_irq(udc_controller->usb_irq, udc_controller);
++
++ tasklet_kill(&udc_controller->rx_tasklet);
++
++ iounmap(udc_controller->usb_regs);
++
++ device_unregister(&udc_controller->gadget.dev);
++ /* wait for release() of gadget.dev to free udc */
++ wait_for_completion(&done);
++
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++static struct of_device_id __devinitdata qe_udc_match[] = {
++ {
++ .compatible = "fsl,mpc8360-qe-usb",
++ .data = (void *)PORT_QE,
++ },
++ {
++ .compatible = "fsl,mpc8272-cpm-usb",
++ .data = (void *)PORT_CPM,
++ },
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, qe_udc_match);
++
++static struct of_platform_driver udc_driver = {
++ .name = (char *)driver_name,
++ .match_table = qe_udc_match,
++ .probe = qe_udc_probe,
++ .remove = __devexit_p(qe_udc_remove),
++#ifdef CONFIG_PM
++ .suspend = qe_udc_suspend,
++ .resume = qe_udc_resume,
++#endif
++};
++
++static int __init qe_udc_init(void)
++{
++ printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc,
++ DRIVER_VERSION);
++ return of_register_platform_driver(&udc_driver);
++}
++
++static void __exit qe_udc_exit(void)
++{
++ of_unregister_platform_driver(&udc_driver);
++}
++
++module_init(qe_udc_init);
++module_exit(qe_udc_exit);
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_LICENSE("GPL");
++
+--- /dev/null
++++ b/drivers/usb/gadget/fsl_qe_udc.h
+@@ -0,0 +1,436 @@
++/*
++ * drivers/usb/gadget/qe_udc.h
++ *
++ * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
++ *
++ * Xiaobo Xie <X.Xie@freescale.com>
++ * Li Yang <leoli@freescale.com>
++ *
++ * Description:
++ * Freescale USB device/endpoint management registers
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ */
++
++#ifndef __FSL_QE_UDC_H
++#define __FSL_QE_UDC_H
++
++/* SoC type */
++#define PORT_CPM 0
++#define PORT_QE 1
++
++#define USB_MAX_ENDPOINTS 4
++#define USB_MAX_PIPES USB_MAX_ENDPOINTS
++#define USB_EP0_MAX_SIZE 64
++#define USB_MAX_CTRL_PAYLOAD 0x4000
++#define USB_BDRING_LEN 16
++#define USB_BDRING_LEN_RX 256
++#define USB_BDRING_LEN_TX 16
++#define MIN_EMPTY_BDS 128
++#define MAX_DATA_BDS 8
++#define USB_CRC_SIZE 2
++#define USB_DIR_BOTH 0x88
++#define R_BUF_MAXSIZE 0x800
++#define USB_EP_PARA_ALIGNMENT 32
++
++/* USB Mode Register bit define */
++#define USB_MODE_EN 0x01
++#define USB_MODE_HOST 0x02
++#define USB_MODE_TEST 0x04
++#define USB_MODE_SFTE 0x08
++#define USB_MODE_RESUME 0x40
++#define USB_MODE_LSS 0x80
++
++/* USB Slave Address Register Mask */
++#define USB_SLVADDR_MASK 0x7F
++
++/* USB Endpoint register define */
++#define USB_EPNUM_MASK 0xF000
++#define USB_EPNUM_SHIFT 12
++
++#define USB_TRANS_MODE_SHIFT 8
++#define USB_TRANS_CTR 0x0000
++#define USB_TRANS_INT 0x0100
++#define USB_TRANS_BULK 0x0200
++#define USB_TRANS_ISO 0x0300
++
++#define USB_EP_MF 0x0020
++#define USB_EP_RTE 0x0010
++
++#define USB_THS_SHIFT 2
++#define USB_THS_MASK 0x000c
++#define USB_THS_NORMAL 0x0
++#define USB_THS_IGNORE_IN 0x0004
++#define USB_THS_NACK 0x0008
++#define USB_THS_STALL 0x000c
++
++#define USB_RHS_SHIFT 0
++#define USB_RHS_MASK 0x0003
++#define USB_RHS_NORMAL 0x0
++#define USB_RHS_IGNORE_OUT 0x0001
++#define USB_RHS_NACK 0x0002
++#define USB_RHS_STALL 0x0003
++
++#define USB_RTHS_MASK 0x000f
++
++/* USB Command Register define */
++#define USB_CMD_STR_FIFO 0x80
++#define USB_CMD_FLUSH_FIFO 0x40
++#define USB_CMD_ISFT 0x20
++#define USB_CMD_DSFT 0x10
++#define USB_CMD_EP_MASK 0x03
++
++/* USB Event and Mask Register define */
++#define USB_E_MSF_MASK 0x0800
++#define USB_E_SFT_MASK 0x0400
++#define USB_E_RESET_MASK 0x0200
++#define USB_E_IDLE_MASK 0x0100
++#define USB_E_TXE4_MASK 0x0080
++#define USB_E_TXE3_MASK 0x0040
++#define USB_E_TXE2_MASK 0x0020
++#define USB_E_TXE1_MASK 0x0010
++#define USB_E_SOF_MASK 0x0008
++#define USB_E_BSY_MASK 0x0004
++#define USB_E_TXB_MASK 0x0002
++#define USB_E_RXB_MASK 0x0001
++#define USBER_ALL_CLEAR 0x0fff
++
++#define USB_E_DEFAULT_DEVICE (USB_E_RESET_MASK | USB_E_TXE4_MASK | \
++ USB_E_TXE3_MASK | USB_E_TXE2_MASK | \
++ USB_E_TXE1_MASK | USB_E_BSY_MASK | \
++ USB_E_TXB_MASK | USB_E_RXB_MASK)
++
++#define USB_E_TXE_MASK (USB_E_TXE4_MASK | USB_E_TXE3_MASK|\
++ USB_E_TXE2_MASK | USB_E_TXE1_MASK)
++/* USB Status Register define */
++#define USB_IDLE_STATUS_MASK 0x01
++
++/* USB Start of Frame Timer */
++#define USB_USSFT_MASK 0x3FFF
++
++/* USB Frame Number Register */
++#define USB_USFRN_MASK 0xFFFF
++
++struct usb_device_para{
++ u16 epptr[4];
++ u32 rstate;
++ u32 rptr;
++ u16 frame_n;
++ u16 rbcnt;
++ u32 rtemp;
++ u32 rxusb_data;
++ u16 rxuptr;
++ u8 reso[2];
++ u32 softbl;
++ u8 sofucrctemp;
++};
++
++struct usb_ep_para{
++ u16 rbase;
++ u16 tbase;
++ u8 rbmr;
++ u8 tbmr;
++ u16 mrblr;
++ u16 rbptr;
++ u16 tbptr;
++ u32 tstate;
++ u32 tptr;
++ u16 tcrc;
++ u16 tbcnt;
++ u32 ttemp;
++ u16 txusbu_ptr;
++ u8 reserve[2];
++};
++
++#define USB_BUSMODE_GBL 0x20
++#define USB_BUSMODE_BO_MASK 0x18
++#define USB_BUSMODE_BO_SHIFT 0x3
++#define USB_BUSMODE_BE 0x2
++#define USB_BUSMODE_CETM 0x04
++#define USB_BUSMODE_DTB 0x02
++
++/* Endpoint basic handle */
++#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF)
++#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
++#define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \
++ USB_DIR_IN) : ((EP)->desc->bEndpointAddress \
++ & USB_DIR_IN) == USB_DIR_IN)
++
++/* ep0 transfer state */
++#define WAIT_FOR_SETUP 0
++#define DATA_STATE_XMIT 1
++#define DATA_STATE_NEED_ZLP 2
++#define WAIT_FOR_OUT_STATUS 3
++#define DATA_STATE_RECV 4
++
++/* ep tramsfer mode */
++#define USBP_TM_CTL 0
++#define USBP_TM_ISO 1
++#define USBP_TM_BULK 2
++#define USBP_TM_INT 3
++
++/*-----------------------------------------------------------------------------
++ USB RX And TX DATA Frame
++ -----------------------------------------------------------------------------*/
++struct qe_frame{
++ u8 *data;
++ u32 len;
++ u32 status;
++ u32 info;
++
++ void *privdata;
++ struct list_head node;
++};
++
++/* Frame structure, info field. */
++#define PID_DATA0 0x80000000 /* Data toggle zero */
++#define PID_DATA1 0x40000000 /* Data toggle one */
++#define PID_SETUP 0x20000000 /* setup bit */
++#define SETUP_STATUS 0x10000000 /* setup status bit */
++#define SETADDR_STATUS 0x08000000 /* setupup address status bit */
++#define NO_REQ 0x04000000 /* Frame without request */
++#define HOST_DATA 0x02000000 /* Host data frame */
++#define FIRST_PACKET_IN_FRAME 0x01000000 /* first packet in the frame */
++#define TOKEN_FRAME 0x00800000 /* Host token frame */
++#define ZLP 0x00400000 /* Zero length packet */
++#define IN_TOKEN_FRAME 0x00200000 /* In token package */
++#define OUT_TOKEN_FRAME 0x00100000 /* Out token package */
++#define SETUP_TOKEN_FRAME 0x00080000 /* Setup token package */
++#define STALL_FRAME 0x00040000 /* Stall handshake */
++#define NACK_FRAME 0x00020000 /* Nack handshake */
++#define NO_PID 0x00010000 /* No send PID */
++#define NO_CRC 0x00008000 /* No send CRC */
++#define HOST_COMMAND 0x00004000 /* Host command frame */
++
++/* Frame status field */
++/* Receive side */
++#define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */
++#define FRAME_ERROR 0x80000000 /* Error occured on frame */
++#define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */
++#define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */
++#define RX_ER_NONOCT 0x10000000 /* Rx Non Octet Aligned Packet */
++#define RX_ER_BITSTUFF 0x08000000 /* Frame Aborted --Received packet
++ with bit stuff error */
++#define RX_ER_CRC 0x04000000 /* Received packet with CRC error */
++#define RX_ER_OVERUN 0x02000000 /* Over-run occured on reception */
++#define RX_ER_PID 0x01000000 /* Wrong PID received */
++/* Tranmit side */
++#define TX_ER_NAK 0x00800000 /* Received NAK handshake */
++#define TX_ER_STALL 0x00400000 /* Received STALL handshake */
++#define TX_ER_TIMEOUT 0x00200000 /* Transmit time out */
++#define TX_ER_UNDERUN 0x00100000 /* Transmit underrun */
++#define FRAME_INPROGRESS 0x00080000 /* Frame is being transmitted */
++#define ER_DATA_UNDERUN 0x00040000 /* Frame is shorter then expected */
++#define ER_DATA_OVERUN 0x00020000 /* Frame is longer then expected */
++
++/* QE USB frame operation functions */
++#define frame_get_length(frm) (frm->len)
++#define frame_set_length(frm, leng) (frm->len = leng)
++#define frame_get_data(frm) (frm->data)
++#define frame_set_data(frm, dat) (frm->data = dat)
++#define frame_get_info(frm) (frm->info)
++#define frame_set_info(frm, inf) (frm->info = inf)
++#define frame_get_status(frm) (frm->status)
++#define frame_set_status(frm, stat) (frm->status = stat)
++#define frame_get_privdata(frm) (frm->privdata)
++#define frame_set_privdata(frm, dat) (frm->privdata = dat)
++
++static inline void qe_frame_clean(struct qe_frame *frm)
++{
++ frame_set_data(frm, NULL);
++ frame_set_length(frm, 0);
++ frame_set_status(frm, FRAME_OK);
++ frame_set_info(frm, 0);
++ frame_set_privdata(frm, NULL);
++}
++
++static inline void qe_frame_init(struct qe_frame *frm)
++{
++ qe_frame_clean(frm);
++ INIT_LIST_HEAD(&(frm->node));
++}
++
++struct qe_req {
++ struct usb_request req;
++ struct list_head queue;
++ /* ep_queue() func will add
++ a request->queue into a udc_ep->queue 'd tail */
++ struct qe_ep *ep;
++ unsigned mapped:1;
++};
++
++struct qe_ep {
++ struct usb_ep ep;
++ struct list_head queue;
++ struct qe_udc *udc;
++ const struct usb_endpoint_descriptor *desc;
++ struct usb_gadget *gadget;
++
++ u8 state;
++
++ struct qe_bd __iomem *rxbase;
++ struct qe_bd __iomem *n_rxbd;
++ struct qe_bd __iomem *e_rxbd;
++
++ struct qe_bd __iomem *txbase;
++ struct qe_bd __iomem *n_txbd;
++ struct qe_bd __iomem *c_txbd;
++
++ struct qe_frame *rxframe;
++ u8 *rxbuffer;
++ dma_addr_t rxbuf_d;
++ u8 rxbufmap;
++ unsigned char localnack;
++ int has_data;
++
++ struct qe_frame *txframe;
++ struct qe_req *tx_req;
++ int sent; /*data already sent */
++ int last; /*data sent in the last time*/
++
++ u8 dir;
++ u8 epnum;
++ u8 tm; /* transfer mode */
++ u8 data01;
++ u8 init;
++
++ u8 already_seen;
++ u8 enable_tasklet;
++ u8 setup_stage;
++ u32 last_io; /* timestamp */
++
++ char name[14];
++
++ unsigned double_buf:1;
++ unsigned stopped:1;
++ unsigned fnf:1;
++ unsigned has_dma:1;
++
++ u8 ackwait;
++ u8 dma_channel;
++ u16 dma_counter;
++ int lch;
++
++ struct timer_list timer;
++};
++
++struct qe_udc {
++ struct usb_gadget gadget;
++ struct usb_gadget_driver *driver;
++ struct device *dev;
++ struct qe_ep eps[USB_MAX_ENDPOINTS];
++ struct usb_ctrlrequest local_setup_buff;
++ spinlock_t lock; /* lock for set/config qe_udc */
++ unsigned long soc_type; /* QE or CPM soc */
++
++ struct qe_req *status_req; /* ep0 status request */
++
++ /* USB and EP Parameter Block pointer */
++ struct usb_device_para __iomem *usb_param;
++ struct usb_ep_para __iomem *ep_param[4];
++
++ u32 max_pipes; /* Device max pipes */
++ u32 max_use_endpts; /* Max endpointes to be used */
++ u32 bus_reset; /* Device is bus reseting */
++ u32 resume_state; /* USB state to resume*/
++ u32 usb_state; /* USB current state */
++ u32 usb_next_state; /* USB next state */
++ u32 ep0_state; /* Enpoint zero state */
++ u32 ep0_dir; /* Enpoint zero direction: can be
++ USB_DIR_IN or USB_DIR_OUT*/
++ u32 usb_sof_count; /* SOF count */
++ u32 errors; /* USB ERRORs count */
++
++ u8 *tmpbuf;
++ u32 c_start;
++ u32 c_end;
++
++ u8 *nullbuf;
++ dma_addr_t nullp;
++ u8 nullmap;
++ u8 device_address; /* Device USB address */
++
++ unsigned int usb_clock;
++ unsigned int usb_irq;
++ struct usb_ctlr __iomem *usb_regs;
++
++ struct tasklet_struct rx_tasklet;
++
++ struct completion *done; /* to make sure release() is done */
++};
++
++#define EP_STATE_IDLE 0
++#define EP_STATE_NACK 1
++#define EP_STATE_STALL 2
++
++/*
++ * transmit BD's status
++ */
++#define T_R 0x80000000 /* ready bit */
++#define T_W 0x20000000 /* wrap bit */
++#define T_I 0x10000000 /* interrupt on completion */
++#define T_L 0x08000000 /* last */
++#define T_TC 0x04000000 /* transmit CRC */
++#define T_CNF 0x02000000 /* wait for transmit confirm */
++#define T_LSP 0x01000000 /* Low-speed transaction */
++#define T_PID 0x00c00000 /* packet id */
++#define T_NAK 0x00100000 /* No ack. */
++#define T_STAL 0x00080000 /* Stall recieved */
++#define T_TO 0x00040000 /* time out */
++#define T_UN 0x00020000 /* underrun */
++
++#define DEVICE_T_ERROR (T_UN | T_TO)
++#define HOST_T_ERROR (T_UN | T_TO | T_NAK | T_STAL)
++#define DEVICE_T_BD_MASK DEVICE_T_ERROR
++#define HOST_T_BD_MASK HOST_T_ERROR
++
++#define T_PID_SHIFT 6
++#define T_PID_DATA0 0x00800000 /* Data 0 toggle */
++#define T_PID_DATA1 0x00c00000 /* Data 1 toggle */
++
++/*
++ * receive BD's status
++ */
++#define R_E 0x80000000 /* buffer empty */
++#define R_W 0x20000000 /* wrap bit */
++#define R_I 0x10000000 /* interrupt on reception */
++#define R_L 0x08000000 /* last */
++#define R_F 0x04000000 /* first */
++#define R_PID 0x00c00000 /* packet id */
++#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */
++#define R_AB 0x00080000 /* Frame Aborted */
++#define R_CR 0x00040000 /* CRC Error */
++#define R_OV 0x00020000 /* Overrun */
++
++#define R_ERROR (R_NO | R_AB | R_CR | R_OV)
++#define R_BD_MASK R_ERROR
++
++#define R_PID_DATA0 0x00000000
++#define R_PID_DATA1 0x00400000
++#define R_PID_SETUP 0x00800000
++
++#define CPM_USB_STOP_TX 0x2e600000
++#define CPM_USB_RESTART_TX 0x2e600000
++#define CPM_USB_STOP_TX_OPCODE 0x0a
++#define CPM_USB_RESTART_TX_OPCODE 0x0b
++#define CPM_USB_EP_SHIFT 5
++
++#ifndef CONFIG_CPM
++inline int cpm_command(u32 command, u8 opcode)
++{
++ return -EOPNOTSUPP;
++}
++#endif
++
++#ifndef CONFIG_QUICC_ENGINE
++inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
++ u32 cmd_input)
++{
++ return -EOPNOTSUPP;
++}
++#endif
++
++#endif /* __FSL_QE_UDC_H */
+--- a/drivers/usb/gadget/gadget_chips.h
++++ b/drivers/usb/gadget/gadget_chips.h
+@@ -151,6 +151,13 @@
+ #define gadget_is_m66592(g) 0
+ #endif
+
++/* Freescale CPM/QE UDC SUPPORT */
++#ifdef CONFIG_USB_GADGET_FSL_QE
++#define gadget_is_fsl_qe(g) !strcmp("fsl_qe_udc", (g)->name)
++#else
++#define gadget_is_fsl_qe(g) 0
++#endif
++
+
+ // CONFIG_USB_GADGET_SX2
+ // CONFIG_USB_GADGET_AU1X00
+@@ -216,6 +223,8 @@ static inline int usb_gadget_controller_
+ return 0x20;
+ else if (gadget_is_m66592(gadget))
+ return 0x21;
++ else if (gadget_is_fsl_qe(gadget))
++ return 0x22;
+ return -ENOENT;
+ }
+
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -341,6 +341,25 @@ config USB_AMD5536UDC
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
++config USB_GADGET_FSL_QE
++ boolean "Freescale QE/CPM USB Device Controller"
++ depends on FSL_SOC && (QUICC_ENGINE || CPM)
++ help
++ Some of Freescale PowerPC processors have a Full Speed
++ QE/CPM2 USB controller, which support device mode with 4
++ programmable endpoints. This driver supports the
++ controller in the MPC8360 and MPC8272, and should work with
++ controllers having QE or CPM2, given minor tweaks.
++
++ Set CONFIG_USB_GADGET to "m" to build this driver as a
++ dynmically linked module called "fsl_qe_udc".
++
++config USB_FSL_QE
++ tristate
++ depends on USB_GADGET_FSL_QE
++ default USB_GADGET
++ select USB_GADGET_SELECTED
++
+ config USB_GADGET_NET2280
+ boolean "NetChip 228x"
+ depends on PCI
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_USB_AT91) += at91_udc.o
+ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
+ obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
+ obj-$(CONFIG_USB_M66592) += m66592-udc.o
++obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
+
+ #
+ # USB gadget drivers
diff --git a/usb/usb-drivers-usb-misc-use-an-is_err-test-rather-than-a-null-test.patch b/usb/usb-drivers-usb-misc-use-an-is_err-test-rather-than-a-null-test.patch
new file mode 100644
index 00000000000000..31242e5f2a04db
--- /dev/null
+++ b/usb/usb-drivers-usb-misc-use-an-is_err-test-rather-than-a-null-test.patch
@@ -0,0 +1,49 @@
+From brunel@diku.dk Thu Sep 11 02:34:58 2008
+From: Julien Brunel <brunel@diku.dk>
+Date: Mon, 1 Sep 2008 10:57:27 +0200
+Subject: USB: drivers/usb/misc: Use an IS_ERR test rather than a NULL test
+To: gregkh@suse.de
+Message-ID: <200809011057.28293.brunel@diku.dk>
+Content-Disposition: inline
+
+
+From: Julien Brunel <brunel@diku.dk>
+
+In case of error, the function backlight_device_register returns an
+ERR pointer, but never returns a NULL pointer. So a NULL test that may
+come after a call to this function should be strengthened by an IS_ERR
+test.
+
+The semantic match that finds this problem is as follows:
+(http://www.emn.fr/x-info/coccinelle/)
+
+// <smpl>
+@match_bad_null_test@
+expression x, E;
+statement S1,S2;
+@@
+x = backlight_device_register(...)
+... when != x = E
+* if (x != NULL)
+S1 else S2
+// </smpl>
+
+Signed-off-by: Julien Brunel <brunel@diku.dk>
+Signed-off-by: Julia Lawall <julia@diku.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/appledisplay.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/appledisplay.c
++++ b/drivers/usb/misc/appledisplay.c
+@@ -314,7 +314,7 @@ error:
+ pdata->urbdata, pdata->urb->transfer_dma);
+ usb_free_urb(pdata->urb);
+ }
+- if (pdata->bd)
++ if (pdata->bd && !IS_ERR(pdata->bd))
+ backlight_device_unregister(pdata->bd);
+ kfree(pdata->msgdata);
+ }
diff --git a/usb/usb-remove-unused-include-version.h.patch b/usb/usb-remove-unused-include-version.h.patch
new file mode 100644
index 00000000000000..3388a20b5bbb20
--- /dev/null
+++ b/usb/usb-remove-unused-include-version.h.patch
@@ -0,0 +1,32 @@
+From weiyi.huang@gmail.com Thu Sep 11 02:32:59 2008
+From: Huang Weiyi <weiyi.huang@gmail.com>
+Date: Sat, 23 Aug 2008 13:56:30 +0800
+Subject: USB: remove unused #include <version.h>
+To: gregkh@suse.de, greg@kroah.com
+Cc: linux-usb@vger.kernel.org
+Message-ID: <20080823133422.128C.WEIYI.HUANG@gmail.com>
+
+From: Huang Weiyi <weiyi.huang@gmail.com>
+
+The driver(s) below do not use LINUX_VERSION_CODE nor KERNEL_VERSION.
+ drivers/usb/gadget/pxa27x_udc.c
+
+This patch removes the said #include <version.h>.
+
+Signed-off-by: Huang Weiyi <weiyi.huang@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/pxa27x_udc.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/gadget/pxa27x_udc.c
++++ b/drivers/usb/gadget/pxa27x_udc.c
+@@ -22,7 +22,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/platform_device.h>
+ #include <linux/delay.h>
diff --git a/usb/usb-storage-report-underflow-with-no-sense-data.patch b/usb/usb-storage-report-underflow-with-no-sense-data.patch
new file mode 100644
index 00000000000000..6bb6db74711de3
--- /dev/null
+++ b/usb/usb-storage-report-underflow-with-no-sense-data.patch
@@ -0,0 +1,39 @@
+From stern+48acf28e@rowland.harvard.edu Thu Sep 11 02:37:35 2008
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 2 Sep 2008 10:12:11 -0400 (EDT)
+Subject: usb-storage: report underflow with no sense data
+To: Matthew Dharm <mdharm-usb@one-eyed-alien.net>, Greg KH <greg@kroah.com>
+Cc: USB Storage list <usb-storage@lists.one-eyed-alien.net>, USB list <linux-usb@vger.kernel.org>
+Message-ID: <Pine.LNX.4.44L0.0808281707040.4308-100000@iolanthe.rowland.org>
+
+
+This patch (as1118) addresses a problem with certain USB mass-storage
+devices. These devices sometimes return less data than asked for and
+then provide no sense data to explain the problem. Currently
+usb-storage leaves it up to the SCSI layer to decide how this should
+be handled, and the SCSI layer interprets the lack of sense data to
+mean that nothing went wrong. But if we got less data than required
+then something definitely _did_ go wrong, and we should say so.
+
+The patch tells the SCSI layer to retry the command when this sort of
+thing happens. Retrying may not solve the underlying problem, but
+it's better than believing that data was transferred when it wasn't.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -663,7 +663,7 @@ void usb_stor_invoke_transport(struct sc
+ }
+
+ /* Did we transfer less than the minimum amount required? */
+- if (srb->result == SAM_STAT_GOOD &&
++ if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) &&
+ scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
+ srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24);
+