int MGC_GadgetFifoStatus(struct usb_ep *ep) { struct musb_ep *musb_ep = to_musb_ep(ep); struct musb *pThis = musb_ep->pThis; int bEnd = musb_ep->bEndNumber; unsigned long flags; int nResult = 0; u8 *pBase = pThis->pRegs; DBG(2, "<==\n"); #ifdef MUSB_PARANOID ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); #endif spin_lock_irqsave(&(pThis->Lock), flags); MGC_SelectEnd(pBase, bEnd); nResult = MGC_ReadCsr16(pBase, (bEnd) ? MGC_O_HDRC_RXCOUNT : MGC_O_HDRC_COUNT0, bEnd); spin_unlock_irqrestore(&(pThis->Lock), flags); DBG(2, "==> %d\n", nResult); return nResult; }
void MGC_GadgetFifoFlush(struct usb_ep *ep) { struct musb_ep *musb_ep = to_musb_ep(ep); MGC_LinuxCd *pThis; u8 *pBase; u8 nEnd; unsigned long flags; u16 wCsr, wIntrTxE; if (!ep) return; pThis = musb_ep->pThis; pBase = pThis->pRegs; nEnd = musb_ep->bEndNumber; #ifdef MUSB_PARANOID if (!pThis) { ERR("Gadget not initialized, pThis=NULL\n"); return; } ASSERT_SPINLOCK_UNLOCKED(&pThis->Lock); #endif spin_lock_irqsave(&(pThis->Lock), flags); MGC_SelectEnd(pBase, (u8) nEnd); /* disable interrupts */ wIntrTxE = MGC_Read16(pBase, MGC_O_HDRC_INTRTXE); MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << nEnd)); if (nEnd) { if (musb_ep->bIsTx) { wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, nEnd); wCsr |= MGC_M_TXCSR_FLUSHFIFO; MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, nEnd, wCsr); MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, nEnd, wCsr); } else { wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, nEnd); wCsr |= MGC_M_RXCSR_FLUSHFIFO; MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, nEnd, wCsr); MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, nEnd, wCsr); } } else { MGC_WriteCsr16(pBase, MGC_O_HDRC_CSR0, 0, MGC_M_CSR0_FLUSHFIFO); } /* re-enable interrupt */ MGC_Write16(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE); spin_unlock_irqrestore(&(pThis->Lock), flags); }
/** * Dump core registers whose reads are non-destructive. * @param pThis * @param bEnd */ void MGC_HdrcDumpRegs(u8 * pBase, int multipoint, u8 bEnd) { MGC_SelectEnd(pBase, bEnd); if (!bEnd) { printk(KERN_INFO " 0: CSR0=%04x, Count0=%02x, Type0=%02x, NAKlimit0=%02x\n", MGC_ReadCsr16(pBase, MGC_O_HDRC_CSR0, 0), MGC_ReadCsr8(pBase, MGC_O_HDRC_COUNT0, 0), MGC_ReadCsr8(pBase, MGC_O_HDRC_TYPE0, 0), MGC_ReadCsr8(pBase, MGC_O_HDRC_NAKLIMIT0, 0)); } else { printk(KERN_INFO "%2d: TxCSR=%04x, TxMaxP=%04x, TxType=%02x, TxInterval=%02x\n", bEnd, MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd), MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd), MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd), MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd)); printk(KERN_INFO " RxCSR=%04x, RxMaxP=%04x, RxType=%02x, RxInterval=%02x, RxCount=%04x\n", MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd), MGC_ReadCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd), MGC_ReadCsr8(pBase, MGC_O_HDRC_TXTYPE, bEnd), MGC_ReadCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd), MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd)); } if (multipoint) { printk(KERN_INFO " TxAddr=%02x, TxHubAddr=%02x, TxHubPort=%02x\n", MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR)), MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR)), MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT))); printk(KERN_INFO " RxAddr=%02x, RxHubAddr=%02x, RxHubPort=%02x\n", MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXFUNCADDR)), MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBADDR)), MGC_Read8(pBase, MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_RXHUBPORT))); } }
/* handle a standard GET_STATUS request * Context: caller holds controller lock */ static int service_tx_status_request(struct musb *pThis, const struct usb_ctrlrequest *pControlRequest) { void __iomem *pBase = pThis->pRegs; int handled = 1; u8 bResult[2], bEnd = 0; const u8 bRecip = pControlRequest->bRequestType & USB_RECIP_MASK; bResult[1] = 0; switch (bRecip) { case USB_RECIP_DEVICE: bResult[0] = pThis->bIsSelfPowered << USB_DEVICE_SELF_POWERED; bResult[0] |= pThis->bMayWakeup << USB_DEVICE_REMOTE_WAKEUP; #ifdef CONFIG_USB_MUSB_OTG if (pThis->g.is_otg) { bResult[0] |= pThis->g.b_hnp_enable << USB_DEVICE_B_HNP_ENABLE; bResult[0] |= pThis->g.a_alt_hnp_support << USB_DEVICE_A_ALT_HNP_SUPPORT; bResult[0] |= pThis->g.a_hnp_support << USB_DEVICE_A_HNP_SUPPORT; } #endif break; case USB_RECIP_INTERFACE: bResult[0] = 0; break; case USB_RECIP_ENDPOINT:{ int is_in; struct musb_ep *ep; u16 tmp; bEnd = (u8) le16_to_cpu(pControlRequest->wIndex); if (!bEnd) { bResult[0] = 0; break; } is_in = bEnd & USB_DIR_IN; if (is_in) { bEnd &= 0x0f; ep = &pThis->aLocalEnd[bEnd * 2 - 1].ep_in; } else { ep = &pThis->aLocalEnd[bEnd * 2].ep_out; } if (bEnd >= MUSB_C_NUM_EPS || !ep->desc) { handled = -EINVAL; break; } MGC_SelectEnd(pBase, bEnd); if (is_in) tmp = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd) & MGC_M_TXCSR_P_SENDSTALL; else tmp = MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd) & MGC_M_RXCSR_P_SENDSTALL; bResult[0] = tmp ? 1 : 0; } break; default: /* class, vendor, etc ... delegate */ handled = 0; break; } /* fill up the fifo; caller updates csr0 */ if (handled > 0) { u16 len = le16_to_cpu(pControlRequest->wLength); if (len > 2) len = 2; if (len) musb_write_fifo(&pThis->aLocalEnd[0], len, bResult); } return handled; }