1550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 2550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MUSB OTG peripheral driver ep0 handling 3550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 4550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Copyright 2005 Mentor Graphics Corporation 5550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Copyright (C) 2005-2006 by Texas Instruments 6550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Copyright (C) 2006-2007 Nokia Corporation 7a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> 8550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 9550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * This program is free software; you can redistribute it and/or 10550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * modify it under the terms of the GNU General Public License 11550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * version 2 as published by the Free Software Foundation. 12550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 13550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * This program is distributed in the hope that it will be useful, but 14550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * WITHOUT ANY WARRANTY; without even the implied warranty of 15550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * General Public License for more details. 17550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 18550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * You should have received a copy of the GNU General Public License 19550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * along with this program; if not, write to the Free Software 20550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 02110-1301 USA 22550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 23550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 24550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 26550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 29550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 30550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 34550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 35550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 36550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/kernel.h> 37550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/list.h> 38550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/timer.h> 39550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/spinlock.h> 40550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/device.h> 41550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/interrupt.h> 42550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 43550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include "musb_core.h" 44550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 45550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* ep0 is always musb->endpoints[0].ep_in */ 46550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define next_ep0_request(musb) next_in_request(&(musb)->endpoints[0]) 47550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 48550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 49550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * locking note: we use only the controller lock, for simpler correctness. 50550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * It's always held with IRQs blocked. 51550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 52550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * It protects the ep0 request queue as well as ep0_state, not just the 53550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * controller and indexed registers. And that lock stays held unless it 54550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * needs to be dropped to allow reentering this driver ... like upcalls to 55550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * the gadget driver, or adjusting endpoint halt status. 56550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 57550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 58550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic char *decode_ep0stage(u8 stage) 59550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 60550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (stage) { 61a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov case MUSB_EP0_STAGE_IDLE: return "idle"; 62a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov case MUSB_EP0_STAGE_SETUP: return "setup"; 63550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_TX: return "in"; 64550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_RX: return "out"; 65550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_ACKWAIT: return "wait"; 66550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSIN: return "in/status"; 67550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSOUT: return "out/status"; 68550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: return "?"; 69550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 70550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 71550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 72550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* handle a standard GET_STATUS request 73550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 74550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 75550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int service_tx_status_request( 76550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb *musb, 77550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi const struct usb_ctrlrequest *ctrlrequest) 78550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 79550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *mbase = musb->mregs; 80550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int handled = 1; 81550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u8 result[2], epnum = 0; 82550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK; 83550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 84550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[1] = 0; 85550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 86550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (recip) { 87550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_DEVICE: 88550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] = musb->is_self_powered << USB_DEVICE_SELF_POWERED; 89550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP; 90550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (musb->g.is_otg) { 91550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] |= musb->g.b_hnp_enable 92550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi << USB_DEVICE_B_HNP_ENABLE; 93550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] |= musb->g.a_alt_hnp_support 94550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi << USB_DEVICE_A_ALT_HNP_SUPPORT; 95550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] |= musb->g.a_hnp_support 96550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi << USB_DEVICE_A_HNP_SUPPORT; 97550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 98550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 99550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 100550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_INTERFACE: 101550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] = 0; 102550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 103550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 104550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_ENDPOINT: { 105550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int is_in; 106550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_ep *ep; 107550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 tmp; 108550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs; 109550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 110550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi epnum = (u8) ctrlrequest->wIndex; 111550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!epnum) { 112550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] = 0; 113550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 114550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 115550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 116550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi is_in = epnum & USB_DIR_IN; 117550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (is_in) { 118550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi epnum &= 0x0f; 119550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep = &musb->endpoints[epnum].ep_in; 120550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else { 121550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep = &musb->endpoints[epnum].ep_out; 122550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 123550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi regs = musb->endpoints[epnum].regs; 124550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 125550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { 126550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = -EINVAL; 127550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 128550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 129550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 130550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, epnum); 131550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (is_in) 132550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi tmp = musb_readw(regs, MUSB_TXCSR) 133550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi & MUSB_TXCSR_P_SENDSTALL; 134550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else 135550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi tmp = musb_readw(regs, MUSB_RXCSR) 136550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi & MUSB_RXCSR_P_SENDSTALL; 137550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, 0); 138550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 139550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi result[0] = tmp ? 1 : 0; 140550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } break; 141550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 142550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 143550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* class, vendor, etc ... delegate */ 144550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 0; 145550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 146550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 147550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 148550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* fill up the fifo; caller updates csr0 */ 149550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (handled > 0) { 150550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 len = le16_to_cpu(ctrlrequest->wLength); 151550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 152550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (len > 2) 153550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi len = 2; 154550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_write_fifo(&musb->endpoints[0], len, result); 155550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 156550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 157550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return handled; 158550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 159550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 160550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 161550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * handle a control-IN request, the end0 buffer contains the current request 162550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * that is supposed to be a standard control request. Assumes the fifo to 163550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * be at least 2 bytes long. 164550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 165550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * @return 0 if the request was NOT HANDLED, 166550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * < 0 when error 167550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * > 0 when the request is processed 168550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 169550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 170550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 171550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int 172550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbiservice_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) 173550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 174550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int handled = 0; /* not handled */ 175550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 176550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if ((ctrlrequest->bRequestType & USB_TYPE_MASK) 177550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi == USB_TYPE_STANDARD) { 178550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (ctrlrequest->bRequest) { 179550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_REQ_GET_STATUS: 180550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = service_tx_status_request(musb, 181550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ctrlrequest); 182550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 183550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 184550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* case USB_REQ_SYNC_FRAME: */ 185550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 186550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 187550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 188550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 189550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 190550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return handled; 191550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 192550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 193550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 194550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 195550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 196550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req) 197550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 198550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_g_giveback(&musb->endpoints[0].ep_in, req, 0); 199550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 200550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 201550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 202550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Tries to start B-device HNP negotiation if enabled via sysfs 203550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 204550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic inline void musb_try_b_hnp_enable(struct musb *musb) 205550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 206550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *mbase = musb->mregs; 207550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u8 devctl; 208550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 2095c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "HNP: Setting HR\n"); 210550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi devctl = musb_readb(mbase, MUSB_DEVCTL); 211550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writeb(mbase, MUSB_DEVCTL, devctl | MUSB_DEVCTL_HR); 212550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 213550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 214550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 215550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Handle all control requests with no DATA stage, including standard 216550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * requests such as: 217550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized 218550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * always delegated to the gadget driver 219550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE 220550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * always handled here, except for class/vendor/... features 221550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 222550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 223550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 224550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int 225550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbiservice_zero_data_request(struct musb *musb, 226550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct usb_ctrlrequest *ctrlrequest) 227550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi__releases(musb->lock) 228550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi__acquires(musb->lock) 229550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 230550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int handled = -EINVAL; 231550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *mbase = musb->mregs; 232550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK; 233550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 234550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* the gadget driver handles everything except what we MUST handle */ 235550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if ((ctrlrequest->bRequestType & USB_TYPE_MASK) 236550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi == USB_TYPE_STANDARD) { 237550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (ctrlrequest->bRequest) { 238550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_REQ_SET_ADDRESS: 239550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* change it after the status stage */ 240550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->set_address = true; 241550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->address = (u8) (ctrlrequest->wValue & 0x7f); 242550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 1; 243550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 244550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 245550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_REQ_CLEAR_FEATURE: 246550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (recip) { 247550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_DEVICE: 248550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (ctrlrequest->wValue 249550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi != USB_DEVICE_REMOTE_WAKEUP) 250550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 251550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->may_wakeup = 0; 252550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 1; 253550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 254550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_INTERFACE: 255550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 256550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_ENDPOINT:{ 25746034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov const u8 epnum = 25846034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov ctrlrequest->wIndex & 0x0f; 25946034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov struct musb_ep *musb_ep; 26046034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov struct musb_hw_ep *ep; 261a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov struct musb_request *request; 26246034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov void __iomem *regs; 26346034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov int is_in; 26446034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov u16 csr; 265550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 26646034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov if (epnum == 0 || epnum >= MUSB_C_NUM_EPS || 26746034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov ctrlrequest->wValue != USB_ENDPOINT_HALT) 268550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 269550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 27046034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov ep = musb->endpoints + epnum; 27146034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov regs = ep->regs; 27246034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov is_in = ctrlrequest->wIndex & USB_DIR_IN; 27346034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov if (is_in) 27446034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_ep = &ep->ep_in; 275550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else 27646034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_ep = &ep->ep_out; 277550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb_ep->desc) 278550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 279550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 28047e9760529a9823be59d879f726acdc7e2fcbe11Sergei Shtylyov handled = 1; 28147e9760529a9823be59d879f726acdc7e2fcbe11Sergei Shtylyov /* Ignore request if endpoint is wedged */ 28247e9760529a9823be59d879f726acdc7e2fcbe11Sergei Shtylyov if (musb_ep->wedged) 28347e9760529a9823be59d879f726acdc7e2fcbe11Sergei Shtylyov break; 28447e9760529a9823be59d879f726acdc7e2fcbe11Sergei Shtylyov 28546034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_ep_select(mbase, epnum); 28646034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov if (is_in) { 28746034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr = musb_readw(regs, MUSB_TXCSR); 28846034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr |= MUSB_TXCSR_CLRDATATOG | 28946034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov MUSB_TXCSR_P_WZC_BITS; 29046034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr &= ~(MUSB_TXCSR_P_SENDSTALL | 29146034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov MUSB_TXCSR_P_SENTSTALL | 29246034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov MUSB_TXCSR_TXPKTRDY); 29346034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_writew(regs, MUSB_TXCSR, csr); 29446034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov } else { 29546034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr = musb_readw(regs, MUSB_RXCSR); 29646034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr |= MUSB_RXCSR_CLRDATATOG | 29746034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov MUSB_RXCSR_P_WZC_BITS; 29846034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr &= ~(MUSB_RXCSR_P_SENDSTALL | 29946034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov MUSB_RXCSR_P_SENTSTALL); 30046034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_writew(regs, MUSB_RXCSR, csr); 30146034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov } 302550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 303a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov /* Maybe start the first request in the queue */ 304ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi request = next_request(musb_ep); 305a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov if (!musb_ep->busy && request) { 3065c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "restarting the request\n"); 307a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov musb_ep_restart(musb, request); 308a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov } 309a666e3e6098a9f56310e4ec2705f1dad124a34b5Sergei Shtylyov 310550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* select ep0 again */ 311550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, 0); 312550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } break; 313550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 314550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* class, vendor, etc ... delegate */ 315550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 0; 316550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 317550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 318550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 319550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 320550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_REQ_SET_FEATURE: 321550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (recip) { 322550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_DEVICE: 323550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 1; 324550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (ctrlrequest->wValue) { 325550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_DEVICE_REMOTE_WAKEUP: 326550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->may_wakeup = 1; 327550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 328550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_DEVICE_TEST_MODE: 329550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (musb->g.speed != USB_SPEED_HIGH) 330550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 331550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (ctrlrequest->wIndex & 0xff) 332550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 333550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 334550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (ctrlrequest->wIndex >> 8) { 335550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case 1: 336550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi pr_debug("TEST_J\n"); 337550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* TEST_J */ 338550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode_nr = 339550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_TEST_J; 340550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 341550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case 2: 342550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* TEST_K */ 343550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi pr_debug("TEST_K\n"); 344550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode_nr = 345550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_TEST_K; 346550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 347550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case 3: 348550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* TEST_SE0_NAK */ 349550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi pr_debug("TEST_SE0_NAK\n"); 350550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode_nr = 351550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_TEST_SE0_NAK; 352550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 353550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case 4: 354550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* TEST_PACKET */ 355550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi pr_debug("TEST_PACKET\n"); 356550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode_nr = 357550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_TEST_PACKET; 358550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 359ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi 360ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi case 0xc0: 361ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi /* TEST_FORCE_HS */ 362ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi pr_debug("TEST_FORCE_HS\n"); 363ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi musb->test_mode_nr = 364ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi MUSB_TEST_FORCE_HS; 365ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi break; 366ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi case 0xc1: 367ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi /* TEST_FORCE_FS */ 368ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi pr_debug("TEST_FORCE_FS\n"); 369ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi musb->test_mode_nr = 370ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi MUSB_TEST_FORCE_FS; 371ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi break; 372ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi case 0xc2: 373ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi /* TEST_FIFO_ACCESS */ 374ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi pr_debug("TEST_FIFO_ACCESS\n"); 375ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi musb->test_mode_nr = 376ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi MUSB_TEST_FIFO_ACCESS; 377ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi break; 378ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi case 0xc3: 379ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi /* TEST_FORCE_HOST */ 380ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi pr_debug("TEST_FORCE_HOST\n"); 381ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi musb->test_mode_nr = 382ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi MUSB_TEST_FORCE_HOST; 383ca4b2532fb0e2d62370d9825147ffa9b9d9e3880Felipe Balbi break; 384550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 385550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 386550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 387550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 388550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* enter test mode after irq */ 389550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (handled > 0) 390550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode = true; 391550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 392550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_DEVICE_B_HNP_ENABLE: 393550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->g.is_otg) 394550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 395550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->g.b_hnp_enable = 1; 396550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_try_b_hnp_enable(musb); 397550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 398550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_DEVICE_A_HNP_SUPPORT: 399550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->g.is_otg) 400550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 401550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->g.a_hnp_support = 1; 402550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 403550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_DEVICE_A_ALT_HNP_SUPPORT: 404550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->g.is_otg) 405550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 406550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->g.a_alt_hnp_support = 1; 407550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 408d0390d92bf548a903a48e1a2b3a12eff8a9d838bstephane duverger case USB_DEVICE_DEBUG_MODE: 409d0390d92bf548a903a48e1a2b3a12eff8a9d838bstephane duverger handled = 0; 410d0390d92bf548a903a48e1a2b3a12eff8a9d838bstephane duverger break; 411550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistall: 412550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 413550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = -EINVAL; 414550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 415550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 416550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 417550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 418550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_INTERFACE: 419550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 420550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 421550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case USB_RECIP_ENDPOINT:{ 422550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi const u8 epnum = 423550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ctrlrequest->wIndex & 0x0f; 424550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_ep *musb_ep; 425550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_hw_ep *ep; 426550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs; 427550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int is_in; 428550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 csr; 429550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 43046034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov if (epnum == 0 || epnum >= MUSB_C_NUM_EPS || 43146034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov ctrlrequest->wValue != USB_ENDPOINT_HALT) 432550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 433550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 434550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep = musb->endpoints + epnum; 435550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi regs = ep->regs; 436550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi is_in = ctrlrequest->wIndex & USB_DIR_IN; 437550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (is_in) 438550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep = &ep->ep_in; 439550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else 440550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep = &ep->ep_out; 441550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb_ep->desc) 442550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 443550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 444550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, epnum); 445550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (is_in) { 44646034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr = musb_readw(regs, MUSB_TXCSR); 447550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (csr & MUSB_TXCSR_FIFONOTEMPTY) 448550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr |= MUSB_TXCSR_FLUSHFIFO; 449550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr |= MUSB_TXCSR_P_SENDSTALL 450550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi | MUSB_TXCSR_CLRDATATOG 451550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi | MUSB_TXCSR_P_WZC_BITS; 45246034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_writew(regs, MUSB_TXCSR, csr); 453550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else { 45446034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov csr = musb_readw(regs, MUSB_RXCSR); 455550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr |= MUSB_RXCSR_P_SENDSTALL 456550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi | MUSB_RXCSR_FLUSHFIFO 457550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi | MUSB_RXCSR_CLRDATATOG 458f01b017d198486ee3553bee6841f788263cf2c23Sergei Shtylyov | MUSB_RXCSR_P_WZC_BITS; 45946034dca515bc4ddca0399ae58106d1f5f0d809fSergei Shtylyov musb_writew(regs, MUSB_RXCSR, csr); 460550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 461550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 462550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* select ep0 again */ 463550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, 0); 464550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 1; 465550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } break; 466550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 467550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 468550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* class, vendor, etc ... delegate */ 469550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 0; 470550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 471550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 472550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 473550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 474550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* delegate SET_CONFIGURATION, etc */ 475550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 0; 476550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 477550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else 478550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = 0; 479550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return handled; 480550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 481550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 482550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* we have an ep0out data packet 483550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 484550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 485550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic void ep0_rxstate(struct musb *musb) 486550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 487550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs = musb->control_ep->regs; 488ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi struct musb_request *request; 489550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct usb_request *req; 49064ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu u16 count, csr; 491550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 492ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi request = next_ep0_request(musb); 493ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi req = &request->request; 494550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 495550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* read packet and ack; or stall because of gadget driver bug: 496550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * should have provided the rx buffer before setup() returned. 497550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 498550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req) { 499550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void *buf = req->buf + req->actual; 500550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi unsigned len = req->length - req->actual; 501550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 502550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* read the buffer */ 50364ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu count = musb_readb(regs, MUSB_COUNT0); 50464ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu if (count > len) { 505550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->status = -EOVERFLOW; 50664ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu count = len; 507550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 50864ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu musb_read_fifo(&musb->endpoints[0], count, buf); 50964ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu req->actual += count; 51064ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu csr = MUSB_CSR0_P_SVDRXPKTRDY; 51164ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu if (count < 64 || req->actual == req->length) { 512550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; 51364ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu csr |= MUSB_CSR0_P_DATAEND; 514550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else 515550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req = NULL; 516550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else 51764ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu csr = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL; 518550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 519550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 520550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* Completion handler may choose to stall, e.g. because the 521550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * message just received holds invalid data. 522550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 523550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req) { 52464ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu musb->ackpend = csr; 525550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_g_ep0_giveback(musb, req); 526550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->ackpend) 527550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return; 528550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 529550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 530fb85d991616046f1b640ed9c4eab9b44908dab74Anand Gadiyar musb_ep_select(musb->mregs, 0); 53164ca44a65adf131c4df5124fe0fcdc3896f0f0dcBryan Wu musb_writew(regs, MUSB_CSR0, csr); 532550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 533550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 534550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 535550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * transmitting to the host (IN), this code might be called from IRQ 536550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * and from kernel thread. 537550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 538550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock 539550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 540550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic void ep0_txstate(struct musb *musb) 541550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 542550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs = musb->control_ep->regs; 543ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi struct musb_request *req = next_ep0_request(musb); 544ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi struct usb_request *request; 545550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 csr = MUSB_CSR0_TXPKTRDY; 546550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u8 *fifo_src; 547550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u8 fifo_count; 548550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 549ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi if (!req) { 550550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* WARN_ON(1); */ 5515c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0)); 552550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return; 553550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 554550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 555ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi request = &req->request; 556ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi 557550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* load the data */ 558550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi fifo_src = (u8 *) request->buf + request->actual; 559550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi fifo_count = min((unsigned) MUSB_EP0_FIFOSIZE, 560550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi request->length - request->actual); 561550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_write_fifo(&musb->endpoints[0], fifo_count, fifo_src); 562550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi request->actual += fifo_count; 563550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 564550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* update the flags */ 565550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (fifo_count < MUSB_MAX_END0_PACKET 5665542bc2ac7b52c021fc9c7a96329955491b7e763Daniel Glöckner || (request->actual == request->length 5675542bc2ac7b52c021fc9c7a96329955491b7e763Daniel Glöckner && !request->zero)) { 568550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; 569550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr |= MUSB_CSR0_P_DATAEND; 570550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else 571550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi request = NULL; 572550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 573550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* report completions as soon as the fifo's loaded; there's no 574550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * win in waiting till this last packet gets acked. (other than 575550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * very precise fault reporting, needed by USB TMC; possible with 576550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * this hardware, but not usable from portable gadget drivers.) 577550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 578550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (request) { 579550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = csr; 580550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_g_ep0_giveback(musb, request); 581550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->ackpend) 582550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return; 583550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 584550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 585550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 586550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* send it out, triggering a "txpktrdy cleared" irq */ 587fb85d991616046f1b640ed9c4eab9b44908dab74Anand Gadiyar musb_ep_select(musb->mregs, 0); 588550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, csr); 589550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 590550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 591550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 592550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Read a SETUP packet (struct usb_ctrlrequest) from the hardware. 593550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Fields are left in USB byte-order. 594550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 595550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: caller holds controller lock. 596550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 597550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic void 598550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbimusb_read_setup(struct musb *musb, struct usb_ctrlrequest *req) 599550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 600ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi struct musb_request *r; 601550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs = musb->control_ep->regs; 602550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 603550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_read_fifo(&musb->endpoints[0], sizeof *req, (u8 *)req); 604550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 605550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* NOTE: earlier 2.6 versions changed setup packets to host 606550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * order, but now USB packets always stay in USB byte order. 607550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 6085c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "SETUP req%02x.%02x v%04x i%04x l%d\n", 609550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->bRequestType, 610550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->bRequest, 611550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi le16_to_cpu(req->wValue), 612550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi le16_to_cpu(req->wIndex), 613550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi le16_to_cpu(req->wLength)); 614550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 615550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* clean up any leftover transfers */ 616550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi r = next_ep0_request(musb); 617550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (r) 618ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi musb_g_ep0_giveback(musb, &r->request); 619550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 620550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* For zero-data requests we want to delay the STATUS stage to 621550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * avoid SETUPEND errors. If we read data (OUT), delay accepting 622550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * packets until there's a buffer to store them in. 623550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 624550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * If we write data, the controller acts happier if we enable 625550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * the TX FIFO right away, and give the controller a moment 626550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * to switch modes... 627550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 628550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->set_address = false; 629550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY; 630550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req->wLength == 0) { 631550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req->bRequestType & USB_DIR_IN) 632550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend |= MUSB_CSR0_TXPKTRDY; 633550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT; 634550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else if (req->bRequestType & USB_DIR_IN) { 635550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_TX; 636550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDRXPKTRDY); 637550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi while ((musb_readw(regs, MUSB_CSR0) 638550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi & MUSB_CSR0_RXPKTRDY) != 0) 639550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi cpu_relax(); 640550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 641550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else 642550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_RX; 643550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 644550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 645550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int 646550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbiforward_to_driver(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) 647550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi__releases(musb->lock) 648550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi__acquires(musb->lock) 649550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 650550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int retval; 651550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!musb->gadget_driver) 652550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EOPNOTSUPP; 653550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_unlock(&musb->lock); 654550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = musb->gadget_driver->setup(&musb->g, ctrlrequest); 655550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_lock(&musb->lock); 656550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return retval; 657550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 658550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 659550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* 660550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Handle peripheral ep0 interrupt 661550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 662550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Context: irq handler; we won't re-enter the driver that way. 663550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 664550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbiirqreturn_t musb_g_ep0_irq(struct musb *musb) 665550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 666550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 csr; 667550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 len; 668550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *mbase = musb->mregs; 669550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs = musb->endpoints[0].regs; 670550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi irqreturn_t retval = IRQ_NONE; 671550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 672550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, 0); /* select ep0 */ 673550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr = musb_readw(regs, MUSB_CSR0); 674550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi len = musb_readb(regs, MUSB_COUNT0); 675550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 6765c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "csr %04x, count %d, myaddr %d, ep0stage %s\n", 677550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr, len, 678550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_readb(mbase, MUSB_FADDR), 679550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi decode_ep0stage(musb->ep0_state)); 680550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 681de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky if (csr & MUSB_CSR0_P_DATAEND) { 682de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky /* 683de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky * If DATAEND is set we should not call the callback, 684de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky * hence the status stage is not complete. 685de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky */ 686de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky return IRQ_HANDLED; 687de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky } 688de76cc2ba2116322f1bcc26f5b22d6092bb63a0dHans Petter Selasky 689550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* I sent a stall.. need to acknowledge it now.. */ 690550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (csr & MUSB_CSR0_P_SENTSTALL) { 691550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, 692550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr & ~MUSB_CSR0_P_SENTSTALL); 693550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 694a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_IDLE; 695550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr = musb_readw(regs, MUSB_CSR0); 696550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 697550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 698550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* request ended "early" */ 699550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (csr & MUSB_CSR0_P_SETUPEND) { 700550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND); 701550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 702a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov /* Transition into the early status phase */ 703a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov switch (musb->ep0_state) { 704a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov case MUSB_EP0_STAGE_TX: 705a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; 706a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov break; 707a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov case MUSB_EP0_STAGE_RX: 708a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; 709a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov break; 710a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov default: 71117be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov ERR("SetupEnd came in a wrong ep0stage %s\n", 712a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov decode_ep0stage(musb->ep0_state)); 713a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov } 714550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr = musb_readw(regs, MUSB_CSR0); 715550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* NOTE: request may need completion */ 716550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 717550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 718550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* docs from Mentor only describe tx, rx, and idle/setup states. 719550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * we need to handle nuances around status stages, and also the 720550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * case where status and setup stages come back-to-back ... 721550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 722550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (musb->ep0_state) { 723550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 724550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_TX: 725550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* irq on clearing txpktrdy */ 726550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if ((csr & MUSB_CSR0_TXPKTRDY) == 0) { 727550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep0_txstate(musb); 728550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 729550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 730550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 731550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 732550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_RX: 733550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* irq on set rxpktrdy */ 734550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (csr & MUSB_CSR0_RXPKTRDY) { 735550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep0_rxstate(musb); 736550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 737550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 738550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 739550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 740550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSIN: 741550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* end of sequence #2 (OUT/RX state) or #3 (no data) */ 742550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 743550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* update address (if needed) only @ the end of the 744550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * status phase per usb spec, which also guarantees 745550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * we get 10 msec to receive this irq... until this 746550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * is done we won't see the next packet. 747550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 748550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (musb->set_address) { 749550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->set_address = false; 750550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writeb(mbase, MUSB_FADDR, musb->address); 751550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 752550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 753550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* enter test mode if needed (exit by reset) */ 754550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else if (musb->test_mode) { 7555c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "entering TESTMODE\n"); 756550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 757550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (MUSB_TEST_PACKET == musb->test_mode_nr) 758550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_load_testpacket(musb); 759550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 760550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writeb(mbase, MUSB_TESTMODE, 761550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->test_mode_nr); 762550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 763550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* FALLTHROUGH */ 764550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 765550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSOUT: 766550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* end of sequence #1: write to host (TX state) */ 767550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi { 768ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi struct musb_request *req; 769550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 770550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req = next_ep0_request(musb); 771550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req) 772ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi musb_g_ep0_giveback(musb, &req->request); 773550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 774a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov 775a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov /* 776a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * In case when several interrupts can get coalesced, 777a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * check to see if we've already received a SETUP packet... 778a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov */ 779a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov if (csr & MUSB_CSR0_RXPKTRDY) 780a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov goto setup; 781a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov 782a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov retval = IRQ_HANDLED; 783a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_IDLE; 784a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov break; 785a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov 786a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov case MUSB_EP0_STAGE_IDLE: 787a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov /* 788a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * This state is typically (but not always) indiscernible 789a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * from the status states since the corresponding interrupts 790a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * tend to happen within too little period of time (with only 791a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov * a zero-length packet in between) and so get coalesced... 792a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov */ 793550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 794550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_SETUP; 795550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* FALLTHROUGH */ 796550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 797550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_SETUP: 798a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyovsetup: 799550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (csr & MUSB_CSR0_RXPKTRDY) { 800550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct usb_ctrlrequest setup; 801550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int handled = 0; 802550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 803550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (len != 8) { 804550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ERR("SETUP packet len %d != 8 ?\n", len); 805550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 806550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 807550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_read_setup(musb, &setup); 808550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 809550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 810550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sometimes the RESET won't be reported */ 811550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (unlikely(musb->g.speed == USB_SPEED_UNKNOWN)) { 812550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u8 power; 813550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 814550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi printk(KERN_NOTICE "%s: peripheral reset " 815550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi "irq lost!\n", 816550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_driver_name); 817550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi power = musb_readb(mbase, MUSB_POWER); 818550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->g.speed = (power & MUSB_POWER_HSMODE) 819550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ? USB_SPEED_HIGH : USB_SPEED_FULL; 820550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 821550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 822550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 823550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (musb->ep0_state) { 824550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 825550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sequence #3 (no data stage), includes requests 826550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * we can't forward (notably SET_ADDRESS and the 827550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * device/endpoint feature set/clear operations) 828550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * plus SET_CONFIGURATION and others we must 829550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 830550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_ACKWAIT: 831550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = service_zero_data_request( 832550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb, &setup); 833550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 83417be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov /* 83517be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov * We're expecting no data in any case, so 83617be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov * always set the DATAEND bit -- doing this 83717be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov * here helps avoid SetupEnd interrupt coming 83817be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov * in the idle stage when we're stalling... 83917be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov */ 84017be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov musb->ackpend |= MUSB_CSR0_P_DATAEND; 84117be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov 842550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* status stage might be immediate */ 84317be5c5f5ef99c94374e07f71effa78e93a20edaSergei Shtylyov if (handled > 0) 844550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = 845550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_EP0_STAGE_STATUSIN; 846550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 847550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 848550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sequence #1 (IN to host), includes GET_STATUS 849550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * requests that we can't forward, GET_DESCRIPTOR 850550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * and others that we must 851550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 852550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_TX: 853550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = service_in_request(musb, &setup); 854550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (handled > 0) { 855550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = MUSB_CSR0_TXPKTRDY 856550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi | MUSB_CSR0_P_DATAEND; 857550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = 858550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi MUSB_EP0_STAGE_STATUSOUT; 859550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 860550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 861550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 862550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sequence #2 (OUT from host), always forward */ 863550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: /* MUSB_EP0_STAGE_RX */ 864550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 865550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 866550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 8675c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "handled %d, csr %04x, ep0stage %s\n", 868550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled, csr, 869550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi decode_ep0stage(musb->ep0_state)); 870550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 871550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* unless we need to delegate this to the gadget 872550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * driver, we know how to wrap this up: csr0 has 873550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * not yet been written. 874550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 875550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (handled < 0) 876550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto stall; 877550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else if (handled > 0) 878550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto finish; 879550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 880550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi handled = forward_to_driver(musb, &setup); 881550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (handled < 0) { 882550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(mbase, 0); 883550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistall: 8845c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "stall (%d)\n", handled); 885550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend |= MUSB_CSR0_P_SENDSTALL; 886a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_IDLE; 887550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbifinish: 888550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, 889550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend); 890550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 891550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 892550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 893550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 894550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 895550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_ACKWAIT: 896550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* This should not happen. But happens with tusb6010 with 897550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * g_file_storage and high speed. Do nothing. 898550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 899550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi retval = IRQ_HANDLED; 900550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 901550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 902550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 903550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* "can't happen" */ 904550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi WARN_ON(1); 905550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL); 906a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_IDLE; 907550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 908550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 909550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 910550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return retval; 911550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 912550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 913550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 914550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int 915550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbimusb_g_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) 916550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 917550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* always enabled */ 918550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EINVAL; 919550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 920550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 921550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int musb_g_ep0_disable(struct usb_ep *e) 922550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 923550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* always enabled */ 924550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EINVAL; 925550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 926550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 927550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int 928550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbimusb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) 929550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 930550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_ep *ep; 931550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_request *req; 932550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb *musb; 933550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int status; 934550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi unsigned long lockflags; 935550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *regs; 936550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 937550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!e || !r) 938550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EINVAL; 939550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 940550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep = to_musb_ep(e); 941550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb = ep->musb; 942550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi regs = musb->control_ep->regs; 943550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 944550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req = to_musb_request(r); 945550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->musb = musb; 946550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->request.actual = 0; 947550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->request.status = -EINPROGRESS; 948550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->tx = ep->is_in; 949550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 950550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_lock_irqsave(&musb->lock, lockflags); 951550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 952550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!list_empty(&ep->req_list)) { 953550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = -EBUSY; 954550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto cleanup; 955550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 956550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 957550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (musb->ep0_state) { 958550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_RX: /* control-OUT data */ 959550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_TX: /* control-IN data */ 960550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_ACKWAIT: /* zero-length data */ 961550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = 0; 962550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 963550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 9645c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "ep0 request queued in state %d\n", 965550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state); 966550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = -EINVAL; 967550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto cleanup; 968550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 969550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 970550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* add request to the list */ 971ad1adb89a0d9410345d573b6995a1fa9f9b7c74aFelipe Balbi list_add_tail(&req->list, &ep->req_list); 972550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 9735c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "queue to %s (%s), length=%d\n", 974550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep->name, ep->is_in ? "IN/TX" : "OUT/RX", 975550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi req->request.length); 976550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 977550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(musb->mregs, 0); 978550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 979550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sequence #1, IN ... start writing the data */ 980550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (musb->ep0_state == MUSB_EP0_STAGE_TX) 981550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep0_txstate(musb); 982550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 983550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* sequence #3, no-data ... issue IN status */ 984550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else if (musb->ep0_state == MUSB_EP0_STAGE_ACKWAIT) { 985550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (req->request.length) 986550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = -EINVAL; 987550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi else { 988550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; 989550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, 990550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend | MUSB_CSR0_P_DATAEND); 991550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 992550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_g_ep0_giveback(ep->musb, r); 993550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 994550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 995550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* else for sequence #2 (OUT), caller provides a buffer 996550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * before the next packet arrives. deferred responses 997550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * (after SETUP is acked) are racey. 998550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 999550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } else if (musb->ackpend) { 1000550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, musb->ackpend); 1001550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 1002550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 1003550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1004550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbicleanup: 1005550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_unlock_irqrestore(&musb->lock, lockflags); 1006550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return status; 1007550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 1008550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1009550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int musb_g_ep0_dequeue(struct usb_ep *ep, struct usb_request *req) 1010550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 1011550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* we just won't support this */ 1012550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EINVAL; 1013550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 1014550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1015550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int musb_g_ep0_halt(struct usb_ep *e, int value) 1016550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{ 1017550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb_ep *ep; 1018550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi struct musb *musb; 1019550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi void __iomem *base, *regs; 1020550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi unsigned long flags; 1021550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi int status; 1022550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi u16 csr; 1023550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1024550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!e || !value) 1025550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return -EINVAL; 1026550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1027550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi ep = to_musb_ep(e); 1028550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb = ep->musb; 1029550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi base = musb->mregs; 1030550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi regs = musb->control_ep->regs; 1031550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = 0; 1032550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1033550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_lock_irqsave(&musb->lock, flags); 1034550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1035550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi if (!list_empty(&ep->req_list)) { 1036550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = -EBUSY; 1037550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi goto cleanup; 1038550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 1039550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1040550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_ep_select(base, 0); 1041550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr = musb->ackpend; 1042550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1043550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi switch (musb->ep0_state) { 1044550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1045550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* Stalls are usually issued after parsing SETUP packet, either 1046550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * directly in irq context from setup() or else later. 1047550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 1048550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_TX: /* control-IN data */ 1049550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_ACKWAIT: /* STALL for zero-length data */ 1050550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_RX: /* control-OUT data */ 1051550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr = musb_readw(regs, MUSB_CSR0); 1052550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* FALLTHROUGH */ 1053550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1054550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi /* It's also OK to issue stalls during callbacks when a non-empty 1055550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * DATA stage buffer has been read (or even written). 1056550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */ 1057550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSIN: /* control-OUT status */ 1058550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi case MUSB_EP0_STAGE_STATUSOUT: /* control-IN status */ 1059550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1060550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi csr |= MUSB_CSR0_P_SENDSTALL; 1061550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb_writew(regs, MUSB_CSR0, csr); 1062a5073b52833e4df8e16c93dc4cbb7e0c558c74a2Sergei Shtylyov musb->ep0_state = MUSB_EP0_STAGE_IDLE; 1063550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi musb->ackpend = 0; 1064550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi break; 1065550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi default: 10665c8a86e10a7c164f44537fabdc169fd8b4e7a440Felipe Balbi dev_dbg(musb->controller, "ep0 can't halt in state %d\n", musb->ep0_state); 1067550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi status = -EINVAL; 1068550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi } 1069550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1070550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbicleanup: 1071550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi spin_unlock_irqrestore(&musb->lock, flags); 1072550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi return status; 1073550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi} 1074550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi 1075550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbiconst struct usb_ep_ops musb_g_ep0_ops = { 1076550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .enable = musb_g_ep0_enable, 1077550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .disable = musb_g_ep0_disable, 1078550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .alloc_request = musb_alloc_request, 1079550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .free_request = musb_free_request, 1080550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .queue = musb_g_ep0_queue, 1081550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .dequeue = musb_g_ep0_dequeue, 1082550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi .set_halt = musb_g_ep0_halt, 1083550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}; 1084