diff options
Diffstat (limited to 'target/linux/lantiq/patches-3.2/0050-MIPS-adds-ifxhcd.patch')
-rw-r--r-- | target/linux/lantiq/patches-3.2/0050-MIPS-adds-ifxhcd.patch | 16604 |
1 files changed, 0 insertions, 16604 deletions
diff --git a/target/linux/lantiq/patches-3.2/0050-MIPS-adds-ifxhcd.patch b/target/linux/lantiq/patches-3.2/0050-MIPS-adds-ifxhcd.patch deleted file mode 100644 index 88348a4543..0000000000 --- a/target/linux/lantiq/patches-3.2/0050-MIPS-adds-ifxhcd.patch +++ /dev/null @@ -1,16604 +0,0 @@ -From 09071b501014528984b158bc5408d8a738ef6883 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 11 Mar 2012 15:59:39 +0100 -Subject: [PATCH 50/70] MIPS: adds ifxhcd - ---- - arch/mips/lantiq/xway/Makefile | 2 +- - arch/mips/lantiq/xway/dev-ifxhcd.c | 45 + - arch/mips/lantiq/xway/dev-ifxhcd.h | 17 + - arch/mips/lantiq/xway/sysctrl.c | 2 + - drivers/usb/Kconfig | 2 + - drivers/usb/Makefile | 2 + - drivers/usb/ifxhcd/Kconfig | 58 + - drivers/usb/ifxhcd/Makefile | 85 + - drivers/usb/ifxhcd/TagHistory | 171 ++ - drivers/usb/ifxhcd/ifxhcd.c | 2523 +++++++++++++++++++++++ - drivers/usb/ifxhcd/ifxhcd.h | 628 ++++++ - drivers/usb/ifxhcd/ifxhcd_es.c | 549 +++++ - drivers/usb/ifxhcd/ifxhcd_intr.c | 3742 +++++++++++++++++++++++++++++++++++ - drivers/usb/ifxhcd/ifxhcd_queue.c | 418 ++++ - drivers/usb/ifxhcd/ifxusb_cif.c | 1458 ++++++++++++++ - drivers/usb/ifxhcd/ifxusb_cif.h | 665 +++++++ - drivers/usb/ifxhcd/ifxusb_cif_d.c | 458 +++++ - drivers/usb/ifxhcd/ifxusb_cif_h.c | 846 ++++++++ - drivers/usb/ifxhcd/ifxusb_ctl.c | 1385 +++++++++++++ - drivers/usb/ifxhcd/ifxusb_driver.c | 970 +++++++++ - drivers/usb/ifxhcd/ifxusb_plat.h | 1018 ++++++++++ - drivers/usb/ifxhcd/ifxusb_regs.h | 1420 +++++++++++++ - drivers/usb/ifxhcd/ifxusb_version.h | 5 + - 23 files changed, 16468 insertions(+), 1 deletions(-) - create mode 100644 arch/mips/lantiq/xway/dev-ifxhcd.c - create mode 100644 arch/mips/lantiq/xway/dev-ifxhcd.h - create mode 100644 drivers/usb/ifxhcd/Kconfig - create mode 100644 drivers/usb/ifxhcd/Makefile - create mode 100644 drivers/usb/ifxhcd/TagHistory - create mode 100644 drivers/usb/ifxhcd/ifxhcd.c - create mode 100644 drivers/usb/ifxhcd/ifxhcd.h - create mode 100644 drivers/usb/ifxhcd/ifxhcd_es.c - create mode 100644 drivers/usb/ifxhcd/ifxhcd_intr.c - create mode 100644 drivers/usb/ifxhcd/ifxhcd_queue.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_cif.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_cif.h - create mode 100644 drivers/usb/ifxhcd/ifxusb_cif_d.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_cif_h.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_ctl.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_driver.c - create mode 100644 drivers/usb/ifxhcd/ifxusb_plat.h - create mode 100644 drivers/usb/ifxhcd/ifxusb_regs.h - create mode 100644 drivers/usb/ifxhcd/ifxusb_version.h - ---- a/arch/mips/lantiq/xway/Makefile -+++ b/arch/mips/lantiq/xway/Makefile -@@ -1,4 +1,4 @@ --obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o timer.o -+obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o timer.o dev-ifxhcd.o - - obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o - obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o ---- /dev/null -+++ b/arch/mips/lantiq/xway/dev-ifxhcd.c -@@ -0,0 +1,45 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org> -+ */ -+ -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/string.h> -+#include <linux/mtd/physmap.h> -+#include <linux/kernel.h> -+#include <linux/reboot.h> -+#include <linux/platform_device.h> -+#include <linux/leds.h> -+#include <linux/etherdevice.h> -+#include <linux/reboot.h> -+#include <linux/time.h> -+#include <linux/io.h> -+#include <linux/gpio.h> -+#include <linux/leds.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/irq.h> -+ -+#include <lantiq_soc.h> -+#include <lantiq_irq.h> -+#include <lantiq_platform.h> -+ -+static u64 dmamask = (u32)0x1fffffff; -+ -+static struct platform_device platform_dev = { -+ .name = "ifxusb_hcd", -+ .dev.dma_mask = &dmamask, -+}; -+ -+int __init -+xway_register_hcd(int *pins) -+{ -+ platform_dev.dev.platform_data = pins; -+ return platform_device_register(&platform_dev); -+} ---- /dev/null -+++ b/arch/mips/lantiq/xway/dev-ifxhcd.h -@@ -0,0 +1,17 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org> -+ */ -+ -+#ifndef _LTQ_DEV_HCD_H__ -+#define _LTQ_DEV_HCD_H__ -+ -+#include <lantiq_platform.h> -+ -+extern void __init xway_register_hcd(int *pin); -+ -+#endif ---- a/arch/mips/lantiq/xway/sysctrl.c -+++ b/arch/mips/lantiq/xway/sysctrl.c -@@ -166,6 +166,8 @@ void __init ltq_soc_init(void) - clkdev_add_pmu("ltq_pcie", "pdi", 1, PMU1_PCIE_PDI); - clkdev_add_pmu("ltq_pcie", "ctl", 1, PMU1_PCIE_CTL); - clkdev_add_pmu("ltq_pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); -+ clkdev_add_pmu("usb0", NULL, 0, (1<<6) | 1); -+ clkdev_add_pmu("usb1", NULL, 0, (1<<26) | (1<<27)); - } else { - clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), - ltq_danube_io_region_clock()); ---- a/drivers/usb/Kconfig -+++ b/drivers/usb/Kconfig -@@ -183,4 +183,6 @@ source "drivers/usb/gadget/Kconfig" - - source "drivers/usb/otg/Kconfig" - -+source "drivers/usb/ifxhcd/Kconfig" -+ - endif # USB_SUPPORT ---- a/drivers/usb/Makefile -+++ b/drivers/usb/Makefile -@@ -57,3 +57,5 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg/ - obj-$(CONFIG_USB_GADGET) += gadget/ - - obj-$(CONFIG_USB_COMMON) += usb-common.o -+ -+obj-$(CONFIG_USB_HOST_IFX) += ifxhcd/ ---- /dev/null -+++ b/drivers/usb/ifxhcd/Kconfig -@@ -0,0 +1,58 @@ -+ -+config USB_HOST_IFX -+ tristate "Infineon USB Host Controller Driver" -+ depends on USB -+ default n -+ help -+ Infineon USB Host Controller -+ -+config USB_HOST_IFX_B -+ bool "USB host mode on core 1 and 2" -+ depends on USB_HOST_IFX -+ help -+ Both cores run as host -+ -+#config USB_HOST_IFX_1 -+#config USB_HOST_IFX_2 -+ -+#config IFX_DANUBE -+#config IFX_AMAZON_SE -+config IFX_AR9 -+ depends on USB_HOST_IFX -+ bool "AR9" -+ -+config IFX_VR9 -+ depends on USB_HOST_IFX -+ bool "VR9" -+ -+#config USB_HOST_IFX_FORCE_USB11 -+# bool "Forced USB1.1" -+# depends on USB_HOST_IFX -+# default n -+# help -+# force to be USB 1.1 -+ -+#config USB_HOST_IFX_WITH_HS_ELECT_TST -+# bool "With HS_Electrical Test" -+# depends on USB_HOST_IFX -+# default n -+# help -+# With USBIF HSET routines -+ -+#config USB_HOST_IFX_WITH_ISO -+# bool "With ISO transfer" -+# depends on USB_HOST_IFX -+# default n -+# help -+# With USBIF ISO transfer -+ -+config USB_HOST_IFX_UNALIGNED_ADJ -+ bool "Adjust" -+ depends on USB_HOST_IFX -+ help -+ USB_HOST_IFX_UNALIGNED_ADJ -+ -+#config USB_HOST_IFX_UNALIGNED_CHK -+#config USB_HOST_IFX_UNALIGNED_NONE -+ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/Makefile -@@ -0,0 +1,85 @@ -+ -+# -+# Makefile for USB Core files and filesystem -+# -+ ifxusb_host-objs := ifxusb_driver.o -+ ifxusb_host-objs += ifxusb_ctl.o -+ ifxusb_host-objs += ifxusb_cif.o -+ ifxusb_host-objs += ifxusb_cif_h.o -+ ifxusb_host-objs += ifxhcd.o -+ ifxusb_host-objs += ifxhcd_es.o -+ ifxusb_host-objs += ifxhcd_intr.o -+ ifxusb_host-objs += ifxhcd_queue.o -+ -+ifeq ($(CONFIG_IFX_TWINPASS),y) -+ EXTRA_CFLAGS += -D__IS_TWINPASS__ -+endif -+ifeq ($(CONFIG_IFX_DANUBE),y) -+ EXTRA_CFLAGS += -D__IS_DANUBE__ -+endif -+ifeq ($(CONFIG_IFX_AMAZON_SE),y) -+ EXTRA_CFLAGS += -D__IS_AMAZON_SE__ -+endif -+ifeq ($(CONFIG_IFX_AR9),y) -+ EXTRA_CFLAGS += -D__IS_AR9__ -+endif -+ifeq ($(CONFIG_IFX_AMAZON_S),y) -+ EXTRA_CFLAGS += -D__IS_AR9__ -+endif -+ifeq ($(CONFIG_IFX_VR9),y) -+ EXTRA_CFLAGS += -D__IS_VR9__ -+endif -+ -+ifeq ($(CONFIG_USB_HOST_IFX),y) -+ EXTRA_CFLAGS += -Dlinux -D__LINUX__ -+ EXTRA_CFLAGS += -D__IS_HOST__ -+ EXTRA_CFLAGS += -D__KERNEL__ -+endif -+ -+ifeq ($(CONFIG_USB_HOST_IFX),m) -+ EXTRA_CFLAGS += -Dlinux -D__LINUX__ -+ EXTRA_CFLAGS += -D__IS_HOST__ -+ EXTRA_CFLAGS += -D__KERNEL__ -+endif -+ -+ifeq ($(CONFIG_USB_DEBUG),y) -+ EXTRA_CFLAGS += -D__DEBUG__ -+ EXTRA_CFLAGS += -D__ENABLE_DUMP__ -+endif -+ -+ifeq ($(CONFIG_USB_HOST_IFX_B),y) -+ EXTRA_CFLAGS += -D__IS_DUAL__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_1),y) -+ EXTRA_CFLAGS += -D__IS_FIRST__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_2),y) -+ EXTRA_CFLAGS += -D__IS_SECOND__ -+endif -+ -+ifeq ($(CONFIG_USB_HOST_IFX_FORCE_USB11),y) -+ EXTRA_CFLAGS += -D__FORCE_USB11__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_WITH_HS_ELECT_TST),y) -+ EXTRA_CFLAGS += -D__WITH_HS_ELECT_TST__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_WITH_ISO),y) -+ EXTRA_CFLAGS += -D__EN_ISOC__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_ADJ),y) -+ EXTRA_CFLAGS += -D__UNALIGNED_BUFFER_ADJ__ -+endif -+ifeq ($(CONFIG_USB_HOST_IFX_UNALIGNED_CHK),y) -+ EXTRA_CFLAGS += -D__UNALIGNED_BUFFER_CHK__ -+endif -+ -+# EXTRA_CFLAGS += -D__DYN_SOF_INTR__ -+ EXTRA_CFLAGS += -D__UEIP__ -+# EXTRA_CFLAGS += -D__EN_ISOC__ -+# EXTRA_CFLAGS += -D__EN_ISOC_SPLIT__ -+ -+## 20110628 AVM/WK New flag for less SOF IRQs -+ EXTRA_CFLAGS += -D__USE_TIMER_4_SOF__ -+ -+obj-$(CONFIG_USB_HOST_IFX) += ifxusb_host.o -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/TagHistory -@@ -0,0 +1,171 @@ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://embeddedvm/home/SVN/drivers/usb_host20/tags/5.18-r240-non_musb_ar9_vr9-SOF_Timer_Fixed -+| Erzeugt mit SVN-Tagger Version 3.74. -++----------------------------------------------------------------------+ -+FIX - Korrektur bei der SOF-Timer/IRQ Steuerung. (Bug in Tag 5.17) -+FIX - Fehlerbehandlung an mehreren Stellen korrigiert bzw. eingebaut. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://embeddedvm/home/SVN/drivers/usb_host20/tags/5.17-r237-non_musb_ar9_vr9-2_6_32_41_Kompatibel -+| Erzeugt mit SVN-Tagger Version 3.73. -++----------------------------------------------------------------------+ -+FIX - Kompatiblität zum Update auf Kernel 2.6.32-41. Weiterhin für 28er geeignet. -+ENH - Reduktion der Interrruptlast durch Nutzung eines hrtimers anstatt SOF-IRQ. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.16-r208-non_musb_ar9_vr9-20110421_Zero_Paket_Optimiert -+| Erzeugt mit SVN-Tagger Version 3.66. -++----------------------------------------------------------------------+ -+ -+FIX - VR9 / AR9 - Zero Packet. Optimierung korrigiert. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.15-r205-non_musb_ar9_vr9-20110421_Zero_Paket_WA_funktioniert -+| Erzeugt mit SVN-Tagger Version 3.66. -++----------------------------------------------------------------------+ -+ -+FIX - VR9 / AR9 - "Zero Packet" funktioniert nun wirklich. Letzter Tag hatte einen Bug. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.14-r202-non_musb_ar9_vr9-20110420_Zero_Paket_WA -+| Erzeugt mit SVN-Tagger Version 3.66. -++----------------------------------------------------------------------+ -+ -+FIX - VR9 / AR9 - Zero Packet Workaround: ZLP wird nun geschickt wenn URB_ZERO_PACKET aktiv ist. -+ Wird von LTE Altair Firmware benoetig. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.13-r199-non_musb_ar9_vr9-20110310_Init_Fix -+| Erzeugt mit SVN-Tagger Version 3.64. -++----------------------------------------------------------------------+ -+ -+FIX - VR9 / AR9 - Timing der Initialisierungsphase angepasst zum Kernel 2.6.28 mit UGW-4.3.1. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.12-r184-non_musb_ar9_vr9-20110118_Full_Speed_Fix -+| Erzeugt mit SVN-Tagger Version 3.58. -++----------------------------------------------------------------------+ -+AR9/VR9 (3370,6840,7320): -+Makefile - FIX - (Workaround) Debug Modus hilft gegen Enumerationsfehler bei Full Speed Drucker. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.11-r175-non_musb_ar9_vr9-20101220_VR9_2_Ports_DMA_Fix -+| Erzeugt mit SVN-Tagger Version 3.58. -++----------------------------------------------------------------------+ -+ -+FIX - VR9 - Workaround DMA Burst Size. Wenn beiden USB Ports benutzt werden, geht der USB Host nicht mehr. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.10-r169-non_musb_ar9_vr9-Fix_Spontan_Reboot -+| Erzeugt mit SVN-Tagger Version 3.58. -++----------------------------------------------------------------------+ -+ -+FIX - Endlosschleife führte zu einem spontanen Reboot. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.9-r166-non_musb_ar9_vr9-20101112_deferred_completion -+| Erzeugt mit SVN-Tagger Version 3.58. -++----------------------------------------------------------------------+ -+ -+ENH - Deferred URB Completion Mechanismus eingebaut. Nun ca. 10% schneller bei usb-storage. -+ -+FIX - PING Flow Control gefixt. -+FIX - Channel Halt wird nun immer angerufen. (Split Transaction wurde nicht erfolgreich gestoppt). -+FIX - Spinlock Benutzung verbessert. Mehr Stabilitaet. -+ -+CHG - Ubersetztungsoption __DEBUG__ ist nun abhaengig von CONFIG_USB_DEBUG -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.8-r149-non_musb_ar9_vr9-20100827_LTE_Interrupt_EP_Fix -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+AR9/VR9 - FIX - Interrupt Packets gingen verloren, wegen falschem Timing beim OddFrame Bit. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.7-r142-non_musb_ar9_vr9-20100728_Unaligned_Buf_Fix -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+FIX - "Unaligned Data" Flag wieder nach Transfer geloescht. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.6-r133-non_musb_ar9_vr9-20100714_Toggle_Datenverlust_Fix -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+TL5508 - Einige UMTS Modems funktionierten nicht korrekt an der 7320 (AR9). -+FIX - USB Data Toggle des usbcore benutzen. Datenverlust nach EP-Halt. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.5-r130-non_musb_ar9_vr9-20100712_USB_Ports_abschaltbar -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+Power - Fix - Beide USB Port abschaltbar bei rmmod. -+rmmod - FIX - URB_Dequeue funktionierte beim Entladen des Treibers nicht (mehrere Ursachen). -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.4-r126-non_musb_ar9_vr9-20100701_Lost_Interrupt_Workaround -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+FIX - Workaround wegen verpasstem Interrupt, bei Full-Speed Interrupt EP. -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.3-r123-non_musb_ar9_vr9-20100630_UMTS_Fixes -+| Erzeugt mit SVN-Tagger Version 3.57. -++----------------------------------------------------------------------+ -+FIX - Full-Speed Interrupt Endpoint hinter Hi-Speed Hub funktioniert nun (UMTS Modems) -+FIX - usb_hcd_link_urb_from_ep API von USBCore muss benutzt werden. -+FIX - Interrupt URBs nicht bei NAK completen. -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.2-r114-non_musb_ar9_vr9-20100520_StickAndSurf_funktioniert -+| Erzeugt mit SVN-Tagger Version 3.56. -++----------------------------------------------------------------------+ -+- Merge mit neuen LANTIQ Sourcen "3.0alpha B100312" -+- Fix - Spin_lock eingebaut, Stick&Surf funktioniert nun -+ -+- DEP - CONFIG_USB_HOST_IFX_WITH_ISO wird nicht unterstuetzt: In der Kernel Config deaktivieren. -+ -+ -+ -++----------------------------------------------------------------------+ -+| TAG: svn://EmbeddedVM/home/SVN/drivers/usb_host20/tags/5.1-r107-non_musb_ar9_vr9-20100505_IFXUSB_Host_mit_Energiemonitor -+| Erzeugt mit SVN-Tagger Version 3.56. -++----------------------------------------------------------------------+ -+USB Host Treiber für AR9 und VR9 -+-------------------------------- -+FIX - Toggle Error nach STALL - Einfacher Workaround - Nun werden Massenspeicherpartitionen erkannt! -+AVM_POWERMETER - USB Energiemonitor Support. -+ -+Bekanntes Problem: Stick and Surf funktioniert nur sporadisch, weil CONTROL_IRQ manchmal ausbleibt. -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxhcd.c -@@ -0,0 +1,2523 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxhcd.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the structures, constants, and interfaces for -+ ** the Host Contoller Driver (HCD). -+ ** -+ ** The Host Controller Driver (HCD) is responsible for translating requests -+ ** from the USB Driver into the appropriate actions on the IFXUSB controller. -+ ** It isolates the USBD from the specifics of the controller by providing an -+ ** API to the USBD. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxhcd.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the implementation of the HCD. In Linux, -+ the HCD implements the hc_driver API. -+*/ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+ -+#include <linux/device.h> -+ -+#include <linux/errno.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/string.h> -+ -+#include <linux/dma-mapping.h> -+ -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+#include "ifxhcd.h" -+ -+#include <asm/irq.h> -+ -+#ifdef CONFIG_AVM_POWERMETER -+#include <linux/avm_power.h> -+#endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/ -+ -+#ifdef __DEBUG__ -+ static void dump_urb_info(struct urb *_urb, char* _fn_name); -+ static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh); -+#endif -+ -+ -+/*! -+ \brief Sets the final status of an URB and returns it to the device driver. Any -+ required cleanup of the URB is performed. -+ */ -+void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status) -+{ -+ struct urb *urb=NULL; -+ unsigned long flags = 0; -+ -+ /*== AVM/BC 20101111 Function called with Lock ==*/ -+ //SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ if (!list_empty(&_urbd->urbd_list_entry)) -+ list_del_init (&_urbd->urbd_list_entry); -+ -+ if(!_urbd->urb) -+ { -+ IFX_ERROR("%s: invalid urb\n",__func__); -+ /*== AVM/BC 20101111 Function called with Lock ==*/ -+ //SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ return; -+ } -+ -+ urb=_urbd->urb; -+ -+ #ifdef __DEBUG__ -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) -+ { -+ IFX_PRINT("%s: _urbd %p, urb %p, device %d, ep %d %s/%s, status=%d\n", -+ __func__, _urbd,_urbd->urb, usb_pipedevice(_urbd->urb->pipe), -+ usb_pipeendpoint(_urbd->urb->pipe), -+ usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT", -+ (_urbd->is_in) ? "IN" : "OUT", -+ _status); -+ if (_urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ int i; -+ for (i = 0; i < _urbd->urb->number_of_packets; i++) -+ IFX_PRINT(" ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status); -+ } -+ } -+ #endif -+ -+ if (!_urbd->epqh) -+ IFX_ERROR("%s: invalid epqd\n",__func__); -+ -+ #if defined(__UNALIGNED_BUFFER_ADJ__) -+ else if(_urbd->is_active) -+ { -+ if( _urbd->epqh->aligned_checked && -+ _urbd->epqh->using_aligned_buf && -+ _urbd->xfer_buff && -+ _urbd->is_in ) -+ memcpy(_urbd->xfer_buff,_urbd->epqh->aligned_buf,_urbd->xfer_len); -+ _urbd->epqh->using_aligned_buf=0; -+ _urbd->epqh->using_aligned_setup=0; -+ _urbd->epqh->aligned_checked=0; -+ } -+ #endif -+ -+ urb->status = _status; -+ urb->hcpriv=NULL; -+ kfree(_urbd); -+ -+ usb_hcd_unlink_urb_from_ep(ifxhcd_to_syshcd(_ifxhcd), urb); -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ -+// usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb); -+ usb_hcd_giveback_urb(ifxhcd_to_syshcd(_ifxhcd), urb, _status); -+ -+ /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+} -+ -+/*== AVM/BC 20101111 URB Complete deferred -+ * Must be called with Spinlock -+ */ -+ -+/*! -+ \brief Inserts an urbd structur in the completion list. The urbd will be -+ later completed by select_eps_sub -+ */ -+void defer_ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status) -+{ -+ -+ _urbd->status = _status; -+ -+ //Unlink Urbd from epqh / Insert it into the complete list -+ list_move_tail(&_urbd->urbd_list_entry, &_ifxhcd->urbd_complete_list); -+ -+} -+ -+/*! -+ \brief Processes all the URBs in a single EPQHs. Completes them with -+ status and frees the URBD. -+ */ -+//static -+void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status) -+{ -+ struct list_head *urbd_item; -+ ifxhcd_urbd_t *urbd; -+ -+ if(!_epqh) -+ return; -+ -+ for (urbd_item = _epqh->urbd_list.next; -+ urbd_item != &_epqh->urbd_list; -+ urbd_item = _epqh->urbd_list.next) -+ { -+ urbd = list_entry(urbd_item, ifxhcd_urbd_t, urbd_list_entry); -+ ifxhcd_complete_urb(_ifxhcd, urbd, _status); -+ } -+} -+ -+ -+/*! -+ \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with -+ -ETIMEDOUT and frees the URBD. -+ */ -+//static -+void epqh_list_free(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list) -+{ -+ struct list_head *item; -+ ifxhcd_epqh_t *epqh; -+ -+ if (!_epqh_list) -+ return; -+ if (_epqh_list->next == NULL) /* The list hasn't been initialized yet. */ -+ return; -+ -+ /* Ensure there are no URBDs or URBs left. */ -+ for (item = _epqh_list->next; item != _epqh_list; item = _epqh_list->next) -+ { -+ epqh = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ kill_all_urbs_in_epqh(_ifxhcd, epqh, -ETIMEDOUT); -+ ifxhcd_epqh_free(epqh); -+ } -+} -+ -+ -+ -+//static -+void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd) -+{ -+ unsigned long flags; -+ -+ /*== AVM/BC 20101111 - 2.6.28 Needs Spinlock ==*/ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_active ); -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_np_ready ); -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_active ); -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_intr_ready ); -+ #ifdef __EN_ISOC__ -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_active ); -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_isoc_ready ); -+ #endif -+ epqh_list_free(_ifxhcd, &_ifxhcd->epqh_stdby ); -+ -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ -+} -+ -+ -+/*! -+ \brief This function is called to handle the disconnection of host port. -+ */ -+int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd) -+{ -+ IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd); -+ -+ /* Set status flags for the hub driver. */ -+ _ifxhcd->flags.b.port_connect_status_change = 1; -+ _ifxhcd->flags.b.port_connect_status = 0; -+ -+ /* -+ * Shutdown any transfers in process by clearing the Tx FIFO Empty -+ * interrupt mask and status bits and disabling subsequent host -+ * channel interrupts. -+ */ -+ { -+ gint_data_t intr = { .d32 = 0 }; -+ intr.b.nptxfempty = 1; -+ intr.b.ptxfempty = 1; -+ intr.b.hcintr = 1; -+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintmsk, intr.d32, 0); -+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintsts, intr.d32, 0); -+ } -+ -+ /* Respond with an error status to all URBs in the schedule. */ -+ epqh_list_free_all(_ifxhcd); -+ -+ /* Clean up any host channels that were in use. */ -+ { -+ int num_channels; -+ ifxhcd_hc_t *channel; -+ ifxusb_hc_regs_t *hc_regs; -+ hcchar_data_t hcchar; -+ int i; -+ -+ num_channels = _ifxhcd->core_if.params.host_channels; -+ -+ for (i = 0; i < num_channels; i++) -+ { -+ channel = &_ifxhcd->ifxhc[i]; -+ if (list_empty(&channel->hc_list_entry)) -+ { -+ hc_regs = _ifxhcd->core_if.hc_regs[i]; -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chen) -+ { -+ /* Halt the channel. */ -+ hcchar.b.chdis = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ } -+ list_add_tail(&channel->hc_list_entry, &_ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel); -+ } -+ } -+ } -+ return 1; -+} -+ -+ -+/*! -+ \brief Frees secondary storage associated with the ifxhcd_hcd structure contained -+ in the struct usb_hcd field. -+ */ -+static void ifxhcd_freeextra(struct usb_hcd *_syshcd) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd); -+ -+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n"); -+ -+ /* Free memory for EPQH/URBD lists */ -+ epqh_list_free_all(ifxhcd); -+ -+ /* Free memory for the host channels. */ -+ ifxusb_free_buf(ifxhcd->status_buf); -+ return; -+} -+#ifdef __USE_TIMER_4_SOF__ -+static enum hrtimer_restart ifxhcd_timer_func(struct hrtimer *timer) { -+ ifxhcd_hcd_t *ifxhcd = container_of(timer, ifxhcd_hcd_t, hr_timer); -+ -+ ifxhcd_handle_intr(ifxhcd); -+ -+ return HRTIMER_NORESTART; -+} -+#endif -+ -+/*! -+ \brief Initializes the HCD. This function allocates memory for and initializes the -+ static parts of the usb_hcd and ifxhcd_hcd structures. It also registers the -+ USB bus with the core and calls the hc_driver->start() function. It returns -+ a negative error on failure. -+ */ -+int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd) -+{ -+ int retval = 0; -+ struct usb_hcd *syshcd = NULL; -+ -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n"); -+ -+ spin_lock_init(&_ifxhcd->lock); -+#ifdef __USE_TIMER_4_SOF__ -+ hrtimer_init(&_ifxhcd->hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ _ifxhcd->hr_timer.function = ifxhcd_timer_func; -+#endif -+ _ifxhcd->hc_driver.description = _ifxhcd->core_if.core_name; -+ _ifxhcd->hc_driver.product_desc = "IFX USB Controller"; -+ //_ifxhcd->hc_driver.hcd_priv_size = sizeof(ifxhcd_hcd_t); -+ _ifxhcd->hc_driver.hcd_priv_size = sizeof(unsigned long); -+ _ifxhcd->hc_driver.irq = ifxhcd_irq; -+ _ifxhcd->hc_driver.flags = HCD_MEMORY | HCD_USB2; -+ _ifxhcd->hc_driver.start = ifxhcd_start; -+ _ifxhcd->hc_driver.stop = ifxhcd_stop; -+ //_ifxhcd->hc_driver.reset = -+ //_ifxhcd->hc_driver.suspend = -+ //_ifxhcd->hc_driver.resume = -+ _ifxhcd->hc_driver.urb_enqueue = ifxhcd_urb_enqueue; -+ _ifxhcd->hc_driver.urb_dequeue = ifxhcd_urb_dequeue; -+ _ifxhcd->hc_driver.endpoint_disable = ifxhcd_endpoint_disable; -+ _ifxhcd->hc_driver.get_frame_number = ifxhcd_get_frame_number; -+ _ifxhcd->hc_driver.hub_status_data = ifxhcd_hub_status_data; -+ _ifxhcd->hc_driver.hub_control = ifxhcd_hub_control; -+ //_ifxhcd->hc_driver.hub_suspend = -+ //_ifxhcd->hc_driver.hub_resume = -+ -+ /* Allocate memory for and initialize the base HCD and */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) -+ syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->core_if.core_name); -+#else -+ syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id); -+#endif -+ -+ if (syshcd == NULL) -+ { -+ retval = -ENOMEM; -+ goto error1; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) -+ syshcd->has_tt = 1; -+#endif -+ -+ syshcd->rsrc_start = (unsigned long)_ifxhcd->core_if.core_global_regs; -+ syshcd->regs = (void *)_ifxhcd->core_if.core_global_regs; -+ syshcd->self.otg_port = 0; -+ -+ //*((unsigned long *)(&(syshcd->hcd_priv)))=(unsigned long)_ifxhcd; -+ //*((unsigned long *)(&(syshcd->hcd_priv[0])))=(unsigned long)_ifxhcd; -+ syshcd->hcd_priv[0]=(unsigned long)_ifxhcd; -+ _ifxhcd->syshcd=syshcd; -+ -+ INIT_LIST_HEAD(&_ifxhcd->epqh_np_active ); -+ INIT_LIST_HEAD(&_ifxhcd->epqh_np_ready ); -+ INIT_LIST_HEAD(&_ifxhcd->epqh_intr_active ); -+ INIT_LIST_HEAD(&_ifxhcd->epqh_intr_ready ); -+ #ifdef __EN_ISOC__ -+ INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_active ); -+ INIT_LIST_HEAD(&_ifxhcd->epqh_isoc_ready ); -+ #endif -+ INIT_LIST_HEAD(&_ifxhcd->epqh_stdby ); -+ INIT_LIST_HEAD(&_ifxhcd->urbd_complete_list); -+ -+ /* -+ * Create a host channel descriptor for each host channel implemented -+ * in the controller. Initialize the channel descriptor array. -+ */ -+ INIT_LIST_HEAD(&_ifxhcd->free_hc_list); -+ { -+ int num_channels = _ifxhcd->core_if.params.host_channels; -+ int i; -+ for (i = 0; i < num_channels; i++) -+ { -+ _ifxhcd->ifxhc[i].hc_num = i; -+ IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i); -+ } -+ } -+ -+ /* Set device flags indicating whether the HCD supports DMA. */ -+ if(_ifxhcd->dev->dma_mask) -+ *(_ifxhcd->dev->dma_mask) = ~0; -+ _ifxhcd->dev->coherent_dma_mask = ~0; -+ -+ /* -+ * Finish generic HCD initialization and start the HCD. This function -+ * allocates the DMA buffer pool, registers the USB bus, requests the -+ * IRQ line, and calls ifxusb_hcd_start method. -+ */ -+// retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, SA_INTERRUPT|SA_SHIRQ); -+ retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, IRQF_DISABLED | IRQF_SHARED ); -+ if (retval < 0) -+ goto error2; -+ -+ /* -+ * Allocate space for storing data on status transactions. Normally no -+ * data is sent, but this space acts as a bit bucket. This must be -+ * done after usb_add_hcd since that function allocates the DMA buffer -+ * pool. -+ */ -+ _ifxhcd->status_buf = ifxusb_alloc_buf(IFXHCD_STATUS_BUF_SIZE, 1); -+ -+ if (_ifxhcd->status_buf) -+ { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum); -+#else -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->dev->bus_id, syshcd->self.busnum); -+#endif -+ return 0; -+ } -+ IFX_ERROR("%s: status_buf allocation failed\n", __func__); -+ -+ /* Error conditions */ -+ usb_remove_hcd(syshcd); -+error2: -+ ifxhcd_freeextra(syshcd); -+ usb_put_hcd(syshcd); -+error1: -+ return retval; -+} -+ -+/*! -+ \brief Removes the HCD. -+ Frees memory and resources associated with the HCD and deregisters the bus. -+ */ -+void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd) -+{ -+ struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd); -+ -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n"); -+ -+/* == AVM/WK 20100709 - Fix: Order changed, disable IRQs not before remove_hcd == */ -+ -+ usb_remove_hcd(syshcd); -+ -+ /* Turn off all interrupts */ -+ ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0); -+ ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0); -+ -+ ifxhcd_freeextra(syshcd); -+ -+ usb_put_hcd(syshcd); -+ -+ return; -+} -+ -+ -+/* ========================================================================= -+ * Linux HC Driver Functions -+ * ========================================================================= */ -+ -+/*! -+ \brief Initializes the IFXUSB controller and its root hub and prepares it for host -+ mode operation. Activates the root port. Returns 0 on success and a negative -+ error code on failure. -+ Called by USB stack. -+ */ -+int ifxhcd_start(struct usb_hcd *_syshcd) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd); -+ ifxusb_core_if_t *core_if = &ifxhcd->core_if; -+ struct usb_bus *bus; -+ -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n"); -+ -+ bus = hcd_to_bus(_syshcd); -+ -+ /* Initialize the bus state. */ -+ _syshcd->state = HC_STATE_RUNNING; -+ -+ /* Initialize and connect root hub if one is not already attached */ -+ if (bus->root_hub) -+ { -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n"); -+ /* Inform the HUB driver to resume. */ -+ usb_hcd_resume_root_hub(_syshcd); -+ } -+ -+ ifxhcd->flags.d32 = 0; -+ -+ /* Put all channels in the free channel list and clean up channel states.*/ -+ { -+ struct list_head *item; -+ item = ifxhcd->free_hc_list.next; -+ while (item != &ifxhcd->free_hc_list) -+ { -+ list_del(item); -+ item = ifxhcd->free_hc_list.next; -+ } -+ } -+ { -+ int num_channels = ifxhcd->core_if.params.host_channels; -+ int i; -+ for (i = 0; i < num_channels; i++) -+ { -+ ifxhcd_hc_t *channel; -+ channel = &ifxhcd->ifxhc[i]; -+ list_add_tail(&channel->hc_list_entry, &ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&ifxhcd->core_if, channel); -+ } -+ } -+ /* Initialize the USB core for host mode operation. */ -+ -+ ifxusb_host_enable_interrupts(core_if); -+ ifxusb_enable_global_interrupts(core_if); -+ ifxusb_phy_power_on (core_if); -+ -+ ifxusb_vbus_init(core_if); -+ -+ /* Turn on the vbus power. */ -+ { -+ hprt0_data_t hprt0; -+ hprt0.d32 = ifxusb_read_hprt0(core_if); -+ -+ IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr); -+ if (hprt0.b.prtpwr == 0 ) -+ { -+ hprt0.b.prtpwr = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ ifxusb_vbus_on(core_if); -+ } -+ } -+ return 0; -+} -+ -+ -+/*! -+ \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are -+ stopped. -+ */ -+void ifxhcd_stop(struct usb_hcd *_syshcd) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd); -+ hprt0_data_t hprt0 = { .d32=0 }; -+ -+ IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n"); -+ -+ /* Turn off all interrupts. */ -+ ifxusb_disable_global_interrupts(&ifxhcd->core_if ); -+ ifxusb_host_disable_interrupts(&ifxhcd->core_if ); -+#ifdef __USE_TIMER_4_SOF__ -+ hrtimer_cancel(&ifxhcd->hr_timer); -+#endif -+ /* -+ * The root hub should be disconnected before this function is called. -+ * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue) -+ * and the EPQH lists (via ..._hcd_endpoint_disable). -+ */ -+ -+ /* Turn off the vbus power */ -+ IFX_PRINT("PortPower off\n"); -+ -+ ifxusb_vbus_off(&ifxhcd->core_if ); -+ -+ ifxusb_vbus_free(&ifxhcd->core_if ); -+ -+ hprt0.b.prtpwr = 0; -+ ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32); -+ return; -+} -+ -+/*! -+ \brief Returns the current frame number -+ */ -+int ifxhcd_get_frame_number(struct usb_hcd *_syshcd) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd); -+ hfnum_data_t hfnum; -+ -+ hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum); -+ -+ return hfnum.b.frnum; -+} -+ -+/*! -+ \brief Starts processing a USB transfer request specified by a USB Request Block -+ (URB). mem_flags indicates the type of memory allocation to use while -+ processing this URB. -+ */ -+int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd, -+ /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/ -+ struct urb *_urb, -+ gfp_t _mem_flags) -+{ -+ int retval = 0; -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd); -+ struct usb_host_endpoint *_sysep = ifxhcd_urb_to_endpoint(_urb); -+ ifxhcd_epqh_t *epqh; -+ -+ #ifdef __DEBUG__ -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) -+ dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue"); -+ #endif //__DEBUG__ -+ -+ if (!ifxhcd->flags.b.port_connect_status) /* No longer connected. */ -+ return -ENODEV; -+ -+ #ifndef __EN_ISOC__ -+ if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) -+ { -+ IFX_ERROR("ISOC transfer not supported!!!\n"); -+ return -ENODEV; -+ } -+ #endif -+ -+ retval=ifxhcd_urbd_create (ifxhcd,_urb); -+ -+ if (retval) -+ { -+ IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n"); -+ return retval; -+ } -+ epqh = (ifxhcd_epqh_t *) _sysep->hcpriv; -+ ifxhcd_epqh_ready(ifxhcd, epqh); -+ -+ select_eps(ifxhcd); -+ //enable_sof(ifxhcd); -+ { -+ gint_data_t gintsts; -+ gintsts.d32=0; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32); -+ } -+ -+ return retval; -+} -+ -+/*! -+ \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate -+ success. -+ */ -+int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd, -+ struct urb *_urb, int status /* Parameter neu in 2.6.28 */) -+{ -+ unsigned long flags; -+ ifxhcd_hcd_t *ifxhcd; -+ ifxhcd_urbd_t *urbd; -+ ifxhcd_epqh_t *epqh; -+ int is_active=0; -+ int rc; -+ -+ struct usb_host_endpoint *_sysep; -+ -+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n"); -+ -+ #ifndef __EN_ISOC__ -+ if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) -+ return 0; -+ #endif -+ -+ _sysep = ifxhcd_urb_to_endpoint(_urb); -+ -+ ifxhcd = syshcd_to_ifxhcd(_syshcd); -+ -+ SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags); -+ -+ /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/ -+ rc = usb_hcd_check_unlink_urb(_syshcd, _urb, status); -+ if (rc) { -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+ return rc; -+ } -+ -+ urbd = (ifxhcd_urbd_t *) _urb->hcpriv; -+ -+ if(_sysep) -+ epqh = (ifxhcd_epqh_t *) _sysep->hcpriv; -+ else -+ epqh = (ifxhcd_epqh_t *) urbd->epqh; -+ -+ if(epqh!=urbd->epqh) -+ IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh); -+ -+ #ifdef __DEBUG__ -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) -+ { -+ dump_urb_info(_urb, "ifxhcd_urb_dequeue"); -+ if (epqh->is_active) -+ dump_channel_info(ifxhcd, epqh); -+ } -+ #endif //__DEBUG__ -+ -+ if(!epqh->hc) -+ epqh->is_active=0; -+ else if (!ifxhcd->flags.b.port_connect_status) -+ epqh->is_active=0; -+ else if (epqh->is_active && urbd->is_active) -+ { -+ /*== AVM/WK 20100709 - halt channel only if really started ==*/ -+ //if (epqh->hc->xfer_started && !epqh->hc->wait_for_sof) { -+ /*== AVM/WK 20101112 - halt channel if started ==*/ -+ if (epqh->hc->xfer_started) { -+ /* -+ * If still connected (i.e. in host mode), halt the -+ * channel so it can be used for other transfers. If -+ * no longer connected, the host registers can't be -+ * written to halt the channel since the core is in -+ * device mode. -+ */ -+ /* == 20110803 AVM/WK FIX propagate status == */ -+ if (_urb->status == -EINPROGRESS) { -+ _urb->status = status; -+ } -+ ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE); -+ epqh->hc = NULL; -+ is_active=1; -+ } -+ } -+ -+ if(is_active) -+ { -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+ } -+ else -+ { -+ list_del_init(&urbd->urbd_list_entry); -+ kfree (urbd); -+ -+ /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/ -+ usb_hcd_unlink_urb_from_ep(_syshcd, _urb); -+ -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+ _urb->hcpriv = NULL; -+// usb_hcd_giveback_urb(_syshcd, _urb); -+ usb_hcd_giveback_urb(_syshcd, _urb, status /* neu in 2.6.28 */); -+ select_eps(ifxhcd); -+ } -+ -+ return 0; -+} -+ -+ -+ -+/*! -+ \brief Frees resources in the IFXUSB controller related to a given endpoint. Also -+ clears state in the HCD related to the endpoint. Any URBs for the endpoint -+ must already be dequeued. -+ */ -+void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd, -+ struct usb_host_endpoint *_sysep) -+{ -+ ifxhcd_epqh_t *epqh; -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd); -+ unsigned long flags; -+ -+ int retry = 0; -+ -+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, " -+ "endpoint=%d\n", _sysep->desc.bEndpointAddress, -+ ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress)); -+ -+ SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags); -+ if((uint32_t)_sysep>=0x80000000 && (uint32_t)_sysep->hcpriv>=(uint32_t)0x80000000) -+ { -+ epqh = (ifxhcd_epqh_t *)(_sysep->hcpriv); -+ if (epqh && epqh->sysep==_sysep) -+ { -+ -+#if 1 /*== AVM/BC 20101111 CHG Option active: Kill URBs when disabling EP ==*/ -+ while (!list_empty(&epqh->urbd_list)) -+ { -+ if (retry++ > 250) -+ { -+ IFX_WARN("IFXUSB HCD EP DISABLE:" -+ " URBD List for this endpoint is not empty\n"); -+ break; -+ } -+ kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT); -+ } -+#else -+ while (!list_empty(&epqh->urbd_list)) -+ { -+ /** Check that the QTD list is really empty */ -+ if (retry++ > 250) -+ { -+ IFX_WARN("IFXUSB HCD EP DISABLE:" -+ " URBD List for this endpoint is not empty\n"); -+ break; -+ } -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+ schedule_timeout_uninterruptible(1); -+ SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags); -+ } -+#endif -+ -+ ifxhcd_epqh_free(epqh); -+ _sysep->hcpriv = NULL; -+ } -+ } -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+} -+ -+ -+/*! -+ \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if -+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid -+ * interrupt. -+ * -+ * This function is called by the USB core when an interrupt occurs -+ */ -+irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd); -+ int32_t retval=0; -+ -+ //mask_and_ack_ifx_irq (ifxhcd->core_if.irq); -+ retval = ifxhcd_handle_intr(ifxhcd); -+ return IRQ_RETVAL(retval); -+} -+ -+ -+/*! -+ \brief Handles host mode Over Current Interrupt -+ */ -+irqreturn_t ifxhcd_oc_irq(int _irq , void *_dev) -+{ -+ ifxhcd_hcd_t *ifxhcd = _dev; -+ int32_t retval=1; -+ -+ ifxhcd->flags.b.port_over_current_change = 1; -+ ifxusb_vbus_off(&ifxhcd->core_if); -+ IFX_DEBUGP("OC INTERRUPT # %d\n",ifxhcd->core_if.core_no); -+ -+ //mask_and_ack_ifx_irq (_irq); -+ return IRQ_RETVAL(retval); -+} -+ -+/*! -+ \brief Creates Status Change bitmap for the root hub and root port. The bitmap is -+ returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1 -+ is the status change indicator for the single root port. Returns 1 if either -+ change indicator is 1, otherwise returns 0. -+ */ -+int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf) -+{ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd); -+ -+ _buf[0] = 0; -+ _buf[0] |= (ifxhcd->flags.b.port_connect_status_change || -+ ifxhcd->flags.b.port_reset_change || -+ ifxhcd->flags.b.port_enable_change || -+ ifxhcd->flags.b.port_suspend_change || -+ ifxhcd->flags.b.port_over_current_change) << 1; -+ -+ #ifdef __DEBUG__ -+ if (_buf[0]) -+ { -+ IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:" -+ " Root port status changed\n"); -+ IFX_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n", -+ ifxhcd->flags.b.port_connect_status_change); -+ IFX_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n", -+ ifxhcd->flags.b.port_reset_change); -+ IFX_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n", -+ ifxhcd->flags.b.port_enable_change); -+ IFX_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n", -+ ifxhcd->flags.b.port_suspend_change); -+ IFX_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n", -+ ifxhcd->flags.b.port_over_current_change); -+ } -+ #endif //__DEBUG__ -+ return (_buf[0] != 0); -+} -+ -+#ifdef __WITH_HS_ELECT_TST__ -+ extern void do_setup(ifxusb_core_if_t *_core_if) ; -+ extern void do_in_ack(ifxusb_core_if_t *_core_if); -+#endif //__WITH_HS_ELECT_TST__ -+ -+/*! -+ \brief Handles hub class-specific requests. -+ */ -+int ifxhcd_hub_control( struct usb_hcd *_syshcd, -+ u16 _typeReq, -+ u16 _wValue, -+ u16 _wIndex, -+ char *_buf, -+ u16 _wLength) -+{ -+ int retval = 0; -+ -+ ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd); -+ ifxusb_core_if_t *core_if = &ifxhcd->core_if; -+ struct usb_hub_descriptor *desc; -+ hprt0_data_t hprt0 = {.d32 = 0}; -+ -+ uint32_t port_status; -+ -+ switch (_typeReq) -+ { -+ case ClearHubFeature: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearHubFeature 0x%x\n", _wValue); -+ switch (_wValue) -+ { -+ case C_HUB_LOCAL_POWER: -+ case C_HUB_OVER_CURRENT: -+ /* Nothing required here */ -+ break; -+ default: -+ retval = -EINVAL; -+ IFX_ERROR ("IFXUSB HCD - " -+ "ClearHubFeature request %xh unknown\n", _wValue); -+ } -+ break; -+ case ClearPortFeature: -+ if (!_wIndex || _wIndex > 1) -+ goto error; -+ -+ switch (_wValue) -+ { -+ case USB_PORT_FEAT_ENABLE: -+ IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtena = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_SUSPEND: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtres = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ /* Clear Resume bit */ -+ mdelay (100); -+ hprt0.b.prtres = 0; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_POWER: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_POWER\n"); -+ #ifdef __IS_DUAL__ -+ ifxusb_vbus_off(core_if); -+ #else -+ ifxusb_vbus_off(core_if); -+ #endif -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtpwr = 0; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_INDICATOR: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n"); -+ /* Port inidicator not supported */ -+ break; -+ case USB_PORT_FEAT_C_CONNECTION: -+ /* Clears drivers internal connect status change -+ * flag */ -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n"); -+ ifxhcd->flags.b.port_connect_status_change = 0; -+ break; -+ case USB_PORT_FEAT_C_RESET: -+ /* Clears the driver's internal Port Reset Change -+ * flag */ -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n"); -+ ifxhcd->flags.b.port_reset_change = 0; -+ break; -+ case USB_PORT_FEAT_C_ENABLE: -+ /* Clears the driver's internal Port -+ * Enable/Disable Change flag */ -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n"); -+ ifxhcd->flags.b.port_enable_change = 0; -+ break; -+ case USB_PORT_FEAT_C_SUSPEND: -+ /* Clears the driver's internal Port Suspend -+ * Change flag, which is set when resume signaling on -+ * the host port is complete */ -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n"); -+ ifxhcd->flags.b.port_suspend_change = 0; -+ break; -+ case USB_PORT_FEAT_C_OVER_CURRENT: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n"); -+ ifxhcd->flags.b.port_over_current_change = 0; -+ break; -+ default: -+ retval = -EINVAL; -+ IFX_ERROR ("IFXUSB HCD - " -+ "ClearPortFeature request %xh " -+ "unknown or unsupported\n", _wValue); -+ } -+ break; -+ case GetHubDescriptor: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "GetHubDescriptor\n"); -+ desc = (struct usb_hub_descriptor *)_buf; -+ desc->bDescLength = 9; -+ desc->bDescriptorType = 0x29; -+ desc->bNbrPorts = 1; -+ desc->wHubCharacteristics = 0x08; -+ desc->bPwrOn2PwrGood = 1; -+ desc->bHubContrCurrent = 0; -+// desc->bitmap[0] = 0; -+// desc->bitmap[1] = 0xff; -+ break; -+ case GetHubStatus: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "GetHubStatus\n"); -+ memset (_buf, 0, 4); -+ break; -+ case GetPortStatus: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "GetPortStatus\n"); -+ if (!_wIndex || _wIndex > 1) -+ goto error; -+ -+# ifdef CONFIG_AVM_POWERMETER -+ { -+ /* first port only, but 2 Hosts */ -+ static unsigned char ucOldPower1 = 255; -+ static unsigned char ucOldPower2 = 255; -+ -+ unsigned char ucNewPower = 0; -+ struct usb_device *childdev = _syshcd->self.root_hub->children[0]; -+ -+ if (childdev != NULL) { -+ ucNewPower = (childdev->actconfig != NULL) -+ ? childdev->actconfig->desc.bMaxPower -+ : 50;/* default: 50 means 100 mA*/ -+ } -+ if (_syshcd->self.busnum == 1) { -+ if (ucOldPower1 != ucNewPower) { -+ ucOldPower1 = ucNewPower; -+ printk (KERN_INFO "IFXHCD#1: AVM Powermeter changed to %u mA\n", ucNewPower*2); -+ PowerManagmentRessourceInfo(powerdevice_usb_host, ucNewPower*2); -+ } -+ } else { -+ if (ucOldPower2 != ucNewPower) { -+ ucOldPower2 = ucNewPower; -+ printk (KERN_INFO "IFXHCD#2: AVM Powermeter changed to %u mA\n", ucNewPower*2); -+ PowerManagmentRessourceInfo(powerdevice_usb_host2, ucNewPower*2); -+ } -+ } -+ } -+# endif /*--- #ifdef CONFIG_AVM_POWERMETER ---*/ -+ -+ port_status = 0; -+ if (ifxhcd->flags.b.port_connect_status_change) -+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION); -+ if (ifxhcd->flags.b.port_enable_change) -+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE); -+ if (ifxhcd->flags.b.port_suspend_change) -+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND); -+ if (ifxhcd->flags.b.port_reset_change) -+ port_status |= (1 << USB_PORT_FEAT_C_RESET); -+ if (ifxhcd->flags.b.port_over_current_change) -+ { -+ IFX_ERROR("Device Not Supported\n"); -+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT); -+ } -+ if (!ifxhcd->flags.b.port_connect_status) -+ { -+ /* -+ * The port is disconnected, which means the core is -+ * either in device mode or it soon will be. Just -+ * return 0's for the remainder of the port status -+ * since the port register can't be read if the core -+ * is in device mode. -+ */ -+ *((u32 *) _buf) = cpu_to_le32(port_status); -+ break; -+ } -+ -+ hprt0.d32 = ifxusb_rreg(core_if->hprt0); -+ IFX_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32); -+ if (hprt0.b.prtconnsts) -+ port_status |= (1 << USB_PORT_FEAT_CONNECTION); -+ if (hprt0.b.prtena) -+ port_status |= (1 << USB_PORT_FEAT_ENABLE); -+ if (hprt0.b.prtsusp) -+ port_status |= (1 << USB_PORT_FEAT_SUSPEND); -+ if (hprt0.b.prtovrcurract) -+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT); -+ if (hprt0.b.prtrst) -+ port_status |= (1 << USB_PORT_FEAT_RESET); -+ if (hprt0.b.prtpwr) -+ port_status |= (1 << USB_PORT_FEAT_POWER); -+/* if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED) -+ port_status |= (1 << USB_PORT_FEAT_HIGHSPEED); -+ else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED) -+ port_status |= (1 << USB_PORT_FEAT_LOWSPEED);*/ -+ if (hprt0.b.prttstctl) -+ port_status |= (1 << USB_PORT_FEAT_TEST); -+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */ -+ *((u32 *) _buf) = cpu_to_le32(port_status); -+ break; -+ case SetHubFeature: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetHubFeature\n"); -+ /* No HUB features supported */ -+ break; -+ case SetPortFeature: -+ if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1)) -+ goto error; -+ /* -+ * The port is disconnected, which means the core is -+ * either in device mode or it soon will be. Just -+ * return without doing anything since the port -+ * register can't be written if the core is in device -+ * mode. -+ */ -+ if (!ifxhcd->flags.b.port_connect_status) -+ break; -+ switch (_wValue) -+ { -+ case USB_PORT_FEAT_SUSPEND: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtsusp = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32); -+ /* Suspend the Phy Clock */ -+ { -+ pcgcctl_data_t pcgcctl = {.d32=0}; -+ pcgcctl.b.stoppclk = 1; -+ ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32); -+ } -+ break; -+ case USB_PORT_FEAT_POWER: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_POWER\n"); -+ ifxusb_vbus_on (core_if); -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtpwr = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_RESET: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_RESET\n"); -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtrst = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ -+ MDELAY (60); -+ hprt0.b.prtrst = 0; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ break; -+ #ifdef __WITH_HS_ELECT_TST__ -+ case USB_PORT_FEAT_TEST: -+ { -+ uint32_t t; -+ gint_data_t gintmsk; -+ t = (_wIndex >> 8); /* MSB wIndex USB */ -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t); -+ warn("USB_PORT_FEAT_TEST %d\n", t); -+ if (t < 6) -+ { -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prttstctl = t; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ } -+ else if (t == 6) /* HS_HOST_PORT_SUSPEND_RESUME */ -+ { -+ /* Save current interrupt mask */ -+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk); -+ -+ /* Disable all interrupts while we muck with -+ * the hardware directly -+ */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Drive suspend on the root port */ -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtsusp = 1; -+ hprt0.b.prtres = 0; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Drive resume on the root port */ -+ hprt0.d32 = ifxusb_read_hprt0 (core_if); -+ hprt0.b.prtsusp = 0; -+ hprt0.b.prtres = 1; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ mdelay(100); -+ -+ /* Clear the resume bit */ -+ hprt0.b.prtres = 0; -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ -+ /* Restore interrupts */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32); -+ } -+ else if (t == 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */ -+ { -+ /* Save current interrupt mask */ -+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk); -+ -+ /* Disable all interrupts while we muck with -+ * the hardware directly -+ */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Send the Setup packet */ -+ do_setup(core_if); -+ -+ /* 15 second delay so nothing else happens for awhile */ -+ mdelay(15000); -+ -+ /* Restore interrupts */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32); -+ } -+ -+ else if (t == 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */ -+ { -+ /* Save current interrupt mask */ -+ gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk); -+ -+ /* Disable all interrupts while we muck with -+ * the hardware directly -+ */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0); -+ -+ /* Send the Setup packet */ -+ do_setup(core_if); -+ -+ /* 15 second delay so nothing else happens for awhile */ -+ mdelay(15000); -+ -+ /* Send the In and Ack packets */ -+ do_in_ack(core_if); -+ -+ /* 15 second delay so nothing else happens for awhile */ -+ mdelay(15000); -+ -+ /* Restore interrupts */ -+ ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32); -+ } -+ } -+ break; -+ #endif //__WITH_HS_ELECT_TST__ -+ case USB_PORT_FEAT_INDICATOR: -+ IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n"); -+ /* Not supported */ -+ break; -+ default: -+ retval = -EINVAL; -+ IFX_ERROR ("IFXUSB HCD - " -+ "SetPortFeature request %xh " -+ "unknown or unsupported\n", _wValue); -+ } -+ break; -+ default: -+ error: -+ retval = -EINVAL; -+ IFX_WARN ("IFXUSB HCD - " -+ "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n", -+ _typeReq, _wIndex, _wValue); -+ } -+ return retval; -+} -+ -+ -+/*! -+ \brief Assigns transactions from a URBD to a free host channel and initializes the -+ host channel to perform the transactions. The host channel is removed from -+ the free list. -+ \param _ifxhcd The HCD state structure. -+ \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel. -+ */ -+static int assign_and_init_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh) -+{ -+ ifxhcd_hc_t *ifxhc; -+ ifxhcd_urbd_t *urbd; -+ struct urb *urb; -+ -+ IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh); -+ -+ if(list_empty(&_epqh->urbd_list)) -+ return 0; -+ -+ ifxhc = list_entry(_ifxhcd->free_hc_list.next, ifxhcd_hc_t, hc_list_entry); -+ /* Remove the host channel from the free list. */ -+ list_del_init(&ifxhc->hc_list_entry); -+ -+ urbd = list_entry(_epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry); -+ urb = urbd->urb; -+ -+ _epqh->hc = ifxhc; -+ _epqh->urbd = urbd; -+ ifxhc->epqh = _epqh; -+ -+ urbd->is_active=1; -+ -+ /* -+ * Use usb_pipedevice to determine device address. This address is -+ * 0 before the SET_ADDRESS command and the correct address afterward. -+ */ -+ ifxhc->dev_addr = usb_pipedevice(urb->pipe); -+ ifxhc->ep_num = usb_pipeendpoint(urb->pipe); -+ -+ ifxhc->xfer_started = 0; -+ -+ if (urb->dev->speed == USB_SPEED_LOW) ifxhc->speed = IFXUSB_EP_SPEED_LOW; -+ else if (urb->dev->speed == USB_SPEED_FULL) ifxhc->speed = IFXUSB_EP_SPEED_FULL; -+ else ifxhc->speed = IFXUSB_EP_SPEED_HIGH; -+ -+ ifxhc->mps = _epqh->mps; -+ ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ -+ ifxhc->ep_type = _epqh->ep_type; -+ -+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL) -+ { -+ ifxhc->control_phase=IFXHCD_CONTROL_SETUP; -+ ifxhc->is_in = 0; -+ ifxhc->data_pid_start = IFXUSB_HC_PID_SETUP; -+ ifxhc->xfer_buff = urbd->setup_buff; -+ ifxhc->xfer_len = 8; -+ ifxhc->xfer_count = 0; -+ ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0; -+ } -+ else -+ { -+ ifxhc->is_in = urbd->is_in; -+ ifxhc->xfer_buff = urbd->xfer_buff; -+ ifxhc->xfer_len = urbd->xfer_len; -+ ifxhc->xfer_count = 0; -+ /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/ -+ //ifxhc->data_pid_start = _epqh->data_toggle; -+ ifxhc->data_pid_start = usb_gettoggle (urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout (urb->pipe)) -+ ? IFXUSB_HC_PID_DATA1 -+ : IFXUSB_HC_PID_DATA0; -+ if(ifxhc->is_in) -+ ifxhc->short_rw =0; -+ else -+ ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0; -+ -+ #ifdef __EN_ISOC__ -+ if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC) -+ { -+ struct usb_iso_packet_descriptor *frame_desc; -+ frame_desc = &urb->iso_frame_desc[urbd->isoc_frame_index]; -+ ifxhc->xfer_buff += frame_desc->offset + urbd->isoc_split_offset; -+ ifxhc->xfer_len = frame_desc->length - urbd->isoc_split_offset; -+ if (ifxhc->isoc_xact_pos == IFXUSB_HCSPLIT_XACTPOS_ALL) -+ { -+ if (ifxhc->xfer_len <= 188) -+ ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL; -+ else -+ ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_BEGIN; -+ } -+ } -+ #endif -+ } -+ -+ ifxhc->do_ping=0; -+ if (_ifxhcd->core_if.snpsid < 0x4f54271a && ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ ifxhc->do_ping=1; -+ -+ -+ /* Set the split attributes */ -+ ifxhc->split = 0; -+ if (_epqh->need_split) { -+ ifxhc->split = 1; -+ ifxhc->hub_addr = urb->dev->tt->hub->devnum; -+ ifxhc->port_addr = urb->dev->ttport; -+ } -+ -+ //ifxhc->uint16_t pkt_count_limit -+ -+ { -+ hcint_data_t hc_intr_mask; -+ uint8_t hc_num = ifxhc->hc_num; -+ ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[hc_num]; -+ -+ /* Clear old interrupt conditions for this host channel. */ -+ hc_intr_mask.d32 = 0xFFFFFFFF; -+ hc_intr_mask.b.reserved = 0; -+ ifxusb_wreg(&hc_regs->hcint, hc_intr_mask.d32); -+ -+ /* Enable channel interrupts required for this transfer. */ -+ hc_intr_mask.d32 = 0; -+ hc_intr_mask.b.chhltd = 1; -+ hc_intr_mask.b.ahberr = 1; -+ -+ ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32); -+ -+ /* Enable the top level host channel interrupt. */ -+ { -+ uint32_t intr_enable; -+ intr_enable = (1 << hc_num); -+ ifxusb_mreg(&_ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable); -+ } -+ -+ /* Make sure host channel interrupts are enabled. */ -+ { -+ gint_data_t gintmsk ={.d32 = 0}; -+ gintmsk.b.hcintr = 1; -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0, gintmsk.d32); -+ } -+ -+ /* -+ * Program the HCCHARn register with the endpoint characteristics for -+ * the current transfer. -+ */ -+ { -+ hcchar_data_t hcchar; -+ -+ hcchar.d32 = 0; -+ hcchar.b.devaddr = ifxhc->dev_addr; -+ hcchar.b.epnum = ifxhc->ep_num; -+ hcchar.b.lspddev = (ifxhc->speed == IFXUSB_EP_SPEED_LOW); -+ hcchar.b.eptype = ifxhc->ep_type; -+ hcchar.b.mps = ifxhc->mps; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ -+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, ifxhc->hc_num); -+ IFX_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n" , hcchar.b.devaddr); -+ IFX_DEBUGPL(DBG_HCDV, " Ep Num: %d\n" , hcchar.b.epnum); -+ IFX_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev); -+ IFX_DEBUGPL(DBG_HCDV, " Ep Type: %d\n" , hcchar.b.eptype); -+ IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , hcchar.b.mps); -+ IFX_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n" , hcchar.b.multicnt); -+ } -+ /* Program the HCSPLIT register for SPLITs */ -+ { -+ hcsplt_data_t hcsplt; -+ -+ hcsplt.d32 = 0; -+ if (ifxhc->split) -+ { -+ IFX_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ifxhc->hc_num, -+ (ifxhc->split==2) ? "CSPLIT" : "SSPLIT"); -+ hcsplt.b.spltena = 1; -+ hcsplt.b.compsplt = (ifxhc->split==2); -+ #ifdef __EN_ISOC__ -+ if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC) -+ hcsplt.b.xactpos = ifxhc->isoc_xact_pos; -+ else -+ #endif -+ hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL; -+ hcsplt.b.hubaddr = ifxhc->hub_addr; -+ hcsplt.b.prtaddr = ifxhc->port_addr; -+ IFX_DEBUGPL(DBG_HCDV, " comp split %d\n" , hcsplt.b.compsplt); -+ IFX_DEBUGPL(DBG_HCDV, " xact pos %d\n" , hcsplt.b.xactpos); -+ IFX_DEBUGPL(DBG_HCDV, " hub addr %d\n" , hcsplt.b.hubaddr); -+ IFX_DEBUGPL(DBG_HCDV, " port addr %d\n" , hcsplt.b.prtaddr); -+ IFX_DEBUGPL(DBG_HCDV, " is_in %d\n" , ifxhc->is_in); -+ IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , ifxhc->mps); -+ IFX_DEBUGPL(DBG_HCDV, " xferlen: %d\n" , ifxhc->xfer_len); -+ } -+ ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32); -+ } -+ } -+ -+ ifxhc->nak_retry_r=ifxhc->nak_retry=0; -+ ifxhc->nak_countdown_r=ifxhc->nak_countdown=0; -+ -+ if (ifxhc->split) -+ { -+ if(ifxhc->is_in) -+ { -+ } -+ else -+ { -+ } -+ } -+ else if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL) -+ { -+ if(ifxhc->is_in) -+ { -+ } -+ else -+ { -+ } -+ } -+ else if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK) -+ { -+ if(ifxhc->is_in) -+ { -+// ifxhc->nak_retry_r=ifxhc->nak_retry=nak_retry_max; -+// ifxhc->nak_countdown_r=ifxhc->nak_countdown=nak_countdown_max; -+ } -+ else -+ { -+ } -+ } -+ else if(_epqh->ep_type==IFXUSB_EP_TYPE_INTR) -+ { -+ if(ifxhc->is_in) -+ { -+ } -+ else -+ { -+ } -+ } -+ else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC) -+ { -+ if(ifxhc->is_in) -+ { -+ } -+ else -+ { -+ } -+ } -+ -+ return 1; -+} -+ -+/*! -+ \brief This function selects transactions from the HCD transfer schedule and -+ assigns them to available host channels. It is called from HCD interrupt -+ handler functions. -+ */ -+static void select_eps_sub(ifxhcd_hcd_t *_ifxhcd) -+{ -+ struct list_head *epqh_ptr; -+ struct list_head *urbd_ptr; -+ ifxhcd_epqh_t *epqh; -+ ifxhcd_urbd_t *urbd; -+ int ret_val=0; -+ -+ /*== AVM/BC 20101111 Function called with Lock ==*/ -+ -+// #ifdef __DEBUG__ -+// IFX_DEBUGPL(DBG_HCD, " ifxhcd_select_ep\n"); -+// #endif -+ -+ /* Process entries in the periodic ready list. */ -+ #ifdef __EN_ISOC__ -+ epqh_ptr = _ifxhcd->epqh_isoc_ready.next; -+ while (epqh_ptr != &_ifxhcd->epqh_isoc_ready && !list_empty(&_ifxhcd->free_hc_list)) -+ { -+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_ptr = epqh_ptr->next; -+ if(epqh->period_do) -+ { -+ if(assign_and_init_hc(_ifxhcd, epqh)) -+ { -+ IFX_DEBUGPL(DBG_HCD, " select_eps ISOC\n"); -+ list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active); -+ epqh->is_active=1; -+ ret_val=1; -+ epqh->period_do=0; -+ } -+ } -+ } -+ #endif -+ -+ epqh_ptr = _ifxhcd->epqh_intr_ready.next; -+ while (epqh_ptr != &_ifxhcd->epqh_intr_ready && !list_empty(&_ifxhcd->free_hc_list)) -+ { -+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_ptr = epqh_ptr->next; -+ if(epqh->period_do) -+ { -+ if(assign_and_init_hc(_ifxhcd, epqh)) -+ { -+ IFX_DEBUGPL(DBG_HCD, " select_eps INTR\n"); -+ list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active); -+ epqh->is_active=1; -+ ret_val=1; -+ epqh->period_do=0; -+ } -+ } -+ } -+ -+ epqh_ptr = _ifxhcd->epqh_np_ready.next; -+ while (epqh_ptr != &_ifxhcd->epqh_np_ready && !list_empty(&_ifxhcd->free_hc_list)) // may need to preserve at lease one for period -+ { -+ epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_ptr = epqh_ptr->next; -+ if(assign_and_init_hc(_ifxhcd, epqh)) -+ { -+ IFX_DEBUGPL(DBG_HCD, " select_eps CTRL/BULK\n"); -+ list_move_tail(&epqh->epqh_list_entry, &_ifxhcd->epqh_np_active); -+ epqh->is_active=1; -+ ret_val=1; -+ } -+ } -+ if(ret_val) -+ /*== AVM/BC 20101111 Function called with Lock ==*/ -+ process_channels_sub(_ifxhcd); -+ -+ /* AVM/BC 20101111 Urbds completion loop */ -+ while (!list_empty(&_ifxhcd->urbd_complete_list)) -+ { -+ urbd_ptr = _ifxhcd->urbd_complete_list.next; -+ list_del_init(urbd_ptr); -+ -+ urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, urbd_list_entry); -+ -+ ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status); -+ -+ } -+ -+} -+ -+static void select_eps_func(unsigned long data) -+{ -+ unsigned long flags; -+ -+ ifxhcd_hcd_t *ifxhcd; -+ ifxhcd=((ifxhcd_hcd_t *)data); -+ -+ /* AVM/BC 20101111 select_eps_in_use flag removed */ -+ -+ SPIN_LOCK_IRQSAVE(&ifxhcd->lock, flags); -+ -+ /*if(ifxhcd->select_eps_in_use){ -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+ return; -+ } -+ ifxhcd->select_eps_in_use=1; -+ */ -+ -+ select_eps_sub(ifxhcd); -+ -+ //ifxhcd->select_eps_in_use=0; -+ -+ SPIN_UNLOCK_IRQRESTORE(&ifxhcd->lock, flags); -+} -+ -+void select_eps(ifxhcd_hcd_t *_ifxhcd) -+{ -+ if(in_irq()) -+ { -+ if(!_ifxhcd->select_eps.func) -+ { -+ _ifxhcd->select_eps.next = NULL; -+ _ifxhcd->select_eps.state = 0; -+ atomic_set( &_ifxhcd->select_eps.count, 0); -+ _ifxhcd->select_eps.func = select_eps_func; -+ _ifxhcd->select_eps.data = (unsigned long)_ifxhcd; -+ } -+ tasklet_schedule(&_ifxhcd->select_eps); -+ } -+ else -+ { -+ unsigned long flags; -+ -+ /* AVM/BC 20101111 select_eps_in_use flag removed */ -+ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ /*if(_ifxhcd->select_eps_in_use){ -+ printk ("select_eps non_irq: busy\n"); -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ return; -+ } -+ _ifxhcd->select_eps_in_use=1; -+ */ -+ -+ select_eps_sub(_ifxhcd); -+ -+ //_ifxhcd->select_eps_in_use=0; -+ -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ } -+} -+ -+/*! -+ \brief -+ */ -+static void process_unaligned( ifxhcd_epqh_t *_epqh) -+{ -+ #if defined(__UNALIGNED_BUFFER_ADJ__) -+ if(!_epqh->aligned_checked) -+ { -+ uint32_t xfer_len; -+ xfer_len=_epqh->urbd->xfer_len; -+ if(_epqh->urbd->is_in && xfer_len<_epqh->mps) -+ xfer_len = _epqh->mps; -+ _epqh->using_aligned_buf=0; -+ -+ if(xfer_len > 0 && ((unsigned long)_epqh->urbd->xfer_buff) & 3) -+ { -+ if( _epqh->aligned_buf -+ && _epqh->aligned_buf_len > 0 -+ && _epqh->aligned_buf_len < xfer_len -+ ) -+ { -+ ifxusb_free_buf(_epqh->aligned_buf); -+ _epqh->aligned_buf=NULL; -+ _epqh->aligned_buf_len=0; -+ } -+ if(! _epqh->aligned_buf || ! _epqh->aligned_buf_len) -+ { -+ _epqh->aligned_buf = ifxusb_alloc_buf(xfer_len, _epqh->urbd->is_in); -+ if(_epqh->aligned_buf) -+ _epqh->aligned_buf_len = xfer_len; -+ } -+ if(_epqh->aligned_buf) -+ { -+ if(!_epqh->urbd->is_in) -+ memcpy(_epqh->aligned_buf, _epqh->urbd->xfer_buff, xfer_len); -+ _epqh->using_aligned_buf=1; -+ _epqh->hc->xfer_buff = _epqh->aligned_buf; -+ } -+ else -+ IFX_WARN("%s():%d\n",__func__,__LINE__); -+ } -+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL) -+ { -+ _epqh->using_aligned_setup=0; -+ if(((unsigned long)_epqh->urbd->setup_buff) & 3) -+ { -+ if(! _epqh->aligned_setup) -+ _epqh->aligned_setup = ifxusb_alloc_buf(8,0); -+ if(_epqh->aligned_setup) -+ { -+ memcpy(_epqh->aligned_setup, _epqh->urbd->setup_buff, 8); -+ _epqh->using_aligned_setup=1; -+ } -+ else -+ IFX_WARN("%s():%d\n",__func__,__LINE__); -+ _epqh->hc->xfer_buff = _epqh->aligned_setup; -+ } -+ } -+ } -+ #elif defined(__UNALIGNED_BUFFER_CHK__) -+ if(!_epqh->aligned_checked) -+ { -+ if(_epqh->urbd->is_in) -+ { -+ if(_epqh->urbd->xfer_len==0) -+ IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__); -+ else{ -+ if(_epqh->urbd->xfer_len < _epqh->mps) -+ IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__); -+ -+ if(((unsigned long)_epqh->urbd->xfer_buff) & 3) -+ IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__); -+ } -+ } -+ else -+ { -+ if(_epqh->urbd->xfer_len > 0 && (((unsigned long)_epqh->urbd->xfer_buff) & 3) ) -+ IFX_WARN("%s():%d OUT xfer Buffer UNALIGNED\n",__func__,__LINE__); -+ } -+ -+ if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL) -+ { -+ if(((unsigned long)_epqh->urbd->setup_buff) & 3) -+ IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__); -+ } -+ } -+ #endif -+ _epqh->aligned_checked=1; -+} -+ -+ -+/*! -+ \brief -+ */ -+void process_channels_sub(ifxhcd_hcd_t *_ifxhcd) -+{ -+ ifxhcd_epqh_t *epqh; -+ struct list_head *epqh_item; -+ struct ifxhcd_hc *hc; -+ -+ #ifdef __EN_ISOC__ -+ if (!list_empty(&_ifxhcd->epqh_isoc_active)) -+ { -+ for (epqh_item = _ifxhcd->epqh_isoc_active.next; -+ epqh_item != &_ifxhcd->epqh_isoc_active; -+ ) -+ { -+ epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_item = epqh_item->next; -+ hc=epqh->hc; -+ if(hc && !hc->xfer_started && epqh->period_do) -+ { -+ if(hc->split==0 -+ || hc->split==1 -+ ) -+ { -+ //epqh->ping_state = 0; -+ process_unaligned(epqh); -+ hc->wait_for_sof=epqh->wait_for_sof; -+ epqh->wait_for_sof=0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, hc); -+ epqh->period_do=0; -+ { -+ gint_data_t gintsts = {.d32 = 0}; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32); -+ } -+ } -+ } -+ } -+ } -+ #endif -+ -+ if (!list_empty(&_ifxhcd->epqh_intr_active)) -+ { -+ for (epqh_item = _ifxhcd->epqh_intr_active.next; -+ epqh_item != &_ifxhcd->epqh_intr_active; -+ ) -+ { -+ epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_item = epqh_item->next; -+ hc=epqh->hc; -+ if(hc && !hc->xfer_started && epqh->period_do) -+ { -+ if(hc->split==0 -+ || hc->split==1 -+ ) -+ { -+ //epqh->ping_state = 0; -+ process_unaligned(epqh); -+ hc->wait_for_sof=epqh->wait_for_sof; -+ epqh->wait_for_sof=0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, hc); -+ epqh->period_do=0; -+#ifdef __USE_TIMER_4_SOF__ -+ /* AVM/WK change: let hc_start decide, if irq is needed */ -+#else -+ { -+ gint_data_t gintsts = {.d32 = 0}; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk,0, gintsts.d32); -+ } -+#endif -+ } -+ } -+ -+ } -+ } -+ -+ if (!list_empty(&_ifxhcd->epqh_np_active)) -+ { -+ for (epqh_item = _ifxhcd->epqh_np_active.next; -+ epqh_item != &_ifxhcd->epqh_np_active; -+ ) -+ { -+ epqh = list_entry(epqh_item, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_item = epqh_item->next; -+ hc=epqh->hc; -+ if(hc) -+ { -+ if(!hc->xfer_started) -+ { -+ if(hc->split==0 -+ || hc->split==1 -+ //|| hc->split_counter == 0 -+ ) -+ { -+ //epqh->ping_state = 0; -+ process_unaligned(epqh); -+ hc->wait_for_sof=epqh->wait_for_sof; -+ epqh->wait_for_sof=0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, hc); -+ } -+ } -+ } -+ } -+ } -+} -+ -+void process_channels(ifxhcd_hcd_t *_ifxhcd) -+{ -+ unsigned long flags; -+ -+ /* AVM/WK Fix: use spin_lock instead busy flag -+ **/ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ //if(_ifxhcd->process_channels_in_use) -+ // return; -+ //_ifxhcd->process_channels_in_use=1; -+ -+ process_channels_sub(_ifxhcd); -+ //_ifxhcd->process_channels_in_use=0; -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+} -+ -+ -+#ifdef __HC_XFER_TIMEOUT__ -+ static void hc_xfer_timeout(unsigned long _ptr) -+ { -+ hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)_ptr; -+ int hc_num = xfer_info->hc->hc_num; -+ IFX_WARN("%s: timeout on channel %d\n", __func__, hc_num); -+ IFX_WARN(" start_hcchar_val 0x%08x\n", xfer_info->hc->start_hcchar_val); -+ } -+#endif -+ -+void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf) -+{ -+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num]; -+ hctsiz_data_t hctsiz= { .d32=0 }; -+ hcchar_data_t hcchar; -+ -+ -+ _ifxhc->xfer_len = _ifxhc->mps; -+ hctsiz.b.xfersize = _ifxhc->mps; -+ hctsiz.b.pktcnt = 0; -+ hctsiz.b.pid = _ifxhc->data_pid_start; -+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32); -+ -+ ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(dump_buf))))); -+ -+ { -+ hcint_data_t hcint= { .d32=0 }; -+// hcint.b.nak =1; -+// hcint.b.nyet=1; -+// hcint.b.ack =1; -+ hcint.d32 =0xFFFFFFFF; -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ } -+ -+ /* Set host channel enable after all other setup is complete. */ -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 0; -+ hcchar.b.epdir = 1; -+ IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", hcchar.d32); -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+} -+ -+/*! -+ \brief This function trigger a data transfer for a host channel and -+ starts the transfer. -+ -+ For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ -+ register along with a packet count of 1 and the channel is enabled. This -+ causes a single PING transaction to occur. Other fields in HCTSIZ are -+ simply set to 0 since no data transfer occurs in this case. -+ -+ For a PING transfer in DMA mode, the HCTSIZ register is initialized with -+ all the information required to perform the subsequent data transfer. In -+ addition, the Do Ping bit is set in the HCTSIZ register. In this case, the -+ controller performs the entire PING protocol, then starts the data -+ transfer. -+ \param _core_if Pointer of core_if structure -+ \param _ifxhc Information needed to initialize the host channel. The xfer_len -+ value may be reduced to accommodate the max widths of the XferSize and -+ PktCnt fields in the HCTSIZn register. The multi_count value may be changed -+ to reflect the final xfer_len value. -+ */ -+void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc) -+{ -+ hctsiz_data_t hctsiz= { .d32=0 }; -+ hcchar_data_t hcchar; -+ uint32_t max_hc_xfer_size = _core_if->params.max_transfer_size; -+ uint16_t max_hc_pkt_count = _core_if->params.max_packet_count; -+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[_ifxhc->hc_num]; -+ hfnum_data_t hfnum; -+ -+ hctsiz.b.dopng = 0; -+// if(_ifxhc->do_ping && !_ifxhc->is_in) hctsiz.b.dopng = 1; -+ -+ _ifxhc->nak_countdown=_ifxhc->nak_countdown_r; -+ -+ /* AVM/BC 20101111 Workaround: Always PING if HI-Speed Out and xfer_len > 0 */ -+ if(/*_ifxhc->do_ping &&*/ -+ (!_ifxhc->is_in) && -+ (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH) && -+ ((_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK) || ((_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL) && (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP))) && -+ _ifxhc->xfer_len -+ ) -+ hctsiz.b.dopng = 1; -+ -+ _ifxhc->xfer_started = 1; -+ -+ if(_ifxhc->epqh->pkt_count_limit > 0 && _ifxhc->epqh->pkt_count_limit < max_hc_pkt_count ) -+ { -+ max_hc_pkt_count=_ifxhc->epqh->pkt_count_limit; -+ if(max_hc_pkt_count * _ifxhc->mps < max_hc_xfer_size) -+ max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps; -+ } -+ if (_ifxhc->split > 0) -+ { -+ { -+ gint_data_t gintsts = {.d32 = 0}; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32); -+ } -+ -+ _ifxhc->start_pkt_count = 1; -+ if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT -+ _ifxhc->xfer_len = 0; -+ if (_ifxhc->xfer_len > _ifxhc->mps) -+ _ifxhc->xfer_len = _ifxhc->mps; -+ if (_ifxhc->xfer_len > 188) -+ _ifxhc->xfer_len = 188; -+ } -+ else if(_ifxhc->is_in) -+ { -+ _ifxhc->short_rw = 0; -+ if (_ifxhc->xfer_len > 0) -+ { -+ if (_ifxhc->xfer_len > max_hc_xfer_size) -+ _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1; -+ _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps; -+ if (_ifxhc->start_pkt_count > max_hc_pkt_count) -+ _ifxhc->start_pkt_count = max_hc_pkt_count; -+ } -+ else /* Need 1 packet for transfer length of 0. */ -+ _ifxhc->start_pkt_count = 1; -+ _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps; -+ } -+ else //non-split out -+ { -+ if (_ifxhc->xfer_len == 0) -+ { -+ /*== AVM/BC WK 20110421 ZERO PACKET Workaround: Is not an error ==*/ -+ //if(_ifxhc->short_rw==0) -+ // printk(KERN_INFO "%s() line %d: ZLP write without short_rw set!\n",__func__,__LINE__); -+ _ifxhc->start_pkt_count = 1; -+ } -+ else -+ { -+ if (_ifxhc->xfer_len > max_hc_xfer_size) -+ { -+ _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps); -+ _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps; -+ } -+ else -+ { -+ _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1) / _ifxhc->mps; -+// if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len ) -+// _ifxhc->start_pkt_count += _ifxhc->short_rw; -+ /*== AVM/BC WK 20110421 ZERO PACKET Workaround / check if short_rw is needed ==*/ -+ if(_ifxhc->start_pkt_count * _ifxhc->mps != _ifxhc->xfer_len ) -+ _ifxhc->short_rw = 0; -+ } -+ } -+ } -+ -+ #ifdef __EN_ISOC__ -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ /* Set up the initial PID for the transfer. */ -+ #if 1 -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ #else -+ if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ { -+ if (_ifxhc->is_in) -+ { -+ if (_ifxhc->multi_count == 1) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ else if (_ifxhc->multi_count == 2) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2; -+ } -+ else -+ { -+ if (_ifxhc->multi_count == 1) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA; -+ } -+ } -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ #endif -+ } -+ #endif -+ -+ hctsiz.b.xfersize = _ifxhc->xfer_len; -+ hctsiz.b.pktcnt = _ifxhc->start_pkt_count; -+ hctsiz.b.pid = _ifxhc->data_pid_start; -+ -+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32); -+ -+ -+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num); -+ IFX_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize); -+ IFX_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n" , hctsiz.b.pktcnt); -+ IFX_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid); -+ IFX_DEBUGPL(DBG_HCDV, " DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count ))); -+ ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count ))); -+ -+ /* Start the split */ -+ if (_ifxhc->split>0) -+ { -+ hcsplt_data_t hcsplt; -+ hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt); -+ hcsplt.b.spltena = 1; -+ if (_ifxhc->split>1) -+ hcsplt.b.compsplt = 1; -+ else -+ hcsplt.b.compsplt = 0; -+ -+ #ifdef __EN_ISOC__ -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC) -+ hcsplt.b.xactpos = _ifxhc->isoc_xact_pos; -+ else -+ #endif -+ hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO -+ ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32); -+ IFX_DEBUGPL(DBG_HCDV, " SPLIT: XACT_POS:0x%08x\n", hcsplt.d32); -+ } -+ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+// hcchar.b.multicnt = _ifxhc->multi_count; -+ hcchar.b.multicnt = 1; -+ -+ #ifdef __DEBUG__ -+ _ifxhc->start_hcchar_val = hcchar.d32; -+ if (hcchar.b.chdis) -+ IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", -+ __func__, _ifxhc->hc_num, hcchar.d32); -+ #endif -+ -+ /* Set host channel enable after all other setup is complete. */ -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 0; -+ hcchar.b.epdir = _ifxhc->is_in; -+ _ifxhc->hcchar=hcchar.d32; -+ -+ IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", _ifxhc->hcchar); -+ -+ /* == 20110901 AVM/WK Fix: Clear IRQ flags in any case ==*/ -+ { -+ hcint_data_t hcint= { .d32=0 }; -+ hcint.d32 =0xFFFFFFFF; -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ } -+ -+ if(_ifxhc->wait_for_sof==0) -+ { -+ hcint_data_t hcint; -+ -+ hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk); -+ -+ hcint.b.nak =0; -+ hcint.b.ack =0; -+ /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/ -+ hcint.b.nyet=0; -+ if(_ifxhc->nak_countdown_r) -+ hcint.b.nak =1; -+ ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32); -+ -+ /* AVM WK / BC 20100827 -+ * MOVED. Oddframe updated inmediatly before write HCChar Register. -+ */ -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ hfnum.d32 = ifxusb_rreg(&_core_if->host_global_regs->hfnum); -+ /* 1 if _next_ frame is odd, 0 if it's even */ -+ hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1; -+ _ifxhc->hcchar=hcchar.d32; -+ } -+ -+ ifxusb_wreg(&hc_regs->hcchar, _ifxhc->hcchar); -+#ifdef __USE_TIMER_4_SOF__ -+ } else { -+ //activate SOF IRQ -+ gint_data_t gintsts = {.d32 = 0}; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&_core_if->core_global_regs->gintmsk,0, gintsts.d32); -+#endif -+ } -+ -+ #ifdef __HC_XFER_TIMEOUT__ -+ /* Start a timer for this transfer. */ -+ init_timer(&_ifxhc->hc_xfer_timer); -+ _ifxhc->hc_xfer_timer.function = hc_xfer_timeout; -+ _ifxhc->hc_xfer_timer.core_if = _core_if; -+ _ifxhc->hc_xfer_timer.hc = _ifxhc; -+ _ifxhc->hc_xfer_timer.data = (unsigned long)(&_ifxhc->hc_xfer_info); -+ _ifxhc->hc_xfer_timer.expires = jiffies + (HZ*10); -+ add_timer(&_ifxhc->hc_xfer_timer); -+ #endif -+} -+ -+/*! -+ \brief Attempts to halt a host channel. This function should only be called -+ to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the -+ controller halts the channel when the transfer is complete or a condition -+ occurs that requires application intervention. -+ -+ In DMA mode, always sets the Channel Enable and Channel Disable bits of the -+ HCCHARn register. The controller ensures there is space in the request -+ queue before submitting the halt request. -+ -+ Some time may elapse before the core flushes any posted requests for this -+ host channel and halts. The Channel Halted interrupt handler completes the -+ deactivation of the host channel. -+ */ -+void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if, -+ ifxhcd_hc_t *_ifxhc, -+ ifxhcd_halt_status_e _halt_status) -+{ -+ hcchar_data_t hcchar; -+ ifxusb_hc_regs_t *hc_regs; -+ -+ hc_regs = _core_if->hc_regs[_ifxhc->hc_num]; -+ -+ WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS); -+ -+ if (_halt_status == HC_XFER_URB_DEQUEUE || -+ _halt_status == HC_XFER_AHB_ERR) -+ { -+ /* -+ * Disable all channel interrupts except Ch Halted. The URBD -+ * and EPQH state associated with this transfer has been cleared -+ * (in the case of URB_DEQUEUE), so the channel needs to be -+ * shut down carefully to prevent crashes. -+ */ -+ hcint_data_t hcintmsk; -+ hcintmsk.d32 = 0; -+ hcintmsk.b.chhltd = 1; -+ ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32); -+ -+ /* -+ * Make sure no other interrupts besides halt are currently -+ * pending. Handling another interrupt could cause a crash due -+ * to the URBD and EPQH state. -+ */ -+ ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32); -+ -+ /* -+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR -+ * even if the channel was already halted for some other -+ * reason. -+ */ -+ _ifxhc->halt_status = _halt_status; -+ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chen == 0) -+ { -+ /* -+ * The channel is either already halted or it hasn't -+ * started yet. In DMA mode, the transfer may halt if -+ * it finishes normally or a condition occurs that -+ * requires driver intervention. Don't want to halt -+ * the channel again. In either Slave or DMA mode, -+ * it's possible that the transfer has been assigned -+ * to a channel, but not started yet when an URB is -+ * dequeued. Don't want to halt a channel that hasn't -+ * started yet. -+ */ -+ return; -+ } -+ } -+ -+ if (_ifxhc->halting) -+ { -+ /* -+ * A halt has already been issued for this channel. This might -+ * happen when a transfer is aborted by a higher level in -+ * the stack. -+ */ -+ #ifdef __DEBUG__ -+ IFX_PRINT("*** %s: Channel %d, _hc->halting already set ***\n", -+ __func__, _ifxhc->hc_num); -+ #endif -+ //ifxusb_dump_global_registers(_core_if); */ -+ //ifxusb_dump_host_registers(_core_if); */ -+ return; -+ } -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ /* == AVM/WK 20100709 halt channel only if enabled ==*/ -+ if (hcchar.b.chen) { -+ _ifxhc->halting = 1; -+ hcchar.b.chdis = 1; -+ -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ _ifxhc->halt_status = _halt_status; -+ } -+ -+ IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num); -+ IFX_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n" , hcchar.d32); -+ IFX_DEBUGPL(DBG_HCDV, " halting: %d\n" , _ifxhc->halting); -+ IFX_DEBUGPL(DBG_HCDV, " halt_status: %d\n" , _ifxhc->halt_status); -+ -+ return; -+} -+ -+/*! -+ \brief Clears a host channel. -+ */ -+void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc) -+{ -+ ifxusb_hc_regs_t *hc_regs; -+ -+ _ifxhc->xfer_started = 0; -+ /* -+ * Clear channel interrupt enables and any unhandled channel interrupt -+ * conditions. -+ */ -+ hc_regs = _core_if->hc_regs[_ifxhc->hc_num]; -+ ifxusb_wreg(&hc_regs->hcintmsk, 0); -+ ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF); -+ -+ #ifdef __HC_XFER_TIMEOUT__ -+ del_timer(&_ifxhc->hc_xfer_timer); -+ #endif -+ #ifdef __DEBUG__ -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chdis) -+ IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32); -+ } -+ #endif -+} -+ -+ -+ -+ -+ -+ -+ -+ -+#ifdef __DEBUG__ -+ static void dump_urb_info(struct urb *_urb, char* _fn_name) -+ { -+ IFX_PRINT("%s, urb %p\n" , _fn_name, _urb); -+ IFX_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe)); -+ IFX_PRINT(" Endpoint: %d, %s\n" , usb_pipeendpoint(_urb->pipe), -+ (usb_pipein(_urb->pipe) ? "IN" : "OUT")); -+ IFX_PRINT(" Endpoint type: %s\n", -+ ({ char *pipetype; -+ switch (usb_pipetype(_urb->pipe)) { -+ case PIPE_CONTROL: pipetype = "CONTROL"; break; -+ case PIPE_BULK: pipetype = "BULK"; break; -+ case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break; -+ case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break; -+ default: pipetype = "UNKNOWN"; break; -+ }; -+ pipetype; -+ })); -+ IFX_PRINT(" Speed: %s\n", -+ ({ char *speed; -+ switch (_urb->dev->speed) { -+ case USB_SPEED_HIGH: speed = "HIGH"; break; -+ case USB_SPEED_FULL: speed = "FULL"; break; -+ case USB_SPEED_LOW: speed = "LOW"; break; -+ default: speed = "UNKNOWN"; break; -+ }; -+ speed; -+ })); -+ IFX_PRINT(" Max packet size: %d\n", -+ usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe))); -+ IFX_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length); -+ IFX_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n", -+ _urb->transfer_buffer, (void *)_urb->transfer_dma); -+ IFX_PRINT(" Setup buffer: %p, Setup DMA: %p\n", -+ _urb->setup_packet, (void *)_urb->setup_dma); -+ IFX_PRINT(" Interval: %d\n", _urb->interval); -+ if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) -+ { -+ int i; -+ for (i = 0; i < _urb->number_of_packets; i++) -+ { -+ IFX_PRINT(" ISO Desc %d:\n", i); -+ IFX_PRINT(" offset: %d, length %d\n", -+ _urb->iso_frame_desc[i].offset, -+ _urb->iso_frame_desc[i].length); -+ } -+ } -+ } -+ -+ static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh) -+ { -+ if (_epqh->hc != NULL) -+ { -+ ifxhcd_hc_t *hc = _epqh->hc; -+ struct list_head *item; -+ ifxhcd_epqh_t *epqh_item; -+ -+ ifxusb_hc_regs_t *hc_regs; -+ -+ hcchar_data_t hcchar; -+ hcsplt_data_t hcsplt; -+ hctsiz_data_t hctsiz; -+ uint32_t hcdma; -+ -+ hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num]; -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt); -+ hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz); -+ hcdma = ifxusb_rreg(&hc_regs->hcdma); -+ -+ IFX_PRINT(" Assigned to channel %d:\n" , hc->hc_num); -+ IFX_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32); -+ IFX_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma); -+ IFX_PRINT(" dev_addr: %d, ep_num: %d, is_in: %d\n", -+ hc->dev_addr, hc->ep_num, hc->is_in); -+ IFX_PRINT(" ep_type: %d\n" , hc->ep_type); -+ IFX_PRINT(" max_packet_size: %d\n", hc->mps); -+ IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start); -+ IFX_PRINT(" xfer_started: %d\n" , hc->xfer_started); -+ IFX_PRINT(" halt_status: %d\n" , hc->halt_status); -+ IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff); -+ IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len); -+ IFX_PRINT(" epqh: %p\n" , hc->epqh); -+ IFX_PRINT(" NP Active:\n"); -+ list_for_each(item, &_ifxhcd->epqh_np_active) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ IFX_PRINT(" NP Ready:\n"); -+ list_for_each(item, &_ifxhcd->epqh_np_ready) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ IFX_PRINT(" INTR Active:\n"); -+ list_for_each(item, &_ifxhcd->epqh_intr_active) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ IFX_PRINT(" INTR Ready:\n"); -+ list_for_each(item, &_ifxhcd->epqh_intr_ready) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ #ifdef __EN_ISOC__ -+ IFX_PRINT(" ISOC Active:\n"); -+ list_for_each(item, &_ifxhcd->epqh_isoc_active) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ IFX_PRINT(" ISOC Ready:\n"); -+ list_for_each(item, &_ifxhcd->epqh_isoc_ready) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ #endif -+ IFX_PRINT(" Standby:\n"); -+ list_for_each(item, &_ifxhcd->epqh_stdby) -+ { -+ epqh_item = list_entry(item, ifxhcd_epqh_t, epqh_list_entry); -+ IFX_PRINT(" %p\n", epqh_item); -+ } -+ } -+ } -+#endif //__DEBUG__ -+ -+ -+/*! -+ \brief This function writes a packet into the Tx FIFO associated with the Host -+ Channel. For a channel associated with a non-periodic EP, the non-periodic -+ Tx FIFO is written. For a channel associated with a periodic EP, the -+ periodic Tx FIFO is written. This function should only be called in Slave -+ mode. -+ -+ Upon return the xfer_buff and xfer_count fields in _hc are incremented by -+ then number of bytes written to the Tx FIFO. -+ */ -+ -+#ifdef __ENABLE_DUMP__ -+ void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd) -+ { -+ int num_channels; -+ int i; -+ num_channels = _ifxhcd->core_if.params.host_channels; -+ IFX_PRINT("\n"); -+ IFX_PRINT("************************************************************\n"); -+ IFX_PRINT("HCD State:\n"); -+ IFX_PRINT(" Num channels: %d\n", num_channels); -+ for (i = 0; i < num_channels; i++) { -+ ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i]; -+ IFX_PRINT(" Channel %d:\n", hc->hc_num); -+ IFX_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n", -+ hc->dev_addr, hc->ep_num, hc->is_in); -+ IFX_PRINT(" speed: %d\n" , hc->speed); -+ IFX_PRINT(" ep_type: %d\n" , hc->ep_type); -+ IFX_PRINT(" mps: %d\n", hc->mps); -+ IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start); -+ IFX_PRINT(" xfer_started: %d\n" , hc->xfer_started); -+ IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff); -+ IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len); -+ IFX_PRINT(" xfer_count: %d\n" , hc->xfer_count); -+ IFX_PRINT(" halting: %d\n" , hc->halting); -+ IFX_PRINT(" halt_status: %d\n" , hc->halt_status); -+ IFX_PRINT(" split: %d\n" , hc->split); -+ IFX_PRINT(" hub_addr: %d\n" , hc->hub_addr); -+ IFX_PRINT(" port_addr: %d\n" , hc->port_addr); -+ #ifdef __EN_ISOC__ -+ IFX_PRINT(" isoc_xact_pos: %d\n" , hc->isoc_xact_pos); -+ #endif -+ IFX_PRINT(" epqh: %p\n" , hc->epqh); -+ IFX_PRINT(" short_rw: %d\n" , hc->short_rw); -+ IFX_PRINT(" do_ping: %d\n" , hc->do_ping); -+ IFX_PRINT(" control_phase: %d\n" , hc->control_phase); -+ IFX_PRINT(" pkt_count_limit: %d\n", hc->epqh->pkt_count_limit); -+ IFX_PRINT(" start_pkt_count: %d\n" , hc->start_pkt_count); -+ } -+ IFX_PRINT("************************************************************\n"); -+ IFX_PRINT("\n"); -+ } -+#endif //__ENABLE_DUMP__ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxhcd.h -@@ -0,0 +1,628 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxhcd.h -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the structures, constants, and interfaces for -+ ** the Host Contoller Driver (HCD). -+ ** -+ ** The Host Controller Driver (HCD) is responsible for translating requests -+ ** from the USB Driver into the appropriate actions on the IFXUSB controller. -+ ** It isolates the USBD from the specifics of the controller by providing an -+ ** API to the USBD. -+ ** FUNCTIONS : -+ ** COMPILER : gcc -+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7 -+ ** COPYRIGHT : -+ ** Version Control Section ** -+ ** $Author$ -+ ** $Date$ -+ ** $Revisions$ -+ ** $Log$ Revision history -+*****************************************************************************/ -+ -+/*! -+ \defgroup IFXUSB_HCD HCD Interface -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief The Host Controller Driver (HCD) is responsible for translating requests -+ from the USB Driver into the appropriate actions on the IFXUSB controller. -+ It isolates the USBD from the specifics of the controller by providing an -+ API to the USBD. -+ */ -+ -+ -+/*! -+ \file ifxhcd.h -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the structures, constants, and interfaces for -+ the Host Contoller Driver (HCD). -+ */ -+ -+#if !defined(__IFXHCD_H__) -+#define __IFXHCD_H__ -+ -+#include <linux/list.h> -+#include <linux/usb.h> -+ -+#ifdef __USE_TIMER_4_SOF__ -+#include <linux/hrtimer.h> -+#endif -+#include <linux/usb/hcd.h> -+ -+#include "ifxusb_cif.h" -+#include "ifxusb_plat.h" -+ -+ -+ -+/*! -+ \addtogroup IFXUSB_HCD -+ */ -+/*@{*/ -+ -+/* Phases for control transfers.*/ -+typedef enum ifxhcd_control_phase { -+ IFXHCD_CONTROL_SETUP, -+ IFXHCD_CONTROL_DATA, -+ IFXHCD_CONTROL_STATUS -+} ifxhcd_control_phase_e; -+ -+/* Reasons for halting a host channel. */ -+typedef enum ifxhcd_halt_status -+{ -+ HC_XFER_NO_HALT_STATUS, // Initial -+ HC_XFER_COMPLETE, // Xact complete without error, upward -+ HC_XFER_URB_COMPLETE, // Xfer complete without error, short upward -+ HC_XFER_STALL, // HC stopped abnormally, upward/downward -+ HC_XFER_XACT_ERR, // HC stopped abnormally, upward -+ HC_XFER_FRAME_OVERRUN, // HC stopped abnormally, upward -+ HC_XFER_BABBLE_ERR, // HC stopped abnormally, upward -+ HC_XFER_AHB_ERR, // HC stopped abnormally, upward -+ HC_XFER_DATA_TOGGLE_ERR, -+ HC_XFER_URB_DEQUEUE, // HC stopper manually, downward -+ HC_XFER_NAK // HC stopped by nak monitor, downward -+} ifxhcd_halt_status_e; -+ -+struct ifxhcd_urbd; -+struct ifxhcd_hc ; -+struct ifxhcd_epqh ; -+struct ifxhcd_hcd; -+ -+/*! -+ \brief A URB Descriptor (URBD) holds the state of a bulk, control, -+ interrupt, or isochronous transfer. A single URBD is created for each URB -+ (of one of these types) submitted to the HCD. The transfer associated with -+ a URBD may require one or multiple transactions. -+ -+ A URBD is linked to a EP Queue Head, which is entered in either the -+ isoc, intr or non-periodic schedule for execution. When a URBD is chosen for -+ execution, some or all of its transactions may be executed. After -+ execution, the state of the URBD is updated. The URBD may be retired if all -+ its transactions are complete or if an error occurred. Otherwise, it -+ remains in the schedule so more transactions can be executed later. -+ */ -+typedef struct ifxhcd_urbd { -+ struct list_head urbd_list_entry; // Hook for EPQH->urbd_list and ifxhcd->urbd_complete_list -+ struct urb *urb; /*!< URB for this transfer */ -+ //struct urb { -+ // struct list_head urb_list; -+ // struct list_head anchor_list; -+ // struct usb_anchor * anchor; -+ // struct usb_device * dev; -+ // struct usb_host_endpoint * ep; -+ // unsigned int pipe; -+ // int status; -+ // unsigned int transfer_flags; -+ // void * transfer_buffer; -+ // dma_addr_t transfer_dma; -+ // u32 transfer_buffer_length; -+ // u32 actual_length; -+ // unsigned char * setup_packet; -+ // dma_addr_t setup_dma; -+ // int start_frame; -+ // int number_of_packets; -+ // int interval; -+ // int error_count; -+ // void * context; -+ // usb_complete_t complete; -+ // struct usb_iso_packet_descriptor iso_frame_desc[0]; -+ //}; -+ //urb_list For use by current owner of the URB. -+ //anchor_list membership in the list of an anchor -+ //anchor to anchor URBs to a common mooring -+ //dev Identifies the USB device to perform the request. -+ //ep Points to the endpoint's data structure. Will -+ // eventually replace pipe. -+ //pipe Holds endpoint number, direction, type, and more. -+ // Create these values with the eight macros available; u -+ // sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is -+ // "ctrl", "bulk", "int" or "iso". For example -+ // usb_sndbulkpipe or usb_rcvintpipe. Endpoint numbers -+ // range from zero to fifteen. Note that "in" endpoint two -+ // is a different endpoint (and pipe) from "out" endpoint -+ // two. The current configuration controls the existence, -+ // type, and maximum packet size of any given endpoint. -+ //status This is read in non-iso completion functions to get -+ // the status of the particular request. ISO requests -+ // only use it to tell whether the URB was unlinked; -+ // detailed status for each frame is in the fields of -+ // the iso_frame-desc. -+ //transfer_flags A variety of flags may be used to affect how URB -+ // submission, unlinking, or operation are handled. -+ // Different kinds of URB can use different flags. -+ // URB_SHORT_NOT_OK -+ // URB_ISO_ASAP -+ // URB_NO_TRANSFER_DMA_MAP -+ // URB_NO_SETUP_DMA_MAP -+ // URB_NO_FSBR -+ // URB_ZERO_PACKET -+ // URB_NO_INTERRUPT -+ //transfer_buffer This identifies the buffer to (or from) which the I/O -+ // request will be performed (unless URB_NO_TRANSFER_DMA_MAP -+ // is set). This buffer must be suitable for DMA; allocate it -+ // with kmalloc or equivalent. For transfers to "in" -+ // endpoints, contents of this buffer will be modified. This -+ // buffer is used for the data stage of control transfers. -+ //transfer_dma When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, the -+ // device driver is saying that it provided this DMA address, -+ // which the host controller driver should use in preference -+ // to the transfer_buffer. -+ //transfer_buffer_length How big is transfer_buffer. The transfer may be broken -+ // up into chunks according to the current maximum packet size -+ // for the endpoint, which is a function of the configuration -+ // and is encoded in the pipe. When the length is zero, neither -+ // transfer_buffer nor transfer_dma is used. -+ //actual_length This is read in non-iso completion functions, and it tells -+ // how many bytes (out of transfer_buffer_length) were transferred. -+ // It will normally be the same as requested, unless either an error -+ // was reported or a short read was performed. The URB_SHORT_NOT_OK -+ // transfer flag may be used to make such short reads be reported -+ // as errors. -+ //setup_packet Only used for control transfers, this points to eight bytes of -+ // setup data. Control transfers always start by sending this data -+ // to the device. Then transfer_buffer is read or written, if needed. -+ //setup_dma For control transfers with URB_NO_SETUP_DMA_MAP set, the device -+ // driver has provided this DMA address for the setup packet. The -+ // host controller driver should use this in preference to setup_packet. -+ //start_frame Returns the initial frame for isochronous transfers. -+ //number_of_packets Lists the number of ISO transfer buffers. -+ //interval Specifies the polling interval for interrupt or isochronous transfers. -+ // The units are frames (milliseconds) for for full and low speed devices, -+ // and microframes (1/8 millisecond) for highspeed ones. -+ //error_count Returns the number of ISO transfers that reported errors. -+ //context For use in completion functions. This normally points to request-specific -+ // driver context. -+ //complete Completion handler. This URB is passed as the parameter to the completion -+ // function. The completion function may then do what it likes with the URB, -+ // including resubmitting or freeing it. -+ //iso_frame_desc[0] Used to provide arrays of ISO transfer buffers and to collect the transfer -+ // status for each buffer. -+ -+ struct ifxhcd_epqh *epqh; -+ // Actual data portion, not SETUP or STATUS in case of CTRL XFER -+ // DMA adjusted -+ uint8_t *setup_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/ -+ uint8_t *xfer_buff; /*!< Pointer to the entire transfer buffer. (CPU accessable)*/ -+ uint32_t xfer_len; /*!< Total number of bytes to transfer in this xfer. */ -+ unsigned is_in :1; -+ unsigned is_active:1; -+ -+ // For ALL XFER -+ uint8_t error_count; /*!< Holds the number of bus errors that have occurred for a transaction -+ within this transfer. -+ */ -+ /*== AVM/BC 20101111 Needed for URB Complete List ==*/ -+ int status; -+ // For ISOC XFER only -+ #ifdef __EN_ISOC__ -+ int isoc_frame_index; /*!< Index of the next frame descriptor for an isochronous transfer. A -+ frame descriptor describes the buffer position and length of the -+ data to be transferred in the next scheduled (micro)frame of an -+ isochronous transfer. It also holds status for that transaction. -+ The frame index starts at 0. -+ */ -+ // For SPLITed ISOC XFER only -+ uint8_t isoc_split_pos; /*!< Position of the ISOC split on full/low speed */ -+ uint16_t isoc_split_offset;/*!< Position of the ISOC split in the buffer for the current frame */ -+ #endif -+} ifxhcd_urbd_t; -+ -+/*! -+ \brief A EP Queue Head (EPQH) holds the static characteristics of an endpoint and -+ maintains a list of transfers (URBDs) for that endpoint. A EPQH structure may -+ be entered in either the isoc, intr or non-periodic schedule. -+ */ -+ -+typedef struct ifxhcd_epqh { -+ struct list_head epqh_list_entry; // Hook for EP Queues -+ struct list_head urbd_list; /*!< List of URBDs for this EPQH. */ -+ struct ifxhcd_hc *hc; /*!< Host channel currently processing transfers for this EPQH. */ -+ struct ifxhcd_urbd *urbd; /*!< URBD currently assigned to a host channel for this EPQH. */ -+ struct usb_host_endpoint *sysep; -+ uint8_t ep_type; /*!< Endpoint type. One of the following values: -+ - IFXUSB_EP_TYPE_CTRL -+ - IFXUSB_EP_TYPE_ISOC -+ - IFXUSB_EP_TYPE_BULK -+ - IFXUSB_EP_TYPE_INTR -+ */ -+ uint16_t mps; /*!< wMaxPacketSize Field of Endpoint Descriptor. */ -+ -+ /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/ -+ /*uint8_t data_toggle;*/ /*!< Determines the PID of the next data packet -+ One of the following values: -+ - IFXHCD_HC_PID_DATA0 -+ - IFXHCD_HC_PID_DATA1 -+ */ -+ uint8_t is_active; -+ -+ uint8_t pkt_count_limit; -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ struct timer_list destroy_timer; -+ #endif -+ -+ uint16_t wait_for_sof; -+ uint8_t need_split; /*!< Full/low speed endpoint on high-speed hub requires split. */ -+ uint16_t interval; /*!< Interval between transfers in (micro)frames. (for INTR)*/ -+ -+ uint16_t period_counter; /*!< Interval between transfers in (micro)frames. */ -+ uint8_t period_do; -+ -+ uint8_t aligned_checked; -+ -+ #if defined(__UNALIGNED_BUFFER_ADJ__) -+ uint8_t using_aligned_setup; -+ uint8_t *aligned_setup; -+ uint8_t using_aligned_buf; -+ uint8_t *aligned_buf; -+ unsigned aligned_buf_len : 19; -+ #endif -+ -+ uint8_t *dump_buf; -+} ifxhcd_epqh_t; -+ -+ -+#if defined(__HC_XFER_TIMEOUT__) -+ struct ifxusb_core_if; -+ struct ifxhcd_hc; -+ typedef struct hc_xfer_info -+ { -+ struct ifxusb_core_if *core_if; -+ struct ifxhcd_hc *hc; -+ } hc_xfer_info_t; -+#endif //defined(__HC_XFER_TIMEOUT__) -+ -+ -+/*! -+ \brief Host channel descriptor. This structure represents the state of a single -+ host channel when acting in host mode. It contains the data items needed to -+ transfer packets to an endpoint via a host channel. -+ */ -+typedef struct ifxhcd_hc -+{ -+ struct list_head hc_list_entry ; // Hook to free hc -+ struct ifxhcd_epqh *epqh ; /*!< EP Queue Head for the transfer being processed by this channel. */ -+ -+ uint8_t hc_num ; /*!< Host channel number used for register address lookup */ -+ uint8_t *xfer_buff ; /*!< Pointer to the entire transfer buffer. */ -+ uint32_t xfer_count ; /*!< Number of bytes transferred so far. The offset of the begin of the buf */ -+ uint32_t xfer_len ; /*!< Total number of bytes to transfer in this xfer. */ -+ uint16_t start_pkt_count ; /*!< Packet count at start of transfer. Used to calculate the actual xfer size*/ -+ ifxhcd_halt_status_e halt_status; /*!< Reason for halting the host channel. */ -+ -+ unsigned dev_addr : 7; /*!< Device to access */ -+ unsigned ep_num : 4; /*!< EP to access */ -+ unsigned is_in : 1; /*!< EP direction. 0: OUT, 1: IN */ -+ unsigned speed : 2; /*!< EP speed. */ -+ unsigned ep_type : 2; /*!< Endpoint type. */ -+ unsigned mps :11; /*!< Max packet size in bytes */ -+ unsigned data_pid_start : 2; /*!< PID for initial transaction. */ -+ unsigned do_ping : 1; /*!< Set to 1 to indicate that a PING request should be issued on this -+ channel. If 0, process normally. -+ */ -+ -+ unsigned xfer_started : 1; /*!< Flag to indicate whether the transfer has been started. Set to 1 if -+ it has been started, 0 otherwise. -+ */ -+ unsigned halting : 1; /*!< Set to 1 if the host channel has been halted, but the core is not -+ finished flushing queued requests. Otherwise 0. -+ */ -+ unsigned short_rw : 1; /*!< When Tx, means termination needed. -+ When Rx, indicate Short Read */ -+ /* Split settings for the host channel */ -+ unsigned split : 2; /*!< Split: 0-Non Split, 1-SSPLIT, 2&3 CSPLIT */ -+ -+ /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/ -+ unsigned nyet_count; -+ -+ /* nak monitor */ -+ unsigned nak_retry_r : 16; -+ unsigned nak_retry : 16; -+ #define nak_retry_max 40000 -+ unsigned nak_countdown : 8; -+ unsigned nak_countdown_r: 8; -+ #define nak_countdown_max 1 -+ -+ uint16_t wait_for_sof; -+ ifxhcd_control_phase_e control_phase; /*!< Current phase for control transfers (Setup, Data, or Status). */ -+ uint32_t ssplit_out_xfer_count; /*!< How many bytes transferred during SSPLIT OUT */ -+ #ifdef __DEBUG__ -+ uint32_t start_hcchar_val; -+ #endif -+ #ifdef __HC_XFER_TIMEOUT__ -+ hc_xfer_info_t hc_xfer_info; -+ struct timer_list hc_xfer_timer; -+ #endif -+ uint32_t hcchar; -+ -+ /* Split settings for the host channel */ -+ uint8_t hub_addr; /*!< Address of high speed hub */ -+ uint8_t port_addr; /*!< Port of the low/full speed device */ -+ #ifdef __EN_ISOC__ -+ uint8_t isoc_xact_pos; /*!< Split transaction position */ -+ #endif -+} ifxhcd_hc_t; -+ -+ -+/*! -+ \brief This structure holds the state of the HCD, including the non-periodic and -+ periodic schedules. -+ */ -+typedef struct ifxhcd_hcd -+{ -+ struct device *dev; -+ struct hc_driver hc_driver; -+ ifxusb_core_if_t core_if; /*!< Pointer to the core interface structure. */ -+ struct usb_hcd *syshcd; -+ -+ volatile union ifxhcd_internal_flags -+ { -+ uint32_t d32; -+ struct -+ { -+ unsigned port_connect_status_change : 1; -+ unsigned port_connect_status : 1; -+ unsigned port_reset_change : 1; -+ unsigned port_enable_change : 1; -+ unsigned port_suspend_change : 1; -+ unsigned port_over_current_change : 1; -+ unsigned reserved : 27; -+ } b; -+ } flags; /*!< Internal HCD Flags */ -+ -+ struct ifxhcd_hc ifxhc[MAX_EPS_CHANNELS]; /*!< Array of pointers to the host channel descriptors. Allows accessing -+ a host channel descriptor given the host channel number. This is -+ useful in interrupt handlers. -+ */ -+ struct list_head free_hc_list; /*!< Free host channels in the controller. This is a list of ifxhcd_hc_t items. */ -+ uint8_t *status_buf; /*!< Buffer to use for any data received during the status phase of a -+ control transfer. Normally no data is transferred during the status -+ phase. This buffer is used as a bit bucket. -+ */ -+ #define IFXHCD_STATUS_BUF_SIZE 64 -+ -+ struct list_head epqh_np_active; // with URBD, with HC -+ struct list_head epqh_np_ready; // with URBD, No HC -+ -+ struct list_head epqh_intr_active; // with URBD, with HC -+ struct list_head epqh_intr_ready; // with URBD, no pass, No HC -+ -+ #ifdef __EN_ISOC__ -+ struct list_head epqh_isoc_active; // with URBD, with HC -+ struct list_head epqh_isoc_ready; // with URBD, no pass, No HC -+ #endif -+ -+ /*== AVM/BC 20101111 URB Complete List ==*/ -+ struct list_head urbd_complete_list; -+ -+ struct list_head epqh_stdby; -+ -+ /* AVM/BC 20101111 flags removed */ -+ //unsigned process_channels_in_use : 1; -+ //unsigned select_eps_in_use : 1; -+ -+ struct tasklet_struct select_eps; /*!< Tasket to do a reset */ -+ uint32_t lastframe; -+ spinlock_t lock; -+#ifdef __USE_TIMER_4_SOF__ -+ struct hrtimer hr_timer; -+#endif -+} ifxhcd_hcd_t; -+ -+/* Gets the ifxhcd_hcd from a struct usb_hcd */ -+static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd) -+{ -+ return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]); -+} -+ -+/* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */ -+static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd) -+{ -+ return (struct usb_hcd *)(ifxhcd->syshcd); -+} -+ -+/*! \brief HCD Create/Destroy Functions */ -+/*@{*/ -+ extern int ifxhcd_init (ifxhcd_hcd_t *_ifxhcd); -+ extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd); -+/*@}*/ -+ -+/*! \brief Linux HC Driver API Functions */ -+/*@{*/ -+extern int ifxhcd_start(struct usb_hcd *hcd); -+extern void ifxhcd_stop (struct usb_hcd *hcd); -+extern int ifxhcd_get_frame_number(struct usb_hcd *hcd); -+ -+ -+/*! -+ \brief This function does the setup for a data transfer for a host channel and -+ starts the transfer. May be called in either Slave mode or DMA mode. In -+ Slave mode, the caller must ensure that there is sufficient space in the -+ request queue and Tx Data FIFO. -+ -+ For an OUT transfer in Slave mode, it loads a data packet into the -+ appropriate FIFO. If necessary, additional data packets will be loaded in -+ the Host ISR. -+ -+ For an IN transfer in Slave mode, a data packet is requested. The data -+ packets are unloaded from the Rx FIFO in the Host ISR. If necessary, -+ additional data packets are requested in the Host ISR. -+ -+ For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ -+ register along with a packet count of 1 and the channel is enabled. This -+ causes a single PING transaction to occur. Other fields in HCTSIZ are -+ simply set to 0 since no data transfer occurs in this case. -+ -+ For a PING transfer in DMA mode, the HCTSIZ register is initialized with -+ all the information required to perform the subsequent data transfer. In -+ addition, the Do Ping bit is set in the HCTSIZ register. In this case, the -+ controller performs the entire PING protocol, then starts the data -+ transfer. -+ -+ @param _ifxhc Information needed to initialize the host channel. The xfer_len -+ value may be reduced to accommodate the max widths of the XferSize and -+ PktCnt fields in the HCTSIZn register. The multi_count value may be changed -+ to reflect the final xfer_len value. -+ */ -+extern void ifxhcd_hc_start(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc); -+ -+//extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags); -+//extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb); -+extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd); -+int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd, -+ /*--- struct usb_host_endpoint *_sysep, Parameter im 2.6.28 entfallen ---*/ -+ struct urb *_urb, -+ gfp_t _mem_flags); -+int ifxhcd_urb_dequeue( struct usb_hcd *_syshcd, -+ struct urb *_urb, int status /* Parameter neu in 2.6.28 */); -+ -+extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep); -+ -+extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf); -+extern int ifxhcd_hub_control( struct usb_hcd *_syshcd, -+ u16 _typeReq, -+ u16 _wValue, -+ u16 _wIndex, -+ char *_buf, -+ u16 _wLength); -+ -+/*@}*/ -+ -+/*! \brief Transaction Execution Functions */ -+/*@{*/ -+extern void ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status); -+ -+/*@}*/ -+ -+/*! \brief Deferred Transaction Execution Functions */ -+/*@{*/ -+ -+/*== AVM/BC 20101111 URB Complete List ==*/ -+extern void defer_ifxhcd_complete_urb (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd, int _status); -+ -+/*! -+ \brief Clears the transfer state for a host channel. This function is normally -+ called after a transfer is done and the host channel is being released. -+ */ -+extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc); -+ -+/*! -+ \brief Attempts to halt a host channel. This function should only be called in -+ Slave mode or to abort a transfer in either Slave mode or DMA mode. Under -+ normal circumstances in DMA mode, the controller halts the channel when the -+ transfer is complete or a condition occurs that requires application -+ intervention. -+ -+ In slave mode, checks for a free request queue entry, then sets the Channel -+ Enable and Channel Disable bits of the Host Channel Characteristics -+ register of the specified channel to intiate the halt. If there is no free -+ request queue entry, sets only the Channel Disable bit of the HCCHARn -+ register to flush requests for this channel. In the latter case, sets a -+ flag to indicate that the host channel needs to be halted when a request -+ queue slot is open. -+ -+ In DMA mode, always sets the Channel Enable and Channel Disable bits of the -+ HCCHARn register. The controller ensures there is space in the request -+ queue before submitting the halt request. -+ -+ Some time may elapse before the core flushes any posted requests for this -+ host channel and halts. The Channel Halted interrupt handler completes the -+ deactivation of the host channel. -+ */ -+extern void ifxhcd_hc_halt(ifxusb_core_if_t *_core_if, -+ ifxhcd_hc_t *_ifxhc, -+ ifxhcd_halt_status_e _halt_status); -+ -+/*! -+ \brief Prepares a host channel for transferring packets to/from a specific -+ endpoint. The HCCHARn register is set up with the characteristics specified -+ in _ifxhc. Host channel interrupts that may need to be serviced while this -+ transfer is in progress are enabled. -+ */ -+extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc); -+ -+/*! -+ \brief This function is called to handle the disconnection of host port. -+ */ -+int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd); -+/*@}*/ -+ -+/*! \brief Interrupt Handler Functions */ -+/*@{*/ -+extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev); -+ -+extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd); -+extern int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd); -+/*@}*/ -+ -+ -+/*! \brief Schedule Queue Functions */ -+/*@{*/ -+extern ifxhcd_epqh_t *ifxhcd_epqh_create (ifxhcd_hcd_t *_ifxhcd, struct urb *_urb); -+extern void ifxhcd_epqh_free ( ifxhcd_epqh_t *_epqh); -+extern void select_eps (ifxhcd_hcd_t *_ifxhcd); -+extern void process_channels(ifxhcd_hcd_t *_ifxhcd); -+extern void process_channels_sub(ifxhcd_hcd_t *_ifxhcd); -+extern void complete_channel(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc, ifxhcd_urbd_t *_urbd); -+extern void ifxhcd_epqh_ready(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh); -+extern void ifxhcd_epqh_active(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh); -+extern void ifxhcd_epqh_idle(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh); -+extern void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh); -+extern int ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb); -+/*@}*/ -+ -+/*! \brief Gets the usb_host_endpoint associated with an URB. */ -+static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb) -+{ -+ struct usb_device *dev = _urb->dev; -+ int ep_num = usb_pipeendpoint(_urb->pipe); -+ -+ return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]); -+} -+ -+/*! -+ * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is -+ * qualified with its direction (possible 32 endpoints per device). -+ */ -+#define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \ -+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4) -+ -+ -+/* AVM/WK: not needed? -+ -+extern struct usb_device *usb_alloc_dev (struct usb_device *parent, struct usb_bus *, unsigned port); -+extern int usb_add_hcd (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags); -+extern void usb_remove_hcd (struct usb_hcd *syshcd); -+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name); -+extern void usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb); -+extern void usb_put_hcd (struct usb_hcd *syshcd); -+extern long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount); -+ -+*/ -+/** Internal Functions */ -+void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd); -+extern char *syserr(int errno); -+ -+/*@}*//*IFXUSB_HCD*/ -+ -+#endif // __IFXHCD_H__ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxhcd_es.c -@@ -0,0 +1,549 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxhcd_es.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The file contain function to enable host mode USB-IF Electrical Test function. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxhcd_es.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief The file contain function to enable host mode USB-IF Electrical Test function. -+*/ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <linux/kernel.h> -+ -+#include <linux/errno.h> -+ -+#include <linux/dma-mapping.h> -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+#include "ifxhcd.h" -+ -+ -+#ifdef __WITH_HS_ELECT_TST__ -+ /* -+ * Quick and dirty hack to implement the HS Electrical Test -+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature. -+ * -+ * This code was copied from our userspace app "hset". It sends a -+ * Get Device Descriptor control sequence in two parts, first the -+ * Setup packet by itself, followed some time later by the In and -+ * Ack packets. Rather than trying to figure out how to add this -+ * functionality to the normal driver code, we just hijack the -+ * hardware, using these two function to drive the hardware -+ * directly. -+ */ -+ -+ -+ void do_setup(ifxusb_core_if_t *_core_if) -+ { -+ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs; -+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0]; -+ uint32_t *data_fifo = _core_if->data_fifo[0]; -+ -+ gint_data_t gintsts; -+ hctsiz_data_t hctsiz; -+ hcchar_data_t hcchar; -+ haint_data_t haint; -+ hcint_data_t hcint; -+ -+ -+ /* Enable HAINTs */ -+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001); -+ -+ /* Enable HCINTs */ -+ ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* -+ * Send Setup packet (Get Device Descriptor) -+ */ -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32); -+ hcchar.b.chdis = 1; -+ // hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ //sleep(1); -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //if (hcchar.b.chen) { -+ // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32); -+ //} -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 8; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = IFXUSB_HC_PID_SETUP; -+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL; -+ hcchar.b.epdir = 0; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ -+ /* Fill FIFO with Setup data for Get Device Descriptor */ -+ ifxusb_wreg(data_fifo++, 0x01000680); -+ ifxusb_wreg(data_fifo++, 0x00080000); -+ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Disable HCINTs */ -+ ifxusb_wreg(&hc_regs->hcintmsk, 0x0000); -+ -+ /* Disable HAINTs */ -+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ } -+ -+ void do_in_ack(ifxusb_core_if_t *_core_if) -+ { -+ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ ifxusb_host_global_regs_t *hc_global_regs = _core_if->host_global_regs; -+ ifxusb_hc_regs_t *hc_regs = _core_if->hc_regs[0]; -+ uint32_t *data_fifo = _core_if->data_fifo[0]; -+ -+ gint_data_t gintsts; -+ hctsiz_data_t hctsiz; -+ hcchar_data_t hcchar; -+ haint_data_t haint; -+ hcint_data_t hcint; -+ grxsts_data_t grxsts; -+ -+ /* Enable HAINTs */ -+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0001); -+ -+ /* Enable HCINTs */ -+ ifxusb_wreg(&hc_regs->hcintmsk, 0x04a3); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* -+ * Receive Control In packet -+ */ -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32); -+ hcchar.b.chdis = 1; -+ hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ //sleep(1); -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //if (hcchar.b.chen) { -+ // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32); -+ //} -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 8; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = IFXUSB_HC_PID_DATA1; -+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL; -+ hcchar.b.epdir = 1; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Wait for receive status queue interrupt */ -+ do { -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ } while (gintsts.b.rxstsqlvl == 0); -+ -+ //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Read RXSTS */ -+ grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp); -+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32); -+ -+ /* Clear RXSTSQLVL in GINTSTS */ -+ gintsts.d32 = 0; -+ gintsts.b.rxstsqlvl = 1; -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ switch (grxsts.hb.pktsts) { -+ case IFXUSB_HSTS_DATA_UPDT: -+ /* Read the data into the host buffer */ -+ if (grxsts.hb.bcnt > 0) { -+ int i; -+ int word_count = (grxsts.hb.bcnt + 3) / 4; -+ -+ for (i = 0; i < word_count; i++) { -+ (void)ifxusb_rreg(data_fifo++); -+ } -+ } -+ -+ //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.hb.bcnt); -+ break; -+ -+ default: -+ //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n"); -+ break; -+ } -+ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Wait for receive status queue interrupt */ -+ do { -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ } while (gintsts.b.rxstsqlvl == 0); -+ -+ //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Read RXSTS */ -+ grxsts.d32 = ifxusb_rreg(&global_regs->grxstsp); -+ //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32); -+ -+ /* Clear RXSTSQLVL in GINTSTS */ -+ gintsts.d32 = 0; -+ gintsts.b.rxstsqlvl = 1; -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ switch (grxsts.hb.pktsts) { -+ case IFXUSB_HSTS_XFER_COMP: -+ break; -+ -+ default: -+ //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n"); -+ break; -+ } -+ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ // usleep(100000); -+ // mdelay(100); -+ mdelay(1); -+ -+ /* -+ * Send handshake packet -+ */ -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32); -+ hcchar.b.chdis = 1; -+ hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ //sleep(1); -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //if (hcchar.b.chen) { -+ // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32); -+ //} -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 0; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = IFXUSB_HC_PID_DATA1; -+ ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ hcchar.b.eptype = IFXUSB_EP_TYPE_CTRL; -+ hcchar.b.epdir = 0; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ ifxusb_wreg(&hc_regs->hcchar, hcchar.d32); -+ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32); -+ -+ /* Disable HCINTs */ -+ ifxusb_wreg(&hc_regs->hcintmsk, 0x0000); -+ -+ /* Disable HAINTs */ -+ ifxusb_wreg(&hc_global_regs->haintmsk, 0x0000); -+ -+ /* Read HAINT */ -+ haint.d32 = ifxusb_rreg(&hc_global_regs->haint); -+ //fprintf(stderr, "HAINT: %08x\n", haint.d32); -+ -+ /* Read HCINT */ -+ hcint.d32 = ifxusb_rreg(&hc_regs->hcint); -+ //fprintf(stderr, "HCINT: %08x\n", hcint.d32); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar); -+ //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); -+ -+ /* Clear HCINT */ -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ ifxusb_wreg(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ ifxusb_wreg(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = ifxusb_rreg(&global_regs->gintsts); -+ //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); -+ } -+#endif //__WITH_HS_ELECT_TST__ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxhcd_intr.c -@@ -0,0 +1,3742 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxhcd_intr.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the implementation of the HCD Interrupt handlers. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxhcd_intr.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the implementation of the HCD Interrupt handlers. -+*/ -+ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+ -+#include "ifxhcd.h" -+ -+/* AVM/WK 20100520*/ -+#ifdef __EN_ISOC__ -+#error AVM/WK: CONFIG_USB_HOST_IFX_WITH_ISO currently not supported! -+#endif -+ -+/* Macro used to clear one channel interrupt */ -+#define clear_hc_int(_hc_regs_,_intr_) \ -+ do { \ -+ hcint_data_t hcint_clear = {.d32 = 0}; \ -+ hcint_clear.b._intr_ = 1; \ -+ ifxusb_wreg(&((_hc_regs_)->hcint), hcint_clear.d32); \ -+ } while (0) -+ -+/* -+ * Macro used to disable one channel interrupt. Channel interrupts are -+ * disabled when the channel is halted or released by the interrupt handler. -+ * There is no need to handle further interrupts of that type until the -+ * channel is re-assigned. In fact, subsequent handling may cause crashes -+ * because the channel structures are cleaned up when the channel is released. -+ */ -+#define disable_hc_int(_hc_regs_,_intr_) \ -+ do { \ -+ hcint_data_t hcintmsk = {.d32 = 0}; \ -+ hcintmsk.b._intr_ = 1; \ -+ ifxusb_mreg(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \ -+ } while (0) -+ -+#define enable_hc_int(_hc_regs_,_intr_) \ -+ do { \ -+ hcint_data_t hcintmsk = {.d32 = 0}; \ -+ hcintmsk.b._intr_ = 1; \ -+ ifxusb_mreg(&((_hc_regs_)->hcintmsk),0, hcintmsk.d32); \ -+ } while (0) -+ -+/* -+ * Save the starting data toggle for the next transfer. The data toggle is -+ * saved in the QH for non-control transfers and it's saved in the QTD for -+ * control transfers. -+ */ -+uint8_t read_data_toggle(ifxusb_hc_regs_t *_hc_regs) -+{ -+ hctsiz_data_t hctsiz; -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ return(hctsiz.b.pid); -+} -+ -+ -+static void release_channel_dump(ifxhcd_hc_t *ifxhc, -+ struct urb *urb, -+ ifxhcd_epqh_t *epqh, -+ ifxhcd_urbd_t *urbd, -+ ifxhcd_halt_status_e halt_status) -+{ -+ #ifdef __DEBUG__ -+ printk(KERN_INFO); -+ switch (halt_status) -+ { -+ case HC_XFER_NO_HALT_STATUS: -+ printk("HC_XFER_NO_HALT_STATUS");break; -+ case HC_XFER_URB_COMPLETE: -+ printk("HC_XFER_URB_COMPLETE");break; -+ case HC_XFER_AHB_ERR: -+ printk("HC_XFER_AHB_ERR");break; -+ case HC_XFER_STALL: -+ printk("HC_XFER_STALL");break; -+ case HC_XFER_BABBLE_ERR: -+ printk("HC_XFER_BABBLE_ERR");break; -+ case HC_XFER_XACT_ERR: -+ printk("HC_XFER_XACT_ERR");break; -+ case HC_XFER_URB_DEQUEUE: -+ printk("HC_XFER_URB_DEQUEUE");break; -+ case HC_XFER_FRAME_OVERRUN: -+ printk("HC_XFER_FRAME_OVERRUN");break; -+ case HC_XFER_DATA_TOGGLE_ERR: -+ printk("HC_XFER_DATA_TOGGLE_ERR");break; -+ case HC_XFER_NAK: -+ printk("HC_XFER_NAK");break; -+ case HC_XFER_COMPLETE: -+ printk("HC_XFER_COMPLETE");break; -+ default: -+ printk("KNOWN");break; -+ } -+ if(ifxhc) -+ printk("Ch %d %s%s S%d " , ifxhc->hc_num -+ ,(ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)?"CTRL-": -+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)?"BULK-": -+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)?"INTR-": -+ ((ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)?"ISOC-":"????" -+ ) -+ ) -+ ) -+ ,(ifxhc->is_in)?"IN":"OUT" -+ ,(ifxhc->split) -+ ); -+ else -+ printk(" [NULL HC] "); -+ printk("urb=%p epqh=%p urbd=%p\n",urb,epqh,urbd); -+ -+ if(urb) -+ { -+ printk(KERN_INFO " Device address: %d\n", usb_pipedevice(urb->pipe)); -+ printk(KERN_INFO " Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe), -+ (usb_pipein(urb->pipe) ? "IN" : "OUT")); -+ printk(KERN_INFO " Endpoint type: %s\n", -+ ({char *pipetype; -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: pipetype = "CTRL"; break; -+ case PIPE_BULK: pipetype = "BULK"; break; -+ case PIPE_INTERRUPT: pipetype = "INTR"; break; -+ case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break; -+ default: pipetype = "????"; break; -+ }; pipetype;})); -+ printk(KERN_INFO " Speed: %s\n", -+ ({char *speed; -+ switch (urb->dev->speed) { -+ case USB_SPEED_HIGH: speed = "HS"; break; -+ case USB_SPEED_FULL: speed = "FS"; break; -+ case USB_SPEED_LOW: speed = "LS"; break; -+ default: speed = "????"; break; -+ }; speed;})); -+ printk(KERN_INFO " Max packet size: %d\n", -+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); -+ printk(KERN_INFO " Data buffer length: %d\n", urb->transfer_buffer_length); -+ printk(KERN_INFO " Transfer buffer: %p, Transfer DMA: %p\n", -+ urb->transfer_buffer, (void *)urb->transfer_dma); -+ printk(KERN_INFO " Setup buffer: %p, Setup DMA: %p\n", -+ urb->setup_packet, (void *)urb->setup_dma); -+ printk(KERN_INFO " Interval: %d\n", urb->interval); -+ switch (urb->status) -+ { -+ case HC_XFER_NO_HALT_STATUS: -+ printk(KERN_INFO " STATUS:HC_XFER_NO_HALT_STATUS\n");break; -+ case HC_XFER_URB_COMPLETE: -+ printk(KERN_INFO " STATUS:HC_XFER_URB_COMPLETE\n");break; -+ case HC_XFER_AHB_ERR: -+ printk(KERN_INFO " STATUS:HC_XFER_AHB_ERR\n");break; -+ case HC_XFER_STALL: -+ printk(KERN_INFO " STATUS:HC_XFER_STALL\n");break; -+ case HC_XFER_BABBLE_ERR: -+ printk(KERN_INFO " STATUS:HC_XFER_BABBLE_ERR\n");break; -+ case HC_XFER_XACT_ERR: -+ printk(KERN_INFO " STATUS:HC_XFER_XACT_ERR\n");break; -+ case HC_XFER_URB_DEQUEUE: -+ printk(KERN_INFO " STATUS:HC_XFER_URB_DEQUEUE\n");break; -+ case HC_XFER_FRAME_OVERRUN: -+ printk(KERN_INFO " STATUS:HC_XFER_FRAME_OVERRUN\n");break; -+ case HC_XFER_DATA_TOGGLE_ERR: -+ printk(KERN_INFO " STATUS:HC_XFER_DATA_TOGGLE_ERR\n");break; -+ case HC_XFER_COMPLETE: -+ printk(KERN_INFO " STATUS:HC_XFER_COMPLETE\n");break; -+ default: -+ printk(KERN_INFO " STATUS:KNOWN\n");break; -+ } -+ } -+ #endif -+} -+ -+ -+static void release_channel(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxhcd_halt_status_e _halt_status) -+{ -+ ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num]; -+ struct urb *urb = NULL; -+ ifxhcd_epqh_t *epqh = NULL; -+ ifxhcd_urbd_t *urbd = NULL; -+ -+ IFX_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", -+ __func__, _ifxhc->hc_num, _halt_status); -+ -+ epqh=_ifxhc->epqh; -+ -+ if(!epqh) -+ IFX_ERROR("%s epqh=null\n",__func__); -+ else -+ { -+ urbd=epqh->urbd; -+ if(!urbd) -+ IFX_ERROR("%s urbd=null\n",__func__); -+ else -+ { -+ urb=urbd->urb; -+ if(!urb) -+ IFX_ERROR("%s urb =null\n",__func__); -+ else { -+ /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/ -+ unsigned toggle = (read_data_toggle(hc_regs) == IFXUSB_HC_PID_DATA0)? 0: 1; -+ usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), usb_pipeout(urb->pipe), toggle); -+ } -+ } -+ //epqh->data_toggle = read_data_toggle(hc_regs); -+ -+ } -+ -+ switch (_halt_status) -+ { -+ case HC_XFER_NO_HALT_STATUS: -+ IFX_ERROR("%s: No halt_status, channel %d\n", __func__, _ifxhc->hc_num); -+ break; -+ case HC_XFER_COMPLETE: -+ IFX_ERROR("%s: Inavalid halt_status HC_XFER_COMPLETE, channel %d\n", __func__, _ifxhc->hc_num); -+ break; -+ case HC_XFER_URB_COMPLETE: -+ case HC_XFER_URB_DEQUEUE: -+ case HC_XFER_AHB_ERR: -+ case HC_XFER_XACT_ERR: -+ case HC_XFER_FRAME_OVERRUN: -+ if(urbd && urb) { -+ /* == 20110803 AVM/WK FIX set status, if still in progress == */ -+ if (urb->status == -EINPROGRESS) { -+ switch (_halt_status) { -+ case HC_XFER_URB_COMPLETE: -+ urb->status = 0; -+ break; -+ case HC_XFER_URB_DEQUEUE: -+ urb->status = -ECONNRESET; -+ break; -+ case HC_XFER_AHB_ERR: -+ case HC_XFER_XACT_ERR: -+ case HC_XFER_FRAME_OVERRUN: -+ urb->status = -EPROTO; -+ break; -+ default: -+ break; -+ } -+ } -+ /*== AVM/BC 20101111 Deferred Complete ==*/ -+ defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status); -+ } -+ else -+ { -+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb); -+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status); -+ } -+ if(epqh) -+ ifxhcd_epqh_idle(_ifxhcd, epqh); -+ else -+ { -+ IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh); -+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status); -+ } -+ -+ list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc); -+ break; -+ case HC_XFER_STALL: -+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status); -+ if(urbd) -+ /*== AVM/BC 20101111 Deferred Complete ==*/ -+ defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EPIPE); -+ else -+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb); -+ if(epqh) -+ { -+// epqh->data_toggle = 0; -+ ifxhcd_epqh_idle(_ifxhcd, epqh); -+ } -+ else -+ IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh); -+ list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc); -+ break; -+ case HC_XFER_NAK: -+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status); -+ if(urbd) -+ { -+ //ifxhcd_complete_urb(_ifxhcd, urbd, -ETIMEDOUT); -+ urb->status = 0; -+ /*== AVM/BC 20101111 Deferred Complete ==*/ -+ defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status); -+ } -+ else -+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb); -+ if(epqh) -+ ifxhcd_epqh_idle(_ifxhcd, epqh); -+ else -+ IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh); -+ list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc); -+ break; -+ case HC_XFER_BABBLE_ERR: -+ case HC_XFER_DATA_TOGGLE_ERR: -+ release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status); -+ if(urbd) -+ /*== AVM/BC 20101111 Deferred Complete ==*/ -+ defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EOVERFLOW); -+ else -+ IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb); -+ if(epqh) -+ ifxhcd_epqh_idle(_ifxhcd, epqh); -+ else -+ IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh); -+ list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list); -+ ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc); -+ break; -+ } -+ select_eps(_ifxhcd); -+} -+ -+/* -+ * Updates the state of the URB after a Transfer Complete interrupt on the -+ * host channel. Updates the actual_length field of the URB based on the -+ * number of bytes transferred via the host channel. Sets the URB status -+ * if the data transfer is finished. -+ * -+ * @return 1 if the data transfer specified by the URB is completely finished, -+ * 0 otherwise. -+ */ -+static int update_urb_state_xfer_comp(ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ struct urb *_urb, -+ ifxhcd_urbd_t *_urbd) -+{ -+ int xfer_done = 0; -+ -+ if (_ifxhc->is_in) -+ { -+ hctsiz_data_t hctsiz; -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ _urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ if ((hctsiz.b.xfersize != 0) || (_urb->actual_length >= _urb->transfer_buffer_length)) -+ { -+ xfer_done = 1; -+ _urb->status = 0; -+ /* 20110805 AVM/WK Workaround: catch overflow error here, hardware does not */ -+ if (_urb->actual_length > _urb->transfer_buffer_length) { -+ _urb->status = -EOVERFLOW; -+ } -+ #if 0 -+ if (_urb->actual_length < _urb->transfer_buffer_length && _urb->transfer_flags & URB_SHORT_NOT_OK) -+ _urb->status = -EREMOTEIO; -+ #endif -+ } -+ -+ } -+ else -+ { -+ if (_ifxhc->split) -+ _urb->actual_length += _ifxhc->ssplit_out_xfer_count; -+ else -+ _urb->actual_length += _ifxhc->xfer_len; -+ -+ if (_urb->actual_length >= _urb->transfer_buffer_length) -+ { -+ /*== AVM/BC WK 20110421 ZERO PACKET Workaround ==*/ -+ if ((_ifxhc->short_rw == 1) && ( _ifxhc->xfer_len > 0) && ( _ifxhc->xfer_len % _ifxhc->mps == 0 )) -+ { -+ _ifxhc->short_rw = 0; -+ //Transfer not finished. Another iteration for ZLP. -+ } -+ else -+ { -+ xfer_done = 1; -+ } -+ _urb->status = 0; -+ } -+ } -+ -+ #ifdef __DEBUG__ -+ { -+ hctsiz_data_t hctsiz; -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB: %s: %s, channel %d\n", -+ __func__, (_ifxhc->is_in ? "IN" : "OUT"), _ifxhc->hc_num); -+ IFX_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _ifxhc->xfer_len); -+ IFX_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize); -+ IFX_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n", -+ _urb->transfer_buffer_length); -+ IFX_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length); -+ } -+ #endif -+ return xfer_done; -+} -+ -+/*== AVM/BC 20101111 Function called with Lock ==*/ -+ -+void complete_channel(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxhcd_urbd_t *_urbd) -+{ -+ ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num]; -+ struct urb *urb = NULL; -+ ifxhcd_epqh_t *epqh = NULL; -+ int urb_xfer_done; -+ -+ IFX_DEBUGPL(DBG_HCD, "--Complete Channel %d : \n", _ifxhc->hc_num); -+ -+ if(!_urbd) -+ { -+ IFX_ERROR("ERROR %s():%d urbd=%p\n",__func__,__LINE__,_urbd); -+ return; -+ } -+ -+ urb = _urbd->urb; -+ epqh = _urbd->epqh; -+ -+ if(!urb || !epqh) -+ { -+ IFX_ERROR("ERROR %s():%d urb=%p epqh=%p\n",__func__,__LINE__,urb,epqh); -+ return; -+ } -+ -+ _ifxhc->do_ping=0; -+ -+ if (_ifxhc->split) -+ _ifxhc->split = 1; -+ -+ switch (epqh->ep_type) -+ { -+ case IFXUSB_EP_TYPE_CTRL: -+ switch (_ifxhc->control_phase) -+ { -+ case IFXHCD_CONTROL_SETUP: -+ IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done\n"); -+ if (_urbd->xfer_len > 0) -+ { -+ _ifxhc->control_phase = IFXHCD_CONTROL_DATA; -+ _ifxhc->is_in = _urbd->is_in; -+ _ifxhc->xfer_len = _urbd->xfer_len; -+ #if defined(__UNALIGNED_BUFFER_ADJ__) -+ if(epqh->using_aligned_buf) -+ _ifxhc->xfer_buff = epqh->aligned_buf; -+ else -+ #endif -+ _ifxhc->xfer_buff = _urbd->xfer_buff; -+ } -+ else -+ { -+ _ifxhc->control_phase = IFXHCD_CONTROL_STATUS; -+ _ifxhc->is_in = 1; -+ _ifxhc->xfer_len = 0; -+ _ifxhc->xfer_buff = _ifxhcd->status_buf; -+ } -+ if(_ifxhc->is_in) -+ _ifxhc->short_rw =0; -+ else -+ _ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0; -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ _ifxhc->xfer_count = 0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ /*== AVM/BC 20101111 Lock not needed ==*/ -+ process_channels_sub(_ifxhcd); -+ break; -+ case IFXHCD_CONTROL_DATA: -+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd); -+ if (urb_xfer_done) -+ { -+ _ifxhc->control_phase = IFXHCD_CONTROL_STATUS; -+ _ifxhc->is_in = (_urbd->is_in)?0:1; -+ _ifxhc->xfer_len = 0; -+ _ifxhc->xfer_count = 0; -+ _ifxhc->xfer_buff = _ifxhcd->status_buf; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ if(_ifxhc->is_in) -+ _ifxhc->short_rw =0; -+ else -+ _ifxhc->short_rw =1; -+ } -+ else // continue -+ { -+ _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length; -+ _ifxhc->xfer_count = urb->actual_length; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->data_pid_start = read_data_toggle(hc_regs); -+ } -+ /*== AVM/BC 20101111 Lock not needed ==*/ -+ process_channels_sub(_ifxhcd); -+ break; -+ case IFXHCD_CONTROL_STATUS: -+ if (urb->status == -EINPROGRESS) -+ urb->status = 0; -+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE); -+ break; -+ } -+ break; -+ case IFXUSB_EP_TYPE_BULK: -+ IFX_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n"); -+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd); -+ if (urb_xfer_done) -+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE); -+ else -+ { -+ _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length; -+ _ifxhc->xfer_count = urb->actual_length; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->data_pid_start = read_data_toggle(hc_regs); -+ /*== AVM/BC 20101111 Lock not needed ==*/ -+ process_channels_sub(_ifxhcd); -+ } -+ break; -+ case IFXUSB_EP_TYPE_INTR: -+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd); -+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE); -+ break; -+ case IFXUSB_EP_TYPE_ISOC: -+// if (_urbd->isoc_split_pos == IFXUSB_HCSPLIT_XACTPOS_ALL) -+// halt_status = update_isoc_urb_state(_ifxhcd, _ifxhc, hc_regs, _urbd, HC_XFER_COMPLETE); -+// complete_periodic_xfer(_ifxhcd, _ifxhc, hc_regs, _urbd, halt_status); -+ urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd); -+ release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE); -+ break; -+ } -+} -+ -+ -+ -+void showint(uint32_t val_hcint -+ ,uint32_t val_hcintmsk -+ ,uint32_t val_hctsiz) -+{ -+#ifdef __DEBUG__ -+ hcint_data_t hcint = {.d32 = val_hcint}; -+ hcint_data_t hcintmsk = {.d32 = val_hcintmsk}; -+ -+ printk(KERN_INFO " WITH FLAG: Sz:%08x I:%08X/M:%08X %s%s%s%s%s%s%s%s%s%s\n" -+ ,val_hctsiz,hcint.d32 ,hcintmsk.d32 -+ ,(hcint.b.datatglerr || hcintmsk.b.datatglerr)? -+ ( -+ (hcint.b.datatglerr && hcintmsk.b.datatglerr)?"datatglerr[*/*] ": -+ ( -+ (hcint.b.datatglerr)?"datatglerr[*/] ":"datatglerr[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.frmovrun || hcintmsk.b.frmovrun)? -+ ( -+ (hcint.b.frmovrun && hcintmsk.b.frmovrun)?"frmovrun[*/*] ": -+ ( -+ (hcint.b.frmovrun)?"frmovrun[*/] ":"frmovrun[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.bblerr || hcintmsk.b.bblerr)? -+ ( -+ (hcint.b.bblerr && hcintmsk.b.bblerr)?"bblerr[*/*] ": -+ ( -+ (hcint.b.bblerr)?"bblerr[*/] ":"bblerr[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.xacterr || hcintmsk.b.xacterr)? -+ ( -+ (hcint.b.xacterr && hcintmsk.b.xacterr)?"xacterr[*/*] ": -+ ( -+ (hcint.b.xacterr)?"xacterr[*/] ":"xacterr[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.nyet || hcintmsk.b.nyet)? -+ ( -+ (hcint.b.nyet && hcintmsk.b.nyet)?"nyet[*/*] ": -+ ( -+ (hcint.b.nyet)?"nyet[*/] ":"nyet[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.nak || hcintmsk.b.nak)? -+ ( -+ (hcint.b.nak && hcintmsk.b.nak)?"nak[*/*] ": -+ ( -+ (hcint.b.nak)?"nak[*/] ":"nak[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.ack || hcintmsk.b.ack)? -+ ( -+ (hcint.b.ack && hcintmsk.b.ack)?"ack[*/*] ": -+ ( -+ (hcint.b.ack)?"ack[*/] ":"ack[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.stall || hcintmsk.b.stall)? -+ ( -+ (hcint.b.stall && hcintmsk.b.stall)?"stall[*/*] ": -+ ( -+ (hcint.b.stall)?"stall[*/] ":"stall[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.ahberr || hcintmsk.b.ahberr)? -+ ( -+ (hcint.b.ahberr && hcintmsk.b.ahberr)?"ahberr[*/*] ": -+ ( -+ (hcint.b.ahberr)?"ahberr[*/] ":"ahberr[/*] " -+ ) -+ ) -+ :"" -+ ,(hcint.b.xfercomp || hcintmsk.b.xfercomp)? -+ ( -+ (hcint.b.xfercomp && hcintmsk.b.xfercomp)?"xfercomp[*/*] ": -+ ( -+ (hcint.b.xfercomp)?"xfercomp[*/] ":"xfercomp[/*] " -+ ) -+ ) -+ :"" -+ ); -+#endif -+} -+ -+ -+extern void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf); -+ -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->do_ping = 0; -+ -+ if(_ifxhc->halt_status == HC_XFER_NAK) -+ { -+ if(_ifxhc->nak_retry_r) -+ { -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ _ifxhc->nak_retry--; -+ if(_ifxhc->nak_retry) -+ { -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status); -+ } -+ } -+ else -+ { -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ -+ if (hcint.b.xfercomp) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if (hcint.b.stall) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ // ZLP shortcut -+ #if 0 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ { -+ // Stall FIFO compensation. -+ #if 0 -+ int sz1,sz2; -+ sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt; -+ sz2*=_ifxhc->mps; -+ sz1=_ifxhc->xfer_len - hctsiz.b.xfersize; -+ sz2-=sz1; -+ if(sz2) -+ ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf); -+ #endif -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ } -+ return 1; -+ } -+ else if (hcint.b.bblerr) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ -+ // ZLP shortcut -+ #if 0 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if (hcint.b.xacterr) -+ { -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ #endif -+ { -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ -+ /* 20110803 AVM/WK FIX: Reset error count on any handshake */ -+ if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) { -+ _urbd->error_count = 1; -+ } else { -+ _urbd->error_count++; -+ } -+ -+ if (_urbd->error_count >= 3) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ #if 1 -+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ #else -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ #endif -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 FRMOVRUN [should be Period only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.nyet ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 NYET [should be Out only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+#ifdef __DEBUG__ -+static int first=0; -+#endif -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+#ifdef __DEBUG__ -+if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK -+ &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack) -+{ -+ showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ first=1; -+ printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n" -+ ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3) -+ ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7) -+ ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11) -+ ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15)); -+ -+ printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n" -+ ,_urbd->urb->actual_length -+ ,_ifxhc->start_pkt_count -+ ,hctsiz.b.pktcnt -+ ,_urbd->xfer_len); -+} -+#endif -+ -+ if(_ifxhc->halt_status == HC_XFER_NAK) -+ { -+ if(_ifxhc->nak_retry_r) -+ { -+ _ifxhc->nak_retry--; -+ if(_ifxhc->nak_retry) -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status); -+ } -+ } -+ else -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ -+ if (hcint.b.xfercomp) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count =0; -+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak) -+ { -+ // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr -+ // Solution: NoSplit: Resend at next SOF -+ // Split : Resend at next SOF with SSPLIT -+ if(hcint.b.nyet && !out_nak_enh) -+ _ifxhc->do_ping = 1; -+ else -+ _ifxhc->do_ping = 0; -+ _ifxhc->xfer_len = 0; -+ _ifxhc->xfer_count = 0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if (hcint.b.stall) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ } -+ return 1; -+ } -+ else if (hcint.b.xacterr) -+ { -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ #endif -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ -+ if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =1; -+ enable_hc_int(_hc_regs,ack); -+ enable_hc_int(_hc_regs,nak); -+ enable_hc_int(_hc_regs,nyet); -+ if(!out_nak_enh) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _urbd->error_count ++ ; -+ if (_urbd->error_count == 3) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ enable_hc_int(_hc_regs,ack); -+ enable_hc_int(_hc_regs,nak); -+ enable_hc_int(_hc_regs,nyet); -+ _ifxhc->wait_for_sof =1; -+ if(!out_nak_enh) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ } -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 BABBLE [should be IN only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _ifxhc->do_ping = 0; -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.nak || hcint.b.nyet) -+ { -+ if(!out_nak_enh) -+ { -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ #endif -+ { -+ if(!out_nak_enh) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ if(_ifxhc->xfer_len!=0) -+ { -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ } -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ } -+ else if(hcint.b.datatglerr ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 DATATGLERR [should be IN only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 FRMOVRUN [should be PERIODIC only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->do_ping =0; -+ -+ if(_ifxhc->halt_status == HC_XFER_NAK) -+ { -+ if(_ifxhc->nak_retry_r) -+ { -+ _ifxhc->nak_retry--; -+ if(_ifxhc->nak_retry) -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status); -+ } -+ } -+ else -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ -+ if(hcint.b.xfercomp ) -+ { -+ _urbd->error_count =0; -+ //restart INTR immediately -+ #if 1 -+ if(hctsiz.b.pktcnt>0) -+ { -+ // TODO Re-initialize Channel (in next b_interval - 1 uF/F) -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ #endif -+ { -+ _ifxhc->wait_for_sof =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if (hcint.b.stall) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ -+ // Don't care shortcut -+ #if 0 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ { -+ // Stall FIFO compensation. -+ #if 0 -+ int sz1,sz2; -+ sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt; -+ sz2*=_ifxhc->mps; -+ sz1=_ifxhc->xfer_len - hctsiz.b.xfersize; -+ sz2-=sz1; -+ if(sz2) -+ ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf); -+ #endif -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ } -+ return 1; -+ } -+ -+ -+ else if (hcint.b.bblerr) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ -+ // Don't care shortcut -+ #if 0 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ { -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ } -+ return 1; -+ } -+ else if (hcint.b.nak || hcint.b.datatglerr || hcint.b.frmovrun) -+ { -+ _urbd->error_count =0; -+ //restart INTR immediately -+ #if 1 -+ if(hctsiz.b.pktcnt>0) -+ { -+ // TODO Re-initialize Channel (in next b_interval - 1 uF/F) -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ #endif -+ { -+ _ifxhc->wait_for_sof =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if (hcint.b.xacterr) -+ { -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ #endif -+ { -+ /* 20110803 AVM/WK FIX: Reset error count on any handshake */ -+ if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) { -+ _urbd->error_count = 1; -+ } else { -+ _urbd->error_count++; -+ } -+ -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ return 1; -+ } -+ else if(hcint.b.nyet ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT0 NYET [should be OUT only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ if(_ifxhc->halt_status == HC_XFER_NAK) -+ { -+ if(_ifxhc->nak_retry_r) -+ { -+ _ifxhc->nak_retry--; -+ if(_ifxhc->nak_retry) -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status); -+ } -+ } -+ else -+ { -+ if(_ifxhc->xfer_len!=0) -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ -+ if(hcint.b.xfercomp ) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count =0; -+ //restart INTR immediately -+ #if 0 -+ if(hctsiz.b.pktcnt>0) -+ { -+ // TODO Re-initialize Channel (in next b_interval - 1 uF/F) -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ if(hcint.b.nyet && !out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ #endif -+ { -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if (hcint.b.stall) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nyet); -+ disable_hc_int(_hc_regs,nak); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ -+ // Don't care shortcut -+ #if 0 -+ if(hctsiz.b.pktcnt==0) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ #endif -+ { -+ if(_ifxhc->xfer_len!=0)// !_ifxhc->is_in -+ _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ } -+ return 1; -+ } -+ else if(hcint.b.nak || hcint.b.frmovrun ) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nyet); -+ disable_hc_int(_hc_regs,nak); -+ _urbd->error_count =0; -+ //restart INTR immediately -+ #if 0 -+ if(hctsiz.b.pktcnt>0) -+ { -+ // TODO Re-initialize Channel (in next b_interval - 1 uF/F) -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ #endif -+ { -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ // ZLP shortcut -+ #if 1 -+ if(hctsiz.b.pktcnt==0) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ #endif -+ { -+ /* 20110803 AVM/WK FIX: Reset error count on any handshake */ -+ if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) { -+ _urbd->error_count = 1; -+ } else { -+ _urbd->error_count++; -+ } -+ -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ //_ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ //if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _ifxhc->wait_for_sof=1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+IFX_WARN("%s() %d Warning INTR OUT SPLIT0 BABBLEERR [should be IN only]\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+IFX_WARN("%s() %d Warning INTR OUT SPLIT0 DATATGLERR\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ if (hcint.b.xfercomp || hcint.b.frmovrun) -+ { -+ _urbd->error_count=0; -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->wait_for_sof = 0; -+ if (hcint.b.xfercomp) -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ else -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ } -+ else if (hcint.b.xacterr || hcint.b.bblerr) -+ { -+ #ifndef VR9Skip -+ if(hctsiz.b.pktcnt==0) -+ { -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ { -+ int sz1,sz2; -+ sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt; -+ sz2*=_ifxhc->mps; -+ sz1=_ifxhc->xfer_len - hctsiz.b.xfersize; -+ sz2-=sz1; -+ if(sz2) -+ ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf); -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 1; -+ enable_hc_int(_hc_regs,ack); -+ enable_hc_int(_hc_regs,nak); -+ enable_hc_int(_hc_regs,nyet); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ #endif -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ warning -+ } -+ else if(hcint.b.stall ) -+ { -+ warning -+ } -+ #else -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ if (hcint.b.xfercomp) -+ { -+ _urbd->error_count=0; -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->wait_for_sof = 0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if (hcint.b.frmovrun) -+ { -+ #ifndef VR9Skip -+ _urbd->error_count=0; -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ #endif -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ warning -+ } -+ else if(hcint.b.bblerr ) -+ { -+ #ifndef VR9Skip -+ if(hctsiz.b.pktcnt==0) -+ { -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ else -+ { -+ int sz1,sz2; -+ sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt; -+ sz2*=_ifxhc->mps; -+ sz1=_ifxhc->xfer_len - hctsiz.b.xfersize; -+ sz2-=sz1; -+ if(sz2) -+ ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf); -+ _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 1; -+ enable_hc_int(_hc_regs,ack); -+ enable_hc_int(_hc_regs,nak); -+ enable_hc_int(_hc_regs,nyet); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ } -+ #endif -+ } -+ else if(hcint.b.xacterr ) -+ { -+ if(hctsiz.b.pktcnt==0) -+ { -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+ warning -+ } -+ #else -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_rx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+ _ifxhc->do_ping =0; -+ -+ if (hcint.b.ack) -+ { -+ _urbd->error_count=0; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof = 8; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if (hcint.b.nak) -+ { -+ _ifxhc->wait_for_sof = 1; -+ _urbd->error_count = 0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if (hcint.b.xacterr) -+ { -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof =1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_DATA_TOGGLE_ERR\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.nyet ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 NYET\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ } -+ else if(hcint.b.xfercomp ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 COMPLETE\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_tx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+#ifdef __DEBUG__ -+static int first=0; -+#endif -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+#ifdef __DEBUG__ -+ if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK -+ &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack) -+ { -+ showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ first=1; -+ printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n" -+ ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3) -+ ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7) -+ ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11) -+ ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15)); -+ -+ printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n" -+ ,_urbd->urb->actual_length -+ ,_ifxhc->start_pkt_count -+ ,hctsiz.b.pktcnt -+ ,_urbd->xfer_len); -+ } -+#endif -+ -+ if (hcint.b.ack ) -+ { -+ _urbd->error_count=0; -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP) -+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof =8; -+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 NYET\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count=0; -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP) -+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof =1; -+ _ifxhc->data_pid_start =read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _ifxhc->wait_for_sof =1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _urbd->error_count =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof =1; -+ _ifxhc->do_ping =1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ _ifxhc->do_ping =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.xfercomp ) -+ { -+ printk(KERN_INFO "%s() %d Warning CTRLBULK OUT SPLIT1 COMPLETE\n",__func__,__LINE__); -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_rx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+ _ifxhc->do_ping =0; -+ -+ if (hcint.b.ack ) -+ { -+ /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/ -+ _ifxhc->nyet_count=0; -+ -+ _urbd->error_count=0; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _urbd->error_count=0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar); -+ _urbd->error_count=hcchar.b.multicnt; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+IFX_WARN( "%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.xfercomp ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_tx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+ if (hcint.b.ack ) -+ { -+ /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/ -+ _ifxhc->nyet_count=0; -+ -+ _urbd->error_count=0; -+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+IFX_WARN("%s() %d Warning INTR OUT SPLIT1 NYET\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count=0; -+ _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len; -+ _ifxhc->split=2; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->data_pid_start = read_data_toggle(_hc_regs); -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _urbd->error_count =0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar); -+ _urbd->error_count=hcchar.b.multicnt; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ enable_hc_int(_hc_regs,ack); -+ enable_hc_int(_hc_regs,nak); -+ enable_hc_int(_hc_regs,nyet); -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT1 BABBLEERR\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT1 STALL\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof =0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ return 1; -+ } -+ else if(hcint.b.xfercomp ) -+ { -+IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__); -+showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_rx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ if (hcint.b.ack ) -+ { -+ Do Complete Split -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ Rewind Buffer Pointers -+ Retry Start Split (in next b_interval ¡V 1 uF) -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ warning -+ } -+ else if(hcint.b.bblerr ) -+ { -+ warning -+ } -+ else if(hcint.b.xacterr ) -+ { -+ warning -+ } -+ else if(hcint.b.stall ) -+ { -+ warning -+ } -+ else if(hcint.b.nak ) -+ { -+ warning -+ } -+ else if(hcint.b.xfercomp ) -+ { -+ warning -+ } -+ else if(hcint.b.nyet) -+ { -+ warning -+ } -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_tx_ssplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ if (hcint.b.ack ) -+ { -+ Do Next Start Split (in next b_interval ¡V 1 uF) -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ Do Next Transaction in next frame. -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ warning -+ } -+ else if(hcint.b.bblerr ) -+ { -+ warning -+ } -+ else if(hcint.b.xacterr ) -+ { -+ warning -+ } -+ else if(hcint.b.stall ) -+ { -+ warning -+ } -+ else if(hcint.b.nak ) -+ { -+ warning -+ } -+ else if(hcint.b.xfercomp ) -+ { -+ warning -+ } -+ else if(hcint.b.nyet) -+ { -+ warning -+ } -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_rx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+ _ifxhc->do_ping = 0; -+ -+ if (hcint.b.xfercomp) -+ { -+ _urbd->error_count =0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->split=1; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if (hcint.b.nak) -+ { -+ _urbd->error_count=0; -+ -+ _ifxhc->split = 1; -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+ _urbd->error_count=0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.stall || hcint.b.bblerr ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ if (hcint.b.stall) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ else if(hcint.b.bblerr ) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_ctrlbulk_tx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+#if 1 -+static int first=0; -+#endif -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+#if 1 -+ if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK -+ &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack) -+ { -+ showint( hcint.d32,hcintmsk.d32,hctsiz.d32); -+ first=1; -+ printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n" -+ ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3) -+ ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7) -+ ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11) -+ ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15)); -+ -+ printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n" -+ ,_urbd->urb->actual_length -+ ,_ifxhc->start_pkt_count -+ ,hctsiz.b.pktcnt -+ ,_urbd->xfer_len); -+ } -+#endif -+ -+ if(hcint.b.xfercomp ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->split=1; -+ _ifxhc->do_ping= 0; -+ #if 0 -+ if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet)) -+ { -+ // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr -+ // Solution: NoSplit: Resend at next SOF -+ // Split : Resend at next SOF with SSPLIT -+ _ifxhc->xfer_len = 0; -+ _ifxhc->xfer_count = 0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ else -+ #endif -+ { -+ _ifxhc->wait_for_sof = 0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ } -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _urbd->error_count=0; -+ -+ _ifxhc->split = 1; -+ _ifxhc->wait_for_sof = 1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+ //Retry Complete Split -+ // Issue Retry instantly on next SOF, without gothrough process_channels -+ _urbd->error_count=0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 1; -+ _ifxhc->do_ping = 0; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.stall ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ _urbd->error_count++; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = 1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = 1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.frmovrun ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_rx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _ifxhc->do_ping = 0; -+ -+ if (hcint.b.xfercomp ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->split=1; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->split = 1; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+ _urbd->error_count=0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 0; -+ -+ /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/ -+ _ifxhc->nyet_count++; -+ if(_ifxhc->nyet_count > 2) { -+ _ifxhc->split = 1; -+ _ifxhc->nyet_count = 0; -+ _ifxhc->wait_for_sof = 5; -+ } -+ -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.frmovrun || hcint.b.bblerr || hcint.b.stall ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ if (hcint.b.stall) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ else if(hcint.b.bblerr ) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ else if(hcint.b.frmovrun ) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar); -+ _urbd->error_count=hcchar.b.multicnt; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_intr_tx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ -+ if(hcint.b.xfercomp ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->split=1; -+ _ifxhc->do_ping = 0; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->split = 1; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.nyet) -+ { -+ _urbd->error_count=0; -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ -+ /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/ -+ _ifxhc->nyet_count++; -+ if(_ifxhc->nyet_count > 2) { -+ _ifxhc->split = 1; -+ _ifxhc->nyet_count = 0; -+ _ifxhc->wait_for_sof = 5; -+ } -+ -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.stall || hcint.b.frmovrun) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ if (hcint.b.stall) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ else if(hcint.b.frmovrun ) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN); -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar); -+ _urbd->error_count=hcchar.b.multicnt; -+ if(_urbd->error_count>=3) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR); -+ } -+ else -+ { -+ _ifxhc->split=1; -+ _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1; -+ if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ } -+ return 1; -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0) -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1; -+ else -+ _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0; -+ _ifxhc->split=1; -+ if(!out_nak_enh ) -+ _ifxhc->do_ping =1; -+ else -+ _ifxhc->do_ping =0; -+ _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length; -+ _ifxhc->xfer_count = _urbd->urb->actual_length; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.bblerr ) -+ { -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->do_ping = 0; -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR); -+ return 1; -+ } -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_rx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ if(hcint.b.xfercomp ) -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,nyet); -+ _urbd->error_count=0; -+ _ifxhc->wait_for_sof = 0; -+ _ifxhc->split=1; -+ complete_channel(_ifxhcd, _ifxhc, _urbd); -+ return 1; -+ } -+ else if(hcint.b.nak ) -+ { -+ Retry Start Split (in next b_interval ¡V 1 uF) -+ } -+ else if(hcint.b.nyet) -+ { -+ //Do Next Complete Split -+ // Issue Retry instantly on next SOF, without gothrough process_channels -+ _urbd->error_count=0; -+ //disable_hc_int(_hc_regs,ack); -+ //disable_hc_int(_hc_regs,nak); -+ //disable_hc_int(_hc_regs,datatglerr); -+ _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS; -+ _ifxhc->wait_for_sof = 1; -+ ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc); -+ return 1; -+ } -+ else if(hcint.b.frmovrun || hcint.b.stall || hcint.b.bblerr) -+ { -+ _urbd->error_count=0; -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nyet); -+ disable_hc_int(_hc_regs,nak); -+ _ifxhc->wait_for_sof = 0; -+ -+ //if(hctsiz.b.pktcnt==0) -+ //{ -+ // complete_channel(_ifxhcd, _ifxhc, _urbd); -+ // return 1; -+ //} -+ //else -+ // _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize); -+ if (hcint.b.stall) -+ release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL); -+ else if(hcint.b.frmovrun ) -+ else if(hcint.b.bblerr ) -+ return 1; -+ } -+ else if(hcint.b.xacterr ) -+ { -+ Rewind Buffer Pointers -+ if (HCCHARn.EC = = 3) // ERR response received -+ { -+ Record ERR error -+ Do Next Start Split (in next frame) -+ } -+ else -+ { -+ De-allocate Channel -+ } -+ } -+ else if(hcint.b.datatglerr ) -+ { -+ warning -+ } -+ else if(hcint.b.ack ) -+ { -+ warning -+ } -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+static int32_t chhltd_isoc_tx_csplit(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__) -+ hcint_data_t hcint; -+ hcint_data_t hcintmsk; -+ hctsiz_data_t hctsiz; -+ int out_nak_enh = 0; -+ -+ if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH) -+ out_nak_enh = 1; -+ -+ hcint.d32 = ifxusb_rreg(&_hc_regs->hcint); -+ hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ warning -+ #endif -+ return 0; -+} -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+static int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: Channel Halted--\n", _ifxhc->hc_num); -+ -+ _ifxhc->halting = 0; -+ _ifxhc->xfer_started = 0; -+ -+ if (_ifxhc->halt_status == HC_XFER_URB_DEQUEUE || -+ _ifxhc->halt_status == HC_XFER_AHB_ERR) { -+ /* -+ * Just release the channel. A dequeue can happen on a -+ * transfer timeout. In the case of an AHB Error, the channel -+ * was forced to halt because there's no way to gracefully -+ * recover. -+ */ -+ release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status); -+ return 1; -+ } -+ -+ if (_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL || _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK) -+ { -+ if (_ifxhc->split==0) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_ctrlbulk_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_ctrlbulk_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==1) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_ctrlbulk_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_ctrlbulk_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==2) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_ctrlbulk_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_ctrlbulk_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ } -+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR) -+ { -+ if (_ifxhc->split==0) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_intr_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_intr_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==1) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_intr_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_intr_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==2) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_intr_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_intr_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ } -+ else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ if (_ifxhc->split==0) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_isoc_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_isoc_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==1) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_isoc_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_isoc_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ else if(_ifxhc->split==2) -+ { -+ if(_ifxhc->is_in) -+ return (chhltd_isoc_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ else -+ return (chhltd_isoc_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd)); -+ } -+ } -+ return 0; -+} -+ -+/* -+ * Handles a host channel AHB error interrupt. This handler is only called in -+ * DMA mode. -+ */ -+static void hc_other_intr_dump(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ #ifdef __DEBUG__ -+ hcchar_data_t hcchar; -+ hcsplt_data_t hcsplt; -+ hctsiz_data_t hctsiz; -+ uint32_t hcdma; -+ struct urb *urb = _urbd->urb; -+ hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar); -+ hcsplt.d32 = ifxusb_rreg(&_hc_regs->hcsplt); -+ hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz); -+ hcdma = ifxusb_rreg(&_hc_regs->hcdma); -+ -+ IFX_ERROR("Channel %d\n", _ifxhc->hc_num); -+ IFX_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32); -+ IFX_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma); -+ IFX_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe)); -+ IFX_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe), -+ (usb_pipein(urb->pipe) ? "IN" : "OUT")); -+ IFX_ERROR(" Endpoint type: %s\n", -+ ({char *pipetype; -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: pipetype = "CTRL"; break; -+ case PIPE_BULK: pipetype = "BULK"; break; -+ case PIPE_INTERRUPT: pipetype = "INTR"; break; -+ case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break; -+ default: pipetype = "????"; break; -+ }; pipetype;})); -+ IFX_ERROR(" Speed: %s\n", -+ ({char *speed; -+ switch (urb->dev->speed) { -+ case USB_SPEED_HIGH: speed = "HS"; break; -+ case USB_SPEED_FULL: speed = "FS"; break; -+ case USB_SPEED_LOW: speed = "LS"; break; -+ default: speed = "????"; break; -+ }; speed;})); -+ IFX_ERROR(" Max packet size: %d\n", -+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); -+ IFX_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length); -+ IFX_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n", -+ urb->transfer_buffer, (void *)urb->transfer_dma); -+ IFX_ERROR(" Setup buffer: %p, Setup DMA: %p\n", -+ urb->setup_packet, (void *)urb->setup_dma); -+ IFX_ERROR(" Interval: %d\n", urb->interval); -+ #endif //__DEBUG__ -+} -+ -+/* -+ * Handles a host channel ACK interrupt. This interrupt is enabled when -+ * errors occur, and during Start Split transactions. -+ */ -+static int32_t handle_hc_ack_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ _urbd->error_count=0; -+ if(_ifxhc->nak_countdown_r) -+ { -+ _ifxhc->nak_retry=_ifxhc->nak_retry_r; -+ _ifxhc->nak_countdown=_ifxhc->nak_countdown_r; -+ } -+ else -+ disable_hc_int(_hc_regs,nak); -+ disable_hc_int(_hc_regs,ack); -+ return 1; -+} -+ -+/* -+ * Handles a host channel ACK interrupt. This interrupt is enabled when -+ * errors occur, and during Start Split transactions. -+ */ -+static int32_t handle_hc_nak_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ -+ _urbd->error_count=0; -+ -+ if(_ifxhc->nak_countdown_r) -+ { -+ _ifxhc->nak_countdown--; -+ if(!_ifxhc->nak_countdown) -+ { -+ _ifxhc->nak_countdown=_ifxhc->nak_countdown_r; -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_NAK); -+ } -+ else -+ enable_hc_int(_hc_regs,ack); -+ } -+ else -+ { -+ disable_hc_int(_hc_regs,ack); -+ disable_hc_int(_hc_regs,nak); -+ } -+ return 1; -+} -+ -+/* -+ * Handles a host channel AHB error interrupt. This handler is only called in -+ * DMA mode. -+ */ -+static int32_t handle_hc_ahberr_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "AHB Error--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ -+ ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_AHB_ERR); -+ return 1; -+} -+ -+/* -+ * Datatoggle -+ */ -+static int32_t handle_hc_datatglerr_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "DATATOGGLE Error--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,datatglerr); -+ return 1; -+} -+ -+ -+ -+/* -+ * Interrupts which should not been triggered -+ */ -+static int32_t handle_hc_frmovrun_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "FrameOverRun Error--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,frmovrun); -+ return 1; -+} -+ -+static int32_t handle_hc_bblerr_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "BBL Error--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,bblerr); -+ return 1; -+} -+ -+static int32_t handle_hc_xacterr_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "XACT Error--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,xacterr); -+ return 1; -+} -+ -+static int32_t handle_hc_nyet_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "NYET--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ _urbd->error_count=0; -+ disable_hc_int(_hc_regs,nyet); -+ return 1; -+} -+ -+static int32_t handle_hc_stall_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "STALL--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,stall); -+ return 1; -+} -+ -+static int32_t handle_hc_xfercomp_intr(ifxhcd_hcd_t *_ifxhcd, -+ ifxhcd_hc_t *_ifxhc, -+ ifxusb_hc_regs_t *_hc_regs, -+ ifxhcd_urbd_t *_urbd) -+{ -+ IFX_ERROR( "--Host Channel %d Interrupt: " -+ "XFERCOMP--\n", _ifxhc->hc_num); -+ hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd); -+ disable_hc_int(_hc_regs,xfercomp); -+ return 1; -+} -+ -+ -+ -+/* This interrupt indicates that the specified host channels has a pending -+ * interrupt. There are multiple conditions that can cause each host channel -+ * interrupt. This function determines which conditions have occurred for this -+ * host channel interrupt and handles them appropriately. */ -+static int32_t handle_hc_n_intr (ifxhcd_hcd_t *_ifxhcd, uint32_t _num) -+{ -+ uint32_t hcintval,hcintmsk; -+ hcint_data_t hcint; -+ ifxhcd_hc_t *ifxhc; -+ ifxusb_hc_regs_t *hc_regs; -+ ifxhcd_urbd_t *urbd; -+ unsigned long flags; -+ -+ int retval = 0; -+ -+ IFX_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num); -+ -+ /*== AVM/BC 20101111 Lock needed ==*/ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ ifxhc = &_ifxhcd->ifxhc[_num]; -+ hc_regs = _ifxhcd->core_if.hc_regs[_num]; -+ -+ hcintval = ifxusb_rreg(&hc_regs->hcint); -+ hcintmsk = ifxusb_rreg(&hc_regs->hcintmsk); -+ hcint.d32 = hcintval & hcintmsk; -+ IFX_DEBUGPL(DBG_HCDV, " 0x%08x & 0x%08x = 0x%08x\n", -+ hcintval, hcintmsk, hcint.d32); -+ -+ urbd = list_entry(ifxhc->epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry); -+ -+ if (hcint.b.datatglerr) -+ retval |= handle_hc_datatglerr_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.frmovrun) -+ retval |= handle_hc_frmovrun_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.bblerr) -+ retval |= handle_hc_bblerr_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.xacterr) -+ retval |= handle_hc_xacterr_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.nyet) -+ retval |= handle_hc_nyet_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.ack) -+ retval |= handle_hc_ack_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.nak) -+ retval |= handle_hc_nak_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.stall) -+ retval |= handle_hc_stall_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ if (hcint.b.ahberr) { -+ clear_hc_int(hc_regs, ahberr); -+ retval |= handle_hc_ahberr_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ } -+ if (hcint.b.chhltd) { -+ /* == 20110901 AVM/WK Fix: Flag must not be cleared after restart of channel ==*/ -+ clear_hc_int(hc_regs, chhltd); -+ retval |= handle_hc_chhltd_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ } -+ if (hcint.b.xfercomp) -+ retval |= handle_hc_xfercomp_intr(_ifxhcd, ifxhc, hc_regs, urbd); -+ -+ /* == 20110901 AVM/WK Fix: Never clear possibly new intvals ==*/ -+ //ifxusb_wreg(&hc_regs->hcint,hcintval); -+ -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ -+ return retval; -+} -+ -+ -+ -+ -+ -+ -+static uint8_t update_interval_counter(ifxhcd_epqh_t *_epqh,uint32_t _diff) -+{ -+ if(_diff>=_epqh->period_counter) -+ { -+ _epqh->period_do=1; -+ if(_diff>_epqh->interval) -+ _epqh->period_counter=1; -+ else -+ _epqh->period_counter=_epqh->period_counter+_epqh->interval-_diff; -+ return 1; -+ } -+ _epqh->period_counter=_epqh->period_counter-_diff; -+ return 0; -+} -+ -+ -+ -+ -+/* -+ * Handles the start-of-frame interrupt in host mode. Non-periodic -+ * transactions may be queued to the DWC_otg controller for the current -+ * (micro)frame. Periodic transactions may be queued to the controller for the -+ * next (micro)frame. -+ */ -+static int32_t handle_sof_intr (ifxhcd_hcd_t *_ifxhcd) -+{ -+ #ifdef __DYN_SOF_INTR__ -+ uint8_t with_count_down=0; -+ #endif -+ uint8_t active_on=0; -+ uint8_t ready_on=0; -+ struct list_head *epqh_entry; -+ ifxhcd_epqh_t *epqh; -+ hfnum_data_t hfnum; -+ uint32_t fndiff; -+ -+ unsigned long flags; -+#ifdef __USE_TIMER_4_SOF__ -+ uint32_t wait_for_sof = 0x10000; -+#endif -+ -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+ { -+ int num_channels; -+ ifxusb_hc_regs_t *hc_regs; -+ int i; -+ num_channels = _ifxhcd->core_if.params.host_channels; -+ -+// AVM/WK moved block here due to use of SOF timer -+ hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum); -+ fndiff = hfnum.b.frnum; -+ fndiff+= 0x00004000; -+ fndiff-= _ifxhcd->lastframe ; -+ fndiff&= 0x00003FFF; -+ if(!fndiff) fndiff =1; -+ -+ for (i = 0; i < num_channels; i++) -+ { -+ if(_ifxhcd->ifxhc[i].wait_for_sof && _ifxhcd->ifxhc[i].xfer_started) -+ { -+#ifdef __USE_TIMER_4_SOF__ -+ if (_ifxhcd->ifxhc[i].wait_for_sof > fndiff) { -+ _ifxhcd->ifxhc[i].wait_for_sof -= fndiff; -+ } else { -+ _ifxhcd->ifxhc[i].wait_for_sof = 0; -+ } -+#else -+ _ifxhcd->ifxhc[i].wait_for_sof--; -+#endif -+ if(_ifxhcd->ifxhc[i].wait_for_sof==0) -+ { -+ hcint_data_t hcint= { .d32=0 }; -+ hc_regs = _ifxhcd->core_if.hc_regs[i]; -+ -+ hcint.d32 =0xFFFFFFFF; -+ ifxusb_wreg(&hc_regs->hcint, hcint.d32); -+ -+ hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk); -+ hcint.b.nak =0; -+ hcint.b.ack =0; -+ /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/ -+ hcint.b.nyet=0; -+ _ifxhcd->ifxhc[i].nak_countdown=_ifxhcd->ifxhc[i].nak_countdown_r; -+ if(_ifxhcd->ifxhc[i].nak_countdown_r) -+ hcint.b.nak =1; -+ ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32); -+ -+ /* AVM WK / BC 20100827 -+ * FIX: Packet was ignored because of wrong Oddframe bit -+ */ -+ if (_ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_INTR || _ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = _ifxhcd->ifxhc[i].hcchar; -+ hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum); -+ /* 1 if _next_ frame is odd, 0 if it's even */ -+ hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1; -+ _ifxhcd->ifxhc[i].hcchar = hcchar.d32; -+ } -+ -+ ifxusb_wreg(&hc_regs->hcchar, _ifxhcd->ifxhc[i].hcchar); -+ -+ } -+ } -+ else -+ _ifxhcd->ifxhc[i].wait_for_sof=0; -+ -+#ifdef __USE_TIMER_4_SOF__ -+ if (_ifxhcd->ifxhc[i].wait_for_sof && (wait_for_sof > _ifxhcd->ifxhc[i].wait_for_sof)) { -+ wait_for_sof = _ifxhcd->ifxhc[i].wait_for_sof; -+ } -+#endif -+ } -+ } -+ -+ // ISOC Active -+ #ifdef __EN_ISOC__ -+ #error ISOC not supported: missing SOF code -+ epqh_entry = _ifxhcd->epqh_isoc_active.next; -+ while (epqh_entry != &_ifxhcd->epqh_isoc_active) -+ { -+ epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_entry = epqh_entry->next; -+ #ifdef __DYN_SOF_INTR__ -+ with_count_down=1; -+ #endif -+ active_on+=update_interval_counter(epqh,fndiff); -+ } -+ -+ // ISOC Ready -+ epqh_entry = _ifxhcd->epqh_isoc_ready.next; -+ while (epqh_entry != &_ifxhcd->epqh_isoc_ready) -+ { -+ epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_entry = epqh_entry->next; -+ #ifdef __DYN_SOF_INTR__ -+ with_count_down=1; -+ #endif -+ ready_on+=update_interval_counter(epqh,fndiff); -+ } -+ #endif -+ -+ // INTR Active -+ epqh_entry = _ifxhcd->epqh_intr_active.next; -+ while (epqh_entry != &_ifxhcd->epqh_intr_active) -+ { -+ epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_entry = epqh_entry->next; -+ #ifdef __DYN_SOF_INTR__ -+ with_count_down=1; -+ #endif -+#ifdef __USE_TIMER_4_SOF__ -+ if (update_interval_counter(epqh,fndiff)) { -+ active_on ++; -+ wait_for_sof = 1; -+ } else { -+ if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) { -+ wait_for_sof = epqh->period_counter; -+ } -+ } -+#else -+ active_on+=update_interval_counter(epqh,fndiff); -+#endif -+ } -+ -+ // INTR Ready -+ epqh_entry = _ifxhcd->epqh_intr_ready.next; -+ while (epqh_entry != &_ifxhcd->epqh_intr_ready) -+ { -+ epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_entry = epqh_entry->next; -+ #ifdef __DYN_SOF_INTR__ -+ with_count_down=1; -+ #endif -+#ifdef __USE_TIMER_4_SOF__ -+ if (update_interval_counter(epqh,fndiff)) { -+ ready_on ++; -+ wait_for_sof = 1; -+ } else { -+ if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) { -+ wait_for_sof = epqh->period_counter; -+ } -+ } -+#else -+ ready_on+=update_interval_counter(epqh,fndiff); -+#endif -+ } -+ -+ // Stdby -+ epqh_entry = _ifxhcd->epqh_stdby.next; -+ while (epqh_entry != &_ifxhcd->epqh_stdby) -+ { -+ epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry); -+ epqh_entry = epqh_entry->next; -+ if(epqh->period_counter > 0 ) { -+#ifdef __USE_TIMER_4_SOF__ -+ if (epqh->period_counter > fndiff) { -+ epqh->period_counter -= fndiff; -+ } else { -+ epqh->period_counter = 0; -+ } -+#else -+ epqh->period_counter --; -+#endif -+ #ifdef __DYN_SOF_INTR__ -+ with_count_down=1; -+ #endif -+ } -+ if(epqh->period_counter == 0) { -+ ifxhcd_epqh_idle_periodic(epqh); -+ } -+#ifdef __USE_TIMER_4_SOF__ -+ else { -+ if (wait_for_sof > epqh->period_counter) { -+ wait_for_sof = epqh->period_counter; -+ } -+ } -+#endif -+ } -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ -+ if(ready_on) -+ select_eps(_ifxhcd); -+ else if(active_on) -+ process_channels(_ifxhcd); -+ -+ /* Clear interrupt */ -+ { -+ gint_data_t gintsts; -+ gintsts.d32=0; -+ gintsts.b.sofintr = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ -+ #ifdef __DYN_SOF_INTR__ -+ if(!with_count_down) -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0); -+ #endif -+#ifdef __USE_TIMER_4_SOF__ -+ wait_for_sof &= 0xFFFF; // reduce to 16 Bits. -+ -+ if(wait_for_sof == 1) { -+ // enable SOF -+ gint_data_t gintsts; -+ gintsts.d32=0; -+ gintsts.b.sofintr = 1; -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32); -+ } else { -+ // disable SOF -+ ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0); -+ if (wait_for_sof > 1) { -+ // use timer, not SOF IRQ -+ hprt0_data_t hprt0; -+ ktime_t ktime; -+ hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if); -+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED) { -+ ktime = ktime_set(0, wait_for_sof * 125 * 1000); /*--- wakeup in n*125usec ---*/ -+ } else { -+ ktime = ktime_set(0, wait_for_sof * (1000*1000)); /*--- wakeup in n*1000usec ---*/ -+ } -+ hrtimer_start(&_ifxhcd->hr_timer, ktime, HRTIMER_MODE_REL); -+ } -+ } -+#endif -+ } -+ _ifxhcd->lastframe=hfnum.b.frnum; -+ return 1; -+} -+ -+ -+ -+/* There are multiple conditions that can cause a port interrupt. This function -+ * determines which interrupt conditions have occurred and handles them -+ * appropriately. */ -+static int32_t handle_port_intr (ifxhcd_hcd_t *_ifxhcd) -+{ -+ int retval = 0; -+ hprt0_data_t hprt0; -+ hprt0_data_t hprt0_modify; -+ -+ hprt0.d32 = -+ hprt0_modify.d32 = ifxusb_rreg(_ifxhcd->core_if.hprt0); -+ -+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in -+ * GINTSTS */ -+ -+ hprt0_modify.b.prtena = 0; -+ hprt0_modify.b.prtconndet = 0; -+ hprt0_modify.b.prtenchng = 0; -+ hprt0_modify.b.prtovrcurrchng = 0; -+ -+ /* Port Connect Detected -+ * Set flag and clear if detected */ -+ if (hprt0.b.prtconndet) { -+ IFX_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x " -+ "Port Connect Detected--\n", hprt0.d32); -+ _ifxhcd->flags.b.port_connect_status_change = 1; -+ _ifxhcd->flags.b.port_connect_status = 1; -+ hprt0_modify.b.prtconndet = 1; -+ -+ /* The Hub driver asserts a reset when it sees port connect -+ * status change flag */ -+ retval |= 1; -+ } -+ -+ /* Port Enable Changed -+ * Clear if detected - Set internal flag if disabled */ -+ if (hprt0.b.prtenchng) { -+ -+ IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " -+ "Port Enable Changed--\n", hprt0.d32); -+ hprt0_modify.b.prtenchng = 1; -+ if (hprt0.b.prtena == 1) -+ /* Port has been enabled set the reset change flag */ -+ _ifxhcd->flags.b.port_reset_change = 1; -+ else -+ _ifxhcd->flags.b.port_enable_change = 1; -+ retval |= 1; -+ } -+ -+ /* Overcurrent Change Interrupt */ -+ -+ if (hprt0.b.prtovrcurrchng) { -+ IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " -+ "Port Overcurrent Changed--\n", hprt0.d32); -+ _ifxhcd->flags.b.port_over_current_change = 1; -+ hprt0_modify.b.prtovrcurrchng = 1; -+ retval |= 1; -+ } -+ -+ /* Clear Port Interrupts */ -+ ifxusb_wreg(_ifxhcd->core_if.hprt0, hprt0_modify.d32); -+ return retval; -+} -+ -+/* -+ * This interrupt indicates that SUSPEND state has been detected on -+ * the USB. -+ * No Functioning in Host Mode -+ */ -+static int32_t handle_usb_suspend_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ gint_data_t gintsts; -+ IFX_DEBUGP("USB SUSPEND RECEIVED!\n"); -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.usbsuspend = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/* -+ * This interrupt indicates that the IFXUSB controller has detected a -+ * resume or remote wakeup sequence. If the IFXUSB controller is in -+ * low power mode, the handler must brings the controller out of low -+ * power mode. The controller automatically begins resume -+ * signaling. The handler schedules a time to stop resume signaling. -+ */ -+static int32_t handle_wakeup_detected_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ gint_data_t gintsts; -+ hprt0_data_t hprt0 = {.d32=0}; -+ pcgcctl_data_t pcgcctl = {.d32=0}; -+ ifxusb_core_if_t *core_if = &_ifxhcd->core_if; -+ -+ IFX_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n"); -+ -+ /* -+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms -+ * so that OPT tests pass with all PHYs). -+ */ -+ /* Restart the Phy Clock */ -+ pcgcctl.b.stoppclk = 1; -+ ifxusb_mreg(core_if->pcgcctl, pcgcctl.d32, 0); -+ UDELAY(10); -+ -+ /* Now wait for 70 ms. */ -+ hprt0.d32 = ifxusb_read_hprt0( core_if ); -+ IFX_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32); -+ MDELAY(70); -+ hprt0.b.prtres = 0; /* Resume */ -+ ifxusb_wreg(core_if->hprt0, hprt0.d32); -+ IFX_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", ifxusb_rreg(core_if->hprt0)); -+ -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.wkupintr = 1; -+ ifxusb_wreg(&core_if->core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/* -+ * This interrupt indicates that a device is initiating the Session -+ * Request Protocol to request the host to turn on bus power so a new -+ * session can begin. The handler responds by turning on bus power. If -+ * the DWC_otg controller is in low power mode, the handler brings the -+ * controller out of low power mode before turning on bus power. -+ */ -+static int32_t handle_session_req_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ /* Clear interrupt */ -+ gint_data_t gintsts = { .d32 = 0 }; -+ gintsts.b.sessreqintr = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/* -+ * This interrupt indicates that a device has been disconnected from -+ * the root port. -+ */ -+static int32_t handle_disconnect_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ gint_data_t gintsts; -+ -+ ifxhcd_disconnect(_ifxhcd); -+ -+ gintsts.d32 = 0; -+ gintsts.b.disconnect = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/* -+ * This function handles the Connector ID Status Change Interrupt. It -+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this -+ * is a Device to Host Mode transition or a Host Mode to Device -+ * Transition. -+ * This only occurs when the cable is connected/removed from the PHY -+ * connector. -+ */ -+static int32_t handle_conn_id_status_change_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ gint_data_t gintsts; -+ -+ IFX_WARN("ID Status Change Interrupt: currently in %s mode\n", -+ ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device"); -+ -+ gintsts.d32 = 0; -+ gintsts.b.conidstschng = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+static int32_t handle_otg_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ ifxusb_core_global_regs_t *global_regs = _ifxhcd->core_if.core_global_regs; -+ gotgint_data_t gotgint; -+ gotgint.d32 = ifxusb_rreg( &global_regs->gotgint); -+ /* Clear GOTGINT */ -+ ifxusb_wreg (&global_regs->gotgint, gotgint.d32); -+ return 1; -+} -+ -+/** This function will log a debug message */ -+static int32_t handle_mode_mismatch_intr(ifxhcd_hcd_t *_ifxhcd) -+{ -+ gint_data_t gintsts; -+ -+ IFX_WARN("Mode Mismatch Interrupt: currently in %s mode\n", -+ ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device"); -+ gintsts.d32 = 0; -+ gintsts.b.modemismatch = 1; -+ ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/** This function handles interrupts for the HCD. */ -+int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd) -+{ -+ int retval = 0; -+ -+ ifxusb_core_if_t *core_if = &_ifxhcd->core_if; -+ /* AVM/BC 20101111 Unnecesary variable removed*/ -+ //gint_data_t gintsts,gintsts2; -+ gint_data_t gintsts; -+ -+ /* Check if HOST Mode */ -+ if (ifxusb_is_device_mode(core_if)) -+ { -+ IFX_ERROR("%s() CRITICAL! IN DEVICE MODE\n", __func__); -+ return 0; -+ } -+ -+ gintsts.d32 = ifxusb_read_core_intr(core_if); -+ -+ if (!gintsts.d32) -+ return 0; -+ -+ //Common INT -+ if (gintsts.b.modemismatch) -+ { -+ retval |= handle_mode_mismatch_intr(_ifxhcd); -+ gintsts.b.modemismatch=0; -+ } -+ if (gintsts.b.otgintr) -+ { -+ retval |= handle_otg_intr(_ifxhcd); -+ gintsts.b.otgintr=0; -+ } -+ if (gintsts.b.conidstschng) -+ { -+ retval |= handle_conn_id_status_change_intr(_ifxhcd); -+ gintsts.b.conidstschng=0; -+ } -+ if (gintsts.b.disconnect) -+ { -+ retval |= handle_disconnect_intr(_ifxhcd); -+ gintsts.b.disconnect=0; -+ } -+ if (gintsts.b.sessreqintr) -+ { -+ retval |= handle_session_req_intr(_ifxhcd); -+ gintsts.b.sessreqintr=0; -+ } -+ if (gintsts.b.wkupintr) -+ { -+ retval |= handle_wakeup_detected_intr(_ifxhcd); -+ gintsts.b.wkupintr=0; -+ } -+ if (gintsts.b.usbsuspend) -+ { -+ retval |= handle_usb_suspend_intr(_ifxhcd); -+ gintsts.b.usbsuspend=0; -+ } -+ -+ //Host Int -+ if (gintsts.b.sofintr) -+ { -+ retval |= handle_sof_intr (_ifxhcd); -+ gintsts.b.sofintr=0; -+ } -+ if (gintsts.b.portintr) -+ { -+ retval |= handle_port_intr (_ifxhcd); -+ gintsts.b.portintr=0; -+ } -+ if (gintsts.b.hcintr) -+ { -+ int i; -+ haint_data_t haint; -+ haint.d32 = ifxusb_read_host_all_channels_intr(core_if); -+ for (i=0; i< core_if->params.host_channels; i++) -+ if (haint.b2.chint & (1 << i)) -+ retval |= handle_hc_n_intr (_ifxhcd, i); -+ gintsts.b.hcintr=0; -+ } -+ return retval; -+} ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxhcd_queue.c -@@ -0,0 +1,418 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxhcd_queue.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the functions to manage Queue Heads and Queue -+ ** Transfer Descriptors. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxhcd_queue.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the functions to manage Queue Heads and Queue -+ Transfer Descriptors. -+*/ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/errno.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/string.h> -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+#include "ifxhcd.h" -+ -+#ifdef __EPQD_DESTROY_TIMEOUT__ -+ #define epqh_self_destroy_timeout 5 -+ static void eqph_destroy_func(unsigned long _ptr) -+ { -+ ifxhcd_epqh_t *epqh=(ifxhcd_epqh_t *)_ptr; -+ if(epqh) -+ { -+ ifxhcd_epqh_free (epqh); -+ } -+ } -+#endif -+ -+#define SCHEDULE_SLOP 10 -+ -+/*! -+ \brief This function allocates and initializes a EPQH. -+ -+ \param _ifxhcd The HCD state structure for the USB Host controller. -+ \param[in] _urb Holds the information about the device/endpoint that we need -+ to initialize the EPQH. -+ -+ \return Returns pointer to the newly allocated EPQH, or NULL on error. -+ */ -+ifxhcd_epqh_t *ifxhcd_epqh_create (ifxhcd_hcd_t *_ifxhcd, struct urb *_urb) -+{ -+ ifxhcd_epqh_t *epqh; -+ -+ hprt0_data_t hprt0; -+ struct usb_host_endpoint *sysep = ifxhcd_urb_to_endpoint(_urb); -+ -+ /* Allocate memory */ -+// epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_KERNEL); -+ epqh=(ifxhcd_epqh_t *) kmalloc (sizeof(ifxhcd_epqh_t), GFP_ATOMIC); -+ -+ if(epqh == NULL) -+ return NULL; -+ -+ memset (epqh, 0, sizeof (ifxhcd_epqh_t)); -+ -+ epqh->sysep=sysep; -+ -+ /* Initialize EPQH */ -+ switch (usb_pipetype(_urb->pipe)) -+ { -+ case PIPE_CONTROL : epqh->ep_type = IFXUSB_EP_TYPE_CTRL; break; -+ case PIPE_BULK : epqh->ep_type = IFXUSB_EP_TYPE_BULK; break; -+ case PIPE_ISOCHRONOUS: epqh->ep_type = IFXUSB_EP_TYPE_ISOC; break; -+ case PIPE_INTERRUPT : epqh->ep_type = IFXUSB_EP_TYPE_INTR; break; -+ } -+ -+ //epqh->data_toggle = IFXUSB_HC_PID_DATA0; -+ -+ epqh->mps = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe))); -+ -+ hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if); -+ -+ INIT_LIST_HEAD(&epqh->urbd_list); -+ INIT_LIST_HEAD(&epqh->epqh_list_entry); -+ epqh->hc = NULL; -+ -+ epqh->dump_buf = ifxusb_alloc_buf(epqh->mps, 0); -+ -+ /* FS/LS Enpoint on HS Hub -+ * NOT virtual root hub */ -+ epqh->need_split = 0; -+ epqh->pkt_count_limit=0; -+ if(epqh->ep_type == IFXUSB_EP_TYPE_BULK && !(usb_pipein(_urb->pipe)) ) -+ epqh->pkt_count_limit=4; -+ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED && -+ ((_urb->dev->speed == USB_SPEED_LOW) || -+ (_urb->dev->speed == USB_SPEED_FULL)) && -+ (_urb->dev->tt) && (_urb->dev->tt->hub->devnum != 1)) -+ { -+ IFX_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n", -+ usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum, -+ _urb->dev->ttport); -+ epqh->need_split = 1; -+ epqh->pkt_count_limit=1; -+ } -+ -+ if (epqh->ep_type == IFXUSB_EP_TYPE_INTR || -+ epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ { -+ /* Compute scheduling parameters once and save them. */ -+ epqh->interval = _urb->interval; -+ if(epqh->need_split) -+ epqh->interval *= 8; -+ } -+ -+ epqh->period_counter=0; -+ epqh->is_active=0; -+ -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ /* Start a timer for this transfer. */ -+ init_timer(&epqh->destroy_timer); -+ epqh->destroy_timer.function = eqph_destroy_func; -+ epqh->destroy_timer.data = (unsigned long)(epqh); -+ #endif -+ -+ #ifdef __DEBUG__ -+ IFX_DEBUGPL(DBG_HCD , "IFXUSB HCD EPQH Initialized\n"); -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - epqh = %p\n", epqh); -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Device Address = %d EP %d, %s\n", -+ _urb->dev->devnum, -+ usb_pipeendpoint(_urb->pipe), -+ usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT"); -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Speed = %s\n", -+ ({ char *speed; switch (_urb->dev->speed) { -+ case USB_SPEED_LOW: speed = "low" ; break; -+ case USB_SPEED_FULL: speed = "full"; break; -+ case USB_SPEED_HIGH: speed = "high"; break; -+ default: speed = "?"; break; -+ }; speed;})); -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - Type = %s\n", -+ ({ -+ char *type; switch (epqh->ep_type) -+ { -+ case IFXUSB_EP_TYPE_ISOC: type = "isochronous"; break; -+ case IFXUSB_EP_TYPE_INTR: type = "interrupt" ; break; -+ case IFXUSB_EP_TYPE_CTRL: type = "control" ; break; -+ case IFXUSB_EP_TYPE_BULK: type = "bulk" ; break; -+ default: type = "?"; break; -+ }; -+ type; -+ })); -+ if (epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ IFX_DEBUGPL(DBG_HCDV, "IFXUSB HCD EPQH - interval = %d\n", epqh->interval); -+ #endif -+ -+ return epqh; -+} -+ -+ -+ -+ -+ -+ -+/*! -+ \brief Free the EPQH. EPQH should already be removed from a list. -+ URBD list should already be empty if called from URB Dequeue. -+ -+ \param[in] _epqh The EPQH to free. -+ */ -+void ifxhcd_epqh_free (ifxhcd_epqh_t *_epqh) -+{ -+ unsigned long flags; -+ -+ if(_epqh->sysep) _epqh->sysep->hcpriv=NULL; -+ _epqh->sysep=NULL; -+ -+ if(!_epqh) -+ return; -+ -+ /* Free each QTD in the QTD list */ -+ local_irq_save (flags); -+ if (!list_empty(&_epqh->urbd_list)) -+ IFX_WARN("%s() invalid epqh state\n",__func__); -+ -+ #if defined(__UNALIGNED_BUFFER_ADJ__) -+ if(_epqh->aligned_buf) -+ ifxusb_free_buf(_epqh->aligned_buf); -+ if(_epqh->aligned_setup) -+ ifxusb_free_buf(_epqh->aligned_setup); -+ #endif -+ -+ if (!list_empty(&_epqh->epqh_list_entry)) -+ list_del_init(&_epqh->epqh_list_entry); -+ -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ del_timer(&_epqh->destroy_timer); -+ #endif -+ if(_epqh->dump_buf) -+ ifxusb_free_buf(_epqh->dump_buf); -+ _epqh->dump_buf=0; -+ -+ -+ kfree (_epqh); -+ local_irq_restore (flags); -+} -+ -+/*! -+ \brief This function adds a EPQH to -+ -+ \return 0 if successful, negative error code otherwise. -+ */ -+void ifxhcd_epqh_ready(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh) -+{ -+ unsigned long flags; -+ local_irq_save(flags); -+ if (list_empty(&_epqh->epqh_list_entry)) -+ { -+ #ifdef __EN_ISOC__ -+ if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready); -+ else -+ #endif -+ if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready); -+ else -+ list_add_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready); -+ _epqh->is_active=0; -+ } -+ else if(!_epqh->is_active) -+ { -+ #ifdef __EN_ISOC__ -+ if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready); -+ else -+ #endif -+ if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready); -+ else -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready); -+ } -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ del_timer(&_epqh->destroy_timer); -+ #endif -+ local_irq_restore(flags); -+} -+ -+void ifxhcd_epqh_active(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh) -+{ -+ unsigned long flags; -+ local_irq_save(flags); -+ if (list_empty(&_epqh->epqh_list_entry)) -+ IFX_WARN("%s() invalid epqh state\n",__func__); -+ #ifdef __EN_ISOC__ -+ if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_active); -+ else -+ #endif -+ if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_active); -+ else -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_active); -+ _epqh->is_active=1; -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ del_timer(&_epqh->destroy_timer); -+ #endif -+ local_irq_restore(flags); -+} -+ -+void ifxhcd_epqh_idle(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh) -+{ -+ unsigned long flags; -+ local_irq_save(flags); -+ -+ if (list_empty(&_epqh->urbd_list)) -+ { -+ if(_epqh->ep_type == IFXUSB_EP_TYPE_ISOC || _epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ { -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_stdby); -+ } -+ else -+ { -+ list_del_init(&_epqh->epqh_list_entry); -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ del_timer(&_epqh->destroy_timer); -+ _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout); -+ add_timer(&_epqh->destroy_timer ); -+ #endif -+ } -+ } -+ else -+ { -+ #ifdef __EN_ISOC__ -+ if (_epqh->ep_type == IFXUSB_EP_TYPE_ISOC) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_isoc_ready); -+ else -+ #endif -+ if(_epqh->ep_type == IFXUSB_EP_TYPE_INTR) -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_intr_ready); -+ else -+ list_move_tail(&_epqh->epqh_list_entry, &_ifxhcd->epqh_np_ready); -+ } -+ _epqh->is_active=0; -+ local_irq_restore(flags); -+} -+ -+ -+void ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh) -+{ -+ unsigned long flags; -+ if(_epqh->ep_type != IFXUSB_EP_TYPE_ISOC && _epqh->ep_type != IFXUSB_EP_TYPE_INTR) -+ return; -+ -+ local_irq_save(flags); -+ -+ if (list_empty(&_epqh->epqh_list_entry)) -+ IFX_WARN("%s() invalid epqh state\n",__func__); -+ if (!list_empty(&_epqh->urbd_list)) -+ IFX_WARN("%s() invalid epqh state(not empty)\n",__func__); -+ -+ _epqh->is_active=0; -+ list_del_init(&_epqh->epqh_list_entry); -+ #ifdef __EPQD_DESTROY_TIMEOUT__ -+ del_timer(&_epqh->destroy_timer); -+ _epqh->destroy_timer.expires = jiffies + (HZ*epqh_self_destroy_timeout); -+ add_timer(&_epqh->destroy_timer ); -+ #endif -+ -+ local_irq_restore(flags); -+} -+ -+ -+int ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb) -+{ -+ ifxhcd_urbd_t *urbd; -+ struct usb_host_endpoint *sysep; -+ ifxhcd_epqh_t *epqh; -+ unsigned long flags; -+ /* == AVM/WK 20100714 retval correctly initialized ==*/ -+ int retval = -ENOMEM; -+ -+ /*== AVM/BC 20100630 - Spinlock ==*/ -+ //local_irq_save(flags); -+ SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags); -+ -+// urbd = (ifxhcd_urbd_t *) kmalloc (sizeof(ifxhcd_urbd_t), GFP_KERNEL); -+ urbd = (ifxhcd_urbd_t *) kmalloc (sizeof(ifxhcd_urbd_t), GFP_ATOMIC); -+ if (urbd != NULL) /* Initializes a QTD structure.*/ -+ { -+ retval = 0; -+ memset (urbd, 0, sizeof (ifxhcd_urbd_t)); -+ -+ sysep = ifxhcd_urb_to_endpoint(_urb); -+ epqh = (ifxhcd_epqh_t *)sysep->hcpriv; -+ if (epqh == NULL) -+ { -+ epqh = ifxhcd_epqh_create (_ifxhcd, _urb); -+ if (epqh == NULL) -+ { -+ retval = -ENOSPC; -+ kfree(urbd); -+ //local_irq_restore (flags); -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ return retval; -+ } -+ sysep->hcpriv = epqh; -+ } -+ -+ INIT_LIST_HEAD(&urbd->urbd_list_entry); -+ -+ /*== AVM/BC 20100630 - 2.6.28 needs HCD link/unlink URBs ==*/ -+ retval = usb_hcd_link_urb_to_ep(ifxhcd_to_syshcd(_ifxhcd), _urb); -+ -+ if (unlikely(retval)){ -+ kfree(urbd); -+ kfree(epqh); -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ return retval; -+ } -+ -+ list_add_tail(&urbd->urbd_list_entry, &epqh->urbd_list); -+ urbd->urb = _urb; -+ _urb->hcpriv = urbd; -+ -+ urbd->epqh=epqh; -+ urbd->is_in=usb_pipein(_urb->pipe) ? 1 : 0;; -+ -+ urbd->xfer_len=_urb->transfer_buffer_length; -+#define URB_NO_SETUP_DMA_MAP 0 -+ -+ if(urbd->xfer_len>0) -+ { -+ if(_urb->transfer_flags && URB_NO_TRANSFER_DMA_MAP) -+ urbd->xfer_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->transfer_dma)); -+ else -+ urbd->xfer_buff = (uint8_t *) _urb->transfer_buffer; -+ } -+ if(epqh->ep_type == IFXUSB_EP_TYPE_CTRL) -+ { -+ if(_urb->transfer_flags && URB_NO_SETUP_DMA_MAP) -+ urbd->setup_buff = (uint8_t *) (KSEG1ADDR((uint32_t *)_urb->setup_dma)); -+ else -+ urbd->setup_buff = (uint8_t *) _urb->setup_packet; -+ } -+ } -+ //local_irq_restore (flags); -+ SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags); -+ return retval; -+} -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_cif.c -@@ -0,0 +1,1458 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_cif.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The Core Interface provides basic services for accessing and -+ ** managing the IFX USB hardware. These services are used by both the -+ ** Host Controller Driver and the Peripheral Controller Driver. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxusb_cif.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the interface to the IFX USB Core. -+*/ -+ -+#include <linux/clk.h> -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <asm/byteorder.h> -+#include <asm/unaligned.h> -+ -+ -+#include <linux/jiffies.h> -+#include <linux/platform_device.h> -+#include <linux/kernel.h> -+#include <linux/ioport.h> -+ -+#if defined(__UEIP__) -+// #include <asm/ifx/ifx_pmu.h> -+// #include <ifx_pmu.h> -+#endif -+ -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+ -+ -+#ifdef __IS_DEVICE__ -+ #include "ifxpcd.h" -+#endif -+ -+#ifdef __IS_HOST__ -+ #include "ifxhcd.h" -+#endif -+ -+#include <linux/mm.h> -+ -+#include <linux/gfp.h> -+ -+#if defined(__UEIP__) -+// #include <asm/ifx/ifx_board.h> -+ //#include <ifx_board.h> -+#endif -+ -+//#include <asm/ifx/ifx_gpio.h> -+//#include <ifx_gpio.h> -+#if defined(__UEIP__) -+// #include <asm/ifx/ifx_led.h> -+ //#include <ifx_led.h> -+#endif -+ -+ -+ -+#if defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ #ifndef USB_CTRL_PMU_SETUP -+ #define USB_CTRL_PMU_SETUP(__x) USB0_CTRL_PMU_SETUP(__x) -+ #endif -+ #ifndef USB_PHY_PMU_SETUP -+ #define USB_PHY_PMU_SETUP(__x) USB0_PHY_PMU_SETUP(__x) -+ #endif -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+#endif // defined(__UEIP__) -+ -+/*! -+ \brief This function is called to allocate buffer of specified size. -+ The allocated buffer is mapped into DMA accessable address. -+ \param size Size in BYTE to be allocated -+ \param clear 0: don't do clear after buffer allocated, other: do clear to zero -+ \return 0/NULL: Fail; uncached pointer of allocated buffer -+ */ -+void *ifxusb_alloc_buf(size_t size, int clear) -+{ -+ uint32_t *cached,*uncached; -+ uint32_t totalsize,page; -+ -+ if(!size) -+ return 0; -+ -+ size=(size+3)&0xFFFFFFFC; -+ totalsize=size + 12; -+ page=get_order(totalsize); -+ -+ cached = (void *) __get_free_pages(( GFP_ATOMIC | GFP_DMA), page); -+ -+ if(!cached) -+ { -+ IFX_PRINT("%s Allocation Failed size:%d\n",__func__,size); -+ return NULL; -+ } -+ -+ uncached = (uint32_t *)(KSEG1ADDR(cached)); -+ if(clear) -+ memset(uncached, 0, totalsize); -+ -+ *(uncached+0)=totalsize; -+ *(uncached+1)=page; -+ *(uncached+2)=(uint32_t)cached; -+ return (void *)(uncached+3); -+} -+ -+ -+/*! -+ \brief This function is called to free allocated buffer. -+ \param vaddr the uncached pointer of the buffer -+ */ -+void ifxusb_free_buf(void *vaddr) -+{ -+ uint32_t totalsize,page; -+ uint32_t *cached,*uncached; -+ -+ if(vaddr != NULL) -+ { -+ uncached=vaddr; -+ uncached-=3; -+ totalsize=*(uncached+0); -+ page=*(uncached+1); -+ cached=(uint32_t *)(*(uncached+2)); -+ if(totalsize && page==get_order(totalsize) && cached==(uint32_t *)(KSEG0ADDR(uncached))) -+ { -+ free_pages((unsigned long)cached, page); -+ return; -+ } -+ // the memory is not allocated by ifxusb_alloc_buf. Allowed but must be careful. -+ return; -+ } -+} -+ -+ -+ -+/*! -+ \brief This function is called to initialize the IFXUSB CSR data -+ structures. The register addresses in the device and host -+ structures are initialized from the base address supplied by the -+ caller. The calling function must make the OS calls to get the -+ base address of the IFXUSB controller registers. -+ -+ \param _core_if Pointer of core_if structure -+ \param _irq irq number -+ \param _reg_base_addr Base address of IFXUSB core registers -+ \param _fifo_base_addr Fifo base address -+ \param _fifo_dbg_addr Fifo debug address -+ \return 0: success; -+ */ -+int ifxusb_core_if_init(ifxusb_core_if_t *_core_if, -+ int _irq, -+ uint32_t _reg_base_addr, -+ uint32_t _fifo_base_addr, -+ uint32_t _fifo_dbg_addr) -+{ -+ int retval = 0; -+ uint32_t *reg_base =NULL; -+ uint32_t *fifo_base =NULL; -+ uint32_t *fifo_dbg =NULL; -+ -+ int i; -+ -+ IFX_DEBUGPL(DBG_CILV, "%s(%p,%d,0x%08X,0x%08X,0x%08X)\n", __func__, -+ _core_if, -+ _irq, -+ _reg_base_addr, -+ _fifo_base_addr, -+ _fifo_dbg_addr); -+ -+ if( _core_if == NULL) -+ { -+ IFX_ERROR("%s() invalid _core_if\n", __func__); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ //memset(_core_if, 0, sizeof(ifxusb_core_if_t)); -+ -+ _core_if->irq=_irq; -+ -+ reg_base =ioremap_nocache(_reg_base_addr , IFXUSB_IOMEM_SIZE ); -+ fifo_base =ioremap_nocache(_fifo_base_addr, IFXUSB_FIFOMEM_SIZE); -+ fifo_dbg =ioremap_nocache(_fifo_dbg_addr , IFXUSB_FIFODBG_SIZE); -+ if( reg_base == NULL || fifo_base == NULL || fifo_dbg == NULL) -+ { -+ IFX_ERROR("%s() usb ioremap() failed\n", __func__); -+ retval = -ENOMEM; -+ goto fail; -+ } -+ -+ _core_if->core_global_regs = (ifxusb_core_global_regs_t *)reg_base; -+ -+ /* -+ * Attempt to ensure this device is really a IFXUSB Controller. -+ * Read and verify the SNPSID register contents. The value should be -+ * 0x45F42XXX -+ */ -+ { -+ int32_t snpsid; -+ snpsid = ifxusb_rreg(&_core_if->core_global_regs->gsnpsid); -+ if ((snpsid & 0xFFFFF000) != 0x4F542000) -+ { -+ IFX_ERROR("%s() snpsid error(0x%08x) failed\n", __func__,snpsid); -+ retval = -EINVAL; -+ goto fail; -+ } -+ _core_if->snpsid=snpsid; -+ } -+ -+ #ifdef __IS_HOST__ -+ _core_if->host_global_regs = (ifxusb_host_global_regs_t *) -+ ((uint32_t)reg_base + IFXUSB_HOST_GLOBAL_REG_OFFSET); -+ _core_if->hprt0 = (uint32_t*)((uint32_t)reg_base + IFXUSB_HOST_PORT_REGS_OFFSET); -+ -+ for (i=0; i<MAX_EPS_CHANNELS; i++) -+ { -+ _core_if->hc_regs[i] = (ifxusb_hc_regs_t *) -+ ((uint32_t)reg_base + IFXUSB_HOST_CHAN_REGS_OFFSET + -+ (i * IFXUSB_CHAN_REGS_OFFSET)); -+ IFX_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n", -+ i, &_core_if->hc_regs[i]->hcchar); -+ } -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ _core_if->dev_global_regs = -+ (ifxusb_device_global_regs_t *)((uint32_t)reg_base + IFXUSB_DEV_GLOBAL_REG_OFFSET); -+ -+ for (i=0; i<MAX_EPS_CHANNELS; i++) -+ { -+ _core_if->in_ep_regs[i] = (ifxusb_dev_in_ep_regs_t *) -+ ((uint32_t)reg_base + IFXUSB_DEV_IN_EP_REG_OFFSET + -+ (i * IFXUSB_EP_REG_OFFSET)); -+ _core_if->out_ep_regs[i] = (ifxusb_dev_out_ep_regs_t *) -+ ((uint32_t)reg_base + IFXUSB_DEV_OUT_EP_REG_OFFSET + -+ (i * IFXUSB_EP_REG_OFFSET)); -+ IFX_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p/%p %p/0x%08X/0x%08X\n", -+ i, &_core_if->in_ep_regs[i]->diepctl, _core_if->in_ep_regs[i], -+ reg_base,IFXUSB_DEV_IN_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET) -+ ); -+ IFX_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p/%p %p/0x%08X/0x%08X\n", -+ i, &_core_if->out_ep_regs[i]->doepctl, _core_if->out_ep_regs[i], -+ reg_base,IFXUSB_DEV_OUT_EP_REG_OFFSET,(i * IFXUSB_EP_REG_OFFSET) -+ ); -+ } -+ #endif //__IS_DEVICE__ -+ -+ /* Setting the FIFO and other Address. */ -+ for (i=0; i<MAX_EPS_CHANNELS; i++) -+ { -+ _core_if->data_fifo[i] = fifo_base + (i * IFXUSB_DATA_FIFO_SIZE); -+ IFX_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n", -+ i, (unsigned)_core_if->data_fifo[i]); -+ } -+ -+ _core_if->data_fifo_dbg = fifo_dbg; -+ _core_if->pcgcctl = (uint32_t*)(((uint32_t)reg_base) + IFXUSB_PCGCCTL_OFFSET); -+ -+ /* -+ * Store the contents of the hardware configuration registers here for -+ * easy access later. -+ */ -+ _core_if->hwcfg1.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg1); -+ _core_if->hwcfg2.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg2); -+ _core_if->hwcfg3.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg3); -+ _core_if->hwcfg4.d32 = ifxusb_rreg(&_core_if->core_global_regs->ghwcfg4); -+ -+ IFX_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",_core_if->hwcfg1.d32); -+ IFX_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",_core_if->hwcfg2.d32); -+ IFX_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",_core_if->hwcfg3.d32); -+ IFX_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",_core_if->hwcfg4.d32); -+ -+ -+ #ifdef __DED_FIFO__ -+ IFX_PRINT("Waiting for PHY Clock Lock!\n"); -+ while(!( ifxusb_rreg(&_core_if->core_global_regs->grxfsiz) & (1<<9))) -+ { -+ } -+ IFX_PRINT("PHY Clock Locked!\n"); -+ //ifxusb_clean_spram(_core_if,128*1024/4); -+ #endif -+ -+ /* Create new workqueue and init works */ -+#if 0 -+ _core_if->wq_usb = create_singlethread_workqueue(_core_if->core_name); -+ -+ if(_core_if->wq_usb == 0) -+ { -+ IFX_DEBUGPL(DBG_CIL, "Creation of wq_usb failed\n"); -+ retval = -EINVAL; -+ goto fail; -+ } -+ -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change, core_if); -+ INIT_WORK(&core_if->w_wkp, w_wakeup_detected, core_if); -+ #else -+ INIT_WORK(&core_if->w_conn_id, w_conn_id_status_change); -+ INIT_DELAYED_WORK(&core_if->w_wkp, w_wakeup_detected); -+ #endif -+#endif -+ return 0; -+ -+fail: -+ if( reg_base != NULL) iounmap(reg_base ); -+ if( fifo_base != NULL) iounmap(fifo_base); -+ if( fifo_dbg != NULL) iounmap(fifo_dbg ); -+ return retval; -+} -+ -+/*! -+ \brief This function free the mapped address in the IFXUSB CSR data structures. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if) -+{ -+ /* Disable all interrupts */ -+ if( _core_if->core_global_regs != NULL) -+ { -+ ifxusb_mreg( &_core_if->core_global_regs->gahbcfg, 1, 0); -+ ifxusb_wreg( &_core_if->core_global_regs->gintmsk, 0); -+ } -+ -+ if( _core_if->core_global_regs != NULL) iounmap(_core_if->core_global_regs ); -+ if( _core_if->data_fifo[0] != NULL) iounmap(_core_if->data_fifo[0] ); -+ if( _core_if->data_fifo_dbg != NULL) iounmap(_core_if->data_fifo_dbg ); -+ -+#if 0 -+ if (_core_if->wq_usb) -+ destroy_workqueue(_core_if->wq_usb); -+#endif -+ memset(_core_if, 0, sizeof(ifxusb_core_if_t)); -+} -+ -+ -+ -+ -+/*! -+ \brief This function enbles the controller's Global Interrupt in the AHB Config register. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if ) -+{ -+ gahbcfg_data_t ahbcfg ={ .d32 = 0}; -+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ -+ ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32); -+} -+ -+/*! -+ \brief This function disables the controller's Global Interrupt in the AHB Config register. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if ) -+{ -+ gahbcfg_data_t ahbcfg ={ .d32 = 0}; -+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ -+ ifxusb_mreg(&_core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0); -+} -+ -+ -+ -+ -+/*! -+ \brief Flush Tx and Rx FIFO. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if ) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ volatile grstctl_t greset ={ .d32 = 0}; -+ int count = 0; -+ -+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__); -+ greset.b.rxfflsh = 1; -+ greset.b.txfflsh = 1; -+ greset.b.txfnum = 0x10; -+ greset.b.intknqflsh=1; -+ greset.b.hstfrm=1; -+ ifxusb_wreg( &global_regs->grstctl, greset.d32 ); -+ -+ do -+ { -+ greset.d32 = ifxusb_rreg( &global_regs->grstctl); -+ if (++count > 10000) -+ { -+ IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32); -+ break; -+ } -+ } while (greset.b.rxfflsh == 1 || greset.b.txfflsh == 1); -+ /* Wait for 3 PHY Clocks*/ -+ UDELAY(1); -+} -+ -+/*! -+ \brief Flush a Tx FIFO. -+ \param _core_if Pointer of core_if structure -+ \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO ) -+ */ -+void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num ) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ volatile grstctl_t greset ={ .d32 = 0}; -+ int count = 0; -+ -+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", _num); -+ -+ greset.b.intknqflsh=1; -+ greset.b.txfflsh = 1; -+ greset.b.txfnum = _num; -+ ifxusb_wreg( &global_regs->grstctl, greset.d32 ); -+ -+ do -+ { -+ greset.d32 = ifxusb_rreg( &global_regs->grstctl); -+ if (++count > 10000&&(_num==0 ||_num==0x10)) -+ { -+ IFX_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n", -+ __func__, greset.d32, -+ ifxusb_rreg( &global_regs->gnptxsts)); -+ break; -+ } -+ } while (greset.b.txfflsh == 1); -+ /* Wait for 3 PHY Clocks*/ -+ UDELAY(1); -+} -+ -+ -+/*! -+ \brief Flush Rx FIFO. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if ) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ volatile grstctl_t greset ={ .d32 = 0}; -+ int count = 0; -+ -+ IFX_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__); -+ greset.b.rxfflsh = 1; -+ ifxusb_wreg( &global_regs->grstctl, greset.d32 ); -+ -+ do -+ { -+ greset.d32 = ifxusb_rreg( &global_regs->grstctl); -+ if (++count > 10000) -+ { -+ IFX_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, greset.d32); -+ break; -+ } -+ } while (greset.b.rxfflsh == 1); -+ /* Wait for 3 PHY Clocks*/ -+ UDELAY(1); -+} -+ -+ -+#define SOFT_RESET_DELAY 100 -+ -+/*! -+ \brief Do a soft reset of the core. Be careful with this because it -+ resets all the internal state machines of the core. -+ \param _core_if Pointer of core_if structure -+ */ -+int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ volatile grstctl_t greset ={ .d32 = 0}; -+ int count = 0; -+ -+ IFX_DEBUGPL(DBG_CILV, "%s\n", __func__); -+ /* Wait for AHB master IDLE state. */ -+ do -+ { -+ UDELAY(10); -+ greset.d32 = ifxusb_rreg( &global_regs->grstctl); -+ if (++count > 100000) -+ { -+ IFX_WARN("%s() HANG! AHB Idle GRSTCTL=%0x %x\n", __func__, -+ greset.d32, greset.b.ahbidle); -+ break; -+ } -+ } while (greset.b.ahbidle == 0); -+ -+ UDELAY(1); -+ -+ /* Core Soft Reset */ -+ count = 0; -+ greset.b.csftrst = 1; -+ ifxusb_wreg( &global_regs->grstctl, greset.d32 ); -+ -+ #ifdef SOFT_RESET_DELAY -+ MDELAY(SOFT_RESET_DELAY); -+ #endif -+ -+ do -+ { -+ UDELAY(10); -+ greset.d32 = ifxusb_rreg( &global_regs->grstctl); -+ if (++count > 100000) -+ { -+ IFX_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__, greset.d32); -+ return -1; -+ } -+ } while (greset.b.csftrst == 1); -+ -+ #ifdef SOFT_RESET_DELAY -+ MDELAY(SOFT_RESET_DELAY); -+ #endif -+ -+ -+ #if defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (4, VR9_RCU_USBRESET2); -+ MDELAY(50); -+ clear_bit (4, VR9_RCU_USBRESET2); -+ } -+ else -+ { -+ set_bit (5, VR9_RCU_USBRESET2); -+ MDELAY(50); -+ clear_bit (5, VR9_RCU_USBRESET2); -+ } -+ MDELAY(50); -+ #endif //defined(__IS_VR9__) -+ -+ IFX_PRINT("USB core #%d soft-reset\n",_core_if->core_no); -+ -+ return 0; -+} -+ -+/*! -+ \brief Turn on the USB Core Power -+ \param _core_if Pointer of core_if structure -+*/ -+void ifxusb_power_on (ifxusb_core_if_t *_core_if) -+{ -+ struct clk *clk0 = clk_get_sys("usb0", NULL); -+ struct clk *clk1 = clk_get_sys("usb1", NULL); -+ // set clock gating -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ #if defined(__UEIP__) -+ -+ #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__) -+ set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR); -+ set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR); -+ clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ set_bit (0, (volatile unsigned long *)AR9_CGU_IFCCR); -+ set_bit (1, (volatile unsigned long *)AR9_CGU_IFCCR); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+// set_bit (0, (volatile unsigned long *)VR9_CGU_IFCCR); -+// set_bit (1, (volatile unsigned long *)VR9_CGU_IFCCR); -+ #endif //defined(__IS_VR9__) -+ -+ MDELAY(50); -+ -+ // set power -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ USB_CTRL_PMU_SETUP(IFX_PMU_ENABLE); -+ //#if defined(__IS_TWINPASS__) -+ // ifxusb_enable_afe_oc(); -+ //#endif -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) || defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ clk_enable(clk0); -+// USB0_CTRL_PMU_SETUP(IFX_PMU_ENABLE); -+ else -+ clk_enable(clk1); -+// USB1_CTRL_PMU_SETUP(IFX_PMU_ENABLE); -+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__) -+ -+ if(_core_if->core_global_regs) -+ { -+ // PHY configurations. -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ //ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_VR9__) -+ } -+ #else //defined(__UEIP__) -+ #if defined(__IS_TWINPASS) || defined(__IS_DANUBE__) -+ set_bit (4, (volatile unsigned long *)DANUBE_CGU_IFCCR); -+ set_bit (5, (volatile unsigned long *)DANUBE_CGU_IFCCR); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ // clear_bit (4, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR); -+ clear_bit (5, (volatile unsigned long *)AMAZON_SE_CGU_IFCCR); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ set_bit (0, (volatile unsigned long *)AMAZON_S_CGU_IFCCR); -+ set_bit (1, (volatile unsigned long *)AMAZON_S_CGU_IFCCR); -+ #endif //defined(__IS_AR9__) -+ -+ MDELAY(50); -+ -+ // set power -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ clear_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB -+ clear_bit (9, (volatile unsigned long *)DANUBE_PMU_PWDCR);//DSL -+ clear_bit (15, (volatile unsigned long *)DANUBE_PMU_PWDCR);//AHB -+ #if defined(__IS_TWINPASS__) -+ ifxusb_enable_afe_oc(); -+ #endif -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ clear_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR); -+ clear_bit (9, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR); -+ clear_bit (15, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ clear_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB -+ else -+ clear_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB -+ clear_bit (9, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//DSL -+ clear_bit (15, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//AHB -+ #endif //defined(__IS_AR9__) -+ -+ if(_core_if->core_global_regs) -+ { -+ // PHY configurations. -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ } -+ -+ #endif //defined(__UEIP__) -+} -+ -+/*! -+ \brief Turn off the USB Core Power -+ \param _core_if Pointer of core_if structure -+*/ -+void ifxusb_power_off (ifxusb_core_if_t *_core_if) -+{ -+ struct clk *clk0 = clk_get_sys("usb0", NULL); -+ struct clk *clk1 = clk_get_sys("usb1", NULL); -+ ifxusb_phy_power_off (_core_if); -+ -+ // set power -+ #if defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ USB_CTRL_PMU_SETUP(IFX_PMU_DISABLE); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) || defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ clk_disable(clk0); -+ //USB0_CTRL_PMU_SETUP(IFX_PMU_DISABLE); -+ else -+ clk_disable(clk1); -+ //USB1_CTRL_PMU_SETUP(IFX_PMU_DISABLE); -+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__) -+ #else //defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (6, (volatile unsigned long *)DANUBE_PMU_PWDCR);//USB -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (6, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//USB -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ set_bit (6, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB -+ else -+ set_bit (27, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//USB -+ #endif //defined(__IS_AR9__) -+ #endif //defined(__UEIP__) -+} -+ -+/*! -+ \brief Turn on the USB PHY Power -+ \param _core_if Pointer of core_if structure -+*/ -+void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if) -+{ -+ struct clk *clk0 = clk_get_sys("usb0", NULL); -+ struct clk *clk1 = clk_get_sys("usb1", NULL); -+ #if defined(__UEIP__) -+ if(_core_if->core_global_regs) -+ { -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9_S__) -+ if(_core_if->core_no==0) -+ set_bit (0, VR9_RCU_USB_ANA_CFG1A); -+ else -+ set_bit (0, VR9_RCU_USB_ANA_CFG1B); -+ #endif //defined(__IS_VR9__) -+ } -+ -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ USB_PHY_PMU_SETUP(IFX_PMU_ENABLE); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) || defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ clk_enable(clk0); -+ //USB0_PHY_PMU_SETUP(IFX_PMU_ENABLE); -+ else -+ clk_enable(clk1); -+ //USB1_PHY_PMU_SETUP(IFX_PMU_ENABLE); -+ #endif //defined(__IS_AR9__) || defined(__IS_VR9__) -+ -+ // PHY configurations. -+ if(_core_if->core_global_regs) -+ { -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9_S__) -+ if(_core_if->core_no==0) -+ set_bit (0, VR9_RCU_USB_ANA_CFG1A); -+ else -+ set_bit (0, VR9_RCU_USB_ANA_CFG1B); -+ #endif //defined(__IS_VR9__) -+ } -+ #else //defined(__UEIP__) -+ // PHY configurations. -+ if(_core_if->core_global_regs) -+ { -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ } -+ -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ clear_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ clear_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ clear_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY -+ else -+ clear_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY -+ #endif //defined(__IS_AR9__) -+ -+ // PHY configurations. -+ if(_core_if->core_global_regs) -+ { -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ } -+ #endif //defined(__UEIP__) -+} -+ -+ -+/*! -+ \brief Turn off the USB PHY Power -+ \param _core_if Pointer of core_if structure -+*/ -+void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if) -+{ -+ struct clk *clk0 = clk_get_sys("usb0", NULL); -+ struct clk *clk1 = clk_get_sys("usb1", NULL); -+ #if defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ USB_PHY_PMU_SETUP(IFX_PMU_DISABLE); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) || defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) || defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ clk_disable(clk0); -+ //USB0_PHY_PMU_SETUP(IFX_PMU_DISABLE); -+ else -+ clk_disable(clk1); -+ //USB1_PHY_PMU_SETUP(IFX_PMU_DISABLE); -+ #endif // defined(__IS_AR9__) || defined(__IS_VR9__) -+ #else //defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (0, (volatile unsigned long *)DANUBE_PMU_PWDCR);//PHY -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (0, (volatile unsigned long *)AMAZON_SE_PMU_PWDCR);//PHY -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ set_bit (0, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY -+ else -+ set_bit (26, (volatile unsigned long *)AMAZON_S_PMU_PWDCR);//PHY -+ #endif //defined(__IS_AR9__) -+ #endif //defined(__UEIP__) -+} -+ -+ -+/*! -+ \brief Reset on the USB Core RCU -+ \param _core_if Pointer of core_if structure -+ */ -+#if defined(__IS_VR9__) -+ int already_hard_reset=0; -+#endif -+void ifxusb_hard_reset(ifxusb_core_if_t *_core_if) -+{ -+ #if defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined (__IS_HOST__) -+ clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #endif -+ #endif //defined(__IS_AMAZON_SE__) -+ -+ #if defined(__IS_AMAZON_SE__) -+ #if defined (__IS_HOST__) -+ clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #endif -+ #endif //defined(__IS_AMAZON_SE__) -+ -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG); -+ #endif -+ } -+ else -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG); -+ #endif -+ } -+ #endif //defined(__IS_AR9__) -+ -+ #if defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG); -+ #endif -+ } -+ else -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (VR9_USBCFG_HDSEL_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG); -+ #endif -+ } -+ #endif //defined(__IS_VR9__) -+ -+ -+ // set the HC's byte-order to big-endian -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG); -+ clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB1CFG); -+ } -+ else -+ { -+ set_bit (AR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG); -+ clear_bit (AR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)AR9_RCU_USB2CFG); -+ } -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG); -+ clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB1CFG); -+ } -+ else -+ { -+ set_bit (VR9_USBCFG_HOST_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG); -+ clear_bit (VR9_USBCFG_SLV_END_BIT, (volatile unsigned long *)VR9_RCU_USB2CFG); -+ } -+ #endif //defined(__IS_VR9__) -+ -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (4, DANUBE_RCU_RESET); -+ MDELAY(500); -+ clear_bit (4, DANUBE_RCU_RESET); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (4, AMAZON_SE_RCU_RESET); -+ MDELAY(500); -+ clear_bit (4, AMAZON_SE_RCU_RESET); -+ MDELAY(500); -+ #endif //defined(__IS_AMAZON_SE__) -+ -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (4, AR9_RCU_USBRESET); -+ MDELAY(500); -+ clear_bit (4, AR9_RCU_USBRESET); -+ } -+ else -+ { -+ set_bit (28, AR9_RCU_USBRESET); -+ MDELAY(500); -+ clear_bit (28, AR9_RCU_USBRESET); -+ } -+ MDELAY(500); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ if(!already_hard_reset) -+ { -+ set_bit (4, VR9_RCU_USBRESET); -+ MDELAY(500); -+ clear_bit (4, VR9_RCU_USBRESET); -+ MDELAY(500); -+ already_hard_reset=1; -+ } -+ #endif //defined(__IS_VR9__) -+ -+ #if defined(__IS_TWINPASS__) -+ ifxusb_enable_afe_oc(); -+ #endif -+ -+ if(_core_if->core_global_regs) -+ { -+ // PHY configurations. -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ // ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_VR9__) -+ } -+ #else //defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined (__IS_HOST__) -+ clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #endif -+ #endif //defined(__IS_AMAZON_SE__) -+ -+ #if defined(__IS_AMAZON_SE__) -+ #if defined (__IS_HOST__) -+ clear_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AMAZON_SE_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #endif -+ #endif //defined(__IS_AMAZON_SE__) -+ -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG); -+ #endif -+ } -+ else -+ { -+ #if defined (__IS_HOST__) -+ clear_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG); -+ #elif defined (__IS_DEVICE__) -+ set_bit (AMAZON_S_USBCFG_HDSEL_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG); -+ #endif -+ } -+ #endif //defined(__IS_AR9__) -+ -+ // set the HC's byte-order to big-endian -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_USBCFG); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (AMAZON_SE_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ clear_bit (AMAZON_SE_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_SE_RCU_USBCFG); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG); -+ clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB1CFG); -+ } -+ else -+ { -+ set_bit (AMAZON_S_USBCFG_HOST_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG); -+ clear_bit (AMAZON_S_USBCFG_SLV_END_BIT, (volatile unsigned long *)AMAZON_S_RCU_USB2CFG); -+ } -+ #endif //defined(__IS_AR9__) -+ -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ set_bit (4, DANUBE_RCU_RESET); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (4, AMAZON_SE_RCU_RESET); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ set_bit (4, AMAZON_S_RCU_USBRESET); -+ } -+ else -+ { -+ set_bit (28, AMAZON_S_RCU_USBRESET); -+ } -+ #endif //defined(__IS_AR9__) -+ -+ MDELAY(500); -+ -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ clear_bit (4, DANUBE_RCU_RESET); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ clear_bit (4, AMAZON_SE_RCU_RESET); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ clear_bit (4, AMAZON_S_RCU_USBRESET); -+ } -+ else -+ { -+ clear_bit (28, AMAZON_S_RCU_USBRESET); -+ } -+ #endif //defined(__IS_AR9__) -+ -+ MDELAY(500); -+ -+ #if defined(__IS_TWINPASS__) -+ ifxusb_enable_afe_oc(); -+ #endif -+ -+ if(_core_if->core_global_regs) -+ { -+ // PHY configurations. -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ ifxusb_wreg (&_core_if->core_global_regs->guid,0x14014); -+ #endif //defined(__IS_AR9__) -+ } -+ #endif //defined(__UEIP__) -+} -+ -+#if defined(__GADGET_LED__) || defined(__HOST_LED__) -+ #if defined(__UEIP__) -+ static void *g_usb_led_trigger = NULL; -+ #endif -+ -+ void ifxusb_led_init(ifxusb_core_if_t *_core_if) -+ { -+ #if defined(__UEIP__) -+ if ( !g_usb_led_trigger ) -+ { -+ ifx_led_trigger_register("usb_link", &g_usb_led_trigger); -+ if ( g_usb_led_trigger != NULL ) -+ { -+ struct ifx_led_trigger_attrib attrib = {0}; -+ attrib.delay_on = 250; -+ attrib.delay_off = 250; -+ attrib.timeout = 2000; -+ attrib.def_value = 1; -+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; -+ IFX_DEBUGP("Reg USB LED!!\n"); -+ ifx_led_trigger_set_attrib(g_usb_led_trigger, &attrib); -+ } -+ } -+ #endif //defined(__UEIP__) -+ } -+ -+ void ifxusb_led_free(ifxusb_core_if_t *_core_if) -+ { -+ #if defined(__UEIP__) -+ if ( g_usb_led_trigger ) -+ { -+ ifx_led_trigger_deregister(g_usb_led_trigger); -+ g_usb_led_trigger = NULL; -+ } -+ #endif //defined(__UEIP__) -+ } -+ -+ /*! -+ \brief Turn off the USB 5V VBus Power -+ \param _core_if Pointer of core_if structure -+ */ -+ void ifxusb_led(ifxusb_core_if_t *_core_if) -+ { -+ #if defined(__UEIP__) -+ if(g_usb_led_trigger) -+ ifx_led_trigger_activate(g_usb_led_trigger); -+ #else -+ #endif //defined(__UEIP__) -+ } -+#endif // defined(__GADGET_LED__) || defined(__HOST_LED__) -+ -+ -+ -+#if defined(__IS_HOST__) && defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__) -+/*! -+ \brief Turn on the OC Int -+ */ -+ void ifxusb_oc_int_on() -+ { -+ #if defined(__UEIP__) -+ #else -+ #if defined(__IS_TWINPASS__) -+ irq_enable(DANUBE_USB_OC_INT); -+ #endif -+ #endif //defined(__UEIP__) -+ } -+/*! -+ \brief Turn off the OC Int -+ */ -+ void ifxusb_oc_int_off() -+ { -+ #if defined(__UEIP__) -+ #else -+ #if defined(__IS_TWINPASS__) -+ irq_disable(DANUBE_USB_OC_INT); -+ #endif -+ #endif //defined(__UEIP__) -+ } -+#endif //defined(__IS_HOST__) && defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__) -+ -+/* internal routines for debugging */ -+void ifxusb_dump_msg(const u8 *buf, unsigned int length) -+{ -+#ifdef __DEBUG__ -+ unsigned int start, num, i; -+ char line[52], *p; -+ -+ if (length >= 512) -+ return; -+ start = 0; -+ while (length > 0) -+ { -+ num = min(length, 16u); -+ p = line; -+ for (i = 0; i < num; ++i) -+ { -+ if (i == 8) -+ *p++ = ' '; -+ sprintf(p, " %02x", buf[i]); -+ p += 3; -+ } -+ *p = 0; -+ IFX_PRINT( "%6x: %s\n", start, line); -+ buf += num; -+ start += num; -+ length -= num; -+ } -+#endif -+} -+ -+/* This functions reads the SPRAM and prints its content */ -+void ifxusb_dump_spram(ifxusb_core_if_t *_core_if) -+{ -+#ifdef __ENABLE_DUMP__ -+ volatile uint8_t *addr, *start_addr, *end_addr; -+ uint32_t size; -+ IFX_PRINT("SPRAM Data:\n"); -+ start_addr = (void*)_core_if->core_global_regs; -+ IFX_PRINT("Base Address: 0x%8X\n", (uint32_t)start_addr); -+ -+ start_addr = (void*)_core_if->data_fifo_dbg; -+ IFX_PRINT("Starting Address: 0x%8X\n", (uint32_t)start_addr); -+ -+ size=_core_if->hwcfg3.b.dfifo_depth; -+ size<<=2; -+ size+=0x200; -+ size&=0x0003FFFC; -+ -+ end_addr = (void*)_core_if->data_fifo_dbg; -+ end_addr += size; -+ -+ for(addr = start_addr; addr < end_addr; addr+=16) -+ { -+ IFX_PRINT("0x%8X:\t%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", (uint32_t)addr, -+ addr[ 0], addr[ 1], addr[ 2], addr[ 3], -+ addr[ 4], addr[ 5], addr[ 6], addr[ 7], -+ addr[ 8], addr[ 9], addr[10], addr[11], -+ addr[12], addr[13], addr[14], addr[15] -+ ); -+ } -+ return; -+#endif //__ENABLE_DUMP__ -+} -+ -+ -+ -+ -+/* This function reads the core global registers and prints them */ -+void ifxusb_dump_registers(ifxusb_core_if_t *_core_if) -+{ -+#ifdef __ENABLE_DUMP__ -+ int i; -+ volatile uint32_t *addr; -+ #ifdef __IS_DEVICE__ -+ volatile uint32_t *addri,*addro; -+ #endif -+ -+ IFX_PRINT("Core Global Registers\n"); -+ addr=&_core_if->core_global_regs->gotgctl; -+ IFX_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gotgint; -+ IFX_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gahbcfg; -+ IFX_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gusbcfg; -+ IFX_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->grstctl; -+ IFX_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gintsts; -+ IFX_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gintmsk; -+ IFX_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gi2cctl; -+ IFX_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gpvndctl; -+ IFX_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->ggpio; -+ IFX_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->guid; -+ IFX_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->gsnpsid; -+ IFX_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->ghwcfg1; -+ IFX_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->ghwcfg2; -+ IFX_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->ghwcfg3; -+ IFX_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->ghwcfg4; -+ IFX_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ -+ addr=_core_if->pcgcctl; -+ IFX_PRINT("PCGCCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ -+ addr=&_core_if->core_global_regs->grxfsiz; -+ IFX_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ -+ #ifdef __IS_HOST__ -+ addr=&_core_if->core_global_regs->gnptxfsiz; -+ IFX_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->core_global_regs->hptxfsiz; -+ IFX_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_FIFO__ -+ addr=&_core_if->core_global_regs->gnptxfsiz; -+ IFX_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ for (i=0; i<= _core_if->hwcfg4.b.num_in_eps; i++) -+ { -+ addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i]; -+ IFX_PRINT("DPTXFSIZ[%d] @0x%08X : 0x%08X\n",i,(uint32_t)addr,ifxusb_rreg(addr)); -+ } -+ #else -+ addr=&_core_if->core_global_regs->gnptxfsiz; -+ IFX_PRINT("TXFSIZ[00] @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ for (i=0; i< _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) -+ { -+ addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i]; -+ IFX_PRINT("TXFSIZ[%02d] @0x%08X : 0x%08X\n",i+1,(uint32_t)addr,ifxusb_rreg(addr)); -+ } -+ #endif -+ #endif //__IS_DEVICE__ -+ -+ #ifdef __IS_HOST__ -+ IFX_PRINT("Host Global Registers\n"); -+ addr=&_core_if->host_global_regs->hcfg; -+ IFX_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->host_global_regs->hfir; -+ IFX_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->host_global_regs->hfnum; -+ IFX_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->host_global_regs->hptxsts; -+ IFX_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->host_global_regs->haint; -+ IFX_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->host_global_regs->haintmsk; -+ IFX_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr= _core_if->hprt0; -+ IFX_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ -+ for (i=0; i<MAX_EPS_CHANNELS; i++) -+ { -+ IFX_PRINT("Host Channel %d Specific Registers\n", i); -+ addr=&_core_if->hc_regs[i]->hcchar; -+ IFX_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->hc_regs[i]->hcsplt; -+ IFX_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->hc_regs[i]->hcint; -+ IFX_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->hc_regs[i]->hcintmsk; -+ IFX_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->hc_regs[i]->hctsiz; -+ IFX_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->hc_regs[i]->hcdma; -+ IFX_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ } -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ IFX_PRINT("Device Global Registers\n"); -+ addr=&_core_if->dev_global_regs->dcfg; -+ IFX_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->dctl; -+ IFX_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->dsts; -+ IFX_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->diepmsk; -+ IFX_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->doepmsk; -+ IFX_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->daintmsk; -+ IFX_PRINT("DAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->daint; -+ IFX_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->dvbusdis; -+ IFX_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ addr=&_core_if->dev_global_regs->dvbuspulse; -+ IFX_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr)); -+ -+ addr=&_core_if->dev_global_regs->dtknqr1; -+ IFX_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,ifxusb_rreg(addr)); -+ if (_core_if->hwcfg2.b.dev_token_q_depth > 6) { -+ addr=&_core_if->dev_global_regs->dtknqr2; -+ IFX_PRINT("DTKNQR2 @0x%08X : 0x%08X\n", (uint32_t)addr,ifxusb_rreg(addr)); -+ } -+ -+ if (_core_if->hwcfg2.b.dev_token_q_depth > 14) -+ { -+ addr=&_core_if->dev_global_regs->dtknqr3_dthrctl; -+ IFX_PRINT("DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr)); -+ } -+ -+ if (_core_if->hwcfg2.b.dev_token_q_depth > 22) -+ { -+ addr=&_core_if->dev_global_regs->dtknqr4_fifoemptymsk; -+ IFX_PRINT("DTKNQR4 @0x%08X : 0x%08X\n", (uint32_t)addr, ifxusb_rreg(addr)); -+ } -+ -+ //for (i=0; i<= MAX_EPS_CHANNELS; i++) -+ //for (i=0; i<= 10; i++) -+ for (i=0; i<= 3; i++) -+ { -+ IFX_PRINT("Device EP %d Registers\n", i); -+ addri=&_core_if->in_ep_regs[i]->diepctl;addro=&_core_if->out_ep_regs[i]->doepctl; -+ IFX_PRINT("DEPCTL I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro)); -+ addro=&_core_if->out_ep_regs[i]->doepfn; -+ IFX_PRINT("DEPFN I: O: 0x%08X\n",ifxusb_rreg(addro)); -+ addri=&_core_if->in_ep_regs[i]->diepint;addro=&_core_if->out_ep_regs[i]->doepint; -+ IFX_PRINT("DEPINT I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro)); -+ addri=&_core_if->in_ep_regs[i]->dieptsiz;addro=&_core_if->out_ep_regs[i]->doeptsiz; -+ IFX_PRINT("DETSIZ I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro)); -+ addri=&_core_if->in_ep_regs[i]->diepdma;addro=&_core_if->out_ep_regs[i]->doepdma; -+ IFX_PRINT("DEPDMA I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro)); -+ addri=&_core_if->in_ep_regs[i]->dtxfsts; -+ IFX_PRINT("DTXFSTS I: 0x%08X\n",ifxusb_rreg(addri) ); -+ addri=&_core_if->in_ep_regs[i]->diepdmab;addro=&_core_if->out_ep_regs[i]->doepdmab; -+ IFX_PRINT("DEPDMAB I: 0x%08X O: 0x%08X\n",ifxusb_rreg(addri),ifxusb_rreg(addro)); -+ } -+ #endif //__IS_DEVICE__ -+#endif //__ENABLE_DUMP__ -+} -+ -+void ifxusb_clean_spram(ifxusb_core_if_t *_core_if,uint32_t dwords) -+{ -+ volatile uint32_t *addr1,*addr2, *start_addr, *end_addr; -+ -+ if(!dwords) -+ return; -+ -+ start_addr = (uint32_t *)_core_if->data_fifo_dbg; -+ -+ end_addr = (uint32_t *)_core_if->data_fifo_dbg; -+ end_addr += dwords; -+ -+ IFX_PRINT("Clearning SPRAM: 0x%8X-0x%8X\n", (uint32_t)start_addr,(uint32_t)end_addr); -+ for(addr1 = start_addr; addr1 < end_addr; addr1+=4) -+ { -+ for(addr2 = addr1; addr2 < addr1+4; addr2++) -+ *addr2=0x00000000; -+ } -+ IFX_PRINT("Clearning SPRAM: 0x%8X-0x%8X Done\n", (uint32_t)start_addr,(uint32_t)end_addr); -+ return; -+} -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_cif.h -@@ -0,0 +1,665 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_cif.h -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The Core Interface provides basic services for accessing and -+ ** managing the IFX USB hardware. These services are used by both the -+ ** Host Controller Driver and the Peripheral Controller Driver. -+ ** FUNCTIONS : -+ ** COMPILER : gcc -+ ** REFERENCE : IFX hardware ref handbook for each plateforms -+ ** COPYRIGHT : -+ ** Version Control Section ** -+ ** $Author$ -+ ** $Date$ -+ ** $Revisions$ -+ ** $Log$ Revision history -+*****************************************************************************/ -+ -+/*! -+ \defgroup IFXUSB_DRIVER_V3 IFX USB SS Project -+ \brief IFX USB subsystem V3.x -+ */ -+ -+/*! -+ \defgroup IFXUSB_CIF Core Interface APIs -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief The Core Interface provides basic services for accessing and -+ managing the IFXUSB hardware. These services are used by both the -+ Host Controller Driver and the Peripheral Controller Driver. -+ */ -+ -+ -+/*! -+ \file ifxusb_cif.h -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the interface to the IFX USB Core. -+ */ -+ -+#if !defined(__IFXUSB_CIF_H__) -+#define __IFXUSB_CIF_H__ -+ -+#include <linux/workqueue.h> -+ -+#include <linux/version.h> -+#include <asm/param.h> -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+ -+#ifdef __DEBUG__ -+ #include "linux/timer.h" -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#define IFXUSB_PARAM_SPEED_HIGH 0 -+#define IFXUSB_PARAM_SPEED_FULL 1 -+ -+#define IFXUSB_EP_SPEED_LOW 0 -+#define IFXUSB_EP_SPEED_FULL 1 -+#define IFXUSB_EP_SPEED_HIGH 2 -+ -+#define IFXUSB_EP_TYPE_CTRL 0 -+#define IFXUSB_EP_TYPE_ISOC 1 -+#define IFXUSB_EP_TYPE_BULK 2 -+#define IFXUSB_EP_TYPE_INTR 3 -+ -+#define IFXUSB_HC_PID_DATA0 0 -+#define IFXUSB_HC_PID_DATA2 1 -+#define IFXUSB_HC_PID_DATA1 2 -+#define IFXUSB_HC_PID_MDATA 3 -+#define IFXUSB_HC_PID_SETUP 3 -+ -+ -+/*! -+ \addtogroup IFXUSB_CIF -+ */ -+/*@{*/ -+ -+/*! -+ \struct ifxusb_params -+ \brief IFXUSB Parameters structure. -+ This structure is used for both importing from insmod stage and run-time storage. -+ These parameters define how the IFXUSB controller should be configured. -+ */ -+typedef struct ifxusb_params -+{ -+ int32_t dma_burst_size; /*!< The DMA Burst size (applicable only for Internal DMA -+ Mode). 0(for single), 1(incr), 4(incr4), 8(incr8) 16(incr16) -+ */ -+ /* Translate this to GAHBCFG values */ -+ int32_t speed; /*!< Specifies the maximum speed of operation in host and device mode. -+ The actual speed depends on the speed of the attached device and -+ the value of phy_type. The actual speed depends on the speed of the -+ attached device. -+ 0 - High Speed (default) -+ 1 - Full Speed -+ */ -+ -+ int32_t data_fifo_size; /*!< Total number of dwords in the data FIFO memory. This -+ memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic -+ Tx FIFOs. -+ 32 to 32768 -+ */ -+ #ifdef __IS_DEVICE__ -+ int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in device mode. -+ 16 to 32768 -+ */ -+ -+ -+ int32_t tx_fifo_size[MAX_EPS_CHANNELS]; /*!< Number of dwords in each of the Tx FIFOs in device mode. -+ 4 to 768 -+ */ -+ #ifdef __DED_FIFO__ -+ int32_t thr_ctl; /*!< Threshold control on/off */ -+ int32_t tx_thr_length; /*!< Threshold length for Tx */ -+ int32_t rx_thr_length; /*!< Threshold length for Rx*/ -+ #endif -+ #else //__IS_HOST__ -+ int32_t host_channels; /*!< The number of host channel registers to use. -+ 1 to 16 -+ */ -+ -+ int32_t rx_fifo_size; /*!< Number of dwords in the Rx FIFO in host mode. -+ 16 to 32768 -+ */ -+ -+ int32_t nperio_tx_fifo_size;/*!< Number of dwords in the non-periodic Tx FIFO in host mode. -+ 16 to 32768 -+ */ -+ -+ int32_t perio_tx_fifo_size; /*!< Number of dwords in the host periodic Tx FIFO. -+ 16 to 32768 -+ */ -+ #endif //__IS_HOST__ -+ -+ int32_t max_transfer_size; /*!< The maximum transfer size supported in bytes. -+ 2047 to 65,535 -+ */ -+ -+ int32_t max_packet_count; /*!< The maximum number of packets in a transfer. -+ 15 to 511 (default 511) -+ */ -+ int32_t phy_utmi_width; /*!< Specifies the UTMI+ Data Width. -+ 8 or 16 bits (default 16) -+ */ -+ -+ int32_t turn_around_time_hs; /*!< Specifies the Turn-Around time at HS*/ -+ int32_t turn_around_time_fs; /*!< Specifies the Turn-Around time at FS*/ -+ -+ int32_t timeout_cal_hs; /*!< Specifies the Timeout_Calibration at HS*/ -+ int32_t timeout_cal_fs; /*!< Specifies the Timeout_Calibration at FS*/ -+} ifxusb_params_t; -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+/*! -+ \struct ifxusb_core_if -+ \brief The ifx_core_if structure contains information needed to manage -+ the IFX USB controller acting in either host or device mode. It -+ represents the programming view of the controller as a whole. -+ */ -+typedef struct ifxusb_core_if -+{ -+ ifxusb_params_t params; /*!< Run-time Parameters */ -+ -+ uint8_t core_no; /*!< core number (used as id when multi-core case */ -+ char *core_name; /*!< core name used for registration and informative purpose*/ -+ int irq; /*!< irq number this core is hooked */ -+ -+ /***************************************************************** -+ * Structures and pointers to physical register interface. -+ *****************************************************************/ -+ /** Core Global registers starting at offset 000h. */ -+ ifxusb_core_global_regs_t *core_global_regs; /*!< pointer to Core Global Registers, offset at 000h */ -+ -+ /** Host-specific registers */ -+ #ifdef __IS_HOST__ -+ /** Host Global Registers starting at offset 400h.*/ -+ ifxusb_host_global_regs_t *host_global_regs; /*!< pointer to Host Global Registers, offset at 400h */ -+ #define IFXUSB_HOST_GLOBAL_REG_OFFSET 0x400 -+ /** Host Port 0 Control and Status Register */ -+ volatile uint32_t *hprt0; /*!< pointer to HPRT0 Registers, offset at 440h */ -+ #define IFXUSB_HOST_PORT_REGS_OFFSET 0x440 -+ /** Host Channel Specific Registers at offsets 500h-5FCh. */ -+ ifxusb_hc_regs_t *hc_regs[MAX_EPS_CHANNELS]; /*!< pointer to Host-Channel n Registers, offset at 500h */ -+ #define IFXUSB_HOST_CHAN_REGS_OFFSET 0x500 -+ #define IFXUSB_CHAN_REGS_OFFSET 0x20 -+ #endif -+ -+ /** Device-specific registers */ -+ #ifdef __IS_DEVICE__ -+ /** Device Global Registers starting at offset 800h */ -+ ifxusb_device_global_regs_t *dev_global_regs; /*!< pointer to Device Global Registers, offset at 800h */ -+ #define IFXUSB_DEV_GLOBAL_REG_OFFSET 0x800 -+ -+ /** Device Logical IN Endpoint-Specific Registers 900h-AFCh */ -+ ifxusb_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS]; /*!< pointer to Device IN-EP Registers, offset at 900h */ -+ #define IFXUSB_DEV_IN_EP_REG_OFFSET 0x900 -+ #define IFXUSB_EP_REG_OFFSET 0x20 -+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */ -+ ifxusb_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];/*!< pointer to Device OUT-EP Registers, offset at 900h */ -+ #define IFXUSB_DEV_OUT_EP_REG_OFFSET 0xB00 -+ #endif -+ -+ /** Power and Clock Gating Control Register */ -+ volatile uint32_t *pcgcctl; /*!< pointer to Power and Clock Gating Control Registers, offset at E00h */ -+ #define IFXUSB_PCGCCTL_OFFSET 0xE00 -+ -+ /** Push/pop addresses for endpoints or host channels.*/ -+ uint32_t *data_fifo[MAX_EPS_CHANNELS]; /*!< pointer to FIFO access windows, offset at 1000h */ -+ #define IFXUSB_DATA_FIFO_OFFSET 0x1000 -+ #define IFXUSB_DATA_FIFO_SIZE 0x1000 -+ -+ uint32_t *data_fifo_dbg; /*!< pointer to FIFO debug windows, offset at 1000h */ -+ -+ /** Hardware Configuration -- stored here for convenience.*/ -+ hwcfg1_data_t hwcfg1; /*!< preserved Hardware Configuration 1 */ -+ hwcfg2_data_t hwcfg2; /*!< preserved Hardware Configuration 2 */ -+ hwcfg3_data_t hwcfg3; /*!< preserved Hardware Configuration 3 */ -+ hwcfg4_data_t hwcfg4; /*!< preserved Hardware Configuration 3 */ -+ uint32_t snpsid; /*!< preserved SNPSID */ -+ -+ /***************************************************************** -+ * Run-time informations. -+ *****************************************************************/ -+ /* Set to 1 if the core PHY interface bits in USBCFG have been initialized. */ -+ uint8_t phy_init_done; /*!< indicated PHY is initialized. */ -+ -+ #ifdef __IS_HOST__ -+ uint8_t queuing_high_bandwidth; /*!< Host mode, Queueing High Bandwidth. */ -+ #endif -+} ifxusb_core_if_t; -+ -+/*@}*//*IFXUSB_CIF*/ -+ -+ -+/*! -+ \fn void *ifxusb_alloc_buf(size_t size, int clear) -+ \brief This function is called to allocate buffer of specified size. -+ The allocated buffer is mapped into DMA accessable address. -+ \param size Size in BYTE to be allocated -+ \param clear 0: don't do clear after buffer allocated, other: do clear to zero -+ \return 0/NULL: Fail; uncached pointer of allocated buffer -+ \ingroup IFXUSB_CIF -+ */ -+extern void *ifxusb_alloc_buf(size_t size, int clear); -+ -+/*! -+ \fn void ifxusb_free_buf(void *vaddr) -+ \brief This function is called to free allocated buffer. -+ \param vaddr the uncached pointer of the buffer -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_free_buf(void *vaddr); -+ -+/*! -+ \fn int ifxusb_core_if_init(ifxusb_core_if_t *_core_if, -+ int _irq, -+ uint32_t _reg_base_addr, -+ uint32_t _fifo_base_addr, -+ uint32_t _fifo_dbg_addr) -+ \brief This function is called to initialize the IFXUSB CSR data -+ structures. The register addresses in the device and host -+ structures are initialized from the base address supplied by the -+ caller. The calling function must make the OS calls to get the -+ base address of the IFXUSB controller registers. -+ \param _core_if Pointer of core_if structure -+ \param _irq irq number -+ \param _reg_base_addr Base address of IFXUSB core registers -+ \param _fifo_base_addr Fifo base address -+ \param _fifo_dbg_addr Fifo debug address -+ \return 0: success; -+ \ingroup IFXUSB_CIF -+ */ -+extern int ifxusb_core_if_init(ifxusb_core_if_t *_core_if, -+ int _irq, -+ uint32_t _reg_base_addr, -+ uint32_t _fifo_base_addr, -+ uint32_t _fifo_dbg_addr); -+ -+ -+/*! -+ \fn void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if) -+ \brief This function free the mapped address in the IFXUSB CSR data structures. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_core_if_remove(ifxusb_core_if_t *_core_if); -+ -+/*! -+ \fn void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if ) -+ \brief This function enbles the controller's Global Interrupt in the AHB Config register. -+ \param _core_if Pointer of core_if structure -+ */ -+extern void ifxusb_enable_global_interrupts( ifxusb_core_if_t *_core_if ); -+ -+/*! -+ \fn void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if ) -+ \brief This function disables the controller's Global Interrupt in the AHB Config register. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_disable_global_interrupts( ifxusb_core_if_t *_core_if ); -+ -+/*! -+ \fn void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num ) -+ \brief Flush a Tx FIFO. -+ \param _core_if Pointer of core_if structure -+ \param _num Tx FIFO to flush. ( 0x10 for ALL TX FIFO ) -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_flush_tx_fifo( ifxusb_core_if_t *_core_if, const int _num ); -+ -+/*! -+ \fn void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if ) -+ \brief Flush Rx FIFO. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_flush_rx_fifo( ifxusb_core_if_t *_core_if ); -+ -+/*! -+ \fn void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if ) -+ \brief Flush ALL Rx and Tx FIFO. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_flush_both_fifo( ifxusb_core_if_t *_core_if ); -+ -+ -+/*! -+ \fn int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if) -+ \brief Do core a soft reset of the core. Be careful with this because it -+ resets all the internal state machines of the core. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern int ifxusb_core_soft_reset(ifxusb_core_if_t *_core_if); -+ -+ -+/*! -+ \brief Turn on the USB Core Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+*/ -+extern void ifxusb_power_on (ifxusb_core_if_t *_core_if); -+ -+/*! -+ \fn void ifxusb_power_off (ifxusb_core_if_t *_core_if) -+ \brief Turn off the USB Core Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+*/ -+extern void ifxusb_power_off (ifxusb_core_if_t *_core_if); -+ -+/*! -+ \fn void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if) -+ \brief Turn on the USB PHY Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+*/ -+extern void ifxusb_phy_power_on (ifxusb_core_if_t *_core_if); -+ -+/*! -+ \fn void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if) -+ \brief Turn off the USB PHY Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+*/ -+extern void ifxusb_phy_power_off (ifxusb_core_if_t *_core_if); -+ -+/*! -+ \fn void ifxusb_hard_reset(ifxusb_core_if_t *_core_if) -+ \brief Reset on the USB Core RCU -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+extern void ifxusb_hard_reset(ifxusb_core_if_t *_core_if); -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ -+#ifdef __IS_HOST__ -+ /*! -+ \fn void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params) -+ \brief This function initializes the IFXUSB controller registers for Host mode. -+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the -+ request queues. -+ \param _core_if Pointer of core_if structure -+ \param _params parameters to be set -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params); -+ -+ /*! -+ \fn void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if) -+ \brief This function enables the Host mode interrupts. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if) -+ \brief This function disables the Host mode interrupts. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if); -+ -+ #if defined(__IS_TWINPASS__) -+ extern void ifxusb_enable_afe_oc(void); -+ #endif -+ -+ /*! -+ \fn void ifxusb_vbus_init(ifxusb_core_if_t *_core_if) -+ \brief This function init the VBUS control. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_vbus_init(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_vbus_free(ifxusb_core_if_t *_core_if) -+ \brief This function free the VBUS control. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_vbus_free(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_vbus_on(ifxusb_core_if_t *_core_if) -+ \brief Turn on the USB 5V VBus Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_vbus_on(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_vbus_off(ifxusb_core_if_t *_core_if) -+ \brief Turn off the USB 5V VBus Power -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_vbus_off(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn int ifxusb_vbus(ifxusb_core_if_t *_core_if) -+ \brief Read Current VBus status -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern int ifxusb_vbus(ifxusb_core_if_t *_core_if); -+ -+ #if defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__) -+ /*! -+ \fn void ifxusb_oc_int_on(void) -+ \brief Turn on the OC interrupt -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_oc_int_on(void); -+ -+ /*! -+ \fn void ifxusb_oc_int_off(void) -+ \brief Turn off the OC interrupt -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_oc_int_off(void); -+ #endif //defined(__DO_OC_INT__) && defined(__DO_OC_INT_ENABLE__) -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ -+#ifdef __IS_DEVICE__ -+ /*! -+ \fn void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if) -+ \brief This function enables the Device mode interrupts. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if) -+ \brief Gets the current USB frame number. This is the frame number from the last SOF packet. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in) -+ \brief Set the EP STALL. -+ \param _core_if Pointer of core_if structure -+ \param _epno EP number -+ \param _is_in 1: is IN transfer -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in); -+ -+ /*! -+ \fn void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in) -+ \brief Set the EP STALL. -+ \param _core_if Pointer of core_if structure -+ \param _epno EP number -+ \param _ep_type EP Type -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in); -+ -+ /*! -+ \fn void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params) -+ \brief This function initializes the IFXUSB controller registers for Device mode. -+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the -+ request queues. -+ This function validate the imported parameters and store the result in the CIF structure. -+ After -+ \param _core_if Pointer of core_if structure -+ \param _params structure of inported parameters -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params); -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#if defined(__GADGET_LED__) || defined(__HOST_LED__) -+ /*! -+ \fn void ifxusb_led_init(ifxusb_core_if_t *_core_if) -+ \brief This function init the LED control. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_led_init(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_led_free(ifxusb_core_if_t *_core_if) -+ \brief This function free the LED control. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_led_free(ifxusb_core_if_t *_core_if); -+ -+ /*! -+ \fn void ifxusb_led(ifxusb_core_if_t *_core_if) -+ \brief This function trigger the LED access. -+ \param _core_if Pointer of core_if structure -+ \ingroup IFXUSB_CIF -+ */ -+ extern void ifxusb_led(ifxusb_core_if_t *_core_if); -+#endif -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+/* internal routines for debugging */ -+extern void ifxusb_dump_msg(const u8 *buf, unsigned int length); -+extern void ifxusb_dump_spram(ifxusb_core_if_t *_core_if); -+extern void ifxusb_dump_registers(ifxusb_core_if_t *_core_if); -+extern void ifxusb_clean_spram(ifxusb_core_if_t *_core_if,uint32_t dwords); -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+static inline uint32_t ifxusb_read_core_intr(ifxusb_core_if_t *_core_if) -+{ -+ return (ifxusb_rreg(&_core_if->core_global_regs->gintsts) & -+ (ifxusb_rreg(&_core_if->core_global_regs->gintmsk) -+#ifdef __USE_TIMER_4_SOF__ -+ | IFXUSB_SOF_INTR_MASK -+#endif -+ )); -+} -+ -+static inline uint32_t ifxusb_read_otg_intr (ifxusb_core_if_t *_core_if) -+{ -+ return (ifxusb_rreg (&_core_if->core_global_regs->gotgint)); -+} -+ -+static inline uint32_t ifxusb_mode(ifxusb_core_if_t *_core_if) -+{ -+ return (ifxusb_rreg( &_core_if->core_global_regs->gintsts ) & 0x1); -+} -+static inline uint8_t ifxusb_is_device_mode(ifxusb_core_if_t *_core_if) -+{ -+ return (ifxusb_mode(_core_if) != 1); -+} -+static inline uint8_t ifxusb_is_host_mode(ifxusb_core_if_t *_core_if) -+{ -+ return (ifxusb_mode(_core_if) == 1); -+} -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#ifdef __IS_HOST__ -+ static inline uint32_t ifxusb_read_hprt0(ifxusb_core_if_t *_core_if) -+ { -+ hprt0_data_t hprt0; -+ hprt0.d32 = ifxusb_rreg(_core_if->hprt0); -+ hprt0.b.prtena = 0; -+ hprt0.b.prtconndet = 0; -+ hprt0.b.prtenchng = 0; -+ hprt0.b.prtovrcurrchng = 0; -+ return hprt0.d32; -+ } -+ -+ static inline uint32_t ifxusb_read_host_all_channels_intr (ifxusb_core_if_t *_core_if) -+ { -+ return (ifxusb_rreg (&_core_if->host_global_regs->haint)); -+ } -+ -+ static inline uint32_t ifxusb_read_host_channel_intr (ifxusb_core_if_t *_core_if, int hc_num) -+ { -+ return (ifxusb_rreg (&_core_if->hc_regs[hc_num]->hcint)); -+ } -+#endif -+ -+#ifdef __IS_DEVICE__ -+ static inline uint32_t ifxusb_read_dev_all_in_ep_intr(ifxusb_core_if_t *_core_if) -+ { -+ uint32_t v; -+ v = ifxusb_rreg(&_core_if->dev_global_regs->daint) & -+ ifxusb_rreg(&_core_if->dev_global_regs->daintmsk); -+ return (v & 0xffff); -+ } -+ -+ static inline uint32_t ifxusb_read_dev_all_out_ep_intr(ifxusb_core_if_t *_core_if) -+ { -+ uint32_t v; -+ v = ifxusb_rreg(&_core_if->dev_global_regs->daint) & -+ ifxusb_rreg(&_core_if->dev_global_regs->daintmsk); -+ return ((v & 0xffff0000) >> 16); -+ } -+ -+ static inline uint32_t ifxusb_read_dev_in_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num) -+ { -+ uint32_t v; -+ v = ifxusb_rreg(&_core_if->in_ep_regs[_ep_num]->diepint) & -+ ifxusb_rreg(&_core_if->dev_global_regs->diepmsk); -+ return v; -+ } -+ -+ static inline uint32_t ifxusb_read_dev_out_ep_intr(ifxusb_core_if_t *_core_if, int _ep_num) -+ { -+ uint32_t v; -+ v = ifxusb_rreg(&_core_if->out_ep_regs[_ep_num]->doepint) & -+ ifxusb_rreg(&_core_if->dev_global_regs->doepmsk); -+ return v; -+ } -+ -+#endif -+ -+extern void ifxusb_attr_create (void *_dev); -+ -+extern void ifxusb_attr_remove (void *_dev); -+ -+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#endif // !defined(__IFXUSB_CIF_H__) -+ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_cif_d.c -@@ -0,0 +1,458 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_cif_d.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The Core Interface provides basic services for accessing and -+ ** managing the IFX USB hardware. These services are used by the -+ ** Peripheral Controller Driver only. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxusb_cif_d.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the interface to the IFX USB Core. -+*/ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+ -+#include <asm/byteorder.h> -+#include <asm/unaligned.h> -+ -+#ifdef __DEBUG__ -+ #include <linux/jiffies.h> -+#endif -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+ -+#include "ifxpcd.h" -+ -+ -+ -+/*! -+ \brief Initializes the DevSpd field of the DCFG register depending on the PHY type -+ and the enumeration speed of the device. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_dev_init_spd(ifxusb_core_if_t *_core_if) -+{ -+ uint32_t val; -+ dcfg_data_t dcfg; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ if (_core_if->params.speed == IFXUSB_PARAM_SPEED_FULL) -+ /* High speed PHY running at full speed */ -+ val = 0x1; -+ else -+ /* High speed PHY running at high speed and full speed*/ -+ val = 0x0; -+ -+ IFX_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val); -+ dcfg.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dcfg); -+ dcfg.b.devspd = val; -+ ifxusb_wreg(&_core_if->dev_global_regs->dcfg, dcfg.d32); -+} -+ -+ -+/*! -+ \brief This function enables the Device mode interrupts. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if) -+{ -+ gint_data_t intr_mask ={ .d32 = 0}; -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__); -+ -+ /* Clear any pending OTG Interrupts */ -+ ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF); -+ -+ /* Clear any pending interrupts */ -+ ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF); -+ -+ /* Enable the interrupts in the GINTMSK.*/ -+ intr_mask.b.modemismatch = 1; -+ intr_mask.b.conidstschng = 1; -+ intr_mask.b.wkupintr = 1; -+ intr_mask.b.disconnect = 1; -+ intr_mask.b.usbsuspend = 1; -+ -+ intr_mask.b.usbreset = 1; -+ intr_mask.b.enumdone = 1; -+ intr_mask.b.inepintr = 1; -+ intr_mask.b.outepintr = 1; -+ intr_mask.b.erlysuspend = 1; -+ #ifndef __DED_FIFO__ -+// intr_mask.b.epmismatch = 1; -+ #endif -+ -+ ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32); -+ IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk)); -+} -+ -+/*! -+ \brief Gets the current USB frame number. This is the frame number from the last SOF packet. -+ \param _core_if Pointer of core_if structure -+ */ -+uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if) -+{ -+ dsts_data_t dsts; -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ dsts.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dsts); -+ /* read current frame/microfreme number from DSTS register */ -+ return dsts.b.soffn; -+} -+ -+ -+/*! -+ \brief Set the EP STALL. -+ */ -+void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in) -+{ -+ depctl_data_t depctl; -+ volatile uint32_t *depctl_addr; -+ -+ IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT")); -+ -+ depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)): -+ (&(_core_if->out_ep_regs[_epno]->doepctl)); -+ depctl.d32 = ifxusb_rreg(depctl_addr); -+ depctl.b.stall = 1; -+ -+ if (_is_in && depctl.b.epena) -+ depctl.b.epdis = 1; -+ -+ ifxusb_wreg(depctl_addr, depctl.d32); -+ IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr)); -+ return; -+} -+ -+/*! -+\brief Clear the EP STALL. -+ */ -+void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in) -+{ -+ depctl_data_t depctl; -+ volatile uint32_t *depctl_addr; -+ -+ IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT")); -+ -+ depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)): -+ (&(_core_if->out_ep_regs[_epno]->doepctl)); -+ -+ depctl.d32 = ifxusb_rreg(depctl_addr); -+ /* clear the stall bits */ -+ depctl.b.stall = 0; -+ -+ /* -+ * USB Spec 9.4.5: For endpoints using data toggle, regardless -+ * of whether an endpoint has the Halt feature set, a -+ * ClearFeature(ENDPOINT_HALT) request always results in the -+ * data toggle being reinitialized to DATA0. -+ */ -+ if (_ep_type == IFXUSB_EP_TYPE_INTR || _ep_type == IFXUSB_EP_TYPE_BULK) -+ depctl.b.setd0pid = 1; /* DATA0 */ -+ -+ ifxusb_wreg(depctl_addr, depctl.d32); -+ IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr)); -+ return; -+} -+ -+/*! -+ \brief This function initializes the IFXUSB controller registers for Device mode. -+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the -+ request queues. -+ \param _core_if Pointer of core_if structure -+ \param _params parameters to be set -+ */ -+void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ -+ gusbcfg_data_t usbcfg ={.d32 = 0}; -+ gahbcfg_data_t ahbcfg ={.d32 = 0}; -+ dcfg_data_t dcfg ={.d32 = 0}; -+ grstctl_t resetctl ={.d32 = 0}; -+ gotgctl_data_t gotgctl ={.d32 = 0}; -+ -+ uint32_t dir; -+ int i; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if); -+ -+ /* Copy Params */ -+ _core_if->params.dma_burst_size = _params->dma_burst_size; -+ _core_if->params.speed = _params->speed; -+ if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) ) -+ _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1); -+ else -+ _core_if->params.max_transfer_size = _params->max_transfer_size; -+ -+ if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) ) -+ _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1); -+ else -+ _core_if->params.max_packet_count= _params->max_packet_count; -+ _core_if->params.phy_utmi_width = _params->phy_utmi_width; -+ _core_if->params.turn_around_time_hs = _params->turn_around_time_hs; -+ _core_if->params.turn_around_time_fs = _params->turn_around_time_fs; -+ _core_if->params.timeout_cal_hs = _params->timeout_cal_hs; -+ _core_if->params.timeout_cal_fs = _params->timeout_cal_fs; -+ -+ #ifdef __DED_FIFO__ -+ _core_if->params.thr_ctl = _params->thr_ctl; -+ _core_if->params.tx_thr_length = _params->tx_thr_length; -+ _core_if->params.rx_thr_length = _params->rx_thr_length; -+ #endif -+ -+ /* Reset the Controller */ -+ do -+ { -+ while(ifxusb_core_soft_reset( _core_if )) -+ ifxusb_hard_reset(_core_if); -+ } while (ifxusb_is_host_mode(_core_if)); -+ -+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); -+ #if 0 -+ #if defined(__DED_FIFO__) -+ usbcfg.b.ForceDevMode = 1; -+ usbcfg.b.ForceHstMode = 0; -+ #endif -+ #endif -+ usbcfg.b.term_sel_dl_pulse = 0; -+ ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* This programming sequence needs to happen in FS mode before any other -+ * programming occurs */ -+ /* High speed PHY. */ -+ if (!_core_if->phy_init_done) -+ { -+ _core_if->phy_init_done = 1; -+ /* HS PHY parameters. These parameters are preserved -+ * during soft reset so only program the first time. Do -+ * a soft reset immediately after setting phyif. */ -+ usbcfg.b.ulpi_utmi_sel = 0; //UTMI+ -+ usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0; -+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); -+ /* Reset after setting the PHY parameters */ -+ ifxusb_core_soft_reset( _core_if ); -+ } -+ -+ /* Program the GAHBCFG Register.*/ -+ switch (_core_if->params.dma_burst_size) -+ { -+ case 0 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE; -+ break; -+ case 1 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR; -+ break; -+ case 4 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4; -+ break; -+ case 8 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8; -+ break; -+ case 16: -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16; -+ break; -+ } -+ ahbcfg.b.dmaenable = 1; -+ ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32); -+ -+ /* Program the GUSBCFG register. */ -+ usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg ); -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = 0; -+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Restart the Phy Clock */ -+ ifxusb_wreg(_core_if->pcgcctl, 0); -+ -+ /* Device configuration register */ -+ ifxusb_dev_init_spd(_core_if); -+ dcfg.d32 = ifxusb_rreg( &_core_if->dev_global_regs->dcfg); -+ dcfg.b.perfrint = IFXUSB_DCFG_FRAME_INTERVAL_80; -+ #if defined(__DED_FIFO__) -+ #if defined(__DESC_DMA__) -+ dcfg.b.descdma = 1; -+ #else -+ dcfg.b.descdma = 0; -+ #endif -+ #endif -+ -+ ifxusb_wreg( &_core_if->dev_global_regs->dcfg, dcfg.d32 ); -+ -+ /* Configure data FIFO sizes */ -+ _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth; -+ _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz); -+ IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); -+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size); -+ -+ _core_if->params.tx_fifo_size[0]= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16; -+ -+ #ifdef __DED_FIFO__ -+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++) -+ _core_if->params.tx_fifo_size[i] = -+ ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]) >> 16; -+ #else -+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) -+ _core_if->params.tx_fifo_size[i+1] = -+ ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]) >> 16; -+ #endif -+ -+ #ifdef __DEBUG__ -+ #ifdef __DED_FIFO__ -+ for (i=0; i <= _core_if->hwcfg4.b.num_in_eps; i++) -+ IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i]); -+ #else -+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.tx_fifo_size[0]); -+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) -+ IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i+1]); -+ #endif -+ #endif -+ -+ { -+ fifosize_data_t txfifosize; -+ if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size) -+ _core_if->params.data_fifo_size = _params->data_fifo_size; -+ -+ -+ if(_params->rx_fifo_size >=0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size) -+ _core_if->params.rx_fifo_size = _params->rx_fifo_size; -+ if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size) -+ _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size; -+ ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size); -+ -+ for (i=0; i < MAX_EPS_CHANNELS; i++) -+ if(_params->tx_fifo_size[i] >=0 && _params->tx_fifo_size[i] < _core_if->params.tx_fifo_size[i]) -+ _core_if->params.tx_fifo_size[i] = _params->tx_fifo_size[i]; -+ -+ txfifosize.b.startaddr = _core_if->params.rx_fifo_size; -+ #ifdef __DED_FIFO__ -+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size) -+ _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ txfifosize.b.depth=_core_if->params.tx_fifo_size[0]; -+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0]; -+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++) -+ { -+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i] > _core_if->params.data_fifo_size) -+ _core_if->params.tx_fifo_size[i]= _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ txfifosize.b.depth=_core_if->params.tx_fifo_size[i]; -+ ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i-1], txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i]; -+ } -+ #else -+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size) -+ _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ txfifosize.b.depth=_core_if->params.tx_fifo_size[0]; -+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0]; -+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) -+ { -+ if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i+1] > _core_if->params.data_fifo_size) -+ _core_if->params.tx_fifo_size[i+1]= _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ //txfifosize.b.depth=_core_if->params.tx_fifo_size[i+1]; -+ ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i], txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i+1]; -+ } -+ #endif -+ } -+ -+ #ifdef __DEBUG__ -+ { -+ fifosize_data_t fifosize; -+ IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); -+ -+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X Sz=0x%06X\n", 0,ifxusb_rreg(&global_regs->grxfsiz)); -+ #ifdef __DED_FIFO__ -+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz); -+ IFX_DEBUGPL(DBG_CIL, " Tx[00] FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); -+ for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++) -+ { -+ fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]); -+ IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth); -+ } -+ #else -+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz); -+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); -+ for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) -+ { -+ fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]); -+ IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth); -+ } -+ #endif -+ } -+ #endif -+ -+ /* Clear Host Set HNP Enable in the OTG Control Register */ -+ gotgctl.b.hstsethnpen = 1; -+ ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0); -+ -+ /* Flush the FIFOs */ -+ ifxusb_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */ -+ ifxusb_flush_rx_fifo(_core_if); -+ -+ /* Flush the Learning Queue. */ -+ resetctl.b.intknqflsh = 1; -+ ifxusb_wreg( &global_regs->grstctl, resetctl.d32); -+ -+ /* Clear all pending Device Interrupts */ -+ ifxusb_wreg( &_core_if->dev_global_regs->diepmsk , 0 ); -+ ifxusb_wreg( &_core_if->dev_global_regs->doepmsk , 0 ); -+ ifxusb_wreg( &_core_if->dev_global_regs->daint , 0xFFFFFFFF ); -+ ifxusb_wreg( &_core_if->dev_global_regs->daintmsk, 0 ); -+ -+ dir=_core_if->hwcfg1.d32; -+ for (i=0; i <= _core_if->hwcfg2.b.num_dev_ep ; i++,dir>>=2) -+ { -+ depctl_data_t depctl; -+ if((dir&0x03)==0 || (dir&0x03) ==1) -+ { -+ depctl.d32 = ifxusb_rreg(&_core_if->in_ep_regs[i]->diepctl); -+ if (depctl.b.epena) -+ { -+ depctl.d32 = 0; -+ depctl.b.epdis = 1; -+ depctl.b.snak = 1; -+ } -+ else -+ depctl.d32 = 0; -+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepctl, depctl.d32); -+ #ifndef __DESC_DMA__ -+ ifxusb_wreg( &_core_if->in_ep_regs[i]->dieptsiz, 0); -+ #endif -+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepdma, 0); -+ ifxusb_wreg( &_core_if->in_ep_regs[i]->diepint, 0xFF); -+ } -+ -+ if((dir&0x03)==0 || (dir&0x03) ==2) -+ { -+ depctl.d32 = ifxusb_rreg(&_core_if->out_ep_regs[i]->doepctl); -+ if (depctl.b.epena) -+ { -+ depctl.d32 = 0; -+ depctl.b.epdis = 1; -+ depctl.b.snak = 1; -+ } -+ else -+ depctl.d32 = 0; -+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepctl, depctl.d32); -+ #ifndef __DESC_DMA__ -+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doeptsiz, 0); -+ #endif -+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepdma, 0); -+ ifxusb_wreg( &_core_if->out_ep_regs[i]->doepint, 0xFF); -+ } -+ } -+} -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_cif_h.c -@@ -0,0 +1,846 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_cif_h.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The Core Interface provides basic services for accessing and -+ ** managing the IFX USB hardware. These services are used by the -+ ** Host Controller Driver only. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxusb_cif_h.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the interface to the IFX USB Core. -+*/ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <asm/byteorder.h> -+#include <asm/unaligned.h> -+ -+#ifdef __DEBUG__ -+ #include <linux/jiffies.h> -+#endif -+#include <linux/platform_device.h> -+#include <linux/kernel.h> -+#include <linux/ioport.h> -+#if defined(__UEIP__) -+// #include <asm/ifx/ifx_board.h> -+#endif -+ -+//#include <asm/ifx/ifx_gpio.h> -+#if defined(__UEIP__) -+// #include <asm/ifx/ifx_led.h> -+#endif -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+ -+#include "ifxhcd.h" -+ -+#if !defined(__UEIP__) -+ #undef __USING_LED_AS_GPIO__ -+#endif -+ -+ -+/*! -+ \brief This function enables the Host mode interrupts. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_host_enable_interrupts(ifxusb_core_if_t *_core_if) -+{ -+ gint_data_t intr_mask ={ .d32 = 0}; -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ -+ IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__); -+ -+ /* Clear any pending OTG Interrupts */ -+ ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF); -+ -+ /* Clear any pending interrupts */ -+ ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF); -+ -+ /* Enable the interrupts in the GINTMSK.*/ -+ -+ /* Common interrupts */ -+ intr_mask.b.modemismatch = 1; -+ intr_mask.b.conidstschng = 1; -+ intr_mask.b.wkupintr = 1; -+ intr_mask.b.disconnect = 1; -+ intr_mask.b.usbsuspend = 1; -+ -+ /* Host interrupts */ -+ intr_mask.b.sofintr = 1; -+ intr_mask.b.portintr = 1; -+ intr_mask.b.hcintr = 1; -+ -+ ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32); -+ IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk)); -+} -+ -+/*! -+ \brief This function disables the Host mode interrupts. -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_host_disable_interrupts(ifxusb_core_if_t *_core_if) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ -+ IFX_DEBUGPL(DBG_CILV, "%s()\n", __func__); -+ -+ #if 1 -+ ifxusb_wreg( &global_regs->gintmsk, 0); -+ #else -+ /* Common interrupts */ -+ { -+ gint_data_t intr_mask ={.d32 = 0}; -+ intr_mask.b.modemismatch = 1; -+ intr_mask.b.rxstsqlvl = 1; -+ intr_mask.b.conidstschng = 1; -+ intr_mask.b.wkupintr = 1; -+ intr_mask.b.disconnect = 1; -+ intr_mask.b.usbsuspend = 1; -+ -+ /* Host interrupts */ -+ intr_mask.b.sofintr = 1; -+ intr_mask.b.portintr = 1; -+ intr_mask.b.hcintr = 1; -+ intr_mask.b.ptxfempty = 1; -+ intr_mask.b.nptxfempty = 1; -+ ifxusb_mreg(&global_regs->gintmsk, intr_mask.d32, 0); -+ } -+ #endif -+} -+ -+/*! -+ \brief This function initializes the IFXUSB controller registers for Host mode. -+ This function flushes the Tx and Rx FIFOs and it flushes any entries in the -+ request queues. -+ \param _core_if Pointer of core_if structure -+ \param _params parameters to be set -+ */ -+void ifxusb_host_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params) -+{ -+ ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs; -+ -+ gusbcfg_data_t usbcfg ={.d32 = 0}; -+ gahbcfg_data_t ahbcfg ={.d32 = 0}; -+ gotgctl_data_t gotgctl ={.d32 = 0}; -+ -+ int i; -+ -+ IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if); -+ -+ /* Copy Params */ -+ -+ _core_if->params.dma_burst_size = _params->dma_burst_size; -+ _core_if->params.speed = _params->speed; -+ _core_if->params.max_transfer_size = _params->max_transfer_size; -+ _core_if->params.max_packet_count = _params->max_packet_count; -+ _core_if->params.phy_utmi_width = _params->phy_utmi_width; -+ _core_if->params.turn_around_time_hs = _params->turn_around_time_hs; -+ _core_if->params.turn_around_time_fs = _params->turn_around_time_fs; -+ _core_if->params.timeout_cal_hs = _params->timeout_cal_hs; -+ _core_if->params.timeout_cal_fs = _params->timeout_cal_fs; -+ -+ /* Reset the Controller */ -+ do -+ { -+ while(ifxusb_core_soft_reset( _core_if )) -+ ifxusb_hard_reset(_core_if); -+ } while (ifxusb_is_device_mode(_core_if)); -+ -+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); -+// usbcfg.b.ulpi_ext_vbus_drv = 1; -+ usbcfg.b.term_sel_dl_pulse = 0; -+ ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* This programming sequence needs to happen in FS mode before any other -+ * programming occurs */ -+ /* High speed PHY. */ -+ if (!_core_if->phy_init_done) -+ { -+ _core_if->phy_init_done = 1; -+ /* HS PHY parameters. These parameters are preserved -+ * during soft reset so only program the first time. Do -+ * a soft reset immediately after setting phyif. */ -+ usbcfg.b.ulpi_utmi_sel = 0; //UTMI+ -+ usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0; -+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); -+ /* Reset after setting the PHY parameters */ -+ ifxusb_core_soft_reset( _core_if ); -+ } -+ -+ usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg); -+// usbcfg.b.ulpi_fsls = 0; -+// usbcfg.b.ulpi_clk_sus_m = 0; -+ ifxusb_wreg(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Program the GAHBCFG Register.*/ -+ switch (_core_if->params.dma_burst_size) -+ { -+ case 0 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE; -+ break; -+ case 1 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR; -+ break; -+ case 4 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4; -+ break; -+ case 8 : -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8; -+ break; -+ case 16: -+ ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16; -+ break; -+ } -+ ahbcfg.b.dmaenable = 1; -+ ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32); -+ -+ /* Program the GUSBCFG register. */ -+ usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg ); -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = 0; -+ ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Restart the Phy Clock */ -+ ifxusb_wreg(_core_if->pcgcctl, 0); -+ -+ /* Initialize Host Configuration Register */ -+ { -+ hcfg_data_t hcfg; -+ hcfg.d32 = ifxusb_rreg(&_core_if->host_global_regs->hcfg); -+ hcfg.b.fslspclksel = IFXUSB_HCFG_30_60_MHZ; -+ if (_params->speed == IFXUSB_PARAM_SPEED_FULL) -+ hcfg.b.fslssupp = 1; -+ ifxusb_wreg(&_core_if->host_global_regs->hcfg, hcfg.d32); -+ } -+ -+ _core_if->params.host_channels=(_core_if->hwcfg2.b.num_host_chan + 1); -+ -+ if(_params->host_channels>0 && _params->host_channels < _core_if->params.host_channels) -+ _core_if->params.host_channels = _params->host_channels; -+ -+ /* Configure data FIFO sizes */ -+ _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth; -+ _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz); -+ _core_if->params.nperio_tx_fifo_size= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16; -+ _core_if->params.perio_tx_fifo_size = ifxusb_rreg(&global_regs->hptxfsiz) >> 16; -+ IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); -+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size); -+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.nperio_tx_fifo_size); -+ IFX_DEBUGPL(DBG_CIL, " PTx FIFO Size=0x%06X\n", _core_if->params.perio_tx_fifo_size); -+ -+ { -+ fifosize_data_t txfifosize; -+ if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size) -+ _core_if->params.data_fifo_size = _params->data_fifo_size; -+ -+ if( _params->rx_fifo_size >= 0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size) -+ _core_if->params.rx_fifo_size = _params->rx_fifo_size; -+ if( _params->nperio_tx_fifo_size >=0 && _params->nperio_tx_fifo_size < _core_if->params.nperio_tx_fifo_size) -+ _core_if->params.nperio_tx_fifo_size = _params->nperio_tx_fifo_size; -+ if( _params->perio_tx_fifo_size >=0 && _params->perio_tx_fifo_size < _core_if->params.perio_tx_fifo_size) -+ _core_if->params.perio_tx_fifo_size = _params->perio_tx_fifo_size; -+ -+ if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size) -+ _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size; -+ ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size); -+ txfifosize.b.startaddr = _core_if->params.rx_fifo_size; -+ -+ if(txfifosize.b.startaddr + _core_if->params.nperio_tx_fifo_size > _core_if->params.data_fifo_size) -+ _core_if->params.nperio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ txfifosize.b.depth=_core_if->params.nperio_tx_fifo_size; -+ ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.nperio_tx_fifo_size; -+ -+ if(txfifosize.b.startaddr + _core_if->params.perio_tx_fifo_size > _core_if->params.data_fifo_size) -+ _core_if->params.perio_tx_fifo_size = _core_if->params.data_fifo_size - txfifosize.b.startaddr; -+ txfifosize.b.depth=_core_if->params.perio_tx_fifo_size; -+ ifxusb_wreg( &global_regs->hptxfsiz, txfifosize.d32); -+ txfifosize.b.startaddr += _core_if->params.perio_tx_fifo_size; -+ } -+ -+ #ifdef __DEBUG__ -+ { -+ fifosize_data_t fifosize; -+ IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size); -+ -+ fifosize.d32=ifxusb_rreg(&global_regs->grxfsiz); -+ IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); -+ fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz); -+ IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); -+ fifosize.d32=ifxusb_rreg(&global_regs->hptxfsiz); -+ IFX_DEBUGPL(DBG_CIL, " PTx FIFO =0x%06X 0x%06X\n", fifosize.b.startaddr,fifosize.b.depth); -+ } -+ #endif -+ -+ /* Clear Host Set HNP Enable in the OTG Control Register */ -+ gotgctl.b.hstsethnpen = 1; -+ ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0); -+ -+ /* Flush the FIFOs */ -+ ifxusb_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */ -+ ifxusb_flush_rx_fifo(_core_if); -+ -+ for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++) -+ { -+ hcchar_data_t hcchar; -+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); -+ hcchar.b.chen = 0; -+ hcchar.b.chdis = 1; -+ hcchar.b.epdir = 0; -+ ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32); -+ } -+ /* Halt all channels to put them into a known state. */ -+ for (i = 0; i < _core_if->hwcfg2.b.num_host_chan + 1; i++) -+ { -+ hcchar_data_t hcchar; -+ int count = 0; -+ -+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 1; -+ hcchar.b.epdir = 0; -+ ifxusb_wreg(&_core_if->hc_regs[i]->hcchar, hcchar.d32); -+ -+ IFX_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i); -+ do{ -+ hcchar.d32 = ifxusb_rreg(&_core_if->hc_regs[i]->hcchar); -+ if (++count > 1000) -+ { -+ IFX_ERROR("%s: Unable to clear halt on channel %d\n", __func__, i); -+ break; -+ } -+ } while (hcchar.b.chen); -+ } -+} -+ -+////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#if defined(__UEIP__) -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ int ifxusb_vbus_status =-1; -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ int ifxusb_vbus1_status =-1; -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ int ifxusb_vbus2_status =-1; -+ #endif -+ -+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ static void *g_usb_vbus_trigger = NULL; -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ static void *g_usb_vbus1_trigger = NULL; -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ static void *g_usb_vbus2_trigger = NULL; -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ int ifxusb_vbus_gpio_inited=0; -+ #endif -+ -+#else //defined(__UEIP__) -+ int ifxusb_vbus_gpio_inited=0; -+#endif -+ -+////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+void ifxusb_vbus_init(ifxusb_core_if_t *_core_if) -+{ -+ #if defined(__UEIP__) -+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ if ( !g_usb_vbus_trigger ) -+ { -+ ifx_led_trigger_register("USB_VBUS", &g_usb_vbus_trigger); -+ if ( g_usb_vbus_trigger != NULL ) -+ { -+ struct ifx_led_trigger_attrib attrib = {0}; -+ attrib.delay_on = 0; -+ attrib.delay_off = 0; -+ attrib.timeout = 0; -+ attrib.def_value = 0; -+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; -+ IFX_DEBUGP("Reg USB power!!\n"); -+ ifx_led_trigger_set_attrib(g_usb_vbus_trigger, &attrib); -+ ifxusb_vbus_status =0; -+ } -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ if(_core_if->core_no==0 && !g_usb_vbus1_trigger ) -+ { -+ ifx_led_trigger_register("USB_VBUS1", &g_usb_vbus1_trigger); -+ if ( g_usb_vbus1_trigger != NULL ) -+ { -+ struct ifx_led_trigger_attrib attrib = {0}; -+ attrib.delay_on = 0; -+ attrib.delay_off = 0; -+ attrib.timeout = 0; -+ attrib.def_value = 0; -+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; -+ IFX_DEBUGP("Reg USB1 power!!\n"); -+ ifx_led_trigger_set_attrib(g_usb_vbus1_trigger, &attrib); -+ ifxusb_vbus1_status =0; -+ } -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ if(_core_if->core_no==1 && !g_usb_vbus2_trigger ) -+ { -+ ifx_led_trigger_register("USB_VBUS2", &g_usb_vbus2_trigger); -+ if ( g_usb_vbus2_trigger != NULL ) -+ { -+ struct ifx_led_trigger_attrib attrib = {0}; -+ attrib.delay_on = 0; -+ attrib.delay_off = 0; -+ attrib.timeout = 0; -+ attrib.def_value = 0; -+ attrib.flags = IFX_LED_TRIGGER_ATTRIB_DELAY_ON | IFX_LED_TRIGGER_ATTRIB_DELAY_OFF | IFX_LED_TRIGGER_ATTRIB_TIMEOUT | IFX_LED_TRIGGER_ATTRIB_DEF_VALUE; -+ IFX_DEBUGP("Reg USB2 power!!\n"); -+ ifx_led_trigger_set_attrib(g_usb_vbus2_trigger, &attrib); -+ ifxusb_vbus2_status =0; -+ } -+ } -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ /* == 20100712 AVM/WK use gpio_inited as bitmask == */ -+ if(ifxusb_vbus_gpio_inited == 0) -+ { -+ if(!ifx_gpio_register(IFX_GPIO_MODULE_USB)) -+ { -+ IFX_DEBUGP("Register USB VBus through GPIO OK!!\n"); -+ #ifdef IFX_GPIO_USB_VBUS -+ ifxusb_vbus_status =0; -+ #endif //IFX_GPIO_USB_VBUS -+ #ifdef IFX_GPIO_USB_VBUS1 -+ ifxusb_vbus1_status=0; -+ #endif //IFX_GPIO_USB_VBUS1 -+ #ifdef IFX_GPIO_USB_VBUS2 -+ ifxusb_vbus2_status=0; -+ #endif //IFX_GPIO_USB_VBUS2 -+ ifxusb_vbus_gpio_inited|= (1<<_core_if->core_no); -+ } -+ else -+ IFX_PRINT("Register USB VBus Failed!!\n"); -+ } else { -+ ifxusb_vbus_gpio_inited|= (1<<_core_if->core_no); -+ } -+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ #endif //defined(__UEIP__) -+} -+ -+void ifxusb_vbus_free(ifxusb_core_if_t *_core_if) -+{ -+ #if defined(__UEIP__) -+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ if ( g_usb_vbus_trigger ) -+ { -+ ifx_led_trigger_deregister(g_usb_vbus_trigger); -+ g_usb_vbus_trigger = NULL; -+ ifxusb_vbus_status =-1; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ if(_core_if->core_no==0 && g_usb_vbus1_trigger ) -+ { -+ ifx_led_trigger_deregister(g_usb_vbus1_trigger); -+ g_usb_vbus1_trigger = NULL; -+ ifxusb_vbus1_status =-1; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ if(_core_if->core_no==1 && g_usb_vbus2_trigger ) -+ { -+ ifx_led_trigger_deregister(g_usb_vbus2_trigger); -+ g_usb_vbus2_trigger = NULL; -+ ifxusb_vbus2_status =-1; -+ } -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ /* == 20100712 AVM/WK use gpio_inited as bitmask == */ -+ if((ifxusb_vbus_gpio_inited & (1<<_core_if->core_no)) == ifxusb_vbus_gpio_inited) -+ { -+ ifx_gpio_deregister(IFX_GPIO_MODULE_USB); -+ #ifdef IFX_GPIO_USB_VBUS -+ ifxusb_vbus_status =-1; -+ #endif //IFX_GPIO_USB_VBUS -+ #ifdef IFX_GPIO_USB_VBUS1 -+ ifxusb_vbus1_status=-1; -+ #endif //IFX_GPIO_USB_VBUS1 -+ #ifdef IFX_GPIO_USB_VBUS2 -+ ifxusb_vbus2_status=-1; -+ #endif //IFX_GPIO_USB_VBUS2 -+ } -+ ifxusb_vbus_gpio_inited &= ~(1<<_core_if->core_no); -+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ #endif //defined(__UEIP__) -+} -+ -+ -+/*! -+ \brief Turn on the USB 5V VBus Power -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_vbus_on(ifxusb_core_if_t *_core_if) -+{ -+ IFX_DEBUGP("SENDING VBus POWER UP\n"); -+ #if defined(__UEIP__) -+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ if ( g_usb_vbus_trigger && ifxusb_vbus_status==0) -+ { -+ ifx_led_trigger_activate(g_usb_vbus_trigger); -+ IFX_DEBUGP("Enable USB power!!\n"); -+ ifxusb_vbus_status=1; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==0) -+ { -+ ifx_led_trigger_activate(g_usb_vbus1_trigger); -+ IFX_DEBUGP("Enable USB1 power!!\n"); -+ ifxusb_vbus1_status=1; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==0) -+ { -+ ifx_led_trigger_activate(g_usb_vbus2_trigger); -+ IFX_DEBUGP("Enable USB2 power!!\n"); -+ ifxusb_vbus2_status=1; -+ } -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ if(ifxusb_vbus_gpio_inited) -+ { -+ #if defined(IFX_GPIO_USB_VBUS) -+ if(ifxusb_vbus_status==0) -+ { -+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus_status=1; -+ } -+ #endif -+ #if defined(IFX_GPIO_USB_VBUS1) -+ if(_core_if->core_no==0 && ifxusb_vbus1_status==0) -+ { -+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus1_status=1; -+ } -+ #endif -+ #if defined(IFX_GPIO_USB_VBUS2) -+ if(_core_if->core_no==1 && ifxusb_vbus2_status==0) -+ { -+ ifx_gpio_output_set(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus2_status=1; -+ } -+ #endif -+ } -+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ #else -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_vbus_status=1; -+ //usb_set_vbus_on(); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ set_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT); -+ ifxusb_vbus_status=1; -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) -+ { -+ IFX_PRINT("Can't enable USB1 5.5V power!!\n"); -+ return; -+ } -+ bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB); -+ bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB); -+ bsp_port_set_dir_out(1, 13, PORT_MODULE_USB); -+ bsp_port_set_pudsel(1, 13, PORT_MODULE_USB); -+ bsp_port_set_puden(1, 13, PORT_MODULE_USB); -+ bsp_port_set_output(1, 13, PORT_MODULE_USB); -+ IFX_DEBUGP("Enable USB1 power!!\n"); -+ ifxusb_vbus1_status=1; -+ } -+ else -+ { -+ if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) -+ { -+ IFX_PRINT("Can't enable USB2 5.5V power!!\n"); -+ return; -+ } -+ bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB); -+ bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB); -+ bsp_port_set_dir_out(3, 4, PORT_MODULE_USB); -+ bsp_port_set_pudsel(3, 4, PORT_MODULE_USB); -+ bsp_port_set_puden(3, 4, PORT_MODULE_USB); -+ bsp_port_set_output(3, 4, PORT_MODULE_USB); -+ IFX_DEBUGP("Enable USB2 power!!\n"); -+ ifxusb_vbus2_status=1; -+ } -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ { -+ ifxusb_vbus1_status=1; -+ } -+ else -+ { -+ ifxusb_vbus2_status=1; -+ } -+ #endif //defined(__IS_VR9__) -+ #endif //defined(__UEIP__) -+} -+ -+ -+/*! -+ \brief Turn off the USB 5V VBus Power -+ \param _core_if Pointer of core_if structure -+ */ -+void ifxusb_vbus_off(ifxusb_core_if_t *_core_if) -+{ -+ IFX_DEBUGP("SENDING VBus POWER OFF\n"); -+ -+ #if defined(__UEIP__) -+ #if defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ if ( g_usb_vbus_trigger && ifxusb_vbus_status==1) -+ { -+ ifx_led_trigger_deactivate(g_usb_vbus_trigger); -+ IFX_DEBUGP("Disable USB power!!\n"); -+ ifxusb_vbus_status=0; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ if(_core_if->core_no==0 && g_usb_vbus1_trigger && ifxusb_vbus1_status==1) -+ { -+ ifx_led_trigger_deactivate(g_usb_vbus1_trigger); -+ IFX_DEBUGP("Disable USB1 power!!\n"); -+ ifxusb_vbus1_status=0; -+ } -+ #endif -+ #if defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ if(_core_if->core_no==1 && g_usb_vbus2_trigger && ifxusb_vbus2_status==1) -+ { -+ ifx_led_trigger_deactivate(g_usb_vbus2_trigger); -+ IFX_DEBUGP("Disable USB2 power!!\n"); -+ ifxusb_vbus2_status=0; -+ } -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ if(ifxusb_vbus_gpio_inited) -+ { -+ #if defined(IFX_GPIO_USB_VBUS) -+ if(ifxusb_vbus_status==1) -+ { -+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus_status=0; -+ } -+ #endif -+ #if defined(IFX_GPIO_USB_VBUS1) -+ if(_core_if->core_no==0 && ifxusb_vbus1_status==1) -+ { -+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS1,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus1_status=0; -+ } -+ #endif -+ #if defined(IFX_GPIO_USB_VBUS2) -+ if(_core_if->core_no==1 && ifxusb_vbus2_status==1) -+ { -+ ifx_gpio_output_clear(IFX_GPIO_USB_VBUS2,IFX_GPIO_MODULE_USB); -+ ifxusb_vbus2_status=0; -+ } -+ #endif -+ } -+ #endif //defined(IFX_GPIO_USB_VBUS) || defined(IFX_GPIO_USB_VBUS1) || defined(IFX_GPIO_USB_VBUS2) -+ #else -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ ifxusb_vbus_status=0; -+ //usb_set_vbus_on(); -+ #endif //defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+ #if defined(__IS_AMAZON_SE__) -+ clear_bit (4, (volatile unsigned long *)AMAZON_SE_GPIO_P0_OUT); -+ ifxusb_vbus_status=0; -+ #endif //defined(__IS_AMAZON_SE__) -+ #if defined(__IS_AR9__) -+ if(_core_if->core_no==0) -+ { -+ if (bsp_port_reserve_pin(1, 13, PORT_MODULE_USB) != 0) { -+ IFX_PRINT("Can't Disable USB1 5.5V power!!\n"); -+ return; -+ } -+ bsp_port_clear_altsel0(1, 13, PORT_MODULE_USB); -+ bsp_port_clear_altsel1(1, 13, PORT_MODULE_USB); -+ bsp_port_set_dir_out(1, 13, PORT_MODULE_USB); -+ bsp_port_set_pudsel(1, 13, PORT_MODULE_USB); -+ bsp_port_set_puden(1, 13, PORT_MODULE_USB); -+ bsp_port_clear_output(1, 13, PORT_MODULE_USB); -+ IFX_DEBUGP("Disable USB1 power!!\n"); -+ ifxusb_vbus1_status=0; -+ } -+ else -+ { -+ if (bsp_port_reserve_pin(3, 4, PORT_MODULE_USB) != 0) { -+ IFX_PRINT("Can't Disable USB2 5.5V power!!\n"); -+ return; -+ } -+ bsp_port_clear_altsel0(3, 4, PORT_MODULE_USB); -+ bsp_port_clear_altsel1(3, 4, PORT_MODULE_USB); -+ bsp_port_set_dir_out(3, 4, PORT_MODULE_USB); -+ bsp_port_set_pudsel(3, 4, PORT_MODULE_USB); -+ bsp_port_set_puden(3, 4, PORT_MODULE_USB); -+ bsp_port_clear_output(3, 4, PORT_MODULE_USB); -+ IFX_DEBUGP("Disable USB2 power!!\n"); -+ -+ ifxusb_vbus2_status=0; -+ } -+ #endif //defined(__IS_AR9__) -+ #if defined(__IS_VR9__) -+ if(_core_if->core_no==0) -+ { -+ ifxusb_vbus1_status=0; -+ } -+ else -+ { -+ ifxusb_vbus2_status=0; -+ } -+ #endif //defined(__IS_VR9__) -+ #endif //defined(__UEIP__) -+} -+ -+ -+ -+/*! -+ \brief Read Current VBus status -+ \param _core_if Pointer of core_if structure -+ */ -+int ifxusb_vbus(ifxusb_core_if_t *_core_if) -+{ -+#if defined(__UEIP__) -+ #if defined(IFX_GPIO_USB_VBUS) || defined(IFX_LEDGPIO_USB_VBUS) || defined(IFX_LEDLED_USB_VBUS) -+ return (ifxusb_vbus_status); -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS1) || defined(IFX_LEDGPIO_USB_VBUS1) || defined(IFX_LEDLED_USB_VBUS1) -+ if(_core_if->core_no==0) -+ return (ifxusb_vbus1_status); -+ #endif -+ -+ #if defined(IFX_GPIO_USB_VBUS2) || defined(IFX_LEDGPIO_USB_VBUS2) || defined(IFX_LEDLED_USB_VBUS2) -+ if(_core_if->core_no==1) -+ return (ifxusb_vbus2_status); -+ #endif -+#else //defined(__UEIP__) -+#endif -+ return -1; -+} -+ -+#if defined(__UEIP__) -+#else -+ #if defined(__IS_TWINPASS__) -+ #define ADSL_BASE 0x20000 -+ #define CRI_BASE 0x31F00 -+ #define CRI_CCR0 CRI_BASE + 0x00 -+ #define CRI_CCR1 CRI_BASE + 0x01*4 -+ #define CRI_CDC0 CRI_BASE + 0x02*4 -+ #define CRI_CDC1 CRI_BASE + 0x03*4 -+ #define CRI_RST CRI_BASE + 0x04*4 -+ #define CRI_MASK0 CRI_BASE + 0x05*4 -+ #define CRI_MASK1 CRI_BASE + 0x06*4 -+ #define CRI_MASK2 CRI_BASE + 0x07*4 -+ #define CRI_STATUS0 CRI_BASE + 0x08*4 -+ #define CRI_STATUS1 CRI_BASE + 0x09*4 -+ #define CRI_STATUS2 CRI_BASE + 0x0A*4 -+ #define CRI_AMASK0 CRI_BASE + 0x0B*4 -+ #define CRI_AMASK1 CRI_BASE + 0x0C*4 -+ #define CRI_UPDCTL CRI_BASE + 0x0D*4 -+ #define CRI_MADST CRI_BASE + 0x0E*4 -+ // 0x0f is missing -+ #define CRI_EVENT0 CRI_BASE + 0x10*4 -+ #define CRI_EVENT1 CRI_BASE + 0x11*4 -+ #define CRI_EVENT2 CRI_BASE + 0x12*4 -+ -+ #define IRI_I_ENABLE 0x32000 -+ #define STY_SMODE 0x3c004 -+ #define AFE_TCR_0 0x3c0dc -+ #define AFE_ADDR_ADDR 0x3c0e8 -+ #define AFE_RDATA_ADDR 0x3c0ec -+ #define AFE_WDATA_ADDR 0x3c0f0 -+ #define AFE_CONFIG 0x3c0f4 -+ #define AFE_SERIAL_CFG 0x3c0fc -+ -+ #define DFE_BASE_ADDR 0xBE116000 -+ //#define DFE_BASE_ADDR 0x9E116000 -+ -+ #define MEI_FR_ARCINT_C (DFE_BASE_ADDR + 0x0000001C) -+ #define MEI_DBG_WADDR_C (DFE_BASE_ADDR + 0x00000024) -+ #define MEI_DBG_RADDR_C (DFE_BASE_ADDR + 0x00000028) -+ #define MEI_DBG_DATA_C (DFE_BASE_ADDR + 0x0000002C) -+ #define MEI_DBG_DECO_C (DFE_BASE_ADDR + 0x00000030) -+ #define MEI_DBG_MASTER_C (DFE_BASE_ADDR + 0x0000003C) -+ -+ static void WriteARCmem(uint32_t addr, uint32_t data) -+ { -+ writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C); -+ writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C ); -+ writel(addr ,(volatile uint32_t *)MEI_DBG_WADDR_C ); -+ writel(data ,(volatile uint32_t *)MEI_DBG_DATA_C ); -+ while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){}; -+ writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C); -+ IFX_DEBUGP("WriteARCmem %08x %08x\n",addr,data); -+ }; -+ -+ static uint32_t ReadARCmem(uint32_t addr) -+ { -+ u32 data; -+ writel(1 ,(volatile uint32_t *)MEI_DBG_MASTER_C); -+ writel(1 ,(volatile uint32_t *)MEI_DBG_DECO_C ); -+ writel(addr ,(volatile uint32_t *)MEI_DBG_RADDR_C ); -+ while( (ifxusb_rreg((volatile uint32_t *)MEI_FR_ARCINT_C) & 0x20) != 0x20 ){}; -+ data = ifxusb_rreg((volatile uint32_t *)MEI_DBG_DATA_C ); -+ writel(0 ,(volatile uint32_t *)MEI_DBG_MASTER_C); -+ IFX_DEBUGP("ReadARCmem %08x %08x\n",addr,data); -+ return data; -+ }; -+ -+ void ifxusb_enable_afe_oc(void) -+ { -+ /* Start the clock */ -+ WriteARCmem(CRI_UPDCTL ,0x00000008); -+ WriteARCmem(CRI_CCR0 ,0x00000014); -+ WriteARCmem(CRI_CCR1 ,0x00000500); -+ WriteARCmem(AFE_CONFIG ,0x000001c8); -+ WriteARCmem(AFE_SERIAL_CFG,0x00000016); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge -+ WriteARCmem(AFE_TCR_0 ,0x00000002); -+ //Take afe out of reset -+ WriteARCmem(AFE_CONFIG ,0x000000c0); -+ WriteARCmem(IRI_I_ENABLE ,0x00000101); -+ WriteARCmem(STY_SMODE ,0x00001980); -+ -+ ReadARCmem(CRI_UPDCTL ); -+ ReadARCmem(CRI_CCR0 ); -+ ReadARCmem(CRI_CCR1 ); -+ ReadARCmem(AFE_CONFIG ); -+ ReadARCmem(AFE_SERIAL_CFG); // (DANUBE_PCI_CFG_BASE+(1<<addrline))AFE serial interface clock & data latch edge -+ ReadARCmem(AFE_TCR_0 ); -+ ReadARCmem(AFE_CONFIG ); -+ ReadARCmem(IRI_I_ENABLE ); -+ ReadARCmem(STY_SMODE ); -+ } -+ #endif //defined(__IS_TWINPASS__) -+#endif //defined(__UEIP__) -+ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_ctl.c -@@ -0,0 +1,1385 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_ctl.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : Implementing the procfs and sysfs for IFX USB driver -+ *****************************************************************************/ -+ -+/*! \file ifxusb_ctl.c -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief Implementing the procfs and sysfs for IFX USB driver -+*/ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+ -+#include <linux/proc_fs.h> -+#include <asm/byteorder.h> -+#include <asm/unaligned.h> -+#include <asm/uaccess.h> -+ -+#include "ifxusb_plat.h" -+#include "ifxusb_regs.h" -+#include "ifxusb_cif.h" -+ -+#ifdef __IS_DEVICE__ -+ #include "ifxpcd.h" -+#endif -+ -+#ifdef __IS_HOST__ -+ #include "ifxhcd.h" -+#endif -+ -+#include <linux/device.h> -+#include <linux/platform_device.h> -+#include <linux/gfp.h> -+ -+ -+#ifdef __IS_HOST__ -+ extern char ifxusb_driver_name[]; -+ -+ #ifdef __IS_DUAL__ -+ extern ifxhcd_hcd_t ifxusb_hcd_1; -+ extern ifxhcd_hcd_t ifxusb_hcd_2; -+ extern char ifxusb_hcd_name_1[]; -+ extern char ifxusb_hcd_name_2[]; -+ #else -+ extern ifxhcd_hcd_t ifxusb_hcd; -+ extern char ifxusb_hcd_name[]; -+ #endif -+ -+#endif -+ -+#ifdef __IS_DEVICE__ -+ extern char ifxusb_driver_name[]; -+ -+ extern ifxpcd_pcd_t ifxusb_pcd; -+ extern char ifxusb_pcd_name[]; -+#endif -+ -+ -+//Attributes for sysfs (for 2.6 only) -+ -+extern struct device_attribute dev_attr_dbglevel; -+ -+#ifdef __IS_DUAL__ -+ extern struct device_attribute dev_attr_dump_params_1; -+ extern struct device_attribute dev_attr_dump_params_2; -+#else -+ extern struct device_attribute dev_attr_dump_params; -+#endif -+ -+#ifdef __IS_DUAL__ -+ extern struct device_attribute dev_attr_mode_1; -+ extern struct device_attribute dev_attr_mode_2; -+#else -+ extern struct device_attribute dev_attr_mode; -+#endif -+ -+#ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ extern struct device_attribute dev_attr_buspower_1; -+ extern struct device_attribute dev_attr_buspower_2; -+ extern struct device_attribute dev_attr_bussuspend_1; -+ extern struct device_attribute dev_attr_bussuspend_2; -+ extern struct device_attribute dev_attr_busconnected_1; -+ extern struct device_attribute dev_attr_busconnected_2; -+ extern struct device_attribute dev_attr_connectspeed_1; -+ extern struct device_attribute dev_attr_connectspeed_1; -+ #else -+ extern struct device_attribute dev_attr_buspower; -+ extern struct device_attribute dev_attr_bussuspend; -+ extern struct device_attribute dev_attr_busconnected; -+ extern struct device_attribute dev_attr_connectspeed; -+ #endif -+#endif //__IS_HOST__ -+ -+#ifdef __IS_DEVICE__ -+ extern struct device_attribute dev_attr_devspeed; -+ extern struct device_attribute dev_attr_enumspeed; -+#endif //__IS_DEVICE__ -+ -+#ifdef __ENABLE_DUMP__ -+ #ifdef __IS_DUAL__ -+ extern struct device_attribute dev_attr_dump_reg_1; -+ extern struct device_attribute dev_attr_dump_reg_2; -+ extern struct device_attribute dev_attr_dump_spram_1; -+ extern struct device_attribute dev_attr_dump_spram_2; -+ #ifdef __IS_HOST__ -+ extern struct device_attribute dev_attr_dump_host_state_1; -+ extern struct device_attribute dev_attr_dump_host_state_2; -+ #else -+ #endif -+ #else -+ extern struct device_attribute dev_attr_dump_reg; -+ extern struct device_attribute dev_attr_dump_spram; -+ #ifdef __IS_HOST__ -+ extern struct device_attribute dev_attr_dump_host_state; -+ #else -+ #endif -+ #endif -+#endif //__ENABLE_DUMP__ -+ -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+static ssize_t procfs_dbglevel_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+{ -+ #ifdef __IS_HOST__ -+ return sprintf( buf, "%08X\n",h_dbg_lvl ); -+ #else -+ return sprintf( buf, "%08X\n",d_dbg_lvl ); -+ #endif -+} -+ -+static ssize_t procfs_dbglevel_store(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ #ifdef __IS_HOST__ -+ h_dbg_lvl =value; -+ #else -+ d_dbg_lvl =value; -+ #endif -+ //turn on and off power -+ return count; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dbglevel_show( struct device *_dev, struct device_attribute *attr,char *buf) -+#else -+ static ssize_t sysfs_dbglevel_show( struct device *_dev, char *buf) -+#endif -+{ -+ #ifdef __IS_HOST__ -+ return sprintf( buf, "%08X\n",h_dbg_lvl ); -+ #else -+ return sprintf( buf, "%08X\n",d_dbg_lvl ); -+ #endif -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dbglevel_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count ) -+#else -+ static ssize_t sysfs_dbglevel_store( struct device *_dev, const char *buffer, size_t count ) -+#endif -+{ -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ #ifdef __IS_HOST__ -+ h_dbg_lvl =value; -+ #else -+ d_dbg_lvl =value; -+ #endif -+ //turn on and off power -+ return count; -+} -+ -+DEVICE_ATTR(dbglevel, S_IRUGO|S_IWUSR, sysfs_dbglevel_show, sysfs_dbglevel_store); -+ -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+static void ifxusb_dump_params(ifxusb_core_if_t *_core_if); -+ -+#ifdef __IS_DUAL__ -+ static void dump_params_1(void) -+ { -+ ifxusb_dump_params(&ifxusb_hcd_1.core_if); -+ } -+ static void dump_params_2(void) -+ { -+ ifxusb_dump_params(&ifxusb_hcd_2.core_if); -+ } -+ -+ static ssize_t procfs_dump_params_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_params_1(); -+ return 0; -+ } -+ static ssize_t procfs_dump_params_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_params_2(); -+ return 0; -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_params_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_params_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_params_1(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_params_1, S_IRUGO|S_IWUSR, sysfs_dump_params_show_1, NULL); -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_params_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_params_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_params_2(); -+ return 0; -+ } -+ -+ DEVICE_ATTR(dump_params_2, S_IRUGO|S_IWUSR, sysfs_dump_params_show_2, NULL); -+#else -+ static void dump_params(void) -+ { -+ #ifdef __IS_HOST__ -+ ifxusb_dump_params(&ifxusb_hcd.core_if); -+ #else -+ ifxusb_dump_params(&ifxusb_pcd.core_if); -+ #endif -+ } -+ -+ static ssize_t procfs_dump_params_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_params(); -+ return 0; -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_params_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_params_show( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_params(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_params, S_IRUGO|S_IWUSR, sysfs_dump_params_show, NULL); -+#endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#ifdef __IS_DUAL__ -+ static ssize_t mode_show_1(char *buf) -+ { -+ if((ifxusb_rreg(&ifxusb_hcd_1.core_if.core_global_regs->gintsts ) & 0x1) == 1) -+ return sprintf( buf, "HOST\n" ); -+ else -+ return sprintf( buf, "DEVICE(INCORRECT!)\n" ); -+ } -+ -+ static ssize_t mode_show_2(char *buf) -+ { -+ if((ifxusb_rreg(&ifxusb_hcd_2.core_if.core_global_regs->gintsts ) & 0x1) == 1) -+ return sprintf( buf, "HOST\n" ); -+ else -+ return sprintf( buf, "DEVICE(INCORRECT!)\n" ); -+ } -+ -+ static ssize_t procfs_mode_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return mode_show_1(buf); -+ } -+ static ssize_t procfs_mode_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return mode_show_2(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_mode_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_mode_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ return mode_show_1(buf); -+ } -+ -+ DEVICE_ATTR(mode_1, S_IRUGO|S_IWUSR, sysfs_mode_show_1, 0); -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_mode_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_mode_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ return mode_show_2(buf); -+ } -+ DEVICE_ATTR(mode_2, S_IRUGO|S_IWUSR, sysfs_mode_show_2, NULL); -+#else -+ static ssize_t mode_show(char *buf) -+ { -+ #ifdef __IS_HOST__ -+ if((ifxusb_rreg(&ifxusb_hcd.core_if.core_global_regs->gintsts ) & 0x1) == 1) -+ return sprintf( buf, "HOST\n" ); -+ else -+ return sprintf( buf, "DEVICE(INCORRECT!)\n" ); -+ #else -+ if((ifxusb_rreg(&ifxusb_pcd.core_if.core_global_regs->gintsts ) & 0x1) != 1) -+ return sprintf( buf, "DEVICE\n" ); -+ else -+ return sprintf( buf, "HOST(INCORRECT!)\n" ); -+ #endif -+ } -+ static ssize_t procfs_mode_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return mode_show(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_mode_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_mode_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return mode_show(buf); -+ } -+ DEVICE_ATTR(mode, S_IRUGO|S_IWUSR, sysfs_mode_show, NULL); -+#endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+#ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ static ssize_t buspower_show_1(char *buf) -+ { -+ if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==1) return sprintf( buf, "1\n" ); -+ if(ifxusb_vbus (&ifxusb_hcd_1.core_if)==0) return sprintf( buf, "0\n" ); -+ return sprintf( buf, "UNKNOWN\n" ); -+ } -+ static void buspower_store_1(uint32_t value) -+ { -+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd_1.core_if); -+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_1.core_if); -+ } -+ static ssize_t buspower_show_2(char *buf) -+ { -+ if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==1) return sprintf( buf, "1\n" ); -+ if(ifxusb_vbus (&ifxusb_hcd_2.core_if)==0) return sprintf( buf, "0\n" ); -+ return sprintf( buf, "UNKNOWN\n" ); -+ } -+ static void buspower_store_2(uint32_t value) -+ { -+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd_2.core_if); -+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd_2.core_if); -+ } -+ static ssize_t procfs_buspower_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return buspower_show_1(buf); -+ } -+ static ssize_t procfs_buspower_store_1(struct file *file, const char *buffer, unsigned long count, void *data) -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store_1(value); -+ return count; -+ } -+ static ssize_t procfs_buspower_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return buspower_show_2(buf); -+ } -+ static ssize_t procfs_buspower_store_2(struct file *file, const char *buffer, unsigned long count, void *data) -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store_2(value); -+ return count; -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_buspower_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ return buspower_show_1(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_store_1( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count ) -+ #else -+ static ssize_t sysfs_buspower_store_1( struct device *_dev, const char *buffer, size_t count ) -+ #endif -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store_1(value); -+ return count; -+ } -+ DEVICE_ATTR(buspower_1, S_IRUGO|S_IWUSR, sysfs_buspower_show_1, sysfs_buspower_store_1); -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_buspower_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ return buspower_show_2(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_store_2( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count ) -+ #else -+ static ssize_t sysfs_buspower_store_2( struct device *_dev, const char *buffer, size_t count ) -+ #endif -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store_2(value); -+ return count; -+ } -+ DEVICE_ATTR(buspower_2, S_IRUGO|S_IWUSR, sysfs_buspower_show_2, sysfs_buspower_store_2); -+ #else -+ static ssize_t buspower_show(char *buf) -+ { -+ if(ifxusb_vbus (&ifxusb_hcd.core_if)==1) return sprintf( buf, "1\n" ); -+ if(ifxusb_vbus (&ifxusb_hcd.core_if)==0) return sprintf( buf, "0\n" ); -+ return sprintf( buf, "UNKNOWN\n" ); -+ } -+ static void buspower_store(uint32_t value) -+ { -+ if (value==1) ifxusb_vbus_on (&ifxusb_hcd.core_if); -+ else if(value==0) ifxusb_vbus_off(&ifxusb_hcd.core_if); -+ } -+ static ssize_t procfs_buspower_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return buspower_show(buf); -+ } -+ static ssize_t procfs_buspower_store(struct file *file, const char *buffer, unsigned long count, void *data) -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store(value); -+ return count; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_buspower_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return buspower_show(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_buspower_store( struct device *_dev, struct device_attribute *attr,const char *buffer, size_t count ) -+ #else -+ static ssize_t sysfs_buspower_store( struct device *_dev, const char *buffer, size_t count ) -+ #endif -+ { -+ char buf[10]; -+ int i = 0; -+ uint32_t value; -+ if (copy_from_user(buf, &buffer[i], sizeof("0xFFFFFFFF\n")+1)) -+ return -EFAULT; -+ value = simple_strtoul(buf, NULL, 16); -+ buspower_store(value); -+ return count; -+ } -+ DEVICE_ATTR(buspower, S_IRUGO|S_IWUSR, sysfs_buspower_show, sysfs_buspower_store); -+ #endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ -+ #ifdef __IS_DUAL__ -+ static ssize_t bussuspend_show_1(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0); -+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); -+ } -+ static ssize_t bussuspend_show_2(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0); -+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); -+ } -+ -+ static ssize_t procfs_bussuspend_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return bussuspend_show_1(buf); -+ } -+ static ssize_t procfs_bussuspend_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return bussuspend_show_2(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_bussuspend_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_bussuspend_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ return bussuspend_show_1(buf); -+ } -+ DEVICE_ATTR(bussuspend_1, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_1, 0); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_bussuspend_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_bussuspend_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ return bussuspend_show_2(buf); -+ } -+ DEVICE_ATTR(bussuspend_2, S_IRUGO|S_IWUSR, sysfs_bussuspend_show_2, 0); -+ #else -+ static ssize_t bussuspend_show(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0); -+ return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); -+ } -+ static ssize_t procfs_bussuspend_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return bussuspend_show(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_bussuspend_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_bussuspend_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return bussuspend_show(buf); -+ } -+ DEVICE_ATTR(bussuspend, S_IRUGO|S_IWUSR, sysfs_bussuspend_show, 0); -+ #endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ #ifdef __IS_DUAL__ -+ static ssize_t busconnected_show_1(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0); -+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts); -+ } -+ static ssize_t busconnected_show_2(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0); -+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts); -+ } -+ -+ static ssize_t procfs_busconnected_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return busconnected_show_1(buf); -+ } -+ static ssize_t procfs_busconnected_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return busconnected_show_2(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_busconnected_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_busconnected_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ return busconnected_show_1(buf); -+ } -+ DEVICE_ATTR(busconnected_1, S_IRUGO|S_IWUSR, sysfs_busconnected_show_1, 0); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_busconnected_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_busconnected_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ return busconnected_show_2(buf); -+ } -+ DEVICE_ATTR(busconnected_2, S_IRUGO|S_IWUSR, sysfs_busconnected_show_2, 0); -+ #else -+ static ssize_t busconnected_show(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0); -+ return sprintf (buf, "Bus Connected = 0x%x\n", val.b.prtconnsts); -+ } -+ static ssize_t procfs_busconnected_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return busconnected_show(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_busconnected_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_busconnected_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return busconnected_show(buf); -+ } -+ DEVICE_ATTR(busconnected, S_IRUGO|S_IWUSR, sysfs_busconnected_show, 0); -+ #endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ #ifdef __IS_DUAL__ -+ static ssize_t connectspeed_show_1(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_1.core_if.hprt0); -+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd); -+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd); -+ } -+ static ssize_t connectspeed_show_2(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd_2.core_if.hprt0); -+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd); -+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd); -+ } -+ -+ static ssize_t procfs_connectspeed_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return connectspeed_show_1(buf); -+ } -+ static ssize_t procfs_connectspeed_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return connectspeed_show_2(buf); -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_connectspeed_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_connectspeed_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ return connectspeed_show_1(buf); -+ } -+ DEVICE_ATTR(connectspeed_1, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_1, 0); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_connectspeed_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_connectspeed_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ return connectspeed_show_2(buf); -+ } -+ DEVICE_ATTR(connectspeed_2, S_IRUGO|S_IWUSR, sysfs_connectspeed_show_2, 0); -+ #else -+ static ssize_t connectspeed_show(char *buf) -+ { -+ hprt0_data_t val; -+ val.d32 = ifxusb_rreg(ifxusb_hcd.core_if.hprt0); -+ if( val.b.prtspd ==0) return sprintf (buf, "Bus Speed = High (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==1) return sprintf (buf, "Bus Speed = Full (%d)\n", val.b.prtspd); -+ if( val.b.prtspd ==2) return sprintf (buf, "Bus Speed = Low (%d)\n", val.b.prtspd); -+ return sprintf (buf, "Bus Speed = Unknown (%d)\n", val.b.prtspd); -+ } -+ -+ static ssize_t procfs_connectspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return connectspeed_show(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_connectspeed_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_connectspeed_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return connectspeed_show(buf); -+ } -+ DEVICE_ATTR(connectspeed, S_IRUGO|S_IWUSR, sysfs_connectspeed_show, 0); -+ #endif -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+#endif -+ -+ -+#ifdef __IS_DEVICE__ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ static ssize_t devspeed_show(char *buf) -+ { -+ dcfg_data_t val; -+ val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dcfg); -+ if( val.b.devspd ==0) return sprintf (buf, "Dev Speed = High (%d)\n", val.b.devspd); -+ if( val.b.devspd ==1) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd); -+ if( val.b.devspd ==3) return sprintf (buf, "Dev Speed = Full (%d)\n", val.b.devspd); -+ return sprintf (buf, "Dev Speed = Unknown (%d)\n", val.b.devspd); -+ } -+ -+ static ssize_t procfs_devspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return devspeed_show(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_devspeed_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_devspeed_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return devspeed_show(buf); -+ } -+ DEVICE_ATTR(devspeed, S_IRUGO|S_IWUSR, sysfs_devspeed_show, 0); -+ -+ static ssize_t enumspeed_show(char *buf) -+ { -+ dsts_data_t val; -+ val.d32 = ifxusb_rreg(&ifxusb_pcd.core_if.dev_global_regs->dsts); -+ if( val.b.enumspd ==0) return sprintf (buf, "Enum Speed = High (%d)\n", val.b.enumspd); -+ if( val.b.enumspd ==1) return sprintf (buf, "Enum Speed = Full (%d)\n", val.b.enumspd); -+ if( val.b.enumspd ==2) return sprintf (buf, "Enum Speed = Low (%d)\n", val.b.enumspd); -+ return sprintf (buf, "Enum Speed = invalid(%d)\n", val.b.enumspd); -+ } -+ -+ static ssize_t procfs_enumspeed_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ return enumspeed_show(buf); -+ } -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_enumspeed_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_enumspeed_show( struct device *_dev, char *buf) -+ #endif -+ { -+ return enumspeed_show(buf); -+ } -+ DEVICE_ATTR(enumspeed, S_IRUGO|S_IWUSR, sysfs_enumspeed_show, 0); -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+#endif -+ -+ -+////////////////////////////////////////////////////////////////////////////////// -+#ifdef __ENABLE_DUMP__ -+ -+ #ifdef __IS_DUAL__ -+ static void dump_reg_1(void) -+ { -+ ifxusb_dump_registers(&ifxusb_hcd_1.core_if); -+ } -+ static void dump_reg_2(void) -+ { -+ ifxusb_dump_registers(&ifxusb_hcd_2.core_if); -+ } -+ -+ static ssize_t procfs_dump_reg_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_reg_1(); -+ return 0; -+ } -+ static ssize_t procfs_dump_reg_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_reg_2(); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_reg_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_reg_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_reg_1(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_reg_1, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_1, 0); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_reg_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_reg_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_reg_2(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_reg_2, S_IRUGO|S_IWUSR, sysfs_dump_reg_show_2, 0); -+ #else -+ static void dump_reg(void) -+ { -+ #ifdef __IS_HOST__ -+ ifxusb_dump_registers(&ifxusb_hcd.core_if); -+ #endif -+ #ifdef __IS_DEVICE__ -+ ifxusb_dump_registers(&ifxusb_pcd.core_if); -+ #endif -+ } -+ static ssize_t procfs_dump_reg_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_reg(); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_reg_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_reg_show( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_reg(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_reg, S_IRUGO|S_IWUSR, sysfs_dump_reg_show, 0); -+ #endif -+ -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ #ifdef __IS_DUAL__ -+ static void dump_spram_1(void) -+ { -+ ifxusb_dump_spram(&ifxusb_hcd_1.core_if); -+ } -+ static void dump_spram_2(void) -+ { -+ ifxusb_dump_spram(&ifxusb_hcd_2.core_if); -+ } -+ -+ static ssize_t procfs_dump_spram_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_spram_1(); -+ return 0; -+ } -+ static ssize_t procfs_dump_spram_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_spram_2(); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_spram_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_spram_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_spram_1(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_spram_1, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_1, 0); -+ -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_spram_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_spram_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_spram_2(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_spram_2, S_IRUGO|S_IWUSR, sysfs_dump_spram_show_2, 0); -+ #else -+ static void dump_spram(void) -+ { -+ #ifdef __IS_HOST__ -+ ifxusb_dump_spram(&ifxusb_hcd.core_if); -+ #endif -+ #ifdef __IS_DEVICE__ -+ ifxusb_dump_spram(&ifxusb_pcd.core_if); -+ #endif -+ } -+ static ssize_t procfs_dump_spram_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ dump_spram(); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_spram_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_spram_show( struct device *_dev,char *buf) -+ #endif -+ { -+ dump_spram(); -+ return 0; -+ } -+ DEVICE_ATTR(dump_spram, S_IRUGO|S_IWUSR, sysfs_dump_spram_show, 0); -+ #endif -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ #ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ static ssize_t procfs_dump_host_state_show_1(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ ifxhcd_dump_state(&ifxusb_hcd_1); -+ return 0; -+ } -+ static ssize_t procfs_dump_host_state_show_2(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ ifxhcd_dump_state(&ifxusb_hcd_2); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_host_state_show_1( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_host_state_show_1( struct device *_dev,char *buf) -+ #endif -+ { -+ ifxhcd_dump_state(&ifxusb_hcd_1); -+ return 0; -+ } -+ DEVICE_ATTR(dump_host_state_1, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_1, 0); -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_host_state_show_2( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_host_state_show_2( struct device *_dev,char *buf) -+ #endif -+ { -+ ifxhcd_dump_state(&ifxusb_hcd_2); -+ return 0; -+ } -+ DEVICE_ATTR(dump_host_state_2, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show_2, 0); -+ #else -+ static ssize_t procfs_dump_host_state_show(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+ { -+ ifxhcd_dump_state(&ifxusb_hcd); -+ return 0; -+ } -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ static ssize_t sysfs_dump_host_state_show( struct device *_dev, struct device_attribute *attr,char *buf) -+ #else -+ static ssize_t sysfs_dump_host_state_show( struct device *_dev,char *buf) -+ #endif -+ { -+ ifxhcd_dump_state(&ifxusb_hcd); -+ return 0; -+ } -+ DEVICE_ATTR(dump_host_state, S_IRUGO|S_IWUSR, sysfs_dump_host_state_show, 0); -+ #endif -+ -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+///////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+ #endif //IS_HOST_ -+ -+#endif //__ENABLE_DUMP__ -+ -+////////////////////////////////////////////////////////////////////////////////// -+ -+static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw); -+static void ifx_proc_delproc(char *funcname); -+ -+////////////////////////////////////////////////////////////////////////////////// -+ -+/*! -+ \brief This function create the sysfs and procfs entries -+ \param[in] _dev Pointer of device structure, if applied -+ */ -+void ifxusb_attr_create (void *_dev) -+{ -+ int error; -+ -+ struct device *dev = (struct device *) _dev; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ error = ifx_proc_addproc("dbglevel", procfs_dbglevel_show, procfs_dbglevel_store); -+ error = device_create_file(dev, &dev_attr_dbglevel); -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("dump_params_1", procfs_dump_params_show_1, NULL); -+ error = ifx_proc_addproc("dump_params_2", procfs_dump_params_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_dump_params_1); -+ error = device_create_file(dev, &dev_attr_dump_params_2); -+ #else -+ error = ifx_proc_addproc("dump_params", procfs_dump_params_show, NULL); -+ error = device_create_file(dev, &dev_attr_dump_params); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("mode_1", procfs_mode_show_1, NULL); -+ error = ifx_proc_addproc("mode_2", procfs_mode_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_mode_1); -+ error = device_create_file(dev, &dev_attr_mode_2); -+ #else -+ error = ifx_proc_addproc("mode", procfs_mode_show, NULL); -+ error = device_create_file(dev, &dev_attr_mode); -+ #endif -+ -+ #ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("buspower_1", procfs_buspower_show_1, procfs_buspower_store_1); -+ error = ifx_proc_addproc("buspower_2", procfs_buspower_show_2, procfs_buspower_store_2); -+ error = device_create_file(dev, &dev_attr_buspower_1); -+ error = device_create_file(dev, &dev_attr_buspower_2); -+ #else -+ error = ifx_proc_addproc("buspower", procfs_buspower_show, procfs_buspower_store); -+ error = device_create_file(dev, &dev_attr_buspower); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("bussuspend_1", procfs_bussuspend_show_1, NULL); -+ error = ifx_proc_addproc("bussuspend_2", procfs_bussuspend_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_bussuspend_1); -+ error = device_create_file(dev, &dev_attr_bussuspend_2); -+ #else -+ error = ifx_proc_addproc("bussuspend", procfs_bussuspend_show, NULL); -+ error = device_create_file(dev, &dev_attr_bussuspend); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("busconnected_1", procfs_busconnected_show_1, NULL); -+ error = ifx_proc_addproc("busconnected_2", procfs_busconnected_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_busconnected_1); -+ error = device_create_file(dev, &dev_attr_busconnected_2); -+ #else -+ error = ifx_proc_addproc("busconnected", procfs_busconnected_show, NULL); -+ error = device_create_file(dev, &dev_attr_busconnected); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("connectspeed_1", procfs_connectspeed_show_1, NULL); -+ error = ifx_proc_addproc("connectspeed_2", procfs_connectspeed_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_connectspeed_1); -+ error = device_create_file(dev, &dev_attr_connectspeed_2); -+ #else -+ error = ifx_proc_addproc("connectspeed", procfs_connectspeed_show, NULL); -+ error = device_create_file(dev, &dev_attr_connectspeed); -+ #endif -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ error = ifx_proc_addproc("devspeed", procfs_devspeed_show, NULL); -+ error = device_create_file(dev, &dev_attr_devspeed); -+ error = ifx_proc_addproc("enumspeed", procfs_enumspeed_show, NULL); -+ error = device_create_file(dev, &dev_attr_enumspeed); -+ #endif -+ -+ ////////////////////////////////////////////////////// -+ #ifdef __ENABLE_DUMP__ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("dump_reg_1", procfs_dump_reg_show_1, NULL); -+ error = ifx_proc_addproc("dump_reg_2", procfs_dump_reg_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_dump_reg_1); -+ error = device_create_file(dev, &dev_attr_dump_reg_2); -+ #else -+ error = ifx_proc_addproc("dump_reg", procfs_dump_reg_show, NULL); -+ error = device_create_file(dev, &dev_attr_dump_reg); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("dump_spram_1", procfs_dump_spram_show_1, NULL); -+ error = ifx_proc_addproc("dump_spram_2", procfs_dump_spram_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_dump_spram_1); -+ error = device_create_file(dev, &dev_attr_dump_spram_2); -+ #else -+ error = ifx_proc_addproc("dump_spram", procfs_dump_spram_show, NULL); -+ error = device_create_file(dev, &dev_attr_dump_spram); -+ #endif -+ -+ #ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ error = ifx_proc_addproc("dump_host_state_1", procfs_dump_host_state_show_1, NULL); -+ error = ifx_proc_addproc("dump_host_state_2", procfs_dump_host_state_show_2, NULL); -+ error = device_create_file(dev, &dev_attr_dump_host_state_1); -+ error = device_create_file(dev, &dev_attr_dump_host_state_2); -+ #else -+ error = ifx_proc_addproc("dump_host_state", procfs_dump_host_state_show, NULL); -+ error = device_create_file(dev, &dev_attr_dump_host_state); -+ #endif -+ #endif -+ #endif //__ENABLE_DUMP__ -+ ////////////////////////////////////////////////////// -+} -+ -+ -+/*! -+ \brief This function remove the sysfs and procfs entries -+ \param[in] _dev Pointer of device structure, if applied -+ */ -+void ifxusb_attr_remove (void *_dev) -+{ -+ struct device *dev = (struct device *) _dev; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ ifx_proc_delproc("dbglevel"); -+ device_remove_file(dev, &dev_attr_dbglevel); -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("dump_params_1"); -+ ifx_proc_delproc("dump_params_2"); -+ device_remove_file(dev, &dev_attr_dump_params_1); -+ device_remove_file(dev, &dev_attr_dump_params_2); -+ #else -+ ifx_proc_delproc("dump_params"); -+ device_remove_file(dev, &dev_attr_dump_params); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("mode_1"); -+ ifx_proc_delproc("mode_2"); -+ device_remove_file(dev, &dev_attr_mode_1); -+ device_remove_file(dev, &dev_attr_mode_2); -+ #else -+ ifx_proc_delproc("mode"); -+ device_remove_file(dev, &dev_attr_mode); -+ #endif -+ -+ #ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("buspower_1"); -+ ifx_proc_delproc("buspower_2"); -+ device_remove_file(dev, &dev_attr_buspower_1); -+ device_remove_file(dev, &dev_attr_buspower_2); -+ #else -+ ifx_proc_delproc("buspower"); -+ device_remove_file(dev, &dev_attr_buspower); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("bussuspend_1"); -+ ifx_proc_delproc("bussuspend_2"); -+ device_remove_file(dev, &dev_attr_bussuspend_1); -+ device_remove_file(dev, &dev_attr_bussuspend_2); -+ #else -+ ifx_proc_delproc("bussuspend"); -+ device_remove_file(dev, &dev_attr_bussuspend); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("busconnected_1"); -+ ifx_proc_delproc("busconnected_2"); -+ device_remove_file(dev, &dev_attr_busconnected_1); -+ device_remove_file(dev, &dev_attr_busconnected_2); -+ #else -+ ifx_proc_delproc("busconnected"); -+ device_remove_file(dev, &dev_attr_busconnected); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("connectspeed_1"); -+ ifx_proc_delproc("connectspeed_2"); -+ device_remove_file(dev, &dev_attr_connectspeed_1); -+ device_remove_file(dev, &dev_attr_connectspeed_2); -+ #else -+ ifx_proc_delproc("connectspeed"); -+ device_remove_file(dev, &dev_attr_connectspeed); -+ #endif -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ ifx_proc_delproc("devspeed"); -+ device_remove_file(dev, &dev_attr_devspeed); -+ ifx_proc_delproc("enumspeed"); -+ device_remove_file(dev, &dev_attr_enumspeed); -+ #endif -+ -+ #ifdef __ENABLE_DUMP__ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("dump_reg_1"); -+ ifx_proc_delproc("dump_reg_2"); -+ device_remove_file(dev, &dev_attr_dump_reg_1); -+ device_remove_file(dev, &dev_attr_dump_reg_2); -+ #else -+ ifx_proc_delproc("dump_reg"); -+ device_remove_file(dev, &dev_attr_dump_reg); -+ #endif -+ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("dump_spram_1"); -+ ifx_proc_delproc("dump_spram_2"); -+ device_remove_file(dev, &dev_attr_dump_spram_1); -+ device_remove_file(dev, &dev_attr_dump_spram_2); -+ #else -+ ifx_proc_delproc("dump_spram"); -+ device_remove_file(dev, &dev_attr_dump_spram); -+ #endif -+ -+ #ifdef __IS_HOST__ -+ #ifdef __IS_DUAL__ -+ ifx_proc_delproc("dump_host_state_1"); -+ ifx_proc_delproc("dump_host_state_2"); -+ device_remove_file(dev, &dev_attr_dump_host_state_1); -+ device_remove_file(dev, &dev_attr_dump_host_state_2); -+ #else -+ ifx_proc_delproc("dump_host_state"); -+ device_remove_file(dev, &dev_attr_dump_host_state); -+ #endif -+ #endif -+ #endif //__ENABLE_DUMP__ -+ /* AVM/WK fix: del IFXUSB root dir*/ -+ ifx_proc_delproc(NULL); -+} -+ -+static struct proc_dir_entry * proc_ifx_root = NULL; -+ -+/* initialize the proc file system and make a dir named /proc/[name] */ -+static void ifx_proc_init(void) -+{ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ proc_ifx_root = proc_mkdir(ifxusb_driver_name, (void *)0); -+ if (!proc_ifx_root){ -+ IFX_PRINT("%s proc initialization failed! \n", ifxusb_driver_name); -+ return; -+ } -+} -+ -+/* proc file system add function for debugging. */ -+static int ifx_proc_addproc(char *funcname, read_proc_t *hookfuncr, write_proc_t *hookfuncw) -+{ -+ struct proc_dir_entry *pe; -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ if (!proc_ifx_root) -+ ifx_proc_init(); -+ -+ if (hookfuncw == NULL) -+ { -+ pe = create_proc_read_entry(funcname, S_IRUGO, proc_ifx_root, hookfuncr, NULL); -+ if (!pe) -+ { -+ IFX_PRINT("ERROR in creating read proc entry (%s)! \n", funcname); -+ return -1; -+ } -+ } -+ else -+ { -+ pe = create_proc_entry(funcname, S_IRUGO | S_IWUGO, proc_ifx_root); -+ if (pe) -+ { -+ pe->read_proc = hookfuncr; -+ pe->write_proc = hookfuncw; -+ } -+ else -+ { -+ IFX_PRINT("ERROR in creating proc entry (%s)! \n", funcname); -+ return -1; -+ } -+ } -+ return 0; -+} -+ -+ -+/* proc file system del function for removing module. */ -+static void ifx_proc_delproc(char *funcname) -+{ -+/* AVM/WK Fix*/ -+ if (funcname != NULL) { -+ remove_proc_entry(funcname, proc_ifx_root); -+ } else { -+ remove_proc_entry(ifxusb_driver_name, NULL); -+ proc_ifx_root = NULL; -+ } -+} -+ -+static void ifxusb_dump_params(ifxusb_core_if_t *_core_if) -+{ -+ ifxusb_params_t *params=&_core_if->params; -+ -+ #ifdef __IS_HOST__ -+ IFX_PRINT("IFXUSB Dump Parameters ( Host Mode) \n"); -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ IFX_PRINT("IFXUSB Dump Parameters ( Device Mode) \n"); -+ #endif //__IS_DEVICE__ -+ -+ #ifdef __DESC_DMA__ -+ IFX_PRINT("DMA: Hermes DMA\n"); -+ #else -+ IFX_PRINT("DMA: Non-Desc DMA\n"); -+ #endif -+ IFX_PRINT(" Burst size: %d\n",params->dma_burst_size); -+ -+ if (params->speed==1) -+ IFX_PRINT("Full Speed only\n"); -+ else if(params->speed==0) -+ IFX_PRINT("Full/Hign Speed\n"); -+ else -+ IFX_PRINT("Unkonwn setting (%d) for Speed\n",params->speed); -+ -+ IFX_PRINT("Total Data FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n", -+ params->data_fifo_size,params->data_fifo_size, -+ params->data_fifo_size*4, params->data_fifo_size*4 -+ ); -+ -+ #ifdef __IS_DEVICE__ -+ IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n", -+ params->rx_fifo_size,params->rx_fifo_size, -+ params->rx_fifo_size*4, params->rx_fifo_size*4 -+ ); -+ { -+ int i; -+ for(i=0;i<MAX_EPS_CHANNELS;i++) -+ { -+ IFX_PRINT("Tx FIFO #%d size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n",i, -+ params->tx_fifo_size[i],params->tx_fifo_size[i], -+ params->tx_fifo_size[i]*4, params->tx_fifo_size[i]*4 -+ ); -+ } -+ } -+ #ifdef __DED_FIFO__ -+ IFX_PRINT("Treshold : %s Rx:%d Tx:%d \n", -+ (params->thr_ctl)?"On":"Off",params->tx_thr_length,params->rx_thr_length); -+ #endif -+ #else //__IS_HOST__ -+ IFX_PRINT("Host Channels: %d\n",params->host_channels); -+ -+ IFX_PRINT("Rx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n", -+ params->data_fifo_size,params->data_fifo_size, -+ params->data_fifo_size*4, params->data_fifo_size*4 -+ ); -+ -+ IFX_PRINT("NP Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n", -+ params->nperio_tx_fifo_size,params->nperio_tx_fifo_size, -+ params->nperio_tx_fifo_size*4, params->nperio_tx_fifo_size*4 -+ ); -+ -+ IFX_PRINT(" P Tx FIFO size: %d(0x%06X) DWord, %d(0x%06X) Bytes\n", -+ params->perio_tx_fifo_size,params->perio_tx_fifo_size, -+ params->perio_tx_fifo_size*4, params->perio_tx_fifo_size*4 -+ ); -+ #endif //__IS_HOST__ -+ -+ IFX_PRINT("Max Transfer size: %d(0x%06X) Bytes\n", -+ params->max_transfer_size,params->max_transfer_size -+ ); -+ IFX_PRINT("Max Packet Count: %d(0x%06X)\n", -+ params->max_packet_count,params->max_packet_count -+ ); -+ -+ IFX_PRINT("PHY UTMI Width: %d\n",params->phy_utmi_width); -+ -+ IFX_PRINT("Turn Around Time: HS:%d FS:%d\n",params->turn_around_time_hs,params->turn_around_time_fs); -+ IFX_PRINT("Timeout Calibration: HS:%d FS:%d\n",params->timeout_cal_hs,params->timeout_cal_fs); -+ -+ -+ IFX_PRINT("==================================================\n"); -+ IFX_PRINT("End of Parameters Dump\n"); -+ IFX_PRINT("==================================================\n"); -+} -+ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_driver.c -@@ -0,0 +1,970 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_driver.c -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : The provides the initialization and cleanup entry -+ ** points for the IFX USB driver. This module can be -+ ** dynamically loaded with insmod command or built-in -+ ** with kernel. When loaded or executed the ifxusb_driver_init -+ ** function is called. When the module is removed (using rmmod), -+ ** the ifxusb_driver_cleanup function is called. -+ *****************************************************************************/ -+ -+/*! -+ \file ifxusb_driver.c -+ \brief This file contains the loading/unloading interface to the Linux driver. -+*/ -+ -+#include <linux/version.h> -+#include "ifxusb_version.h" -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+ -+#include <linux/device.h> -+#include <linux/platform_device.h> -+ -+#include <linux/errno.h> -+#include <linux/types.h> -+#include <linux/stat.h> /* permission constants */ -+#include <linux/gpio.h> -+#include <lantiq_soc.h> -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+ #include <linux/irq.h> -+#endif -+ -+#include <asm/io.h> -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ #include <asm/irq.h> -+#endif -+ -+#include "ifxusb_plat.h" -+ -+#include "ifxusb_cif.h" -+ -+#ifdef __IS_HOST__ -+ #include "ifxhcd.h" -+ -+ #define USB_DRIVER_DESC "IFX USB HCD driver" -+ const char ifxusb_driver_name[] = "ifxusb_hcd"; -+ -+ #ifdef __IS_DUAL__ -+ ifxhcd_hcd_t ifxusb_hcd_1; -+ ifxhcd_hcd_t ifxusb_hcd_2; -+ const char ifxusb_hcd_name_1[] = "ifxusb_hcd_1"; -+ const char ifxusb_hcd_name_2[] = "ifxusb_hcd_2"; -+ #else -+ ifxhcd_hcd_t ifxusb_hcd; -+ const char ifxusb_hcd_name[] = "ifxusb_hcd"; -+ #endif -+ -+ #if defined(__DO_OC_INT__) -+ static unsigned int oc_int_installed=0; -+ static ifxhcd_hcd_t *oc_int_id=NULL; -+ #endif -+#endif -+ -+#ifdef __IS_DEVICE__ -+ #include "ifxpcd.h" -+ -+ #define USB_DRIVER_DESC "IFX USB PCD driver" -+ const char ifxusb_driver_name[] = "ifxusb_pcd"; -+ -+ ifxpcd_pcd_t ifxusb_pcd; -+ const char ifxusb_pcd_name[] = "ifxusb_pcd"; -+#endif -+ -+/* Global Debug Level Mask. */ -+#ifdef __IS_HOST__ -+ uint32_t h_dbg_lvl = 0x00; -+#endif -+ -+#ifdef __IS_DEVICE__ -+ uint32_t d_dbg_lvl = 0x00; -+#endif -+ -+ifxusb_params_t ifxusb_module_params; -+ -+static void parse_parms(void); -+ -+ -+#include <lantiq_irq.h> -+#define IFX_USB0_IR (INT_NUM_IM1_IRL0 + 22) -+#define IFX_USB1_IR (INT_NUM_IM2_IRL0 + 19) -+ -+/*! -+ \brief This function is called when a driver is unregistered. This happens when -+ the rmmod command is executed. The device may or may not be electrically -+ present. If it is present, the driver stops device processing. Any resources -+ used on behalf of this device are freed. -+*/ -+static int ifxusb_driver_remove(struct platform_device *_dev) -+{ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ #ifdef __IS_HOST__ -+ #if defined(__DO_OC_INT__) -+ #if defined(__DO_OC_INT_ENABLE__) -+ ifxusb_oc_int_off(); -+ #endif -+ -+ if(oc_int_installed && oc_int_id) -+ free_irq((unsigned int)IFXUSB_OC_IRQ, oc_int_id ); -+ oc_int_installed=0; -+ oc_int_id=NULL; -+ #endif -+ -+ #if defined(__IS_DUAL__) -+ ifxhcd_remove(&ifxusb_hcd_1); -+ ifxusb_core_if_remove(&ifxusb_hcd_1.core_if ); -+ ifxhcd_remove(&ifxusb_hcd_2); -+ ifxusb_core_if_remove(&ifxusb_hcd_2.core_if ); -+ #else -+ ifxhcd_remove(&ifxusb_hcd); -+ ifxusb_core_if_remove(&ifxusb_hcd.core_if ); -+ #endif -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ ifxpcd_remove(); -+ ifxusb_core_if_remove(&ifxusb_pcd.core_if ); -+ #endif -+ -+ /* Remove the device attributes */ -+ -+ ifxusb_attr_remove(&_dev->dev); -+ -+ return 0; -+} -+ -+ -+/* Function to setup the structures to control one usb core running as host*/ -+#ifdef __IS_HOST__ -+/*! -+ \brief inlined by ifxusb_driver_probe(), handling host mode probing. Run at each host core. -+*/ -+ static inline int ifxusb_driver_probe_h(ifxhcd_hcd_t *_hcd, -+ int _irq, -+ uint32_t _iobase, -+ uint32_t _fifomem, -+ uint32_t _fifodbg -+ ) -+ { -+ int retval = 0; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ -+#ifdef __DEV_NEW__ -+ ifxusb_power_off (&_hcd->core_if); -+ ifxusb_phy_power_off (&_hcd->core_if); // Test -+ mdelay(500); -+#endif //__DEV_NEW__ -+ ifxusb_power_on (&_hcd->core_if); -+ mdelay(50); -+ ifxusb_phy_power_on (&_hcd->core_if); // Test -+ mdelay(50); -+ ifxusb_hard_reset(&_hcd->core_if); -+ retval =ifxusb_core_if_init(&_hcd->core_if, -+ _irq, -+ _iobase, -+ _fifomem, -+ _fifodbg); -+ if(retval) -+ return retval; -+ -+ ifxusb_host_core_init(&_hcd->core_if,&ifxusb_module_params); -+ -+ ifxusb_disable_global_interrupts( &_hcd->core_if); -+ -+ /* The driver is now initialized and need to be registered into Linux USB sub-system */ -+ -+ retval = ifxhcd_init(_hcd); // hook the hcd into usb ss -+ -+ if (retval != 0) -+ { -+ IFX_ERROR("_hcd_init failed\n"); -+ return retval; -+ } -+ -+ //ifxusb_enable_global_interrupts( _hcd->core_if ); // this should be done at hcd_start , including hcd_interrupt -+ return 0; -+ } -+#endif //__IS_HOST__ -+ -+#ifdef __IS_DEVICE__ -+/*! -+ \brief inlined by ifxusb_driver_probe(), handling device mode probing. -+*/ -+ static inline int ifxusb_driver_probe_d(ifxpcd_pcd_t *_pcd, -+ int _irq, -+ uint32_t _iobase, -+ uint32_t _fifomem, -+ uint32_t _fifodbg -+ ) -+ { -+ int retval = 0; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+#ifdef __DEV_NEW__ -+ ifxusb_power_off (&_pcd->core_if); -+ ifxusb_phy_power_off (&_pcd->core_if); // Test -+ mdelay(500); -+#endif // __DEV_NEW__ -+ ifxusb_power_on (&_pcd->core_if); -+ mdelay(50); -+ ifxusb_phy_power_on (&_pcd->core_if); // Test -+ mdelay(50); -+ ifxusb_hard_reset(&_pcd->core_if); -+ retval =ifxusb_core_if_init(&_pcd->core_if, -+ _irq, -+ _iobase, -+ _fifomem, -+ _fifodbg); -+ if(retval) -+ return retval; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ ifxusb_dev_core_init(&_pcd->core_if,&ifxusb_module_params); -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ ifxusb_disable_global_interrupts( &_pcd->core_if); -+ -+ /* The driver is now initialized and need to be registered into -+ Linux USB Gadget sub-system -+ */ -+ retval = ifxpcd_init(); -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ -+ if (retval != 0) -+ { -+ IFX_ERROR("_pcd_init failed\n"); -+ return retval; -+ } -+ //ifxusb_enable_global_interrupts( _pcd->core_if ); // this should be done at gadget bind or start -+ return 0; -+ } -+#endif //__IS_DEVICE__ -+ -+ -+ -+/*! -+ \brief This function is called by module management in 2.6 kernel or by ifxusb_driver_init with 2.4 kernel -+ It is to probe and setup IFXUSB core(s). -+*/ -+static int ifxusb_driver_probe(struct platform_device *_dev) -+{ -+ int retval = 0; -+ int *pins = _dev->dev.platform_data; -+ if (ltq_is_vr9()) { -+ gpio_request(6, "id1"); -+ gpio_request(9, "id2"); -+ gpio_direction_input(6); -+ gpio_direction_input(9); -+ } -+ if (pins) { -+ if (pins[0]) { -+ gpio_request(pins[0], "vbus1"); -+ gpio_direction_output(pins[0], 1); -+ } -+ if (pins[1] && ltq_is_vr9()) { -+ gpio_request(pins[1], "vbus2"); -+ gpio_direction_output(pins[1], 1); -+ } -+ } -+ // Parsing and store the parameters -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ parse_parms(); -+ -+ #ifdef __IS_HOST__ -+ #if defined(__IS_DUAL__) -+ memset(&ifxusb_hcd_1, 0, sizeof(ifxhcd_hcd_t)); -+ memset(&ifxusb_hcd_2, 0, sizeof(ifxhcd_hcd_t)); -+ -+ ifxusb_hcd_1.core_if.core_no=0; -+ ifxusb_hcd_2.core_if.core_no=1; -+ ifxusb_hcd_1.core_if.core_name=(char *)ifxusb_hcd_name_1; -+ ifxusb_hcd_2.core_if.core_name=(char *)ifxusb_hcd_name_2; -+ -+ ifxusb_hcd_1.dev=&_dev->dev; -+ ifxusb_hcd_2.dev=&_dev->dev; -+ -+ retval = ifxusb_driver_probe_h(&ifxusb_hcd_1, -+ IFX_USB0_IR, -+ IFXUSB1_IOMEM_BASE, -+ IFXUSB1_FIFOMEM_BASE, -+ IFXUSB1_FIFODBG_BASE -+ ); -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ -+ retval = ifxusb_driver_probe_h(&ifxusb_hcd_2, -+ IFX_USB1_IR, -+ IFXUSB2_IOMEM_BASE, -+ IFXUSB2_FIFOMEM_BASE, -+ IFXUSB2_FIFODBG_BASE -+ ); -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ -+ #elif defined(__IS_FIRST__) -+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); -+ -+ ifxusb_hcd.core_if.core_no=0; -+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; -+ -+ ifxusb_hcd.dev=&_dev->dev; -+ -+ retval = ifxusb_driver_probe_h(&ifxusb_hcd, -+ IFX_USB0_IR, -+ IFXUSB1_IOMEM_BASE, -+ IFXUSB1_FIFOMEM_BASE, -+ IFXUSB1_FIFODBG_BASE -+ ); -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ -+ #elif defined(__IS_SECOND__) -+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); -+ -+ ifxusb_hcd.core_if.core_no=1; -+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; -+ -+ ifxusb_hcd.dev=&_dev->dev; -+ -+ retval = ifxusb_driver_probe_h(&ifxusb_hcd, -+ IFX_USB1_IR, -+ IFXUSB2_IOMEM_BASE, -+ IFXUSB2_FIFOMEM_BASE, -+ IFXUSB2_FIFODBG_BASE -+ ); -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ -+ #else -+ memset(&ifxusb_hcd, 0, sizeof(ifxhcd_hcd_t)); -+ -+ ifxusb_hcd.core_if.core_no=0; -+ ifxusb_hcd.core_if.core_name=(char *)ifxusb_hcd_name; -+ -+ ifxusb_hcd.dev=&_dev->dev; -+ -+ retval = ifxusb_driver_probe_h(&ifxusb_hcd, -+ IFXUSB_IRQ, -+ IFXUSB_IOMEM_BASE, -+ IFXUSB_FIFOMEM_BASE, -+ IFXUSB_FIFODBG_BASE -+ ); -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ #endif -+ -+ #if defined(__DO_OC_INT__) -+ IFXUSB_DEBUGPL( DBG_CIL, "registering (overcurrent) handler for irq%d\n", IFXUSB_OC_IRQ); -+ #if defined(__IS_DUAL__) -+ request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq, -+// SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd_1); -+ IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd_1); -+ oc_int_id=&ifxusb_hcd_1; -+ #else -+ request_irq((unsigned int)IFXUSB_OC_IRQ, &ifx_hcd_oc_irq, -+// SA_INTERRUPT|SA_SHIRQ, "ifxusb_oc", (void *)&ifxusb_hcd); -+ IRQF_DISABLED | IRQF_SHARED, "ifxusb_oc", (void *)&ifxusb_hcd); -+ oc_int_id=&ifxusb_hcd; -+ #endif -+ oc_int_installed=1; -+ -+ #if defined(__DO_OC_INT_ENABLE__) -+ ifxusb_oc_int_on(); -+ #endif -+ #endif -+ -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ memset(&ifxusb_pcd, 0, sizeof(ifxpcd_pcd_t)); -+ ifxusb_pcd.core_if.core_name=(char *)&ifxusb_pcd_name[0]; -+ -+ ifxusb_pcd.dev=&_dev->dev; -+ -+ #if defined(__IS_FIRST__) -+ ifxusb_pcd.core_if.core_no=0; -+ retval = ifxusb_driver_probe_d(&ifxusb_pcd, -+ IFXUSB1_IRQ, -+ IFXUSB1_IOMEM_BASE, -+ IFXUSB1_FIFOMEM_BASE, -+ IFXUSB1_FIFODBG_BASE -+ ); -+ #elif defined(__IS_SECOND__) -+ ifxusb_pcd.core_if.core_no=1; -+ retval = ifxusb_driver_probe_d(&ifxusb_pcd, -+ IFXUSB2_IRQ, -+ IFXUSB2_IOMEM_BASE, -+ IFXUSB2_FIFOMEM_BASE, -+ IFXUSB2_FIFODBG_BASE -+ ); -+ #else -+ ifxusb_pcd.core_if.core_no=0; -+ retval = ifxusb_driver_probe_d(&ifxusb_pcd, -+ IFXUSB_IRQ, -+ IFXUSB_IOMEM_BASE, -+ IFXUSB_FIFOMEM_BASE, -+ IFXUSB_FIFODBG_BASE -+ ); -+ #endif -+ if(retval) -+ goto ifxusb_driver_probe_fail; -+ #endif -+ -+ ifxusb_attr_create(&_dev->dev); -+ -+ return 0; -+ -+ifxusb_driver_probe_fail: -+ ifxusb_driver_remove(_dev); -+ return retval; -+} -+ -+ -+ -+/*! -+ \brief This function is called when the ifxusb_driver is installed with the insmod command. -+*/ -+ -+ -+static struct platform_driver ifxusb_driver = { -+ .driver = { -+ .name = ifxusb_driver_name, -+ .owner = THIS_MODULE, -+ }, -+ .probe = ifxusb_driver_probe, -+ .remove = ifxusb_driver_remove, -+}; -+ -+int __init ifxusb_driver_init(void) -+{ -+ int retval = 0; -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ IFX_PRINT("%s: version %s\n", ifxusb_driver_name, IFXUSB_VERSION); -+ -+ retval = platform_driver_register(&ifxusb_driver); -+ -+ if (retval < 0) { -+ IFX_ERROR("%s retval=%d\n", __func__, retval); -+ return retval; -+ } -+ return retval; -+} -+ -+#if 0 // 2.4 -+ int __init ifxusb_driver_init(void) -+ { -+ int retval = 0; -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ IFX_PRINT("%s: version %s\n", ifxusb_driver_name, IFXUSB_VERSION); -+ retval = ifxusb_driver_probe(); -+ -+ if (retval < 0) { -+ IFX_ERROR("%s retval=%d\n", __func__, retval); -+ return retval; -+ } -+ -+ return retval; -+ } -+#endif -+ -+module_init(ifxusb_driver_init); -+ -+ -+/*! -+ \brief This function is called when the driver is removed from the kernel -+ with the rmmod command. The driver unregisters itself with its bus -+ driver. -+*/ -+ -+void __exit ifxusb_driver_cleanup(void) -+{ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ -+ platform_driver_unregister(&ifxusb_driver); -+ -+ IFX_PRINT("%s module removed\n", ifxusb_driver_name); -+} -+#if 0 -+ void __exit ifxusb_driver_cleanup(void) -+ { -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ ifxusb_driver_remove(); -+ IFX_PRINT("%s module removed\n", ifxusb_driver_name); -+ } -+#endif -+module_exit(ifxusb_driver_cleanup); -+ -+ -+ -+MODULE_DESCRIPTION(USB_DRIVER_DESC); -+MODULE_AUTHOR("Infineon"); -+MODULE_LICENSE("GPL"); -+ -+ -+ -+// Parameters set when loaded -+//static long dbg_lvl =0xFFFFFFFF; -+static long dbg_lvl =0; -+static short dma_burst_size =-1; -+static short speed =-1; -+static long data_fifo_size =-1; -+#ifdef __IS_DEVICE__ -+ static long rx_fifo_size =-1; -+ #ifdef __DED_FIFO__ -+ static long tx_fifo_size_00 =-1; -+ static long tx_fifo_size_01 =-1; -+ static long tx_fifo_size_02 =-1; -+ static long tx_fifo_size_03 =-1; -+ static long tx_fifo_size_04 =-1; -+ static long tx_fifo_size_05 =-1; -+ static long tx_fifo_size_06 =-1; -+ static long tx_fifo_size_07 =-1; -+ static long tx_fifo_size_08 =-1; -+ static long tx_fifo_size_09 =-1; -+ static long tx_fifo_size_10 =-1; -+ static long tx_fifo_size_11 =-1; -+ static long tx_fifo_size_12 =-1; -+ static long tx_fifo_size_13 =-1; -+ static long tx_fifo_size_14 =-1; -+ static long tx_fifo_size_15 =-1; -+ static short thr_ctl=-1; -+ static long tx_thr_length =-1; -+ static long rx_thr_length =-1; -+ #else -+ static long nperio_tx_fifo_size =-1; -+ static long perio_tx_fifo_size_01 =-1; -+ static long perio_tx_fifo_size_02 =-1; -+ static long perio_tx_fifo_size_03 =-1; -+ static long perio_tx_fifo_size_04 =-1; -+ static long perio_tx_fifo_size_05 =-1; -+ static long perio_tx_fifo_size_06 =-1; -+ static long perio_tx_fifo_size_07 =-1; -+ static long perio_tx_fifo_size_08 =-1; -+ static long perio_tx_fifo_size_09 =-1; -+ static long perio_tx_fifo_size_10 =-1; -+ static long perio_tx_fifo_size_11 =-1; -+ static long perio_tx_fifo_size_12 =-1; -+ static long perio_tx_fifo_size_13 =-1; -+ static long perio_tx_fifo_size_14 =-1; -+ static long perio_tx_fifo_size_15 =-1; -+ #endif -+ static short dev_endpoints =-1; -+#endif -+ -+#ifdef __IS_HOST__ -+ static long rx_fifo_size =-1; -+ static long nperio_tx_fifo_size =-1; -+ static long perio_tx_fifo_size =-1; -+ static short host_channels =-1; -+#endif -+ -+static long max_transfer_size =-1; -+static long max_packet_count =-1; -+static long phy_utmi_width =-1; -+static long turn_around_time_hs =-1; -+static long turn_around_time_fs =-1; -+static long timeout_cal_hs =-1; -+static long timeout_cal_fs =-1; -+ -+/*! -+ \brief Parsing the parameters taken when module load -+*/ -+static void parse_parms(void) -+{ -+ -+ IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ ); -+ #ifdef __IS_HOST__ -+ h_dbg_lvl=dbg_lvl; -+ #endif -+ #ifdef __IS_DEVICE__ -+ d_dbg_lvl=dbg_lvl; -+ #endif -+ -+ switch(dma_burst_size) -+ { -+ case 0: -+ case 1: -+ case 4: -+ case 8: -+ case 16: -+ ifxusb_module_params.dma_burst_size=dma_burst_size; -+ break; -+ default: -+ ifxusb_module_params.dma_burst_size=default_param_dma_burst_size; -+ } -+ -+ if(speed==0 || speed==1) -+ ifxusb_module_params.speed=speed; -+ else -+ ifxusb_module_params.speed=default_param_speed; -+ -+ if(max_transfer_size>=2048 && max_transfer_size<=65535) -+ ifxusb_module_params.max_transfer_size=max_transfer_size; -+ else -+ ifxusb_module_params.max_transfer_size=default_param_max_transfer_size; -+ -+ if(max_packet_count>=15 && max_packet_count<=511) -+ ifxusb_module_params.max_packet_count=max_packet_count; -+ else -+ ifxusb_module_params.max_packet_count=default_param_max_packet_count; -+ -+ switch(phy_utmi_width) -+ { -+ case 8: -+ case 16: -+ ifxusb_module_params.phy_utmi_width=phy_utmi_width; -+ break; -+ default: -+ ifxusb_module_params.phy_utmi_width=default_param_phy_utmi_width; -+ } -+ -+ if(turn_around_time_hs>=0 && turn_around_time_hs<=7) -+ ifxusb_module_params.turn_around_time_hs=turn_around_time_hs; -+ else -+ ifxusb_module_params.turn_around_time_hs=default_param_turn_around_time_hs; -+ -+ if(turn_around_time_fs>=0 && turn_around_time_fs<=7) -+ ifxusb_module_params.turn_around_time_fs=turn_around_time_fs; -+ else -+ ifxusb_module_params.turn_around_time_fs=default_param_turn_around_time_fs; -+ -+ if(timeout_cal_hs>=0 && timeout_cal_hs<=7) -+ ifxusb_module_params.timeout_cal_hs=timeout_cal_hs; -+ else -+ ifxusb_module_params.timeout_cal_hs=default_param_timeout_cal_hs; -+ -+ if(timeout_cal_fs>=0 && timeout_cal_fs<=7) -+ ifxusb_module_params.timeout_cal_fs=timeout_cal_fs; -+ else -+ ifxusb_module_params.timeout_cal_fs=default_param_timeout_cal_fs; -+ -+ if(data_fifo_size>=32 && data_fifo_size<=32768) -+ ifxusb_module_params.data_fifo_size=data_fifo_size; -+ else -+ ifxusb_module_params.data_fifo_size=default_param_data_fifo_size; -+ -+ #ifdef __IS_HOST__ -+ if(host_channels>=1 && host_channels<=16) -+ ifxusb_module_params.host_channels=host_channels; -+ else -+ ifxusb_module_params.host_channels=default_param_host_channels; -+ -+ if(rx_fifo_size>=16 && rx_fifo_size<=32768) -+ ifxusb_module_params.rx_fifo_size=rx_fifo_size; -+ else -+ ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size; -+ -+ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) -+ ifxusb_module_params.nperio_tx_fifo_size=nperio_tx_fifo_size; -+ else -+ ifxusb_module_params.nperio_tx_fifo_size=default_param_nperio_tx_fifo_size; -+ -+ if(perio_tx_fifo_size>=16 && perio_tx_fifo_size<=32768) -+ ifxusb_module_params.perio_tx_fifo_size=perio_tx_fifo_size; -+ else -+ ifxusb_module_params.perio_tx_fifo_size=default_param_perio_tx_fifo_size; -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ if(rx_fifo_size>=16 && rx_fifo_size<=32768) -+ ifxusb_module_params.rx_fifo_size=rx_fifo_size; -+ else -+ ifxusb_module_params.rx_fifo_size=default_param_rx_fifo_size; -+ #ifdef __DED_FIFO__ -+ if(tx_fifo_size_00>=16 && tx_fifo_size_00<=32768) -+ ifxusb_module_params.tx_fifo_size[ 0]=tx_fifo_size_00; -+ else -+ ifxusb_module_params.tx_fifo_size[ 0]=default_param_tx_fifo_size_00; -+ if(tx_fifo_size_01>=0 && tx_fifo_size_01<=32768) -+ ifxusb_module_params.tx_fifo_size[ 1]=tx_fifo_size_01; -+ else -+ ifxusb_module_params.tx_fifo_size[ 1]=default_param_tx_fifo_size_01; -+ if(tx_fifo_size_02>=0 && tx_fifo_size_02<=32768) -+ ifxusb_module_params.tx_fifo_size[ 2]=tx_fifo_size_02; -+ else -+ ifxusb_module_params.tx_fifo_size[ 2]=default_param_tx_fifo_size_02; -+ if(tx_fifo_size_03>=0 && tx_fifo_size_03<=32768) -+ ifxusb_module_params.tx_fifo_size[ 3]=tx_fifo_size_03; -+ else -+ ifxusb_module_params.tx_fifo_size[ 3]=default_param_tx_fifo_size_03; -+ if(tx_fifo_size_04>=0 && tx_fifo_size_04<=32768) -+ ifxusb_module_params.tx_fifo_size[ 4]=tx_fifo_size_04; -+ else -+ ifxusb_module_params.tx_fifo_size[ 4]=default_param_tx_fifo_size_04; -+ if(tx_fifo_size_05>=0 && tx_fifo_size_05<=32768) -+ ifxusb_module_params.tx_fifo_size[ 5]=tx_fifo_size_05; -+ else -+ ifxusb_module_params.tx_fifo_size[ 5]=default_param_tx_fifo_size_05; -+ if(tx_fifo_size_06>=0 && tx_fifo_size_06<=32768) -+ ifxusb_module_params.tx_fifo_size[ 6]=tx_fifo_size_06; -+ else -+ ifxusb_module_params.tx_fifo_size[ 6]=default_param_tx_fifo_size_06; -+ if(tx_fifo_size_07>=0 && tx_fifo_size_07<=32768) -+ ifxusb_module_params.tx_fifo_size[ 7]=tx_fifo_size_07; -+ else -+ ifxusb_module_params.tx_fifo_size[ 7]=default_param_tx_fifo_size_07; -+ if(tx_fifo_size_08>=0 && tx_fifo_size_08<=32768) -+ ifxusb_module_params.tx_fifo_size[ 8]=tx_fifo_size_08; -+ else -+ ifxusb_module_params.tx_fifo_size[ 8]=default_param_tx_fifo_size_08; -+ if(tx_fifo_size_09>=0 && tx_fifo_size_09<=32768) -+ ifxusb_module_params.tx_fifo_size[ 9]=tx_fifo_size_09; -+ else -+ ifxusb_module_params.tx_fifo_size[ 9]=default_param_tx_fifo_size_09; -+ if(tx_fifo_size_10>=0 && tx_fifo_size_10<=32768) -+ ifxusb_module_params.tx_fifo_size[10]=tx_fifo_size_10; -+ else -+ ifxusb_module_params.tx_fifo_size[10]=default_param_tx_fifo_size_10; -+ if(tx_fifo_size_11>=0 && tx_fifo_size_11<=32768) -+ ifxusb_module_params.tx_fifo_size[11]=tx_fifo_size_11; -+ else -+ ifxusb_module_params.tx_fifo_size[11]=default_param_tx_fifo_size_11; -+ if(tx_fifo_size_12>=0 && tx_fifo_size_12<=32768) -+ ifxusb_module_params.tx_fifo_size[12]=tx_fifo_size_12; -+ else -+ ifxusb_module_params.tx_fifo_size[12]=default_param_tx_fifo_size_12; -+ if(tx_fifo_size_13>=0 && tx_fifo_size_13<=32768) -+ ifxusb_module_params.tx_fifo_size[13]=tx_fifo_size_13; -+ else -+ ifxusb_module_params.tx_fifo_size[13]=default_param_tx_fifo_size_13; -+ if(tx_fifo_size_14>=0 && tx_fifo_size_14<=32768) -+ ifxusb_module_params.tx_fifo_size[14]=tx_fifo_size_14; -+ else -+ ifxusb_module_params.tx_fifo_size[14]=default_param_tx_fifo_size_14; -+ if(tx_fifo_size_15>=0 && tx_fifo_size_15<=32768) -+ ifxusb_module_params.tx_fifo_size[15]=tx_fifo_size_15; -+ else -+ ifxusb_module_params.tx_fifo_size[15]=default_param_tx_fifo_size_15; -+ if(thr_ctl==0 || thr_ctl==1) -+ ifxusb_module_params.thr_ctl=thr_ctl; -+ else -+ ifxusb_module_params.thr_ctl=default_param_thr_ctl; -+ if(tx_thr_length>=16 && tx_thr_length<=511) -+ ifxusb_module_params.tx_thr_length=tx_thr_length; -+ else -+ ifxusb_module_params.tx_thr_length=default_param_tx_thr_length; -+ if(rx_thr_length>=16 && rx_thr_length<=511) -+ ifxusb_module_params.rx_thr_length=rx_thr_length; -+ else -+ ifxusb_module_params.rx_thr_length=default_param_rx_thr_length; -+ #else //__DED_FIFO__ -+ if(nperio_tx_fifo_size>=16 && nperio_tx_fifo_size<=32768) -+ ifxusb_module_params.tx_fifo_size[ 0]=nperio_tx_fifo_size; -+ else -+ ifxusb_module_params.tx_fifo_size[ 0]=default_param_nperio_tx_fifo_size; -+ if(perio_tx_fifo_size_01>=0 && perio_tx_fifo_size_01<=32768) -+ ifxusb_module_params.tx_fifo_size[ 1]=perio_tx_fifo_size_01; -+ else -+ ifxusb_module_params.tx_fifo_size[ 1]=default_param_perio_tx_fifo_size_01; -+ if(perio_tx_fifo_size_02>=0 && perio_tx_fifo_size_02<=32768) -+ ifxusb_module_params.tx_fifo_size[ 2]=perio_tx_fifo_size_02; -+ else -+ ifxusb_module_params.tx_fifo_size[ 2]=default_param_perio_tx_fifo_size_02; -+ if(perio_tx_fifo_size_03>=0 && perio_tx_fifo_size_03<=32768) -+ ifxusb_module_params.tx_fifo_size[ 3]=perio_tx_fifo_size_03; -+ else -+ ifxusb_module_params.tx_fifo_size[ 3]=default_param_perio_tx_fifo_size_03; -+ if(perio_tx_fifo_size_04>=0 && perio_tx_fifo_size_04<=32768) -+ ifxusb_module_params.tx_fifo_size[ 4]=perio_tx_fifo_size_04; -+ else -+ ifxusb_module_params.tx_fifo_size[ 4]=default_param_perio_tx_fifo_size_04; -+ if(perio_tx_fifo_size_05>=0 && perio_tx_fifo_size_05<=32768) -+ ifxusb_module_params.tx_fifo_size[ 5]=perio_tx_fifo_size_05; -+ else -+ ifxusb_module_params.tx_fifo_size[ 5]=default_param_perio_tx_fifo_size_05; -+ if(perio_tx_fifo_size_06>=0 && perio_tx_fifo_size_06<=32768) -+ ifxusb_module_params.tx_fifo_size[ 6]=perio_tx_fifo_size_06; -+ else -+ ifxusb_module_params.tx_fifo_size[ 6]=default_param_perio_tx_fifo_size_06; -+ if(perio_tx_fifo_size_07>=0 && perio_tx_fifo_size_07<=32768) -+ ifxusb_module_params.tx_fifo_size[ 7]=perio_tx_fifo_size_07; -+ else -+ ifxusb_module_params.tx_fifo_size[ 7]=default_param_perio_tx_fifo_size_07; -+ if(perio_tx_fifo_size_08>=0 && perio_tx_fifo_size_08<=32768) -+ ifxusb_module_params.tx_fifo_size[ 8]=perio_tx_fifo_size_08; -+ else -+ ifxusb_module_params.tx_fifo_size[ 8]=default_param_perio_tx_fifo_size_08; -+ if(perio_tx_fifo_size_09>=0 && perio_tx_fifo_size_09<=32768) -+ ifxusb_module_params.tx_fifo_size[ 9]=perio_tx_fifo_size_09; -+ else -+ ifxusb_module_params.tx_fifo_size[ 9]=default_param_perio_tx_fifo_size_09; -+ if(perio_tx_fifo_size_10>=0 && perio_tx_fifo_size_10<=32768) -+ ifxusb_module_params.tx_fifo_size[10]=perio_tx_fifo_size_10; -+ else -+ ifxusb_module_params.tx_fifo_size[10]=default_param_perio_tx_fifo_size_10; -+ if(perio_tx_fifo_size_11>=0 && perio_tx_fifo_size_11<=32768) -+ ifxusb_module_params.tx_fifo_size[11]=perio_tx_fifo_size_11; -+ else -+ ifxusb_module_params.tx_fifo_size[11]=default_param_perio_tx_fifo_size_11; -+ if(perio_tx_fifo_size_12>=0 && perio_tx_fifo_size_12<=32768) -+ ifxusb_module_params.tx_fifo_size[12]=perio_tx_fifo_size_12; -+ else -+ ifxusb_module_params.tx_fifo_size[12]=default_param_perio_tx_fifo_size_12; -+ if(perio_tx_fifo_size_13>=0 && perio_tx_fifo_size_13<=32768) -+ ifxusb_module_params.tx_fifo_size[13]=perio_tx_fifo_size_13; -+ else -+ ifxusb_module_params.tx_fifo_size[13]=default_param_perio_tx_fifo_size_13; -+ if(perio_tx_fifo_size_14>=0 && perio_tx_fifo_size_14<=32768) -+ ifxusb_module_params.tx_fifo_size[14]=perio_tx_fifo_size_14; -+ else -+ ifxusb_module_params.tx_fifo_size[14]=default_param_perio_tx_fifo_size_14; -+ if(perio_tx_fifo_size_15>=0 && perio_tx_fifo_size_15<=32768) -+ ifxusb_module_params.tx_fifo_size[15]=perio_tx_fifo_size_15; -+ else -+ ifxusb_module_params.tx_fifo_size[15]=default_param_perio_tx_fifo_size_15; -+ #endif //__DED_FIFO__ -+ #endif //__IS_DEVICE__ -+} -+ -+ -+ -+ -+ -+ -+ -+module_param(dbg_lvl, long, 0444); -+MODULE_PARM_DESC(dbg_lvl, "Debug level."); -+ -+module_param(dma_burst_size, short, 0444); -+MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 0, 1, 4, 8, 16"); -+ -+module_param(speed, short, 0444); -+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed"); -+ -+module_param(data_fifo_size, long, 0444); -+MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768"); -+ -+#ifdef __IS_DEVICE__ -+ module_param(rx_fifo_size, long, 0444); -+ MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); -+ -+ #ifdef __DED_FIFO__ -+ module_param(tx_fifo_size_00, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_00, "Number of words in the Tx FIFO #00 16-32768"); -+ module_param(tx_fifo_size_01, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_01, "Number of words in the Tx FIFO #01 0-32768"); -+ module_param(tx_fifo_size_02, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_02, "Number of words in the Tx FIFO #02 0-32768"); -+ module_param(tx_fifo_size_03, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_03, "Number of words in the Tx FIFO #03 0-32768"); -+ module_param(tx_fifo_size_04, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_04, "Number of words in the Tx FIFO #04 0-32768"); -+ module_param(tx_fifo_size_05, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_05, "Number of words in the Tx FIFO #05 0-32768"); -+ module_param(tx_fifo_size_06, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_06, "Number of words in the Tx FIFO #06 0-32768"); -+ module_param(tx_fifo_size_07, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_07, "Number of words in the Tx FIFO #07 0-32768"); -+ module_param(tx_fifo_size_08, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_08, "Number of words in the Tx FIFO #08 0-32768"); -+ module_param(tx_fifo_size_09, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_09, "Number of words in the Tx FIFO #09 0-32768"); -+ module_param(tx_fifo_size_10, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_10, "Number of words in the Tx FIFO #10 0-32768"); -+ module_param(tx_fifo_size_11, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_11, "Number of words in the Tx FIFO #11 0-32768"); -+ module_param(tx_fifo_size_12, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_12, "Number of words in the Tx FIFO #12 0-32768"); -+ module_param(tx_fifo_size_13, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_13, "Number of words in the Tx FIFO #13 0-32768"); -+ module_param(tx_fifo_size_14, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_14, "Number of words in the Tx FIFO #14 0-32768"); -+ module_param(tx_fifo_size_15, long, 0444); -+ MODULE_PARM_DESC(tx_fifo_size_15, "Number of words in the Tx FIFO #15 0-32768"); -+ -+ module_param(thr_ctl, short, 0444); -+ MODULE_PARM_DESC(thr_ctl, "0=Without 1=With Theshold Ctrl"); -+ -+ module_param(tx_thr_length, long, 0444); -+ MODULE_PARM_DESC(tx_thr_length, "TX Threshold length"); -+ -+ module_param(rx_thr_length, long, 0444); -+ MODULE_PARM_DESC(rx_thr_length, "RX Threshold length"); -+ -+ #else -+ module_param(nperio_tx_fifo_size, long, 0444); -+ MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768"); -+ -+ module_param(perio_tx_fifo_size_01, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_01, "Number of words in the periodic Tx FIFO #01 0-32768"); -+ module_param(perio_tx_fifo_size_02, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_02, "Number of words in the periodic Tx FIFO #02 0-32768"); -+ module_param(perio_tx_fifo_size_03, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_03, "Number of words in the periodic Tx FIFO #03 0-32768"); -+ module_param(perio_tx_fifo_size_04, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_04, "Number of words in the periodic Tx FIFO #04 0-32768"); -+ module_param(perio_tx_fifo_size_05, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_05, "Number of words in the periodic Tx FIFO #05 0-32768"); -+ module_param(perio_tx_fifo_size_06, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_06, "Number of words in the periodic Tx FIFO #06 0-32768"); -+ module_param(perio_tx_fifo_size_07, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_07, "Number of words in the periodic Tx FIFO #07 0-32768"); -+ module_param(perio_tx_fifo_size_08, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_08, "Number of words in the periodic Tx FIFO #08 0-32768"); -+ module_param(perio_tx_fifo_size_09, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_09, "Number of words in the periodic Tx FIFO #09 0-32768"); -+ module_param(perio_tx_fifo_size_10, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO #10 0-32768"); -+ module_param(perio_tx_fifo_size_11, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO #11 0-32768"); -+ module_param(perio_tx_fifo_size_12, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO #12 0-32768"); -+ module_param(perio_tx_fifo_size_13, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO #13 0-32768"); -+ module_param(perio_tx_fifo_size_14, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO #14 0-32768"); -+ module_param(perio_tx_fifo_size_15, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO #15 0-32768"); -+ #endif//__DED_FIFO__ -+ module_param(dev_endpoints, short, 0444); -+ MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15"); -+#endif -+ -+#ifdef __IS_HOST__ -+ module_param(rx_fifo_size, long, 0444); -+ MODULE_PARM_DESC(rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); -+ -+ module_param(nperio_tx_fifo_size, long, 0444); -+ MODULE_PARM_DESC(nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768"); -+ -+ module_param(perio_tx_fifo_size, long, 0444); -+ MODULE_PARM_DESC(perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768"); -+ -+ module_param(host_channels, short, 0444); -+ MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16"); -+#endif -+ -+module_param(max_transfer_size, long, 0444); -+MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535"); -+ -+module_param(max_packet_count, long, 0444); -+MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511"); -+ -+module_param(phy_utmi_width, long, 0444); -+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits"); -+ -+module_param(turn_around_time_hs, long, 0444); -+MODULE_PARM_DESC(turn_around_time_hs, "Turn-Around time for HS"); -+ -+module_param(turn_around_time_fs, long, 0444); -+MODULE_PARM_DESC(turn_around_time_fs, "Turn-Around time for FS"); -+ -+module_param(timeout_cal_hs, long, 0444); -+MODULE_PARM_DESC(timeout_cal_hs, "Timeout Cal for HS"); -+ -+module_param(timeout_cal_fs, long, 0444); -+MODULE_PARM_DESC(timeout_cal_fs, "Timeout Cal for FS"); -+ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_plat.h -@@ -0,0 +1,1018 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_plat.h -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the Platform Specific constants, interfaces -+ ** (functions and macros). -+ ** FUNCTIONS : -+ ** COMPILER : gcc -+ ** REFERENCE : IFX hardware ref handbook for each plateforms -+ ** COPYRIGHT : -+ ** Version Control Section ** -+ ** $Author$ -+ ** $Date$ -+ ** $Revisions$ -+ ** $Log$ Revision history -+ *****************************************************************************/ -+ -+ -+/*! -+ \defgroup IFXUSB_PLATEFORM_DEFINITION Platform Specific constants, interfaces (functions and macros). -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief Maintain plateform specific definitions and macros in this file. -+ Each plateform has its own definition zone. -+ */ -+ -+/*! -+ \defgroup IFXUSB_PLATEFORM_MEM_ADDR Definition of memory address and size and default parameters -+ \ingroup IFXUSB_PLATEFORM_DEFINITION -+ */ -+ -+/*! -+ \defgroup IFXUSB_DBG_ROUTINE Routines for debug message -+ \ingroup IFXUSB_PLATEFORM_DEFINITION -+ */ -+ -+ -+/*! \file ifxusb_plat.h -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the Platform Specific constants, interfaces (functions and macros). -+*/ -+ -+#if !defined(__IFXUSB_PLAT_H__) -+#define __IFXUSB_PLAT_H__ -+ -+ -+#include <linux/types.h> -+#include <linux/slab.h> -+#include <linux/list.h> -+#include <linux/delay.h> -+#include <asm/io.h> -+ -+ -+#define IFXUSB_IOMEM_SIZE 0x00001000 -+#define IFXUSB_FIFOMEM_SIZE 0x00010000 -+#define IFXUSB_FIFODBG_SIZE 0x00020000 -+ -+ -+ -+/*! -+ \addtogroup IFXUSB_PLATEFORM_MEM_ADDR -+ */ -+/*@{*/ -+#if defined(__UEIP__) -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+// #define IFXUSB_IRQ 54 -+ #define IFXUSB_IOMEM_BASE 0x1e101000 -+ #define IFXUSB_FIFOMEM_BASE 0x1e120000 -+ #define IFXUSB_FIFODBG_BASE 0x1e140000 -+// #define IFXUSB_OC_IRQ 151 -+ -+ #ifndef DANUBE_RCU_BASE_ADDR -+ #define DANUBE_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef DANUBE_CGU -+ #define DANUBE_CGU (0xBF103000) -+ #endif -+ #ifndef DANUBE_CGU_IFCCR -+ #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018)) -+ #endif -+ #ifndef DANUBE_PMU -+ #define DANUBE_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef DANUBE_PMU_PWDCR -+ #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C)) -+ #endif -+ -+ #ifndef DANUBE_GPIO_P0_OUT -+ #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10) -+ #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18) -+ #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define DANUBE_GPIO_P0_OD (0xBF103000+0x24) -+ #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40) -+ #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48) -+ #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define DANUBE_GPIO_P1_OD (0xBF103000+0x54) -+ #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18)) -+ #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10)) -+ #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 -+ #define default_param_turn_around_time_fs 4 -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 640 -+ #define default_param_nperio_tx_fifo_size 640 -+ #define default_param_perio_tx_fifo_size 768 -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 1024 -+ #define default_param_nperio_tx_fifo_size 1016 -+ #define default_param_perio_tx_fifo_size_01 8 -+ #else -+ #define default_param_rx_fifo_size 1024 -+ #define default_param_nperio_tx_fifo_size 1024 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_AMAZON_SE__) -+ //#include <asm/amazon_se/amazon_se.h> -+ //#include <asm/amazon_se/irq.h> -+ -+// #define IFXUSB_IRQ 31 -+ #define IFXUSB_IOMEM_BASE 0x1e101000 -+ #define IFXUSB_FIFOMEM_BASE 0x1e120000 -+ #define IFXUSB_FIFODBG_BASE 0x1e140000 -+// #define IFXUSB_OC_IRQ 20 -+ -+ #ifndef AMAZON_SE_RCU_BASE_ADDR -+ #define AMAZON_SE_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18)) -+ #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10)) -+ #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end -+ -+ #ifndef AMAZON_SE_GPIO_P0_OUT -+ #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10) -+ #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18) -+ #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24) -+ #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40) -+ #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48) -+ #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54) -+ #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #ifndef AMAZON_SE_CGU -+ #define AMAZON_SE_CGU (0xBF103000) -+ #endif -+ #ifndef AMAZON_SE_CGU_IFCCR -+ #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018)) -+ #endif -+ #ifndef AMAZON_SE_PMU -+ #define AMAZON_SE_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef AMAZON_SE_PMU_PWDCR -+ #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C)) -+ #endif -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 //(NoChange) -+ #define default_param_turn_around_time_fs 4 //(NoChange) -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 248 -+ #define default_param_perio_tx_fifo_size_01 8 -+ #else -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 256 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_AR9__) -+// #define IFXUSB1_IRQ 54 -+ #define IFXUSB1_IOMEM_BASE 0x1E101000 -+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000 -+ #define IFXUSB1_FIFODBG_BASE 0x1E140000 -+ -+// #define IFXUSB2_IRQ 83 -+ #define IFXUSB2_IOMEM_BASE 0x1E106000 -+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000 -+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000 -+ -+// #define IFXUSB_OC_IRQ 60 -+ -+ #ifndef AR9_RCU_BASE_ADDR -+ #define AR9_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef AR9_CGU -+ #define AR9_CGU (0xBF103000) -+ #endif -+ #ifndef AR9_CGU_IFCCR -+ #define AR9_CGU_IFCCR ((volatile unsigned long *)(AR9_CGU+ 0x0018)) -+ #endif -+ -+ #ifndef AR9_PMU -+ #define AR9_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef AR9_PMU_PWDCR -+ #define AR9_PMU_PWDCR ((volatile unsigned long *)(AR9_PMU+0x001C)) -+ #endif -+ -+ #ifndef AR9_GPIO_P0_OUT -+ #define AR9_GPIO_P0_OUT (0xBF103000+0x10) -+ #define AR9_GPIO_P0_DIR (0xBF103000+0x18) -+ #define AR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define AR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define AR9_GPIO_P0_OD (0xBF103000+0x24) -+ #define AR9_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define AR9_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define AR9_GPIO_P1_OUT (0xBF103000+0x40) -+ #define AR9_GPIO_P1_DIR (0xBF103000+0x48) -+ #define AR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define AR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define AR9_GPIO_P1_OD (0xBF103000+0x54) -+ #define AR9_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define AR9_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #define AR9_RCU_USB1CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x18)) -+ #define AR9_RCU_USB2CFG ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x34)) -+ #define AR9_RCU_USBRESET ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x10)) -+ #define AR9_USBCFG_ARB 7 // -+ #define AR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define AR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define AR9_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 //(NoChange) -+ #define default_param_turn_around_time_fs 4 //(NoChange) -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 256 -+// #define default_param_nperio_tx_fifo_size 248 -+// #define default_param_perio_tx_fifo_size_01 8 -+ #define default_param_nperio_tx_fifo_size 252 -+ #define default_param_perio_tx_fifo_size_01 4 -+ #else -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 256 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_VR9__) -+// #define IFXUSB1_IRQ 54 -+ #define IFXUSB1_IOMEM_BASE 0x1E101000 -+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000 -+ #define IFXUSB1_FIFODBG_BASE 0x1E140000 -+ -+// #define IFXUSB2_IRQ 83 -+ #define IFXUSB2_IOMEM_BASE 0x1E106000 -+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000 -+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000 -+// #define IFXUSB_OC_IRQ 60 -+ -+ #ifndef VR9_RCU_BASE_ADDR -+ #define VR9_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef VR9_CGU -+ #define VR9_CGU (0xBF103000) -+ #endif -+ #ifndef VR9_CGU_IFCCR -+ #define VR9_CGU_IFCCR ((volatile unsigned long *)(VR9_CGU+ 0x0018)) -+ #endif -+ -+ #ifndef VR9_PMU -+ #define VR9_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef VR9_PMU_PWDCR -+ #define VR9_PMU_PWDCR ((volatile unsigned long *)(VR9_PMU+0x001C)) -+ #endif -+ -+ #ifndef VR9_GPIO_P0_OUT -+ #define VR9_GPIO_P0_OUT (0xBF103000+0x10) -+ #define VR9_GPIO_P0_DIR (0xBF103000+0x18) -+ #define VR9_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define VR9_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define VR9_GPIO_P0_OD (0xBF103000+0x24) -+ #define VR9_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define VR9_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define VR9_GPIO_P1_OUT (0xBF103000+0x40) -+ #define VR9_GPIO_P1_DIR (0xBF103000+0x48) -+ #define VR9_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define VR9_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define VR9_GPIO_P1_OD (0xBF103000+0x54) -+ #define VR9_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define VR9_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #define VR9_RCU_USB1CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x18)) -+ #define VR9_RCU_USB2CFG ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x34)) -+ #define VR9_RCU_USB_ANA_CFG1A ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x38)) -+ #define VR9_RCU_USB_ANA_CFG1B ((volatile unsigned long *)(AR9_RCU_BASE_ADDR + 0x3C)) -+ #define VR9_RCU_USBRESET ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x10)) -+ #define VR9_RCU_USBRESET2 ((volatile unsigned long *)(VR9_RCU_BASE_ADDR + 0x48)) -+ #define VR9_USBCFG_ARB 7 // -+ #define VR9_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define VR9_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define VR9_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end -+ -+ /*== AVM/BC 20101220 Workaround VR9 DMA burst size == -+ * Using 2 Devices in diferent ports cause a general USB Host Error. -+ * Workaround found in UGW4.3 -+ */ -+// #define default_param_dma_burst_size 4 //(ALL) -+ //WA for AHB -+ #define default_param_dma_burst_size 0 //(ALL) -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a -+ #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+#if 0 -+ #define default_param_rx_fifo_size 256 -+ #define default_param_tx_fifo_size_00 -1 -+ #define default_param_tx_fifo_size_01 -1 -+ #define default_param_tx_fifo_size_02 -1 -+#else -+ #define default_param_rx_fifo_size 256 -+ #define default_param_tx_fifo_size_00 32 -+ #define default_param_tx_fifo_size_01 200 -+ #define default_param_tx_fifo_size_02 8 -+#endif -+ #define default_param_tx_fifo_size_03 -1 -+ #define default_param_tx_fifo_size_04 -1 -+ #define default_param_tx_fifo_size_05 -1 -+ #define default_param_tx_fifo_size_06 -1 -+ #define default_param_tx_fifo_size_07 -1 -+ #define default_param_tx_fifo_size_08 -1 -+ #define default_param_tx_fifo_size_09 -1 -+ #define default_param_tx_fifo_size_10 -1 -+ #define default_param_tx_fifo_size_11 -1 -+ #define default_param_tx_fifo_size_12 -1 -+ #define default_param_tx_fifo_size_13 -1 -+ #define default_param_tx_fifo_size_14 -1 -+ #define default_param_tx_fifo_size_15 -1 -+ #define default_param_dma_unalgned_tx -1 -+ #define default_param_dma_unalgned_rx -1 -+ #define default_param_thr_ctl -1 -+ #define default_param_tx_thr_length -1 -+ #define default_param_rx_thr_length -1 -+ #endif //__IS_DEVICE__ -+ #else // __IS_VR9__ -+ #error "Please choose one platform!!" -+ #endif // __IS_VR9__ -+ -+#else //UEIP -+ #if defined(__IS_TWINPASS__) || defined(__IS_DANUBE__) -+// #define IFXUSB_IRQ 54 -+ #define IFXUSB_IOMEM_BASE 0x1e101000 -+ #define IFXUSB_FIFOMEM_BASE 0x1e120000 -+ #define IFXUSB_FIFODBG_BASE 0x1e140000 -+// #define IFXUSB_OC_IRQ 151 -+ -+ -+ #ifndef DANUBE_RCU_BASE_ADDR -+ #define DANUBE_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef DANUBE_CGU -+ #define DANUBE_CGU (0xBF103000) -+ #endif -+ #ifndef DANUBE_CGU_IFCCR -+ #define DANUBE_CGU_IFCCR ((volatile unsigned long *)(DANUBE_CGU+ 0x0018)) -+ #endif -+ #ifndef DANUBE_PMU -+ #define DANUBE_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef DANUBE_PMU_PWDCR -+ #define DANUBE_PMU_PWDCR ((volatile unsigned long *)(DANUBE_PMU+0x001C)) -+ #endif -+ -+ #ifndef DANUBE_GPIO_P0_OUT -+ #define DANUBE_GPIO_P0_OUT (0xBF103000+0x10) -+ #define DANUBE_GPIO_P0_DIR (0xBF103000+0x18) -+ #define DANUBE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define DANUBE_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define DANUBE_GPIO_P0_OD (0xBF103000+0x24) -+ #define DANUBE_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define DANUBE_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define DANUBE_GPIO_P1_OUT (0xBF103000+0x40) -+ #define DANUBE_GPIO_P1_DIR (0xBF103000+0x48) -+ #define DANUBE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define DANUBE_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define DANUBE_GPIO_P1_OD (0xBF103000+0x54) -+ #define DANUBE_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define DANUBE_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ -+ #define DANUBE_RCU_USBCFG ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x18)) -+ #define DANUBE_RCU_RESET ((volatile unsigned long *)(DANUBE_RCU_BASE_ADDR + 0x10)) -+ #define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 //(NoChange) -+ #define default_param_turn_around_time_fs 4 //(NoChange) -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 640 -+ #define default_param_nperio_tx_fifo_size 640 -+ #define default_param_perio_tx_fifo_size 768 -+ #endif //__IS_HOST__ -+ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 1024 -+ #define default_param_nperio_tx_fifo_size 1016 -+ #define default_param_perio_tx_fifo_size_01 8 -+ #else -+ #define default_param_rx_fifo_size 1024 -+ #define default_param_nperio_tx_fifo_size 1024 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_AMAZON_SE__) -+ #include <asm/amazon_se/amazon_se.h> -+ //#include <asm/amazon_se/irq.h> -+ -+// #define IFXUSB_IRQ 31 -+ #define IFXUSB_IOMEM_BASE 0x1e101000 -+ #define IFXUSB_FIFOMEM_BASE 0x1e120000 -+ #define IFXUSB_FIFODBG_BASE 0x1e140000 -+// #define IFXUSB_OC_IRQ 20 -+ -+ #define AMAZON_SE_RCU_USBCFG ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x18)) -+ #define AMAZON_SE_RCU_RESET ((volatile unsigned long *)(AMAZON_SE_RCU_BASE_ADDR + 0x10)) -+ #define AMAZON_SE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define AMAZON_SE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define AMAZON_SE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end -+ -+ #ifndef AMAZON_SE_GPIO_P0_OUT -+ #define AMAZON_SE_GPIO_P0_OUT (0xBF103000+0x10) -+ #define AMAZON_SE_GPIO_P0_DIR (0xBF103000+0x18) -+ #define AMAZON_SE_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define AMAZON_SE_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define AMAZON_SE_GPIO_P0_OD (0xBF103000+0x24) -+ #define AMAZON_SE_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define AMAZON_SE_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define AMAZON_SE_GPIO_P1_OUT (0xBF103000+0x40) -+ #define AMAZON_SE_GPIO_P1_DIR (0xBF103000+0x48) -+ #define AMAZON_SE_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define AMAZON_SE_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define AMAZON_SE_GPIO_P1_OD (0xBF103000+0x54) -+ #define AMAZON_SE_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define AMAZON_SE_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ -+ #ifndef AMAZON_SE_CGU -+ #define AMAZON_SE_CGU (0xBF103000) -+ #endif -+ #ifndef AMAZON_SE_CGU_IFCCR -+ #define AMAZON_SE_CGU_IFCCR ((volatile unsigned long *)(AMAZON_SE_CGU+ 0x0018)) -+ #endif -+ #ifndef AMAZON_SE_PMU -+ #define AMAZON_SE_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef AMAZON_SE_PMU_PWDCR -+ #define AMAZON_SE_PMU_PWDCR ((volatile unsigned long *)(AMAZON_SE_PMU+0x001C)) -+ #endif -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 //(NoChange) -+ #define default_param_turn_around_time_fs 4 //(NoChange) -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 248 -+ #define default_param_perio_tx_fifo_size_01 8 -+ #else -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 256 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_AR9__) -+// #define IFXUSB1_IRQ 54 -+ #define IFXUSB1_IOMEM_BASE 0x1E101000 -+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000 -+ #define IFXUSB1_FIFODBG_BASE 0x1E140000 -+ -+// #define IFXUSB2_IRQ 83 -+ #define IFXUSB2_IOMEM_BASE 0x1E106000 -+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000 -+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000 -+ -+// #define IFXUSB_OC_IRQ 60 -+ -+ #ifndef AMAZON_S_RCU_BASE_ADDR -+ #define AMAZON_S_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef AMAZON_S_CGU -+ #define AMAZON_S_CGU (0xBF103000) -+ #endif -+ #ifndef AMAZON_S_CGU_IFCCR -+ #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018)) -+ #endif -+ -+ #ifndef AMAZON_S_PMU -+ #define AMAZON_S_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef AMAZON_S_PMU_PWDCR -+ #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C)) -+ #endif -+ -+ #ifndef AMAZON_S_GPIO_P0_OUT -+ #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10) -+ #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18) -+ #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24) -+ #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40) -+ #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48) -+ #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54) -+ #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18)) -+ #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34)) -+ #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10)) -+ #define AMAZON_S_USBCFG_ARB 7 // -+ #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end -+ -+ #define default_param_dma_burst_size 4 -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 4 //(NoChange) -+ #define default_param_turn_around_time_fs 4 //(NoChange) -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ #ifdef __DED_INTR__ -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 248 -+ #define default_param_perio_tx_fifo_size_01 8 -+ #else -+ #define default_param_rx_fifo_size 256 -+ #define default_param_nperio_tx_fifo_size 256 -+ #define default_param_perio_tx_fifo_size_01 0 -+ #endif -+ #define default_param_perio_tx_fifo_size_02 0 -+ #define default_param_perio_tx_fifo_size_03 0 -+ #define default_param_perio_tx_fifo_size_04 0 -+ #define default_param_perio_tx_fifo_size_05 0 -+ #define default_param_perio_tx_fifo_size_06 0 -+ #define default_param_perio_tx_fifo_size_07 0 -+ #define default_param_perio_tx_fifo_size_08 0 -+ #define default_param_perio_tx_fifo_size_09 0 -+ #define default_param_perio_tx_fifo_size_10 0 -+ #define default_param_perio_tx_fifo_size_11 0 -+ #define default_param_perio_tx_fifo_size_12 0 -+ #define default_param_perio_tx_fifo_size_13 0 -+ #define default_param_perio_tx_fifo_size_14 0 -+ #define default_param_perio_tx_fifo_size_15 0 -+ #endif //__IS_DEVICE__ -+ -+ #elif defined(__IS_VR9__) -+// #define IFXUSB1_IRQ 54 -+ #define IFXUSB1_IOMEM_BASE 0x1E101000 -+ #define IFXUSB1_FIFOMEM_BASE 0x1E120000 -+ #define IFXUSB1_FIFODBG_BASE 0x1E140000 -+ -+// #define IFXUSB2_IRQ 83 -+ #define IFXUSB2_IOMEM_BASE 0x1E106000 -+ #define IFXUSB2_FIFOMEM_BASE 0x1E1E0000 -+ #define IFXUSB2_FIFODBG_BASE 0x1E1C0000 -+// #define IFXUSB_OC_IRQ 60 -+ -+ #ifndef AMAZON_S_RCU_BASE_ADDR -+ #define AMAZON_S_RCU_BASE_ADDR (0xBF203000) -+ #endif -+ -+ #ifndef AMAZON_S_CGU -+ #define AMAZON_S_CGU (0xBF103000) -+ #endif -+ #ifndef AMAZON_S_CGU_IFCCR -+ #define AMAZON_S_CGU_IFCCR ((volatile unsigned long *)(AMAZON_S_CGU+ 0x0018)) -+ #endif -+ -+ #ifndef AMAZON_S_PMU -+ #define AMAZON_S_PMU (KSEG1+0x1F102000) -+ #endif -+ #ifndef AMAZON_S_PMU_PWDCR -+ #define AMAZON_S_PMU_PWDCR ((volatile unsigned long *)(AMAZON_S_PMU+0x001C)) -+ #endif -+ -+ #ifndef AMAZON_S_GPIO_P0_OUT -+ #define AMAZON_S_GPIO_P0_OUT (0xBF103000+0x10) -+ #define AMAZON_S_GPIO_P0_DIR (0xBF103000+0x18) -+ #define AMAZON_S_GPIO_P0_ALTSEL0 (0xBF103000+0x1C) -+ #define AMAZON_S_GPIO_P0_ALTSEL1 (0xBF103000+0x20) -+ #define AMAZON_S_GPIO_P0_OD (0xBF103000+0x24) -+ #define AMAZON_S_GPIO_P0_PUDSEL (0xBF103000+0x2C) -+ #define AMAZON_S_GPIO_P0_PUDEN (0xBF103000+0x30) -+ #define AMAZON_S_GPIO_P1_OUT (0xBF103000+0x40) -+ #define AMAZON_S_GPIO_P1_DIR (0xBF103000+0x48) -+ #define AMAZON_S_GPIO_P1_ALTSEL0 (0xBF103000+0x4C) -+ #define AMAZON_S_GPIO_P1_ALTSEL1 (0xBF103000+0x50) -+ #define AMAZON_S_GPIO_P1_OD (0xBF103000+0x54) -+ #define AMAZON_S_GPIO_P1_PUDSEL (0xBF103000+0x5C) -+ #define AMAZON_S_GPIO_P1_PUDEN (0xBF103000+0x60) -+ #endif -+ -+ #define AMAZON_S_RCU_USB1CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x18)) -+ #define AMAZON_S_RCU_USB2CFG ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x34)) -+ #define AMAZON_S_RCU_USBRESET ((volatile unsigned long *)(AMAZON_S_RCU_BASE_ADDR + 0x10)) -+ #define AMAZON_S_USBCFG_ARB 7 // -+ #define AMAZON_S_USBCFG_HDSEL_BIT 11 // 0:host, 1:device -+ #define AMAZON_S_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end -+ #define AMAZON_S_USBCFG_SLV_END_BIT 17 // 0:little_end, 1:big_end -+ -+ #define default_param_dma_burst_size 4 //(ALL) -+ -+ #define default_param_speed IFXUSB_PARAM_SPEED_HIGH -+ -+ #define default_param_max_transfer_size -1 //(Max, hwcfg) -+ #define default_param_max_packet_count -1 //(Max, hwcfg) -+ #define default_param_phy_utmi_width 16 -+ -+ #define default_param_turn_around_time_hs 6 //(NoChange) snpsid >= 0x4f54260a -+ #define default_param_turn_around_time_fs 6 //(NoChange) snpsid >= 0x4f54260a -+ #define default_param_timeout_cal_hs -1 //(NoChange) -+ #define default_param_timeout_cal_fs -1 //(NoChange) -+ -+ #define default_param_data_fifo_size -1 //(Max, hwcfg) -+ -+ #ifdef __IS_HOST__ -+ #define default_param_host_channels -1 //(Max, hwcfg) -+ #define default_param_rx_fifo_size 240 -+ #define default_param_nperio_tx_fifo_size 240 -+ #define default_param_perio_tx_fifo_size 32 -+ #endif //__IS_HOST__ -+ #ifdef __IS_DEVICE__ -+ #define default_param_rx_fifo_size 256 -+ #define default_param_tx_fifo_size_00 -1 -+ #define default_param_tx_fifo_size_01 -1 -+ #define default_param_tx_fifo_size_02 -1 -+ #define default_param_tx_fifo_size_03 -1 -+ #define default_param_tx_fifo_size_04 -1 -+ #define default_param_tx_fifo_size_05 -1 -+ #define default_param_tx_fifo_size_06 -1 -+ #define default_param_tx_fifo_size_07 -1 -+ #define default_param_tx_fifo_size_08 -1 -+ #define default_param_tx_fifo_size_09 -1 -+ #define default_param_tx_fifo_size_10 -1 -+ #define default_param_tx_fifo_size_11 -1 -+ #define default_param_tx_fifo_size_12 -1 -+ #define default_param_tx_fifo_size_13 -1 -+ #define default_param_tx_fifo_size_14 -1 -+ #define default_param_tx_fifo_size_15 -1 -+ #define default_param_dma_unalgned_tx -1 -+ #define default_param_dma_unalgned_rx -1 -+ #define default_param_thr_ctl -1 -+ #define default_param_tx_thr_length -1 -+ #define default_param_rx_thr_length -1 -+ #endif //__IS_DEVICE__ -+ #else // __IS_VR9__ -+ #error "Please choose one platform!!" -+ #endif // __IS_VR9__ -+#endif //UEIP -+ -+/*@}*//*IFXUSB_PLATEFORM_MEM_ADDR*/ -+ -+///////////////////////////////////////////////////////////////////////// -+ -+#ifdef __IS_HOST__ -+ #ifdef CONFIG_USB_HOST_IFX_FORCE_USB11 -+ #undef default_param_speed -+ #define default_param_speed IFXUSB_PARAM_SPEED_FULL -+ #endif -+#endif -+#ifdef __IS_DEVICE__ -+ #ifndef CONFIG_USB_GADGET_DUALSPEED -+ #undef default_param_speed -+ #define default_param_speed IFXUSB_PARAM_SPEED_FULL -+ #endif -+#endif -+ -+///////////////////////////////////////////////////////////////////////// -+ -+static __inline__ void UDELAY( const uint32_t _usecs ) -+{ -+ udelay( _usecs ); -+} -+ -+static __inline__ void MDELAY( const uint32_t _msecs ) -+{ -+ mdelay( _msecs ); -+} -+ -+static __inline__ void SPIN_LOCK( spinlock_t *_lock ) -+{ -+ spin_lock(_lock); -+} -+ -+static __inline__ void SPIN_UNLOCK( spinlock_t *_lock ) -+{ -+ spin_unlock(_lock); -+} -+ -+#define SPIN_LOCK_IRQSAVE( _l, _f ) \ -+ { \ -+ spin_lock_irqsave(_l,_f); \ -+ } -+ -+#define SPIN_UNLOCK_IRQRESTORE( _l,_f ) \ -+ { \ -+ spin_unlock_irqrestore(_l,_f); \ -+ } -+ -+///////////////////////////////////////////////////////////////////////// -+/*! -+ \addtogroup IFXUSB_DBG_ROUTINE -+ */ -+/*@{*/ -+#ifdef __IS_HOST__ -+ extern uint32_t h_dbg_lvl; -+#endif -+ -+#ifdef __IS_DEVICE__ -+ extern uint32_t d_dbg_lvl; -+#endif -+ -+/*! \brief When debug level has the DBG_CIL bit set, display CIL Debug messages. */ -+#define DBG_CIL (0x2) -+/*! \brief When debug level has the DBG_CILV bit set, display CIL Verbose debug messages */ -+#define DBG_CILV (0x20) -+/*! \brief When debug level has the DBG_PCD bit set, display PCD (Device) debug messages */ -+#define DBG_PCD (0x4) -+/*! \brief When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug messages */ -+#define DBG_PCDV (0x40) -+/*! \brief When debug level has the DBG_HCD bit set, display Host debug messages */ -+#define DBG_HCD (0x8) -+/*! \brief When debug level has the DBG_HCDV bit set, display Verbose Host debug messages */ -+#define DBG_HCDV (0x80) -+/*! \brief When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host mode. */ -+#define DBG_HCD_URB (0x800) -+/*! \brief When debug level has any bit set, display debug messages */ -+#define DBG_ANY (0xFF) -+/*! \brief All debug messages off */ -+#define DBG_OFF 0 -+ -+#define DBG_ENTRY (0x8000) -+ -+#define IFXUSB "IFXUSB: " -+ -+/*! -+ \fn inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) -+ \brief Set the Debug Level variable. -+ \param _new 32-bit mask of debug level. -+ \return previous debug level -+ */ -+static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) -+{ -+ #ifdef __IS_HOST__ -+ uint32_t old = h_dbg_lvl; -+ h_dbg_lvl = _new; -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ uint32_t old = d_dbg_lvl; -+ d_dbg_lvl = _new; -+ #endif -+ return old; -+} -+ -+#ifdef __DEBUG__ -+ #ifdef __IS_HOST__ -+ # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&h_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0) -+ # define CHK_DEBUG_LEVEL(level) ((level) & h_dbg_lvl) -+ #endif -+ -+ #ifdef __IS_DEVICE__ -+ # define IFX_DEBUGPL(lvl, x...) do{ if ((lvl)&d_dbg_lvl)printk( KERN_DEBUG IFXUSB x ); }while(0) -+ # define CHK_DEBUG_LEVEL(level) ((level) & d_dbg_lvl) -+ #endif -+ -+ # define IFX_DEBUGP(x...) IFX_DEBUGPL(DBG_ANY, x ) -+#else -+ # define IFX_DEBUGPL(lvl, x...) do{}while(0) -+ # define IFX_DEBUGP(x...) -+ # define CHK_DEBUG_LEVEL(level) (0) -+#endif //__DEBUG__ -+ -+/* Print an Error message. */ -+#define IFX_ERROR(x...) printk( KERN_ERR IFXUSB x ) -+/* Print a Warning message. */ -+#define IFX_WARN(x...) printk( KERN_WARNING IFXUSB x ) -+/* Print a notice (normal but significant message). */ -+#define IFX_NOTICE(x...) printk( KERN_NOTICE IFXUSB x ) -+/* Basic message printing. */ -+#define IFX_PRINT(x...) printk( KERN_INFO IFXUSB x ) -+ -+/*@}*//*IFXUSB_DBG_ROUTINE*/ -+ -+ -+#endif //__IFXUSB_PLAT_H__ -+ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_regs.h -@@ -0,0 +1,1420 @@ -+/***************************************************************************** -+ ** FILE NAME : ifxusb_regs.h -+ ** PROJECT : IFX USB sub-system V3 -+ ** MODULES : IFX USB sub-system Host and Device driver -+ ** SRC VERSION : 1.0 -+ ** DATE : 1/Jan/2009 -+ ** AUTHOR : Chen, Howard -+ ** DESCRIPTION : This file contains the data structures for accessing the IFXUSB core -+ ** registers. -+ ** The application interfaces with the USB core by reading from and -+ ** writing to the Control and Status Register (CSR) space through the -+ ** AHB Slave interface. These registers are 32 bits wide, and the -+ ** addresses are 32-bit-block aligned. -+ ** CSRs are classified as follows: -+ ** - Core Global Registers -+ ** - Device Mode Registers -+ ** - Device Global Registers -+ ** - Device Endpoint Specific Registers -+ ** - Host Mode Registers -+ ** - Host Global Registers -+ ** - Host Port CSRs -+ ** - Host Channel Specific Registers -+ ** -+ ** Only the Core Global registers can be accessed in both Device and -+ ** Host modes. When the USB core is operating in one mode, either -+ ** Device or Host, the application must not access registers from the -+ ** other mode. When the core switches from one mode to another, the -+ ** registers in the new mode of operation must be reprogrammed as they -+ ** would be after a power-on reset. -+ ** FUNCTIONS : -+ ** COMPILER : gcc -+ ** REFERENCE : Synopsys DWC-OTG Driver 2.7 -+ ** COPYRIGHT : -+ ** Version Control Section ** -+ ** $Author$ -+ ** $Date$ -+ ** $Revisions$ -+ ** $Log$ Revision history -+*****************************************************************************/ -+ -+ -+ -+/*! -+ \defgroup IFXUSB_CSR_DEFINITION Control and Status Register bit-map definition -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief Data structures for accessing the IFXUSB core registers. -+ The application interfaces with the USB core by reading from and -+ writing to the Control and Status Register (CSR) space through the -+ AHB Slave interface. These registers are 32 bits wide, and the -+ addresses are 32-bit-block aligned. -+ CSRs are classified as follows: -+ - Core Global Registers -+ - Device Mode Registers -+ - Device Global Registers -+ - Device Endpoint Specific Registers -+ - Host Mode Registers -+ - Host Global Registers -+ - Host Port CSRs -+ - Host Channel Specific Registers -+ -+ Only the Core Global registers can be accessed in both Device andHost modes. -+ When the USB core is operating in one mode, either Device or Host, the -+ application must not access registers from the other mode. When the core -+ switches from one mode to another, the registers in the new mode of operation -+ must be reprogrammed as they would be after a power-on reset. -+ */ -+ -+/*! -+ \defgroup IFXUSB_CSR_DEVICE_GLOBAL_REG Device Mode Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Device Mode Global Registers -+ */ -+ -+/*! -+ \defgroup IFXUSB_CSR_DEVICE_EP_REG Device Mode EP Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Device Mode EP Registers -+ There will be one set of endpoint registers per logical endpoint -+ implemented. -+ These registers are visible only in Device mode and must not be -+ accessed in Host mode, as the results are unknown. -+ */ -+ -+/*! -+ \defgroup IFXUSB_CSR_DEVICE_DMA_DESC Device mode scatter dma descriptor strusture -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to DMA descriptor -+ */ -+ -+ -+/*! -+ \defgroup IFXUSB_CSR_HOST_GLOBAL_REG Host Mode Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Host Mode Global Registers -+ */ -+ -+/*! -+ \defgroup IFXUSB_CSR_HOST_HC_REG Host Mode HC Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Host Mode Host Channel Registers -+ There will be one set of endpoint registers per host channel -+ implemented. -+ These registers are visible only in Host mode and must not be -+ accessed in Device mode, as the results are unknown. -+ */ -+ -+/*! -+ \defgroup IFXUSB_CSR_PWR_CLK_GATING_REG Power and Clock Gating Control Register -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to Power and Clock Gating Control Register -+ */ -+ -+ -+ -+ -+ -+ -+ -+ -+/*! -+ \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Core Global Registers -+ */ -+/*! -+ \defgroup IFXUSB_CSR_CORE_GLOBAL_REG Core Global Registers -+ \ingroup IFXUSB_CSR_DEFINITION -+ \brief Bit-mapped structure to access Core Global Registers -+ */ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+/*! -+ \file ifxusb_regs.h -+ \ingroup IFXUSB_DRIVER_V3 -+ \brief This file contains the data structures for accessing the IFXUSB core registers. -+ */ -+ -+ -+#ifndef __IFXUSB_REGS_H__ -+#define __IFXUSB_REGS_H__ -+ -+/****************************************************************************/ -+ -+#define MAX_PERIO_FIFOS 15 /** Maximum number of Periodic FIFOs */ -+#define MAX_TX_FIFOS 15 /** Maximum number of Periodic FIFOs */ -+#define MAX_EPS_CHANNELS 16 /** Maximum number of Endpoints/HostChannels */ -+ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_ACCESS_MACROS -+ */ -+/*@{*/ -+ -+//#define RecordRegRW -+ -+/*! -+ \fn static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg) -+ \brief Reads the content of a register. -+ \param _reg address of register to read. -+ \return contents of the register. -+ */ -+static __inline__ uint32_t ifxusb_rreg( volatile uint32_t *_reg) -+{ -+ #ifdef RecordRegRW -+ uint32_t r; -+ r=*(_reg); -+ return (r); -+ #else -+ return (*(_reg)); -+ #endif -+}; -+ -+ -+/*! -+ \fn static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value) -+ \brief Writes a register with a 32 bit value. -+ \param _reg address of register to write. -+ \param _value value to write to _reg. -+ */ -+static __inline__ void ifxusb_wreg( volatile uint32_t *_reg, const uint32_t _value) -+{ -+ #ifdef RecordRegRW -+ printk(KERN_INFO "[W %p<-%08X]\n",_reg,_value); -+ #else -+ *(_reg)=_value; -+ #endif -+}; -+ -+/*! -+ \fn static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask) -+ \brief Modifies bit values in a register. Using the -+ algorithm: (reg_contents & ~clear_mask) | set_mask. -+ \param _reg address of register to modify. -+ \param _clear_mask bit mask to be cleared. -+ \param _set_mask bit mask to be set. -+ */ -+static __inline__ void ifxusb_mreg( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask) -+{ -+ uint32_t v; -+ #ifdef RecordRegRW -+ uint32_t r; -+ v= *(_reg); -+ r=v; -+ r&=(~_clear_mask); -+ r|= _set_mask; -+ *(_reg)=r ; -+ printk(KERN_INFO "[M %p->%08X+%08X/%08X<-%08X]\n",_reg,r,_clear_mask,_set_mask,r); -+ #else -+ v= *(_reg); -+ v&=(~_clear_mask); -+ v|= _set_mask; -+ *(_reg)=v ; -+ #endif -+}; -+ -+/*@}*//*IFXUSB_CSR_ACCESS_MACROS*/ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_CORE_GLOBAL_REG -+ */ -+/*@{*/ -+ -+/*! -+ \struct ifxusb_core_global_regs -+ \brief IFXUSB Core registers . -+ The ifxusb_core_global_regs structure defines the size -+ and relative field offsets for the Core Global registers. -+ */ -+typedef struct ifxusb_core_global_regs -+{ -+ volatile uint32_t gotgctl; /*!< 000h OTG Control and Status Register. */ -+ volatile uint32_t gotgint; /*!< 004h OTG Interrupt Register. */ -+ volatile uint32_t gahbcfg; /*!< 008h Core AHB Configuration Register. */ -+ volatile uint32_t gusbcfg; /*!< 00Ch Core USB Configuration Register. */ -+ volatile uint32_t grstctl; /*!< 010h Core Reset Register. */ -+ volatile uint32_t gintsts; /*!< 014h Core Interrupt Register. */ -+ volatile uint32_t gintmsk; /*!< 018h Core Interrupt Mask Register. */ -+ volatile uint32_t grxstsr; /*!< 01Ch Receive Status Queue Read Register (Read Only). */ -+ volatile uint32_t grxstsp; /*!< 020h Receive Status Queue Read & POP Register (Read Only). */ -+ volatile uint32_t grxfsiz; /*!< 024h Receive FIFO Size Register. */ -+ volatile uint32_t gnptxfsiz; /*!< 028h Non Periodic Transmit FIFO Size Register. */ -+ volatile uint32_t gnptxsts; /*!< 02Ch Non Periodic Transmit FIFO/Queue Status Register (Read Only). */ -+ volatile uint32_t gi2cctl; /*!< 030h I2C Access Register. */ -+ volatile uint32_t gpvndctl; /*!< 034h PHY Vendor Control Register. */ -+ volatile uint32_t ggpio; /*!< 038h General Purpose Input/Output Register. */ -+ volatile uint32_t guid; /*!< 03Ch User ID Register. */ -+ volatile uint32_t gsnpsid; /*!< 040h Synopsys ID Register (Read Only). */ -+ volatile uint32_t ghwcfg1; /*!< 044h User HW Config1 Register (Read Only). */ -+ volatile uint32_t ghwcfg2; /*!< 048h User HW Config2 Register (Read Only). */ -+ volatile uint32_t ghwcfg3; /*!< 04Ch User HW Config3 Register (Read Only). */ -+ volatile uint32_t ghwcfg4; /*!< 050h User HW Config4 Register (Read Only). */ -+ volatile uint32_t reserved[43]; /*!< 054h Reserved 054h-0FFh */ -+ volatile uint32_t hptxfsiz; /*!< 100h Host Periodic Transmit FIFO Size Register. */ -+ volatile uint32_t dptxfsiz_dieptxf[15];/*!< 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15. -+ Device Periodic Transmit FIFO#n Register if dedicated -+ fifos are disabled, otherwise Device Transmit FIFO#n -+ Register. -+ */ -+} ifxusb_core_global_regs_t; -+ -+/*! -+ \brief Bits of the Core OTG Control and Status Register (GOTGCTL). -+ */ -+typedef union gotgctl_data -+{ -+ uint32_t d32; -+ struct{ -+ unsigned reserved21_31 : 11; -+ unsigned currmod : 1 ; /*!< 20 */ -+ unsigned bsesvld : 1 ; /*!< 19 */ -+ unsigned asesvld : 1 ; /*!< 18 */ -+ unsigned reserved17 : 1 ; -+ unsigned conidsts : 1 ; /*!< 16 */ -+ unsigned reserved12_15 : 4 ; -+ unsigned devhnpen : 1 ; /*!< 11 */ -+ unsigned hstsethnpen : 1 ; /*!< 10 */ -+ unsigned hnpreq : 1 ; /*!< 09 */ -+ unsigned hstnegscs : 1 ; /*!< 08 */ -+ unsigned reserved2_7 : 6 ; -+ unsigned sesreq : 1 ; /*!< 01 */ -+ unsigned sesreqscs : 1 ; /*!< 00 */ -+ } b; -+} gotgctl_data_t; -+ -+/*! -+ \brief Bit fields of the Core OTG Interrupt Register (GOTGINT). -+ */ -+typedef union gotgint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31_20 : 12; -+ unsigned debdone : 1 ; /*!< 19 Debounce Done */ -+ unsigned adevtoutchng : 1 ; /*!< 18 A-Device Timeout Change */ -+ unsigned hstnegdet : 1 ; /*!< 17 Host Negotiation Detected */ -+ unsigned reserver10_16 : 7 ; -+ unsigned hstnegsucstschng : 1 ; /*!< 09 Host Negotiation Success Status Change */ -+ unsigned sesreqsucstschng : 1 ; /*!< 08 Session Request Success Status Change */ -+ unsigned reserved3_7 : 5 ; -+ unsigned sesenddet : 1 ; /*!< 02 Session End Detected */ -+ unsigned reserved0_1 : 2 ; -+ } b; -+} gotgint_data_t; -+ -+/*! -+ \brief Bit fields of the Core AHB Configuration Register (GAHBCFG). -+ */ -+typedef union gahbcfg_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved9_31 : 23; -+ unsigned ptxfemplvl : 1 ; /*!< 08 Periodic FIFO empty level trigger condition*/ -+ unsigned nptxfemplvl : 1 ; /*!< 07 Non-Periodic FIFO empty level trigger condition*/ -+ #define IFXUSB_GAHBCFG_TXFEMPTYLVL_EMPTY 1 -+ #define IFXUSB_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -+ unsigned reserved : 1 ; -+ unsigned dmaenable : 1 ; /*!< 05 DMA enable*/ -+ #define IFXUSB_GAHBCFG_DMAENABLE 1 -+ unsigned hburstlen : 4 ; /*!< 01-04 DMA Burst-length*/ -+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE 0 -+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR 1 -+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4 3 -+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8 5 -+ #define IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16 7 -+ unsigned glblintrmsk : 1 ; /*!< 00 USB Global Interrupt Enable */ -+ #define IFXUSB_GAHBCFG_GLBINT_ENABLE 1 -+ } b; -+} gahbcfg_data_t; -+ -+/*! -+ \brief Bit fields of the Core USB Configuration Register (GUSBCFG). -+*/ -+typedef union gusbcfg_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31 : 1; -+ unsigned ForceDevMode : 1; /*!< 30 Force Device Mode */ -+ unsigned ForceHstMode : 1; /*!< 29 Force Host Mode */ -+ unsigned TxEndDelay : 1; /*!< 28 Tx End Delay */ -+ unsigned reserved2723 : 5; -+ unsigned term_sel_dl_pulse : 1; /*!< 22 TermSel DLine Pulsing Selection */ -+ unsigned reserved2117 : 5; -+ unsigned otgutmifssel : 1; /*!< 16 UTMIFS Select */ -+ unsigned phylpwrclksel : 1; /*!< 15 PHY Low-Power Clock Select */ -+ unsigned reserved14 : 1; -+ unsigned usbtrdtim : 4; /*!< 13-10 USB Turnaround Time */ -+ unsigned hnpcap : 1; /*!< 09 HNP-Capable */ -+ unsigned srpcap : 1; /*!< 08 SRP-Capable */ -+ unsigned reserved07 : 1; -+ unsigned physel : 1; /*!< 06 USB 2.0 High-Speed PHY or -+ USB 1.1 Full-Speed Serial -+ Transceiver Select */ -+ unsigned fsintf : 1; /*!< 05 Full-Speed Serial Interface Select */ -+ unsigned ulpi_utmi_sel : 1; /*!< 04 ULPI or UTMI+ Select */ -+ unsigned phyif : 1; /*!< 03 PHY Interface */ -+ unsigned toutcal : 3; /*!< 00-02 HS/FS Timeout Calibration */ -+ }b; -+} gusbcfg_data_t; -+ -+/*! -+ \brief Bit fields of the Core Reset Register (GRSTCTL). -+ */ -+typedef union grstctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned ahbidle : 1; /*!< 31 AHB Master Idle. Indicates the AHB Master State -+ Machine is in IDLE condition. */ -+ unsigned dmareq : 1; /*!< 30 DMA Request Signal. Indicated DMA request is in -+ probress. Used for debug purpose. */ -+ unsigned reserved11_29 :19; -+ unsigned txfnum : 5; /*!< 10-06 TxFIFO Number (TxFNum) to be flushed. -+ 0x00: Non Periodic TxFIFO Flush or TxFIFO 0 -+ 0x01-0x0F: Periodic TxFIFO Flush or TxFIFO n -+ 0x10: Flush all TxFIFO -+ */ -+ unsigned txfflsh : 1; /*!< 05 TxFIFO Flush */ -+ unsigned rxfflsh : 1; /*!< 04 RxFIFO Flush */ -+ unsigned intknqflsh : 1; /*!< 03 In Token Sequence Learning Queue Flush (Device Only) */ -+ unsigned hstfrm : 1; /*!< 02 Host Frame Counter Reset (Host Only) */ -+ unsigned hsftrst : 1; /*!< 01 Hclk Soft Reset */ -+ -+ unsigned csftrst : 1; /*!< 00 Core Soft Reset -+ The application can flush the control logic in the -+ entire core using this bit. This bit resets the -+ pipelines in the AHB Clock domain as well as the -+ PHY Clock domain. -+ The state machines are reset to an IDLE state, the -+ control bits in the CSRs are cleared, all the -+ transmit FIFOs and the receive FIFO are flushed. -+ The status mask bits that control the generation of -+ the interrupt, are cleared, to clear the -+ interrupt. The interrupt status bits are not -+ cleared, so the application can get the status of -+ any events that occurred in the core after it has -+ set this bit. -+ Any transactions on the AHB are terminated as soon -+ as possible following the protocol. Any -+ transactions on the USB are terminated immediately. -+ The configuration settings in the CSRs are -+ unchanged, so the software doesn't have to -+ reprogram these registers (Device -+ Configuration/Host Configuration/Core System -+ Configuration/Core PHY Configuration). -+ The application can write to this bit, any time it -+ wants to reset the core. This is a self clearing -+ bit and the core clears this bit after all the -+ necessary logic is reset in the core, which may -+ take several clocks, depending on the current state -+ of the core. -+ */ -+ }b; -+} grstctl_t; -+ -+/*! -+ \brief Bit fields of the Core Interrupt Mask Register (GINTMSK) and -+ Core Interrupt Register (GINTSTS). -+ */ -+typedef union gint_data -+{ -+ uint32_t d32; -+ #define IFXUSB_SOF_INTR_MASK 0x0008 -+ struct -+ { -+ unsigned wkupintr : 1; /*!< 31 Resume/Remote Wakeup Detected Interrupt */ -+ unsigned sessreqintr : 1; /*!< 30 Session Request/New Session Detected Interrupt */ -+ unsigned disconnect : 1; /*!< 29 Disconnect Detected Interrupt */ -+ unsigned conidstschng : 1; /*!< 28 Connector ID Status Change */ -+ unsigned reserved27 : 1; -+ unsigned ptxfempty : 1; /*!< 26 Periodic TxFIFO Empty */ -+ unsigned hcintr : 1; /*!< 25 Host Channels Interrupt */ -+ unsigned portintr : 1; /*!< 24 Host Port Interrupt */ -+ unsigned reserved23 : 1; -+ unsigned fetsuspmsk : 1; /*!< 22 Data Fetch Suspended */ -+ unsigned incomplisoout : 1; /*!< 21 Incomplete IsochronousOUT/Period Transfer */ -+ unsigned incomplisoin : 1; /*!< 20 Incomplete Isochronous IN Transfer */ -+ unsigned outepintr : 1; /*!< 19 OUT Endpoints Interrupt */ -+ unsigned inepintr : 1; /*!< 18 IN Endpoints Interrupt */ -+ unsigned epmismatch : 1; /*!< 17 Endpoint Mismatch Interrupt */ -+ unsigned reserved16 : 1; -+ unsigned eopframe : 1; /*!< 15 End of Periodic Frame Interrupt */ -+ unsigned isooutdrop : 1; /*!< 14 Isochronous OUT Packet Dropped Interrupt */ -+ unsigned enumdone : 1; /*!< 13 Enumeration Done */ -+ unsigned usbreset : 1; /*!< 12 USB Reset */ -+ unsigned usbsuspend : 1; /*!< 11 USB Suspend */ -+ unsigned erlysuspend : 1; /*!< 10 Early Suspend */ -+ unsigned i2cintr : 1; /*!< 09 I2C Interrupt */ -+ unsigned reserved8 : 1; -+ unsigned goutnakeff : 1; /*!< 07 Global OUT NAK Effective */ -+ unsigned ginnakeff : 1; /*!< 06 Global Non-periodic IN NAK Effective */ -+ unsigned nptxfempty : 1; /*!< 05 Non-periodic TxFIFO Empty */ -+ unsigned rxstsqlvl : 1; /*!< 04 Receive FIFO Non-Empty */ -+ unsigned sofintr : 1; /*!< 03 Start of (u)Frame */ -+ unsigned otgintr : 1; /*!< 02 OTG Interrupt */ -+ unsigned modemismatch : 1; /*!< 01 Mode Mismatch Interrupt */ -+ unsigned reserved0 : 1; -+ } b; -+} gint_data_t; -+ -+/*! -+ \brief Bit fields in the Receive Status Read and Pop Registers (GRXSTSR, GRXSTSP) -+ */ -+typedef union grxsts_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 7; -+ unsigned fn : 4; /*!< 24-21 Frame Number */ -+ unsigned pktsts : 4; /*!< 20-17 Packet Status */ -+ #define IFXUSB_DSTS_DATA_UPDT 0x2 // OUT Data Packet -+ #define IFXUSB_DSTS_XFER_COMP 0x3 // OUT Data Transfer Complete -+ #define IFXUSB_DSTS_GOUT_NAK 0x1 // Global OUT NAK -+ #define IFXUSB_DSTS_SETUP_COMP 0x4 // Setup Phase Complete -+ #define IFXUSB_DSTS_SETUP_UPDT 0x6 // SETUP Packet -+ unsigned dpid : 2; /*!< 16-15 Data PID */ -+ unsigned bcnt :11; /*!< 14-04 Byte Count */ -+ unsigned epnum : 4; /*!< 03-00 Endpoint Number */ -+ } db; -+ struct -+ { -+ unsigned reserved :11; -+ unsigned pktsts : 4; /*!< 20-17 Packet Status */ -+ #define IFXUSB_HSTS_DATA_UPDT 0x2 // OUT Data Packet -+ #define IFXUSB_HSTS_XFER_COMP 0x3 // OUT Data Transfer Complete -+ #define IFXUSB_HSTS_DATA_TOGGLE_ERR 0x5 // DATA TOGGLE Error -+ #define IFXUSB_HSTS_CH_HALTED 0x7 // Channel Halted -+ unsigned dpid : 2; /*!< 16-15 Data PID */ -+ unsigned bcnt :11; /*!< 14-04 Byte Count */ -+ unsigned chnum : 4; /*!< 03-00 Channel Number */ -+ } hb; -+} grxsts_data_t; -+ -+/*! -+ \brief Bit fields in the FIFO Size Registers (HPTXFSIZ, GNPTXFSIZ, DPTXFSIZn). -+ */ -+typedef union fifosize_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned depth : 16; /*!< 31-16 TxFIFO Depth (in DWord)*/ -+ unsigned startaddr : 16; /*!< 15-00 RAM Starting address */ -+ } b; -+} fifosize_data_t; -+ -+/*! -+ \brief Bit fields in the Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS). -+ */ -+ -+typedef union gnptxsts_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 1; -+ unsigned nptxqtop_chnep : 4; /*!< 30-27 Channel/EP Number of top of the Non-Periodic -+ Transmit Request Queue -+ */ -+ unsigned nptxqtop_token : 2; /*!< 26-25 Token Type top of the Non-Periodic -+ Transmit Request Queue -+ 0 - IN/OUT -+ 1 - Zero Length OUT -+ 2 - PING/Complete Split -+ 3 - Channel Halt -+ */ -+ unsigned nptxqtop_terminate : 1; /*!< 24 Terminate (Last entry for the selected -+ channel/EP)*/ -+ unsigned nptxqspcavail : 8; /*!< 23-16 Transmit Request Queue Space Available */ -+ unsigned nptxfspcavail :16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/ -+ }b; -+} gnptxsts_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Transmit FIFO Status Register (DTXFSTS). -+ */ -+typedef union dtxfsts_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 16; -+ unsigned txfspcavail : 16; /*!< 15-00 TxFIFO Space Avail (in DWord)*/ -+ }b; -+} dtxfsts_data_t; -+ -+ -+/*! -+ \brief Bit fields in the I2C Control Register (I2CCTL). -+ */ -+typedef union gi2cctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned bsydne : 1; /*!< 31 I2C Busy/Done*/ -+ unsigned rw : 1; /*!< 30 Read/Write Indicator */ -+ unsigned reserved : 2; -+ unsigned i2cdevaddr : 2; /*!< 27-26 I2C Device Address */ -+ unsigned i2csuspctl : 1; /*!< 25 I2C Suspend Control */ -+ unsigned ack : 1; /*!< 24 I2C ACK */ -+ unsigned i2cen : 1; /*!< 23 I2C Enable */ -+ unsigned addr : 7; /*!< 22-16 I2C Address */ -+ unsigned regaddr : 8; /*!< 15-08 I2C Register Addr */ -+ unsigned rwdata : 8; /*!< I2C Read/Write Data */ -+ } b; -+} gi2cctl_data_t; -+ -+ -+/*! -+ \brief Bit fields in the User HW Config1 Register. -+ */ -+typedef union hwcfg1_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned ep_dir15 : 2; /*!< Direction of each EP -+ 0: BIDIR (IN and OUT) endpoint -+ 1: IN endpoint -+ 2: OUT endpoint -+ 3: Reserved -+ */ -+ unsigned ep_dir14 : 2; -+ unsigned ep_dir13 : 2; -+ unsigned ep_dir12 : 2; -+ unsigned ep_dir11 : 2; -+ unsigned ep_dir10 : 2; -+ unsigned ep_dir09 : 2; -+ unsigned ep_dir08 : 2; -+ unsigned ep_dir07 : 2; -+ unsigned ep_dir06 : 2; -+ unsigned ep_dir05 : 2; -+ unsigned ep_dir04 : 2; -+ unsigned ep_dir03 : 2; -+ unsigned ep_dir02 : 2; -+ unsigned ep_dir01 : 2; -+ unsigned ep_dir00 : 2; -+ }b; -+} hwcfg1_data_t; -+ -+/*! -+ \brief Bit fields in the User HW Config2 Register. -+ */ -+typedef union hwcfg2_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31 : 1; -+ unsigned dev_token_q_depth : 5; /*!< 30-26 Device Mode IN Token Sequence Learning Queue Depth */ -+ unsigned host_perio_tx_q_depth : 2; /*!< 25-24 Host Mode Periodic Request Queue Depth */ -+ unsigned nonperio_tx_q_depth : 2; /*!< 23-22 Non-periodic Request Queue Depth */ -+ unsigned rx_status_q_depth : 2; /*!< 21-20 Multi Processor Interrupt Enabled */ -+ unsigned dynamic_fifo : 1; /*!< 19 Dynamic FIFO Sizing Enabled */ -+ unsigned perio_ep_supported : 1; /*!< 18 Periodic OUT Channels Supported in Host Mode */ -+ unsigned num_host_chan : 4; /*!< 17-14 Number of Host Channels */ -+ unsigned num_dev_ep : 4; /*!< 13-10 Number of Device Endpoints */ -+ unsigned fs_phy_type : 2; /*!< 09-08 Full-Speed PHY Interface Type */ -+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0 -+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_DEDICATE 1 -+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_UTMI 2 -+ #define IFXUSB_HWCFG2_FS_PHY_TYPE_ULPI 3 -+ unsigned hs_phy_type : 2; /*!< 07-06 High-Speed PHY Interface Type */ -+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 -+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI 1 -+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_ULPI 2 -+ #define IFXUSB_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 -+ unsigned point2point : 1; /*!< 05 Point-to-Point */ -+ unsigned architecture : 2; /*!< 04-03 Architecture */ -+ #define IFXUSB_HWCFG2_ARCH_SLAVE_ONLY 0 -+ #define IFXUSB_HWCFG2_ARCH_EXT_DMA 1 -+ #define IFXUSB_HWCFG2_ARCH_INT_DMA 2 -+ unsigned op_mode : 3; /*!< 02-00 Mode of Operation */ -+ #define IFXUSB_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0 -+ #define IFXUSB_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1 -+ #define IFXUSB_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2 -+ #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 -+ #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 -+ #define IFXUSB_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 -+ #define IFXUSB_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 -+ } b; -+} hwcfg2_data_t; -+ -+/*! -+ \brief Bit fields in the User HW Config3 Register. -+ */ -+typedef union hwcfg3_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned dfifo_depth :16; /*!< 31-16 DFIFO Depth */ -+ unsigned reserved15_12 : 4; -+ unsigned synch_reset_type : 1; /*!< 11 Reset Style for Clocked always Blocks in RTL */ -+ unsigned optional_features : 1; /*!< 10 Optional Features Removed */ -+ unsigned vendor_ctrl_if : 1; /*!< 09 Vendor Control Interface Support */ -+ unsigned i2c : 1; /*!< 08 I2C Selection */ -+ unsigned otg_func : 1; /*!< 07 OTG Function Enabled */ -+ unsigned packet_size_cntr_width : 3; /*!< 06-04 Width of Packet Size Counters */ -+ unsigned xfer_size_cntr_width : 4; /*!< 03-00 Width of Transfer Size Counters */ -+ } b; -+} hwcfg3_data_t; -+ -+/*! -+ \brief Bit fields in the User HW Config4 -+ * Register. Read the register into the <i>d32</i> element then read -+ * out the bits using the <i>b</i>it elements. -+ */ -+typedef union hwcfg4_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned desc_dma_dyn : 1; /*!< 31 Scatter/Gather DMA */ -+ unsigned desc_dma : 1; /*!< 30 Scatter/Gather DMA configuration */ -+ unsigned num_in_eps : 4; /*!< 29-26 Number of Device Mode IN Endpoints Including Control Endpoints */ -+ unsigned ded_fifo_en : 1; /*!< 25 Enable Dedicated Transmit FIFO for device IN Endpoints */ -+ unsigned session_end_filt_en : 1; /*!< 24 session_end Filter Enabled */ -+ unsigned b_valid_filt_en : 1; /*!< 23 b_valid Filter Enabled */ -+ unsigned a_valid_filt_en : 1; /*!< 22 a_valid Filter Enabled */ -+ unsigned vbus_valid_filt_en : 1; /*!< 21 vbus_valid Filter Enabled */ -+ unsigned iddig_filt_en : 1; /*!< 20 iddig Filter Enable */ -+ unsigned num_dev_mode_ctrl_ep : 4; /*!< 19-16 Number of Device Mode Control Endpoints in Addition to Endpoint 0 */ -+ unsigned utmi_phy_data_width : 2; /*!< 15-14 UTMI+ PHY/ULPI-to-Internal UTMI+ Wrapper Data Width */ -+ unsigned reserved13_06 : 8; -+ unsigned min_ahb_freq : 1; /*!< 05 Minimum AHB Frequency Less Than 60 MHz */ -+ unsigned power_optimiz : 1; /*!< 04 Enable Power Optimization? */ -+ unsigned num_dev_perio_in_ep : 4; /*!< 03-00 Number of Device Mode Periodic IN Endpoints */ -+ } b; -+} hwcfg4_data_t; -+ -+/*@}*//*IFXUSB_CSR_CORE_GLOBAL_REG*/ -+ -+/****************************************************************************/ -+/*! -+ \addtogroup IFXUSB_CSR_DEVICE_GLOBAL_REG -+ */ -+/*@{*/ -+ -+/*! -+ \struct ifxusb_dev_global_regs -+ \brief IFXUSB Device Mode Global registers. Offsets 800h-BFFh -+ The ifxusb_dev_global_regs structure defines the size -+ and relative field offsets for the Device Global registers. -+ These registers are visible only in Device mode and must not be -+ accessed in Host mode, as the results are unknown. -+ */ -+typedef struct ifxusb_dev_global_regs -+{ -+ volatile uint32_t dcfg; /*!< 800h Device Configuration Register. */ -+ volatile uint32_t dctl; /*!< 804h Device Control Register. */ -+ volatile uint32_t dsts; /*!< 808h Device Status Register (Read Only). */ -+ uint32_t unused; -+ volatile uint32_t diepmsk; /*!< 810h Device IN Endpoint Common Interrupt Mask Register. */ -+ volatile uint32_t doepmsk; /*!< 814h Device OUT Endpoint Common Interrupt Mask Register. */ -+ volatile uint32_t daint; /*!< 818h Device All Endpoints Interrupt Register. */ -+ volatile uint32_t daintmsk; /*!< 81Ch Device All Endpoints Interrupt Mask Register. */ -+ volatile uint32_t dtknqr1; /*!< 820h Device IN Token Queue Read Register-1 (Read Only). */ -+ volatile uint32_t dtknqr2; /*!< 824h Device IN Token Queue Read Register-2 (Read Only). */ -+ volatile uint32_t dvbusdis; /*!< 828h Device VBUS discharge Register.*/ -+ volatile uint32_t dvbuspulse; /*!< 82Ch Device VBUS Pulse Register. */ -+ volatile uint32_t dtknqr3_dthrctl; /*!< 830h Device IN Token Queue Read Register-3 (Read Only). -+ Device Thresholding control register (Read/Write) -+ */ -+ volatile uint32_t dtknqr4_fifoemptymsk; /*!< 834h Device IN Token Queue Read Register-4 (Read Only). -+ Device IN EPs empty Inr. Mask Register (Read/Write) -+ */ -+} ifxusb_device_global_regs_t; -+ -+/*! -+ \brief Bit fields in the Device Configuration Register. -+ */ -+ -+typedef union dcfg_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31_26 : 6; -+ unsigned perschintvl : 2; /*!< 25-24 Periodic Scheduling Interval */ -+ unsigned descdma : 1; /*!< 23 Enable Descriptor DMA in Device mode */ -+ unsigned epmscnt : 5; /*!< 22-18 In Endpoint Mis-match count */ -+ unsigned reserved13_17 : 5; -+ unsigned perfrint : 2; /*!< 12-11 Periodic Frame Interval */ -+ #define IFXUSB_DCFG_FRAME_INTERVAL_80 0 -+ #define IFXUSB_DCFG_FRAME_INTERVAL_85 1 -+ #define IFXUSB_DCFG_FRAME_INTERVAL_90 2 -+ #define IFXUSB_DCFG_FRAME_INTERVAL_95 3 -+ unsigned devaddr : 7; /*!< 10-04 Device Addresses */ -+ unsigned reserved3 : 1; -+ unsigned nzstsouthshk : 1; /*!< 02 Non Zero Length Status OUT Handshake */ -+ #define IFXUSB_DCFG_SEND_STALL 1 -+ unsigned devspd : 2; /*!< 01-00 Device Speed */ -+ } b; -+} dcfg_data_t; -+ -+/*! -+ \brief Bit fields in the Device Control Register. -+ */ -+typedef union dctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved16_31 :16; -+ unsigned ifrmnum : 1; /*!< 15 Ignore Frame Number for ISOC EPs */ -+ unsigned gmc : 2; /*!< 14-13 Global Multi Count */ -+ unsigned gcontbna : 1; /*!< 12 Global Continue on BNA */ -+ unsigned pwronprgdone : 1; /*!< 11 Power-On Programming Done */ -+ unsigned cgoutnak : 1; /*!< 10 Clear Global OUT NAK */ -+ unsigned sgoutnak : 1; /*!< 09 Set Global OUT NAK */ -+ unsigned cgnpinnak : 1; /*!< 08 Clear Global Non-Periodic IN NAK */ -+ unsigned sgnpinnak : 1; /*!< 07 Set Global Non-Periodic IN NAK */ -+ unsigned tstctl : 3; /*!< 06-04 Test Control */ -+ unsigned goutnaksts : 1; /*!< 03 Global OUT NAK Status */ -+ unsigned gnpinnaksts : 1; /*!< 02 Global Non-Periodic IN NAK Status */ -+ unsigned sftdiscon : 1; /*!< 01 Soft Disconnect */ -+ unsigned rmtwkupsig : 1; /*!< 00 Remote Wakeup */ -+ } b; -+} dctl_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Device Status Register. -+ */ -+typedef union dsts_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved22_31 :10; -+ unsigned soffn :14; /*!< 21-08 Frame or Microframe Number of the received SOF */ -+ unsigned reserved4_7 : 4; -+ unsigned errticerr : 1; /*!< 03 Erratic Error */ -+ unsigned enumspd : 2; /*!< 02-01 Enumerated Speed */ -+ #define IFXUSB_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 -+ #define IFXUSB_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 -+ #define IFXUSB_DSTS_ENUMSPD_LS_PHY_6MHZ 2 -+ #define IFXUSB_DSTS_ENUMSPD_FS_PHY_48MHZ 3 -+ unsigned suspsts : 1; /*!< 00 Suspend Status */ -+ } b; -+} dsts_data_t; -+ -+/*! -+ \brief Bit fields in the Device IN EP Interrupt Register -+ and the Device IN EP Common Mask Register. -+ */ -+typedef union diepint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved14_31 :18; -+ unsigned nakmsk : 1; /*!< 13 NAK interrupt Mask */ -+ unsigned reserved10_12 : 3; -+ unsigned bna : 1; /*!< 09 BNA Interrupt mask */ -+ unsigned txfifoundrn : 1; /*!< 08 Fifo Underrun Mask */ -+ unsigned emptyintr : 1; /*!< 07 IN Endpoint HAK Effective mask */ -+ unsigned inepnakeff : 1; /*!< 06 IN Endpoint HAK Effective mask */ -+ unsigned intknepmis : 1; /*!< 05 IN Token Received with EP mismatch mask */ -+ unsigned intktxfemp : 1; /*!< 04 IN Token received with TxF Empty mask */ -+ unsigned timeout : 1; /*!< 03 TimeOUT Handshake mask (non-ISOC EPs) */ -+ unsigned ahberr : 1; /*!< 02 AHB Error mask */ -+ unsigned epdisabled : 1; /*!< 01 Endpoint disable mask */ -+ unsigned xfercompl : 1; /*!< 00 Transfer complete mask */ -+ } b; -+} diepint_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Device OUT EP Interrupt Register and -+ Device OUT EP Common Interrupt Mask Register. -+ */ -+typedef union doepint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved15_31 :17; -+ unsigned nyetmsk : 1; /*!< 14 NYET Interrupt */ -+ unsigned nakmsk : 1; /*!< 13 NAK Interrupt */ -+ unsigned bbleerrmsk : 1; /*!< 12 Babble Interrupt */ -+ unsigned reserved10_11 : 2; -+ unsigned bna : 1; /*!< 09 BNA Interrupt */ -+ unsigned outpkterr : 1; /*!< 08 OUT packet Error */ -+ unsigned reserved07 : 1; -+ unsigned back2backsetup : 1; /*!< 06 Back-to-Back SETUP Packets Received */ -+ unsigned stsphsercvd : 1; /*!< 05 */ -+ unsigned outtknepdis : 1; /*!< 04 OUT Token Received when Endpoint Disabled */ -+ unsigned setup : 1; /*!< 03 Setup Phase Done (contorl EPs) */ -+ unsigned ahberr : 1; /*!< 02 AHB Error */ -+ unsigned epdisabled : 1; /*!< 01 Endpoint disable */ -+ unsigned xfercompl : 1; /*!< 00 Transfer complete */ -+ } b; -+} doepint_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Device All EP Interrupt Registers. -+ */ -+typedef union daint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned out : 16; /*!< 31-16 OUT Endpoint bits */ -+ unsigned in : 16; /*!< 15-00 IN Endpoint bits */ -+ } eps; -+ struct -+ { -+ /** OUT Endpoint bits */ -+ unsigned outep15 : 1; -+ unsigned outep14 : 1; -+ unsigned outep13 : 1; -+ unsigned outep12 : 1; -+ unsigned outep11 : 1; -+ unsigned outep10 : 1; -+ unsigned outep09 : 1; -+ unsigned outep08 : 1; -+ unsigned outep07 : 1; -+ unsigned outep06 : 1; -+ unsigned outep05 : 1; -+ unsigned outep04 : 1; -+ unsigned outep03 : 1; -+ unsigned outep02 : 1; -+ unsigned outep01 : 1; -+ unsigned outep00 : 1; -+ /** IN Endpoint bits */ -+ unsigned inep15 : 1; -+ unsigned inep14 : 1; -+ unsigned inep13 : 1; -+ unsigned inep12 : 1; -+ unsigned inep11 : 1; -+ unsigned inep10 : 1; -+ unsigned inep09 : 1; -+ unsigned inep08 : 1; -+ unsigned inep07 : 1; -+ unsigned inep06 : 1; -+ unsigned inep05 : 1; -+ unsigned inep04 : 1; -+ unsigned inep03 : 1; -+ unsigned inep02 : 1; -+ unsigned inep01 : 1; -+ unsigned inep00 : 1; -+ } ep; -+} daint_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Device IN Token Queue Read Registers. -+ */ -+typedef union dtknq1_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned epnums0_5 :24; /*!< 31-08 EP Numbers of IN Tokens 0 ... 4 */ -+ unsigned wrap_bit : 1; /*!< 07 write pointer has wrapped */ -+ unsigned reserved05_06 : 2; -+ unsigned intknwptr : 5; /*!< 04-00 In Token Queue Write Pointer */ -+ }b; -+} dtknq1_data_t; -+ -+ -+/*! -+ \brief Bit fields in Threshold control Register -+ */ -+typedef union dthrctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved26_31 : 6; -+ unsigned rx_thr_len : 9; /*!< 25-17 Rx Thr. Length */ -+ unsigned rx_thr_en : 1; /*!< 16 Rx Thr. Enable */ -+ unsigned reserved11_15 : 5; -+ unsigned tx_thr_len : 9; /*!< 10-02 Tx Thr. Length */ -+ unsigned iso_thr_en : 1; /*!< 01 ISO Tx Thr. Enable */ -+ unsigned non_iso_thr_en : 1; /*!< 00 non ISO Tx Thr. Enable */ -+ } b; -+} dthrctl_data_t; -+ -+/*@}*//*IFXUSB_CSR_DEVICE_GLOBAL_REG*/ -+ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_DEVICE_EP_REG -+ */ -+/*@{*/ -+ -+/*! -+ \struct ifxusb_dev_in_ep_regs -+ \brief Device Logical IN Endpoint-Specific Registers. -+ There will be one set of endpoint registers per logical endpoint -+ implemented. -+ each EP's IN EP Register are offset at : -+ 900h + * (ep_num * 20h) -+ */ -+ -+typedef struct ifxusb_dev_in_ep_regs -+{ -+ volatile uint32_t diepctl; /*!< 00h: Endpoint Control Register */ -+ uint32_t reserved04; /*!< 04h: */ -+ volatile uint32_t diepint; /*!< 08h: Endpoint Interrupt Register */ -+ uint32_t reserved0C; /*!< 0Ch: */ -+ volatile uint32_t dieptsiz; /*!< 10h: Endpoint Transfer Size Register.*/ -+ volatile uint32_t diepdma; /*!< 14h: Endpoint DMA Address Register. */ -+ volatile uint32_t dtxfsts; /*!< 18h: Endpoint Transmit FIFO Status Register. */ -+ volatile uint32_t diepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */ -+} ifxusb_dev_in_ep_regs_t; -+ -+/*! -+ \brief Device Logical OUT Endpoint-Specific Registers. -+ There will be one set of endpoint registers per logical endpoint -+ implemented. -+ each EP's OUT EP Register are offset at : -+ B00h + * (ep_num * 20h) + 00h -+ */ -+typedef struct ifxusb_dev_out_ep_regs -+{ -+ volatile uint32_t doepctl; /*!< 00h: Endpoint Control Register */ -+ volatile uint32_t doepfn; /*!< 04h: Endpoint Frame number Register */ -+ volatile uint32_t doepint; /*!< 08h: Endpoint Interrupt Register */ -+ uint32_t reserved0C; /*!< 0Ch: */ -+ volatile uint32_t doeptsiz; /*!< 10h: Endpoint Transfer Size Register.*/ -+ volatile uint32_t doepdma; /*!< 14h: Endpoint DMA Address Register. */ -+ uint32_t reserved18; /*!< 18h: */ -+ volatile uint32_t doepdmab; /*!< 1Ch: Endpoint DMA Buffer Register. */ -+} ifxusb_dev_out_ep_regs_t; -+ -+ -+/*! -+ \brief Bit fields in the Device EP Control -+ Register. -+ */ -+typedef union depctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned epena : 1; /*!< 31 Endpoint Enable */ -+ unsigned epdis : 1; /*!< 30 Endpoint Disable */ -+ unsigned setd1pid : 1; /*!< 29 Set DATA1 PID (INTR/Bulk IN and OUT endpoints) */ -+ unsigned setd0pid : 1; /*!< 28 Set DATA0 PID (INTR/Bulk IN and OUT endpoints) */ -+ unsigned snak : 1; /*!< 27 Set NAK */ -+ unsigned cnak : 1; /*!< 26 Clear NAK */ -+ unsigned txfnum : 4; /*!< 25-22 Tx Fifo Number */ -+ unsigned stall : 1; /*!< 21 Stall Handshake */ -+ unsigned snp : 1; /*!< 20 Snoop Mode */ -+ unsigned eptype : 2; /*!< 19-18 Endpoint Type -+ 0: Control -+ 1: Isochronous -+ 2: Bulk -+ 3: Interrupt -+ */ -+ unsigned naksts : 1; /*!< 17 NAK Status */ -+ unsigned dpid : 1; /*!< 16 Endpoint DPID (INTR/Bulk IN and OUT endpoints) */ -+ unsigned usbactep : 1; /*!< 15 USB Active Endpoint */ -+ unsigned nextep : 4; /*!< 14-11 Next Endpoint */ -+ unsigned mps :11; /*!< 10-00 Maximum Packet Size */ -+ #define IFXUSB_DEP0CTL_MPS_64 0 -+ #define IFXUSB_DEP0CTL_MPS_32 1 -+ #define IFXUSB_DEP0CTL_MPS_16 2 -+ #define IFXUSB_DEP0CTL_MPS_8 3 -+ } b; -+} depctl_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Device EP Transfer Size Register. (EP0 and EPn) -+ */ -+typedef union deptsiz_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31 : 1; -+ unsigned supcnt : 2; /*!< 30-29 Setup Packet Count */ -+ unsigned reserved20_28 : 9; -+ unsigned pktcnt : 1; /*!< 19 Packet Count */ -+ unsigned reserved7_18 :12; -+ unsigned xfersize : 7; /*!< 06-00 Transfer size */ -+ }b0; -+ struct -+ { -+ unsigned reserved : 1; -+ unsigned mc : 2; /*!< 30-29 Multi Count */ -+ unsigned pktcnt :10; /*!< 28-19 Packet Count */ -+ unsigned xfersize :19; /*!< 18-00 Transfer size */ -+ } b; -+} deptsiz_data_t; -+ -+/*@}*//*IFXUSB_CSR_DEVICE_EP_REG*/ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_DEVICE_DMA_DESC -+ */ -+/*@{*/ -+/*! -+ \struct desc_sts_data -+ \brief Bit fields in the DMA Descriptor status quadlet. -+ */ -+typedef union desc_sts_data -+{ -+ struct -+ { -+ unsigned bs : 2; /*!< 31-30 Buffer Status */ -+ #define BS_HOST_READY 0x0 -+ #define BS_DMA_BUSY 0x1 -+ #define BS_DMA_DONE 0x2 -+ #define BS_HOST_BUSY 0x3 -+ unsigned sts : 2; /*!< 29-28 Receive/Trasmit Status */ -+ #define RTS_SUCCESS 0x0 -+ #define RTS_BUFFLUSH 0x1 -+ #define RTS_RESERVED 0x2 -+ #define RTS_BUFERR 0x3 -+ unsigned l : 1; /*!< 27 Last */ -+ unsigned sp : 1; /*!< 26 Short Packet */ -+ unsigned ioc : 1; /*!< 25 Interrupt On Complete */ -+ unsigned sr : 1; /*!< 24 Setup Packet received */ -+ unsigned mtrf : 1; /*!< 23 Multiple Transfer */ -+ unsigned reserved16_22 : 7; -+ unsigned bytes :16; /*!< 15-00 Transfer size in bytes */ -+ } b; -+ uint32_t d32; /*!< DMA Descriptor data buffer pointer */ -+} desc_sts_data_t; -+ -+/*@}*//*IFXUSB_CSR_DEVICE_DMA_DESC*/ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_HOST_GLOBAL_REG -+ */ -+/*@{*/ -+/*! -+ \struct ifxusb_host_global_regs -+ \brief IFXUSB Host Mode Global registers. Offsets 400h-7FFh -+ The ifxusb_host_global_regs structure defines the size -+ and relative field offsets for the Host Global registers. -+ These registers are visible only in Host mode and must not be -+ accessed in Device mode, as the results are unknown. -+ */ -+typedef struct ifxusb_host_global_regs -+{ -+ volatile uint32_t hcfg; /*!< 400h Host Configuration Register. */ -+ volatile uint32_t hfir; /*!< 404h Host Frame Interval Register. */ -+ volatile uint32_t hfnum; /*!< 408h Host Frame Number / Frame Remaining Register. */ -+ uint32_t reserved40C; -+ volatile uint32_t hptxsts; /*!< 410h Host Periodic Transmit FIFO/ Queue Status Register. */ -+ volatile uint32_t haint; /*!< 414h Host All Channels Interrupt Register. */ -+ volatile uint32_t haintmsk; /*!< 418h Host All Channels Interrupt Mask Register. */ -+} ifxusb_host_global_regs_t; -+ -+/*! -+ \brief Bit fields in the Host Configuration Register. -+ */ -+typedef union hcfg_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved31_03 :29; -+ unsigned fslssupp : 1; /*!< 02 FS/LS Only Support */ -+ unsigned fslspclksel : 2; /*!< 01-00 FS/LS Phy Clock Select */ -+ #define IFXUSB_HCFG_30_60_MHZ 0 -+ #define IFXUSB_HCFG_48_MHZ 1 -+ #define IFXUSB_HCFG_6_MHZ 2 -+ } b; -+} hcfg_data_t; -+ -+/*! -+ \brief Bit fields in the Host Frame Interval Register. -+ */ -+typedef union hfir_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 16; -+ unsigned frint : 16; /*!< 15-00 Frame Interval */ -+ } b; -+} hfir_data_t; -+ -+/*! -+ \brief Bit fields in the Host Frame Time Remaing/Number Register. -+ */ -+typedef union hfnum_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned frrem : 16; /*!< 31-16 Frame Time Remaining */ -+ unsigned frnum : 16; /*!< 15-00 Frame Number*/ -+ #define IFXUSB_HFNUM_MAX_FRNUM 0x3FFF -+ } b; -+} hfnum_data_t; -+ -+/*! -+ \brief Bit fields in the Host Periodic Transmit FIFO/Queue Status Register -+ */ -+typedef union hptxsts_data -+{ -+ /** raw register data */ -+ uint32_t d32; -+ struct -+ { -+ /** Top of the Periodic Transmit Request Queue -+ * - bit 24 - Terminate (last entry for the selected channel) -+ */ -+ unsigned ptxqtop_odd : 1; /*!< 31 Top of the Periodic Transmit Request -+ Queue Odd/even microframe*/ -+ unsigned ptxqtop_chnum : 4; /*!< 30-27 Top of the Periodic Transmit Request -+ Channel Number */ -+ unsigned ptxqtop_token : 2; /*!< 26-25 Top of the Periodic Transmit Request -+ Token Type -+ 0 - Zero length -+ 1 - Ping -+ 2 - Disable -+ */ -+ unsigned ptxqtop_terminate : 1; /*!< 24 Top of the Periodic Transmit Request -+ Terminate (last entry for the selected channel)*/ -+ unsigned ptxqspcavail : 8; /*!< 23-16 Periodic Transmit Request Queue Space Available */ -+ unsigned ptxfspcavail :16; /*!< 15-00 Periodic Transmit Data FIFO Space Available */ -+ } b; -+} hptxsts_data_t; -+ -+/*! -+ \brief Bit fields in the Host Port Control and Status Register. -+ */ -+typedef union hprt0_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved19_31 :13; -+ unsigned prtspd : 2; /*!< 18-17 Port Speed */ -+ #define IFXUSB_HPRT0_PRTSPD_HIGH_SPEED 0 -+ #define IFXUSB_HPRT0_PRTSPD_FULL_SPEED 1 -+ #define IFXUSB_HPRT0_PRTSPD_LOW_SPEED 2 -+ unsigned prttstctl : 4; /*!< 16-13 Port Test Control */ -+ unsigned prtpwr : 1; /*!< 12 Port Power */ -+ unsigned prtlnsts : 2; /*!< 11-10 Port Line Status */ -+ unsigned reserved9 : 1; -+ unsigned prtrst : 1; /*!< 08 Port Reset */ -+ unsigned prtsusp : 1; /*!< 07 Port Suspend */ -+ unsigned prtres : 1; /*!< 06 Port Resume */ -+ unsigned prtovrcurrchng : 1; /*!< 05 Port Overcurrent Change */ -+ unsigned prtovrcurract : 1; /*!< 04 Port Overcurrent Active */ -+ unsigned prtenchng : 1; /*!< 03 Port Enable/Disable Change */ -+ unsigned prtena : 1; /*!< 02 Port Enable */ -+ unsigned prtconndet : 1; /*!< 01 Port Connect Detected */ -+ unsigned prtconnsts : 1; /*!< 00 Port Connect Status */ -+ }b; -+} hprt0_data_t; -+ -+/*! -+ \brief Bit fields in the Host All Interrupt Register. -+ */ -+typedef union haint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 16; -+ unsigned ch15 : 1; -+ unsigned ch14 : 1; -+ unsigned ch13 : 1; -+ unsigned ch12 : 1; -+ unsigned ch11 : 1; -+ unsigned ch10 : 1; -+ unsigned ch09 : 1; -+ unsigned ch08 : 1; -+ unsigned ch07 : 1; -+ unsigned ch06 : 1; -+ unsigned ch05 : 1; -+ unsigned ch04 : 1; -+ unsigned ch03 : 1; -+ unsigned ch02 : 1; -+ unsigned ch01 : 1; -+ unsigned ch00 : 1; -+ } b; -+ struct -+ { -+ unsigned reserved : 16; -+ unsigned chint : 16; -+ } b2; -+} haint_data_t; -+/*@}*//*IFXUSB_CSR_HOST_GLOBAL_REG*/ -+/****************************************************************************/ -+/*! -+ \addtogroup IFXUSB_CSR_HOST_HC_REG -+ */ -+/*@{*/ -+/*! -+ \brief Host Channel Specific Registers -+ There will be one set of hc registers per host channelimplemented. -+ each HC's Register are offset at : -+ 500h + * (hc_num * 20h) -+ */ -+typedef struct ifxusb_hc_regs -+{ -+ volatile uint32_t hcchar; /*!< 00h Host Channel Characteristic Register.*/ -+ volatile uint32_t hcsplt; /*!< 04h Host Channel Split Control Register.*/ -+ volatile uint32_t hcint; /*!< 08h Host Channel Interrupt Register. */ -+ volatile uint32_t hcintmsk; /*!< 0Ch Host Channel Interrupt Mask Register. */ -+ volatile uint32_t hctsiz; /*!< 10h Host Channel Transfer Size Register. */ -+ volatile uint32_t hcdma; /*!< 14h Host Channel DMA Address Register. */ -+ uint32_t reserved[2]; /*!< 18h Reserved. */ -+} ifxusb_hc_regs_t; -+ -+ -+/*! -+ \brief Bit fields in the Host Channel Characteristics Register. -+ */ -+typedef union hcchar_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned chen : 1; /*!< 31 Channel enable */ -+ unsigned chdis : 1; /*!< 30 Channel disable */ -+ unsigned oddfrm : 1; /*!< 29 Frame to transmit periodic transaction */ -+ unsigned devaddr : 7; /*!< 28-22 Device address */ -+ unsigned multicnt : 2; /*!< 21-20 Packets per frame for periodic transfers */ -+ unsigned eptype : 2; /*!< 19-18 0: Control, 1: Isoc, 2: Bulk, 3: Intr */ -+ unsigned lspddev : 1; /*!< 17 0: Full/high speed device, 1: Low speed device */ -+ unsigned reserved : 1; -+ unsigned epdir : 1; /*!< 15 0: OUT, 1: IN */ -+ unsigned epnum : 4; /*!< 14-11 Endpoint number */ -+ unsigned mps :11; /*!< 10-00 Maximum packet size in bytes */ -+ } b; -+} hcchar_data_t; -+ -+/*! -+ \brief Bit fields in the Host Channel Split Control Register -+ */ -+typedef union hcsplt_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned spltena : 1; /*!< 31 Split Enble */ -+ unsigned reserved :14; -+ unsigned compsplt : 1; /*!< 16 Do Complete Split */ -+ unsigned xactpos : 2; /*!< 15-14 Transaction Position */ -+ #define IFXUSB_HCSPLIT_XACTPOS_MID 0 -+ #define IFXUSB_HCSPLIT_XACTPOS_END 1 -+ #define IFXUSB_HCSPLIT_XACTPOS_BEGIN 2 -+ #define IFXUSB_HCSPLIT_XACTPOS_ALL 3 -+ unsigned hubaddr : 7; /*!< 13-07 Hub Address */ -+ unsigned prtaddr : 7; /*!< 06-00 Port Address */ -+ } b; -+} hcsplt_data_t; -+ -+/*! -+ \brief Bit fields in the Host Interrupt Register. -+ */ -+typedef union hcint_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved :21; -+ unsigned datatglerr : 1; /*!< 10 Data Toggle Error */ -+ unsigned frmovrun : 1; /*!< 09 Frame Overrun */ -+ unsigned bblerr : 1; /*!< 08 Babble Error */ -+ unsigned xacterr : 1; /*!< 07 Transaction Err */ -+ unsigned nyet : 1; /*!< 06 NYET Response Received */ -+ unsigned ack : 1; /*!< 05 ACK Response Received */ -+ unsigned nak : 1; /*!< 04 NAK Response Received */ -+ unsigned stall : 1; /*!< 03 STALL Response Received */ -+ unsigned ahberr : 1; /*!< 02 AHB Error */ -+ unsigned chhltd : 1; /*!< 01 Channel Halted */ -+ unsigned xfercomp : 1; /*!< 00 Channel Halted */ -+ }b; -+} hcint_data_t; -+ -+ -+/*! -+ \brief Bit fields in the Host Channel Transfer Size -+ Register. -+ */ -+typedef union hctsiz_data -+{ -+ uint32_t d32; -+ struct -+ { -+ /** */ -+ unsigned dopng : 1; /*!< 31 Do PING protocol when 1 */ -+ /** -+ * Packet ID for next data packet -+ * 0: DATA0 -+ * 1: DATA2 -+ * 2: DATA1 -+ * 3: MDATA (non-Control), SETUP (Control) -+ */ -+ unsigned pid : 2; /*!< 30-29 Packet ID for next data packet -+ 0: DATA0 -+ 1: DATA2 -+ 2: DATA1 -+ 3: MDATA (non-Control), SETUP (Control) -+ */ -+ #define IFXUSB_HCTSIZ_DATA0 0 -+ #define IFXUSB_HCTSIZ_DATA1 2 -+ #define IFXUSB_HCTSIZ_DATA2 1 -+ #define IFXUSB_HCTSIZ_MDATA 3 -+ #define IFXUSB_HCTSIZ_SETUP 3 -+ unsigned pktcnt :10; /*!< 28-19 Data packets to transfer */ -+ unsigned xfersize :19; /*!< 18-00 Total transfer size in bytes */ -+ }b; -+} hctsiz_data_t; -+ -+/*@}*//*IFXUSB_CSR_HOST_HC_REG*/ -+ -+/****************************************************************************/ -+ -+/*! -+ \addtogroup IFXUSB_CSR_PWR_CLK_GATING_REG -+ */ -+/*@{*/ -+/*! -+ \brief Bit fields in the Power and Clock Gating Control Register -+ */ -+typedef union pcgcctl_data -+{ -+ uint32_t d32; -+ struct -+ { -+ unsigned reserved : 27; -+ unsigned physuspended : 1; /*!< 04 PHY Suspended */ -+ unsigned rstpdwnmodule : 1; /*!< 03 Reset Power Down Modules */ -+ unsigned pwrclmp : 1; /*!< 02 Power Clamp */ -+ unsigned gatehclk : 1; /*!< 01 Gate Hclk */ -+ unsigned stoppclk : 1; /*!< 00 Stop Pclk */ -+ } b; -+} pcgcctl_data_t; -+/*@}*//*IFXUSB_CSR_PWR_CLK_GATING_REG*/ -+ -+/****************************************************************************/ -+ -+#endif //__IFXUSB_REGS_H__ ---- /dev/null -+++ b/drivers/usb/ifxhcd/ifxusb_version.h -@@ -0,0 +1,5 @@ -+ -+#ifndef IFXUSB_VERSION -+#define IFXUSB_VERSION "3.0alpha B100312" -+#endif -+ |