usb: gadget: patches for v3.5
This pull request is quite big, but mainly because there's a giant rework of the s3c_hsotg.c driver to make it friendlier for other users. Samsung Exynos platforms use the DesignWare Core USB2 IP from Synopsys so it's a bit unfair to have the driver work for Samsung platforms only. In short, the big rework is in preparation to make the driver more reusable. Another big rework in this pull request came from Ido, where he's removing the redundant pointer for the endpoint descriptor from the controller driver's own endpoint representation. The same pointer is available through the generic struct usb_ep structure. Also on this pull request is the conversion of a few extra controller drivers to the new style registration, which allows multiple controllers to be available on the same platform and helps remove global pointers from those drivers. Together with those big changes, there's the usual fixes and cleanups to gadget drivers. Nothing major. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJPp3l8AAoJEIaOsuA1yqRECjkP/3mScTFWEgjQsa7ynlYW6bfE 9uI3yP0VPws8EK0MBIOeXOhz7z/x/of/9XEEvnVjqnVkXlYc23IEJactbc1sYHQY WsUyeuD6D+W5UHkomV0W8Xh1agVeW9QYDubQxI62KL81pWCC3MVa+BfW+430lrdi 7FUxWykCByYu1VYNZYfaGFyKalkpOpIydFtAZp2ykawUJMyB1PPl+2uzA1u/zB9A Tm6E2Su+CzWp59/Udc64O25FhPo/g5GQWX2VbO1XneUrpNQgfihq6RjSi3hHYZdq NkeR0eWwc5KeWZfsfm57AErQlN97uP3fAUSHz9o6c5N9V7bW221sCh4ZH3s32+IB Dnps2WbW7IslUntYd1GyakfRILTrhMbg7GJZbmxdzWmIK6Pv0NLISPq4bZ64QJOH iqa8NtluN0m1DSwUNX7UBHQZ6Cj1X3xZIdAJvdg4IlqUJ+Q2UmgCG9/kloF1H0C3 QnRXUEgbmMZ42sVVWEafUhwfEQTNFJyWd7OpFuyo8R3vARJg/miaEy7Lf+IqpRxD 5WV6o/TVCL2c6lQP2NbJoCSr10K2VcHOJpUS8cYv6K+ZIyTbKvOh8rlArX2+/W3a YZtd+nfq2FyuRVxAasXwpsVCDT319LWt+Myq+9cl23+PyN54j+OnhHPJr15tBru1 OB/Z6arXyc17Gq/Ng2ur =irDV -----END PGP SIGNATURE----- Merge tag 'gadget-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next usb: gadget: patches for v3.5 This pull request is quite big, but mainly because there's a giant rework of the s3c_hsotg.c driver to make it friendlier for other users. Samsung Exynos platforms use the DesignWare Core USB2 IP from Synopsys so it's a bit unfair to have the driver work for Samsung platforms only. In short, the big rework is in preparation to make the driver more reusable. Another big rework in this pull request came from Ido, where he's removing the redundant pointer for the endpoint descriptor from the controller driver's own endpoint representation. The same pointer is available through the generic struct usb_ep structure. Also on this pull request is the conversion of a few extra controller drivers to the new style registration, which allows multiple controllers to be available on the same platform and helps remove global pointers from those drivers. Together with those big changes, there's the usual fixes and cleanups to gadget drivers. Nothing major.
This commit is contained in:
Коммит
6a1e1d71d0
|
@ -44,6 +44,7 @@
|
|||
#include <plat/fb.h>
|
||||
#include <plat/sdhci.h>
|
||||
#include <plat/ehci.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
#include <plat/clock.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/iic.h>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <plat/fimc-core.h>
|
||||
#include <plat/camport.h>
|
||||
#include <plat/mipi_csis.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#include <plat/sdhci.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/s3c64xx-spi.h>
|
||||
#include <plat/udc-hs.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
|
||||
#include <plat/keypad.h>
|
||||
#include <plat/clock.h>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/hwmon.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/udc-hs.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
#include <plat/usb-control.h>
|
||||
#include <plat/sdhci.h>
|
||||
#include <plat/ts.h>
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
#include <plat/keypad.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/udc-hs.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <plat/mfc.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/camport.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/s5p_fimc.h>
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include <plat/sdhci.h>
|
||||
#include <plat/ts.h>
|
||||
#include <plat/udc.h>
|
||||
#include <plat/udc-hs.h>
|
||||
#include <linux/platform_data/s3c-hsotg.h>
|
||||
#include <plat/usb-control.h>
|
||||
#include <plat/usb-phy.h>
|
||||
#include <plat/regs-iic.h>
|
||||
|
|
|
@ -1,379 +0,0 @@
|
|||
/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
|
||||
*
|
||||
* Copyright 2008 Openmoko, Inc.
|
||||
* Copyright 2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* S3C - USB2.0 Highspeed/OtG device block registers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H
|
||||
#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
|
||||
|
||||
#define S3C_HSOTG_REG(x) (x)
|
||||
|
||||
#define S3C_GOTGCTL S3C_HSOTG_REG(0x000)
|
||||
#define S3C_GOTGCTL_BSESVLD (1 << 19)
|
||||
#define S3C_GOTGCTL_ASESVLD (1 << 18)
|
||||
#define S3C_GOTGCTL_DBNC_SHORT (1 << 17)
|
||||
#define S3C_GOTGCTL_CONID_B (1 << 16)
|
||||
#define S3C_GOTGCTL_DEVHNPEN (1 << 11)
|
||||
#define S3C_GOTGCTL_HSSETHNPEN (1 << 10)
|
||||
#define S3C_GOTGCTL_HNPREQ (1 << 9)
|
||||
#define S3C_GOTGCTL_HSTNEGSCS (1 << 8)
|
||||
#define S3C_GOTGCTL_SESREQ (1 << 1)
|
||||
#define S3C_GOTGCTL_SESREQSCS (1 << 0)
|
||||
|
||||
#define S3C_GOTGINT S3C_HSOTG_REG(0x004)
|
||||
#define S3C_GOTGINT_DbnceDone (1 << 19)
|
||||
#define S3C_GOTGINT_ADevTOUTChg (1 << 18)
|
||||
#define S3C_GOTGINT_HstNegDet (1 << 17)
|
||||
#define S3C_GOTGINT_HstnegSucStsChng (1 << 9)
|
||||
#define S3C_GOTGINT_SesReqSucStsChng (1 << 8)
|
||||
#define S3C_GOTGINT_SesEndDet (1 << 2)
|
||||
|
||||
#define S3C_GAHBCFG S3C_HSOTG_REG(0x008)
|
||||
#define S3C_GAHBCFG_PTxFEmpLvl (1 << 8)
|
||||
#define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7)
|
||||
#define S3C_GAHBCFG_DMAEn (1 << 5)
|
||||
#define S3C_GAHBCFG_HBstLen_MASK (0xf << 1)
|
||||
#define S3C_GAHBCFG_HBstLen_SHIFT (1)
|
||||
#define S3C_GAHBCFG_HBstLen_Single (0x0 << 1)
|
||||
#define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1)
|
||||
#define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1)
|
||||
#define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1)
|
||||
#define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1)
|
||||
#define S3C_GAHBCFG_GlblIntrEn (1 << 0)
|
||||
|
||||
#define S3C_GUSBCFG S3C_HSOTG_REG(0x00C)
|
||||
#define S3C_GUSBCFG_PHYLPClkSel (1 << 15)
|
||||
#define S3C_GUSBCFG_HNPCap (1 << 9)
|
||||
#define S3C_GUSBCFG_SRPCap (1 << 8)
|
||||
#define S3C_GUSBCFG_PHYIf16 (1 << 3)
|
||||
#define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0)
|
||||
#define S3C_GUSBCFG_TOutCal_SHIFT (0)
|
||||
#define S3C_GUSBCFG_TOutCal_LIMIT (0x7)
|
||||
#define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0)
|
||||
|
||||
#define S3C_GRSTCTL S3C_HSOTG_REG(0x010)
|
||||
|
||||
#define S3C_GRSTCTL_AHBIdle (1 << 31)
|
||||
#define S3C_GRSTCTL_DMAReq (1 << 30)
|
||||
#define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6)
|
||||
#define S3C_GRSTCTL_TxFNum_SHIFT (6)
|
||||
#define S3C_GRSTCTL_TxFNum_LIMIT (0x1f)
|
||||
#define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6)
|
||||
#define S3C_GRSTCTL_TxFFlsh (1 << 5)
|
||||
#define S3C_GRSTCTL_RxFFlsh (1 << 4)
|
||||
#define S3C_GRSTCTL_INTknQFlsh (1 << 3)
|
||||
#define S3C_GRSTCTL_FrmCntrRst (1 << 2)
|
||||
#define S3C_GRSTCTL_HSftRst (1 << 1)
|
||||
#define S3C_GRSTCTL_CSftRst (1 << 0)
|
||||
|
||||
#define S3C_GINTSTS S3C_HSOTG_REG(0x014)
|
||||
#define S3C_GINTMSK S3C_HSOTG_REG(0x018)
|
||||
|
||||
#define S3C_GINTSTS_WkUpInt (1 << 31)
|
||||
#define S3C_GINTSTS_SessReqInt (1 << 30)
|
||||
#define S3C_GINTSTS_DisconnInt (1 << 29)
|
||||
#define S3C_GINTSTS_ConIDStsChng (1 << 28)
|
||||
#define S3C_GINTSTS_PTxFEmp (1 << 26)
|
||||
#define S3C_GINTSTS_HChInt (1 << 25)
|
||||
#define S3C_GINTSTS_PrtInt (1 << 24)
|
||||
#define S3C_GINTSTS_FetSusp (1 << 22)
|
||||
#define S3C_GINTSTS_incompIP (1 << 21)
|
||||
#define S3C_GINTSTS_IncomplSOIN (1 << 20)
|
||||
#define S3C_GINTSTS_OEPInt (1 << 19)
|
||||
#define S3C_GINTSTS_IEPInt (1 << 18)
|
||||
#define S3C_GINTSTS_EPMis (1 << 17)
|
||||
#define S3C_GINTSTS_EOPF (1 << 15)
|
||||
#define S3C_GINTSTS_ISOutDrop (1 << 14)
|
||||
#define S3C_GINTSTS_EnumDone (1 << 13)
|
||||
#define S3C_GINTSTS_USBRst (1 << 12)
|
||||
#define S3C_GINTSTS_USBSusp (1 << 11)
|
||||
#define S3C_GINTSTS_ErlySusp (1 << 10)
|
||||
#define S3C_GINTSTS_GOUTNakEff (1 << 7)
|
||||
#define S3C_GINTSTS_GINNakEff (1 << 6)
|
||||
#define S3C_GINTSTS_NPTxFEmp (1 << 5)
|
||||
#define S3C_GINTSTS_RxFLvl (1 << 4)
|
||||
#define S3C_GINTSTS_SOF (1 << 3)
|
||||
#define S3C_GINTSTS_OTGInt (1 << 2)
|
||||
#define S3C_GINTSTS_ModeMis (1 << 1)
|
||||
#define S3C_GINTSTS_CurMod_Host (1 << 0)
|
||||
|
||||
#define S3C_GRXSTSR S3C_HSOTG_REG(0x01C)
|
||||
#define S3C_GRXSTSP S3C_HSOTG_REG(0x020)
|
||||
|
||||
#define S3C_GRXSTS_FN_MASK (0x7f << 25)
|
||||
#define S3C_GRXSTS_FN_SHIFT (25)
|
||||
|
||||
#define S3C_GRXSTS_PktSts_MASK (0xf << 17)
|
||||
#define S3C_GRXSTS_PktSts_SHIFT (17)
|
||||
#define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17)
|
||||
#define S3C_GRXSTS_PktSts_OutRX (0x2 << 17)
|
||||
#define S3C_GRXSTS_PktSts_OutDone (0x3 << 17)
|
||||
#define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17)
|
||||
#define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17)
|
||||
|
||||
#define S3C_GRXSTS_DPID_MASK (0x3 << 15)
|
||||
#define S3C_GRXSTS_DPID_SHIFT (15)
|
||||
#define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4)
|
||||
#define S3C_GRXSTS_ByteCnt_SHIFT (4)
|
||||
#define S3C_GRXSTS_EPNum_MASK (0xf << 0)
|
||||
#define S3C_GRXSTS_EPNum_SHIFT (0)
|
||||
|
||||
#define S3C_GRXFSIZ S3C_HSOTG_REG(0x024)
|
||||
|
||||
#define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028)
|
||||
|
||||
#define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16)
|
||||
#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16)
|
||||
#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff)
|
||||
#define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16)
|
||||
#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0)
|
||||
#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0)
|
||||
#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff)
|
||||
#define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0)
|
||||
|
||||
#define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C)
|
||||
|
||||
#define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24)
|
||||
#define S3C_GNPTXSTS_NPtxQTop_SHIFT (24)
|
||||
|
||||
#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16)
|
||||
#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16)
|
||||
#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff)
|
||||
|
||||
#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0)
|
||||
#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0)
|
||||
#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff)
|
||||
|
||||
|
||||
#define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100)
|
||||
|
||||
#define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
|
||||
|
||||
#define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16)
|
||||
#define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16)
|
||||
#define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff)
|
||||
#define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff)
|
||||
#define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16)
|
||||
|
||||
#define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0)
|
||||
#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0)
|
||||
|
||||
/* Device mode registers */
|
||||
#define S3C_DCFG S3C_HSOTG_REG(0x800)
|
||||
|
||||
#define S3C_DCFG_EPMisCnt_MASK (0x1f << 18)
|
||||
#define S3C_DCFG_EPMisCnt_SHIFT (18)
|
||||
#define S3C_DCFG_EPMisCnt_LIMIT (0x1f)
|
||||
#define S3C_DCFG_EPMisCnt(_x) ((_x) << 18)
|
||||
|
||||
#define S3C_DCFG_PerFrInt_MASK (0x3 << 11)
|
||||
#define S3C_DCFG_PerFrInt_SHIFT (11)
|
||||
#define S3C_DCFG_PerFrInt_LIMIT (0x3)
|
||||
#define S3C_DCFG_PerFrInt(_x) ((_x) << 11)
|
||||
|
||||
#define S3C_DCFG_DevAddr_MASK (0x7f << 4)
|
||||
#define S3C_DCFG_DevAddr_SHIFT (4)
|
||||
#define S3C_DCFG_DevAddr_LIMIT (0x7f)
|
||||
#define S3C_DCFG_DevAddr(_x) ((_x) << 4)
|
||||
|
||||
#define S3C_DCFG_NZStsOUTHShk (1 << 2)
|
||||
|
||||
#define S3C_DCFG_DevSpd_MASK (0x3 << 0)
|
||||
#define S3C_DCFG_DevSpd_SHIFT (0)
|
||||
#define S3C_DCFG_DevSpd_HS (0x0 << 0)
|
||||
#define S3C_DCFG_DevSpd_FS (0x1 << 0)
|
||||
#define S3C_DCFG_DevSpd_LS (0x2 << 0)
|
||||
#define S3C_DCFG_DevSpd_FS48 (0x3 << 0)
|
||||
|
||||
#define S3C_DCTL S3C_HSOTG_REG(0x804)
|
||||
|
||||
#define S3C_DCTL_PWROnPrgDone (1 << 11)
|
||||
#define S3C_DCTL_CGOUTNak (1 << 10)
|
||||
#define S3C_DCTL_SGOUTNak (1 << 9)
|
||||
#define S3C_DCTL_CGNPInNAK (1 << 8)
|
||||
#define S3C_DCTL_SGNPInNAK (1 << 7)
|
||||
#define S3C_DCTL_TstCtl_MASK (0x7 << 4)
|
||||
#define S3C_DCTL_TstCtl_SHIFT (4)
|
||||
#define S3C_DCTL_GOUTNakSts (1 << 3)
|
||||
#define S3C_DCTL_GNPINNakSts (1 << 2)
|
||||
#define S3C_DCTL_SftDiscon (1 << 1)
|
||||
#define S3C_DCTL_RmtWkUpSig (1 << 0)
|
||||
|
||||
#define S3C_DSTS S3C_HSOTG_REG(0x808)
|
||||
|
||||
#define S3C_DSTS_SOFFN_MASK (0x3fff << 8)
|
||||
#define S3C_DSTS_SOFFN_SHIFT (8)
|
||||
#define S3C_DSTS_SOFFN_LIMIT (0x3fff)
|
||||
#define S3C_DSTS_SOFFN(_x) ((_x) << 8)
|
||||
#define S3C_DSTS_ErraticErr (1 << 3)
|
||||
#define S3C_DSTS_EnumSpd_MASK (0x3 << 1)
|
||||
#define S3C_DSTS_EnumSpd_SHIFT (1)
|
||||
#define S3C_DSTS_EnumSpd_HS (0x0 << 1)
|
||||
#define S3C_DSTS_EnumSpd_FS (0x1 << 1)
|
||||
#define S3C_DSTS_EnumSpd_LS (0x2 << 1)
|
||||
#define S3C_DSTS_EnumSpd_FS48 (0x3 << 1)
|
||||
|
||||
#define S3C_DSTS_SuspSts (1 << 0)
|
||||
|
||||
#define S3C_DIEPMSK S3C_HSOTG_REG(0x810)
|
||||
|
||||
#define S3C_DIEPMSK_TxFIFOEmpty (1 << 7)
|
||||
#define S3C_DIEPMSK_INEPNakEffMsk (1 << 6)
|
||||
#define S3C_DIEPMSK_INTknEPMisMsk (1 << 5)
|
||||
#define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4)
|
||||
#define S3C_DIEPMSK_TimeOUTMsk (1 << 3)
|
||||
#define S3C_DIEPMSK_AHBErrMsk (1 << 2)
|
||||
#define S3C_DIEPMSK_EPDisbldMsk (1 << 1)
|
||||
#define S3C_DIEPMSK_XferComplMsk (1 << 0)
|
||||
|
||||
#define S3C_DOEPMSK S3C_HSOTG_REG(0x814)
|
||||
|
||||
#define S3C_DOEPMSK_Back2BackSetup (1 << 6)
|
||||
#define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4)
|
||||
#define S3C_DOEPMSK_SetupMsk (1 << 3)
|
||||
#define S3C_DOEPMSK_AHBErrMsk (1 << 2)
|
||||
#define S3C_DOEPMSK_EPDisbldMsk (1 << 1)
|
||||
#define S3C_DOEPMSK_XferComplMsk (1 << 0)
|
||||
|
||||
#define S3C_DAINT S3C_HSOTG_REG(0x818)
|
||||
#define S3C_DAINTMSK S3C_HSOTG_REG(0x81C)
|
||||
|
||||
#define S3C_DAINT_OutEP_SHIFT (16)
|
||||
#define S3C_DAINT_OutEP(x) (1 << ((x) + 16))
|
||||
#define S3C_DAINT_InEP(x) (1 << (x))
|
||||
|
||||
#define S3C_DTKNQR1 S3C_HSOTG_REG(0x820)
|
||||
#define S3C_DTKNQR2 S3C_HSOTG_REG(0x824)
|
||||
#define S3C_DTKNQR3 S3C_HSOTG_REG(0x830)
|
||||
#define S3C_DTKNQR4 S3C_HSOTG_REG(0x834)
|
||||
|
||||
#define S3C_DVBUSDIS S3C_HSOTG_REG(0x828)
|
||||
#define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C)
|
||||
|
||||
#define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900)
|
||||
#define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00)
|
||||
#define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
|
||||
#define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
|
||||
|
||||
/* EP0 specialness:
|
||||
* bits[29..28] - reserved (no SetD0PID, SetD1PID)
|
||||
* bits[25..22] - should always be zero, this isn't a periodic endpoint
|
||||
* bits[10..0] - MPS setting differenct for EP0
|
||||
*/
|
||||
#define S3C_D0EPCTL_MPS_MASK (0x3 << 0)
|
||||
#define S3C_D0EPCTL_MPS_SHIFT (0)
|
||||
#define S3C_D0EPCTL_MPS_64 (0x0 << 0)
|
||||
#define S3C_D0EPCTL_MPS_32 (0x1 << 0)
|
||||
#define S3C_D0EPCTL_MPS_16 (0x2 << 0)
|
||||
#define S3C_D0EPCTL_MPS_8 (0x3 << 0)
|
||||
|
||||
#define S3C_DxEPCTL_EPEna (1 << 31)
|
||||
#define S3C_DxEPCTL_EPDis (1 << 30)
|
||||
#define S3C_DxEPCTL_SetD1PID (1 << 29)
|
||||
#define S3C_DxEPCTL_SetOddFr (1 << 29)
|
||||
#define S3C_DxEPCTL_SetD0PID (1 << 28)
|
||||
#define S3C_DxEPCTL_SetEvenFr (1 << 28)
|
||||
#define S3C_DxEPCTL_SNAK (1 << 27)
|
||||
#define S3C_DxEPCTL_CNAK (1 << 26)
|
||||
#define S3C_DxEPCTL_TxFNum_MASK (0xf << 22)
|
||||
#define S3C_DxEPCTL_TxFNum_SHIFT (22)
|
||||
#define S3C_DxEPCTL_TxFNum_LIMIT (0xf)
|
||||
#define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22)
|
||||
|
||||
#define S3C_DxEPCTL_Stall (1 << 21)
|
||||
#define S3C_DxEPCTL_Snp (1 << 20)
|
||||
#define S3C_DxEPCTL_EPType_MASK (0x3 << 18)
|
||||
#define S3C_DxEPCTL_EPType_SHIFT (18)
|
||||
#define S3C_DxEPCTL_EPType_Control (0x0 << 18)
|
||||
#define S3C_DxEPCTL_EPType_Iso (0x1 << 18)
|
||||
#define S3C_DxEPCTL_EPType_Bulk (0x2 << 18)
|
||||
#define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18)
|
||||
|
||||
#define S3C_DxEPCTL_NAKsts (1 << 17)
|
||||
#define S3C_DxEPCTL_DPID (1 << 16)
|
||||
#define S3C_DxEPCTL_EOFrNum (1 << 16)
|
||||
#define S3C_DxEPCTL_USBActEp (1 << 15)
|
||||
#define S3C_DxEPCTL_NextEp_MASK (0xf << 11)
|
||||
#define S3C_DxEPCTL_NextEp_SHIFT (11)
|
||||
#define S3C_DxEPCTL_NextEp_LIMIT (0xf)
|
||||
#define S3C_DxEPCTL_NextEp(_x) ((_x) << 11)
|
||||
|
||||
#define S3C_DxEPCTL_MPS_MASK (0x7ff << 0)
|
||||
#define S3C_DxEPCTL_MPS_SHIFT (0)
|
||||
#define S3C_DxEPCTL_MPS_LIMIT (0x7ff)
|
||||
#define S3C_DxEPCTL_MPS(_x) ((_x) << 0)
|
||||
|
||||
#define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
|
||||
#define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
|
||||
|
||||
#define S3C_DxEPINT_INEPNakEff (1 << 6)
|
||||
#define S3C_DxEPINT_Back2BackSetup (1 << 6)
|
||||
#define S3C_DxEPINT_INTknEPMis (1 << 5)
|
||||
#define S3C_DxEPINT_INTknTXFEmp (1 << 4)
|
||||
#define S3C_DxEPINT_OUTTknEPdis (1 << 4)
|
||||
#define S3C_DxEPINT_Timeout (1 << 3)
|
||||
#define S3C_DxEPINT_Setup (1 << 3)
|
||||
#define S3C_DxEPINT_AHBErr (1 << 2)
|
||||
#define S3C_DxEPINT_EPDisbld (1 << 1)
|
||||
#define S3C_DxEPINT_XferCompl (1 << 0)
|
||||
|
||||
#define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910)
|
||||
|
||||
#define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19)
|
||||
#define S3C_DIEPTSIZ0_PktCnt_SHIFT (19)
|
||||
#define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3)
|
||||
#define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19)
|
||||
|
||||
#define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0)
|
||||
#define S3C_DIEPTSIZ0_XferSize_SHIFT (0)
|
||||
#define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f)
|
||||
#define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0)
|
||||
|
||||
|
||||
#define DOEPTSIZ0 S3C_HSOTG_REG(0xB10)
|
||||
#define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29)
|
||||
#define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29)
|
||||
#define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3)
|
||||
#define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29)
|
||||
|
||||
#define S3C_DOEPTSIZ0_PktCnt (1 << 19)
|
||||
#define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0)
|
||||
#define S3C_DOEPTSIZ0_XferSize_SHIFT (0)
|
||||
|
||||
#define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
|
||||
#define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
|
||||
|
||||
#define S3C_DxEPTSIZ_MC_MASK (0x3 << 29)
|
||||
#define S3C_DxEPTSIZ_MC_SHIFT (29)
|
||||
#define S3C_DxEPTSIZ_MC_LIMIT (0x3)
|
||||
#define S3C_DxEPTSIZ_MC(_x) ((_x) << 29)
|
||||
|
||||
#define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19)
|
||||
#define S3C_DxEPTSIZ_PktCnt_SHIFT (19)
|
||||
#define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff)
|
||||
#define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff)
|
||||
#define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19)
|
||||
|
||||
#define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0)
|
||||
#define S3C_DxEPTSIZ_XferSize_SHIFT (0)
|
||||
#define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff)
|
||||
#define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff)
|
||||
#define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0)
|
||||
|
||||
|
||||
#define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
|
||||
#define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
|
||||
#define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20))
|
||||
|
||||
#define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
|
||||
|
||||
#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
|
|
@ -361,7 +361,6 @@ struct dwc3_ep {
|
|||
dma_addr_t trb_pool_dma;
|
||||
u32 free_slot;
|
||||
u32 busy_slot;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
const struct usb_ss_ep_comp_descriptor *comp_desc;
|
||||
struct dwc3 *dwc;
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
|
|||
int ret;
|
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
if (!dep->desc) {
|
||||
if (!dep->endpoint.desc) {
|
||||
dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
|
||||
request, dep->name);
|
||||
ret = -ESHUTDOWN;
|
||||
|
|
|
@ -178,8 +178,8 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
|
|||
if (!(dep->flags & DWC3_EP_ENABLED))
|
||||
continue;
|
||||
|
||||
if (usb_endpoint_xfer_bulk(dep->desc)
|
||||
|| usb_endpoint_xfer_isoc(dep->desc))
|
||||
if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
|
||||
|| usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
mult = 3;
|
||||
|
||||
/*
|
||||
|
@ -229,7 +229,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||
* completed (not the LINK TRB).
|
||||
*/
|
||||
if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
|
||||
usb_endpoint_xfer_isoc(dep->desc))
|
||||
usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
dep->busy_slot++;
|
||||
}
|
||||
list_del(&req->list);
|
||||
|
@ -470,7 +470,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
dep->desc = desc;
|
||||
dep->endpoint.desc = desc;
|
||||
dep->comp_desc = comp_desc;
|
||||
dep->type = usb_endpoint_type(desc);
|
||||
dep->flags |= DWC3_EP_ENABLED;
|
||||
|
@ -533,7 +533,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
|
|||
dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
|
||||
|
||||
dep->stream_capable = false;
|
||||
dep->desc = NULL;
|
||||
dep->endpoint.desc = NULL;
|
||||
dep->comp_desc = NULL;
|
||||
dep->type = 0;
|
||||
|
@ -694,7 +693,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
|
|||
|
||||
/* Skip the LINK-TRB on ISOC */
|
||||
if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
|
||||
usb_endpoint_xfer_isoc(dep->desc))
|
||||
usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
return;
|
||||
|
||||
if (!req->trb) {
|
||||
|
@ -707,7 +706,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
|
|||
trb->bpl = lower_32_bits(dma);
|
||||
trb->bph = upper_32_bits(dma);
|
||||
|
||||
switch (usb_endpoint_type(dep->desc)) {
|
||||
switch (usb_endpoint_type(dep->endpoint.desc)) {
|
||||
case USB_ENDPOINT_XFER_CONTROL:
|
||||
trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP;
|
||||
break;
|
||||
|
@ -732,7 +731,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
|
|||
BUG();
|
||||
}
|
||||
|
||||
if (usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
|
||||
trb->ctrl |= DWC3_TRB_CTRL_CSP;
|
||||
} else {
|
||||
|
@ -743,7 +742,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
|
|||
trb->ctrl |= DWC3_TRB_CTRL_LST;
|
||||
}
|
||||
|
||||
if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
|
||||
if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
|
||||
trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
|
||||
|
||||
trb->ctrl |= DWC3_TRB_CTRL_HWO;
|
||||
|
@ -771,7 +770,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
|
|||
trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
|
||||
|
||||
/* Can't wrap around on a non-isoc EP since there's no link TRB */
|
||||
if (!usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK);
|
||||
if (trbs_left > max)
|
||||
trbs_left = max;
|
||||
|
@ -797,7 +796,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
|
|||
* processed from the first TRB until the last one. Since we
|
||||
* don't wrap around we have to start at the beginning.
|
||||
*/
|
||||
if (usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
dep->busy_slot = 1;
|
||||
dep->free_slot = 1;
|
||||
} else {
|
||||
|
@ -807,7 +806,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
|
|||
}
|
||||
|
||||
/* The last TRB is a link TRB, not used for xfer */
|
||||
if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))
|
||||
if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(req, n, &dep->request_list, list) {
|
||||
|
@ -984,7 +983,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
|||
int start_trans;
|
||||
|
||||
start_trans = 1;
|
||||
if (usb_endpoint_xfer_isoc(dep->desc) &&
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
|
||||
(dep->flags & DWC3_EP_BUSY))
|
||||
start_trans = 0;
|
||||
|
||||
|
@ -1011,7 +1010,7 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
|
|||
|
||||
int ret;
|
||||
|
||||
if (!dep->desc) {
|
||||
if (!dep->endpoint.desc) {
|
||||
dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
|
||||
request, ep->name);
|
||||
return -ESHUTDOWN;
|
||||
|
@ -1125,7 +1124,7 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)
|
|||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
|
||||
if (usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
@ -1681,7 +1680,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
|||
case DWC3_DEPEVT_XFERCOMPLETE:
|
||||
dep->res_trans_idx = 0;
|
||||
|
||||
if (usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",
|
||||
dep->name);
|
||||
return;
|
||||
|
@ -1690,7 +1689,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
|||
dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
|
||||
break;
|
||||
case DWC3_DEPEVT_XFERINPROGRESS:
|
||||
if (!usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
|
||||
dep->name);
|
||||
return;
|
||||
|
@ -1699,7 +1698,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
|||
dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
|
||||
break;
|
||||
case DWC3_DEPEVT_XFERNOTREADY:
|
||||
if (usb_endpoint_xfer_isoc(dep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
|
||||
dwc3_gadget_start_isoc(dwc, dep, event);
|
||||
} else {
|
||||
int ret;
|
||||
|
@ -1720,7 +1719,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
|||
|
||||
break;
|
||||
case DWC3_DEPEVT_STREAMEVT:
|
||||
if (!usb_endpoint_xfer_bulk(dep->desc)) {
|
||||
if (!usb_endpoint_xfer_bulk(dep->endpoint.desc)) {
|
||||
dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
|
||||
dep->name);
|
||||
return;
|
||||
|
|
|
@ -172,7 +172,7 @@ config USB_FSL_USB2
|
|||
select USB_GADGET_DUALSPEED
|
||||
select USB_FSL_MPH_DR_OF if OF
|
||||
help
|
||||
Some of Freescale PowerPC processors have a High Speed
|
||||
Some of Freescale PowerPC and i.MX processors have a High Speed
|
||||
Dual-Role(DR) USB controller, which supports device mode.
|
||||
|
||||
The number of programmable endpoints is different through
|
||||
|
|
|
@ -333,7 +333,7 @@ udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc)
|
|||
return -ESHUTDOWN;
|
||||
|
||||
spin_lock_irqsave(&dev->lock, iflags);
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
|
||||
ep->halted = 0;
|
||||
|
||||
|
@ -442,7 +442,6 @@ static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep)
|
|||
u32 tmp;
|
||||
|
||||
VDBG(ep->dev, "ep-%d reset\n", ep->num);
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->ep.ops = &udc_ep_ops;
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
|
@ -489,7 +488,7 @@ static int udc_ep_disable(struct usb_ep *usbep)
|
|||
return -EINVAL;
|
||||
|
||||
ep = container_of(usbep, struct udc_ep, ep);
|
||||
if (usbep->name == ep0_string || !ep->desc)
|
||||
if (usbep->name == ep0_string || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
DBG(ep->dev, "Disable ep-%d\n", ep->num);
|
||||
|
@ -1066,7 +1065,7 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
|
|||
return -EINVAL;
|
||||
|
||||
ep = container_of(usbep, struct udc_ep, ep);
|
||||
if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
|
||||
if (!ep->ep.desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
|
||||
return -EINVAL;
|
||||
|
||||
VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in);
|
||||
|
@ -1257,7 +1256,7 @@ static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq)
|
|||
unsigned long iflags;
|
||||
|
||||
ep = container_of(usbep, struct udc_ep, ep);
|
||||
if (!usbep || !usbreq || (!ep->desc && (ep->num != 0
|
||||
if (!usbep || !usbreq || (!ep->ep.desc && (ep->num != 0
|
||||
&& ep->num != UDC_EP0OUT_IX)))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1317,7 +1316,7 @@ udc_set_halt(struct usb_ep *usbep, int halt)
|
|||
pr_debug("set_halt %s: halt=%d\n", usbep->name, halt);
|
||||
|
||||
ep = container_of(usbep, struct udc_ep, ep);
|
||||
if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
|
||||
if (!ep->ep.desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
|
||||
return -EINVAL;
|
||||
if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
|
||||
return -ESHUTDOWN;
|
||||
|
@ -1539,7 +1538,7 @@ static void udc_setup_endpoints(struct udc *dev)
|
|||
* disabling ep interrupts when ENUM interrupt occurs but ep is
|
||||
* not enabled by gadget driver
|
||||
*/
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
ep_init(dev->regs, ep);
|
||||
|
||||
if (use_dma) {
|
||||
|
@ -3402,19 +3401,7 @@ static struct pci_driver udc_pci_driver = {
|
|||
.remove = udc_pci_remove,
|
||||
};
|
||||
|
||||
/* Inits driver */
|
||||
static int __init init(void)
|
||||
{
|
||||
return pci_register_driver(&udc_pci_driver);
|
||||
}
|
||||
module_init(init);
|
||||
|
||||
/* Cleans driver */
|
||||
static void __exit cleanup(void)
|
||||
{
|
||||
pci_unregister_driver(&udc_pci_driver);
|
||||
}
|
||||
module_exit(cleanup);
|
||||
module_pci_driver(udc_pci_driver);
|
||||
|
||||
MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION);
|
||||
MODULE_AUTHOR("Thomas Dahlmann");
|
||||
|
|
|
@ -512,7 +512,6 @@ struct udc_ep {
|
|||
|
||||
/* queue for requests */
|
||||
struct list_head queue;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
unsigned halted;
|
||||
unsigned cancel_transfer;
|
||||
unsigned num : 5,
|
||||
|
|
|
@ -212,7 +212,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
|
|||
if (udc->enabled && udc->vbus) {
|
||||
proc_ep_show(s, &udc->ep[0]);
|
||||
list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
|
||||
if (ep->desc)
|
||||
if (ep->ep.desc)
|
||||
proc_ep_show(s, ep);
|
||||
}
|
||||
}
|
||||
|
@ -530,7 +530,7 @@ ok:
|
|||
tmp |= AT91_UDP_EPEDS;
|
||||
__raw_writel(tmp, ep->creg);
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->ep.maxpacket = maxpacket;
|
||||
|
||||
/*
|
||||
|
@ -558,7 +558,6 @@ static int at91_ep_disable (struct usb_ep * _ep)
|
|||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
/* restore the endpoint's pristine config */
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->ep.maxpacket = ep->maxpacket;
|
||||
|
||||
|
@ -618,7 +617,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!_ep || (!ep->desc && ep->ep.name != ep0name)) {
|
||||
if (!_ep || (!ep->ep.desc && ep->ep.name != ep0name)) {
|
||||
DBG("invalid ep\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -833,7 +832,7 @@ static void udc_reinit(struct at91_udc *udc)
|
|||
|
||||
if (i != 0)
|
||||
list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 0;
|
||||
ep->fifo_bank = 0;
|
||||
ep->ep.maxpacket = ep->maxpacket;
|
||||
|
@ -978,18 +977,18 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int at91_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *));
|
||||
static int at91_stop(struct usb_gadget_driver *driver);
|
||||
|
||||
static int at91_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static int at91_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static const struct usb_gadget_ops at91_udc_ops = {
|
||||
.get_frame = at91_get_frame,
|
||||
.wakeup = at91_wakeup,
|
||||
.set_selfpowered = at91_set_selfpowered,
|
||||
.vbus_session = at91_vbus_session,
|
||||
.pullup = at91_pullup,
|
||||
.start = at91_start,
|
||||
.stop = at91_stop,
|
||||
.udc_start = at91_start,
|
||||
.udc_stop = at91_stop,
|
||||
|
||||
/*
|
||||
* VBUS-powered devices may also also want to support bigger
|
||||
|
@ -1172,7 +1171,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
|
|||
| USB_REQ_GET_STATUS:
|
||||
tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
|
||||
ep = &udc->ep[tmp];
|
||||
if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc))
|
||||
if (tmp >= NUM_ENDPOINTS || (tmp && !ep->ep.desc))
|
||||
goto stall;
|
||||
|
||||
if (tmp) {
|
||||
|
@ -1197,7 +1196,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
|
|||
ep = &udc->ep[tmp];
|
||||
if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS)
|
||||
goto stall;
|
||||
if (!ep->desc || ep->is_iso)
|
||||
if (!ep->ep.desc || ep->is_iso)
|
||||
goto stall;
|
||||
if ((w_index & USB_DIR_IN)) {
|
||||
if (!ep->is_in)
|
||||
|
@ -1218,7 +1217,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
|
|||
goto stall;
|
||||
if (tmp == 0)
|
||||
goto succeed;
|
||||
if (!ep->desc || ep->is_iso)
|
||||
if (!ep->ep.desc || ep->is_iso)
|
||||
goto stall;
|
||||
if ((w_index & USB_DIR_IN)) {
|
||||
if (!ep->is_in)
|
||||
|
@ -1627,66 +1626,34 @@ static void at91_vbus_timer(unsigned long data)
|
|||
schedule_work(&udc->vbus_timer_work);
|
||||
}
|
||||
|
||||
static int at91_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *))
|
||||
static int at91_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct at91_udc *udc = &controller;
|
||||
int retval;
|
||||
unsigned long flags;
|
||||
|
||||
if (!driver
|
||||
|| driver->max_speed < USB_SPEED_FULL
|
||||
|| !bind
|
||||
|| !driver->setup) {
|
||||
DBG("bad parameter.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (udc->driver) {
|
||||
DBG("UDC already has a gadget driver\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
struct at91_udc *udc;
|
||||
|
||||
udc = container_of(gadget, struct at91_udc, gadget);
|
||||
udc->driver = driver;
|
||||
udc->gadget.dev.driver = &driver->driver;
|
||||
dev_set_drvdata(&udc->gadget.dev, &driver->driver);
|
||||
udc->enabled = 1;
|
||||
udc->selfpowered = 1;
|
||||
|
||||
retval = bind(&udc->gadget);
|
||||
if (retval) {
|
||||
DBG("bind() returned %d\n", retval);
|
||||
udc->driver = NULL;
|
||||
udc->gadget.dev.driver = NULL;
|
||||
dev_set_drvdata(&udc->gadget.dev, NULL);
|
||||
udc->enabled = 0;
|
||||
udc->selfpowered = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
pullup(udc, 1);
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
DBG("bound to %s\n", driver->driver.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at91_stop(struct usb_gadget_driver *driver)
|
||||
static int at91_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct at91_udc *udc = &controller;
|
||||
struct at91_udc *udc;
|
||||
unsigned long flags;
|
||||
|
||||
if (!driver || driver != udc->driver || !driver->unbind)
|
||||
return -EINVAL;
|
||||
|
||||
udc = container_of(gadget, struct at91_udc, gadget);
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
udc->enabled = 0;
|
||||
at91_udp_write(udc, AT91_UDP_IDR, ~0);
|
||||
pullup(udc, 0);
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
driver->unbind(&udc->gadget);
|
||||
udc->gadget.dev.driver = NULL;
|
||||
dev_set_drvdata(&udc->gadget.dev, NULL);
|
||||
udc->driver = NULL;
|
||||
|
|
|
@ -105,9 +105,6 @@ struct at91_ep {
|
|||
unsigned is_in:1;
|
||||
unsigned is_iso:1;
|
||||
unsigned fifo_bank:1;
|
||||
|
||||
const struct usb_endpoint_descriptor
|
||||
*desc;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -599,13 +599,13 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
|
||||
spin_lock_irqsave(&ep->udc->lock, flags);
|
||||
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
spin_unlock_irqrestore(&ep->udc->lock, flags);
|
||||
DBG(DBG_ERR, "ep%d already enabled\n", ep->index);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->ep.maxpacket = maxpacket;
|
||||
|
||||
usba_ep_writel(ep, CFG, ept_cfg);
|
||||
|
@ -647,7 +647,7 @@ static int usba_ep_disable(struct usb_ep *_ep)
|
|||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
|
||||
if (!ep->desc) {
|
||||
if (!ep->ep.desc) {
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
/* REVISIT because this driver disables endpoints in
|
||||
* reset_all_endpoints() before calling disconnect(),
|
||||
|
@ -658,7 +658,6 @@ static int usba_ep_disable(struct usb_ep *_ep)
|
|||
ep->ep.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
|
||||
list_splice_init(&ep->queue, &req_list);
|
||||
|
@ -752,7 +751,7 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep,
|
|||
*/
|
||||
ret = -ESHUTDOWN;
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
if (list_empty(&ep->queue))
|
||||
submit_request(ep, req);
|
||||
|
||||
|
@ -776,7 +775,8 @@ usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n",
|
||||
ep->ep.name, req, _req->length);
|
||||
|
||||
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN || !ep->desc)
|
||||
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN ||
|
||||
!ep->ep.desc)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
req->submitted = 0;
|
||||
|
@ -792,7 +792,7 @@ usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
/* May have received a reset since last time we checked */
|
||||
ret = -ESHUTDOWN;
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
list_add_tail(&req->queue, &ep->queue);
|
||||
|
||||
if ((!ep_is_control(ep) && ep->is_in) ||
|
||||
|
@ -905,7 +905,7 @@ static int usba_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name,
|
||||
value ? "set" : "clear");
|
||||
|
||||
if (!ep->desc) {
|
||||
if (!ep->ep.desc) {
|
||||
DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n",
|
||||
ep->ep.name);
|
||||
return -ENODEV;
|
||||
|
@ -1008,16 +1008,16 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_usba_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *));
|
||||
static int atmel_usba_stop(struct usb_gadget_driver *driver);
|
||||
|
||||
static int atmel_usba_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static int atmel_usba_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static const struct usb_gadget_ops usba_udc_ops = {
|
||||
.get_frame = usba_udc_get_frame,
|
||||
.wakeup = usba_udc_wakeup,
|
||||
.set_selfpowered = usba_udc_set_selfpowered,
|
||||
.start = atmel_usba_start,
|
||||
.stop = atmel_usba_stop,
|
||||
.udc_start = atmel_usba_start,
|
||||
.udc_stop = atmel_usba_stop,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor usba_ep0_desc = {
|
||||
|
@ -1071,7 +1071,7 @@ static void reset_all_endpoints(struct usba_udc *udc)
|
|||
* FIXME remove this code ... and retest thoroughly.
|
||||
*/
|
||||
list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
spin_unlock(&udc->lock);
|
||||
usba_ep_disable(&ep->ep);
|
||||
spin_lock(&udc->lock);
|
||||
|
@ -1089,9 +1089,9 @@ static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex)
|
|||
list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
|
||||
u8 bEndpointAddress;
|
||||
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
continue;
|
||||
bEndpointAddress = ep->desc->bEndpointAddress;
|
||||
bEndpointAddress = ep->ep.desc->bEndpointAddress;
|
||||
if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
|
||||
continue;
|
||||
if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
|
||||
|
@ -1727,7 +1727,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
|
|||
usb_speed_string(udc->gadget.speed));
|
||||
|
||||
ep0 = &usba_ep[0];
|
||||
ep0->desc = &usba_ep0_desc;
|
||||
ep0->ep.desc = &usba_ep0_desc;
|
||||
ep0->state = WAIT_FOR_SETUP;
|
||||
usba_ep_writel(ep0, CFG,
|
||||
(USBA_BF(EPT_SIZE, EP0_EPT_SIZE)
|
||||
|
@ -1795,21 +1795,13 @@ out:
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int atmel_usba_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *))
|
||||
static int atmel_usba_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct usba_udc *udc = &the_udc;
|
||||
struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget);
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!udc->pdev)
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
if (udc->driver) {
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
udc->devstatus = 1 << USB_DEVICE_SELF_POWERED;
|
||||
udc->driver = driver;
|
||||
|
@ -1819,13 +1811,6 @@ static int atmel_usba_start(struct usb_gadget_driver *driver,
|
|||
clk_enable(udc->pclk);
|
||||
clk_enable(udc->hclk);
|
||||
|
||||
ret = bind(&udc->gadget);
|
||||
if (ret) {
|
||||
DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
|
||||
driver->driver.name, ret);
|
||||
goto err_driver_bind;
|
||||
}
|
||||
|
||||
DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
|
||||
|
||||
udc->vbus_prev = 0;
|
||||
|
@ -1842,23 +1827,14 @@ static int atmel_usba_start(struct usb_gadget_driver *driver,
|
|||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
err_driver_bind:
|
||||
udc->driver = NULL;
|
||||
udc->gadget.dev.driver = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_usba_stop(struct usb_gadget_driver *driver)
|
||||
static int atmel_usba_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct usba_udc *udc = &the_udc;
|
||||
struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget);
|
||||
unsigned long flags;
|
||||
|
||||
if (!udc->pdev)
|
||||
return -ENODEV;
|
||||
if (driver != udc->driver || !driver->unbind)
|
||||
return -EINVAL;
|
||||
|
||||
if (gpio_is_valid(udc->vbus_pin))
|
||||
disable_irq(gpio_to_irq(udc->vbus_pin));
|
||||
|
||||
|
@ -1871,10 +1847,6 @@ static int atmel_usba_stop(struct usb_gadget_driver *driver)
|
|||
toggle_bias(0);
|
||||
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
|
||||
|
||||
if (udc->driver->disconnect)
|
||||
udc->driver->disconnect(&udc->gadget);
|
||||
|
||||
driver->unbind(&udc->gadget);
|
||||
udc->gadget.dev.driver = NULL;
|
||||
udc->driver = NULL;
|
||||
|
||||
|
|
|
@ -280,7 +280,6 @@ struct usba_ep {
|
|||
struct usba_udc *udc;
|
||||
|
||||
struct list_head queue;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
|
||||
u16 fifo_size;
|
||||
u8 nr_banks;
|
||||
|
|
|
@ -148,27 +148,7 @@ static struct pci_driver ci13xxx_pci_driver = {
|
|||
.remove = __devexit_p(ci13xxx_pci_remove),
|
||||
};
|
||||
|
||||
/**
|
||||
* ci13xxx_pci_init: module init
|
||||
*
|
||||
* Driver load
|
||||
*/
|
||||
static int __init ci13xxx_pci_init(void)
|
||||
{
|
||||
return pci_register_driver(&ci13xxx_pci_driver);
|
||||
}
|
||||
module_init(ci13xxx_pci_init);
|
||||
|
||||
/**
|
||||
* ci13xxx_pci_exit: module exit
|
||||
*
|
||||
* Driver unload
|
||||
*/
|
||||
static void __exit ci13xxx_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ci13xxx_pci_driver);
|
||||
}
|
||||
module_exit(ci13xxx_pci_exit);
|
||||
module_pci_driver(ci13xxx_pci_driver);
|
||||
|
||||
MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
|
||||
MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
|
||||
|
|
|
@ -1916,7 +1916,7 @@ __acquires(udc->lock)
|
|||
int type, num, dir, err = -EINVAL;
|
||||
struct usb_ctrlrequest req;
|
||||
|
||||
if (mEp->desc == NULL)
|
||||
if (mEp->ep.desc == NULL)
|
||||
continue; /* not configured */
|
||||
|
||||
if (hw_test_and_clear_complete(i)) {
|
||||
|
@ -2112,7 +2112,7 @@ static int ep_enable(struct usb_ep *ep,
|
|||
|
||||
/* only internal SW should enable ctrl endpts */
|
||||
|
||||
mEp->desc = desc;
|
||||
mEp->ep.desc = desc;
|
||||
|
||||
if (!list_empty(&mEp->qh.queue))
|
||||
warn("enabling a non-empty endpoint!");
|
||||
|
@ -2164,7 +2164,7 @@ static int ep_disable(struct usb_ep *ep)
|
|||
|
||||
if (ep == NULL)
|
||||
return -EINVAL;
|
||||
else if (mEp->desc == NULL)
|
||||
else if (mEp->ep.desc == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock_irqsave(mEp->lock, flags);
|
||||
|
@ -2183,7 +2183,6 @@ static int ep_disable(struct usb_ep *ep)
|
|||
|
||||
} while (mEp->dir != direction);
|
||||
|
||||
mEp->desc = NULL;
|
||||
mEp->ep.desc = NULL;
|
||||
|
||||
spin_unlock_irqrestore(mEp->lock, flags);
|
||||
|
@ -2272,7 +2271,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
|
|||
|
||||
trace("%p, %p, %X", ep, req, gfp_flags);
|
||||
|
||||
if (ep == NULL || req == NULL || mEp->desc == NULL)
|
||||
if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(mEp->lock, flags);
|
||||
|
@ -2335,7 +2334,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
|||
trace("%p, %p", ep, req);
|
||||
|
||||
if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
|
||||
mEp->desc == NULL || list_empty(&mReq->queue) ||
|
||||
mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
|
||||
list_empty(&mEp->qh.queue))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2378,7 +2377,7 @@ static int ep_set_halt(struct usb_ep *ep, int value)
|
|||
|
||||
trace("%p, %i", ep, value);
|
||||
|
||||
if (ep == NULL || mEp->desc == NULL)
|
||||
if (ep == NULL || mEp->ep.desc == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(mEp->lock, flags);
|
||||
|
@ -2421,7 +2420,7 @@ static int ep_set_wedge(struct usb_ep *ep)
|
|||
|
||||
trace("%p", ep);
|
||||
|
||||
if (ep == NULL || mEp->desc == NULL)
|
||||
if (ep == NULL || mEp->ep.desc == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(mEp->lock, flags);
|
||||
|
|
|
@ -82,7 +82,6 @@ struct ci13xxx_req {
|
|||
/* Extension of usb_ep */
|
||||
struct ci13xxx_ep {
|
||||
struct usb_ep ep;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
u8 dir;
|
||||
u8 num;
|
||||
u8 type;
|
||||
|
|
|
@ -737,6 +737,19 @@ int usb_add_config(struct usb_composite_dev *cdev,
|
|||
|
||||
status = bind(config);
|
||||
if (status < 0) {
|
||||
while (!list_empty(&config->functions)) {
|
||||
struct usb_function *f;
|
||||
|
||||
f = list_first_entry(&config->functions,
|
||||
struct usb_function, list);
|
||||
list_del(&f->list);
|
||||
if (f->unbind) {
|
||||
DBG(cdev, "unbind function '%s'/%p\n",
|
||||
f->name, f);
|
||||
f->unbind(config, f);
|
||||
/* may free memory for "f" */
|
||||
}
|
||||
}
|
||||
list_del(&config->list);
|
||||
config->cdev = NULL;
|
||||
} else {
|
||||
|
@ -785,7 +798,7 @@ done:
|
|||
static void collect_langs(struct usb_gadget_strings **sp, __le16 *buf)
|
||||
{
|
||||
const struct usb_gadget_strings *s;
|
||||
u16 language;
|
||||
__le16 language;
|
||||
__le16 *tmp;
|
||||
|
||||
while (*sp) {
|
||||
|
|
|
@ -595,14 +595,12 @@ static struct usb_request *dummy_alloc_request(struct usb_ep *_ep,
|
|||
|
||||
static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
||||
{
|
||||
struct dummy_ep *ep;
|
||||
struct dummy_request *req;
|
||||
|
||||
if (!_ep || !_req)
|
||||
return;
|
||||
ep = usb_ep_to_dummy_ep(_ep);
|
||||
if (!ep->desc && _ep->name != ep0name)
|
||||
if (!_ep || !_req) {
|
||||
__WARN();
|
||||
return;
|
||||
}
|
||||
|
||||
req = usb_request_to_dummy_request(_req);
|
||||
WARN_ON(!list_empty(&req->queue));
|
||||
|
|
|
@ -1473,8 +1473,22 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev,
|
|||
|
||||
static void ffs_func_free(struct ffs_function *func)
|
||||
{
|
||||
struct ffs_ep *ep = func->eps;
|
||||
unsigned count = func->ffs->eps_count;
|
||||
unsigned long flags;
|
||||
|
||||
ENTER();
|
||||
|
||||
/* cleanup after autoconfig */
|
||||
spin_lock_irqsave(&func->ffs->eps_lock, flags);
|
||||
do {
|
||||
if (ep->ep && ep->req)
|
||||
usb_ep_free_request(ep->ep, ep->req);
|
||||
ep->req = NULL;
|
||||
++ep;
|
||||
} while (--count);
|
||||
spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
|
||||
|
||||
ffs_data_put(func->ffs);
|
||||
|
||||
kfree(func->eps);
|
||||
|
|
|
@ -286,7 +286,7 @@ static void disable_loopback(struct f_loopback *loop)
|
|||
struct usb_composite_dev *cdev;
|
||||
|
||||
cdev = loop->function.config->cdev;
|
||||
disable_endpoints(cdev, loop->in_ep, loop->out_ep);
|
||||
disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
|
||||
VDBG(cdev, "%s disabled\n", loop->function.name);
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ fail0:
|
|||
* than 'buflen' bytes each.
|
||||
*/
|
||||
for (i = 0; i < qlen && result == 0; i++) {
|
||||
req = alloc_ep_req(ep);
|
||||
req = alloc_ep_req(ep, 0);
|
||||
if (req) {
|
||||
req->complete = loopback_complete;
|
||||
result = usb_ep_queue(ep, req, GFP_ATOMIC);
|
||||
|
|
|
@ -3110,13 +3110,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static inline int __deprecated __maybe_unused
|
||||
fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c,
|
||||
struct fsg_common *common)
|
||||
{
|
||||
return fsg_bind_config(cdev, c, common);
|
||||
}
|
||||
|
||||
|
||||
/************************* Module parameters *************************/
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ struct f_sourcesink {
|
|||
|
||||
struct usb_ep *in_ep;
|
||||
struct usb_ep *out_ep;
|
||||
struct usb_ep *iso_in_ep;
|
||||
struct usb_ep *iso_out_ep;
|
||||
int cur_alt;
|
||||
};
|
||||
|
||||
static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
|
||||
|
@ -59,18 +62,45 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
|
|||
}
|
||||
|
||||
static unsigned pattern;
|
||||
module_param(pattern, uint, 0);
|
||||
MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
|
||||
module_param(pattern, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none");
|
||||
|
||||
static unsigned isoc_interval = 4;
|
||||
module_param(isoc_interval, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(isoc_interval, "1 - 16");
|
||||
|
||||
static unsigned isoc_maxpacket = 1024;
|
||||
module_param(isoc_maxpacket, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
|
||||
|
||||
static unsigned isoc_mult;
|
||||
module_param(isoc_mult, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)");
|
||||
|
||||
static unsigned isoc_maxburst;
|
||||
module_param(isoc_maxburst, uint, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct usb_interface_descriptor source_sink_intf = {
|
||||
.bLength = sizeof source_sink_intf,
|
||||
static struct usb_interface_descriptor source_sink_intf_alt0 = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
|
||||
/* .iInterface = DYNAMIC */
|
||||
/* .iInterface = DYNAMIC */
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor source_sink_intf_alt1 = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
||||
.bAlternateSetting = 1,
|
||||
.bNumEndpoints = 4,
|
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
|
||||
/* .iInterface = DYNAMIC */
|
||||
};
|
||||
|
||||
/* full speed support: */
|
||||
|
@ -91,10 +121,36 @@ static struct usb_endpoint_descriptor fs_sink_desc = {
|
|||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor fs_iso_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor fs_iso_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &fs_sink_desc,
|
||||
(struct usb_descriptor_header *) &fs_source_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt1,
|
||||
#define FS_ALT_IFC_1_OFFSET 3
|
||||
(struct usb_descriptor_header *) &fs_sink_desc,
|
||||
(struct usb_descriptor_header *) &fs_source_desc,
|
||||
(struct usb_descriptor_header *) &fs_iso_sink_desc,
|
||||
(struct usb_descriptor_header *) &fs_iso_source_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -116,10 +172,34 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
|
|||
.wMaxPacketSize = cpu_to_le16(512),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_iso_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_iso_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &hs_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_sink_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt1,
|
||||
#define HS_ALT_IFC_1_OFFSET 3
|
||||
(struct usb_descriptor_header *) &hs_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_sink_desc,
|
||||
(struct usb_descriptor_header *) &hs_iso_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_iso_sink_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -136,6 +216,7 @@ static struct usb_endpoint_descriptor ss_source_desc = {
|
|||
struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = 0,
|
||||
|
@ -152,17 +233,64 @@ static struct usb_endpoint_descriptor ss_sink_desc = {
|
|||
struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = 0,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ss_iso_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ss_iso_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &ss_source_desc,
|
||||
(struct usb_descriptor_header *) &ss_source_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_sink_desc,
|
||||
(struct usb_descriptor_header *) &ss_sink_comp_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt1,
|
||||
#define SS_ALT_IFC_1_OFFSET 5
|
||||
(struct usb_descriptor_header *) &ss_source_desc,
|
||||
(struct usb_descriptor_header *) &ss_source_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_sink_desc,
|
||||
(struct usb_descriptor_header *) &ss_sink_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_source_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_sink_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -196,9 +324,10 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
id = usb_interface_id(c, f);
|
||||
if (id < 0)
|
||||
return id;
|
||||
source_sink_intf.bInterfaceNumber = id;
|
||||
source_sink_intf_alt0.bInterfaceNumber = id;
|
||||
source_sink_intf_alt1.bInterfaceNumber = id;
|
||||
|
||||
/* allocate endpoints */
|
||||
/* allocate bulk endpoints */
|
||||
ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
|
||||
if (!ss->in_ep) {
|
||||
autoconf_fail:
|
||||
|
@ -213,12 +342,74 @@ autoconf_fail:
|
|||
goto autoconf_fail;
|
||||
ss->out_ep->driver_data = cdev; /* claim */
|
||||
|
||||
/* sanity check the isoc module parameters */
|
||||
if (isoc_interval < 1)
|
||||
isoc_interval = 1;
|
||||
if (isoc_interval > 16)
|
||||
isoc_interval = 16;
|
||||
if (isoc_mult > 2)
|
||||
isoc_mult = 2;
|
||||
if (isoc_maxburst > 15)
|
||||
isoc_maxburst = 15;
|
||||
|
||||
/* fill in the FS isoc descriptors from the module parameters */
|
||||
fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
|
||||
1023 : isoc_maxpacket;
|
||||
fs_iso_source_desc.bInterval = isoc_interval;
|
||||
fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
|
||||
1023 : isoc_maxpacket;
|
||||
fs_iso_sink_desc.bInterval = isoc_interval;
|
||||
|
||||
/* allocate iso endpoints */
|
||||
ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
|
||||
if (!ss->iso_in_ep)
|
||||
goto no_iso;
|
||||
ss->iso_in_ep->driver_data = cdev; /* claim */
|
||||
|
||||
ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
|
||||
if (ss->iso_out_ep) {
|
||||
ss->iso_out_ep->driver_data = cdev; /* claim */
|
||||
} else {
|
||||
ss->iso_in_ep->driver_data = NULL;
|
||||
ss->iso_in_ep = NULL;
|
||||
no_iso:
|
||||
/*
|
||||
* We still want to work even if the UDC doesn't have isoc
|
||||
* endpoints, so null out the alt interface that contains
|
||||
* them and continue.
|
||||
*/
|
||||
fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
|
||||
hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
|
||||
ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
|
||||
}
|
||||
|
||||
if (isoc_maxpacket > 1024)
|
||||
isoc_maxpacket = 1024;
|
||||
|
||||
/* support high speed hardware */
|
||||
if (gadget_is_dualspeed(c->cdev->gadget)) {
|
||||
hs_source_desc.bEndpointAddress =
|
||||
fs_source_desc.bEndpointAddress;
|
||||
hs_sink_desc.bEndpointAddress =
|
||||
fs_sink_desc.bEndpointAddress;
|
||||
|
||||
/*
|
||||
* Fill in the HS isoc descriptors from the module parameters.
|
||||
* We assume that the user knows what they are doing and won't
|
||||
* give parameters that their UDC doesn't support.
|
||||
*/
|
||||
hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
|
||||
hs_iso_source_desc.bInterval = isoc_interval;
|
||||
hs_iso_source_desc.bEndpointAddress =
|
||||
fs_iso_source_desc.bEndpointAddress;
|
||||
|
||||
hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
|
||||
hs_iso_sink_desc.bInterval = isoc_interval;
|
||||
hs_iso_sink_desc.bEndpointAddress =
|
||||
fs_iso_sink_desc.bEndpointAddress;
|
||||
|
||||
f->hs_descriptors = hs_source_sink_descs;
|
||||
}
|
||||
|
||||
|
@ -228,13 +419,39 @@ autoconf_fail:
|
|||
fs_source_desc.bEndpointAddress;
|
||||
ss_sink_desc.bEndpointAddress =
|
||||
fs_sink_desc.bEndpointAddress;
|
||||
|
||||
/*
|
||||
* Fill in the SS isoc descriptors from the module parameters.
|
||||
* We assume that the user knows what they are doing and won't
|
||||
* give parameters that their UDC doesn't support.
|
||||
*/
|
||||
ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
ss_iso_source_desc.bInterval = isoc_interval;
|
||||
ss_iso_source_comp_desc.bmAttributes = isoc_mult;
|
||||
ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
|
||||
ss_iso_source_comp_desc.wBytesPerInterval =
|
||||
isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
|
||||
ss_iso_source_desc.bEndpointAddress =
|
||||
fs_iso_source_desc.bEndpointAddress;
|
||||
|
||||
ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
ss_iso_sink_desc.bInterval = isoc_interval;
|
||||
ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
|
||||
ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
|
||||
ss_iso_sink_comp_desc.wBytesPerInterval =
|
||||
isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
|
||||
ss_iso_sink_desc.bEndpointAddress =
|
||||
fs_iso_sink_desc.bEndpointAddress;
|
||||
|
||||
f->ss_descriptors = ss_source_sink_descs;
|
||||
}
|
||||
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
|
||||
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
||||
(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
|
||||
f->name, ss->in_ep->name, ss->out_ep->name);
|
||||
f->name, ss->in_ep->name, ss->out_ep->name,
|
||||
ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
|
||||
ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -251,6 +468,9 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
|
|||
u8 *buf = req->buf;
|
||||
struct usb_composite_dev *cdev = ss->function.config->cdev;
|
||||
|
||||
if (pattern == 2)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < req->actual; i++, buf++) {
|
||||
switch (pattern) {
|
||||
|
||||
|
@ -265,7 +485,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
|
|||
* each usb transfer request should be. Resync is done
|
||||
* with set_interface or set_config. (We *WANT* it to
|
||||
* get quickly out of sync if controllers or their drivers
|
||||
* stutter for any reason, including buffer duplcation...)
|
||||
* stutter for any reason, including buffer duplication...)
|
||||
*/
|
||||
case 1:
|
||||
if (*buf == (u8)(i % 63))
|
||||
|
@ -292,21 +512,30 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
|
|||
for (i = 0; i < req->length; i++)
|
||||
*buf++ = (u8) (i % 63);
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
struct f_sourcesink *ss = ep->driver_data;
|
||||
struct usb_composite_dev *cdev = ss->function.config->cdev;
|
||||
int status = req->status;
|
||||
struct usb_composite_dev *cdev;
|
||||
struct f_sourcesink *ss = ep->driver_data;
|
||||
int status = req->status;
|
||||
|
||||
/* driver_data will be null if ep has been disabled */
|
||||
if (!ss)
|
||||
return;
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
|
||||
switch (status) {
|
||||
|
||||
case 0: /* normal completion? */
|
||||
if (ep == ss->out_ep) {
|
||||
check_read_data(ss, req);
|
||||
memset(req->buf, 0x55, req->length);
|
||||
if (pattern != 2)
|
||||
memset(req->buf, 0x55, req->length);
|
||||
} else
|
||||
reinit_write_data(ep, req);
|
||||
break;
|
||||
|
@ -344,32 +573,57 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
}
|
||||
}
|
||||
|
||||
static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in)
|
||||
static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
|
||||
bool is_iso, int speed)
|
||||
{
|
||||
struct usb_ep *ep;
|
||||
struct usb_request *req;
|
||||
int status;
|
||||
int i, size, status;
|
||||
|
||||
ep = is_in ? ss->in_ep : ss->out_ep;
|
||||
req = alloc_ep_req(ep);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (is_iso) {
|
||||
switch (speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
size = isoc_maxpacket * (isoc_mult + 1) *
|
||||
(isoc_maxburst + 1);
|
||||
break;
|
||||
case USB_SPEED_HIGH:
|
||||
size = isoc_maxpacket * (isoc_mult + 1);
|
||||
break;
|
||||
default:
|
||||
size = isoc_maxpacket > 1023 ?
|
||||
1023 : isoc_maxpacket;
|
||||
break;
|
||||
}
|
||||
ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
|
||||
req = alloc_ep_req(ep, size);
|
||||
} else {
|
||||
ep = is_in ? ss->in_ep : ss->out_ep;
|
||||
req = alloc_ep_req(ep, 0);
|
||||
}
|
||||
|
||||
req->complete = source_sink_complete;
|
||||
if (is_in)
|
||||
reinit_write_data(ep, req);
|
||||
else
|
||||
memset(req->buf, 0x55, req->length);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
status = usb_ep_queue(ep, req, GFP_ATOMIC);
|
||||
if (status) {
|
||||
struct usb_composite_dev *cdev;
|
||||
req->complete = source_sink_complete;
|
||||
if (is_in)
|
||||
reinit_write_data(ep, req);
|
||||
else if (pattern != 2)
|
||||
memset(req->buf, 0x55, req->length);
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
ERROR(cdev, "start %s %s --> %d\n",
|
||||
is_in ? "IN" : "OUT",
|
||||
ep->name, status);
|
||||
free_ep_req(ep, req);
|
||||
status = usb_ep_queue(ep, req, GFP_ATOMIC);
|
||||
if (status) {
|
||||
struct usb_composite_dev *cdev;
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
ERROR(cdev, "start %s%s %s --> %d\n",
|
||||
is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
|
||||
ep->name, status);
|
||||
free_ep_req(ep, req);
|
||||
}
|
||||
|
||||
if (!is_iso)
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -380,17 +634,20 @@ static void disable_source_sink(struct f_sourcesink *ss)
|
|||
struct usb_composite_dev *cdev;
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
disable_endpoints(cdev, ss->in_ep, ss->out_ep);
|
||||
disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
|
||||
ss->iso_out_ep);
|
||||
VDBG(cdev, "%s disabled\n", ss->function.name);
|
||||
}
|
||||
|
||||
static int
|
||||
enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
|
||||
enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
|
||||
int alt)
|
||||
{
|
||||
int result = 0;
|
||||
int speed = cdev->gadget->speed;
|
||||
struct usb_ep *ep;
|
||||
|
||||
/* one endpoint writes (sources) zeroes IN (to the host) */
|
||||
/* one bulk endpoint writes (sources) zeroes IN (to the host) */
|
||||
ep = ss->in_ep;
|
||||
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
|
||||
if (result)
|
||||
|
@ -400,7 +657,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
|
|||
return result;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, true);
|
||||
result = source_sink_start_ep(ss, true, false, speed);
|
||||
if (result < 0) {
|
||||
fail:
|
||||
ep = ss->in_ep;
|
||||
|
@ -409,7 +666,7 @@ fail:
|
|||
return result;
|
||||
}
|
||||
|
||||
/* one endpoint reads (sinks) anything OUT (from the host) */
|
||||
/* one bulk endpoint reads (sinks) anything OUT (from the host) */
|
||||
ep = ss->out_ep;
|
||||
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
|
||||
if (result)
|
||||
|
@ -419,27 +676,82 @@ fail:
|
|||
goto fail;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, false);
|
||||
result = source_sink_start_ep(ss, false, false, speed);
|
||||
if (result < 0) {
|
||||
fail2:
|
||||
ep = ss->out_ep;
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DBG(cdev, "%s enabled\n", ss->function.name);
|
||||
if (alt == 0)
|
||||
goto out;
|
||||
|
||||
/* one iso endpoint writes (sources) zeroes IN (to the host) */
|
||||
ep = ss->iso_in_ep;
|
||||
if (ep) {
|
||||
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
|
||||
if (result)
|
||||
goto fail2;
|
||||
result = usb_ep_enable(ep);
|
||||
if (result < 0)
|
||||
goto fail2;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, true, true, speed);
|
||||
if (result < 0) {
|
||||
fail3:
|
||||
ep = ss->iso_in_ep;
|
||||
if (ep) {
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
}
|
||||
goto fail2;
|
||||
}
|
||||
}
|
||||
|
||||
/* one iso endpoint reads (sinks) anything OUT (from the host) */
|
||||
ep = ss->iso_out_ep;
|
||||
if (ep) {
|
||||
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
|
||||
if (result)
|
||||
goto fail3;
|
||||
result = usb_ep_enable(ep);
|
||||
if (result < 0)
|
||||
goto fail3;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, false, true, speed);
|
||||
if (result < 0) {
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
goto fail3;
|
||||
}
|
||||
}
|
||||
out:
|
||||
ss->cur_alt = alt;
|
||||
|
||||
DBG(cdev, "%s enabled, alt intf %d\n", ss->function.name, alt);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sourcesink_set_alt(struct usb_function *f,
|
||||
unsigned intf, unsigned alt)
|
||||
{
|
||||
struct f_sourcesink *ss = func_to_ss(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
struct f_sourcesink *ss = func_to_ss(f);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
|
||||
/* we know alt is zero */
|
||||
if (ss->in_ep->driver_data)
|
||||
disable_source_sink(ss);
|
||||
return enable_source_sink(cdev, ss);
|
||||
return enable_source_sink(cdev, ss, alt);
|
||||
}
|
||||
|
||||
static int sourcesink_get_alt(struct usb_function *f, unsigned intf)
|
||||
{
|
||||
struct f_sourcesink *ss = func_to_ss(f);
|
||||
|
||||
return ss->cur_alt;
|
||||
}
|
||||
|
||||
static void sourcesink_disable(struct usb_function *f)
|
||||
|
@ -465,6 +777,7 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
|
|||
ss->function.bind = sourcesink_bind;
|
||||
ss->function.unbind = sourcesink_unbind;
|
||||
ss->function.set_alt = sourcesink_set_alt;
|
||||
ss->function.get_alt = sourcesink_get_alt;
|
||||
ss->function.disable = sourcesink_disable;
|
||||
|
||||
status = usb_add_function(c, &ss->function);
|
||||
|
@ -536,7 +849,7 @@ unknown:
|
|||
req->length = value;
|
||||
value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
|
||||
if (value < 0)
|
||||
ERROR(c->cdev, "source/sinkc response, err %d\n",
|
||||
ERROR(c->cdev, "source/sink response, err %d\n",
|
||||
value);
|
||||
}
|
||||
|
||||
|
@ -545,12 +858,12 @@ unknown:
|
|||
}
|
||||
|
||||
static struct usb_configuration sourcesink_driver = {
|
||||
.label = "source/sink",
|
||||
.strings = sourcesink_strings,
|
||||
.setup = sourcesink_setup,
|
||||
.bConfigurationValue = 3,
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
.label = "source/sink",
|
||||
.strings = sourcesink_strings,
|
||||
.setup = sourcesink_setup,
|
||||
.bConfigurationValue = 3,
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
/* .iConfiguration = DYNAMIC */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -567,7 +880,8 @@ int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
|
|||
return id;
|
||||
strings_sourcesink[0].id = id;
|
||||
|
||||
source_sink_intf.iInterface = id;
|
||||
source_sink_intf_alt0.iInterface = id;
|
||||
source_sink_intf_alt1.iInterface = id;
|
||||
sourcesink_driver.iConfiguration = id;
|
||||
|
||||
/* support autoresume for remote wakeup testing */
|
||||
|
|
|
@ -71,9 +71,6 @@ static struct usb_endpoint_descriptor qe_ep0_desc = {
|
|||
.wMaxPacketSize = USB_MAX_CTRL_PAYLOAD,
|
||||
};
|
||||
|
||||
/* it is initialized in probe() */
|
||||
static struct qe_udc *udc_controller;
|
||||
|
||||
/********************************************************************
|
||||
* Internal Used Function Start
|
||||
********************************************************************/
|
||||
|
@ -188,8 +185,8 @@ static int qe_ep0_stall(struct qe_udc *udc)
|
|||
{
|
||||
qe_eptx_stall_change(&udc->eps[0], 1);
|
||||
qe_eprx_stall_change(&udc->eps[0], 1);
|
||||
udc_controller->ep0_state = WAIT_FOR_SETUP;
|
||||
udc_controller->ep0_dir = 0;
|
||||
udc->ep0_state = WAIT_FOR_SETUP;
|
||||
udc->ep0_dir = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -450,13 +447,13 @@ static int qe_ep_rxbd_update(struct qe_ep *ep)
|
|||
|
||||
ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer);
|
||||
if (ep->rxbuf_d == DMA_ADDR_INVALID) {
|
||||
ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent,
|
||||
ep->rxbuf_d = dma_map_single(ep->udc->gadget.dev.parent,
|
||||
ep->rxbuffer,
|
||||
size,
|
||||
DMA_FROM_DEVICE);
|
||||
ep->rxbufmap = 1;
|
||||
} else {
|
||||
dma_sync_single_for_device(udc_controller->gadget.dev.parent,
|
||||
dma_sync_single_for_device(ep->udc->gadget.dev.parent,
|
||||
ep->rxbuf_d, size,
|
||||
DMA_FROM_DEVICE);
|
||||
ep->rxbufmap = 0;
|
||||
|
@ -489,10 +486,10 @@ static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num)
|
|||
epparam = udc->ep_param[pipe_num];
|
||||
|
||||
usep = 0;
|
||||
logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
|
||||
logepnum = (ep->ep.desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
|
||||
usep |= (logepnum << USB_EPNUM_SHIFT);
|
||||
|
||||
switch (ep->desc->bmAttributes & 0x03) {
|
||||
switch (ep->ep.desc->bmAttributes & 0x03) {
|
||||
case USB_ENDPOINT_XFER_BULK:
|
||||
usep |= USB_TRANS_BULK;
|
||||
break;
|
||||
|
@ -644,7 +641,7 @@ static int qe_ep_init(struct qe_udc *udc,
|
|||
/* initialize ep structure */
|
||||
ep->ep.maxpacket = max;
|
||||
ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->stopped = 0;
|
||||
ep->init = 1;
|
||||
|
||||
|
@ -698,14 +695,14 @@ en_done:
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void qe_usb_enable(void)
|
||||
static inline void qe_usb_enable(struct qe_udc *udc)
|
||||
{
|
||||
setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
|
||||
setbits8(&udc->usb_regs->usb_usmod, USB_MODE_EN);
|
||||
}
|
||||
|
||||
static inline void qe_usb_disable(void)
|
||||
static inline void qe_usb_disable(struct qe_udc *udc)
|
||||
{
|
||||
clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
|
||||
clrbits8(&udc->usb_regs->usb_usmod, USB_MODE_EN);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
|
@ -1599,7 +1596,7 @@ static int qe_ep_enable(struct usb_ep *_ep,
|
|||
ep = container_of(_ep, struct qe_ep, ep);
|
||||
|
||||
/* catch various bogus parameters */
|
||||
if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] ||
|
||||
if (!_ep || !desc || ep->ep.desc || _ep->name == ep_name[0] ||
|
||||
(desc->bDescriptorType != USB_DT_ENDPOINT))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1629,7 +1626,7 @@ static int qe_ep_disable(struct usb_ep *_ep)
|
|||
ep = container_of(_ep, struct qe_ep, ep);
|
||||
udc = ep->udc;
|
||||
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1637,7 +1634,6 @@ static int qe_ep_disable(struct usb_ep *_ep)
|
|||
spin_lock_irqsave(&udc->lock, flags);
|
||||
/* Nuke all pending requests (does flush) */
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
ep->tx_req = NULL;
|
||||
|
@ -1656,13 +1652,13 @@ static int qe_ep_disable(struct usb_ep *_ep)
|
|||
if (ep->dir != USB_DIR_IN) {
|
||||
kfree(ep->rxframe);
|
||||
if (ep->rxbufmap) {
|
||||
dma_unmap_single(udc_controller->gadget.dev.parent,
|
||||
dma_unmap_single(udc->gadget.dev.parent,
|
||||
ep->rxbuf_d, size,
|
||||
DMA_FROM_DEVICE);
|
||||
ep->rxbuf_d = DMA_ADDR_INVALID;
|
||||
} else {
|
||||
dma_sync_single_for_cpu(
|
||||
udc_controller->gadget.dev.parent,
|
||||
udc->gadget.dev.parent,
|
||||
ep->rxbuf_d, size,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
|
@ -1715,7 +1711,7 @@ static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
|
|||
dev_dbg(udc->dev, "bad params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!_ep || (!ep->desc && ep_index(ep))) {
|
||||
if (!_ep || (!ep->ep.desc && ep_index(ep))) {
|
||||
dev_dbg(udc->dev, "bad ep\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1826,7 +1822,7 @@ static int qe_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
struct qe_udc *udc;
|
||||
|
||||
ep = container_of(_ep, struct qe_ep, ep);
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1880,9 +1876,10 @@ static struct usb_ep_ops qe_ep_ops = {
|
|||
/* Get the current frame number */
|
||||
static int qe_get_frame(struct usb_gadget *gadget)
|
||||
{
|
||||
struct qe_udc *udc = container_of(gadget, struct qe_udc, gadget);
|
||||
u16 tmp;
|
||||
|
||||
tmp = in_be16(&udc_controller->usb_param->frame_n);
|
||||
tmp = in_be16(&udc->usb_param->frame_n);
|
||||
if (tmp & 0x8000)
|
||||
tmp = tmp & 0x07ff;
|
||||
else
|
||||
|
@ -1891,57 +1888,16 @@ static int qe_get_frame(struct usb_gadget *gadget)
|
|||
return (int)tmp;
|
||||
}
|
||||
|
||||
/* Tries to wake up the host connected to this gadget
|
||||
*
|
||||
* Return : 0-success
|
||||
* Negative-this feature not enabled by host or not supported by device hw
|
||||
*/
|
||||
static int qe_wakeup(struct usb_gadget *gadget)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* Notify controller that VBUS is powered, Called by whatever
|
||||
detects VBUS sessions */
|
||||
static int qe_vbus_session(struct usb_gadget *gadget, int is_active)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* constrain controller's VBUS power usage
|
||||
* This call is used by gadget drivers during SET_CONFIGURATION calls,
|
||||
* reporting how much power the device may consume. For example, this
|
||||
* could affect how quickly batteries are recharged.
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*/
|
||||
static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* Change Data+ pullup status
|
||||
* this func is used by usb_gadget_connect/disconnect
|
||||
*/
|
||||
static int qe_pullup(struct usb_gadget *gadget, int is_on)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int fsl_qe_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *));
|
||||
static int fsl_qe_stop(struct usb_gadget_driver *driver);
|
||||
static int fsl_qe_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static int fsl_qe_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
|
||||
/* defined in usb_gadget.h */
|
||||
static struct usb_gadget_ops qe_gadget_ops = {
|
||||
.get_frame = qe_get_frame,
|
||||
.wakeup = qe_wakeup,
|
||||
/* .set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */
|
||||
.vbus_session = qe_vbus_session,
|
||||
.vbus_draw = qe_vbus_draw,
|
||||
.pullup = qe_pullup,
|
||||
.start = fsl_qe_start,
|
||||
.stop = fsl_qe_stop,
|
||||
.udc_start = fsl_qe_start,
|
||||
.udc_stop = fsl_qe_stop,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -2015,7 +1971,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
|
|||
u16 usep;
|
||||
|
||||
/* stall if endpoint doesn't exist */
|
||||
if (!target_ep->desc)
|
||||
if (!target_ep->ep.desc)
|
||||
goto stall;
|
||||
|
||||
usep = in_be16(&udc->usb_regs->usb_usep[pipe]);
|
||||
|
@ -2190,7 +2146,7 @@ static int reset_irq(struct qe_udc *udc)
|
|||
if (udc->usb_state == USB_STATE_DEFAULT)
|
||||
return 0;
|
||||
|
||||
qe_usb_disable();
|
||||
qe_usb_disable(udc);
|
||||
out_8(&udc->usb_regs->usb_usadr, 0);
|
||||
|
||||
for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
|
||||
|
@ -2202,7 +2158,7 @@ static int reset_irq(struct qe_udc *udc)
|
|||
udc->usb_state = USB_STATE_DEFAULT;
|
||||
udc->ep0_state = WAIT_FOR_SETUP;
|
||||
udc->ep0_dir = USB_DIR_OUT;
|
||||
qe_usb_enable();
|
||||
qe_usb_enable(udc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2327,92 +2283,65 @@ static irqreturn_t qe_udc_irq(int irq, void *_udc)
|
|||
/*-------------------------------------------------------------------------
|
||||
Gadget driver probe and unregister.
|
||||
--------------------------------------------------------------------------*/
|
||||
static int fsl_qe_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *))
|
||||
static int fsl_qe_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
int retval;
|
||||
unsigned long flags = 0;
|
||||
|
||||
/* standard operations */
|
||||
if (!udc_controller)
|
||||
return -ENODEV;
|
||||
|
||||
if (!driver || driver->max_speed < USB_SPEED_FULL
|
||||
|| !bind || !driver->disconnect || !driver->setup)
|
||||
return -EINVAL;
|
||||
|
||||
if (udc_controller->driver)
|
||||
return -EBUSY;
|
||||
struct qe_udc *udc;
|
||||
unsigned long flags;
|
||||
|
||||
udc = container_of(gadget, struct qe_udc, gadget);
|
||||
/* lock is needed but whether should use this lock or another */
|
||||
spin_lock_irqsave(&udc_controller->lock, flags);
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
|
||||
driver->driver.bus = NULL;
|
||||
/* hook up the driver */
|
||||
udc_controller->driver = driver;
|
||||
udc_controller->gadget.dev.driver = &driver->driver;
|
||||
udc_controller->gadget.speed = driver->max_speed;
|
||||
spin_unlock_irqrestore(&udc_controller->lock, flags);
|
||||
|
||||
retval = bind(&udc_controller->gadget);
|
||||
if (retval) {
|
||||
dev_err(udc_controller->dev, "bind to %s --> %d",
|
||||
driver->driver.name, retval);
|
||||
udc_controller->gadget.dev.driver = NULL;
|
||||
udc_controller->driver = NULL;
|
||||
return retval;
|
||||
}
|
||||
udc->driver = driver;
|
||||
udc->gadget.dev.driver = &driver->driver;
|
||||
udc->gadget.speed = driver->max_speed;
|
||||
|
||||
/* Enable IRQ reg and Set usbcmd reg EN bit */
|
||||
qe_usb_enable();
|
||||
qe_usb_enable(udc);
|
||||
|
||||
out_be16(&udc_controller->usb_regs->usb_usber, 0xffff);
|
||||
out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
|
||||
udc_controller->usb_state = USB_STATE_ATTACHED;
|
||||
udc_controller->ep0_state = WAIT_FOR_SETUP;
|
||||
udc_controller->ep0_dir = USB_DIR_OUT;
|
||||
dev_info(udc_controller->dev, "%s bind to driver %s \n",
|
||||
udc_controller->gadget.name, driver->driver.name);
|
||||
out_be16(&udc->usb_regs->usb_usber, 0xffff);
|
||||
out_be16(&udc->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
|
||||
udc->usb_state = USB_STATE_ATTACHED;
|
||||
udc->ep0_state = WAIT_FOR_SETUP;
|
||||
udc->ep0_dir = USB_DIR_OUT;
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
dev_info(udc->dev, "%s bind to driver %s\n", udc->gadget.name,
|
||||
driver->driver.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_qe_stop(struct usb_gadget_driver *driver)
|
||||
static int fsl_qe_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct qe_udc *udc;
|
||||
struct qe_ep *loop_ep;
|
||||
unsigned long flags;
|
||||
|
||||
if (!udc_controller)
|
||||
return -ENODEV;
|
||||
|
||||
if (!driver || driver != udc_controller->driver)
|
||||
return -EINVAL;
|
||||
|
||||
udc = container_of(gadget, struct qe_udc, gadget);
|
||||
/* stop usb controller, disable intr */
|
||||
qe_usb_disable();
|
||||
qe_usb_disable(udc);
|
||||
|
||||
/* in fact, no needed */
|
||||
udc_controller->usb_state = USB_STATE_ATTACHED;
|
||||
udc_controller->ep0_state = WAIT_FOR_SETUP;
|
||||
udc_controller->ep0_dir = 0;
|
||||
udc->usb_state = USB_STATE_ATTACHED;
|
||||
udc->ep0_state = WAIT_FOR_SETUP;
|
||||
udc->ep0_dir = 0;
|
||||
|
||||
/* stand operation */
|
||||
spin_lock_irqsave(&udc_controller->lock, flags);
|
||||
udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
nuke(&udc_controller->eps[0], -ESHUTDOWN);
|
||||
list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
|
||||
ep.ep_list)
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
nuke(&udc->eps[0], -ESHUTDOWN);
|
||||
list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list)
|
||||
nuke(loop_ep, -ESHUTDOWN);
|
||||
spin_unlock_irqrestore(&udc_controller->lock, flags);
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
||||
/* report disconnect; the controller is already quiesced */
|
||||
driver->disconnect(&udc_controller->gadget);
|
||||
udc->gadget.dev.driver = NULL;
|
||||
udc->driver = NULL;
|
||||
|
||||
/* unbind gadget and unhook driver. */
|
||||
driver->unbind(&udc_controller->gadget);
|
||||
udc_controller->gadget.dev.driver = NULL;
|
||||
udc_controller->driver = NULL;
|
||||
|
||||
dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n",
|
||||
dev_info(udc->dev, "unregistered gadget driver '%s'\r\n",
|
||||
driver->driver.name);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2502,7 +2431,7 @@ static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
|
|||
ep->ep.ops = &qe_ep_ops;
|
||||
ep->stopped = 1;
|
||||
ep->ep.maxpacket = (unsigned short) ~0;
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->dir = 0xff;
|
||||
ep->epnum = (u8)pipe_num;
|
||||
ep->sent = 0;
|
||||
|
@ -2531,21 +2460,22 @@ static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
|
|||
*----------------------------------------------------------------------*/
|
||||
static void qe_udc_release(struct device *dev)
|
||||
{
|
||||
int i = 0;
|
||||
struct qe_udc *udc = container_of(dev, struct qe_udc, gadget.dev);
|
||||
int i;
|
||||
|
||||
complete(udc_controller->done);
|
||||
cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0]));
|
||||
complete(udc->done);
|
||||
cpm_muram_free(cpm_muram_offset(udc->ep_param[0]));
|
||||
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
|
||||
udc_controller->ep_param[i] = NULL;
|
||||
udc->ep_param[i] = NULL;
|
||||
|
||||
kfree(udc_controller);
|
||||
udc_controller = NULL;
|
||||
kfree(udc);
|
||||
}
|
||||
|
||||
/* Driver probe functions */
|
||||
static const struct of_device_id qe_udc_match[];
|
||||
static int __devinit qe_udc_probe(struct platform_device *ofdev)
|
||||
{
|
||||
struct qe_udc *udc;
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
struct qe_ep *ep;
|
||||
|
@ -2562,44 +2492,44 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev)
|
|||
return -ENODEV;
|
||||
|
||||
/* Initialize the udc structure including QH member and other member */
|
||||
udc_controller = qe_udc_config(ofdev);
|
||||
if (!udc_controller) {
|
||||
udc = qe_udc_config(ofdev);
|
||||
if (!udc) {
|
||||
dev_err(&ofdev->dev, "failed to initialize\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
udc_controller->soc_type = (unsigned long)match->data;
|
||||
udc_controller->usb_regs = of_iomap(np, 0);
|
||||
if (!udc_controller->usb_regs) {
|
||||
udc->soc_type = (unsigned long)match->data;
|
||||
udc->usb_regs = of_iomap(np, 0);
|
||||
if (!udc->usb_regs) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
/* initialize usb hw reg except for regs for EP,
|
||||
* leave usbintr reg untouched*/
|
||||
qe_udc_reg_init(udc_controller);
|
||||
qe_udc_reg_init(udc);
|
||||
|
||||
/* here comes the stand operations for probe
|
||||
* set the qe_udc->gadget.xxx */
|
||||
udc_controller->gadget.ops = &qe_gadget_ops;
|
||||
udc->gadget.ops = &qe_gadget_ops;
|
||||
|
||||
/* gadget.ep0 is a pointer */
|
||||
udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
|
||||
udc->gadget.ep0 = &udc->eps[0].ep;
|
||||
|
||||
INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
|
||||
INIT_LIST_HEAD(&udc->gadget.ep_list);
|
||||
|
||||
/* modify in register gadget process */
|
||||
udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
udc->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
|
||||
/* name: Identifies the controller hardware type. */
|
||||
udc_controller->gadget.name = driver_name;
|
||||
udc->gadget.name = driver_name;
|
||||
|
||||
device_initialize(&udc_controller->gadget.dev);
|
||||
device_initialize(&udc->gadget.dev);
|
||||
|
||||
dev_set_name(&udc_controller->gadget.dev, "gadget");
|
||||
dev_set_name(&udc->gadget.dev, "gadget");
|
||||
|
||||
udc_controller->gadget.dev.release = qe_udc_release;
|
||||
udc_controller->gadget.dev.parent = &ofdev->dev;
|
||||
udc->gadget.dev.release = qe_udc_release;
|
||||
udc->gadget.dev.parent = &ofdev->dev;
|
||||
|
||||
/* initialize qe_ep struct */
|
||||
for (i = 0; i < USB_MAX_ENDPOINTS ; i++) {
|
||||
|
@ -2608,104 +2538,104 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev)
|
|||
|
||||
/* setup the qe_ep struct and link ep.ep.list
|
||||
* into gadget.ep_list */
|
||||
qe_ep_config(udc_controller, (unsigned char)i);
|
||||
qe_ep_config(udc, (unsigned char)i);
|
||||
}
|
||||
|
||||
/* ep0 initialization in here */
|
||||
ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc);
|
||||
ret = qe_ep_init(udc, 0, &qe_ep0_desc);
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
/* create a buf for ZLP send, need to remain zeroed */
|
||||
udc_controller->nullbuf = kzalloc(256, GFP_KERNEL);
|
||||
if (udc_controller->nullbuf == NULL) {
|
||||
dev_err(udc_controller->dev, "cannot alloc nullbuf\n");
|
||||
udc->nullbuf = kzalloc(256, GFP_KERNEL);
|
||||
if (udc->nullbuf == NULL) {
|
||||
dev_err(udc->dev, "cannot alloc nullbuf\n");
|
||||
ret = -ENOMEM;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
/* buffer for data of get_status request */
|
||||
udc_controller->statusbuf = kzalloc(2, GFP_KERNEL);
|
||||
if (udc_controller->statusbuf == NULL) {
|
||||
udc->statusbuf = kzalloc(2, GFP_KERNEL);
|
||||
if (udc->statusbuf == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err4;
|
||||
}
|
||||
|
||||
udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf);
|
||||
if (udc_controller->nullp == DMA_ADDR_INVALID) {
|
||||
udc_controller->nullp = dma_map_single(
|
||||
udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullbuf,
|
||||
udc->nullp = virt_to_phys((void *)udc->nullbuf);
|
||||
if (udc->nullp == DMA_ADDR_INVALID) {
|
||||
udc->nullp = dma_map_single(
|
||||
udc->gadget.dev.parent,
|
||||
udc->nullbuf,
|
||||
256,
|
||||
DMA_TO_DEVICE);
|
||||
udc_controller->nullmap = 1;
|
||||
udc->nullmap = 1;
|
||||
} else {
|
||||
dma_sync_single_for_device(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
dma_sync_single_for_device(udc->gadget.dev.parent,
|
||||
udc->nullp, 256,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet,
|
||||
(unsigned long)udc_controller);
|
||||
tasklet_init(&udc->rx_tasklet, ep_rx_tasklet,
|
||||
(unsigned long)udc);
|
||||
/* request irq and disable DR */
|
||||
udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
|
||||
if (!udc_controller->usb_irq) {
|
||||
udc->usb_irq = irq_of_parse_and_map(np, 0);
|
||||
if (!udc->usb_irq) {
|
||||
ret = -EINVAL;
|
||||
goto err_noirq;
|
||||
}
|
||||
|
||||
ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
|
||||
driver_name, udc_controller);
|
||||
ret = request_irq(udc->usb_irq, qe_udc_irq, 0,
|
||||
driver_name, udc);
|
||||
if (ret) {
|
||||
dev_err(udc_controller->dev, "cannot request irq %d err %d \n",
|
||||
udc_controller->usb_irq, ret);
|
||||
dev_err(udc->dev, "cannot request irq %d err %d\n",
|
||||
udc->usb_irq, ret);
|
||||
goto err5;
|
||||
}
|
||||
|
||||
ret = device_add(&udc_controller->gadget.dev);
|
||||
ret = device_add(&udc->gadget.dev);
|
||||
if (ret)
|
||||
goto err6;
|
||||
|
||||
ret = usb_add_gadget_udc(&ofdev->dev, &udc_controller->gadget);
|
||||
ret = usb_add_gadget_udc(&ofdev->dev, &udc->gadget);
|
||||
if (ret)
|
||||
goto err7;
|
||||
|
||||
dev_info(udc_controller->dev,
|
||||
dev_set_drvdata(&ofdev->dev, udc);
|
||||
dev_info(udc->dev,
|
||||
"%s USB controller initialized as device\n",
|
||||
(udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
|
||||
(udc->soc_type == PORT_QE) ? "QE" : "CPM");
|
||||
return 0;
|
||||
|
||||
err7:
|
||||
device_unregister(&udc_controller->gadget.dev);
|
||||
device_unregister(&udc->gadget.dev);
|
||||
err6:
|
||||
free_irq(udc_controller->usb_irq, udc_controller);
|
||||
free_irq(udc->usb_irq, udc);
|
||||
err5:
|
||||
irq_dispose_mapping(udc_controller->usb_irq);
|
||||
irq_dispose_mapping(udc->usb_irq);
|
||||
err_noirq:
|
||||
if (udc_controller->nullmap) {
|
||||
dma_unmap_single(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
if (udc->nullmap) {
|
||||
dma_unmap_single(udc->gadget.dev.parent,
|
||||
udc->nullp, 256,
|
||||
DMA_TO_DEVICE);
|
||||
udc_controller->nullp = DMA_ADDR_INVALID;
|
||||
udc->nullp = DMA_ADDR_INVALID;
|
||||
} else {
|
||||
dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
dma_sync_single_for_cpu(udc->gadget.dev.parent,
|
||||
udc->nullp, 256,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
kfree(udc_controller->statusbuf);
|
||||
kfree(udc->statusbuf);
|
||||
err4:
|
||||
kfree(udc_controller->nullbuf);
|
||||
kfree(udc->nullbuf);
|
||||
err3:
|
||||
ep = &udc_controller->eps[0];
|
||||
ep = &udc->eps[0];
|
||||
cpm_muram_free(cpm_muram_offset(ep->rxbase));
|
||||
kfree(ep->rxframe);
|
||||
kfree(ep->rxbuffer);
|
||||
kfree(ep->txframe);
|
||||
err2:
|
||||
iounmap(udc_controller->usb_regs);
|
||||
iounmap(udc->usb_regs);
|
||||
err1:
|
||||
kfree(udc_controller);
|
||||
udc_controller = NULL;
|
||||
kfree(udc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2723,44 +2653,41 @@ static int qe_udc_resume(struct platform_device *dev)
|
|||
|
||||
static int __devexit qe_udc_remove(struct platform_device *ofdev)
|
||||
{
|
||||
struct qe_udc *udc = dev_get_drvdata(&ofdev->dev);
|
||||
struct qe_ep *ep;
|
||||
unsigned int size;
|
||||
|
||||
DECLARE_COMPLETION(done);
|
||||
|
||||
if (!udc_controller)
|
||||
return -ENODEV;
|
||||
usb_del_gadget_udc(&udc->gadget);
|
||||
|
||||
usb_del_gadget_udc(&udc_controller->gadget);
|
||||
udc->done = &done;
|
||||
tasklet_disable(&udc->rx_tasklet);
|
||||
|
||||
udc_controller->done = &done;
|
||||
tasklet_disable(&udc_controller->rx_tasklet);
|
||||
|
||||
if (udc_controller->nullmap) {
|
||||
dma_unmap_single(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
if (udc->nullmap) {
|
||||
dma_unmap_single(udc->gadget.dev.parent,
|
||||
udc->nullp, 256,
|
||||
DMA_TO_DEVICE);
|
||||
udc_controller->nullp = DMA_ADDR_INVALID;
|
||||
udc->nullp = DMA_ADDR_INVALID;
|
||||
} else {
|
||||
dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
|
||||
udc_controller->nullp, 256,
|
||||
dma_sync_single_for_cpu(udc->gadget.dev.parent,
|
||||
udc->nullp, 256,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
kfree(udc_controller->statusbuf);
|
||||
kfree(udc_controller->nullbuf);
|
||||
kfree(udc->statusbuf);
|
||||
kfree(udc->nullbuf);
|
||||
|
||||
ep = &udc_controller->eps[0];
|
||||
ep = &udc->eps[0];
|
||||
cpm_muram_free(cpm_muram_offset(ep->rxbase));
|
||||
size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1);
|
||||
|
||||
kfree(ep->rxframe);
|
||||
if (ep->rxbufmap) {
|
||||
dma_unmap_single(udc_controller->gadget.dev.parent,
|
||||
dma_unmap_single(udc->gadget.dev.parent,
|
||||
ep->rxbuf_d, size,
|
||||
DMA_FROM_DEVICE);
|
||||
ep->rxbuf_d = DMA_ADDR_INVALID;
|
||||
} else {
|
||||
dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
|
||||
dma_sync_single_for_cpu(udc->gadget.dev.parent,
|
||||
ep->rxbuf_d, size,
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
|
@ -2768,14 +2695,14 @@ static int __devexit qe_udc_remove(struct platform_device *ofdev)
|
|||
kfree(ep->rxbuffer);
|
||||
kfree(ep->txframe);
|
||||
|
||||
free_irq(udc_controller->usb_irq, udc_controller);
|
||||
irq_dispose_mapping(udc_controller->usb_irq);
|
||||
free_irq(udc->usb_irq, udc);
|
||||
irq_dispose_mapping(udc->usb_irq);
|
||||
|
||||
tasklet_kill(&udc_controller->rx_tasklet);
|
||||
tasklet_kill(&udc->rx_tasklet);
|
||||
|
||||
iounmap(udc_controller->usb_regs);
|
||||
iounmap(udc->usb_regs);
|
||||
|
||||
device_unregister(&udc_controller->gadget.dev);
|
||||
device_unregister(&udc->gadget.dev);
|
||||
/* wait for release() of gadget.dev to free udc */
|
||||
wait_for_completion(&done);
|
||||
|
||||
|
|
|
@ -266,7 +266,6 @@ struct qe_ep {
|
|||
struct usb_ep ep;
|
||||
struct list_head queue;
|
||||
struct qe_udc *udc;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct usb_gadget *gadget;
|
||||
|
||||
u8 state;
|
||||
|
|
|
@ -567,7 +567,7 @@ static int fsl_ep_enable(struct usb_ep *_ep,
|
|||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
|
||||
/* catch various bogus parameters */
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| (desc->bDescriptorType != USB_DT_ENDPOINT))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -608,7 +608,7 @@ static int fsl_ep_enable(struct usb_ep *_ep,
|
|||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
ep->ep.maxpacket = max;
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->stopped = 0;
|
||||
|
||||
/* Controller related setup */
|
||||
|
@ -632,7 +632,7 @@ static int fsl_ep_enable(struct usb_ep *_ep,
|
|||
retval = 0;
|
||||
|
||||
VDBG("enabled %s (ep%d%s) maxpacket %d",ep->ep.name,
|
||||
ep->desc->bEndpointAddress & 0x0f,
|
||||
ep->ep.desc->bEndpointAddress & 0x0f,
|
||||
(desc->bEndpointAddress & USB_DIR_IN)
|
||||
? "in" : "out", max);
|
||||
en_done:
|
||||
|
@ -652,7 +652,7 @@ static int fsl_ep_disable(struct usb_ep *_ep)
|
|||
int ep_num;
|
||||
|
||||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
VDBG("%s not enabled", _ep ? ep->ep.name : NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -675,7 +675,6 @@ static int fsl_ep_disable(struct usb_ep *_ep)
|
|||
/* nuke all pending requests (does flush) */
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
spin_unlock_irqrestore(&udc->lock, flags);
|
||||
|
@ -754,6 +753,8 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
|
|||
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
|
||||
lastreq->tail->next_td_ptr =
|
||||
cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
|
||||
/* Ensure dTD's next dtd pointer to be updated */
|
||||
wmb();
|
||||
/* Read prime bit, if 1 goto done */
|
||||
if (fsl_readl(&dr_regs->endpointprime) & bitmask)
|
||||
return;
|
||||
|
@ -892,11 +893,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
VDBG("%s, bad params", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(!_ep || !ep->desc)) {
|
||||
if (unlikely(!_ep || !ep->ep.desc)) {
|
||||
VDBG("%s, bad ep", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (usb_endpoint_xfer_isoc(ep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
|
||||
if (req->req.length > ep->ep.maxpacket)
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
@ -1035,12 +1036,12 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
|
||||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
udc = ep->udc;
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (usb_endpoint_xfer_isoc(ep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
|
||||
status = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1079,7 +1080,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
|
|||
struct ep_queue_head *qh;
|
||||
|
||||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
if (!_ep || (!ep->desc && ep_index(ep) != 0))
|
||||
if (!_ep || (!ep->ep.desc && ep_index(ep) != 0))
|
||||
return -ENODEV;
|
||||
|
||||
udc = (struct fsl_udc *)ep->udc;
|
||||
|
@ -1112,7 +1113,7 @@ static void fsl_ep_fifo_flush(struct usb_ep *_ep)
|
|||
return;
|
||||
} else {
|
||||
ep = container_of(_ep, struct fsl_ep, ep);
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
return;
|
||||
}
|
||||
ep_num = ep_index(ep);
|
||||
|
@ -1367,7 +1368,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
|||
target_ep = get_ep_by_pipe(udc, get_pipe_by_windex(index));
|
||||
|
||||
/* stall if endpoint doesn't exist */
|
||||
if (!target_ep->desc)
|
||||
if (!target_ep->ep.desc)
|
||||
goto stall;
|
||||
tmp = dr_ep_get_stall(ep_index(target_ep), ep_is_in(target_ep))
|
||||
<< USB_ENDPOINT_HALT;
|
||||
|
@ -2277,7 +2278,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
|
|||
}
|
||||
/* other gadget->eplist ep */
|
||||
list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
t = scnprintf(next, size,
|
||||
"\nFor %s Maxpkt is 0x%x "
|
||||
"index is 0x%x\n",
|
||||
|
|
|
@ -461,7 +461,6 @@ struct fsl_ep {
|
|||
struct list_head queue;
|
||||
struct fsl_udc *udc;
|
||||
struct ep_queue_head *qh;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct usb_gadget *gadget;
|
||||
|
||||
char name[14];
|
||||
|
|
|
@ -203,7 +203,7 @@ static int config_ep(struct fusb300_ep *ep,
|
|||
struct fusb300 *fusb300 = ep->fusb300;
|
||||
struct fusb300_ep_info info;
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
|
||||
info.interval = 0;
|
||||
info.addrofs = 0;
|
||||
|
@ -443,7 +443,7 @@ static int fusb300_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||
req->req.actual = 0;
|
||||
req->req.status = -EINPROGRESS;
|
||||
|
||||
if (ep->desc == NULL) /* ep0 */
|
||||
if (ep->ep.desc == NULL) /* ep0 */
|
||||
ep0_queue(ep, req);
|
||||
else if (request && !ep->stall)
|
||||
enable_fifo_int(ep);
|
||||
|
|
|
@ -650,7 +650,6 @@ struct fusb300_ep {
|
|||
|
||||
unsigned char epnum;
|
||||
unsigned char type;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
};
|
||||
|
||||
struct fusb300 {
|
||||
|
|
|
@ -13,10 +13,11 @@ extern unsigned buflen;
|
|||
extern const struct usb_descriptor_header *otg_desc[];
|
||||
|
||||
/* common utilities */
|
||||
struct usb_request *alloc_ep_req(struct usb_ep *ep);
|
||||
struct usb_request *alloc_ep_req(struct usb_ep *ep, int len);
|
||||
void free_ep_req(struct usb_ep *ep, struct usb_request *req);
|
||||
void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *in, struct usb_ep *out);
|
||||
struct usb_ep *in, struct usb_ep *out,
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out);
|
||||
|
||||
/* configuration-specific linkup */
|
||||
int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
|
||||
|
|
|
@ -102,7 +102,7 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
unsigned long flags;
|
||||
|
||||
ep = container_of(_ep, struct goku_ep, ep);
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT)
|
||||
return -EINVAL;
|
||||
dev = ep->dev;
|
||||
|
@ -176,7 +176,7 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||
command(ep->dev->regs, COMMAND_RESET, ep->num);
|
||||
ep->ep.maxpacket = max;
|
||||
ep->stopped = 0;
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
spin_unlock_irqrestore(&ep->dev->lock, flags);
|
||||
|
||||
DBG(dev, "enable %s %s %s maxpacket %u\n", ep->ep.name,
|
||||
|
@ -233,7 +233,6 @@ static void ep_reset(struct goku_udc_regs __iomem *regs, struct goku_ep *ep)
|
|||
}
|
||||
|
||||
ep->ep.maxpacket = MAX_FIFO_SIZE;
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
ep->irqs = 0;
|
||||
|
@ -247,7 +246,7 @@ static int goku_ep_disable(struct usb_ep *_ep)
|
|||
unsigned long flags;
|
||||
|
||||
ep = container_of(_ep, struct goku_ep, ep);
|
||||
if (!_ep || !ep->desc)
|
||||
if (!_ep || !ep->ep.desc)
|
||||
return -ENODEV;
|
||||
dev = ep->dev;
|
||||
if (dev->ep0state == EP0_SUSPEND)
|
||||
|
@ -722,7 +721,7 @@ goku_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
|| !_req->buf || !list_empty(&req->queue)))
|
||||
return -EINVAL;
|
||||
ep = container_of(_ep, struct goku_ep, ep);
|
||||
if (unlikely(!_ep || (!ep->desc && ep->num != 0)))
|
||||
if (unlikely(!_ep || (!ep->ep.desc && ep->num != 0)))
|
||||
return -EINVAL;
|
||||
dev = ep->dev;
|
||||
if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN))
|
||||
|
@ -815,7 +814,7 @@ static int goku_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||
unsigned long flags;
|
||||
|
||||
ep = container_of(_ep, struct goku_ep, ep);
|
||||
if (!_ep || !_req || (!ep->desc && ep->num != 0))
|
||||
if (!_ep || !_req || (!ep->ep.desc && ep->num != 0))
|
||||
return -EINVAL;
|
||||
dev = ep->dev;
|
||||
if (!dev->driver)
|
||||
|
@ -896,7 +895,7 @@ static int goku_set_halt(struct usb_ep *_ep, int value)
|
|||
return -EINVAL;
|
||||
|
||||
/* don't change EPxSTATUS_EP_INVALID to READY */
|
||||
} else if (!ep->desc) {
|
||||
} else if (!ep->ep.desc) {
|
||||
DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -955,7 +954,7 @@ static void goku_fifo_flush(struct usb_ep *_ep)
|
|||
VDBG(ep->dev, "%s %s\n", __func__, ep->ep.name);
|
||||
|
||||
/* don't change EPxSTATUS_EP_INVALID to READY */
|
||||
if (!ep->desc && ep->num != 0) {
|
||||
if (!ep->ep.desc && ep->num != 0) {
|
||||
DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
|
||||
return;
|
||||
}
|
||||
|
@ -1152,7 +1151,7 @@ udc_proc_read(char *buffer, char **start, off_t off, int count,
|
|||
struct goku_ep *ep = &dev->ep [i];
|
||||
struct goku_request *req;
|
||||
|
||||
if (i && !ep->desc)
|
||||
if (i && !ep->ep.desc)
|
||||
continue;
|
||||
|
||||
tmp = readl(ep->reg_status);
|
||||
|
@ -1473,7 +1472,8 @@ static void ep0_setup(struct goku_udc *dev)
|
|||
case USB_RECIP_ENDPOINT:
|
||||
tmp = le16_to_cpu(ctrl.wIndex) & 0x0f;
|
||||
/* active endpoint */
|
||||
if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
|
||||
if (tmp > 3 ||
|
||||
(!dev->ep[tmp].ep.desc && tmp != 0))
|
||||
goto stall;
|
||||
if (ctrl.wIndex & cpu_to_le16(
|
||||
USB_DIR_IN)) {
|
||||
|
@ -1895,14 +1895,4 @@ static struct pci_driver goku_pci_driver = {
|
|||
/* FIXME add power management support */
|
||||
};
|
||||
|
||||
static int __init init (void)
|
||||
{
|
||||
return pci_register_driver (&goku_pci_driver);
|
||||
}
|
||||
module_init (init);
|
||||
|
||||
static void __exit cleanup (void)
|
||||
{
|
||||
pci_unregister_driver (&goku_pci_driver);
|
||||
}
|
||||
module_exit (cleanup);
|
||||
module_pci_driver(goku_pci_driver);
|
||||
|
|
|
@ -216,7 +216,6 @@ struct goku_ep {
|
|||
|
||||
/* analogous to a host-side qh */
|
||||
struct list_head queue;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
|
||||
u32 __iomem *reg_fifo;
|
||||
u32 __iomem *reg_mode;
|
||||
|
|
|
@ -1237,14 +1237,15 @@ irq_handler_t intr_handler(int i)
|
|||
*******************************************************************************
|
||||
*/
|
||||
|
||||
static int imx_udc_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *));
|
||||
static int imx_udc_stop(struct usb_gadget_driver *driver);
|
||||
static int imx_udc_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static int imx_udc_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver);
|
||||
static const struct usb_gadget_ops imx_udc_ops = {
|
||||
.get_frame = imx_udc_get_frame,
|
||||
.wakeup = imx_udc_wakeup,
|
||||
.start = imx_udc_start,
|
||||
.stop = imx_udc_stop,
|
||||
.get_frame = imx_udc_get_frame,
|
||||
.wakeup = imx_udc_wakeup,
|
||||
.udc_start = imx_udc_start,
|
||||
.udc_stop = imx_udc_stop,
|
||||
};
|
||||
|
||||
static struct imx_udc_struct controller = {
|
||||
|
@ -1329,23 +1330,13 @@ static struct imx_udc_struct controller = {
|
|||
* USB gadget driver functions
|
||||
*******************************************************************************
|
||||
*/
|
||||
static int imx_udc_start(struct usb_gadget_driver *driver,
|
||||
int (*bind)(struct usb_gadget *))
|
||||
static int imx_udc_start(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct imx_udc_struct *imx_usb = &controller;
|
||||
struct imx_udc_struct *imx_usb;
|
||||
int retval;
|
||||
|
||||
if (!driver
|
||||
|| driver->max_speed < USB_SPEED_FULL
|
||||
|| !bind
|
||||
|| !driver->disconnect
|
||||
|| !driver->setup)
|
||||
return -EINVAL;
|
||||
if (!imx_usb)
|
||||
return -ENODEV;
|
||||
if (imx_usb->driver)
|
||||
return -EBUSY;
|
||||
|
||||
imx_usb = container_of(gadget, struct imx_udc_struct, gadget);
|
||||
/* first hook up the driver ... */
|
||||
imx_usb->driver = driver;
|
||||
imx_usb->gadget.dev.driver = &driver->driver;
|
||||
|
@ -1353,14 +1344,6 @@ static int imx_udc_start(struct usb_gadget_driver *driver,
|
|||
retval = device_add(&imx_usb->gadget.dev);
|
||||
if (retval)
|
||||
goto fail;
|
||||
retval = bind(&imx_usb->gadget);
|
||||
if (retval) {
|
||||
D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n",
|
||||
__func__, driver->driver.name, retval);
|
||||
device_del(&imx_usb->gadget.dev);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n",
|
||||
__func__, driver->driver.name);
|
||||
|
@ -1374,20 +1357,16 @@ fail:
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int imx_udc_stop(struct usb_gadget_driver *driver)
|
||||
static int imx_udc_stop(struct usb_gadget *gadget,
|
||||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct imx_udc_struct *imx_usb = &controller;
|
||||
|
||||
if (!imx_usb)
|
||||
return -ENODEV;
|
||||
if (!driver || driver != imx_usb->driver || !driver->unbind)
|
||||
return -EINVAL;
|
||||
struct imx_udc_struct *imx_usb = container_of(gadget,
|
||||
struct imx_udc_struct, gadget);
|
||||
|
||||
udc_stop_activity(imx_usb, driver);
|
||||
imx_udc_disable(imx_usb);
|
||||
del_timer(&imx_usb->timer);
|
||||
|
||||
driver->unbind(&imx_usb->gadget);
|
||||
imx_usb->gadget.dev.driver = NULL;
|
||||
imx_usb->driver = NULL;
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ static inline void print_all_registers(struct langwell_udc *dev)
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
|
||||
USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
|
||||
USB_DIR_IN) : (usb_endpoint_dir_in((ep)->ep.desc)))
|
||||
|
||||
#define DIR_STRING(ep) (is_in(ep) ? "in" : "out")
|
||||
|
||||
|
@ -257,7 +257,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
|
|||
dev = ep->dev;
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -337,7 +337,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
|
|||
spin_lock_irqsave(&dev->lock, flags);
|
||||
|
||||
ep->ep.maxpacket = max;
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->stopped = 0;
|
||||
ep->ep_num = usb_endpoint_num(desc);
|
||||
|
||||
|
@ -432,7 +432,7 @@ static void nuke(struct langwell_ep *ep, int status)
|
|||
ep->stopped = 1;
|
||||
|
||||
/* endpoint fifo flush */
|
||||
if (&ep->ep && ep->desc)
|
||||
if (&ep->ep && ep->ep.desc)
|
||||
langwell_ep_fifo_flush(&ep->ep);
|
||||
|
||||
while (!list_empty(&ep->queue)) {
|
||||
|
@ -459,7 +459,7 @@ static int langwell_ep_disable(struct usb_ep *_ep)
|
|||
dev = ep->dev;
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !ep->desc)
|
||||
if (!_ep || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
|
@ -476,7 +476,6 @@ static int langwell_ep_disable(struct usb_ep *_ep)
|
|||
/* nuke all pending requests (does flush) */
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
|
||||
|
@ -752,14 +751,14 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(!_ep || !ep->desc))
|
||||
if (unlikely(!_ep || !ep->ep.desc))
|
||||
return -EINVAL;
|
||||
|
||||
dev = ep->dev;
|
||||
req->ep = ep;
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (usb_endpoint_xfer_isoc(ep->desc)) {
|
||||
if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
|
||||
if (req->req.length > ep->ep.maxpacket)
|
||||
return -EMSGSIZE;
|
||||
is_iso = 1;
|
||||
|
@ -822,7 +821,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||
dev = ep->dev;
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !ep->desc || !_req)
|
||||
if (!_ep || !ep->ep.desc || !_req)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dev->driver)
|
||||
|
@ -950,13 +949,13 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !ep->desc)
|
||||
if (!_ep || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
if (usb_endpoint_xfer_isoc(ep->desc))
|
||||
if (usb_endpoint_xfer_isoc(ep->ep.desc))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
|
@ -999,7 +998,7 @@ static int langwell_ep_set_wedge(struct usb_ep *_ep)
|
|||
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !ep->desc)
|
||||
if (!_ep || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
|
||||
|
@ -1020,8 +1019,8 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
|
|||
|
||||
dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
|
||||
|
||||
if (!_ep || !ep->desc) {
|
||||
dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n");
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
dev_vdbg(&dev->pdev->dev, "ep or ep->ep.desc is NULL\n");
|
||||
dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
@ -1402,7 +1401,7 @@ static int eps_reinit(struct langwell_udc *dev)
|
|||
ep->stopped = 0;
|
||||
ep->ep.maxpacket = EP0_MAX_PKT_SIZE;
|
||||
ep->ep_num = 0;
|
||||
ep->desc = &langwell_ep0_desc;
|
||||
ep->ep.desc = &langwell_ep0_desc;
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
|
||||
ep->ep_type = USB_ENDPOINT_XFER_CONTROL;
|
||||
|
@ -1737,7 +1736,7 @@ static ssize_t show_langwell_udc(struct device *_dev,
|
|||
}
|
||||
/* other gadget->eplist ep */
|
||||
list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
|
||||
if (ep->desc) {
|
||||
if (ep->ep.desc) {
|
||||
t = scnprintf(next, size,
|
||||
"\n%s MaxPacketSize: 0x%x, "
|
||||
"ep_num: %d\n",
|
||||
|
@ -2046,10 +2045,10 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
|
|||
|
||||
list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
|
||||
u8 bEndpointAddress;
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
continue;
|
||||
|
||||
bEndpointAddress = ep->desc->bEndpointAddress;
|
||||
bEndpointAddress = ep->ep.desc->bEndpointAddress;
|
||||
if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
|
||||
continue;
|
||||
|
||||
|
@ -3412,23 +3411,9 @@ static struct pci_driver langwell_pci_driver = {
|
|||
.shutdown = langwell_udc_shutdown,
|
||||
};
|
||||
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
return pci_register_driver(&langwell_pci_driver);
|
||||
}
|
||||
module_init(init);
|
||||
|
||||
|
||||
static void __exit cleanup(void)
|
||||
{
|
||||
pci_unregister_driver(&langwell_pci_driver);
|
||||
}
|
||||
module_exit(cleanup);
|
||||
|
||||
module_pci_driver(langwell_pci_driver);
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
|
||||
MODULE_VERSION(DRIVER_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -116,7 +116,6 @@ struct langwell_ep {
|
|||
unsigned long irqs;
|
||||
struct list_head queue;
|
||||
struct langwell_dqh *dqh;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
char name[14];
|
||||
unsigned stopped:1,
|
||||
ep_type:2,
|
||||
|
|
|
@ -390,7 +390,7 @@ static int alloc_pipe_config(struct m66592_ep *ep,
|
|||
int *counter;
|
||||
int ret;
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
|
||||
BUG_ON(ep->pipenum);
|
||||
|
||||
|
@ -558,7 +558,7 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req)
|
|||
|
||||
static void start_packet(struct m66592_ep *ep, struct m66592_request *req)
|
||||
{
|
||||
if (ep->desc->bEndpointAddress & USB_DIR_IN)
|
||||
if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
|
||||
start_packet_write(ep, req);
|
||||
else
|
||||
start_packet_read(ep, req);
|
||||
|
@ -734,7 +734,7 @@ __acquires(m66592->lock)
|
|||
|
||||
if (restart) {
|
||||
req = list_entry(ep->queue.next, struct m66592_request, queue);
|
||||
if (ep->desc)
|
||||
if (ep->ep.desc)
|
||||
start_packet(ep, req);
|
||||
}
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb)
|
|||
ep = m66592->pipenum2ep[pipenum];
|
||||
req = list_entry(ep->queue.next,
|
||||
struct m66592_request, queue);
|
||||
if (ep->desc->bEndpointAddress & USB_DIR_IN)
|
||||
if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
|
||||
irq_packet_write(ep, req);
|
||||
else
|
||||
irq_packet_read(ep, req);
|
||||
|
@ -1377,7 +1377,7 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||
req->req.actual = 0;
|
||||
req->req.status = -EINPROGRESS;
|
||||
|
||||
if (ep->desc == NULL) /* control */
|
||||
if (ep->ep.desc == NULL) /* control */
|
||||
start_ep0(ep, req);
|
||||
else {
|
||||
if (request && !ep->busy)
|
||||
|
|
|
@ -456,7 +456,7 @@ struct m66592_ep {
|
|||
unsigned use_dma:1;
|
||||
u16 pipenum;
|
||||
u16 type;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
|
||||
/* register address */
|
||||
unsigned long fifoaddr;
|
||||
unsigned long fifosel;
|
||||
|
|
|
@ -232,7 +232,6 @@ struct mv_ep {
|
|||
struct mv_udc *udc;
|
||||
struct list_head queue;
|
||||
struct mv_dqh *dqh;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
u32 direction;
|
||||
char name[14];
|
||||
unsigned stopped:1,
|
||||
|
|
|
@ -464,7 +464,7 @@ static int mv_ep_enable(struct usb_ep *_ep,
|
|||
ep = container_of(_ep, struct mv_ep, ep);
|
||||
udc = ep->udc;
|
||||
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -528,7 +528,7 @@ static int mv_ep_enable(struct usb_ep *_ep,
|
|||
dqh->size_ioc_int_sts = 0;
|
||||
|
||||
ep->ep.maxpacket = max;
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->stopped = 0;
|
||||
|
||||
/* Enable the endpoint for Rx or Tx and set the endpoint type */
|
||||
|
@ -580,7 +580,7 @@ static int mv_ep_disable(struct usb_ep *_ep)
|
|||
unsigned long flags;
|
||||
|
||||
ep = container_of(_ep, struct mv_ep, ep);
|
||||
if ((_ep == NULL) || !ep->desc)
|
||||
if ((_ep == NULL) || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
udc = ep->udc;
|
||||
|
@ -606,7 +606,6 @@ static int mv_ep_disable(struct usb_ep *_ep)
|
|||
/* nuke all pending requests (does flush) */
|
||||
nuke(ep, -ESHUTDOWN);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
|
||||
|
@ -651,7 +650,7 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep)
|
|||
return;
|
||||
|
||||
ep = container_of(_ep, struct mv_ep, ep);
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
return;
|
||||
|
||||
udc = ep->udc;
|
||||
|
@ -715,11 +714,11 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
dev_err(&udc->dev->dev, "%s, bad params", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(!_ep || !ep->desc)) {
|
||||
if (unlikely(!_ep || !ep->ep.desc)) {
|
||||
dev_err(&udc->dev->dev, "%s, bad ep", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
if (req->req.length > ep->ep.maxpacket)
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
@ -925,12 +924,12 @@ static int mv_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge)
|
|||
|
||||
ep = container_of(_ep, struct mv_ep, ep);
|
||||
udc = ep->udc;
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
status = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1279,7 +1278,7 @@ static int eps_init(struct mv_udc *udc)
|
|||
ep->stopped = 0;
|
||||
ep->ep.maxpacket = EP0_MAX_PKT_SIZE;
|
||||
ep->ep_num = 0;
|
||||
ep->desc = &mv_ep0_desc;
|
||||
ep->ep.desc = &mv_ep0_desc;
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
|
||||
ep->ep_type = USB_ENDPOINT_XFER_CONTROL;
|
||||
|
|
|
@ -153,7 +153,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
|
|||
u16 maxp;
|
||||
|
||||
/* catch various bogus parameters */
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||
|| ep->maxpacket < usb_endpoint_maxp(desc)) {
|
||||
|
@ -200,7 +200,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
|
|||
|
||||
spin_lock_irqsave(&udc->lock, flags);
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->irqs = 0;
|
||||
ep->stopped = 0;
|
||||
ep->ep.maxpacket = maxp;
|
||||
|
@ -242,14 +242,13 @@ static int omap_ep_disable(struct usb_ep *_ep)
|
|||
struct omap_ep *ep = container_of(_ep, struct omap_ep, ep);
|
||||
unsigned long flags;
|
||||
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
DBG("%s, %s not enabled\n", __func__,
|
||||
_ep ? ep->ep.name : NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ep->udc->lock, flags);
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
nuke (ep, -ESHUTDOWN);
|
||||
ep->ep.maxpacket = ep->maxpacket;
|
||||
|
@ -917,7 +916,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
DBG("%s, bad params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!_ep || (!ep->desc && ep->bEndpointAddress)) {
|
||||
if (!_ep || (!ep->ep.desc && ep->bEndpointAddress)) {
|
||||
DBG("%s, bad ep\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1121,7 +1120,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
status = 0;
|
||||
|
||||
/* otherwise, all active non-ISO endpoints can halt */
|
||||
} else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->desc) {
|
||||
} else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->ep.desc) {
|
||||
|
||||
/* IN endpoints must already be idle */
|
||||
if ((ep->bEndpointAddress & USB_DIR_IN)
|
||||
|
@ -1625,7 +1624,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
|
|||
if (w_index & USB_DIR_IN)
|
||||
ep += 16;
|
||||
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|
||||
|| !ep->desc)
|
||||
|| !ep->ep.desc)
|
||||
goto do_stall;
|
||||
use_ep(ep, 0);
|
||||
omap_writew(udc->clr_halt, UDC_CTRL);
|
||||
|
@ -1653,7 +1652,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
|
|||
if (w_index & USB_DIR_IN)
|
||||
ep += 16;
|
||||
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|
||||
|| ep == ep0 || !ep->desc)
|
||||
|| ep == ep0 || !ep->ep.desc)
|
||||
goto do_stall;
|
||||
if (use_dma && ep->has_dma) {
|
||||
/* this has rude side-effects (aborts) and
|
||||
|
@ -1688,7 +1687,7 @@ ep0out_status_stage:
|
|||
ep = &udc->ep[w_index & 0xf];
|
||||
if (w_index & USB_DIR_IN)
|
||||
ep += 16;
|
||||
if (!ep->desc)
|
||||
if (!ep->ep.desc)
|
||||
goto do_stall;
|
||||
|
||||
/* iso never stalls */
|
||||
|
@ -2509,7 +2508,7 @@ static int proc_udc_show(struct seq_file *s, void *_)
|
|||
if (tmp & UDC_ADD) {
|
||||
list_for_each_entry (ep, &udc->gadget.ep_list,
|
||||
ep.ep_list) {
|
||||
if (ep->desc)
|
||||
if (ep->ep.desc)
|
||||
proc_ep_show(s, ep);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@ struct omap_ep {
|
|||
struct list_head queue;
|
||||
unsigned long irqs;
|
||||
struct list_head iso;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
char name[14];
|
||||
u16 maxpacket;
|
||||
u8 bEndpointAddress;
|
||||
|
|
|
@ -295,7 +295,6 @@ struct pch_udc_ep {
|
|||
struct pch_udc_data_dma_desc *td_data;
|
||||
struct pch_udc_dev *dev;
|
||||
unsigned long offset_addr;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct list_head queue;
|
||||
unsigned num:5,
|
||||
in:1,
|
||||
|
@ -1705,7 +1704,7 @@ static int pch_udc_pcd_ep_enable(struct usb_ep *usbep,
|
|||
if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN))
|
||||
return -ESHUTDOWN;
|
||||
spin_lock_irqsave(&dev->lock, iflags);
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->halted = 0;
|
||||
pch_udc_ep_enable(ep, &ep->dev->cfg_data, desc);
|
||||
ep->ep.maxpacket = usb_endpoint_maxp(desc);
|
||||
|
@ -1734,7 +1733,7 @@ static int pch_udc_pcd_ep_disable(struct usb_ep *usbep)
|
|||
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
dev = ep->dev;
|
||||
if ((usbep->name == ep0_string) || !ep->desc)
|
||||
if ((usbep->name == ep0_string) || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&ep->dev->lock, iflags);
|
||||
|
@ -1742,7 +1741,6 @@ static int pch_udc_pcd_ep_disable(struct usb_ep *usbep)
|
|||
ep->halted = 1;
|
||||
pch_udc_ep_disable(ep);
|
||||
pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num));
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
spin_unlock_irqrestore(&ep->dev->lock, iflags);
|
||||
|
@ -1849,7 +1847,7 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq,
|
|||
return -EINVAL;
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
dev = ep->dev;
|
||||
if (!ep->desc && ep->num)
|
||||
if (!ep->ep.desc && ep->num)
|
||||
return -EINVAL;
|
||||
req = container_of(usbreq, struct pch_udc_request, req);
|
||||
if (!list_empty(&req->queue))
|
||||
|
@ -1949,7 +1947,7 @@ static int pch_udc_pcd_dequeue(struct usb_ep *usbep,
|
|||
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
dev = ep->dev;
|
||||
if (!usbep || !usbreq || (!ep->desc && ep->num))
|
||||
if (!usbep || !usbreq || (!ep->ep.desc && ep->num))
|
||||
return ret;
|
||||
req = container_of(usbreq, struct pch_udc_request, req);
|
||||
spin_lock_irqsave(&ep->dev->lock, flags);
|
||||
|
@ -1988,7 +1986,7 @@ static int pch_udc_pcd_set_halt(struct usb_ep *usbep, int halt)
|
|||
return -EINVAL;
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
dev = ep->dev;
|
||||
if (!ep->desc && !ep->num)
|
||||
if (!ep->ep.desc && !ep->num)
|
||||
return -EINVAL;
|
||||
if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
|
||||
return -ESHUTDOWN;
|
||||
|
@ -2033,7 +2031,7 @@ static int pch_udc_pcd_set_wedge(struct usb_ep *usbep)
|
|||
return -EINVAL;
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
dev = ep->dev;
|
||||
if (!ep->desc && !ep->num)
|
||||
if (!ep->ep.desc && !ep->num)
|
||||
return -EINVAL;
|
||||
if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
|
||||
return -ESHUTDOWN;
|
||||
|
@ -2065,7 +2063,7 @@ static void pch_udc_pcd_fifo_flush(struct usb_ep *usbep)
|
|||
return;
|
||||
|
||||
ep = container_of(usbep, struct pch_udc_ep, ep);
|
||||
if (ep->desc || !ep->num)
|
||||
if (ep->ep.desc || !ep->num)
|
||||
pch_udc_ep_fifo_flush(ep, ep->in);
|
||||
}
|
||||
|
||||
|
@ -3282,7 +3280,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {
|
|||
|
||||
MODULE_DEVICE_TABLE(pci, pch_udc_pcidev_id);
|
||||
|
||||
|
||||
static struct pci_driver pch_udc_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = pch_udc_pcidev_id,
|
||||
|
@ -3293,17 +3290,7 @@ static struct pci_driver pch_udc_driver = {
|
|||
.shutdown = pch_udc_shutdown,
|
||||
};
|
||||
|
||||
static int __init pch_udc_pci_init(void)
|
||||
{
|
||||
return pci_register_driver(&pch_udc_driver);
|
||||
}
|
||||
module_init(pch_udc_pci_init);
|
||||
|
||||
static void __exit pch_udc_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&pch_udc_driver);
|
||||
}
|
||||
module_exit(pch_udc_pci_exit);
|
||||
module_pci_driver(pch_udc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Intel EG20T USB Device Controller");
|
||||
MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
* the runtime footprint, and giving us at least some parts of what
|
||||
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
|
||||
*/
|
||||
#include "composite.c"
|
||||
#include "usbstring.c"
|
||||
#include "config.c"
|
||||
#include "epautoconf.c"
|
||||
|
@ -75,8 +76,6 @@ struct printer_dev {
|
|||
/* lock buffer lists during read/write calls */
|
||||
struct mutex lock_printer_io;
|
||||
struct usb_gadget *gadget;
|
||||
struct usb_request *req; /* for control responses */
|
||||
u8 config;
|
||||
s8 interface;
|
||||
struct usb_ep *in_ep, *out_ep;
|
||||
|
||||
|
@ -100,6 +99,7 @@ struct printer_dev {
|
|||
struct device *pdev;
|
||||
u8 printer_cdev_open;
|
||||
wait_queue_head_t wait;
|
||||
struct usb_function function;
|
||||
};
|
||||
|
||||
static struct printer_dev usb_printer_gadget;
|
||||
|
@ -120,26 +120,6 @@ static struct printer_dev usb_printer_gadget;
|
|||
* parameters are in UTF-8 (superset of ASCII's 7 bit characters).
|
||||
*/
|
||||
|
||||
static ushort idVendor;
|
||||
module_param(idVendor, ushort, S_IRUGO);
|
||||
MODULE_PARM_DESC(idVendor, "USB Vendor ID");
|
||||
|
||||
static ushort idProduct;
|
||||
module_param(idProduct, ushort, S_IRUGO);
|
||||
MODULE_PARM_DESC(idProduct, "USB Product ID");
|
||||
|
||||
static ushort bcdDevice;
|
||||
module_param(bcdDevice, ushort, S_IRUGO);
|
||||
MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
|
||||
|
||||
static char *iManufacturer;
|
||||
module_param(iManufacturer, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
|
||||
|
||||
static char *iProduct;
|
||||
module_param(iProduct, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(iProduct, "USB Product string");
|
||||
|
||||
static char *iSerialNum;
|
||||
module_param(iSerialNum, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(iSerialNum, "1");
|
||||
|
@ -154,47 +134,8 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
|
|||
|
||||
#define QLEN qlen
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
#define DEVSPEED USB_SPEED_HIGH
|
||||
#else /* full speed (low speed doesn't do bulk) */
|
||||
#define DEVSPEED USB_SPEED_FULL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define xprintk(d, level, fmt, args...) \
|
||||
printk(level "%s: " fmt, DRIVER_DESC, ## args)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(dev, fmt, args...) \
|
||||
xprintk(dev, KERN_DEBUG, fmt, ## args)
|
||||
#else
|
||||
#define DBG(dev, fmt, args...) \
|
||||
do { } while (0)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef VERBOSE
|
||||
#define VDBG(dev, fmt, args...) \
|
||||
xprintk(dev, KERN_DEBUG, fmt, ## args)
|
||||
#else
|
||||
#define VDBG(dev, fmt, args...) \
|
||||
do { } while (0)
|
||||
#endif /* VERBOSE */
|
||||
|
||||
#define ERROR(dev, fmt, args...) \
|
||||
xprintk(dev, KERN_ERR, fmt, ## args)
|
||||
#define WARNING(dev, fmt, args...) \
|
||||
xprintk(dev, KERN_WARNING, fmt, ## args)
|
||||
#define INFO(dev, fmt, args...) \
|
||||
xprintk(dev, KERN_INFO, fmt, ## args)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
|
||||
* ep0 implementation: descriptors, config management, setup().
|
||||
* also optional class-specific notification interrupt transfer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTORS ... most are static, but strings and (full) configuration
|
||||
* descriptors are built on demand.
|
||||
|
@ -227,24 +168,6 @@ static struct usb_device_descriptor device_desc = {
|
|||
.bNumConfigurations = 1
|
||||
};
|
||||
|
||||
static struct usb_otg_descriptor otg_desc = {
|
||||
.bLength = sizeof otg_desc,
|
||||
.bDescriptorType = USB_DT_OTG,
|
||||
.bmAttributes = USB_OTG_SRP
|
||||
};
|
||||
|
||||
static struct usb_config_descriptor config_desc = {
|
||||
.bLength = sizeof config_desc,
|
||||
.bDescriptorType = USB_DT_CONFIG,
|
||||
|
||||
/* compute wTotalLength on the fly */
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = DEV_CONFIG_VALUE,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor intf_desc = {
|
||||
.bLength = sizeof intf_desc,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
@ -270,16 +193,13 @@ static struct usb_endpoint_descriptor fs_ep_out_desc = {
|
|||
.bmAttributes = USB_ENDPOINT_XFER_BULK
|
||||
};
|
||||
|
||||
static const struct usb_descriptor_header *fs_printer_function [11] = {
|
||||
(struct usb_descriptor_header *) &otg_desc,
|
||||
static struct usb_descriptor_header *fs_printer_function[] = {
|
||||
(struct usb_descriptor_header *) &intf_desc,
|
||||
(struct usb_descriptor_header *) &fs_ep_in_desc,
|
||||
(struct usb_descriptor_header *) &fs_ep_out_desc,
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
|
||||
/*
|
||||
* usb 2.0 devices need to expose both high speed and full speed
|
||||
* descriptors, unless they only run at full speed.
|
||||
|
@ -307,24 +227,27 @@ static struct usb_qualifier_descriptor dev_qualifier = {
|
|||
.bNumConfigurations = 1
|
||||
};
|
||||
|
||||
static const struct usb_descriptor_header *hs_printer_function [11] = {
|
||||
(struct usb_descriptor_header *) &otg_desc,
|
||||
static struct usb_descriptor_header *hs_printer_function[] = {
|
||||
(struct usb_descriptor_header *) &intf_desc,
|
||||
(struct usb_descriptor_header *) &hs_ep_in_desc,
|
||||
(struct usb_descriptor_header *) &hs_ep_out_desc,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct usb_otg_descriptor otg_descriptor = {
|
||||
.bLength = sizeof otg_descriptor,
|
||||
.bDescriptorType = USB_DT_OTG,
|
||||
.bmAttributes = USB_OTG_SRP,
|
||||
};
|
||||
|
||||
static const struct usb_descriptor_header *otg_desc[] = {
|
||||
(struct usb_descriptor_header *) &otg_descriptor,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* maxpacket and other transfer characteristics vary by speed. */
|
||||
#define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs))
|
||||
|
||||
#else
|
||||
|
||||
/* if there's no high speed support, maxpacket doesn't change. */
|
||||
#define ep_desc(g, hs, fs) (((void)(g)), (fs))
|
||||
|
||||
#endif /* !CONFIG_USB_GADGET_DUALSPEED */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* descriptors that are built on-demand */
|
||||
|
@ -343,11 +266,16 @@ static struct usb_string strings [] = {
|
|||
{ } /* end of list */
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings stringtab = {
|
||||
static struct usb_gadget_strings stringtab_dev = {
|
||||
.language = 0x0409, /* en-us */
|
||||
.strings = strings,
|
||||
};
|
||||
|
||||
static struct usb_gadget_strings *dev_strings[] = {
|
||||
&stringtab_dev,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct usb_request *
|
||||
|
@ -937,82 +865,8 @@ static void printer_reset_interface(struct printer_dev *dev)
|
|||
dev->interface = -1;
|
||||
}
|
||||
|
||||
/* change our operational config. must agree with the code
|
||||
* that returns config descriptors, and altsetting code.
|
||||
*/
|
||||
static int
|
||||
printer_set_config(struct printer_dev *dev, unsigned number)
|
||||
{
|
||||
int result = 0;
|
||||
struct usb_gadget *gadget = dev->gadget;
|
||||
|
||||
switch (number) {
|
||||
case DEV_CONFIG_VALUE:
|
||||
result = 0;
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
/* FALL THROUGH */
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
usb_gadget_vbus_draw(dev->gadget,
|
||||
dev->gadget->is_otg ? 8 : 100);
|
||||
} else {
|
||||
unsigned power;
|
||||
|
||||
power = 2 * config_desc.bMaxPower;
|
||||
usb_gadget_vbus_draw(dev->gadget, power);
|
||||
|
||||
dev->config = number;
|
||||
INFO(dev, "%s config #%d: %d mA, %s\n",
|
||||
usb_speed_string(gadget->speed),
|
||||
number, power, driver_desc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index,
|
||||
int is_otg)
|
||||
{
|
||||
int len;
|
||||
const struct usb_descriptor_header **function;
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
int hs = (speed == USB_SPEED_HIGH);
|
||||
|
||||
if (type == USB_DT_OTHER_SPEED_CONFIG)
|
||||
hs = !hs;
|
||||
|
||||
if (hs) {
|
||||
function = hs_printer_function;
|
||||
} else {
|
||||
function = fs_printer_function;
|
||||
}
|
||||
#else
|
||||
function = fs_printer_function;
|
||||
#endif
|
||||
|
||||
if (index >= device_desc.bNumConfigurations)
|
||||
return -EINVAL;
|
||||
|
||||
/* for now, don't advertise srp-only devices */
|
||||
if (!is_otg)
|
||||
function++;
|
||||
|
||||
len = usb_gadget_config_buf(&config_desc, buf, USB_DESC_BUFSIZE,
|
||||
function);
|
||||
if (len < 0)
|
||||
return len;
|
||||
((struct usb_config_descriptor *) buf)->bDescriptorType = type;
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Change our operational Interface. */
|
||||
static int
|
||||
set_interface(struct printer_dev *dev, unsigned number)
|
||||
static int set_interface(struct printer_dev *dev, unsigned number)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
|
@ -1043,14 +897,6 @@ set_interface(struct printer_dev *dev, unsigned number)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void printer_setup_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
if (req->status || req->actual != req->length)
|
||||
DBG((struct printer_dev *) ep->driver_data,
|
||||
"setup complete --> %d, %d/%d\n",
|
||||
req->status, req->actual, req->length);
|
||||
}
|
||||
|
||||
static void printer_soft_reset(struct printer_dev *dev)
|
||||
{
|
||||
struct usb_request *req;
|
||||
|
@ -1107,11 +953,12 @@ static void printer_soft_reset(struct printer_dev *dev)
|
|||
* The setup() callback implements all the ep0 functionality that's not
|
||||
* handled lower down.
|
||||
*/
|
||||
static int
|
||||
printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
static int printer_func_setup(struct usb_function *f,
|
||||
const struct usb_ctrlrequest *ctrl)
|
||||
{
|
||||
struct printer_dev *dev = get_gadget_data(gadget);
|
||||
struct usb_request *req = dev->req;
|
||||
struct printer_dev *dev = container_of(f, struct printer_dev, function);
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
struct usb_request *req = cdev->req;
|
||||
int value = -EOPNOTSUPP;
|
||||
u16 wIndex = le16_to_cpu(ctrl->wIndex);
|
||||
u16 wValue = le16_to_cpu(ctrl->wValue);
|
||||
|
@ -1120,102 +967,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
|||
DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n",
|
||||
ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength);
|
||||
|
||||
req->complete = printer_setup_complete;
|
||||
|
||||
switch (ctrl->bRequestType&USB_TYPE_MASK) {
|
||||
|
||||
case USB_TYPE_STANDARD:
|
||||
switch (ctrl->bRequest) {
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if (ctrl->bRequestType != USB_DIR_IN)
|
||||
break;
|
||||
switch (wValue >> 8) {
|
||||
|
||||
case USB_DT_DEVICE:
|
||||
device_desc.bMaxPacketSize0 =
|
||||
gadget->ep0->maxpacket;
|
||||
value = min(wLength, (u16) sizeof device_desc);
|
||||
memcpy(req->buf, &device_desc, value);
|
||||
break;
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
case USB_DT_DEVICE_QUALIFIER:
|
||||
if (!gadget_is_dualspeed(gadget))
|
||||
break;
|
||||
/*
|
||||
* assumes ep0 uses the same value for both
|
||||
* speeds
|
||||
*/
|
||||
dev_qualifier.bMaxPacketSize0 =
|
||||
gadget->ep0->maxpacket;
|
||||
value = min(wLength,
|
||||
(u16) sizeof dev_qualifier);
|
||||
memcpy(req->buf, &dev_qualifier, value);
|
||||
break;
|
||||
|
||||
case USB_DT_OTHER_SPEED_CONFIG:
|
||||
if (!gadget_is_dualspeed(gadget))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
#endif /* CONFIG_USB_GADGET_DUALSPEED */
|
||||
case USB_DT_CONFIG:
|
||||
value = config_buf(gadget->speed, req->buf,
|
||||
wValue >> 8,
|
||||
wValue & 0xff,
|
||||
gadget->is_otg);
|
||||
if (value >= 0)
|
||||
value = min(wLength, (u16) value);
|
||||
break;
|
||||
|
||||
case USB_DT_STRING:
|
||||
value = usb_gadget_get_string(&stringtab,
|
||||
wValue & 0xff, req->buf);
|
||||
if (value >= 0)
|
||||
value = min(wLength, (u16) value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
if (ctrl->bRequestType != 0)
|
||||
break;
|
||||
if (gadget->a_hnp_support)
|
||||
DBG(dev, "HNP available\n");
|
||||
else if (gadget->a_alt_hnp_support)
|
||||
DBG(dev, "HNP needs a different root port\n");
|
||||
value = printer_set_config(dev, wValue);
|
||||
if (!value)
|
||||
value = set_interface(dev, PRINTER_INTERFACE);
|
||||
break;
|
||||
case USB_REQ_GET_CONFIGURATION:
|
||||
if (ctrl->bRequestType != USB_DIR_IN)
|
||||
break;
|
||||
*(u8 *)req->buf = dev->config;
|
||||
value = min(wLength, (u16) 1);
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (ctrl->bRequestType != USB_RECIP_INTERFACE ||
|
||||
!dev->config)
|
||||
break;
|
||||
|
||||
value = set_interface(dev, PRINTER_INTERFACE);
|
||||
break;
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (ctrl->bRequestType !=
|
||||
(USB_DIR_IN|USB_RECIP_INTERFACE)
|
||||
|| !dev->config)
|
||||
break;
|
||||
|
||||
*(u8 *)req->buf = dev->interface;
|
||||
value = min(wLength, (u16) 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_TYPE_CLASS:
|
||||
switch (ctrl->bRequest) {
|
||||
case 0: /* Get the IEEE-1284 PNP String */
|
||||
|
@ -1261,44 +1013,50 @@ unknown:
|
|||
wValue, wIndex, wLength);
|
||||
break;
|
||||
}
|
||||
|
||||
/* respond with data transfer before status phase? */
|
||||
if (value >= 0) {
|
||||
req->length = value;
|
||||
req->zero = value < wLength;
|
||||
value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
|
||||
if (value < 0) {
|
||||
DBG(dev, "ep_queue --> %d\n", value);
|
||||
req->status = 0;
|
||||
printer_setup_complete(gadget->ep0, req);
|
||||
}
|
||||
}
|
||||
|
||||
/* host either stalls (value < 0) or reports success */
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
printer_disconnect(struct usb_gadget *gadget)
|
||||
static int __init printer_func_bind(struct usb_configuration *c,
|
||||
struct usb_function *f)
|
||||
{
|
||||
struct printer_dev *dev = get_gadget_data(gadget);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void printer_func_unbind(struct usb_configuration *c,
|
||||
struct usb_function *f)
|
||||
{
|
||||
}
|
||||
|
||||
static int printer_func_set_alt(struct usb_function *f,
|
||||
unsigned intf, unsigned alt)
|
||||
{
|
||||
struct printer_dev *dev = container_of(f, struct printer_dev, function);
|
||||
int ret = -ENOTSUPP;
|
||||
|
||||
if (!alt)
|
||||
ret = set_interface(dev, PRINTER_INTERFACE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void printer_func_disable(struct usb_function *f)
|
||||
{
|
||||
struct printer_dev *dev = container_of(f, struct printer_dev, function);
|
||||
unsigned long flags;
|
||||
|
||||
DBG(dev, "%s\n", __func__);
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
|
||||
printer_reset_interface(dev);
|
||||
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_unbind(struct usb_gadget *gadget)
|
||||
static void printer_cfg_unbind(struct usb_configuration *c)
|
||||
{
|
||||
struct printer_dev *dev = get_gadget_data(gadget);
|
||||
struct printer_dev *dev;
|
||||
struct usb_request *req;
|
||||
|
||||
dev = &usb_printer_gadget;
|
||||
|
||||
DBG(dev, "%s\n", __func__);
|
||||
|
||||
|
@ -1336,18 +1094,18 @@ printer_unbind(struct usb_gadget *gadget)
|
|||
list_del(&req->list);
|
||||
printer_req_free(dev->out_ep, req);
|
||||
}
|
||||
|
||||
if (dev->req) {
|
||||
printer_req_free(gadget->ep0, dev->req);
|
||||
dev->req = NULL;
|
||||
}
|
||||
|
||||
set_gadget_data(gadget, NULL);
|
||||
}
|
||||
|
||||
static int __init
|
||||
printer_bind(struct usb_gadget *gadget)
|
||||
static struct usb_configuration printer_cfg_driver = {
|
||||
.label = "printer",
|
||||
.unbind = printer_cfg_unbind,
|
||||
.bConfigurationValue = 1,
|
||||
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
|
||||
};
|
||||
|
||||
static int __init printer_bind_config(struct usb_configuration *c)
|
||||
{
|
||||
struct usb_gadget *gadget = c->cdev->gadget;
|
||||
struct printer_dev *dev;
|
||||
struct usb_ep *in_ep, *out_ep;
|
||||
int status = -ENOMEM;
|
||||
|
@ -1358,6 +1116,14 @@ printer_bind(struct usb_gadget *gadget)
|
|||
|
||||
dev = &usb_printer_gadget;
|
||||
|
||||
dev->function.name = shortname;
|
||||
dev->function.descriptors = fs_printer_function;
|
||||
dev->function.hs_descriptors = hs_printer_function;
|
||||
dev->function.bind = printer_func_bind;
|
||||
dev->function.setup = printer_func_setup;
|
||||
dev->function.unbind = printer_func_unbind;
|
||||
dev->function.set_alt = printer_func_set_alt;
|
||||
dev->function.disable = printer_func_disable;
|
||||
|
||||
/* Setup the sysfs files for the printer gadget. */
|
||||
dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
|
||||
|
@ -1393,29 +1159,6 @@ printer_bind(struct usb_gadget *gadget)
|
|||
init_utsname()->sysname, init_utsname()->release,
|
||||
gadget->name);
|
||||
|
||||
device_desc.idVendor =
|
||||
cpu_to_le16(PRINTER_VENDOR_NUM);
|
||||
device_desc.idProduct =
|
||||
cpu_to_le16(PRINTER_PRODUCT_NUM);
|
||||
|
||||
/* support optional vendor/distro customization */
|
||||
if (idVendor) {
|
||||
if (!idProduct) {
|
||||
dev_err(&gadget->dev, "idVendor needs idProduct!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
device_desc.idVendor = cpu_to_le16(idVendor);
|
||||
device_desc.idProduct = cpu_to_le16(idProduct);
|
||||
if (bcdDevice)
|
||||
device_desc.bcdDevice = cpu_to_le16(bcdDevice);
|
||||
}
|
||||
|
||||
if (iManufacturer)
|
||||
strlcpy(manufacturer, iManufacturer, sizeof manufacturer);
|
||||
|
||||
if (iProduct)
|
||||
strlcpy(product_desc, iProduct, sizeof product_desc);
|
||||
|
||||
if (iSerialNum)
|
||||
strlcpy(serial_num, iSerialNum, sizeof serial_num);
|
||||
|
||||
|
@ -1442,17 +1185,16 @@ autoconf_fail:
|
|||
goto autoconf_fail;
|
||||
out_ep->driver_data = out_ep; /* claim */
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
/* assumes that all endpoints are dual-speed */
|
||||
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
|
||||
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
|
||||
#endif /* DUALSPEED */
|
||||
|
||||
usb_gadget_set_selfpowered(gadget);
|
||||
|
||||
if (gadget->is_otg) {
|
||||
otg_desc.bmAttributes |= USB_OTG_HNP,
|
||||
config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
otg_descriptor.bmAttributes |= USB_OTG_HNP;
|
||||
printer_cfg_driver.descriptors = otg_desc;
|
||||
printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
}
|
||||
|
||||
spin_lock_init(&dev->lock);
|
||||
|
@ -1466,7 +1208,6 @@ autoconf_fail:
|
|||
init_waitqueue_head(&dev->tx_wait);
|
||||
init_waitqueue_head(&dev->tx_flush_wait);
|
||||
|
||||
dev->config = 0;
|
||||
dev->interface = -1;
|
||||
dev->printer_cdev_open = 0;
|
||||
dev->printer_status = PRINTER_NOT_ERROR;
|
||||
|
@ -1477,14 +1218,6 @@ autoconf_fail:
|
|||
dev->in_ep = in_ep;
|
||||
dev->out_ep = out_ep;
|
||||
|
||||
/* preallocate control message data and buffer */
|
||||
dev->req = printer_req_alloc(gadget->ep0, USB_DESC_BUFSIZE,
|
||||
GFP_KERNEL);
|
||||
if (!dev->req) {
|
||||
status = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < QLEN; i++) {
|
||||
req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
|
||||
if (!req) {
|
||||
|
@ -1513,45 +1246,37 @@ autoconf_fail:
|
|||
list_add(&req->list, &dev->rx_reqs);
|
||||
}
|
||||
|
||||
dev->req->complete = printer_setup_complete;
|
||||
|
||||
/* finish hookup to lower layer ... */
|
||||
dev->gadget = gadget;
|
||||
set_gadget_data(gadget, dev);
|
||||
gadget->ep0->driver_data = dev;
|
||||
|
||||
INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
|
||||
INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name,
|
||||
in_ep->name);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
printer_unbind(gadget);
|
||||
printer_cfg_unbind(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int printer_unbind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_gadget_driver printer_driver = {
|
||||
.max_speed = DEVSPEED,
|
||||
static int __init printer_bind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
|
||||
}
|
||||
|
||||
.function = (char *) driver_desc,
|
||||
static struct usb_composite_driver printer_driver = {
|
||||
.name = shortname,
|
||||
.dev = &device_desc,
|
||||
.strings = dev_strings,
|
||||
.max_speed = USB_SPEED_HIGH,
|
||||
.unbind = printer_unbind,
|
||||
|
||||
.setup = printer_setup,
|
||||
.disconnect = printer_disconnect,
|
||||
|
||||
.driver = {
|
||||
.name = (char *) shortname,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_AUTHOR("Craig Nadler");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int __init
|
||||
init(void)
|
||||
{
|
||||
|
@ -1560,23 +1285,23 @@ init(void)
|
|||
usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget");
|
||||
if (IS_ERR(usb_gadget_class)) {
|
||||
status = PTR_ERR(usb_gadget_class);
|
||||
ERROR(dev, "unable to create usb_gadget class %d\n", status);
|
||||
pr_err("unable to create usb_gadget class %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = alloc_chrdev_region(&g_printer_devno, 0, 1,
|
||||
"USB printer gadget");
|
||||
if (status) {
|
||||
ERROR(dev, "alloc_chrdev_region %d\n", status);
|
||||
pr_err("alloc_chrdev_region %d\n", status);
|
||||
class_destroy(usb_gadget_class);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = usb_gadget_probe_driver(&printer_driver, printer_bind);
|
||||
status = usb_composite_probe(&printer_driver, printer_bind);
|
||||
if (status) {
|
||||
class_destroy(usb_gadget_class);
|
||||
unregister_chrdev_region(g_printer_devno, 1);
|
||||
DBG(dev, "usb_gadget_probe_driver %x\n", status);
|
||||
pr_err("usb_gadget_probe_driver %x\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -1586,15 +1311,14 @@ module_init(init);
|
|||
static void __exit
|
||||
cleanup(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
mutex_lock(&usb_printer_gadget.lock_printer_io);
|
||||
status = usb_gadget_unregister_driver(&printer_driver);
|
||||
if (status)
|
||||
ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
|
||||
|
||||
usb_composite_unregister(&printer_driver);
|
||||
unregister_chrdev_region(g_printer_devno, 1);
|
||||
class_destroy(usb_gadget_class);
|
||||
mutex_unlock(&usb_printer_gadget.lock_printer_io);
|
||||
}
|
||||
module_exit(cleanup);
|
||||
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_AUTHOR("Craig Nadler");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -218,7 +218,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep,
|
|||
struct pxa25x_udc *dev;
|
||||
|
||||
ep = container_of (_ep, struct pxa25x_ep, ep);
|
||||
if (!_ep || !desc || ep->desc || _ep->name == ep0name
|
||||
if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||
|| ep->fifo_size < usb_endpoint_maxp (desc)) {
|
||||
|
@ -249,7 +249,7 @@ static int pxa25x_ep_enable (struct usb_ep *_ep,
|
|||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->stopped = 0;
|
||||
ep->pio_irqs = 0;
|
||||
ep->ep.maxpacket = usb_endpoint_maxp (desc);
|
||||
|
@ -269,7 +269,7 @@ static int pxa25x_ep_disable (struct usb_ep *_ep)
|
|||
unsigned long flags;
|
||||
|
||||
ep = container_of (_ep, struct pxa25x_ep, ep);
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
DMSG("%s, %s not enabled\n", __func__,
|
||||
_ep ? ep->ep.name : NULL);
|
||||
return -EINVAL;
|
||||
|
@ -281,7 +281,6 @@ static int pxa25x_ep_disable (struct usb_ep *_ep)
|
|||
/* flush fifo (mostly for IN buffers) */
|
||||
pxa25x_ep_fifo_flush (_ep);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 1;
|
||||
|
||||
|
@ -390,7 +389,7 @@ write_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req)
|
|||
{
|
||||
unsigned max;
|
||||
|
||||
max = usb_endpoint_maxp(ep->desc);
|
||||
max = usb_endpoint_maxp(ep->ep.desc);
|
||||
do {
|
||||
unsigned count;
|
||||
int is_last, is_short;
|
||||
|
@ -644,7 +643,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
}
|
||||
|
||||
ep = container_of(_ep, struct pxa25x_ep, ep);
|
||||
if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||
if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
|
||||
DMSG("%s, bad ep\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -660,7 +659,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
* we can report per-packet status. that also helps with dma.
|
||||
*/
|
||||
if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
|
||||
&& req->req.length > usb_endpoint_maxp (ep->desc)))
|
||||
&& req->req.length > usb_endpoint_maxp(ep->ep.desc)))
|
||||
return -EMSGSIZE;
|
||||
|
||||
DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
|
||||
|
@ -673,7 +672,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
|
||||
/* kickstart this i/o queue? */
|
||||
if (list_empty(&ep->queue) && !ep->stopped) {
|
||||
if (ep->desc == NULL/* ep0 */) {
|
||||
if (ep->ep.desc == NULL/* ep0 */) {
|
||||
unsigned length = _req->length;
|
||||
|
||||
switch (dev->ep0state) {
|
||||
|
@ -722,7 +721,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||
req = NULL;
|
||||
}
|
||||
|
||||
if (likely (req && ep->desc))
|
||||
if (likely(req && ep->ep.desc))
|
||||
pio_irq_enable(ep->bEndpointAddress);
|
||||
}
|
||||
|
||||
|
@ -749,7 +748,7 @@ static void nuke(struct pxa25x_ep *ep, int status)
|
|||
queue);
|
||||
done(ep, req, status);
|
||||
}
|
||||
if (ep->desc)
|
||||
if (ep->ep.desc)
|
||||
pio_irq_disable (ep->bEndpointAddress);
|
||||
}
|
||||
|
||||
|
@ -792,7 +791,7 @@ static int pxa25x_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
|
||||
ep = container_of(_ep, struct pxa25x_ep, ep);
|
||||
if (unlikely (!_ep
|
||||
|| (!ep->desc && ep->ep.name != ep0name))
|
||||
|| (!ep->ep.desc && ep->ep.name != ep0name))
|
||||
|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||
DMSG("%s, bad ep\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -820,7 +819,7 @@ static int pxa25x_ep_set_halt(struct usb_ep *_ep, int value)
|
|||
*ep->reg_udccs = UDCCS_BI_FST|UDCCS_BI_FTF;
|
||||
|
||||
/* ep0 needs special care */
|
||||
if (!ep->desc) {
|
||||
if (!ep->ep.desc) {
|
||||
start_watchdog(ep->dev);
|
||||
ep->dev->req_pending = 0;
|
||||
ep->dev->ep0state = EP0_STALL;
|
||||
|
@ -1087,7 +1086,7 @@ udc_seq_show(struct seq_file *m, void *_d)
|
|||
if (i != 0) {
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
|
||||
desc = ep->desc;
|
||||
desc = ep->ep.desc;
|
||||
if (!desc)
|
||||
continue;
|
||||
tmp = *dev->ep [i].reg_udccs;
|
||||
|
@ -1191,7 +1190,6 @@ static void udc_reinit(struct pxa25x_udc *dev)
|
|||
if (i != 0)
|
||||
list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->stopped = 0;
|
||||
INIT_LIST_HEAD (&ep->queue);
|
||||
|
|
|
@ -41,7 +41,6 @@ struct pxa25x_ep {
|
|||
struct usb_ep ep;
|
||||
struct pxa25x_udc *dev;
|
||||
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct list_head queue;
|
||||
unsigned long pio_irqs;
|
||||
|
||||
|
|
|
@ -459,7 +459,7 @@ static int alloc_pipe_config(struct r8a66597_ep *ep,
|
|||
unsigned char *counter;
|
||||
int ret;
|
||||
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
|
||||
if (ep->pipenum) /* already allocated pipe */
|
||||
return 0;
|
||||
|
@ -648,7 +648,7 @@ static int sudmac_alloc_channel(struct r8a66597 *r8a66597,
|
|||
/* set SUDMAC parameters */
|
||||
dma = &r8a66597->dma;
|
||||
dma->used = 1;
|
||||
if (ep->desc->bEndpointAddress & USB_DIR_IN) {
|
||||
if (ep->ep.desc->bEndpointAddress & USB_DIR_IN) {
|
||||
dma->dir = 1;
|
||||
} else {
|
||||
dma->dir = 0;
|
||||
|
@ -770,7 +770,7 @@ static void start_packet_read(struct r8a66597_ep *ep,
|
|||
|
||||
static void start_packet(struct r8a66597_ep *ep, struct r8a66597_request *req)
|
||||
{
|
||||
if (ep->desc->bEndpointAddress & USB_DIR_IN)
|
||||
if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
|
||||
start_packet_write(ep, req);
|
||||
else
|
||||
start_packet_read(ep, req);
|
||||
|
@ -930,7 +930,7 @@ __acquires(r8a66597->lock)
|
|||
|
||||
if (restart) {
|
||||
req = get_request_from_ep(ep);
|
||||
if (ep->desc)
|
||||
if (ep->ep.desc)
|
||||
start_packet(ep, req);
|
||||
}
|
||||
}
|
||||
|
@ -1116,7 +1116,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597, u16 status, u16 enb)
|
|||
r8a66597_write(r8a66597, ~check, BRDYSTS);
|
||||
ep = r8a66597->pipenum2ep[pipenum];
|
||||
req = get_request_from_ep(ep);
|
||||
if (ep->desc->bEndpointAddress & USB_DIR_IN)
|
||||
if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
|
||||
irq_packet_write(ep, req);
|
||||
else
|
||||
irq_packet_read(ep, req);
|
||||
|
@ -1170,7 +1170,7 @@ __acquires(r8a66597->lock)
|
|||
|
||||
switch (ctrl->bRequestType & USB_RECIP_MASK) {
|
||||
case USB_RECIP_DEVICE:
|
||||
status = 1 << USB_DEVICE_SELF_POWERED;
|
||||
status = r8a66597->device_status;
|
||||
break;
|
||||
case USB_RECIP_INTERFACE:
|
||||
status = 0;
|
||||
|
@ -1627,7 +1627,7 @@ static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||
req->req.actual = 0;
|
||||
req->req.status = -EINPROGRESS;
|
||||
|
||||
if (ep->desc == NULL) /* control */
|
||||
if (ep->ep.desc == NULL) /* control */
|
||||
start_ep0(ep, req);
|
||||
else {
|
||||
if (request && !ep->busy)
|
||||
|
@ -1692,7 +1692,7 @@ static int r8a66597_set_wedge(struct usb_ep *_ep)
|
|||
|
||||
ep = container_of(_ep, struct r8a66597_ep, ep);
|
||||
|
||||
if (!ep || !ep->desc)
|
||||
if (!ep || !ep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&ep->r8a66597->lock, flags);
|
||||
|
@ -1800,11 +1800,24 @@ static int r8a66597_pullup(struct usb_gadget *gadget, int is_on)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self)
|
||||
{
|
||||
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
|
||||
|
||||
if (is_self)
|
||||
r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED;
|
||||
else
|
||||
r8a66597->device_status &= ~(1 << USB_DEVICE_SELF_POWERED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_gadget_ops r8a66597_gadget_ops = {
|
||||
.get_frame = r8a66597_get_frame,
|
||||
.udc_start = r8a66597_start,
|
||||
.udc_stop = r8a66597_stop,
|
||||
.pullup = r8a66597_pullup,
|
||||
.set_selfpowered = r8a66597_set_selfpowered,
|
||||
};
|
||||
|
||||
static int __exit r8a66597_remove(struct platform_device *pdev)
|
||||
|
|
|
@ -72,7 +72,7 @@ struct r8a66597_ep {
|
|||
unsigned use_dma:1;
|
||||
u16 pipenum;
|
||||
u16 type;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
|
||||
/* register address */
|
||||
unsigned char fifoaddr;
|
||||
unsigned char fifosel;
|
||||
|
@ -111,6 +111,7 @@ struct r8a66597 {
|
|||
u16 old_vbus;
|
||||
u16 scount;
|
||||
u16 old_dvsq;
|
||||
u16 device_status; /* for GET_STATUS */
|
||||
|
||||
/* pipe config */
|
||||
unsigned char bulk;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,377 @@
|
|||
/* drivers/usb/gadget/s3c-hsotg.h
|
||||
*
|
||||
* Copyright 2008 Openmoko, Inc.
|
||||
* Copyright 2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* USB2.0 Highspeed/OtG Synopsis DWC2 device block registers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __REGS_USB_HSOTG_H
|
||||
#define __REGS_USB_HSOTG_H __FILE__
|
||||
|
||||
#define HSOTG_REG(x) (x)
|
||||
|
||||
#define GOTGCTL HSOTG_REG(0x000)
|
||||
#define GOTGCTL_BSESVLD (1 << 19)
|
||||
#define GOTGCTL_ASESVLD (1 << 18)
|
||||
#define GOTGCTL_DBNC_SHORT (1 << 17)
|
||||
#define GOTGCTL_CONID_B (1 << 16)
|
||||
#define GOTGCTL_DEVHNPEN (1 << 11)
|
||||
#define GOTGCTL_HSSETHNPEN (1 << 10)
|
||||
#define GOTGCTL_HNPREQ (1 << 9)
|
||||
#define GOTGCTL_HSTNEGSCS (1 << 8)
|
||||
#define GOTGCTL_SESREQ (1 << 1)
|
||||
#define GOTGCTL_SESREQSCS (1 << 0)
|
||||
|
||||
#define GOTGINT HSOTG_REG(0x004)
|
||||
#define GOTGINT_DbnceDone (1 << 19)
|
||||
#define GOTGINT_ADevTOUTChg (1 << 18)
|
||||
#define GOTGINT_HstNegDet (1 << 17)
|
||||
#define GOTGINT_HstnegSucStsChng (1 << 9)
|
||||
#define GOTGINT_SesReqSucStsChng (1 << 8)
|
||||
#define GOTGINT_SesEndDet (1 << 2)
|
||||
|
||||
#define GAHBCFG HSOTG_REG(0x008)
|
||||
#define GAHBCFG_PTxFEmpLvl (1 << 8)
|
||||
#define GAHBCFG_NPTxFEmpLvl (1 << 7)
|
||||
#define GAHBCFG_DMAEn (1 << 5)
|
||||
#define GAHBCFG_HBstLen_MASK (0xf << 1)
|
||||
#define GAHBCFG_HBstLen_SHIFT (1)
|
||||
#define GAHBCFG_HBstLen_Single (0x0 << 1)
|
||||
#define GAHBCFG_HBstLen_Incr (0x1 << 1)
|
||||
#define GAHBCFG_HBstLen_Incr4 (0x3 << 1)
|
||||
#define GAHBCFG_HBstLen_Incr8 (0x5 << 1)
|
||||
#define GAHBCFG_HBstLen_Incr16 (0x7 << 1)
|
||||
#define GAHBCFG_GlblIntrEn (1 << 0)
|
||||
|
||||
#define GUSBCFG HSOTG_REG(0x00C)
|
||||
#define GUSBCFG_PHYLPClkSel (1 << 15)
|
||||
#define GUSBCFG_HNPCap (1 << 9)
|
||||
#define GUSBCFG_SRPCap (1 << 8)
|
||||
#define GUSBCFG_PHYIf16 (1 << 3)
|
||||
#define GUSBCFG_TOutCal_MASK (0x7 << 0)
|
||||
#define GUSBCFG_TOutCal_SHIFT (0)
|
||||
#define GUSBCFG_TOutCal_LIMIT (0x7)
|
||||
#define GUSBCFG_TOutCal(_x) ((_x) << 0)
|
||||
|
||||
#define GRSTCTL HSOTG_REG(0x010)
|
||||
|
||||
#define GRSTCTL_AHBIdle (1 << 31)
|
||||
#define GRSTCTL_DMAReq (1 << 30)
|
||||
#define GRSTCTL_TxFNum_MASK (0x1f << 6)
|
||||
#define GRSTCTL_TxFNum_SHIFT (6)
|
||||
#define GRSTCTL_TxFNum_LIMIT (0x1f)
|
||||
#define GRSTCTL_TxFNum(_x) ((_x) << 6)
|
||||
#define GRSTCTL_TxFFlsh (1 << 5)
|
||||
#define GRSTCTL_RxFFlsh (1 << 4)
|
||||
#define GRSTCTL_INTknQFlsh (1 << 3)
|
||||
#define GRSTCTL_FrmCntrRst (1 << 2)
|
||||
#define GRSTCTL_HSftRst (1 << 1)
|
||||
#define GRSTCTL_CSftRst (1 << 0)
|
||||
|
||||
#define GINTSTS HSOTG_REG(0x014)
|
||||
#define GINTMSK HSOTG_REG(0x018)
|
||||
|
||||
#define GINTSTS_WkUpInt (1 << 31)
|
||||
#define GINTSTS_SessReqInt (1 << 30)
|
||||
#define GINTSTS_DisconnInt (1 << 29)
|
||||
#define GINTSTS_ConIDStsChng (1 << 28)
|
||||
#define GINTSTS_PTxFEmp (1 << 26)
|
||||
#define GINTSTS_HChInt (1 << 25)
|
||||
#define GINTSTS_PrtInt (1 << 24)
|
||||
#define GINTSTS_FetSusp (1 << 22)
|
||||
#define GINTSTS_incompIP (1 << 21)
|
||||
#define GINTSTS_IncomplSOIN (1 << 20)
|
||||
#define GINTSTS_OEPInt (1 << 19)
|
||||
#define GINTSTS_IEPInt (1 << 18)
|
||||
#define GINTSTS_EPMis (1 << 17)
|
||||
#define GINTSTS_EOPF (1 << 15)
|
||||
#define GINTSTS_ISOutDrop (1 << 14)
|
||||
#define GINTSTS_EnumDone (1 << 13)
|
||||
#define GINTSTS_USBRst (1 << 12)
|
||||
#define GINTSTS_USBSusp (1 << 11)
|
||||
#define GINTSTS_ErlySusp (1 << 10)
|
||||
#define GINTSTS_GOUTNakEff (1 << 7)
|
||||
#define GINTSTS_GINNakEff (1 << 6)
|
||||
#define GINTSTS_NPTxFEmp (1 << 5)
|
||||
#define GINTSTS_RxFLvl (1 << 4)
|
||||
#define GINTSTS_SOF (1 << 3)
|
||||
#define GINTSTS_OTGInt (1 << 2)
|
||||
#define GINTSTS_ModeMis (1 << 1)
|
||||
#define GINTSTS_CurMod_Host (1 << 0)
|
||||
|
||||
#define GRXSTSR HSOTG_REG(0x01C)
|
||||
#define GRXSTSP HSOTG_REG(0x020)
|
||||
|
||||
#define GRXSTS_FN_MASK (0x7f << 25)
|
||||
#define GRXSTS_FN_SHIFT (25)
|
||||
|
||||
#define GRXSTS_PktSts_MASK (0xf << 17)
|
||||
#define GRXSTS_PktSts_SHIFT (17)
|
||||
#define GRXSTS_PktSts_GlobalOutNAK (0x1 << 17)
|
||||
#define GRXSTS_PktSts_OutRX (0x2 << 17)
|
||||
#define GRXSTS_PktSts_OutDone (0x3 << 17)
|
||||
#define GRXSTS_PktSts_SetupDone (0x4 << 17)
|
||||
#define GRXSTS_PktSts_SetupRX (0x6 << 17)
|
||||
|
||||
#define GRXSTS_DPID_MASK (0x3 << 15)
|
||||
#define GRXSTS_DPID_SHIFT (15)
|
||||
#define GRXSTS_ByteCnt_MASK (0x7ff << 4)
|
||||
#define GRXSTS_ByteCnt_SHIFT (4)
|
||||
#define GRXSTS_EPNum_MASK (0xf << 0)
|
||||
#define GRXSTS_EPNum_SHIFT (0)
|
||||
|
||||
#define GRXFSIZ HSOTG_REG(0x024)
|
||||
|
||||
#define GNPTXFSIZ HSOTG_REG(0x028)
|
||||
|
||||
#define GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16)
|
||||
#define GNPTXFSIZ_NPTxFDep_SHIFT (16)
|
||||
#define GNPTXFSIZ_NPTxFDep_LIMIT (0xffff)
|
||||
#define GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16)
|
||||
#define GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0)
|
||||
#define GNPTXFSIZ_NPTxFStAddr_SHIFT (0)
|
||||
#define GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff)
|
||||
#define GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0)
|
||||
|
||||
#define GNPTXSTS HSOTG_REG(0x02C)
|
||||
|
||||
#define GNPTXSTS_NPtxQTop_MASK (0x7f << 24)
|
||||
#define GNPTXSTS_NPtxQTop_SHIFT (24)
|
||||
|
||||
#define GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16)
|
||||
#define GNPTXSTS_NPTxQSpcAvail_SHIFT (16)
|
||||
#define GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff)
|
||||
|
||||
#define GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0)
|
||||
#define GNPTXSTS_NPTxFSpcAvail_SHIFT (0)
|
||||
#define GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff)
|
||||
|
||||
|
||||
#define HPTXFSIZ HSOTG_REG(0x100)
|
||||
|
||||
#define DPTXFSIZn(_a) HSOTG_REG(0x104 + (((_a) - 1) * 4))
|
||||
|
||||
#define DPTXFSIZn_DPTxFSize_MASK (0xffff << 16)
|
||||
#define DPTXFSIZn_DPTxFSize_SHIFT (16)
|
||||
#define DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff)
|
||||
#define DPTXFSIZn_DPTxFSize_LIMIT (0xffff)
|
||||
#define DPTXFSIZn_DPTxFSize(_x) ((_x) << 16)
|
||||
|
||||
#define DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0)
|
||||
#define DPTXFSIZn_DPTxFStAddr_SHIFT (0)
|
||||
|
||||
/* Device mode registers */
|
||||
#define DCFG HSOTG_REG(0x800)
|
||||
|
||||
#define DCFG_EPMisCnt_MASK (0x1f << 18)
|
||||
#define DCFG_EPMisCnt_SHIFT (18)
|
||||
#define DCFG_EPMisCnt_LIMIT (0x1f)
|
||||
#define DCFG_EPMisCnt(_x) ((_x) << 18)
|
||||
|
||||
#define DCFG_PerFrInt_MASK (0x3 << 11)
|
||||
#define DCFG_PerFrInt_SHIFT (11)
|
||||
#define DCFG_PerFrInt_LIMIT (0x3)
|
||||
#define DCFG_PerFrInt(_x) ((_x) << 11)
|
||||
|
||||
#define DCFG_DevAddr_MASK (0x7f << 4)
|
||||
#define DCFG_DevAddr_SHIFT (4)
|
||||
#define DCFG_DevAddr_LIMIT (0x7f)
|
||||
#define DCFG_DevAddr(_x) ((_x) << 4)
|
||||
|
||||
#define DCFG_NZStsOUTHShk (1 << 2)
|
||||
|
||||
#define DCFG_DevSpd_MASK (0x3 << 0)
|
||||
#define DCFG_DevSpd_SHIFT (0)
|
||||
#define DCFG_DevSpd_HS (0x0 << 0)
|
||||
#define DCFG_DevSpd_FS (0x1 << 0)
|
||||
#define DCFG_DevSpd_LS (0x2 << 0)
|
||||
#define DCFG_DevSpd_FS48 (0x3 << 0)
|
||||
|
||||
#define DCTL HSOTG_REG(0x804)
|
||||
|
||||
#define DCTL_PWROnPrgDone (1 << 11)
|
||||
#define DCTL_CGOUTNak (1 << 10)
|
||||
#define DCTL_SGOUTNak (1 << 9)
|
||||
#define DCTL_CGNPInNAK (1 << 8)
|
||||
#define DCTL_SGNPInNAK (1 << 7)
|
||||
#define DCTL_TstCtl_MASK (0x7 << 4)
|
||||
#define DCTL_TstCtl_SHIFT (4)
|
||||
#define DCTL_GOUTNakSts (1 << 3)
|
||||
#define DCTL_GNPINNakSts (1 << 2)
|
||||
#define DCTL_SftDiscon (1 << 1)
|
||||
#define DCTL_RmtWkUpSig (1 << 0)
|
||||
|
||||
#define DSTS HSOTG_REG(0x808)
|
||||
|
||||
#define DSTS_SOFFN_MASK (0x3fff << 8)
|
||||
#define DSTS_SOFFN_SHIFT (8)
|
||||
#define DSTS_SOFFN_LIMIT (0x3fff)
|
||||
#define DSTS_SOFFN(_x) ((_x) << 8)
|
||||
#define DSTS_ErraticErr (1 << 3)
|
||||
#define DSTS_EnumSpd_MASK (0x3 << 1)
|
||||
#define DSTS_EnumSpd_SHIFT (1)
|
||||
#define DSTS_EnumSpd_HS (0x0 << 1)
|
||||
#define DSTS_EnumSpd_FS (0x1 << 1)
|
||||
#define DSTS_EnumSpd_LS (0x2 << 1)
|
||||
#define DSTS_EnumSpd_FS48 (0x3 << 1)
|
||||
|
||||
#define DSTS_SuspSts (1 << 0)
|
||||
|
||||
#define DIEPMSK HSOTG_REG(0x810)
|
||||
|
||||
#define DIEPMSK_TxFIFOEmpty (1 << 7)
|
||||
#define DIEPMSK_INEPNakEffMsk (1 << 6)
|
||||
#define DIEPMSK_INTknEPMisMsk (1 << 5)
|
||||
#define DIEPMSK_INTknTXFEmpMsk (1 << 4)
|
||||
#define DIEPMSK_TimeOUTMsk (1 << 3)
|
||||
#define DIEPMSK_AHBErrMsk (1 << 2)
|
||||
#define DIEPMSK_EPDisbldMsk (1 << 1)
|
||||
#define DIEPMSK_XferComplMsk (1 << 0)
|
||||
|
||||
#define DOEPMSK HSOTG_REG(0x814)
|
||||
|
||||
#define DOEPMSK_Back2BackSetup (1 << 6)
|
||||
#define DOEPMSK_OUTTknEPdisMsk (1 << 4)
|
||||
#define DOEPMSK_SetupMsk (1 << 3)
|
||||
#define DOEPMSK_AHBErrMsk (1 << 2)
|
||||
#define DOEPMSK_EPDisbldMsk (1 << 1)
|
||||
#define DOEPMSK_XferComplMsk (1 << 0)
|
||||
|
||||
#define DAINT HSOTG_REG(0x818)
|
||||
#define DAINTMSK HSOTG_REG(0x81C)
|
||||
|
||||
#define DAINT_OutEP_SHIFT (16)
|
||||
#define DAINT_OutEP(x) (1 << ((x) + 16))
|
||||
#define DAINT_InEP(x) (1 << (x))
|
||||
|
||||
#define DTKNQR1 HSOTG_REG(0x820)
|
||||
#define DTKNQR2 HSOTG_REG(0x824)
|
||||
#define DTKNQR3 HSOTG_REG(0x830)
|
||||
#define DTKNQR4 HSOTG_REG(0x834)
|
||||
|
||||
#define DVBUSDIS HSOTG_REG(0x828)
|
||||
#define DVBUSPULSE HSOTG_REG(0x82C)
|
||||
|
||||
#define DIEPCTL0 HSOTG_REG(0x900)
|
||||
#define DOEPCTL0 HSOTG_REG(0xB00)
|
||||
#define DIEPCTL(_a) HSOTG_REG(0x900 + ((_a) * 0x20))
|
||||
#define DOEPCTL(_a) HSOTG_REG(0xB00 + ((_a) * 0x20))
|
||||
|
||||
/* EP0 specialness:
|
||||
* bits[29..28] - reserved (no SetD0PID, SetD1PID)
|
||||
* bits[25..22] - should always be zero, this isn't a periodic endpoint
|
||||
* bits[10..0] - MPS setting differenct for EP0
|
||||
*/
|
||||
#define D0EPCTL_MPS_MASK (0x3 << 0)
|
||||
#define D0EPCTL_MPS_SHIFT (0)
|
||||
#define D0EPCTL_MPS_64 (0x0 << 0)
|
||||
#define D0EPCTL_MPS_32 (0x1 << 0)
|
||||
#define D0EPCTL_MPS_16 (0x2 << 0)
|
||||
#define D0EPCTL_MPS_8 (0x3 << 0)
|
||||
|
||||
#define DxEPCTL_EPEna (1 << 31)
|
||||
#define DxEPCTL_EPDis (1 << 30)
|
||||
#define DxEPCTL_SetD1PID (1 << 29)
|
||||
#define DxEPCTL_SetOddFr (1 << 29)
|
||||
#define DxEPCTL_SetD0PID (1 << 28)
|
||||
#define DxEPCTL_SetEvenFr (1 << 28)
|
||||
#define DxEPCTL_SNAK (1 << 27)
|
||||
#define DxEPCTL_CNAK (1 << 26)
|
||||
#define DxEPCTL_TxFNum_MASK (0xf << 22)
|
||||
#define DxEPCTL_TxFNum_SHIFT (22)
|
||||
#define DxEPCTL_TxFNum_LIMIT (0xf)
|
||||
#define DxEPCTL_TxFNum(_x) ((_x) << 22)
|
||||
|
||||
#define DxEPCTL_Stall (1 << 21)
|
||||
#define DxEPCTL_Snp (1 << 20)
|
||||
#define DxEPCTL_EPType_MASK (0x3 << 18)
|
||||
#define DxEPCTL_EPType_SHIFT (18)
|
||||
#define DxEPCTL_EPType_Control (0x0 << 18)
|
||||
#define DxEPCTL_EPType_Iso (0x1 << 18)
|
||||
#define DxEPCTL_EPType_Bulk (0x2 << 18)
|
||||
#define DxEPCTL_EPType_Intterupt (0x3 << 18)
|
||||
|
||||
#define DxEPCTL_NAKsts (1 << 17)
|
||||
#define DxEPCTL_DPID (1 << 16)
|
||||
#define DxEPCTL_EOFrNum (1 << 16)
|
||||
#define DxEPCTL_USBActEp (1 << 15)
|
||||
#define DxEPCTL_NextEp_MASK (0xf << 11)
|
||||
#define DxEPCTL_NextEp_SHIFT (11)
|
||||
#define DxEPCTL_NextEp_LIMIT (0xf)
|
||||
#define DxEPCTL_NextEp(_x) ((_x) << 11)
|
||||
|
||||
#define DxEPCTL_MPS_MASK (0x7ff << 0)
|
||||
#define DxEPCTL_MPS_SHIFT (0)
|
||||
#define DxEPCTL_MPS_LIMIT (0x7ff)
|
||||
#define DxEPCTL_MPS(_x) ((_x) << 0)
|
||||
|
||||
#define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20))
|
||||
#define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20))
|
||||
|
||||
#define DxEPINT_INEPNakEff (1 << 6)
|
||||
#define DxEPINT_Back2BackSetup (1 << 6)
|
||||
#define DxEPINT_INTknEPMis (1 << 5)
|
||||
#define DxEPINT_INTknTXFEmp (1 << 4)
|
||||
#define DxEPINT_OUTTknEPdis (1 << 4)
|
||||
#define DxEPINT_Timeout (1 << 3)
|
||||
#define DxEPINT_Setup (1 << 3)
|
||||
#define DxEPINT_AHBErr (1 << 2)
|
||||
#define DxEPINT_EPDisbld (1 << 1)
|
||||
#define DxEPINT_XferCompl (1 << 0)
|
||||
|
||||
#define DIEPTSIZ0 HSOTG_REG(0x910)
|
||||
|
||||
#define DIEPTSIZ0_PktCnt_MASK (0x3 << 19)
|
||||
#define DIEPTSIZ0_PktCnt_SHIFT (19)
|
||||
#define DIEPTSIZ0_PktCnt_LIMIT (0x3)
|
||||
#define DIEPTSIZ0_PktCnt(_x) ((_x) << 19)
|
||||
|
||||
#define DIEPTSIZ0_XferSize_MASK (0x7f << 0)
|
||||
#define DIEPTSIZ0_XferSize_SHIFT (0)
|
||||
#define DIEPTSIZ0_XferSize_LIMIT (0x7f)
|
||||
#define DIEPTSIZ0_XferSize(_x) ((_x) << 0)
|
||||
|
||||
#define DOEPTSIZ0 HSOTG_REG(0xB10)
|
||||
#define DOEPTSIZ0_SUPCnt_MASK (0x3 << 29)
|
||||
#define DOEPTSIZ0_SUPCnt_SHIFT (29)
|
||||
#define DOEPTSIZ0_SUPCnt_LIMIT (0x3)
|
||||
#define DOEPTSIZ0_SUPCnt(_x) ((_x) << 29)
|
||||
|
||||
#define DOEPTSIZ0_PktCnt (1 << 19)
|
||||
#define DOEPTSIZ0_XferSize_MASK (0x7f << 0)
|
||||
#define DOEPTSIZ0_XferSize_SHIFT (0)
|
||||
|
||||
#define DIEPTSIZ(_a) HSOTG_REG(0x910 + ((_a) * 0x20))
|
||||
#define DOEPTSIZ(_a) HSOTG_REG(0xB10 + ((_a) * 0x20))
|
||||
|
||||
#define DxEPTSIZ_MC_MASK (0x3 << 29)
|
||||
#define DxEPTSIZ_MC_SHIFT (29)
|
||||
#define DxEPTSIZ_MC_LIMIT (0x3)
|
||||
#define DxEPTSIZ_MC(_x) ((_x) << 29)
|
||||
|
||||
#define DxEPTSIZ_PktCnt_MASK (0x3ff << 19)
|
||||
#define DxEPTSIZ_PktCnt_SHIFT (19)
|
||||
#define DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff)
|
||||
#define DxEPTSIZ_PktCnt_LIMIT (0x3ff)
|
||||
#define DxEPTSIZ_PktCnt(_x) ((_x) << 19)
|
||||
|
||||
#define DxEPTSIZ_XferSize_MASK (0x7ffff << 0)
|
||||
#define DxEPTSIZ_XferSize_SHIFT (0)
|
||||
#define DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff)
|
||||
#define DxEPTSIZ_XferSize_LIMIT (0x7ffff)
|
||||
#define DxEPTSIZ_XferSize(_x) ((_x) << 0)
|
||||
|
||||
#define DIEPDMA(_a) HSOTG_REG(0x914 + ((_a) * 0x20))
|
||||
#define DOEPDMA(_a) HSOTG_REG(0xB14 + ((_a) * 0x20))
|
||||
#define DTXFSTS(_a) HSOTG_REG(0x918 + ((_a) * 0x20))
|
||||
|
||||
#define EPFIFO(_a) HSOTG_REG(0x1000 + ((_a) * 0x1000))
|
||||
|
||||
#endif /* __REGS_USB_HSOTG_H */
|
|
@ -110,7 +110,6 @@ struct s3c_hsudc_ep {
|
|||
struct usb_ep ep;
|
||||
char name[20];
|
||||
struct s3c_hsudc *dev;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct list_head queue;
|
||||
u8 stopped;
|
||||
u8 wedge;
|
||||
|
@ -761,7 +760,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep,
|
|||
u32 ecr = 0;
|
||||
|
||||
hsep = our_ep(_ep);
|
||||
if (!_ep || !desc || hsep->desc || _ep->name == ep0name
|
||||
if (!_ep || !desc || hsep->ep.desc || _ep->name == ep0name
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
||||
|| hsep->bEndpointAddress != desc->bEndpointAddress
|
||||
|| ep_maxpacket(hsep) < usb_endpoint_maxp(desc))
|
||||
|
@ -783,7 +782,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep,
|
|||
writel(ecr, hsudc->regs + S3C_ECR);
|
||||
|
||||
hsep->stopped = hsep->wedge = 0;
|
||||
hsep->desc = desc;
|
||||
hsep->ep.desc = desc;
|
||||
hsep->ep.maxpacket = usb_endpoint_maxp(desc);
|
||||
|
||||
s3c_hsudc_set_halt(_ep, 0);
|
||||
|
@ -806,7 +805,7 @@ static int s3c_hsudc_ep_disable(struct usb_ep *_ep)
|
|||
struct s3c_hsudc *hsudc = hsep->dev;
|
||||
unsigned long flags;
|
||||
|
||||
if (!_ep || !hsep->desc)
|
||||
if (!_ep || !hsep->ep.desc)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&hsudc->lock, flags);
|
||||
|
@ -816,7 +815,6 @@ static int s3c_hsudc_ep_disable(struct usb_ep *_ep)
|
|||
|
||||
s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
|
||||
|
||||
hsep->desc = 0;
|
||||
hsep->ep.desc = NULL;
|
||||
hsep->stopped = 1;
|
||||
|
||||
|
@ -1006,7 +1004,6 @@ static void s3c_hsudc_initep(struct s3c_hsudc *hsudc,
|
|||
hsep->ep.maxpacket = epnum ? 512 : 64;
|
||||
hsep->ep.ops = &s3c_hsudc_ep_ops;
|
||||
hsep->fifo = hsudc->regs + S3C_BR(epnum);
|
||||
hsep->desc = 0;
|
||||
hsep->ep.desc = NULL;
|
||||
hsep->stopped = 0;
|
||||
hsep->wedge = 0;
|
||||
|
|
|
@ -1062,7 +1062,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
|
|||
|
||||
ep = to_s3c2410_ep(_ep);
|
||||
|
||||
if (!_ep || !desc || ep->desc
|
||||
if (!_ep || !desc || ep->ep.desc
|
||||
|| _ep->name == ep0name
|
||||
|| desc->bDescriptorType != USB_DT_ENDPOINT)
|
||||
return -EINVAL;
|
||||
|
@ -1075,7 +1075,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
|
|||
|
||||
local_irq_save (flags);
|
||||
_ep->maxpacket = max & 0x7ff;
|
||||
ep->desc = desc;
|
||||
ep->ep.desc = desc;
|
||||
ep->halted = 0;
|
||||
ep->bEndpointAddress = desc->bEndpointAddress;
|
||||
|
||||
|
@ -1136,7 +1136,7 @@ static int s3c2410_udc_ep_disable(struct usb_ep *_ep)
|
|||
unsigned long flags;
|
||||
u32 int_en_reg;
|
||||
|
||||
if (!_ep || !ep->desc) {
|
||||
if (!_ep || !ep->ep.desc) {
|
||||
dprintk(DEBUG_NORMAL, "%s not enabled\n",
|
||||
_ep ? ep->ep.name : NULL);
|
||||
return -EINVAL;
|
||||
|
@ -1146,7 +1146,6 @@ static int s3c2410_udc_ep_disable(struct usb_ep *_ep)
|
|||
|
||||
dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
|
||||
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->halted = 1;
|
||||
|
||||
|
@ -1195,7 +1194,7 @@ s3c2410_udc_free_request(struct usb_ep *_ep, struct usb_request *_req)
|
|||
|
||||
dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
|
||||
|
||||
if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
|
||||
if (!ep || !_req || (!ep->ep.desc && _ep->name != ep0name))
|
||||
return;
|
||||
|
||||
WARN_ON (!list_empty (&req->queue));
|
||||
|
@ -1215,7 +1214,7 @@ static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||
int fifo_count = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||
if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
|
||||
dprintk(DEBUG_NORMAL, "%s: invalid args\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1363,7 +1362,7 @@ static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value)
|
|||
unsigned long flags;
|
||||
u32 idx;
|
||||
|
||||
if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||
if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
|
||||
dprintk(DEBUG_NORMAL, "%s: inval 2\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1629,7 +1628,6 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev)
|
|||
list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
|
||||
|
||||
ep->dev = dev;
|
||||
ep->desc = NULL;
|
||||
ep->ep.desc = NULL;
|
||||
ep->halted = 0;
|
||||
INIT_LIST_HEAD (&ep->queue);
|
||||
|
|
|
@ -19,7 +19,6 @@ struct s3c2410_ep {
|
|||
unsigned long last_io; /* jiffies timestamp */
|
||||
struct usb_gadget *gadget;
|
||||
struct s3c2410_udc *dev;
|
||||
const struct usb_endpoint_descriptor *desc;
|
||||
struct usb_ep ep;
|
||||
u8 num;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
static const char longname[] = "Gadget Zero";
|
||||
|
||||
unsigned buflen = 4096;
|
||||
unsigned buflen = 4096; /* only used for bulk endpoints */
|
||||
module_param(buflen, uint, 0);
|
||||
|
||||
/*
|
||||
|
@ -170,14 +170,17 @@ static struct usb_gadget_strings *dev_strings[] = {
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
struct usb_request *alloc_ep_req(struct usb_ep *ep)
|
||||
struct usb_request *alloc_ep_req(struct usb_ep *ep, int len)
|
||||
{
|
||||
struct usb_request *req;
|
||||
|
||||
req = usb_ep_alloc_request(ep, GFP_ATOMIC);
|
||||
if (req) {
|
||||
req->length = buflen;
|
||||
req->buf = kmalloc(buflen, GFP_ATOMIC);
|
||||
if (len)
|
||||
req->length = len;
|
||||
else
|
||||
req->length = buflen;
|
||||
req->buf = kmalloc(req->length, GFP_ATOMIC);
|
||||
if (!req->buf) {
|
||||
usb_ep_free_request(ep, req);
|
||||
req = NULL;
|
||||
|
@ -206,10 +209,15 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
|
|||
}
|
||||
|
||||
void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *in, struct usb_ep *out)
|
||||
struct usb_ep *in, struct usb_ep *out,
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out)
|
||||
{
|
||||
disable_ep(cdev, in);
|
||||
disable_ep(cdev, out);
|
||||
if (iso_in)
|
||||
disable_ep(cdev, iso_in);
|
||||
if (iso_out)
|
||||
disable_ep(cdev, iso_out);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -311,7 +319,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
|
|||
device_desc.bcdDevice = cpu_to_le16(0x9999);
|
||||
}
|
||||
|
||||
|
||||
INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
|
||||
|
||||
snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
|
||||
|
|
|
@ -55,6 +55,7 @@ struct usbhsg_gpriv {
|
|||
#define USBHSG_STATUS_STARTED (1 << 0)
|
||||
#define USBHSG_STATUS_REGISTERD (1 << 1)
|
||||
#define USBHSG_STATUS_WEDGE (1 << 2)
|
||||
#define USBHSG_STATUS_SELF_POWERED (1 << 3)
|
||||
};
|
||||
|
||||
struct usbhsg_recip_handle {
|
||||
|
@ -333,7 +334,10 @@ static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv,
|
|||
struct usb_ctrlrequest *ctrl)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
|
||||
unsigned short status = 1 << USB_DEVICE_SELF_POWERED;
|
||||
unsigned short status = 0;
|
||||
|
||||
if (usbhsg_status_has(gpriv, USBHSG_STATUS_SELF_POWERED))
|
||||
status = 1 << USB_DEVICE_SELF_POWERED;
|
||||
|
||||
__usbhsg_recip_send_status(gpriv, status);
|
||||
|
||||
|
@ -879,8 +883,21 @@ static int usbhsg_get_frame(struct usb_gadget *gadget)
|
|||
return usbhs_frame_get_num(priv);
|
||||
}
|
||||
|
||||
static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
|
||||
|
||||
if (is_self)
|
||||
usbhsg_status_set(gpriv, USBHSG_STATUS_SELF_POWERED);
|
||||
else
|
||||
usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_gadget_ops usbhsg_gadget_ops = {
|
||||
.get_frame = usbhsg_get_frame,
|
||||
.set_selfpowered = usbhsg_set_selfpowered,
|
||||
.udc_start = usbhsg_gadget_start,
|
||||
.udc_stop = usbhsg_gadget_stop,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* arch/arm/plat-s3c/include/plat/udc-hs.h
|
||||
/* include/linux/platform_data/s3c-hsotg.h
|
||||
*
|
||||
* Copyright 2008 Openmoko, Inc.
|
||||
* Copyright 2008 Simtec Electronics
|
||||
|
@ -25,7 +25,8 @@ enum s3c_hsotg_dmamode {
|
|||
*/
|
||||
struct s3c_hsotg_plat {
|
||||
enum s3c_hsotg_dmamode dma;
|
||||
unsigned int is_osc : 1;
|
||||
unsigned int is_osc:1;
|
||||
int phy_type;
|
||||
|
||||
int (*phy_init)(struct platform_device *pdev, int type);
|
||||
int (*phy_exit)(struct platform_device *pdev, int type);
|
Загрузка…
Ссылка в новой задаче