^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ISP1362 HCD (Host Controller Driver) for USB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005 Lothar Wassmann <LW@KARO-electronics.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Derived from the SL811 HCD, rewritten for ISP116x.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Portions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2004 David Brownell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * The ISP1362 chip requires a large delay (300ns and 462ns) between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * accesses to the address and data register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * The following timing options exist:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * 1. Configure your memory controller to add such delays if it can (the best)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 2. Implement platform-specific delay function possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * combined with configuring the memory controller; see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * include/linux/usb_isp1362.h for more info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 3. Use ndelay (easiest, poorest).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Use the corresponding macros USE_PLATFORM_DELAY and USE_NDELAY in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * platform specific section of isp1362.h to select the appropriate variant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Also note that according to the Philips "ISP1362 Errata" document
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Rev 1.00 from 27 May data corruption may occur when the #WR signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * is reasserted (even with #CS deasserted) within 132ns after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * write cycle to any controller register. If the hardware doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * implement the recommended fix (gating the #WR with #CS) software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * must ensure that no further write cycle (not necessarily to the chip!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * is issued by the CPU within this interval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * For PXA25x this can be ensured by using VLIO with the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * recovery time (MSCx = 0x7f8c) with a memory clock of 99.53 MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #undef ISP1362_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * The PXA255 UDC apparently doesn't handle GET_STATUS, GET_CONFIG and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * GET_INTERFACE requests correctly when the SETUP and DATA stages of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * requests are carried out in separate frames. This will delay any SETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * packets until the start of the next frame so that this situation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * unlikely to occur (and makes usbtest happy running with a PXA255 target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * device).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #undef BUGGY_PXA2XX_UDC_USBTEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #undef PTD_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #undef URB_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #undef VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #undef REGISTERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* This enables a memory test on the ISP1362 chip memory to make sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * chip access timing is correct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #undef CHIP_BUFFER_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/usb/isp1362.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <linux/usb/hcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/prefetch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int dbg_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #ifdef ISP1362_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) module_param(dbg_level, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) module_param(dbg_level, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include "../core/usb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include "isp1362.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define DRIVER_VERSION "2005-04-04"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define DRIVER_DESC "ISP1362 USB Host Controller Driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const char hcd_name[] = "isp1362-hcd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void isp1362_hc_stop(struct usb_hcd *hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int isp1362_hc_start(struct usb_hcd *hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * When called from the interrupthandler only isp1362_hcd->irqenb is modified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * since the interrupt handler will write isp1362_hcd->irqenb to HCuPINT upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * We don't need a 'disable' counterpart, since interrupts will be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * only by the interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline void isp1362_enable_int(struct isp1362_hcd *isp1362_hcd, u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if ((isp1362_hcd->irqenb | mask) == isp1362_hcd->irqenb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (mask & ~isp1362_hcd->irqenb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) isp1362_write_reg16(isp1362_hcd, HCuPINT, mask & ~isp1362_hcd->irqenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) isp1362_hcd->irqenb |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (isp1362_hcd->irq_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline struct isp1362_ep_queue *get_ptd_queue(struct isp1362_hcd *isp1362_hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u16 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct isp1362_ep_queue *epq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (offset < isp1362_hcd->istl_queue[1].buf_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) epq = &isp1362_hcd->istl_queue[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) else if (offset < isp1362_hcd->intl_queue.buf_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) epq = &isp1362_hcd->istl_queue[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) else if (offset < isp1362_hcd->atl_queue.buf_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) epq = &isp1362_hcd->intl_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) else if (offset < isp1362_hcd->atl_queue.buf_start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) isp1362_hcd->atl_queue.buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) epq = &isp1362_hcd->atl_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) DBG(1, "%s: PTD $%04x is on %s queue\n", __func__, offset, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pr_warn("%s: invalid PTD $%04x\n", __func__, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return epq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static inline int get_ptd_offset(struct isp1362_ep_queue *epq, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (index * epq->blk_size > epq->buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pr_warn("%s: Bad %s index %d(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) __func__, epq->name, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) epq->buf_size / epq->blk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) offset = epq->buf_start + index * epq->blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) DBG(3, "%s: %s PTD[%02x] # %04x\n", __func__, epq->name, index, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static inline u16 max_transfer_size(struct isp1362_ep_queue *epq, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int mps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u16 xfer_size = min_t(size_t, MAX_XFER_SIZE, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) xfer_size = min_t(size_t, xfer_size, epq->buf_avail * epq->blk_size - PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (xfer_size < size && xfer_size % mps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) xfer_size -= xfer_size % mps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return xfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int claim_ptd_buffers(struct isp1362_ep_queue *epq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct isp1362_ep *ep, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int ptd_offset = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int num_ptds = ((len + PTD_HEADER_SIZE - 1) / epq->blk_size) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) BUG_ON(len > epq->buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!epq->buf_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (ep->num_ptds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pr_err("%s: %s len %d/%d num_ptds %d buf_map %08lx skip_map %08lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) epq->name, len, epq->blk_size, num_ptds, epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) BUG_ON(ep->num_ptds != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) found = bitmap_find_next_zero_area(&epq->buf_map, epq->buf_count, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) num_ptds, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (found >= epq->buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) DBG(1, "%s: Found %d PTDs[%d] for %d/%d byte\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) num_ptds, found, len, (int)(epq->blk_size - PTD_HEADER_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ptd_offset = get_ptd_offset(epq, found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) WARN_ON(ptd_offset < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ep->ptd_offset = ptd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ep->num_ptds += num_ptds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) epq->buf_avail -= num_ptds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) BUG_ON(epq->buf_avail > epq->buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ep->ptd_index = found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) bitmap_set(&epq->buf_map, found, num_ptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) DBG(1, "%s: Done %s PTD[%d] $%04x, avail %d count %d claimed %d %08lx:%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) __func__, epq->name, ep->ptd_index, ep->ptd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) epq->buf_avail, epq->buf_count, num_ptds, epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static inline void release_ptd_buffers(struct isp1362_ep_queue *epq, struct isp1362_ep *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int last = ep->ptd_index + ep->num_ptds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (last > epq->buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pr_err("%s: ep %p req %d len %d %s PTD[%d] $%04x num_ptds %d buf_count %d buf_avail %d buf_map %08lx skip_map %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) __func__, ep, ep->num_req, ep->length, epq->name, ep->ptd_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ep->ptd_offset, ep->num_ptds, epq->buf_count, epq->buf_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) BUG_ON(last > epq->buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) bitmap_clear(&epq->buf_map, ep->ptd_index, ep->num_ptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bitmap_set(&epq->skip_map, ep->ptd_index, ep->num_ptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) epq->buf_avail += ep->num_ptds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) epq->ptd_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) BUG_ON(epq->buf_avail > epq->buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) BUG_ON(epq->ptd_count > epq->buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) DBG(1, "%s: Done %s PTDs $%04x released %d avail %d count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) __func__, epq->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ep->ptd_offset, ep->num_ptds, epq->buf_avail, epq->buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) DBG(1, "%s: buf_map %08lx skip_map %08lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ep->num_ptds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ep->ptd_offset = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ep->ptd_index = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) Set up PTD's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void prepare_ptd(struct isp1362_hcd *isp1362_hcd, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct isp1362_ep *ep, struct isp1362_ep_queue *epq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u16 fno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct ptd *ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int toggle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) size_t buf_len = urb->transfer_buffer_length - urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) DBG(3, "%s: %s ep %p\n", __func__, epq->name, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ptd = &ep->ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ep->data = (unsigned char *)urb->transfer_buffer + urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) switch (ep->nextpid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case USB_PID_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) toggle = usb_gettoggle(urb->dev, ep->epnum, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dir = PTD_DIR_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (usb_pipecontrol(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) len = min_t(size_t, ep->maxpacket, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) } else if (usb_pipeisoc(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) len = min_t(size_t, urb->iso_frame_desc[fno].length, MAX_XFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ep->data = urb->transfer_buffer + urb->iso_frame_desc[fno].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) len = max_transfer_size(epq, buf_len, ep->maxpacket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) DBG(1, "%s: IN len %d/%d/%d from URB\n", __func__, len, ep->maxpacket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) (int)buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case USB_PID_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) toggle = usb_gettoggle(urb->dev, ep->epnum, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dir = PTD_DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (usb_pipecontrol(urb->pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) len = min_t(size_t, ep->maxpacket, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) else if (usb_pipeisoc(urb->pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) len = min_t(size_t, urb->iso_frame_desc[0].length, MAX_XFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) len = max_transfer_size(epq, buf_len, ep->maxpacket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pr_info("%s: Sending ZERO packet: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) urb->transfer_flags & URB_ZERO_PACKET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) DBG(1, "%s: OUT len %d/%d/%d from URB\n", __func__, len, ep->maxpacket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) (int)buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case USB_PID_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) toggle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dir = PTD_DIR_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) len = sizeof(struct usb_ctrlrequest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) DBG(1, "%s: SETUP len %d\n", __func__, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ep->data = urb->setup_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case USB_PID_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) toggle = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dir = (urb->transfer_buffer_length && usb_pipein(urb->pipe)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) PTD_DIR_OUT : PTD_DIR_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) DBG(1, "%s: ACK len %d\n", __func__, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) toggle = dir = len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pr_err("%s@%d: ep->nextpid %02x\n", __func__, __LINE__, ep->nextpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) BUG_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ep->length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ep->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ptd->mps = PTD_MPS(ep->maxpacket) | PTD_SPD(urb->dev->speed == USB_SPEED_LOW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) PTD_EP(ep->epnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ptd->len = PTD_LEN(len) | PTD_DIR(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (usb_pipeint(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ptd->faddr |= PTD_SF_INT(ep->branch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ptd->faddr |= PTD_PR(ep->interval ? __ffs(ep->interval) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (usb_pipeisoc(urb->pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ptd->faddr |= PTD_SF_ISO(fno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) DBG(1, "%s: Finished\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void isp1362_write_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct isp1362_ep_queue *epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct ptd *ptd = &ep->ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int len = PTD_GET_DIR(ptd) == PTD_DIR_IN ? 0 : ep->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) prefetch(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) isp1362_write_buffer(isp1362_hcd, ptd, ep->ptd_offset, PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) isp1362_write_buffer(isp1362_hcd, ep->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ep->ptd_offset + PTD_HEADER_SIZE, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dump_ptd(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dump_ptd_out_data(ptd, ep->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static void isp1362_read_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct isp1362_ep_queue *epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct ptd *ptd = &ep->ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int act_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) WARN_ON(list_empty(&ep->active));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) BUG_ON(ep->ptd_offset < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) list_del_init(&ep->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) DBG(1, "%s: ep %p removed from active list %p\n", __func__, ep, &epq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) prefetchw(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) isp1362_read_buffer(isp1362_hcd, ptd, ep->ptd_offset, PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dump_ptd(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) act_len = PTD_GET_COUNT(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (PTD_GET_DIR(ptd) != PTD_DIR_IN || act_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (act_len > ep->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) pr_err("%s: ep %p PTD $%04x act_len %d ep->length %d\n", __func__, ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ep->ptd_offset, act_len, ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) BUG_ON(act_len > ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Only transfer the amount of data that has actually been overwritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * in the chip buffer. We don't want any data that doesn't belong to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * transfer to leak out of the chip to the callers transfer buffer!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) prefetchw(ep->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) isp1362_read_buffer(isp1362_hcd, ep->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ep->ptd_offset + PTD_HEADER_SIZE, act_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dump_ptd_in_data(ptd, ep->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * INT PTDs will stay in the chip until data is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * This function will remove a PTD from the chip when the URB is dequeued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Must be called with the spinlock held and IRQs disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void remove_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct isp1362_ep_queue *epq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) DBG(1, "%s: ep %p PTD[%d] $%04x\n", __func__, ep, ep->ptd_index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) BUG_ON(ep->ptd_offset < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) epq = get_ptd_queue(isp1362_hcd, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) BUG_ON(!epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* put ep in remove_list for cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) WARN_ON(!list_empty(&ep->remove_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) list_add_tail(&ep->remove_list, &isp1362_hcd->remove_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* let SOF interrupt handle the cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) isp1362_enable_int(isp1362_hcd, HCuPINT_SOF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) index = ep->ptd_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* ISO queues don't have SKIP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) DBG(1, "%s: Disabling PTD[%02x] $%04x %08lx|%08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) index, ep->ptd_offset, epq->skip_map, 1 << index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* prevent further processing of PTD (will be effective after next SOF) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) epq->skip_map |= 1 << index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (epq == &isp1362_hcd->atl_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) DBG(2, "%s: ATLSKIP = %08x -> %08lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) isp1362_read_reg32(isp1362_hcd, HCATLSKIP), epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) isp1362_write_reg32(isp1362_hcd, HCATLSKIP, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (~epq->skip_map == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) } else if (epq == &isp1362_hcd->intl_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) DBG(2, "%s: INTLSKIP = %08x -> %08lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) isp1362_read_reg32(isp1362_hcd, HCINTLSKIP), epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (~epq->skip_map == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) Take done or failed requests out of schedule. Give back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) processed urbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void finish_request(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct urb *urb, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) __releases(isp1362_hcd->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) __acquires(isp1362_hcd->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) urb->hcpriv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ep->error_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (usb_pipecontrol(urb->pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ep->nextpid = USB_PID_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) URB_DBG("%s: req %d FA %d ep%d%s %s: len %d/%d %s stat %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ep->num_req, usb_pipedevice(urb->pipe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) usb_pipeendpoint(urb->pipe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) !usb_pipein(urb->pipe) ? "out" : "in",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) usb_pipecontrol(urb->pipe) ? "ctrl" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) usb_pipeint(urb->pipe) ? "int" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) usb_pipebulk(urb->pipe) ? "bulk" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) "iso",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) urb->actual_length, urb->transfer_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) !(urb->transfer_flags & URB_SHORT_NOT_OK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) "short_ok" : "", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) usb_hcd_unlink_urb_from_ep(isp1362_hcd_to_hcd(isp1362_hcd), urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_unlock(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) usb_hcd_giveback_urb(isp1362_hcd_to_hcd(isp1362_hcd), urb, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) spin_lock(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* take idle endpoints out of the schedule right away */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!list_empty(&ep->hep->urb_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* async deschedule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!list_empty(&ep->schedule)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) list_del_init(&ep->schedule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ep->interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* periodic deschedule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) DBG(1, "deschedule qh%d/%p branch %d load %d bandwidth %d -> %d\n", ep->interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ep, ep->branch, ep->load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) isp1362_hcd->load[ep->branch],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) isp1362_hcd->load[ep->branch] - ep->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) isp1362_hcd->load[ep->branch] -= ep->load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ep->branch = PERIODIC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Analyze transfer results, handle partial transfers and errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct urb *urb = get_urb(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct ptd *ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int short_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int urbstat = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u8 cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) DBG(2, "%s: ep %p req %d\n", __func__, ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) udev = urb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ptd = &ep->ptd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) cc = PTD_GET_CC(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (cc == PTD_NOTACCESSED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) pr_err("%s: req %d PTD %p Untouched by ISP1362\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ep->num_req, ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) cc = PTD_DEVNOTRESP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) short_ok = !(urb->transfer_flags & URB_SHORT_NOT_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) len = urb->transfer_buffer_length - urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* Data underrun is special. For allowed underrun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) we clear the error and continue as normal. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) forbidden underrun we finish the DATA stage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) immediately while for control transfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) we do a STATUS stage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (cc == PTD_DATAUNDERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (short_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) DBG(1, "%s: req %d Allowed data underrun short_%sok %d/%d/%d byte\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) __func__, ep->num_req, short_ok ? "" : "not_",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) PTD_GET_COUNT(ptd), ep->maxpacket, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cc = PTD_CC_NOERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) urbstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) DBG(1, "%s: req %d Data Underrun %s nextpid %02x short_%sok %d/%d/%d byte\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) __func__, ep->num_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) short_ok ? "" : "not_",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) PTD_GET_COUNT(ptd), ep->maxpacket, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* save the data underrun error code for later and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * proceed with the status stage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) urb->actual_length += PTD_GET_COUNT(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (usb_pipecontrol(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ep->nextpid = USB_PID_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) BUG_ON(urb->actual_length > urb->transfer_buffer_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (urb->status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) urb->status = cc_to_error[PTD_DATAUNDERRUN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) usb_settoggle(udev, ep->epnum, ep->nextpid == USB_PID_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) PTD_GET_TOGGLE(ptd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) urbstat = cc_to_error[PTD_DATAUNDERRUN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (cc != PTD_CC_NOERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (++ep->error_count >= 3 || cc == PTD_CC_STALL || cc == PTD_DATAOVERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) urbstat = cc_to_error[cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) DBG(1, "%s: req %d nextpid %02x, status %d, error %d, error_count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) __func__, ep->num_req, ep->nextpid, urbstat, cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ep->error_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) switch (ep->nextpid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case USB_PID_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (PTD_GET_COUNT(ptd) != ep->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) pr_err("%s: count=%d len=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) PTD_GET_COUNT(ptd), ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) BUG_ON(PTD_GET_COUNT(ptd) != ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) urb->actual_length += ep->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) BUG_ON(urb->actual_length > urb->transfer_buffer_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (urb->actual_length == urb->transfer_buffer_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) DBG(3, "%s: req %d xfer complete %d/%d status %d -> 0\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ep->num_req, len, ep->maxpacket, urbstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (usb_pipecontrol(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) DBG(3, "%s: req %d %s Wait for ACK\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ep->num_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) usb_pipein(urb->pipe) ? "IN" : "OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ep->nextpid = USB_PID_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (len % ep->maxpacket ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) !(urb->transfer_flags & URB_ZERO_PACKET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) urbstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) DBG(3, "%s: req %d URB %s status %d count %d/%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) __func__, ep->num_req, usb_pipein(urb->pipe) ? "IN" : "OUT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) urbstat, len, ep->maxpacket, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case USB_PID_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) len = PTD_GET_COUNT(ptd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) BUG_ON(len > ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) urb->actual_length += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) BUG_ON(urb->actual_length > urb->transfer_buffer_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* if transfer completed or (allowed) data underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if ((urb->transfer_buffer_length == urb->actual_length) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) len % ep->maxpacket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) DBG(3, "%s: req %d xfer complete %d/%d status %d -> 0\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ep->num_req, len, ep->maxpacket, urbstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (usb_pipecontrol(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) DBG(3, "%s: req %d %s Wait for ACK\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ep->num_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) usb_pipein(urb->pipe) ? "IN" : "OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ep->nextpid = USB_PID_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) urbstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) DBG(3, "%s: req %d URB %s status %d count %d/%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) __func__, ep->num_req, usb_pipein(urb->pipe) ? "IN" : "OUT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) urbstat, len, ep->maxpacket, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case USB_PID_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (urb->transfer_buffer_length == urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ep->nextpid = USB_PID_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) } else if (usb_pipeout(urb->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) usb_settoggle(udev, 0, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ep->nextpid = USB_PID_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) usb_settoggle(udev, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ep->nextpid = USB_PID_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case USB_PID_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) DBG(3, "%s: req %d got ACK %d -> 0\n", __func__, ep->num_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) urbstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) WARN_ON(urbstat != -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) urbstat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ep->nextpid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) BUG_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (urbstat != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) DBG(2, "%s: Finishing ep %p req %d urb %p status %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) ep, ep->num_req, urb, urbstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) finish_request(isp1362_hcd, ep, urb, urbstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static void finish_unlinks(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct isp1362_ep *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) list_for_each_entry_safe(ep, tmp, &isp1362_hcd->remove_list, remove_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct isp1362_ep_queue *epq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) get_ptd_queue(isp1362_hcd, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int index = ep->ptd_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) BUG_ON(epq == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) DBG(1, "%s: remove PTD[%d] $%04x\n", __func__, index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) BUG_ON(ep->num_ptds == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) release_ptd_buffers(epq, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!list_empty(&ep->hep->urb_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct urb *urb = get_urb(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) DBG(1, "%s: Finishing req %d ep %p from remove_list\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ep->num_req, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) finish_request(isp1362_hcd, ep, urb, -ESHUTDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) WARN_ON(list_empty(&ep->active));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!list_empty(&ep->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) list_del_init(&ep->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) DBG(1, "%s: ep %p removed from active list\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) list_del_init(&ep->remove_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) DBG(1, "%s: ep %p removed from remove_list\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) DBG(1, "%s: Done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static inline void enable_atl_transfers(struct isp1362_hcd *isp1362_hcd, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (count < isp1362_hcd->atl_queue.ptd_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) isp1362_write_reg16(isp1362_hcd, HCATLDTC, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) isp1362_enable_int(isp1362_hcd, HCuPINT_ATL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) isp1362_write_reg32(isp1362_hcd, HCATLSKIP, isp1362_hcd->atl_queue.skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) isp1362_enable_int(isp1362_hcd, HCuPINT_SOF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static inline void enable_intl_transfers(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) isp1362_enable_int(isp1362_hcd, HCuPINT_INTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, isp1362_hcd->intl_queue.skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static inline void enable_istl_transfers(struct isp1362_hcd *isp1362_hcd, int flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) isp1362_enable_int(isp1362_hcd, flip ? HCuPINT_ISTL1 : HCuPINT_ISTL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, flip ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) HCBUFSTAT_ISTL1_FULL : HCBUFSTAT_ISTL0_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int submit_req(struct isp1362_hcd *isp1362_hcd, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct isp1362_ep *ep, struct isp1362_ep_queue *epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) prepare_ptd(isp1362_hcd, urb, ep, epq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) index = claim_ptd_buffers(epq, ep, ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (index == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) DBG(1, "%s: req %d No free %s PTD available: %d, %08lx:%08lx\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ep->num_req, epq->name, ep->num_ptds, epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) } else if (index == -EOVERFLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) DBG(1, "%s: req %d Not enough space for %d byte %s PTD %d %08lx:%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) __func__, ep->num_req, ep->length, epq->name, ep->num_ptds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) epq->buf_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) BUG_ON(index < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) list_add_tail(&ep->active, &epq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) DBG(1, "%s: ep %p req %d len %d added to active list %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ep, ep->num_req, ep->length, &epq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) DBG(1, "%s: Submitting %s PTD $%04x for ep %p req %d\n", __func__, epq->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ep->ptd_offset, ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) isp1362_write_ptd(isp1362_hcd, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) __clear_bit(ep->ptd_index, &epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static void start_atl_transfers(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int ptd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct isp1362_ep_queue *epq = &isp1362_hcd->atl_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int defer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (atomic_read(&epq->finishing)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) list_for_each_entry(ep, &isp1362_hcd->async, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct urb *urb = get_urb(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (!list_empty(&ep->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) DBG(2, "%s: Skipping active %s ep %p\n", __func__, epq->name, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) DBG(1, "%s: Processing %s ep %p req %d\n", __func__, epq->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = submit_req(isp1362_hcd, urb, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ret == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) defer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) } else if (ret == -EOVERFLOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) defer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef BUGGY_PXA2XX_UDC_USBTEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) defer = ep->nextpid == USB_PID_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ptd_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* Avoid starving of endpoints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (isp1362_hcd->async.next != isp1362_hcd->async.prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) DBG(2, "%s: Cycling ASYNC schedule %d\n", __func__, ptd_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) list_move(&isp1362_hcd->async, isp1362_hcd->async.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ptd_count || defer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) enable_atl_transfers(isp1362_hcd, defer ? 0 : ptd_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) epq->ptd_count += ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (epq->ptd_count > epq->stat_maxptds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) epq->stat_maxptds = epq->ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) DBG(0, "%s: max_ptds: %d\n", __func__, epq->stat_maxptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static void start_intl_transfers(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int ptd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct isp1362_ep_queue *epq = &isp1362_hcd->intl_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (atomic_read(&epq->finishing)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) list_for_each_entry(ep, &isp1362_hcd->periodic, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct urb *urb = get_urb(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!list_empty(&ep->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) DBG(1, "%s: Skipping active %s ep %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) epq->name, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) DBG(1, "%s: Processing %s ep %p req %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) epq->name, ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = submit_req(isp1362_hcd, urb, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) else if (ret == -EOVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ptd_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (ptd_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int last_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (ptd_count != last_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) DBG(0, "%s: ptd_count: %d\n", __func__, ptd_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) last_count = ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) enable_intl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) epq->ptd_count += ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (epq->ptd_count > epq->stat_maxptds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) epq->stat_maxptds = epq->ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static inline int next_ptd(struct isp1362_ep_queue *epq, struct isp1362_ep *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) u16 ptd_offset = ep->ptd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int num_ptds = (ep->length + PTD_HEADER_SIZE + (epq->blk_size - 1)) / epq->blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) DBG(2, "%s: PTD offset $%04x + %04x => %d * %04x -> $%04x\n", __func__, ptd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ep->length, num_ptds, epq->blk_size, ptd_offset + num_ptds * epq->blk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) ptd_offset += num_ptds * epq->blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (ptd_offset < epq->buf_start + epq->buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return ptd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static void start_iso_transfers(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int ptd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int flip = isp1362_hcd->istl_flip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct isp1362_ep_queue *epq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int ptd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct isp1362_ep *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u16 fno = isp1362_read_reg32(isp1362_hcd, HCFMNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) fill2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) epq = &isp1362_hcd->istl_queue[flip];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (atomic_read(&epq->finishing)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (!list_empty(&epq->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ptd_offset = epq->buf_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) list_for_each_entry_safe(ep, tmp, &isp1362_hcd->isoc, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct urb *urb = get_urb(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) s16 diff = fno - (u16)urb->start_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) DBG(1, "%s: Processing %s ep %p\n", __func__, epq->name, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (diff > urb->number_of_packets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* time frame for this URB has elapsed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) finish_request(isp1362_hcd, ep, urb, -EOVERFLOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) } else if (diff < -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* URB is not due in this frame or the next one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * Comparing with '-1' instead of '0' accounts for double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * buffering in the ISP1362 which enables us to queue the PTD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * one frame ahead of time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) } else if (diff == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* submit PTD's that are due in the next frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) prepare_ptd(isp1362_hcd, urb, ep, epq, fno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (ptd_offset + PTD_HEADER_SIZE + ep->length >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) epq->buf_start + epq->buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) pr_err("%s: Not enough ISO buffer space for %d byte PTD\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) __func__, ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ep->ptd_offset = ptd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) list_add_tail(&ep->active, &epq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ptd_offset = next_ptd(epq, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (ptd_offset < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pr_warn("%s: req %d No more %s PTD buffers available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) __func__, ep->num_req, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) list_for_each_entry(ep, &epq->active, active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (epq->active.next == &ep->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ep->ptd.mps |= PTD_LAST_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) isp1362_write_ptd(isp1362_hcd, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ptd_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (ptd_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) enable_istl_transfers(isp1362_hcd, flip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) epq->ptd_count += ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (epq->ptd_count > epq->stat_maxptds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) epq->stat_maxptds = epq->ptd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* check, whether the second ISTL buffer may also be filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) (flip ? HCBUFSTAT_ISTL0_FULL : HCBUFSTAT_ISTL1_FULL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) fno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ptd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) flip = 1 - flip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) goto fill2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static void finish_transfers(struct isp1362_hcd *isp1362_hcd, unsigned long done_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct isp1362_ep_queue *epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct isp1362_ep *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (list_empty(&epq->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) DBG(1, "%s: Nothing to do for %s queue\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) DBG(1, "%s: Finishing %s transfers %08lx\n", __func__, epq->name, done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) atomic_inc(&epq->finishing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) list_for_each_entry_safe(ep, tmp, &epq->active, active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int index = ep->ptd_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) DBG(1, "%s: Checking %s PTD[%02x] $%04x\n", __func__, epq->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) BUG_ON(index < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (__test_and_clear_bit(index, &done_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) isp1362_read_ptd(isp1362_hcd, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) epq->free_ptd = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) BUG_ON(ep->num_ptds == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) release_ptd_buffers(epq, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) DBG(1, "%s: ep %p req %d removed from active list\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (!list_empty(&ep->remove_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) list_del_init(&ep->remove_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) DBG(1, "%s: ep %p removed from remove list\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) DBG(1, "%s: Postprocessing %s ep %p req %d\n", __func__, epq->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) postproc_ep(isp1362_hcd, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (!done_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (done_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) pr_warn("%s: done_map not clear: %08lx:%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) __func__, done_map, epq->skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) atomic_dec(&epq->finishing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static void finish_iso_transfers(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep_queue *epq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct isp1362_ep *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (list_empty(&epq->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) DBG(1, "%s: Nothing to do for %s queue\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) DBG(1, "%s: Finishing %s transfers\n", __func__, epq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) atomic_inc(&epq->finishing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) list_for_each_entry_safe(ep, tmp, &epq->active, active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) DBG(1, "%s: Checking PTD $%04x\n", __func__, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) isp1362_read_ptd(isp1362_hcd, ep, epq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) DBG(1, "%s: Postprocessing %s ep %p\n", __func__, epq->name, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) postproc_ep(isp1362_hcd, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) WARN_ON(epq->blk_size != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) atomic_dec(&epq->finishing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static irqreturn_t isp1362_irq(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) u16 irqstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) u16 svc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) spin_lock(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) BUG_ON(isp1362_hcd->irq_active++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) irqstat = isp1362_read_reg16(isp1362_hcd, HCuPINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) DBG(3, "%s: got IRQ %04x:%04x\n", __func__, irqstat, isp1362_hcd->irqenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* only handle interrupts that are currently enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) irqstat &= isp1362_hcd->irqenb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) isp1362_write_reg16(isp1362_hcd, HCuPINT, irqstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) svc_mask = irqstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (irqstat & HCuPINT_SOF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) isp1362_hcd->irqenb &= ~HCuPINT_SOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) isp1362_hcd->irq_stat[ISP1362_INT_SOF]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) svc_mask &= ~HCuPINT_SOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) DBG(3, "%s: SOF\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) isp1362_hcd->fmindex = isp1362_read_reg32(isp1362_hcd, HCFMNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!list_empty(&isp1362_hcd->remove_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) finish_unlinks(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!list_empty(&isp1362_hcd->async) && !(irqstat & HCuPINT_ATL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (list_empty(&isp1362_hcd->atl_queue.active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) start_atl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) isp1362_enable_int(isp1362_hcd, HCuPINT_ATL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) isp1362_write_reg32(isp1362_hcd, HCATLSKIP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) isp1362_hcd->atl_queue.skip_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (irqstat & HCuPINT_ISTL0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) isp1362_hcd->irq_stat[ISP1362_INT_ISTL0]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) svc_mask &= ~HCuPINT_ISTL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ISTL0_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) DBG(1, "%s: ISTL0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) WARN_ON((int)!!isp1362_hcd->istl_flip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) WARN_ON(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) HCBUFSTAT_ISTL0_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) WARN_ON(!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) HCBUFSTAT_ISTL0_DONE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) isp1362_hcd->irqenb &= ~HCuPINT_ISTL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (irqstat & HCuPINT_ISTL1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) isp1362_hcd->irq_stat[ISP1362_INT_ISTL1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) svc_mask &= ~HCuPINT_ISTL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ISTL1_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) DBG(1, "%s: ISTL1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) WARN_ON(!(int)isp1362_hcd->istl_flip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) WARN_ON(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) HCBUFSTAT_ISTL1_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) WARN_ON(!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) HCBUFSTAT_ISTL1_DONE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) isp1362_hcd->irqenb &= ~HCuPINT_ISTL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (irqstat & (HCuPINT_ISTL0 | HCuPINT_ISTL1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) WARN_ON((irqstat & (HCuPINT_ISTL0 | HCuPINT_ISTL1)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) (HCuPINT_ISTL0 | HCuPINT_ISTL1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) finish_iso_transfers(isp1362_hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) &isp1362_hcd->istl_queue[isp1362_hcd->istl_flip]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) start_iso_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) isp1362_hcd->istl_flip = 1 - isp1362_hcd->istl_flip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (irqstat & HCuPINT_INTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) u32 done_map = isp1362_read_reg32(isp1362_hcd, HCINTLDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) u32 skip_map = isp1362_read_reg32(isp1362_hcd, HCINTLSKIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) isp1362_hcd->irq_stat[ISP1362_INT_INTL]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) DBG(2, "%s: INTL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) svc_mask &= ~HCuPINT_INTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, skip_map | done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (~(done_map | skip_map) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* All PTDs are finished, disable INTL processing entirely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) WARN_ON(!done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (done_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) DBG(3, "%s: INTL done_map %08x\n", __func__, done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->intl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) start_intl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (irqstat & HCuPINT_ATL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) u32 done_map = isp1362_read_reg32(isp1362_hcd, HCATLDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) u32 skip_map = isp1362_read_reg32(isp1362_hcd, HCATLSKIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) isp1362_hcd->irq_stat[ISP1362_INT_ATL]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) DBG(2, "%s: ATL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) svc_mask &= ~HCuPINT_ATL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) isp1362_write_reg32(isp1362_hcd, HCATLSKIP, skip_map | done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (~(done_map | skip_map) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (done_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) DBG(3, "%s: ATL done_map %08x\n", __func__, done_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->atl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) start_atl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (irqstat & HCuPINT_OPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) u32 intstat = isp1362_read_reg32(isp1362_hcd, HCINTSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) isp1362_hcd->irq_stat[ISP1362_INT_OPR]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) svc_mask &= ~HCuPINT_OPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) DBG(2, "%s: OPR %08x:%08x\n", __func__, intstat, isp1362_hcd->intenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) intstat &= isp1362_hcd->intenb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (intstat & OHCI_INTR_UE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) pr_err("Unrecoverable error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* FIXME: do here reset or cleanup or whatever */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (intstat & OHCI_INTR_RHSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) isp1362_hcd->rhstatus = isp1362_read_reg32(isp1362_hcd, HCRHSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) isp1362_hcd->rhport[0] = isp1362_read_reg32(isp1362_hcd, HCRHPORT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) isp1362_hcd->rhport[1] = isp1362_read_reg32(isp1362_hcd, HCRHPORT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (intstat & OHCI_INTR_RD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pr_info("%s: RESUME DETECTED\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) isp1362_show_reg(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) usb_hcd_resume_root_hub(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) isp1362_write_reg32(isp1362_hcd, HCINTSTAT, intstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) irqstat &= ~HCuPINT_OPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (irqstat & HCuPINT_SUSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) isp1362_hcd->irq_stat[ISP1362_INT_SUSP]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) svc_mask &= ~HCuPINT_SUSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) pr_info("%s: SUSPEND IRQ\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (irqstat & HCuPINT_CLKRDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) isp1362_hcd->irq_stat[ISP1362_INT_CLKRDY]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) isp1362_hcd->irqenb &= ~HCuPINT_CLKRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) svc_mask &= ~HCuPINT_CLKRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) pr_info("%s: CLKRDY IRQ\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (svc_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) pr_err("%s: Unserviced interrupt(s) %04x\n", __func__, svc_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) isp1362_hcd->irq_active--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) spin_unlock(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) #define MAX_PERIODIC_LOAD 900 /* out of 1000 usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static int balance(struct isp1362_hcd *isp1362_hcd, u16 interval, u16 load)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) int i, branch = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* search for the least loaded schedule branch of that interval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * which has enough bandwidth left unreserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) for (i = 0; i < interval; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (branch < 0 || isp1362_hcd->load[branch] > isp1362_hcd->load[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) for (j = i; j < PERIODIC_SIZE; j += interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if ((isp1362_hcd->load[j] + load) > MAX_PERIODIC_LOAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) pr_err("%s: new load %d load[%02x] %d max %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) load, j, isp1362_hcd->load[j], MAX_PERIODIC_LOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (j < PERIODIC_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) branch = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* NB! ALL the code above this point runs with isp1362_hcd->lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) held, irqs off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int isp1362_urb_enqueue(struct usb_hcd *hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) gfp_t mem_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct usb_device *udev = urb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) unsigned int pipe = urb->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int is_out = !usb_pipein(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int type = usb_pipetype(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int epnum = usb_pipeendpoint(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct usb_host_endpoint *hep = urb->ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct isp1362_ep *ep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) DBG(3, "%s: urb %p\n", __func__, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (type == PIPE_ISOCHRONOUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) pr_err("Isochronous transfers not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) URB_DBG("%s: FA %d ep%d%s %s: len %d %s%s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) usb_pipedevice(pipe), epnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) is_out ? "out" : "in",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) usb_pipecontrol(pipe) ? "ctrl" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) usb_pipeint(pipe) ? "int" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) usb_pipebulk(pipe) ? "bulk" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) "iso",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) urb->transfer_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) (urb->transfer_flags & URB_ZERO_PACKET) ? "ZERO_PACKET " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) !(urb->transfer_flags & URB_SHORT_NOT_OK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) "short_ok" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) /* avoid all allocations within spinlocks: request or endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (!hep->hcpriv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ep = kzalloc(sizeof *ep, mem_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /* don't submit to a dead or disabled port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (!((isp1362_hcd->rhport[0] | isp1362_hcd->rhport[1]) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) USB_PORT_STAT_ENABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) !HC_IS_RUNNING(hcd->state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) goto fail_not_linked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) retval = usb_hcd_link_urb_to_ep(hcd, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) goto fail_not_linked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (hep->hcpriv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ep = hep->hcpriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) INIT_LIST_HEAD(&ep->schedule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) INIT_LIST_HEAD(&ep->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) INIT_LIST_HEAD(&ep->remove_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ep->udev = usb_get_dev(udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) ep->hep = hep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ep->epnum = epnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) ep->ptd_offset = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ep->ptd_index = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) usb_settoggle(udev, epnum, is_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (type == PIPE_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ep->nextpid = USB_PID_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) else if (is_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ep->nextpid = USB_PID_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ep->nextpid = USB_PID_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case PIPE_ISOCHRONOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) case PIPE_INTERRUPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (urb->interval > PERIODIC_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) urb->interval = PERIODIC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ep->interval = urb->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) ep->branch = PERIODIC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ep->load = usb_calc_bus_time(udev->speed, !is_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) (type == PIPE_ISOCHRONOUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) usb_maxpacket(udev, pipe, is_out)) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) hep->hcpriv = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ep->num_req = isp1362_hcd->req_serial++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* maybe put endpoint into schedule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) case PIPE_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) case PIPE_BULK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (list_empty(&ep->schedule)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) DBG(1, "%s: Adding ep %p req %d to async schedule\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) __func__, ep, ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) list_add_tail(&ep->schedule, &isp1362_hcd->async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) case PIPE_ISOCHRONOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) case PIPE_INTERRUPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) urb->interval = ep->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* urb submitted for already existing EP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (ep->branch < PERIODIC_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) retval = balance(isp1362_hcd, ep->interval, ep->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) pr_err("%s: balance returned %d\n", __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ep->branch = retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) isp1362_hcd->fmindex = isp1362_read_reg32(isp1362_hcd, HCFMNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) DBG(1, "%s: Current frame %04x branch %02x start_frame %04x(%04x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) __func__, isp1362_hcd->fmindex, ep->branch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) ((isp1362_hcd->fmindex + PERIODIC_SIZE - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) ~(PERIODIC_SIZE - 1)) + ep->branch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) (isp1362_hcd->fmindex & (PERIODIC_SIZE - 1)) + ep->branch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (list_empty(&ep->schedule)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (type == PIPE_ISOCHRONOUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) u16 frame = isp1362_hcd->fmindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) frame += max_t(u16, 8, ep->interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) frame &= ~(ep->interval - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) frame |= ep->branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (frame_before(frame, isp1362_hcd->fmindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) frame += ep->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) urb->start_frame = frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) DBG(1, "%s: Adding ep %p to isoc schedule\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) list_add_tail(&ep->schedule, &isp1362_hcd->isoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) DBG(1, "%s: Adding ep %p to periodic schedule\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) list_add_tail(&ep->schedule, &isp1362_hcd->periodic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) DBG(1, "%s: ep %p already scheduled\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) DBG(2, "%s: load %d bandwidth %d -> %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ep->load / ep->interval, isp1362_hcd->load[ep->branch],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) isp1362_hcd->load[ep->branch] + ep->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) isp1362_hcd->load[ep->branch] += ep->load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) urb->hcpriv = hep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ALIGNSTAT(isp1362_hcd, urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case PIPE_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) case PIPE_BULK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) start_atl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) case PIPE_INTERRUPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) start_intl_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) case PIPE_ISOCHRONOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) start_iso_transfers(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) usb_hcd_unlink_urb_from_ep(hcd, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) fail_not_linked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) DBG(0, "%s: urb %p failed with %d\n", __func__, urb, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static int isp1362_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) struct usb_host_endpoint *hep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) DBG(3, "%s: urb %p\n", __func__, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) retval = usb_hcd_check_unlink_urb(hcd, urb, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) hep = urb->hcpriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (!hep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return -EIDRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ep = hep->hcpriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* In front of queue? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (ep->hep->urb_list.next == &urb->urb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (!list_empty(&ep->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) DBG(1, "%s: urb %p ep %p req %d active PTD[%d] $%04x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) urb, ep, ep->num_req, ep->ptd_index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) /* disable processing and queue PTD for removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) remove_ptd(isp1362_hcd, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) DBG(1, "%s: Finishing ep %p req %d\n", __func__, ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) ep->num_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) finish_request(isp1362_hcd, ep, urb, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) DBG(1, "%s: urb %p active; wait4irq\n", __func__, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) pr_warn("%s: No EP in URB %p\n", __func__, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) DBG(3, "%s: exit\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static void isp1362_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) struct isp1362_ep *ep = hep->hcpriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) DBG(1, "%s: ep %p\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (!list_empty(&hep->urb_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (!list_empty(&ep->active) && list_empty(&ep->remove_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) DBG(1, "%s: Removing ep %p req %d PTD[%d] $%04x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) ep, ep->num_req, ep->ptd_index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) remove_ptd(isp1362_hcd, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pr_info("%s: Waiting for Interrupt to clean up\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* Wait for interrupt to clear out active list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) while (!list_empty(&ep->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) DBG(1, "%s: Freeing EP %p\n", __func__, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) usb_put_dev(ep->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) hep->hcpriv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static int isp1362_get_frame(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) u32 fmnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) fmnum = isp1362_read_reg32(isp1362_hcd, HCFMNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return (int)fmnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /* Adapted from ohci-hub.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static int isp1362_hub_status_data(struct usb_hcd *hcd, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) int ports, i, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (!HC_IS_RUNNING(hcd->state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return -ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) /* Report no status change now, if we are scheduled to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) called later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (timer_pending(&hcd->rh_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) ports = isp1362_hcd->rhdesca & RH_A_NDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) BUG_ON(ports > 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) /* init status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (isp1362_hcd->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) buf[0] = changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) for (i = 0; i < ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) u32 status = isp1362_hcd->rhport[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) RH_PS_OCIC | RH_PS_PRSC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) buf[0] |= 1 << (i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (!(status & RH_PS_CCS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct usb_hub_descriptor *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) u32 reg = isp1362_hcd->rhdesca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) DBG(3, "%s: enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) desc->bDescriptorType = USB_DT_HUB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) desc->bDescLength = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) desc->bHubContrCurrent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) desc->bNbrPorts = reg & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* Power switching, device type, overcurrent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) desc->wHubCharacteristics = cpu_to_le16((reg >> 8) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) (HUB_CHAR_LPSM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) HUB_CHAR_COMPOUND |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) HUB_CHAR_OCPM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) DBG(0, "%s: hubcharacteristics = %02x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) desc->wHubCharacteristics);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) desc->bPwrOn2PwrGood = (reg >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /* ports removable, and legacy PortPwrCtrlMask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) desc->u.hs.DeviceRemovable[1] = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) DBG(3, "%s: exit\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /* Adapted from ohci-hub.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static int isp1362_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) u16 wIndex, char *buf, u16 wLength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) unsigned long t1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) int ports = isp1362_hcd->rhdesca & RH_A_NDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) switch (typeReq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) case ClearHubFeature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) DBG(0, "ClearHubFeature: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) switch (wValue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) case C_HUB_OVER_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) DBG(0, "C_HUB_OVER_CURRENT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_OCIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) case C_HUB_LOCAL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) DBG(0, "C_HUB_LOCAL_POWER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) case SetHubFeature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) DBG(0, "SetHubFeature: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) switch (wValue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) case C_HUB_OVER_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) case C_HUB_LOCAL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) DBG(0, "C_HUB_OVER_CURRENT or C_HUB_LOCAL_POWER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) case GetHubDescriptor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) DBG(0, "GetHubDescriptor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) isp1362_hub_descriptor(isp1362_hcd, (struct usb_hub_descriptor *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) case GetHubStatus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) DBG(0, "GetHubStatus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) put_unaligned(cpu_to_le32(0), (__le32 *) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) case GetPortStatus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) #ifndef VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) DBG(0, "GetPortStatus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (!wIndex || wIndex > ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) tmp = isp1362_hcd->rhport[--wIndex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) put_unaligned(cpu_to_le32(tmp), (__le32 *) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) case ClearPortFeature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) DBG(0, "ClearPortFeature: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (!wIndex || wIndex > ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) wIndex--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) switch (wValue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) case USB_PORT_FEAT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) DBG(0, "USB_PORT_FEAT_ENABLE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) tmp = RH_PS_CCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) case USB_PORT_FEAT_C_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) DBG(0, "USB_PORT_FEAT_C_ENABLE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) tmp = RH_PS_PESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) case USB_PORT_FEAT_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) DBG(0, "USB_PORT_FEAT_SUSPEND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) tmp = RH_PS_POCI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) case USB_PORT_FEAT_C_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) DBG(0, "USB_PORT_FEAT_C_SUSPEND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) tmp = RH_PS_PSSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) case USB_PORT_FEAT_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) DBG(0, "USB_PORT_FEAT_POWER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) tmp = RH_PS_LSDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) case USB_PORT_FEAT_C_CONNECTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) DBG(0, "USB_PORT_FEAT_C_CONNECTION\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) tmp = RH_PS_CSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) case USB_PORT_FEAT_C_OVER_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) DBG(0, "USB_PORT_FEAT_C_OVER_CURRENT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) tmp = RH_PS_OCIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) case USB_PORT_FEAT_C_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) DBG(0, "USB_PORT_FEAT_C_RESET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) tmp = RH_PS_PRSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) isp1362_hcd->rhport[wIndex] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) case SetPortFeature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) DBG(0, "SetPortFeature: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (!wIndex || wIndex > ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) wIndex--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) switch (wValue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) case USB_PORT_FEAT_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) DBG(0, "USB_PORT_FEAT_SUSPEND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) isp1362_hcd->rhport[wIndex] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) case USB_PORT_FEAT_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) DBG(0, "USB_PORT_FEAT_POWER\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) isp1362_hcd->rhport[wIndex] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) case USB_PORT_FEAT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) DBG(0, "USB_PORT_FEAT_RESET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) t1 = jiffies + msecs_to_jiffies(USB_RESET_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) while (time_before(jiffies, t1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) /* spin until any current reset finishes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) tmp = isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (!(tmp & RH_PS_PRS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) udelay(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (!(tmp & RH_PS_CCS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) /* Reset lasts 10ms (claims datasheet) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, (RH_PS_PRS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) isp1362_hcd->rhport[wIndex] = isp1362_read_reg32(isp1362_hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) HCRHPORT1 + wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /* "protocol stall" on error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) DBG(0, "PROTOCOL STALL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) retval = -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) static int isp1362_bus_suspend(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (time_before(jiffies, isp1362_hcd->next_statechange))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) msleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) switch (isp1362_hcd->hc_control & OHCI_CTRL_HCFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) case OHCI_USB_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) DBG(0, "%s: resume/suspend?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) isp1362_hcd->hc_control &= ~OHCI_CTRL_HCFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) isp1362_hcd->hc_control |= OHCI_USB_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) case OHCI_USB_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) status = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) pr_warn("%s: needs reinit!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) case OHCI_USB_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) pr_warn("%s: already suspended?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) DBG(0, "%s: suspend root hub\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) /* First stop any processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) hcd->state = HC_STATE_QUIESCING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (!list_empty(&isp1362_hcd->atl_queue.active) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) !list_empty(&isp1362_hcd->intl_queue.active) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) !list_empty(&isp1362_hcd->istl_queue[0] .active) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) !list_empty(&isp1362_hcd->istl_queue[1] .active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) int limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) isp1362_write_reg32(isp1362_hcd, HCATLSKIP, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) isp1362_write_reg16(isp1362_hcd, HCBUFSTAT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) isp1362_write_reg32(isp1362_hcd, HCINTSTAT, OHCI_INTR_SF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) DBG(0, "%s: stopping schedules ...\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) limit = 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) while (limit > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) udelay(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) limit -= 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (isp1362_read_reg32(isp1362_hcd, HCINTSTAT) & OHCI_INTR_SF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) mdelay(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ATL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) u32 done_map = isp1362_read_reg32(isp1362_hcd, HCATLDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->atl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_INTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) u32 done_map = isp1362_read_reg32(isp1362_hcd, HCINTLDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->intl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ISTL0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) finish_iso_transfers(isp1362_hcd, &isp1362_hcd->istl_queue[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ISTL1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) finish_iso_transfers(isp1362_hcd, &isp1362_hcd->istl_queue[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) DBG(0, "%s: HCINTSTAT: %08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) isp1362_read_reg32(isp1362_hcd, HCINTSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) isp1362_write_reg32(isp1362_hcd, HCINTSTAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) isp1362_read_reg32(isp1362_hcd, HCINTSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) /* Suspend hub */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) isp1362_hcd->hc_control = OHCI_USB_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) isp1362_show_reg(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) isp1362_show_reg(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if ((isp1362_hcd->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_SUSPEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) pr_err("%s: controller won't suspend %08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) status = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /* no resumes until devices finish suspending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) isp1362_hcd->next_statechange = jiffies + msecs_to_jiffies(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) hcd->state = HC_STATE_SUSPENDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) DBG(0, "%s: HCD suspended: %08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) isp1362_read_reg32(isp1362_hcd, HCCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static int isp1362_bus_resume(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) u32 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) int status = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (time_before(jiffies, isp1362_hcd->next_statechange))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) msleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) pr_info("%s: HCCONTROL: %08x\n", __func__, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) if (hcd->state == HC_STATE_RESUMING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) pr_warn("%s: duplicate resume\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) switch (isp1362_hcd->hc_control & OHCI_CTRL_HCFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) case OHCI_USB_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) DBG(0, "%s: resume root hub\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) isp1362_hcd->hc_control &= ~OHCI_CTRL_HCFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) isp1362_hcd->hc_control |= OHCI_USB_RESUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) case OHCI_USB_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) /* HCFS changes sometime after INTR_RD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) DBG(0, "%s: remote wakeup\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) case OHCI_USB_OPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) DBG(0, "%s: odd resume\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) hcd->self.root_hub->dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) default: /* RESET, we lost power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) DBG(0, "%s: root hub hardware reset\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) status = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (status == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) DBG(0, "%s: Restarting HC\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) isp1362_hc_stop(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return isp1362_hc_start(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (status != -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) port = isp1362_read_reg32(isp1362_hcd, HCRHDESCA) & RH_A_NDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) while (port--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) u32 stat = isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) /* force global, not selective, resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (!(stat & RH_PS_PSS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) DBG(0, "%s: Not Resuming RH port %d\n", __func__, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) DBG(0, "%s: Resuming RH port %d\n", __func__, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + port, RH_PS_POCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /* Some controllers (lucent) need extra-long delays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) hcd->state = HC_STATE_RESUMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) mdelay(20 /* usb 11.5.1.10 */ + 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) isp1362_hcd->hc_control = OHCI_USB_OPER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) isp1362_show_reg(isp1362_hcd, HCCONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* TRSMRCY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /* keep it alive for ~5x suspend + resume costs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) isp1362_hcd->next_statechange = jiffies + msecs_to_jiffies(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) hcd->self.root_hub->dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) hcd->state = HC_STATE_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) #define isp1362_bus_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) #define isp1362_bus_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) static void dump_irq(struct seq_file *s, char *label, u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) seq_printf(s, "%-15s %04x%s%s%s%s%s%s\n", label, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) mask & HCuPINT_CLKRDY ? " clkrdy" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) mask & HCuPINT_SUSP ? " susp" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) mask & HCuPINT_OPR ? " opr" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) mask & HCuPINT_EOT ? " eot" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) mask & HCuPINT_ATL ? " atl" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) mask & HCuPINT_SOF ? " sof" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) static void dump_int(struct seq_file *s, char *label, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) seq_printf(s, "%-15s %08x%s%s%s%s%s%s%s\n", label, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) mask & OHCI_INTR_MIE ? " MIE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) mask & OHCI_INTR_RHSC ? " rhsc" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) mask & OHCI_INTR_FNO ? " fno" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) mask & OHCI_INTR_UE ? " ue" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) mask & OHCI_INTR_RD ? " rd" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) mask & OHCI_INTR_SF ? " sof" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) mask & OHCI_INTR_SO ? " so" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) static void dump_ctrl(struct seq_file *s, char *label, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) seq_printf(s, "%-15s %08x%s%s%s\n", label, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) mask & OHCI_CTRL_RWC ? " rwc" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) mask & OHCI_CTRL_RWE ? " rwe" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) char *hcfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) switch (mask & OHCI_CTRL_HCFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) case OHCI_USB_OPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) hcfs = " oper";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) case OHCI_USB_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) hcfs = " reset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) case OHCI_USB_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) hcfs = " resume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) case OHCI_USB_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) hcfs = " suspend";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) hcfs = " ?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) hcfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) static void dump_regs(struct seq_file *s, struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) seq_printf(s, "HCREVISION [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCREVISION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) isp1362_read_reg32(isp1362_hcd, HCREVISION));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) seq_printf(s, "HCCONTROL [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCCONTROL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) isp1362_read_reg32(isp1362_hcd, HCCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) seq_printf(s, "HCCMDSTAT [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCCMDSTAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) isp1362_read_reg32(isp1362_hcd, HCCMDSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) seq_printf(s, "HCINTSTAT [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTSTAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) isp1362_read_reg32(isp1362_hcd, HCINTSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) seq_printf(s, "HCINTENB [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTENB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) isp1362_read_reg32(isp1362_hcd, HCINTENB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) seq_printf(s, "HCFMINTVL [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMINTVL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) isp1362_read_reg32(isp1362_hcd, HCFMINTVL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) seq_printf(s, "HCFMREM [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMREM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) isp1362_read_reg32(isp1362_hcd, HCFMREM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) seq_printf(s, "HCFMNUM [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMNUM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) isp1362_read_reg32(isp1362_hcd, HCFMNUM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) seq_printf(s, "HCLSTHRESH [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCLSTHRESH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) isp1362_read_reg32(isp1362_hcd, HCLSTHRESH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) seq_printf(s, "HCRHDESCA [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHDESCA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) isp1362_read_reg32(isp1362_hcd, HCRHDESCA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) seq_printf(s, "HCRHDESCB [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHDESCB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) isp1362_read_reg32(isp1362_hcd, HCRHDESCB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) seq_printf(s, "HCRHSTATUS [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHSTATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) isp1362_read_reg32(isp1362_hcd, HCRHSTATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) seq_printf(s, "HCRHPORT1 [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHPORT1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) isp1362_read_reg32(isp1362_hcd, HCRHPORT1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) seq_printf(s, "HCRHPORT2 [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHPORT2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) isp1362_read_reg32(isp1362_hcd, HCRHPORT2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) seq_printf(s, "HCHWCFG [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCHWCFG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) isp1362_read_reg16(isp1362_hcd, HCHWCFG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) seq_printf(s, "HCDMACFG [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCDMACFG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) isp1362_read_reg16(isp1362_hcd, HCDMACFG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) seq_printf(s, "HCXFERCTR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCXFERCTR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) isp1362_read_reg16(isp1362_hcd, HCXFERCTR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) seq_printf(s, "HCuPINT [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCuPINT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) isp1362_read_reg16(isp1362_hcd, HCuPINT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) seq_printf(s, "HCuPINTENB [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCuPINTENB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) isp1362_read_reg16(isp1362_hcd, HCuPINTENB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) seq_printf(s, "HCCHIPID [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCCHIPID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) isp1362_read_reg16(isp1362_hcd, HCCHIPID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) seq_printf(s, "HCSCRATCH [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCSCRATCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) isp1362_read_reg16(isp1362_hcd, HCSCRATCH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) seq_printf(s, "HCBUFSTAT [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCBUFSTAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) isp1362_read_reg16(isp1362_hcd, HCBUFSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) seq_printf(s, "HCDIRADDR [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCDIRADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) isp1362_read_reg32(isp1362_hcd, HCDIRADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) seq_printf(s, "HCDIRDATA [%02x] %04x\n", ISP1362_REG_NO(HCDIRDATA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) isp1362_read_reg16(isp1362_hcd, HCDIRDATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) seq_printf(s, "HCISTLBUFSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCISTLBUFSZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) isp1362_read_reg16(isp1362_hcd, HCISTLBUFSZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) seq_printf(s, "HCISTLRATE [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCISTLRATE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) isp1362_read_reg16(isp1362_hcd, HCISTLRATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) seq_printf(s, "HCINTLBUFSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLBUFSZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) isp1362_read_reg16(isp1362_hcd, HCINTLBUFSZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) seq_printf(s, "HCINTLBLKSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLBLKSZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) isp1362_read_reg16(isp1362_hcd, HCINTLBLKSZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) seq_printf(s, "HCINTLDONE [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLDONE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) isp1362_read_reg32(isp1362_hcd, HCINTLDONE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) seq_printf(s, "HCINTLSKIP [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLSKIP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) isp1362_read_reg32(isp1362_hcd, HCINTLSKIP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) seq_printf(s, "HCINTLLAST [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLLAST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) isp1362_read_reg32(isp1362_hcd, HCINTLLAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) seq_printf(s, "HCINTLCURR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLCURR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) isp1362_read_reg16(isp1362_hcd, HCINTLCURR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) seq_printf(s, "HCATLBUFSZ [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLBUFSZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) isp1362_read_reg16(isp1362_hcd, HCATLBUFSZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) seq_printf(s, "HCATLBLKSZ [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLBLKSZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) isp1362_read_reg16(isp1362_hcd, HCATLBLKSZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) seq_printf(s, "HCATLDONE [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDONE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) isp1362_read_reg32(isp1362_hcd, HCATLDONE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) seq_printf(s, "HCATLSKIP [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLSKIP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) isp1362_read_reg32(isp1362_hcd, HCATLSKIP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) seq_printf(s, "HCATLLAST [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLLAST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) isp1362_read_reg32(isp1362_hcd, HCATLLAST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) seq_printf(s, "HCATLCURR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLCURR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) isp1362_read_reg16(isp1362_hcd, HCATLCURR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) seq_printf(s, "HCATLDTC [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDTC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) isp1362_read_reg16(isp1362_hcd, HCATLDTC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) seq_printf(s, "HCATLDTCTO [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDTCTO),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) isp1362_read_reg16(isp1362_hcd, HCATLDTCTO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int isp1362_show(struct seq_file *s, void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) struct isp1362_hcd *isp1362_hcd = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) struct isp1362_ep *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) seq_printf(s, "%s\n%s version %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) isp1362_hcd_to_hcd(isp1362_hcd)->product_desc, hcd_name, DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /* collect statistics to help estimate potential win for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) * DMA engines that care about alignment (PXA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) seq_printf(s, "alignment: 16b/%ld 8b/%ld 4b/%ld 2b/%ld 1b/%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) isp1362_hcd->stat16, isp1362_hcd->stat8, isp1362_hcd->stat4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) isp1362_hcd->stat2, isp1362_hcd->stat1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) seq_printf(s, "max # ptds in ATL fifo: %d\n", isp1362_hcd->atl_queue.stat_maxptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) seq_printf(s, "max # ptds in INTL fifo: %d\n", isp1362_hcd->intl_queue.stat_maxptds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) seq_printf(s, "max # ptds in ISTL fifo: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) max(isp1362_hcd->istl_queue[0] .stat_maxptds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) isp1362_hcd->istl_queue[1] .stat_maxptds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) /* FIXME: don't show the following in suspended state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) spin_lock_irq(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) dump_irq(s, "hc_irq_enable", isp1362_read_reg16(isp1362_hcd, HCuPINTENB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) dump_irq(s, "hc_irq_status", isp1362_read_reg16(isp1362_hcd, HCuPINT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) dump_int(s, "ohci_int_enable", isp1362_read_reg32(isp1362_hcd, HCINTENB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) dump_int(s, "ohci_int_status", isp1362_read_reg32(isp1362_hcd, HCINTSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) dump_ctrl(s, "ohci_control", isp1362_read_reg32(isp1362_hcd, HCCONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) for (i = 0; i < NUM_ISP1362_IRQS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) if (isp1362_hcd->irq_stat[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) seq_printf(s, "%-15s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) ISP1362_INT_NAME(i), isp1362_hcd->irq_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) dump_regs(s, isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) list_for_each_entry(ep, &isp1362_hcd->async, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, ep->epnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) switch (ep->nextpid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) case USB_PID_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) s = "in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) case USB_PID_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) s = "out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) case USB_PID_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) s = "setup";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) case USB_PID_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) s = "status";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) s = "?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) s;}), ep->maxpacket) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) seq_printf(s, " urb%p, %d/%d\n", urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) urb->actual_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) urb->transfer_buffer_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (!list_empty(&isp1362_hcd->async))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) dump_ptd_queue(&isp1362_hcd->atl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) list_for_each_entry(ep, &isp1362_hcd->periodic, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) seq_printf(s, "branch:%2d load:%3d PTD[%d] $%04x:\n", ep->branch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) isp1362_hcd->load[ep->branch], ep->ptd_index, ep->ptd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) ep->interval, ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) (ep->udev->speed == USB_SPEED_FULL) ? "" : "ls ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) ep->udev->devnum, ep->epnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) (ep->epnum == 0) ? "" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) ((ep->nextpid == USB_PID_IN) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) "in" : "out"), ep->maxpacket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) dump_ptd_queue(&isp1362_hcd->intl_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) seq_printf(s, "ISO:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) list_for_each_entry(ep, &isp1362_hcd->isoc, schedule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) ep->interval, ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) (ep->udev->speed == USB_SPEED_FULL) ? "" : "ls ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) ep->udev->devnum, ep->epnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) (ep->epnum == 0) ? "" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) ((ep->nextpid == USB_PID_IN) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) "in" : "out"), ep->maxpacket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) spin_unlock_irq(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) seq_printf(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) DEFINE_SHOW_ATTRIBUTE(isp1362);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) /* expect just one isp1362_hcd per system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) static void create_debug_file(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) isp1362_hcd->debug_file = debugfs_create_file("isp1362", S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) usb_debug_root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) isp1362_hcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) &isp1362_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) static void remove_debug_file(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) debugfs_remove(isp1362_hcd->debug_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) int tmp = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) isp1362_write_reg16(isp1362_hcd, HCSWRES, HCSWRES_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) isp1362_write_reg32(isp1362_hcd, HCCMDSTAT, OHCI_HCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) while (--tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if (!(isp1362_read_reg32(isp1362_hcd, HCCMDSTAT) & OHCI_HCR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) pr_err("Software reset timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) __isp1362_sw_reset(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) static int isp1362_mem_config(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) u32 total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) u16 istl_size = ISP1362_ISTL_BUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) u16 intl_blksize = ISP1362_INTL_BLKSIZE + PTD_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) u16 intl_size = ISP1362_INTL_BUFFERS * intl_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) u16 atl_blksize = ISP1362_ATL_BLKSIZE + PTD_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) u16 atl_buffers = (ISP1362_BUF_SIZE - (istl_size + intl_size)) / atl_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) u16 atl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) WARN_ON(istl_size & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) WARN_ON(atl_blksize & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) WARN_ON(intl_blksize & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) WARN_ON(atl_blksize < PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) WARN_ON(intl_blksize < PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) BUG_ON((unsigned)ISP1362_INTL_BUFFERS > 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (atl_buffers > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) atl_buffers = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) atl_size = atl_buffers * atl_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) total = atl_size + intl_size + istl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) istl_size / 2, istl_size, 0, istl_size / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) dev_info(hcd->self.controller, " INTL: %4d * (%3zu+8): %4d @ $%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) intl_size, istl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) dev_info(hcd->self.controller, " ATL : %4d * (%3zu+8): %4d @ $%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) atl_buffers, atl_blksize - PTD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) atl_size, istl_size + intl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) ISP1362_BUF_SIZE - total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (total > ISP1362_BUF_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) dev_err(hcd->self.controller, "%s: Memory requested: %d, available %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) __func__, total, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) isp1362_hcd->istl_queue[i].buf_start = i * istl_size / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) isp1362_hcd->istl_queue[i].buf_size = istl_size / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) isp1362_hcd->istl_queue[i].blk_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) INIT_LIST_HEAD(&isp1362_hcd->istl_queue[i].active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) snprintf(isp1362_hcd->istl_queue[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) sizeof(isp1362_hcd->istl_queue[i].name), "ISTL%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) DBG(3, "%s: %5s buf $%04x %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) isp1362_hcd->istl_queue[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) isp1362_hcd->istl_queue[i].buf_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) isp1362_hcd->istl_queue[i].buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) isp1362_write_reg16(isp1362_hcd, HCISTLBUFSZ, istl_size / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) isp1362_hcd->intl_queue.buf_start = istl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) isp1362_hcd->intl_queue.buf_size = intl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) isp1362_hcd->intl_queue.buf_count = ISP1362_INTL_BUFFERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) isp1362_hcd->intl_queue.blk_size = intl_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) isp1362_hcd->intl_queue.buf_avail = isp1362_hcd->intl_queue.buf_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) isp1362_hcd->intl_queue.skip_map = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) INIT_LIST_HEAD(&isp1362_hcd->intl_queue.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) isp1362_write_reg16(isp1362_hcd, HCINTLBUFSZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) isp1362_hcd->intl_queue.buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) isp1362_write_reg16(isp1362_hcd, HCINTLBLKSZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) isp1362_hcd->intl_queue.blk_size - PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) isp1362_write_reg32(isp1362_hcd, HCINTLLAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 1 << (ISP1362_INTL_BUFFERS - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) isp1362_hcd->atl_queue.buf_start = istl_size + intl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) isp1362_hcd->atl_queue.buf_size = atl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) isp1362_hcd->atl_queue.buf_count = atl_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) isp1362_hcd->atl_queue.blk_size = atl_blksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) isp1362_hcd->atl_queue.buf_avail = isp1362_hcd->atl_queue.buf_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) isp1362_hcd->atl_queue.skip_map = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) INIT_LIST_HEAD(&isp1362_hcd->atl_queue.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) isp1362_write_reg16(isp1362_hcd, HCATLBUFSZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) isp1362_hcd->atl_queue.buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) isp1362_write_reg16(isp1362_hcd, HCATLBLKSZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) isp1362_hcd->atl_queue.blk_size - PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) isp1362_write_reg32(isp1362_hcd, HCATLSKIP, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) isp1362_write_reg32(isp1362_hcd, HCATLLAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 1 << (atl_buffers - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) snprintf(isp1362_hcd->atl_queue.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) sizeof(isp1362_hcd->atl_queue.name), "ATL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) snprintf(isp1362_hcd->intl_queue.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) sizeof(isp1362_hcd->intl_queue.name), "INTL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) DBG(3, "%s: %5s buf $%04x %2d * %4d = %4d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) isp1362_hcd->intl_queue.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) isp1362_hcd->intl_queue.buf_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) ISP1362_INTL_BUFFERS, isp1362_hcd->intl_queue.blk_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) isp1362_hcd->intl_queue.buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) DBG(3, "%s: %5s buf $%04x %2d * %4d = %4d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) isp1362_hcd->atl_queue.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) isp1362_hcd->atl_queue.buf_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) atl_buffers, isp1362_hcd->atl_queue.blk_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) isp1362_hcd->atl_queue.buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) static int isp1362_hc_reset(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) unsigned long timeout = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) int clkrdy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) if (isp1362_hcd->board && isp1362_hcd->board->reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) isp1362_hcd->board->reset(hcd->self.controller, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) if (isp1362_hcd->board->clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) isp1362_hcd->board->clock(hcd->self.controller, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) isp1362_hcd->board->reset(hcd->self.controller, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) isp1362_sw_reset(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) /* chip has been reset. First we need to see a clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) t = jiffies + msecs_to_jiffies(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) while (!clkrdy && time_before_eq(jiffies, t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) clkrdy = isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_CLKRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) if (!clkrdy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) msleep(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_CLKRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if (!clkrdy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) pr_err("Clock not ready after %lums\n", timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static void isp1362_hc_stop(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) del_timer_sync(&hcd->rh_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) /* Switch off power for all ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) tmp = isp1362_read_reg32(isp1362_hcd, HCRHDESCA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) tmp &= ~(RH_A_NPS | RH_A_PSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) isp1362_write_reg32(isp1362_hcd, HCRHDESCA, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) /* Reset the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) if (isp1362_hcd->board && isp1362_hcd->board->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) isp1362_hcd->board->reset(hcd->self.controller, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) __isp1362_sw_reset(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (isp1362_hcd->board && isp1362_hcd->board->clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) isp1362_hcd->board->clock(hcd->self.controller, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) #ifdef CHIP_BUFFER_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static int isp1362_chip_test(struct isp1362_hcd *isp1362_hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) u16 *ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) ref = kmalloc(2 * ISP1362_BUF_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) u16 *tst = &ref[ISP1362_BUF_SIZE / 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) for (offset = 0; offset < ISP1362_BUF_SIZE / 2; offset++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) ref[offset] = ~offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) tst[offset] = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) for (offset = 0; offset < 4; offset++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) for (j = 0; j < 8; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) isp1362_write_buffer(isp1362_hcd, (u8 *)ref + offset, 0, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) isp1362_read_buffer(isp1362_hcd, (u8 *)tst + offset, 0, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) if (memcmp(ref, tst, j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) pr_err("%s: memory check with %d byte offset %d failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) __func__, j, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) dump_data((u8 *)ref + offset, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) dump_data((u8 *)tst + offset, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) isp1362_write_buffer(isp1362_hcd, ref, 0, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) isp1362_read_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (memcmp(ref, tst, ISP1362_BUF_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) pr_err("%s: memory check failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) dump_data((u8 *)tst, ISP1362_BUF_SIZE / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) for (offset = 0; offset < 256; offset++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) int test_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) yield();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) memset(tst, 0, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) isp1362_write_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) isp1362_read_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) if (memcmp(tst, tst + (ISP1362_BUF_SIZE / (2 * sizeof(*tst))),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) ISP1362_BUF_SIZE / 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) pr_err("%s: Failed to clear buffer\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) dump_data((u8 *)tst, ISP1362_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) isp1362_write_buffer(isp1362_hcd, ref, offset * 2, PTD_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) isp1362_write_buffer(isp1362_hcd, ref + PTD_HEADER_SIZE / sizeof(*ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) offset * 2 + PTD_HEADER_SIZE, test_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) isp1362_read_buffer(isp1362_hcd, tst, offset * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) PTD_HEADER_SIZE + test_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) if (memcmp(ref, tst, PTD_HEADER_SIZE + test_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) dump_data(((u8 *)ref) + offset, PTD_HEADER_SIZE + test_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) dump_data((u8 *)tst, PTD_HEADER_SIZE + test_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) isp1362_read_buffer(isp1362_hcd, tst, offset * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) PTD_HEADER_SIZE + test_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) if (memcmp(ref, tst, PTD_HEADER_SIZE + test_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) pr_err("%s: memory check with offset %02x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) __func__, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) pr_warn("%s: memory check with offset %02x ok after second read\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) __func__, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) kfree(ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) static int isp1362_hc_start(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) struct isp1362_platform_data *board = isp1362_hcd->board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) u16 hwcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) u16 chipid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) pr_debug("%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) chipid = isp1362_read_reg16(isp1362_hcd, HCCHIPID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) if ((chipid & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) pr_err("%s: Invalid chip ID %04x\n", __func__, chipid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) #ifdef CHIP_BUFFER_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) ret = isp1362_chip_test(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) /* clear interrupt status and disable all interrupt sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) isp1362_write_reg16(isp1362_hcd, HCuPINT, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) /* HW conf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) hwcfg = HCHWCFG_INT_ENABLE | HCHWCFG_DBWIDTH(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if (board->sel15Kres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) hwcfg |= HCHWCFG_PULLDOWN_DS2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) ((MAX_ROOT_PORTS > 1) ? HCHWCFG_PULLDOWN_DS1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (board->clknotstop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) hwcfg |= HCHWCFG_CLKNOTSTOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (board->oc_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) hwcfg |= HCHWCFG_ANALOG_OC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (board->int_act_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) hwcfg |= HCHWCFG_INT_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) if (board->int_edge_triggered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) hwcfg |= HCHWCFG_INT_TRIGGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (board->dreq_act_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) hwcfg |= HCHWCFG_DREQ_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) if (board->dack_act_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) hwcfg |= HCHWCFG_DACK_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) isp1362_write_reg16(isp1362_hcd, HCHWCFG, hwcfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) isp1362_show_reg(isp1362_hcd, HCHWCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) isp1362_write_reg16(isp1362_hcd, HCDMACFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) ret = isp1362_mem_config(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) /* Root hub conf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) isp1362_hcd->rhdesca = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) if (board->no_power_switching)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) isp1362_hcd->rhdesca |= RH_A_NPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) if (board->power_switching_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) isp1362_hcd->rhdesca |= RH_A_PSM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) if (board->potpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) isp1362_hcd->rhdesca |= (board->potpg << 24) & RH_A_POTPGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) isp1362_hcd->rhdesca |= (25 << 24) & RH_A_POTPGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) isp1362_write_reg32(isp1362_hcd, HCRHDESCA, isp1362_hcd->rhdesca & ~RH_A_OCPM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) isp1362_write_reg32(isp1362_hcd, HCRHDESCA, isp1362_hcd->rhdesca | RH_A_OCPM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) isp1362_hcd->rhdesca = isp1362_read_reg32(isp1362_hcd, HCRHDESCA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) isp1362_hcd->rhdescb = RH_B_PPCM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) isp1362_write_reg32(isp1362_hcd, HCRHDESCB, isp1362_hcd->rhdescb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) isp1362_hcd->rhdescb = isp1362_read_reg32(isp1362_hcd, HCRHDESCB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) isp1362_read_reg32(isp1362_hcd, HCFMINTVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) isp1362_write_reg32(isp1362_hcd, HCFMINTVL, (FSMP(FI) << 16) | FI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) isp1362_write_reg32(isp1362_hcd, HCLSTHRESH, LSTHRESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) isp1362_hcd->hc_control = OHCI_USB_OPER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) hcd->state = HC_STATE_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) /* Set up interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) isp1362_hcd->intenb = OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) isp1362_hcd->intenb |= OHCI_INTR_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) isp1362_hcd->irqenb = HCuPINT_OPR | HCuPINT_SUSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) isp1362_write_reg32(isp1362_hcd, HCINTENB, isp1362_hcd->intenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) /* Go operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) /* enable global power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPSC | RH_HS_DRWE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) static const struct hc_driver isp1362_hc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) .description = hcd_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) .product_desc = "ISP1362 Host Controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) .hcd_priv_size = sizeof(struct isp1362_hcd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) .irq = isp1362_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) .flags = HCD_USB11 | HCD_MEMORY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) .reset = isp1362_hc_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) .start = isp1362_hc_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) .stop = isp1362_hc_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) .urb_enqueue = isp1362_urb_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) .urb_dequeue = isp1362_urb_dequeue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) .endpoint_disable = isp1362_endpoint_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) .get_frame_number = isp1362_get_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) .hub_status_data = isp1362_hub_status_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) .hub_control = isp1362_hub_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) .bus_suspend = isp1362_bus_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) .bus_resume = isp1362_bus_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) static int isp1362_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) struct usb_hcd *hcd = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) remove_debug_file(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) DBG(0, "%s: Removing HCD\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) usb_remove_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) DBG(0, "%s: put_hcd\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) DBG(0, "%s: Done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) static int isp1362_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) struct isp1362_hcd *isp1362_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) struct resource *data, *irq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) void __iomem *addr_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) void __iomem *data_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) unsigned int irq_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) if (usb_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) /* basic sanity checks first. board-specific init logic should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) * have initialized this the three resources and probably board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) * specific platform_data. we don't probe for IRQs, and do only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) * minimal sanity checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) if (pdev->num_resources < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) if (!irq_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) irq = irq_res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) addr_reg = devm_platform_ioremap_resource(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) if (IS_ERR(addr_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) return PTR_ERR(addr_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) data_reg = devm_ioremap_resource(&pdev->dev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) if (IS_ERR(data_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) return PTR_ERR(data_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) /* allocate and initialize hcd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) hcd = usb_create_hcd(&isp1362_hc_driver, &pdev->dev, dev_name(&pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (!hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) hcd->rsrc_start = data->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) isp1362_hcd->data_reg = data_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) isp1362_hcd->addr_reg = addr_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) isp1362_hcd->next_statechange = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) spin_lock_init(&isp1362_hcd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) INIT_LIST_HEAD(&isp1362_hcd->async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) INIT_LIST_HEAD(&isp1362_hcd->periodic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) INIT_LIST_HEAD(&isp1362_hcd->isoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) INIT_LIST_HEAD(&isp1362_hcd->remove_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) isp1362_hcd->board = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) #if USE_PLATFORM_DELAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) if (!isp1362_hcd->board->delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) dev_err(hcd->self.controller, "No platform delay function given\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) irq_flags |= IRQF_TRIGGER_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) irq_flags |= IRQF_TRIGGER_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) irq_flags |= IRQF_TRIGGER_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) irq_flags |= IRQF_TRIGGER_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) if (retval != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) device_wakeup_enable(hcd->self.controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) dev_info(&pdev->dev, "%s, irq %d\n", hcd->product_desc, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) create_debug_file(isp1362_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) static int isp1362_suspend(struct platform_device *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) struct usb_hcd *hcd = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) DBG(0, "%s: Suspending device\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) if (state.event == PM_EVENT_FREEZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) DBG(0, "%s: Suspending root hub\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) retval = isp1362_bus_suspend(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) DBG(0, "%s: Suspending RH ports\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) pdev->dev.power.power_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) static int isp1362_resume(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) struct usb_hcd *hcd = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) DBG(0, "%s: Resuming\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) DBG(0, "%s: Resume RH ports\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) spin_lock_irqsave(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) pdev->dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) return isp1362_bus_resume(isp1362_hcd_to_hcd(isp1362_hcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) #define isp1362_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) #define isp1362_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) static struct platform_driver isp1362_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) .probe = isp1362_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) .remove = isp1362_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) .suspend = isp1362_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) .resume = isp1362_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) .name = hcd_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) module_platform_driver(isp1362_driver);