diff --exclude CVS -uNr linuxppc_2_4_devel/.gdbinit linuxppc_2_4_devel.modified/.gdbinit --- linuxppc_2_4_devel/.gdbinit 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/.gdbinit 2007-01-30 18:03:11.000000000 +0100 @@ -0,0 +1,2 @@ +file /home/fra/Projekte/tsuka/tsuka/src/kernel/linuxppc_2_4_devel.modified/vmlinux +target remote bdi:2001 diff --exclude CVS -uNr linuxppc_2_4_devel/Makefile linuxppc_2_4_devel.modified/Makefile --- linuxppc_2_4_devel/Makefile 2006-05-05 17:00:49.000000000 +0200 +++ linuxppc_2_4_devel.modified/Makefile 2007-01-12 17:49:05.000000000 +0100 @@ -195,6 +195,7 @@ DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o +DRIVERS-$(CONFIG_TSUKA) += drivers/tsuka/tsuka-obj.o DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o @@ -476,7 +477,7 @@ cd .. && tar cf - linux/ | gzip -9 > backup.gz sync -sgmldocs: +sgmldocs: chmod 755 $(TOPDIR)/scripts/docgen chmod 755 $(TOPDIR)/scripts/gen-all-syms chmod 755 $(TOPDIR)/scripts/kernel-doc diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/5xxx_io/Config.in linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/Config.in --- linuxppc_2_4_devel/arch/ppc/5xxx_io/Config.in 2006-07-13 16:20:35.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/Config.in 2006-12-04 10:09:11.000000000 +0100 @@ -11,13 +11,15 @@ dep_bool ' Generic PHY support' CONFIG_FEC_GENERIC_PHY $CONFIG_USE_MDIO dep_bool ' Support LXT971 PHY' CONFIG_FEC_LXT971 $CONFIG_USE_MDIO dep_bool ' Support DP83847 PHY' CONFIG_FEC_DP83847 $CONFIG_USE_MDIO -if [ "$CONFIG_PPC_5xxx_FEC" = "y" ]; then - define_bool CONFIG_USB_USEBOTH n -fi +dep_bool ' Support DP83848 PHY' CONFIG_FEC_DP83848 $CONFIG_USE_MDIO +#if [ "$CONFIG_PPC_5xxx_FEC" = "y" ]; then +# define_bool CONFIG_USB_USEBOTH n +#fi # Serial. bool 'PSC serial support' CONFIG_PPC_5xxx_PSC dep_bool ' PSC Console support' CONFIG_PPC_5xxx_PSC_CONSOLE $CONFIG_PPC_5xxx_PSC +dep_bool ' Katana Reset' CONFIG_MECH_KATANA_RESET $CONFIG_PPC_5xxx_PSC_CONSOLE if [ "$CONFIG_PPC_5xxx_PSC_CONSOLE" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y fi diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/5xxx_io/fec.c linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/fec.c --- linuxppc_2_4_devel/arch/ppc/5xxx_io/fec.c 2006-05-04 23:56:09.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/fec.c 2006-12-11 18:06:47.000000000 +0100 @@ -610,6 +610,78 @@ #endif /* CONFIG_FEC_DP83847 */ + +/* ----------------------------------------------------------------- */ +/* The National Semiconductor DP83848 is used on a Tsuka board */ +/* ----------------------------------------------------------------- */ + +#ifdef CONFIG_FEC_DP83848 + +/* Register definitions */ +#define MII_DP83848_PHYSTS 0x10 /* PHY Status Register */ + +static void mii_parse_dp83848_physts(uint mii_reg, struct net_device *dev, uint data) +{ + struct mpc5xxx_fec_priv *priv = (struct mpc5xxx_fec_priv *)dev->priv; + uint s = priv->phy_status; + + s &= ~(PHY_STAT_SPMASK); + + if (mii_reg & 0x2) { + if (mii_reg & 0x4) + s |= PHY_STAT_10FDX; + else + s |= PHY_STAT_10HDX; + } + else { + if (mii_reg & 0x4) + s |= PHY_STAT_100FDX; + else + s |= PHY_STAT_100HDX; + } + if (mii_reg & 0x40) + s |= PHY_STAT_FAULT; + + priv->full_duplex = ((mii_reg & 0x4) != 0); + + priv->phy_status = s; +} + +static phy_info_t phy_info_dp83848 = { + 0x020005c9, + "DP83848", + + (const phy_cmd_t []) { /* config */ + { mk_mii_write(MII_REG_ANAR, 0x01E1), NULL }, /* Auto-Negociation Register Control set to */ + /* auto-negociate 10/100MBps, Half/Full duplex */ + /*{ mk_mii_write(MII_REG_ANAR, 0x0081), NULL },*/ /* no auto-negociate 100MBps, Half duplex */ + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup */ + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* Enable and Restart Auto-Negotiation */ + /* { mk_mii_write(MII_REG_CR, 0x2100), NULL }, */ /* Disable Auto-Negotiation */ + /* { mk_mii_write(MII_REG_CR, 0x2000), NULL }, */ /* Disable Auto-Negotiation */ + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_DP83848_PHYSTS), mii_parse_dp83848_physts }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_DP83848_PHYSTS), mii_parse_dp83848_physts }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_end, } + } +}; + +#endif /* CONFIG_FEC_DP83848 */ + + static phy_info_t *phy_info[] = { #ifdef CONFIG_FEC_LXT971 @@ -620,6 +692,10 @@ &phy_info_dp83847, #endif /* CONFIG_FEC_DP83847 */ +#ifdef CONFIG_FEC_DP83848 + &phy_info_dp83848, +#endif /* CONFIG_FEC_DP83848 */ + #ifdef CONFIG_FEC_GENERIC_PHY /* Generic PHY support. This must be the last PHY in the table. * It will be used to support any PHY that doesn't match a previous @@ -1013,8 +1089,8 @@ priv->phy_speed = (((MPC5xxx_IPBFREQ >> 20) / 5) << 1); - /*mpc5xxx_fec_restart (dev, 0);*/ /* half duplex, negotiate speed */ - mpc5xxx_fec_restart (dev, 1); /* full duplex, negotiate speed */ + mpc5xxx_fec_restart (dev, 0); /* half duplex, negotiate speed */ + /*mpc5xxx_fec_restart (dev, 1);*/ /* full duplex, negotiate speed */ /* Queue up command to detect the PHY and initialize the * remainder of the interface. @@ -1118,15 +1194,15 @@ short length; BDIdx bdi_a; -#if MPC5xxx_FEC_DEBUG > 4 - printk("mpc5xxx_fec_hard_start_xmit:\n"); - printk("dev %08x, priv %08x, skb %08x\n", - (u32)dev, (u32)priv, (u32)skb); -#endif -#if MPC5xxx_FEC_DEBUG > 0 - if (fec_start_status(&priv->t_queue) & MPC5xxx_FEC_TBD_TFD) - panic("MPC5xxx transmit queue overrun\n"); -#endif +// #if MPC5xxx_FEC_DEBUG > 4 +// printk("mpc5xxx_fec_hard_start_xmit:\n"); +// printk("dev %08x, priv %08x, skb %08x\n", +// (u32)dev, (u32)priv, (u32)skb); +// #endif +// #if MPC5xxx_FEC_DEBUG > 0 +// if (fec_start_status(&priv->t_queue) & MPC5xxx_FEC_TBD_TFD) +// panic("MPC5xxx transmit queue overrun\n"); +// #endif length = skb->len; #ifdef MUST_ALIGN_TRANSMIT_DATA diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/5xxx_io/psc.c linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/psc.c --- linuxppc_2_4_devel/arch/ppc/5xxx_io/psc.c 2006-07-28 01:15:20.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/5xxx_io/psc.c 2006-08-14 13:08:04.000000000 +0200 @@ -33,6 +33,14 @@ #include #endif + +#ifdef CONFIG_MECH_KATANA_RESET +# define GPIO_PSC6_1 0x20000000UL +# define SET_MECH_RESET_KATANA ((*(unsigned long*) MPC5xxx_WU_GPIO_DATAOUT) |= GPIO_PSC6_1) +# define CLEAR_MECH_RESET_KATANA ((*(unsigned long*) MPC5xxx_WU_GPIO_DATAOUT) &= ~GPIO_PSC6_1) +# define MECH_RESET_KATANA_DELAY 10 +#endif + /* * This driver can spew a whole lot of debugging output at you. If you * need maximum performance, you should disable the DEBUG define. @@ -81,7 +89,7 @@ #elif defined(CONFIG_MCC200) #define MPC5xxx_PSC_NPORTS 1 #else -#define MPC5xxx_PSC_NPORTS 3 +#define MPC5xxx_PSC_NPORTS 2 #endif #ifdef CONFIG_PPC_5xxx_PSC_CONSOLE @@ -674,6 +682,28 @@ func_exit(); } + +#ifdef CONFIG_MECH_KATANA_RESET +static int reset_katana(struct rs_port *port){ + + struct mpc5xxx_psc *psc = port->psc; + + if(psc == (struct mpc5xxx_psc*)MPC5xxx_PSC6){ + printk("Katana reset\n"); + /* reset katana */ + *((unsigned int*)MPC5xxx_GPT0_ENABLE) = 0x00000034; + udelay(100); + *((unsigned int*)MPC5xxx_GPT0_ENABLE) = 0x00000024; + + return 0; + } + else{ + printk("Katana reset can only be applied on katana UART\n"); + return -EREMOTEIO; + } +} +#endif + static int rs_ioctl(struct tty_struct * tty, struct file * filp, unsigned int cmd, unsigned long arg) { @@ -708,6 +738,12 @@ rc = gs_setserial(&port->gs, (struct serial_struct *) arg); break; +#ifdef CONFIG_MECH_KATANA_RESET + case MECH_RESET_KATANA: + rc = reset_katana(port); + printk("reset done\n"); + break; +#endif default: rc = -ENOIOCTLCMD; break; diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/config.in linuxppc_2_4_devel.modified/arch/ppc/config.in --- linuxppc_2_4_devel/arch/ppc/config.in 2006-07-20 12:52:07.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/config.in 2006-08-25 09:11:45.000000000 +0200 @@ -1094,6 +1094,8 @@ source drivers/usb/Config.in +source drivers/tsuka/Config.in + source net/bluetooth/Config.in source crypto/Config.in diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/configs/TSUKA_defconfig linuxppc_2_4_devel.modified/arch/ppc/configs/TSUKA_defconfig --- linuxppc_2_4_devel/arch/ppc/configs/TSUKA_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/arch/ppc/configs/TSUKA_defconfig 2007-02-01 15:04:07.000000000 +0100 @@ -0,0 +1,981 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_ADVANCED_OPTIONS=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E500 is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_83xx is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_INKA4X0 is not set +# CONFIG_WILLOW is not set +# CONFIG_TOP5200 is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_PPMC260 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_HMI1001 is not set +# CONFIG_PP01 is not set +# CONFIG_CPC45 is not set +# CONFIG_CU824 is not set +# CONFIG_PM520 is not set +# CONFIG_MCC200 is not set +# CONFIG_PUMA_A is not set +# CONFIG_ALASKA is not set +# CONFIG_GLACIER is not set +# CONFIG_ICECUBE is not set +# CONFIG_LITE5200B is not set +# CONFIG_HXEB100 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_P3G4 is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_SL8245 is not set +# CONFIG_SMMACO4 is not set +# CONFIG_GEMINI is not set +CONFIG_TQM5200=y +# CONFIG_O2DNT is not set +# CONFIG_SORCERY is not set +CONFIG_PPC_5xxx=y +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +CONFIG_PPC_ISATIMER=y +# CONFIG_MPC5100 is not set +CONFIG_MPC5200=y +CONFIG_PPC_5xxx_PSC_CONSOLE_BAUD=115200 +CONFIG_UBOOT=y +CONFIG_PPC_5xxx_PSC_CONSOLE_PORT=0 +# CONFIG_TB5200 is not set +CONFIG_STK52XX=y + +# +# General setup +# +# CONFIG_BIGPHYS_AREA is not set +# CONFIG_HIGHMEM is not set +# CONFIG_LOWMEM_SIZE_BOOL is not set +# CONFIG_KERNEL_START_BOOL is not set +# CONFIG_TASK_SIZE_BOOL is not set +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_GEN_RTC is not set +CONFIG_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Embedded options +# +# CONFIG_EMBEDDED is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PUMA_A is not set +# CONFIG_MTD_CHESTNUT is not set +# CONFIG_MTD_K2 is not set +# CONFIG_MTD_HXEB100 is not set +# CONFIG_MTD_PPMC260 is not set +# CONFIG_MTD_CU824 is not set +# CONFIG_MTD_CPC45 is not set +# CONFIG_MTD_HMI1001 is not set +# CONFIG_MTD_ICECUBE is not set +# CONFIG_MTD_ICECUBE is not set +# CONFIG_MTD_INKA4X0 is not set +# CONFIG_MTD_O2DNT is not set +# CONFIG_MTD_P3G4 is not set +# CONFIG_MTD_PP01 is not set +# CONFIG_MTD_MCC200 is not set +# CONFIG_MTD_PM520 is not set +# CONFIG_MTD_SL8245 is not set +# CONFIG_MTD_SMMACO4 is not set +# CONFIG_MTD_SORCERY is not set +CONFIG_MTD_TQM5200=y +# CONFIG_MTD_TQM5200_B is not set +CONFIG_MTD_TSUKA=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=12288 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_TOS is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_SCSI_DEBUG_QUEUES is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_GIANFAR is not set +# CONFIG_GFAR_NAPI is not set +# CONFIG_GFAR_BDSTASH is not set +# CONFIG_GFAR_BUFSTASH is not set +# CONFIG_FDDI is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_PS2MULT is not set +# CONFIG_KEYMAP_DE_LATIN1 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_11_MINUTE_MODE is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_FLASH is not set +# CONFIG_3DMSMFIFO_DRV is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# +# CONFIG_DRM is not set +# CONFIG_SRAM is not set +# CONFIG_TQM5200_DIGIO is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WRITEBUFFER is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_ZISOFS_FS=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC5xxx I/O Options +# +CONFIG_BESTCOMM_API=y +CONFIG_PPC_5xxx_FEC=y +CONFIG_USE_MDIO=y +# CONFIG_FEC_GENERIC_PHY is not set +# CONFIG_FEC_LXT971 is not set +# CONFIG_FEC_DP83847 is not set +CONFIG_FEC_DP83848=y +CONFIG_PPC_5xxx_PSC=y +CONFIG_PPC_5xxx_PSC_CONSOLE=y +CONFIG_MECH_KATANA_RESET=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_5200_I2S is not set +# CONFIG_5200_I2S_RING is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI_PCI=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_OHCI_5xxx=y +# CONFIG_USB_SINGLEENDED is not set +CONFIG_USB_USEBOTH=y +CONFIG_USB_OHCI_BIG_ENDIAN=y +CONFIG_USB_OHCI=y +# CONFIG_USB_ISP1362 is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_MCT_U232=y +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set +# CONFIG_ISP1362_USB is not set +# CONFIG_ISP1362_NETLINK is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_NET2280 is not set +CONFIG_USB_GADGET_NET2282=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_NET2280=y +CONFIG_USB_GADGET_CONTROLLER=y +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_FILE_STORAGE is not set + +# +# Tsuka +# +CONFIG_TSUKA=y +CONFIG_TSUKA_IO=y + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_IOVIRT is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +CONFIG_BDI_SWITCH=y +CONFIG_MORE_COMPILE_OPTIONS=y +CONFIG_COMPILE_OPTIONS="-g -ggdb" +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_LOG_BUF_SHIFT=0 diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/defconfig linuxppc_2_4_devel.modified/arch/ppc/defconfig --- linuxppc_2_4_devel/arch/ppc/defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/arch/ppc/defconfig 2007-02-01 15:03:31.000000000 +0100 @@ -0,0 +1,999 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_ADVANCED_OPTIONS=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E500 is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_83xx is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_INKA4X0 is not set +# CONFIG_WILLOW is not set +# CONFIG_TOP5200 is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_PPMC260 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_HMI1001 is not set +# CONFIG_PP01 is not set +# CONFIG_CPC45 is not set +# CONFIG_CU824 is not set +# CONFIG_PM520 is not set +# CONFIG_MCC200 is not set +# CONFIG_PUMA_A is not set +# CONFIG_ALASKA is not set +# CONFIG_GLACIER is not set +# CONFIG_ICECUBE is not set +# CONFIG_LITE5200B is not set +# CONFIG_HXEB100 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_P3G4 is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_SL8245 is not set +# CONFIG_SMMACO4 is not set +# CONFIG_GEMINI is not set +CONFIG_TQM5200=y +# CONFIG_O2DNT is not set +# CONFIG_SORCERY is not set +CONFIG_PPC_5xxx=y +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +CONFIG_PPC_ISATIMER=y +# CONFIG_MPC5100 is not set +CONFIG_MPC5200=y +CONFIG_PPC_5xxx_PSC_CONSOLE_BAUD=115200 +CONFIG_UBOOT=y +CONFIG_PPC_5xxx_PSC_CONSOLE_PORT=0 +# CONFIG_TB5200 is not set +CONFIG_STK52XX=y + +# +# General setup +# +# CONFIG_BIGPHYS_AREA is not set +# CONFIG_HIGHMEM is not set +# CONFIG_LOWMEM_SIZE_BOOL is not set +# CONFIG_KERNEL_START_BOOL is not set +# CONFIG_TASK_SIZE_BOOL is not set +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_GEN_RTC is not set +CONFIG_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Embedded options +# +# CONFIG_EMBEDDED is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PUMA_A is not set +# CONFIG_MTD_CHESTNUT is not set +# CONFIG_MTD_K2 is not set +# CONFIG_MTD_HXEB100 is not set +# CONFIG_MTD_PPMC260 is not set +# CONFIG_MTD_CU824 is not set +# CONFIG_MTD_CPC45 is not set +# CONFIG_MTD_HMI1001 is not set +# CONFIG_MTD_ICECUBE is not set +# CONFIG_MTD_ICECUBE is not set +# CONFIG_MTD_INKA4X0 is not set +# CONFIG_MTD_O2DNT is not set +# CONFIG_MTD_P3G4 is not set +# CONFIG_MTD_PP01 is not set +# CONFIG_MTD_MCC200 is not set +# CONFIG_MTD_PM520 is not set +# CONFIG_MTD_SL8245 is not set +# CONFIG_MTD_SMMACO4 is not set +# CONFIG_MTD_SORCERY is not set +CONFIG_MTD_TQM5200=y +# CONFIG_MTD_TQM5200_B is not set +CONFIG_MTD_TSUKA=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=12288 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_TOS is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_SCSI_DEBUG_QUEUES is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_GIANFAR is not set +# CONFIG_GFAR_NAPI is not set +# CONFIG_GFAR_BDSTASH is not set +# CONFIG_GFAR_BUFSTASH is not set +# CONFIG_FDDI is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_PS2MULT is not set +# CONFIG_KEYMAP_DE_LATIN1 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_ALGOBIT is not set +CONFIG_SPI_5xxx=y +CONFIG_SPI_PINS_ALTERNATIVE=y +# CONFIG_SPI_5xxx_PSC is not set +# CONFIG_SPI_5xxx_USE_EOF is not set +# CONFIG_SPI_ITI5200 is not set +CONFIG_SPI_TSUKA=y +# CONFIG_SPI_EVAL is not set +# CONFIG_SPI_HMI1001 is not set +# CONFIG_HMI1001_KBD is not set +# CONFIG_SPI_MCC200 is not set +# CONFIG_SPI_5xxx_PSC2_FIFO is not set +# CONFIG_SPI_5xxx_PSC3_FIFO is not set +# CONFIG_SPI_5xxx_PSC6_FIFO is not set +CONFIG_SPI_CHARDEV=y +# CONFIG_SPI_MCC200DEV is not set +# CONFIG_SPI_EVAL_CHARDEV is not set +CONFIG_SPI_PROC=y + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_RTC_11_MINUTE_MODE is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_FLASH is not set +# CONFIG_3DMSMFIFO_DRV is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# +# CONFIG_DRM is not set +# CONFIG_SRAM is not set +# CONFIG_TQM5200_DIGIO is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WRITEBUFFER is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +CONFIG_ROMFS_FS=y +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_ZISOFS_FS=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC5xxx I/O Options +# +CONFIG_BESTCOMM_API=y +CONFIG_PPC_5xxx_FEC=y +CONFIG_USE_MDIO=y +# CONFIG_FEC_GENERIC_PHY is not set +# CONFIG_FEC_LXT971 is not set +# CONFIG_FEC_DP83847 is not set +CONFIG_FEC_DP83848=y +CONFIG_PPC_5xxx_PSC=y +CONFIG_PPC_5xxx_PSC_CONSOLE=y +CONFIG_MECH_KATANA_RESET=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_5200_I2S is not set +# CONFIG_5200_I2S_RING is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI_PCI=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_OHCI_5xxx=y +# CONFIG_USB_SINGLEENDED is not set +CONFIG_USB_USEBOTH=y +CONFIG_USB_OHCI_BIG_ENDIAN=y +CONFIG_USB_OHCI=y +# CONFIG_USB_ISP1362 is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_MCT_U232=y +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set +# CONFIG_ISP1362_USB is not set +# CONFIG_ISP1362_NETLINK is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_NET2280 is not set +CONFIG_USB_GADGET_NET2282=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_NET2280=y +CONFIG_USB_GADGET_CONTROLLER=y +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_FILE_STORAGE is not set + +# +# Tsuka +# +CONFIG_TSUKA=y +CONFIG_TSUKA_IO=y + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_IOVIRT is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +CONFIG_BDI_SWITCH=y +CONFIG_MORE_COMPILE_OPTIONS=y +CONFIG_COMPILE_OPTIONS="-g -ggdb" +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_LOG_BUF_SHIFT=0 diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/kernel/mpc5xxx_pic.c linuxppc_2_4_devel.modified/arch/ppc/kernel/mpc5xxx_pic.c --- linuxppc_2_4_devel/arch/ppc/kernel/mpc5xxx_pic.c 2006-07-13 20:18:37.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/kernel/mpc5xxx_pic.c 2006-12-15 17:06:26.000000000 +0100 @@ -207,6 +207,10 @@ 0x000c0000 | /* IRQ2: level-sensitive, active low */ 0x00030000 | /* IRQ3: level-sensitive, active low */ #endif +#if defined(CONFIG_TSUKA) + 0x000c0000 | /* IRQ2: level-sensitive, active low */ + 0x00030000 | /* IRQ3: level-sensitive, active low */ +#endif 0x00001000 | /* MEE master external enable */ 0x00000000 | /* 0 means disable IRQ 0-3 */ 0x00000001); /* CEb route critical normally */ diff --exclude CVS -uNr linuxppc_2_4_devel/arch/ppc/platforms/tqm5200.h linuxppc_2_4_devel.modified/arch/ppc/platforms/tqm5200.h --- linuxppc_2_4_devel/arch/ppc/platforms/tqm5200.h 2006-07-20 12:52:07.000000000 +0200 +++ linuxppc_2_4_devel.modified/arch/ppc/platforms/tqm5200.h 2006-08-14 13:27:17.000000000 +0200 @@ -56,7 +56,7 @@ #if defined(CONFIG_SPI_EVAL) || defined(CONFIG_TB5200) #define RS_TABLE_SIZE 2 #else -#define RS_TABLE_SIZE 3 +#define RS_TABLE_SIZE 2 #endif #endif @@ -93,22 +93,36 @@ .io_type = SERIAL_IO_MEM, \ } #else -#ifdef CONFIG_SPI_EVAL -#define SERIAL_PORT_DFNS \ +#define SERIAL_PORT_DFNS \ + STD_PSC_OP(1) \ +{ \ + .magic = 0, \ + .baud_base = MPC5xxx_INIT_BAUD_BASE, \ + .irq = MPC5xxx_IRDA_IRQ, \ + .flags = ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST, \ + .iomem_base = (void *)MPC5xxx_PSC6, \ + .io_type = SERIAL_IO_MEM, \ +} + +#if 0 +# ifdef CONFIG_SPI_EVAL +# define SERIAL_PORT_DFNS \ STD_PSC_OP(6) \ STD_PSC_OP(3) -#else -#ifdef CONFIG_TB5200 -#define SERIAL_PORT_DFNS \ +# else +# ifdef CONFIG_TB5200 +# define SERIAL_PORT_DFNS \ STD_PSC_OP(1) \ STD_PSC_OP(6) -#else -#define SERIAL_PORT_DFNS \ +# else +# define SERIAL_PORT_DFNS \ STD_PSC_OP(1) \ STD_PSC_OP(2) \ STD_PSC_OP(3) -#endif /* CONFIG_TB5200 */ -#endif /* CONFIG_SPI_EVAL */ +# endif /* CONFIG_TB5200 */ +# endif /* CONFIG_SPI_EVAL */ +#endif + #endif /* CONFIG_PS2MULT */ #endif /* __PLATFORMS_TQM5200_H */ diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/Makefile linuxppc_2_4_devel.modified/drivers/Makefile --- linuxppc_2_4_devel/drivers/Makefile 2006-04-21 18:37:25.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/Makefile 2006-08-25 09:19:10.000000000 +0200 @@ -50,5 +50,6 @@ subdir-$(CONFIG_ACPI_BOOT) += acpi subdir-$(CONFIG_BLUEZ) += bluetooth +subdir-$(CONFIG_TSUKA) += tsuka include $(TOPDIR)/Rules.make diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/mtd/maps/Config.in linuxppc_2_4_devel.modified/drivers/mtd/maps/Config.in --- linuxppc_2_4_devel/drivers/mtd/maps/Config.in 2006-07-28 11:39:51.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/mtd/maps/Config.in 2006-08-14 13:50:29.000000000 +0200 @@ -70,6 +70,7 @@ dep_tristate ' CFI Flash device mapped on TQM5200' CONFIG_MTD_TQM5200 $CONFIG_MTD_CFI $CONFIG_TQM5200 if [ "$CONFIG_MTD_TQM5200" = "y" ]; then bool ' Flash map for Rev B modules' CONFIG_MTD_TQM5200_B + bool ' Flash map for Tsuka' CONFIG_MTD_TSUKA fi fi if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "y" ]; then diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/mtd/maps/tqm5200.c linuxppc_2_4_devel.modified/drivers/mtd/maps/tqm5200.c --- linuxppc_2_4_devel/drivers/mtd/maps/tqm5200.c 2006-07-28 11:39:51.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/mtd/maps/tqm5200.c 2006-12-15 10:35:36.000000000 +0100 @@ -103,7 +103,65 @@ /* partition definition for first (and only) flash bank */ -#ifdef CONFIG_MTD_TQM5200_B +#ifdef CONFIG_MTD_TSUKA +static struct mtd_partition tqm5200_partitions_32M[] = { + { + name: "firmware", /* U-Boot Firmware and configuration*/ + offset: 0x00000000, + size: 0x000C0000, + mask_flags: MTD_WRITEABLE, /* force read-only 768k*/ + }, + { + name: "kernel", /* default kernel image 1280k*/ + offset: 0x000C0000, + size: 0x00140000, + }, + { + name: "initrd", /* RAMdisk image 6MB*/ + offset: 0x00200000, + size: 0x00600000, + }, + { + name: "big-fs", /* Big filesystem 23MB */ + offset: 0x00800000, + size: 0x01740000, + }, + { + name: "fpga-fw", /* FPGA-Firmware 768k */ + offset: 0x01f40000, + size: 0x000C0000, + }, +}; +/*static struct mtd_partition tqm5200_partitions_32M[] = { + { + name: "firmware", + offset: 0x00000000, + size: 0x00080000, + mask_flags: MTD_WRITEABLE, + }, + { + name: "kernel", + offset: 0x00080000, + size: 0x00180000, + }, + { + name: "initrd", + offset: 0x00200000, + size: 0x00600000, + }, + { + name: "big-fs", + offset: 0x00800000, + size: 0x01700000, + }, + { + name: "fpga-fw", + offset: 0x01f00000, + size: 0x00100000, + }, +};*/ +#else +# ifdef CONFIG_MTD_TQM5200_B static struct mtd_partition tqm5200_partitions_32M[] = { { name: "firmware", /* U-Boot Firmware */ @@ -132,7 +190,7 @@ size: 0x01000000, }, }; -#else /* older modules */ +# else /* older modules */ static struct mtd_partition tqm5200_partitions_32M[] = { { name: "firmware", /* U-Boot Firmware */ @@ -161,6 +219,7 @@ size: 0x01000000, }, }; +#endif /* CONFIG_MTD_TSUKA */ #endif /* CONFIG_MTD_TQM5200_B */ #ifdef CONFIG_MTD_TQM5200_B diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/Config.in linuxppc_2_4_devel.modified/drivers/tsuka/Config.in --- linuxppc_2_4_devel/drivers/tsuka/Config.in 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/Config.in 2006-07-14 14:58:05.000000000 +0200 @@ -0,0 +1,11 @@ +# +# Character device configuration +# +mainmenu_option next_comment +comment 'Tsuka' + +tristate 'Tsuka' CONFIG_TSUKA +if [ "$CONFIG_TSUKA" = "y" -o "$CONFIG_TSUKA" = "m" ]; then + bool ' Support Tsuka IO' CONFIG_TSUKA_IO +fi +endmenu diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/Makefile linuxppc_2_4_devel.modified/drivers/tsuka/Makefile --- linuxppc_2_4_devel/drivers/tsuka/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/Makefile 2007-01-30 12:24:41.000000000 +0100 @@ -0,0 +1,42 @@ +# /* ************************************************************ * +# * _____ ______ _____ * +# * |_ _| | ____|/ ____| * +# * | | _ __ | |__ | (___ Institute of Embedded Systems * +# * | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +# * _| |_| | | | |____ ____) | (University of Applied Sciences) * +# * |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +# ***************************************************************** +# * +# * Project : Tsuka +# * Description : Makefile zu Treiber und Testprogramm +# * +# * $LastChangedDate: 2006-08-23 09:40:28 +0200 (Wed, 23 Aug 2006) $ +# * $Rev: 99 $ +# * $Author: fra $ +# *--------------------------------------------------------------- +# * +# * Change History +# * Date |Name |Modification +# *----------|----------|----------------------------------------- +# * 20.08.06 | fra |file ceated +# *---------------------------------------------------------------*/ + + +O_TARGET := tsuka-obj.o +TSUKA_DEV_MAJOR=122 + +list-multi := tsuka.o +tsuka-objs := tsuka_main.o tsuka_input.o tsuka_output.o tsuka_timer_output.o + +obj-$(CONFIG_TSUKA) += tsuka.o + +# export-objs := .o # all objects which make use of the EXPORT_SYMBOL macro + +EXTRA_CFLAGS += -DTSUKA_DEV_MAJOR=${TSUKA_DEV_MAJOR} + + +include $(TOPDIR)/Rules.make + +tsuka.o: $(tsuka-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(tsuka-objs) + diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/logfunctions.h linuxppc_2_4_devel.modified/drivers/tsuka/logfunctions.h --- linuxppc_2_4_devel/drivers/tsuka/logfunctions.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/logfunctions.h 2007-02-01 14:48:13.000000000 +0100 @@ -0,0 +1,74 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : This file provides macros verbosity based logging +* to kernel-log. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-08-23 09:39:04 +0200 (Wed, 23 Aug 2006) $ +* $Rev: 98 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +/* */ + +#ifndef TSUKA_LOGFUNCTIONS_H +#define TSUKA_LOGFUNCTIONS_H + + +// #define TSUKA_DEBUG_LOG + +/* + * Macros for driver log outputs + */ +#define PFX "["DRV_NAME"]: " + +/* log a line to kernel log */ +#ifdef TSUKA_DEBUG_LOG_SRC + /* add source file name and line number */ + #define TSUKA_LOG(format, args...) \ + printk(KERN_INFO PFX __FILE__ ":%d: " format, __LINE__, ##args) +#else + #define TSUKA_LOG(format, args...) printk(KERN_INFO PFX format, ##args) +#endif + + +/* info and error log macros */ +#define TSUKA_INFOOUT(format, args...) TSUKA_LOG(" "format, ##args) +#define TSUKA_ERROUT(format, args...) TSUKA_LOG(" " format, ##args) + +/* general module debug macros */ +#ifdef TSUKA_DEBUG_LOG + extern int debug_level; + #define TSUKA_LOGOUT(level, format, args...) if (debug_level >= level) \ + TSUKA_LOG(" " format, ##args) +#else + #define TSUKA_LOGOUT(level, format, args...) +#endif + +/* IO debug macros */ +#ifdef TSUKA_DEBUG_LOG + extern int io_debug_level; + #define TSUKA_IO_LOGOUT(level, format, args...) if (io_debug_level >= level) \ + TSUKA_LOG(" " format, ##args) +#else + #define TSUKA_IO_LOGOUT(level, format, args...) +#endif + + +#endif /* TSUKA_LOGFUNCTIONS_H */ + diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_devfile.h linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_devfile.h --- linuxppc_2_4_devel/drivers/tsuka/tsuka_devfile.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_devfile.h 2007-01-30 14:41:58.000000000 +0100 @@ -0,0 +1,106 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Common header file for driver module and user +* space applications using the tsuka module. +* Contains information needed for device file usage. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + + +#ifndef TSUKA_DEVFILE_H +#define TSUKA_DEVFILE_H + +#ifndef __KERNEL__ +typedef unsigned int u32; +#endif + +/* Major number of device file (120 - 127 is for local/experimental use */ +// #define TSUKA_DEV_MAJOR 122 + +/* base name of the device file */ +#define TSUKA_DEV_FILENAME "tsuka" +/* names for io device files */ +#define TSUKA_DEV_FILE0 TSUKA_DEV_FILENAME"0" +#define TSUKA_DEV_FILE1 TSUKA_DEV_FILENAME"1" +#define TSUKA_DEV_FILE2 TSUKA_DEV_FILENAME"2" +#define TSUKA_DEV_FILE3 TSUKA_DEV_FILENAME"3" +#define TSUKA_DEV_FILE4 TSUKA_DEV_FILENAME"5" +#define TSUKA_DEV_FILE5 TSUKA_DEV_FILENAME"6" + + +/* this bitmaps defines which io pin is accessible on which device + * file from user space. Change this array for an other pin / device + * file configuration */ +/* used by TSUKA_input_dev_t */ + +static const u32 input_bitmask[] = +/* in diagnose stop pwr fail under voltage over current*/ +{ 0x0000000f, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000}; +#define TSUKA_NUM_INPUT_BITMASK (sizeof(input_bitmask)/sizeof(u32)) +#define TSUKA_NUM_INPUT_DEV TSUKA_NUM_INPUT_BITMASK + +/* used by TSUKA_output_dev_t */ + /* led */ +static const u32 output_bitmask[] = {0x00ffffff}; +#define TSUKA_NUM_OUTPUT_BITMASK (sizeof(output_bitmask)/sizeof(u32)) +#define TSUKA_NUM_OUTPUT_DEV TSUKA_NUM_OUTPUT_BITMASK + +#define TSUKA_NUM_TIMER_OUTPUT_DEV 1 + +#define TSUKA_NUM_DEVICES (TSUKA_NUM_INPUT_DEV + TSUKA_NUM_OUTPUT_DEV + TSUKA_NUM_TIMER_OUTPUT_DEV) + +/* get device from minor number */ +#define TSUKA_MINOR_GET_INPUT_DEV_NUM(minor) (minor) +#define TSUKA_MINOR_GET_OUTPUT_DEV_NUM(minor) (minor - TSUKA_NUM_INPUT_DEV) +#define TSUKA_MINOR_GET_TIMER_OUTPUT_DEV_NUM(minor) (minor - TSUKA_NUM_INPUT_DEV - TSUKA_NUM_OUTPUT_DEV) + + + +/*****************************************************************************/ +/*** this section is for user land applications which use the device file ****/ +#ifndef _IO +#include /* for ioctl commands */ +#endif +/*****************************************************************************/ + + +/* commands for ioctl() on the device file */ +#define TSUKA_DEV_IOCTL_MAGIC 'E' + +/* FPGA global ioctls */ +#define TSUKA_IOCTL_GET_HW_INFO _IOR(TSUKA_DEV_IOCTL_MAGIC, 1, Tsuka_Hw_Info) +/* input dev ioctls */ +#define TSUKA_INDEV_IOCTL_SET_IRQ_MASK _IOW(TSUKA_DEV_IOCTL_MAGIC, 1, u32) +#define TSUKA_INDEV_IOCTL_GET_IRQ_MASK _IOR(TSUKA_DEV_IOCTL_MAGIC, 2, u32) +#define TSUKA_INDEV_IOCTL_SET_POTI_CURRENT _IOW(TSUKA_DEV_IOCTL_MAGIC, 3, u32) +#define TSUKA_INDEV_IOCTL_GET_POTI_CURRENT _IOR(TSUKA_DEV_IOCTL_MAGIC, 4, u32) +#define TSUKA_INDEV_IOCTL_SET_POTI_VOLTAGE _IOW(TSUKA_DEV_IOCTL_MAGIC, 5, u32) +#define TSUKA_INDEV_IOCTL_GET_POTI_VOLTAGE _IOR(TSUKA_DEV_IOCTL_MAGIC, 6, u32) + +typedef struct{ + u32 hw_id; + u32 fw_id; +}Tsuka_Hw_Info; + + +#endif /* TSUKA_DEVFILE_H */ + diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_input.c linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_input.c --- linuxppc_2_4_devel/drivers/tsuka/tsuka_input.c 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_input.c 2007-01-12 16:36:22.000000000 +0100 @@ -0,0 +1,277 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Input class. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +/* include this in all files but the module main file */ +#define __NO_VERSION__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tsuka_input.h" +#include "tsuka_devfile.h" +#include "logfunctions.h" +#include "tsuka_main.h" + + +/* FPGA provides irq 2 and 3, we use irq 2 (MPC5xxx_IRQ2) for the input module */ +#define TSUKA_INPUT_IRQ 6 + +/***************************************************************************** + * private functions prototypes + *****************************************************************************/ + + +/***************************************************************************** + * private variables + *****************************************************************************/ + +/* one spinlock per fpga input region */ +static spinlock_t input_reg_lock = SPIN_LOCK_UNLOCKED; +/* count created input devices, is needed by create */ +static int tsuka_num_input_dev = 0; +/* Pointer to each input device is needed by the interrupt handler */ +static struct TSUKA_input_dev_t* tsuka_input_devs[TSUKA_NUM_INPUT_DEV] = {NULL, }; + + +/***************************************************************************** + * private functions implementations + *****************************************************************************/ + +/* write a fpga register */ +static inline void tsuka_input_fpga_write(struct TSUKA_input_dev_t* indev, u16 reg, u32 data) +{ + u32 *wr_ptr = indev->fpga_base_addr + (reg >> 2); + + TSUKA_IO_LOGOUT(3, "indev: entering %s() val 0x%08x @ %p for minor number %d\n", + __FUNCTION__, data, wr_ptr, indev->minor); + + writel(data, wr_ptr); + + return; +} + +/* read a fpga register */ +static inline u32 tsuka_input_fpga_read(struct TSUKA_input_dev_t* indev, u16 reg) +{ + u32 *rd_ptr = indev->fpga_base_addr + (reg >> 2); + u32 rd_val; + + rd_val = (u32)readl(rd_ptr); + + TSUKA_IO_LOGOUT(3, "indev: entering %s() @ %p for minor number %d, reading 0x%08x\n", + __FUNCTION__, rd_ptr, indev->minor, rd_val); + + return rd_val; +} + +/* write which touches only the bits of the given indev object */ +static inline void tsuka_input_fpga_write_masked(struct TSUKA_input_dev_t* indev, u16 reg, u32 data) +{ + u32 saved_register; +TSUKA_IO_LOGOUT(3, "indev: entering %s() reg: %x, data: 0x%08x\n", __FUNCTION__, reg, data); + spin_lock(indev->lock); + saved_register = tsuka_input_fpga_read(indev, reg); + barrier(); + saved_register &= ~indev->bitmask; + saved_register |= (data & indev->bitmask); + barrier(); + tsuka_input_fpga_write(indev, reg, saved_register); + spin_unlock(indev->lock); +} + +/* write which touches only the bits of the given indev object */ +static inline u32 tsuka_input_fpga_read_masked(struct TSUKA_input_dev_t* indev, u16 reg) +{ + u32 saved_register; + + saved_register = tsuka_input_fpga_read(indev, reg); + saved_register = saved_register & indev->bitmask; + + return saved_register; +} + + +/* called by the kernel if device file is opened */ +static int tsuka_input_dev_open(struct TSUKA_dev_t* thisptr, struct inode* inode, struct file* filp) +{ + struct TSUKA_input_dev_t* indev = (struct TSUKA_input_dev_t*)thisptr; + int minor; + + TSUKA_IO_LOGOUT(3, "indev: entering %s() for minor number %d\n", + __FUNCTION__, MINOR(inode->i_rdev)); + + /* get the minor number for the device file which was opened */ + minor = indev->minor; + + /* enable interrupt channel in FPGA */ + tsuka_input_fpga_write_masked(indev, TSUKA_REG_IRQ_MASK, 0xffffffff); + indev->open_count++; + + TSUKA_IO_LOGOUT(3, "indev: device file /dev/%s%d opened\n", TSUKA_DEV_FILENAME, minor); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is closed */ +static int tsuka_input_dev_release(struct inode * inode, struct file * filp) +{ + struct TSUKA_input_dev_t* indev = filp->private_data; + int minor; + /* get the minor number for the device file which was opened */ + minor = indev->minor; + + TSUKA_IO_LOGOUT(3, "indev: /dev/%s%d: device file closed\n", TSUKA_DEV_FILENAME, minor); + + indev->open_count--; + /* disable interrupt channel in FPGA */ + if(indev->open_count == 0) + tsuka_input_fpga_write_masked(indev, TSUKA_REG_IRQ_MASK, 0x0); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is read */ +static ssize_t tsuka_input_dev_read(struct file* filp, char* buf, size_t count, loff_t* offset) +{ + struct TSUKA_input_dev_t* indev = filp->private_data; + u32 value; + + TSUKA_IO_LOGOUT(3, "indev: entering %s() for minor number %d\n", + __FUNCTION__, indev->minor); + + /* if the user requested more or less bytes than a io width, return EOF */ + if (count != sizeof(u32)) + { + TSUKA_ERROUT("indev: %s%d: bytes requested: %u, allowed is sizeof(u32) = %u, returning EOF\n", + TSUKA_DEV_FILENAME, indev->minor, count, + sizeof(u32)); + /* a return value of 0 signals EOF (end of file) to user */ + return(0); + } + + TSUKA_IO_LOGOUT(2, "indev: %s%d: read request for %u bytes\n", TSUKA_DEV_FILENAME, + indev->minor, count); + + /* read input from fpga */ + value = tsuka_input_fpga_read_masked(indev, TSUKA_REG_IN_1); + + /* copy value to userspace */ + if (copy_to_user(buf, &value, sizeof(u32)) != 0) + { + return(-EINVAL); + } + /* return number of bytes copied */ + return(count); +} + + +/* called by the kernel if ioctl on device file */ +static int tsuka_input_dev_ioctl(struct inode* inode , struct file* filp, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + return(ret); +} + + +/***************************************************************************** + * public interface functions implementations + *****************************************************************************/ + +/* return a pointer to kmalloced struct TSUKA_input_dev_t if successfull, NULL if failed */ +struct TSUKA_dev_t* __devinit tsuka_input_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor) +{ + struct TSUKA_input_dev_t* indev; + int ret = 0; + + TSUKA_IO_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* allocate a struct, fill it and give it back */ + if ((indev = kmalloc(sizeof(struct TSUKA_input_dev_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("allocation of struct TSUKA_input_dev_t failed\n"); + return(0); + } + TSUKA_IO_LOGOUT(2, "%s\n", "struct TSUKA_input_dev_t allocated"); + + /* initialize struct */ + memset(indev, 0, sizeof(*indev)); + + /* init private variables */ + init_waitqueue_head(&indev->read_queue); + indev->fpga_base_addr = fpga_base_addr + (TSUKA_REGION_INPUT_DEV >> 2); + indev->bitmask = input_bitmask[TSUKA_MINOR_GET_INPUT_DEV_NUM(minor)]; + indev->minor = minor; + indev->lock = &input_reg_lock; + indev->open_count = 0; + + tsuka_fops->tsuka_dev_open = tsuka_input_dev_open; + tsuka_fops->tsuka_dev_release = tsuka_input_dev_release; + tsuka_fops->tsuka_dev_read = tsuka_input_dev_read; +// tsuka_fops->tsuka_dev_poll = tsuka_input_dev_poll; + tsuka_fops->tsuka_dev_ioctl = tsuka_input_dev_ioctl; + + + /* make this object accessible for the interrupt handler */ + tsuka_input_devs[tsuka_num_input_dev] = indev; + TSUKA_IO_LOGOUT(2, "tsuka_input_devs[%d](=%p)->fpga_base_addr: %p\n", tsuka_num_input_dev, indev, tsuka_input_devs[tsuka_num_input_dev]->fpga_base_addr); + + tsuka_num_input_dev++; + + TSUKA_IO_LOGOUT(2, "indev: created, registers @ %p\n", indev->fpga_base_addr); + + /* if we are here, we were successfull */ + return((struct TSUKA_dev_t*)indev); + +error_free_indev: + kfree(indev); + return 0; +} + +/* stop and free all resources, the indev pointer is not valid anymore + * after a call to this function! */ +void __devexit tsuka_input_dev_destroy(struct TSUKA_dev_t* tsuka_dev) +{ + struct TSUKA_input_dev_t* indev = (struct TSUKA_input_dev_t*)tsuka_dev; + TSUKA_IO_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* free the structure */ + kfree(indev); + + tsuka_num_input_dev--; + + TSUKA_IO_LOGOUT(2, "FPGA: struct TSUKA_input_dev_t freed"); +} diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_input.h linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_input.h --- linuxppc_2_4_devel/drivers/tsuka/tsuka_input.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_input.h 2006-12-19 07:23:27.000000000 +0100 @@ -0,0 +1,77 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Input class. +* Credits: : basic driver framework is based on Jög Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + + +#ifndef TSUKA_INPUT_H +#define TSUKA_INPUT_H + + +#define TSUKA_REGION_INPUT_DEV 0x40 /* first register of io modul offset (address/4) */ // 0x10 + + +/* FPGA registers offsets */ +#define TSUKA_REG_IO_ID 0x0 +#define TSUKA_REG_IRQ_MASK 0x4 +#define TSUKA_REG_IRQ_EDGE 0x8 +#define TSUKA_REG_IRQ_PEND 0xC +#define TSUKA_REG_IN_1 0x10 + + + + +struct TSUKA_fops_t; + +/* Attention: all TSUKA_xyz_dev_t must contain some values in a given order!!! + * The struct are used as pointer arrays. In tsuka_main.c is the basic type + * containing only the mandatory parameter. Copy and past this to setup a new class.*/ +struct TSUKA_input_dev_t +{ + /* device specific parameters */ + int minor; /* minor number for this device file */ + u32* fpga_base_addr; /* base address of io registers */ + wait_queue_head_t read_queue; /* kernel wait queue for blocking reads */ + u32 bitmask; /* which bits are handled by this object? */ + spinlock_t *lock; /* lock the fpga region */ + int open_count; /* needed to enable and disable interrupt sources in FPGA */ +}; + +/***************************************************************************** + * public interface function prototypes + *****************************************************************************/ + +/* return a pointer to kmalloced TSUKA_input_dev_t if successfull, NULL if failed */ +struct TSUKA_input_dev_t* __devinit tsuka_devfile_create(unsigned int* fpga_base_addr); +/* free all resources, the iodev pointer is not valid anymore + * after a call to this function! */ +void __devexit tsuka_devfile_destroy(struct TSUKA_input_dev_t* iodev); + +/* setup TSUKA_input_dev_t internal struct and return a ponter to the new object */ +struct TSUKA_dev_t* __devinit tsuka_input_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor); +/* tidy up what tsuka_input_dev_create initialised */ +void __devexit tsuka_input_dev_destroy(struct TSUKA_dev_t* tsuka_dev); + +// void __devexit tsuka_input_dev_get_irq_handler(*TSUKA_irq_handler_t fptr); + +#endif /* TSUKA_INPUT_H */ diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_main.c linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_main.c --- linuxppc_2_4_devel/drivers/tsuka/tsuka_main.c 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_main.c 2007-02-01 10:02:56.000000000 +0100 @@ -0,0 +1,873 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Supports the functions provided by the ZHW Tsuka +* FPGA: Inputs, Outputs +* This is the central class of the driver. +* Some object-oriented structures are setup and the +* PCI interface is configured. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +/* This is the main module file which contains the code to load and + * unload the module */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tsuka_devfile.h" +#include "tsuka_input.h" +#include "tsuka_output.h" +#include "tsuka_timer_output.h" +#include "tsuka_main.h" +#include "logfunctions.h" + + +/***************************************************************************** + * private types + *****************************************************************************/ + +typedef void* tsuka_iobase_t; + +/* per PCI card data */ +struct TSUKA_pci_card_t +{ + /* PCI */ + tsuka_iobase_t iobase; /* IO base address */ + unsigned long iolen; /* length of IO range */ + unsigned int* fpga_base_addr; /* base address of global registers */ + + /* one pointer for each Object (IO, OUTPUT, LED...)*/ + struct TSUKA_dev_t* tsuka_dev[TSUKA_NUM_DEVICES]; + struct TSUKA_fops_t* tsuka_fops[TSUKA_NUM_DEVICES]; +}; + + +/***************************************************************************** + * module global variables + *****************************************************************************/ + +#ifdef TSUKA_DEBUG_LOG + int debug_level = 3; + int io_debug_level = 3; +#endif + +/***************************************************************************** + * module parameter declarations + *****************************************************************************/ + +/* + * Module parameters for debugging + * use module_param for 2.6 kernels, this makes module parameters + * automagically appear in /sys/modules/TSUKA/parameters + * where they can be written and read when the is module loaded +*/ +#ifdef TSUKA_DEBUG_LOG + MODULE_PARM(debug_level, "i"); + MODULE_PARM(io_debug_level, "i"); + MODULE_PARM_DESC(debug_level, DRV_NAME "general debug log level"); + MODULE_PARM_DESC(io_debug_level, DRV_NAME "IO debug log level"); +#endif + +/***************************************************************************** + * module strings + *****************************************************************************/ + +MODULE_AUTHOR("ZHW/InES Adrian Freihofer "); +MODULE_DESCRIPTION("Linux driver for IOs on Tsuka"); +MODULE_LICENSE("GPL"); + +/***************************************************************************** + * private functions prototypes + *****************************************************************************/ + +/* file operations */ +/* called by the kernel if device file is opened */ +static int tsuka_dev_open(struct inode* inode, struct file *filp); +/* called by the kernel if device file is closed */ +static int tsuka_dev_release(struct inode* inode, struct file *filp); +/* called by the kernel if ioctl on device file */ +static int tsuka_dev_ioctl(struct inode* inode , struct file* filp, + unsigned int cmd, unsigned long arg); +/* called by the kernel if device file is read */ +static ssize_t tsuka_dev_read(struct file* filp, char* buf, size_t count, loff_t* offset); +/* called by the kernel if device file is writen */ +static ssize_t tsuka_dev_write(struct file* filp, const char* buf, size_t count, loff_t* offset); +/* called by the kernel on system call select or poll */ +static unsigned int tsuka_dev_poll(struct file * filp, struct poll_table_struct *waitp); + +/* called by kernel if proc filesystem is read */ +static int tsuka_dev_read_procmem(char *buf, char **start, off_t offset, + int count, int *eof, void *data); + +/* register the device file in the kernel */ +static int tsuka_dev_register(void); +/* unregister the device file in the kernel */ +static void tsuka_dev_unregister(void); + +/* called by the kernel if module is loaded */ +static int __init tsuka_init_module(void); +/* called by the kernel if module is unloaded */ +static void __exit tsuka_exit_module(void); + +/* add PCI device, this function is called from pci_module_init() */ +static int __devinit tsuka_probe_pci(struct pci_dev* pdev, const struct pci_device_id* pci_id); +/* remove PCI device, this function is called from pci_unregister_driver() */ +static void __devexit tsuka_remove_pci(struct pci_dev *pdev); + +/* check if the FPGA is up and running */ +static int tsuka_check_fpga(struct TSUKA_pci_card_t* carddev); + + +/***************************************************************************** + * declare module load/unload functions + *****************************************************************************/ + +module_init(tsuka_init_module); +module_exit(tsuka_exit_module); + +/***************************************************************************** + * PCI device identifiers + *****************************************************************************/ + +/* faked ZHW PCI Identifier (not registered by PCI SIG) */ +#define TSUKA_PCI_SUBSYSTEM_VENDOR_ID_ZHW 0x0abb +#define TSUKA_PCI_SUBSYSTEM_ID 0x0001 +static struct pci_device_id TSUKA_pci_tbl[] __devinitdata = { + { TSUKA_PCI_SUBSYSTEM_VENDOR_ID_ZHW, TSUKA_PCI_SUBSYSTEM_ID, 0x1588, 0x0001, 0, 0, 0 }, + { 0, } /* 0 terminated list!!! do not remove this or you will get kernel oops while module loading */ +}; +/* declare PCI ids used by this module */ +MODULE_DEVICE_TABLE(pci, TSUKA_pci_tbl); + +/***************************************************************************** + * private variables + *****************************************************************************/ + +/* kernel PCI driver data */ +static struct pci_driver TSUKA_pci_driver = +{ + .name = DRV_NAME, + .probe = tsuka_probe_pci, + .remove = __devexit_p(tsuka_remove_pci), + .id_table = TSUKA_pci_tbl, +}; + +/* struct containing the file operation function pointers for the device file * + * gcc inits all members not mentioned here to NULL */ +static struct file_operations tsuka_dev_fops = +{ + .open = tsuka_dev_open, + .release = tsuka_dev_release, + .ioctl = tsuka_dev_ioctl, + .read = tsuka_dev_read, + .write = tsuka_dev_write, + .poll = tsuka_dev_poll, +}; + +/* For normal use the minor specific datas of this struct are available + * via the file->private_data pointer. This array serves only to pass + * the pointer from the pci_probe function to the per minor open function */ +static struct TSUKA_pci_card_t* tsuka_pci_device = NULL; +/* counter of active pci instances to find errors */ +static atomic_t tsuka_pci_card_count = ATOMIC_INIT(0); + + +/***************************************************************************** + * private function implementations + *****************************************************************************/ + +/* write a fpga register */ +static inline void tsuka_fpga_write(struct TSUKA_pci_card_t* carddev, u16 reg, u32 data) +{ + TSUKA_LOGOUT(3, "dev: entering %s() @ %p\n", __FUNCTION__, carddev->fpga_base_addr + reg); + writel(data, carddev->fpga_base_addr + reg); + return; +} + + +/* read a fpga register */ +static inline u32 tsuka_fpga_read(struct TSUKA_pci_card_t* carddev, u16 reg) +{ + TSUKA_LOGOUT(3, "dev: entering %s() @ %p\n", __FUNCTION__, carddev->fpga_base_addr + reg); + return (u32)readl(carddev->fpga_base_addr + reg); +} + +static u32 read_fpga_hw_id(void) +{ + return tsuka_fpga_read(tsuka_pci_device, TSUKA_REG_HW_ID); +} + +static u32 read_fpga_fw_id(void) +{ + return tsuka_fpga_read(tsuka_pci_device, TSUKA_REG_FW_ID); +} + +/* called by the kernel if module is loaded */ +static int __init tsuka_init_module(void) +{ + int ret; + + TSUKA_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + TSUKA_LOGOUT(0, "%s\n", "start module loading"); + + TSUKA_INFOOUT("ZHW/InES TSUKA IO driver\n"); + TSUKA_INFOOUT("%s\n", "Linux Driver " VERSION); + TSUKA_INFOOUT("(c) 2005 Zurich University of Applied Sciences\n"); + TSUKA_INFOOUT(" Institute of Embedded Systems\n"); + TSUKA_INFOOUT("contact \n"); + TSUKA_LOGOUT(0, "Module debug logging enabled\n"); + TSUKA_LOGOUT(0, "Debug levels:\n"); + TSUKA_LOGOUT(0, " debug_level = %d\n", debug_level); + TSUKA_LOGOUT(0, " io_debug_level = %d\n", io_debug_level); + + /* register the device file(s) */ + if ((ret = tsuka_dev_register()) < 0) + { + return -ENODEV; + } + + /* search for TSUKA PCI fpga */ + if ((ret = pci_module_init(&TSUKA_pci_driver)) < 0) + { + TSUKA_ERROUT("%s\n", "No " DRV_NAME " PCI cards found"); + goto err_unregister_devfile; + ret = -ENODEV; + } + TSUKA_INFOOUT("%d " DRV_NAME " PCI fpga found\n", atomic_read(&tsuka_pci_card_count)); + + + /* create entry in /proc file system */ + create_proc_read_entry(DRV_NAME, 0, NULL, tsuka_dev_read_procmem, NULL); + + /* if we are here, we were successfull */ + TSUKA_INFOOUT("module loaded\n"); + return(0); + +err_unregister_devfile: + /* unregister the device file(s) */ + TSUKA_ERROUT("%s\n", "loading module failed"); + tsuka_dev_unregister(); + return(ret); +} + +/* called by the kernel if module is unloaded */ +static void __exit tsuka_exit_module(void) +{ + TSUKA_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + TSUKA_LOGOUT(2, "%s\n", "start module unloading"); + + /* unregister the pci devices */ + pci_unregister_driver(&TSUKA_pci_driver); + + /* unregister the device file(s) */ + tsuka_dev_unregister(); + + TSUKA_INFOOUT("%s\n", "module unloaded"); +} + +/* add PCI device, this function is called from pci_module_init() */ +static int __devinit tsuka_probe_pci(struct pci_dev* pdev, const struct pci_device_id* pci_id) +{ + struct TSUKA_pci_card_t* carddev; + int res; + int ret = 0; + unsigned long iobase_phys; + int dev_num; + + TSUKA_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + if(atomic_read(&tsuka_pci_card_count) == 1) + { + TSUKA_ERROUT("driver supports only one FPGA\n"); + return(-ENODEV); + } + + /* allocate a struct */ + if ((carddev = kmalloc(sizeof(struct TSUKA_pci_card_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("allocation of struct TSUKA_pci_card_t failed\n"); + return(-ENOMEM); + } + TSUKA_LOGOUT(2, "struct TSUKA_pci_card_t allocated\n"); + + /* init pointers */ + for(dev_num=0; dev_num < TSUKA_NUM_DEVICES; dev_num++){ + carddev->tsuka_dev[dev_num] = NULL; + carddev->tsuka_fops[dev_num] = NULL; + } + + /* enable the pci device */ + if ((res = pci_enable_device(pdev)) < 0) + { + TSUKA_ERROUT("failed to enable PCI device - pci_enable_device() returned %d\n", res); + ret = -ENODEV; + goto err_free_carddev; + } + TSUKA_LOGOUT(2, "%s\n", "PCI device successfully enabled"); + + /* Get the memory IO base address */ + if ((iobase_phys = pci_resource_start(pdev, FPGA_REG_GLOBAL_OFFSET)) == 0) + { + TSUKA_ERROUT("%s\n", "PCI card has no memory IO resources"); + ret = -ENODEV; + goto err_disable_device; + } + TSUKA_LOGOUT(2, "physical memory IO base address: %ph\n", (void*)iobase_phys); + + /* check if it is a memory IO resource */ + if ((pci_resource_flags(pdev, FPGA_REG_GLOBAL_OFFSET) & IORESOURCE_MEM) == 0) + { + TSUKA_ERROUT("PCI resource in BAR%d is not of type memory IO\n", FPGA_REG_GLOBAL_OFFSET); + ret = -ENODEV; + goto err_disable_device; + } + TSUKA_LOGOUT(2, "PCI resource in BAR%d is of type memory IO\n", FPGA_REG_GLOBAL_OFFSET); + + /* get the memory IO space length */ + if ((carddev->iolen = pci_resource_len(pdev, FPGA_REG_GLOBAL_OFFSET)) == 0) + { + TSUKA_ERROUT("%s\n", "unable to retrieve memory IO space length"); + ret = -ENODEV; + goto err_disable_device; + } + TSUKA_LOGOUT(2, "memory IO space length : %u bytes\n", (unsigned int)carddev->iolen); + + /* remap the physical memory IO to make it accessable */ + if ((carddev->iobase = ioremap(iobase_phys, carddev->iolen)) == NULL) + { + TSUKA_ERROUT("unable to remap physical IO memory range 0x%p - 0x%p\n", + (void*)iobase_phys, (void*)(iobase_phys + carddev->iolen)); + ret = -ENOMEM; + goto err_disable_device; + } + TSUKA_LOGOUT(2, "physical IO memory region remapped to 0x%p - 0x%p\n", + carddev->iobase, carddev->iobase + carddev->iolen); + + /* request the memory IO region */ + if (request_mem_region((unsigned long)carddev->iobase, carddev->iolen, DRV_NAME) == NULL) + { + TSUKA_ERROUT("unable to reserve memory IO range 0x%p - 0x%p\n", + (void*)carddev->iobase, (void*)(carddev->iobase + carddev->iolen)); + ret = -ENOMEM; + goto err_release_mem_region; + } + TSUKA_LOGOUT(0, "memory IO region successfully reserved: 0x%p - 0x%p\n", + (void*)carddev->iobase, (void*)(carddev->iobase + carddev->iolen)); + + TSUKA_INFOOUT("%s found. Memory mapped IO: 0x%p - 0x%p\n", + TSUKA_CARD_NAME, carddev->iobase, + carddev->iobase + carddev->iolen); + + /* store our private data into the pci device struct */ + pci_set_drvdata(pdev, carddev); + /* store it also in a global array to make it available in open */ + tsuka_pci_device = carddev; + + carddev->fpga_base_addr = carddev->iobase + FPGA_REG_GLOBAL_OFFSET; + + /* check if FPGA is running */ + if (tsuka_check_fpga(carddev) < 0) + { + TSUKA_ERROUT("fpga not ready!!\n"); + ret = -ENODEV; + goto err_iounmap; + } + + TSUKA_LOGOUT(2, "FPGA up and running. :-)\n"); + + TSUKA_LOGOUT(3, "setting up %d input devices\n", TSUKA_NUM_INPUT_DEV); + TSUKA_LOGOUT(3, "setting up %d output devices\n", TSUKA_NUM_OUTPUT_DEV); + TSUKA_LOGOUT(3, "setting up %d timer_output devices\n", 1); + /* init module sub classes */ + dev_num = 0; + + /* init input devices */ + for(; dev_num < TSUKA_NUM_INPUT_DEV; dev_num++) + { + if ((carddev->tsuka_fops[dev_num] = kmalloc(sizeof(struct TSUKA_fops_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("%s\n", "allocation of struct TSUKA_pci_card_t failed"); + ret = -ENOMEM; + goto err_destroy_devs; + } + carddev->tsuka_fops[dev_num]->tsuka_dev_open = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_release = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_read = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_write = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_poll = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_ioctl = NULL; + if ((carddev->tsuka_dev[dev_num] = tsuka_input_dev_create(carddev->tsuka_fops[dev_num], + carddev->iobase, dev_num)) == NULL) + { + TSUKA_ERROUT("unable to setup input module\n"); + ret = -ENOMEM; + goto err_destroy_devs; + } + } + + /* init output devices */ + for(; dev_num < TSUKA_NUM_INPUT_DEV + TSUKA_NUM_OUTPUT_DEV; dev_num++) + { + if ((carddev->tsuka_fops[dev_num] = kmalloc(sizeof(struct TSUKA_fops_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("%s\n", "allocation of struct TSUKA_pci_card_t failed"); + ret = -ENOMEM; + goto err_destroy_devs; + } + carddev->tsuka_fops[dev_num]->tsuka_dev_open = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_release = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_read = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_write = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_poll = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_ioctl = NULL; + if ((carddev->tsuka_dev[dev_num] = tsuka_output_dev_create(carddev->tsuka_fops[dev_num], + carddev->iobase, dev_num)) == NULL) + { + TSUKA_ERROUT("unable to setup output module\n"); + ret = -ENOMEM; + goto err_destroy_devs; + } + } + + /* initiate tuska_timer_output */ + if ((carddev->tsuka_fops[dev_num] = kmalloc(sizeof(struct TSUKA_fops_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("%s\n", "allocation of struct TSUKA_pci_card_t failed"); + ret = -ENOMEM; + goto err_destroy_devs; + } + carddev->tsuka_fops[dev_num]->tsuka_dev_open = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_release = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_read = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_write = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_poll = NULL; + carddev->tsuka_fops[dev_num]->tsuka_dev_ioctl = NULL; + if ((carddev->tsuka_dev[dev_num] = tsuka_timer_output_dev_create(carddev->tsuka_fops[dev_num], + 0x0, dev_num)) == NULL) + { + TSUKA_ERROUT("unable to setup timer_output module\n"); + ret = -ENOMEM; + goto err_destroy_devs; + } + dev_num++; + + atomic_inc(&tsuka_pci_card_count); + + return(ret); + + /* error exit, cleanup things */ +err_destroy_devs: + dev_num = 0; + for(; dev_num < TSUKA_NUM_INPUT_DEV; dev_num++) + { + if (carddev->tsuka_dev[dev_num] != NULL) tsuka_input_dev_destroy(carddev->tsuka_dev[dev_num]); + if (carddev->tsuka_fops[dev_num] != NULL) kfree(carddev->tsuka_fops[dev_num]); + } + for(; dev_num < TSUKA_NUM_INPUT_DEV + TSUKA_NUM_OUTPUT_DEV; dev_num++) + { + if (carddev->tsuka_dev[dev_num] != NULL) tsuka_output_dev_destroy(carddev->tsuka_dev[dev_num]); + if (carddev->tsuka_fops[dev_num] != NULL) kfree(carddev->tsuka_fops[dev_num]); + } + +err_iounmap: + iounmap(carddev->iobase); + TSUKA_LOGOUT(2, "%s\n", "memory IO region unmaped"); +err_release_mem_region: + release_mem_region((unsigned long)carddev->iobase, carddev->iolen); + TSUKA_LOGOUT(2, "%s\n", "memory IO region released"); +err_disable_device: + pci_disable_device(pdev); + TSUKA_LOGOUT(2, "%s\n", "PCI device disabled"); +err_free_carddev: + kfree(carddev); + TSUKA_LOGOUT(2, "%s\n", "carddev freed"); + + return(ret); +} + +/* remove PCI device, this function is called from pci_unregister_driver() */ +static void __devexit tsuka_remove_pci(struct pci_dev *pdev) +{ + struct TSUKA_pci_card_t* carddev; + int dev_num; + + TSUKA_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* get our private data */ + carddev = (struct TSUKA_pci_card_t*)pci_get_drvdata(pdev); + + /* clean up everything, order is important */ + dev_num = 0; + for(; dev_num < TSUKA_NUM_INPUT_DEV; dev_num++) + { + if (carddev->tsuka_dev[dev_num] != NULL) tsuka_input_dev_destroy(carddev->tsuka_dev[dev_num]); + if (carddev->tsuka_fops[dev_num] != NULL) kfree(carddev->tsuka_fops[dev_num]); + } + for(; dev_num < TSUKA_NUM_INPUT_DEV + TSUKA_NUM_OUTPUT_DEV; dev_num++) + { + if (carddev->tsuka_dev[dev_num] != NULL) tsuka_output_dev_destroy(carddev->tsuka_dev[dev_num]); + if (carddev->tsuka_fops[dev_num] != NULL) kfree(carddev->tsuka_fops[dev_num]); + } + + /* release memory IO region */ + release_mem_region((unsigned long)carddev->iobase, carddev->iolen); + TSUKA_LOGOUT(2, "%s\n", "memory IO region released"); + /* unmap memory IO */ + iounmap(carddev->iobase); + TSUKA_LOGOUT(2, "%s\n", "memory IO region unmaped"); + /* disable PCI device */ + pci_disable_device(pdev); + TSUKA_LOGOUT(2, "%s\n", "PCI device disabled"); + + kfree(carddev); + TSUKA_LOGOUT(2, "%s\n", "TSUKA_pci_card_t freed"); + + atomic_dec(&tsuka_pci_card_count); +} + +/* check if FPGA has a valid ID */ +static int tsuka_check_fpga(struct TSUKA_pci_card_t* carddev) +{ + u32 fpga_reg; + int ret = 0; + + TSUKA_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + fpga_reg = tsuka_fpga_read(carddev, TSUKA_REG_HW_ID); + if(SUPPORTED_FPGA_HW_ID_MIN > fpga_reg || + SUPPORTED_FPGA_HW_ID_MAX < fpga_reg) + { + TSUKA_ERROUT("dev: unsupported FPGA HW_ID. should: %u < HW_ID < %u, is: %u\n", + (u32)SUPPORTED_FPGA_HW_ID_MIN, (u32)SUPPORTED_FPGA_HW_ID_MAX, fpga_reg ); + ret = -ENODEV; + } + + fpga_reg = tsuka_fpga_read(carddev, TSUKA_REG_FW_ID); + if(SUPPORTED_FPGA_FW_ID_MIN > fpga_reg || + SUPPORTED_FPGA_FW_ID_MAX < fpga_reg) + { + TSUKA_ERROUT("dev: unsupported FPGA FW_ID. should: %u < FW_ID < %u, is: %u\n", + (u32)SUPPORTED_FPGA_FW_ID_MIN, (u32)SUPPORTED_FPGA_FW_ID_MAX, fpga_reg ); +// ret = -ENODEV; + } + else + { + TSUKA_INFOOUT(" FPGA FW-Version: %u\n", fpga_reg); + } + + return(ret); +} + +/* register the device file in the kernel */ +static int tsuka_dev_register(void) +{ + int ret; + + TSUKA_IO_LOGOUT(3, "dev: %s()\n", __FUNCTION__); + + /* register the device file */ + if ((ret = register_chrdev(TSUKA_DEV_MAJOR, DRV_NAME, &tsuka_dev_fops)) < 0) + { + TSUKA_ERROUT("dev: error registering devicefile(s) /dev/%sx", TSUKA_DEV_FILENAME); + return(ret); + } + + /* if we are here, we were successfull */ + TSUKA_IO_LOGOUT(3, "tsuka_dev: register_chrdev value %i, Major %i, dev %s\n", ret, TSUKA_DEV_MAJOR, DRV_NAME); + TSUKA_IO_LOGOUT(3, "tsuka_dev: device file(s) /dev/%sx registered\n", TSUKA_DEV_FILENAME); + return(0); +} + +/* unregister the device file in the kernel */ +static void tsuka_dev_unregister(void) +{ + int ret; + + /* unregister the device file */ + if ((ret = unregister_chrdev(TSUKA_DEV_MAJOR, DRV_NAME)) < 0) + { + TSUKA_ERROUT("tsuka_dev: error unregistering devicefile(s) /dev/%s%s\n", TSUKA_DEV_FILENAME, "x"); + return; + } + + /* if we are here, we were successfull */ + TSUKA_IO_LOGOUT(2, "tsuka_iodev: device file(s) /dev/%sx unregistered\n", TSUKA_DEV_FILENAME); +} + + +/* called by the kernel if device file is opened */ +static int tsuka_dev_open(struct inode* inode, struct file* filp) +{ + struct TSUKA_pci_card_t* pci_dev = NULL; + struct TSUKA_dev_t* tsuka_dev = NULL; + int minor = MINOR(inode->i_rdev); + + TSUKA_LOGOUT(3, "dev: entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + + tsuka_dev = pci_dev->tsuka_dev[minor]; + TSUKA_LOGOUT(3, "tsuka_dev: 0x%p\n", tsuka_dev); + /* set the private_data pointer to the minor number data */ + if(tsuka_dev != NULL) + { + filp->private_data = tsuka_dev; + } + else{ + TSUKA_ERROUT("dev: error while registering private datas of minor %d\n", minor); + return(-EINVAL); + } + + /* increment the kernel module use counter */ + MOD_INC_USE_COUNT; + + TSUKA_LOGOUT(3, "dev: device file /dev/%s%d opened\n", TSUKA_DEV_FILENAME, minor); + + /* if we are here, we were successfull */ + if(pci_dev->tsuka_fops[minor]->tsuka_dev_open == NULL) + return 0; + return(pci_dev->tsuka_fops[minor]->tsuka_dev_open(tsuka_dev, inode, filp)); +} + +/* called by the kernel if device file is closed */ +static int tsuka_dev_release(struct inode* inode, struct file* filp) +{ + struct TSUKA_pci_card_t* pci_dev = NULL; + int minor = MINOR(inode->i_rdev); + + TSUKA_LOGOUT(3, "dev: entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + + /* decrement the kernel module use counter */ + MOD_DEC_USE_COUNT; + + TSUKA_LOGOUT(3, "dev: device file /dev/%s%d closed\n", TSUKA_DEV_FILENAME, minor); + + /* if we are here, we were successfull */ + if(pci_dev->tsuka_fops[minor]->tsuka_dev_release == NULL) + return 0; + return(pci_dev->tsuka_fops[minor]->tsuka_dev_release(inode, filp)); +} + +/* called by the kernel if device file is read */ +static ssize_t tsuka_dev_read(struct file* filp, char* buf, size_t count, loff_t* offset) +{ + struct TSUKA_pci_card_t* pci_dev; + struct TSUKA_dev_t* tsuka_dev = filp->private_data; + unsigned char minor = tsuka_dev->minor; + + TSUKA_LOGOUT(3, "dev: entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + pci_dev = NULL; + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + + if(pci_dev->tsuka_fops[minor]->tsuka_dev_read == NULL){ + TSUKA_LOGOUT(3, "dev: no read function registered for minor %d\n", minor); + return -EINVAL; + } + return(pci_dev->tsuka_fops[minor]->tsuka_dev_read(filp, buf, count, offset)); +} + +/* called by the kernel if device file is written */ +static ssize_t tsuka_dev_write(struct file* filp, const char* buf, size_t count, loff_t* offset) +{ + struct TSUKA_pci_card_t* pci_dev; + struct TSUKA_dev_t* tsuka_dev = filp->private_data; + unsigned char minor = tsuka_dev->minor; + + TSUKA_LOGOUT(3, "dev: tsuka_main entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + pci_dev = NULL; + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + if(pci_dev->tsuka_fops[minor]->tsuka_dev_write == NULL){ + TSUKA_LOGOUT(3, "dev: no write function registered for minor %d\n", minor); + return -EINVAL; + } + return(pci_dev->tsuka_fops[minor]->tsuka_dev_write(filp, buf, count, offset)); +} + +/* called by the kernel if ioctl on device file */ +static int tsuka_dev_ioctl(struct inode* inode , struct file* filp, + unsigned int cmd, unsigned long arg) +{ + struct TSUKA_pci_card_t* pci_dev; + struct TSUKA_dev_t* tsuka_dev = filp->private_data; + unsigned char minor = tsuka_dev->minor; + Tsuka_Hw_Info hw_info; + int ret = 0; + + TSUKA_LOGOUT(3, "dev: entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + pci_dev = NULL; + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + + /* extract the type bitfield, and don't decode + * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */ + if (_IOC_TYPE(cmd) != TSUKA_DEV_IOCTL_MAGIC) + { + TSUKA_ERROUT("invalid ioctl command %u\n", cmd); + return -ENOTTY; + } + + /* check parameters and pointers */ + if (_IOC_DIR(cmd) & _IOC_READ) + { + /* check if legal address for write to user space */ + ret = access_ok(VERIFY_WRITE, (void*)arg, _IOC_SIZE(cmd)); + } + else if (_IOC_DIR(cmd) & _IOC_WRITE) + { + /* check if legal address for read from user space */ + ret = access_ok(VERIFY_READ, (void*)arg, _IOC_SIZE(cmd)); + } + if (ret == 0) + { + TSUKA_ERROUT("indev: %s%d: received bad argument pointer %ph\n", + TSUKA_DEV_FILENAME, tsuka_dev->minor, (void*)arg); + return -EFAULT; + } + + switch(cmd) + { + case TSUKA_IOCTL_GET_HW_INFO: + /* get info from FPGA and copy it to userspace */ + hw_info.hw_id = read_fpga_hw_id(); + hw_info.fw_id = read_fpga_fw_id(); + if (copy_to_user((Tsuka_Hw_Info*)arg, &hw_info, sizeof(Tsuka_Hw_Info)) != 0) + { + ret = -EINVAL; + } + break; + /* call ioctl function of an other object */ + default: + if(pci_dev->tsuka_fops[minor]->tsuka_dev_ioctl == NULL) + return -EINVAL; + return(pci_dev->tsuka_fops[minor]->tsuka_dev_ioctl(inode, filp, cmd, arg)); + }; + return ret; +} + +static unsigned int tsuka_dev_poll(struct file * filp, struct poll_table_struct *waitp){ + + struct TSUKA_pci_card_t* pci_dev; + struct TSUKA_dev_t* tsuka_dev = filp->private_data; + unsigned char minor = tsuka_dev->minor; + + TSUKA_LOGOUT(3, "dev: entering %s() for minor number %d\n", + __FUNCTION__, minor); + + /* check if minor number is valid */ + pci_dev = NULL; + if(minor < TSUKA_NUM_DEVICES) + { + pci_dev = tsuka_pci_device; + } + else + { + TSUKA_ERROUT("dev: minor number %d has no registered device file\n", minor); + return(-EINVAL); + } + if(pci_dev->tsuka_fops[minor]->tsuka_dev_poll == NULL) + return -EINVAL; + return(pci_dev->tsuka_fops[minor]->tsuka_dev_poll(filp, waitp)); +} + +static int tsuka_dev_read_procmem(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + int board=0; + + TSUKA_LOGOUT(3, "dev: entering %s()\n", __FUNCTION__); + + len += sprintf(buf+len, "%s\n", TSUKA_CARD_NAME); + len += sprintf(buf+len, "%s\n", VERSION); + len += sprintf(buf+len, "Devices: %d\n", TSUKA_NUM_DEVICES); + len += sprintf(buf+len, "FPGAs: %d\n", atomic_read(&tsuka_pci_card_count)); + for(board = 0; board < atomic_read(&tsuka_pci_card_count); board++){ + len += sprintf(buf+len, " FPGA %u: HW ID %u\n", board+1, read_fpga_hw_id()); + len += sprintf(buf+len, " FPGA %u: FW ID %u\n", board+1, read_fpga_fw_id()); + } + *eof = 1; + return( len ); +} diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_main.h linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_main.h --- linuxppc_2_4_devel/drivers/tsuka/tsuka_main.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_main.h 2007-02-01 09:02:20.000000000 +0100 @@ -0,0 +1,83 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Supports the functions provided by the ZHW Tsuka +* FPGA: Inputs, Outputs +* This is the central class of the driver. In this +* some object oriented structures are setup and the +* PCI interface is configured. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +#ifndef TSUKAMAIN_H +#define TSUKAMAIN_H + +#ifndef LINUX_VERSION_CODE + #include +#endif + +/* + * Name string constants +*/ +#define DRV_NAME "tsuka" +#define DRV_VERSION "0.1" +#define DRV_RELDATE "08/15/2006" +#define VERSION "Version " DRV_VERSION " date " DRV_RELDATE +#define TSUKA_CARD_NAME "ZHW/InES TSUKA driver" +#define SUPPORTED_FPGA_HW_ID_MIN 2 +#define SUPPORTED_FPGA_HW_ID_MAX 2 +#define SUPPORTED_FPGA_FW_ID_MIN 1 +#define SUPPORTED_FPGA_FW_ID_MAX 1000 + + +/* FPGA register offsets */ +#define FPGA_REG_GLOBAL_OFFSET 0 /* register address offset io registers relative to fpga base address */ +#define TSUKA_REG_HW_ID 0 +#define TSUKA_REG_FW_ID 1 +#define TSUKA_REG_IRQ_PENDING 2 + + +/* Attention: all TSUKA_xyz_dev_t must have this values in the same order!!! + * The struct are used as pointer arrays. This is the basic type, all parameters + * are mandatory */ +struct TSUKA_dev_t +{ + /* device specific parameters */ + int minor; /* minor number for this device file */ + u32* fpga_base_addr; /* base address of io registers */ +}; + + +struct TSUKA_fops_t +{ + /* device specific fops */ + int (*tsuka_dev_open)(struct TSUKA_dev_t* thisptr, struct inode * inode, struct file * filp); + int (*tsuka_dev_release)(struct inode * inode, struct file * filp); + ssize_t (*tsuka_dev_read)(struct file *filp, char *buffer, size_t count, loff_t *offset); + ssize_t (*tsuka_dev_write)(struct file * filp, const char * buffer, + size_t count,loff_t *offset); + unsigned int (*tsuka_dev_poll)(struct file * filp, struct poll_table_struct *waitp); + int (*tsuka_dev_ioctl)(struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg); +}; + + +#endif /* TSUKAMAIN_H */ + diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_output.c linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_output.c --- linuxppc_2_4_devel/drivers/tsuka/tsuka_output.c 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_output.c 2006-12-21 16:24:52.000000000 +0100 @@ -0,0 +1,231 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Output class. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +/* include this in all files but the module main file */ +#define __NO_VERSION__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tsuka_output.h" +#include "tsuka_devfile.h" +#include "logfunctions.h" +#include "tsuka_main.h" + + +/***************************************************************************** + * private functions prototypes + *****************************************************************************/ + + +/***************************************************************************** + * private variables + *****************************************************************************/ + +/* one spinlock per fpga output region */ +static spinlock_t output_reg_lock = SPIN_LOCK_UNLOCKED; + +/***************************************************************************** + * private functions implementations + *****************************************************************************/ + +/* write a fpga register */ +static inline void tsuka_output_fpga_write(struct TSUKA_output_dev_t* outdev, u16 reg, u32 data) +{ + u32 *wr_ptr = outdev->fpga_base_addr + (reg >> 2); + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() val %u @ %p for minor number %d\n", + __FUNCTION__, data, wr_ptr, outdev->minor); + + writel(data, wr_ptr); + + return; +} + +/* read a fpga register */ +static inline u32 tsuka_output_fpga_read(struct TSUKA_output_dev_t* outdev, u16 reg) +{ + u32 *rd_ptr = outdev->fpga_base_addr + (reg >> 2); + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() @ %p for minor number %d\n", + __FUNCTION__, rd_ptr, outdev->minor); + + return (u32)readl(outdev->fpga_base_addr + reg); +} + + +/* called by the kernel if device file is opened */ +static int tsuka_output_dev_open(struct TSUKA_dev_t* thisptr, struct inode* inode, struct file* filp) +{ + struct TSUKA_output_dev_t* outdev = (struct TSUKA_output_dev_t*)thisptr; + u32 saved_register; + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + /* init fpga register to 0 */ + spin_lock(outdev->lock); + saved_register = tsuka_output_fpga_read(outdev, TSUKA_REG_OUT); + barrier(); + saved_register &= ~outdev->bitmask; + barrier(); + tsuka_output_fpga_write(outdev, TSUKA_REG_OUT, saved_register); + spin_unlock(outdev->lock); + + TSUKA_IO_LOGOUT(3, "outdev: device file /dev/%s%d opened\n", TSUKA_DEV_FILENAME, outdev->minor); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is closed */ +static int tsuka_output_dev_release(struct inode * inode, struct file * filp) +{ + struct TSUKA_output_dev_t* outdev = (struct TSUKA_output_dev_t*)filp->private_data; + + TSUKA_IO_LOGOUT(3, "outdev: /dev/%s%d: device file closed\n", TSUKA_DEV_FILENAME, outdev->minor); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is read */ +static ssize_t tsuka_output_dev_read(struct file* filp, char* buf, size_t count, loff_t* offset) +{ + struct TSUKA_output_dev_t* outdev = (struct TSUKA_output_dev_t*)filp->private_data; + u32 value; + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + value = tsuka_output_fpga_read(outdev, TSUKA_REG_OUT); + value = value & outdev->bitmask; + /* copy value to userspace */ + if (copy_to_user(buf, &value, sizeof(u32)) != 0) + { + return(-EINVAL); + } + /* return number of bytes copied */ + return(count); +} + +/* called by the kernel if device file is written */ +static ssize_t tsuka_output_dev_write(struct file* filp, const char* buf, size_t count, loff_t* offset){ + + struct TSUKA_output_dev_t* outdev = filp->private_data; + u32 value, saved_register; + + TSUKA_IO_LOGOUT(3, "outdev: entering tsuka_output %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + if(count != sizeof(u32)) + return(-EINVAL); + if(copy_from_user(&value, buf, count)) + return(-EFAULT); + + spin_lock(outdev->lock); + saved_register = tsuka_output_fpga_read(outdev, TSUKA_REG_OUT); + barrier(); + saved_register &= ~outdev->bitmask; + saved_register |= (value & outdev->bitmask); + barrier(); + tsuka_output_fpga_write(outdev, TSUKA_REG_OUT, saved_register); + spin_unlock(outdev->lock); + + return(count); +} + +/* called by the kernel if ioctl on device file */ +static int tsuka_output_dev_ioctl(struct inode* inode , struct file* filp, + unsigned int cmd, unsigned long arg) +{ + struct TSUKA_output_dev_t* outdev = (struct TSUKA_output_dev_t*)filp->private_data; + int ret = 0; + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + return(ret); +} + + +/***************************************************************************** + * public interface functions implementations + *****************************************************************************/ + +/* return a pointer to kmalloced struct TSUKA_output_dev_t if successfull, NULL if failed */ +struct TSUKA_dev_t* __devinit tsuka_output_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor) +{ + struct TSUKA_output_dev_t* outdev; + + TSUKA_IO_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* allocate a struct, fill it and give it back */ + if ((outdev = kmalloc(sizeof(struct TSUKA_output_dev_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("allocation of struct TSUKA_output_dev_t failed\n"); + return(NULL); + } + TSUKA_IO_LOGOUT(2, "%s\n", "struct TSUKA_output_dev_t allocated"); + + /* initialize struct */ + memset(outdev, 0, sizeof(*outdev)); + + /* init private variables */ + outdev->fpga_base_addr = fpga_base_addr + (TSUKA_REGION_OUTPUT_DEV >> 2); + outdev->bitmask = output_bitmask[TSUKA_MINOR_GET_OUTPUT_DEV_NUM(minor)]; + outdev->minor = minor; + outdev->lock = &output_reg_lock; + + tsuka_fops->tsuka_dev_open = tsuka_output_dev_open; + tsuka_fops->tsuka_dev_release = tsuka_output_dev_release; + tsuka_fops->tsuka_dev_read = tsuka_output_dev_read; + tsuka_fops->tsuka_dev_write = tsuka_output_dev_write; + tsuka_fops->tsuka_dev_ioctl = tsuka_output_dev_ioctl; + + TSUKA_IO_LOGOUT(2, "outdev: created, registers @ %p\n", outdev->fpga_base_addr); + + /* if we are here, we were successfull */ + return((struct TSUKA_dev_t*)outdev); +} + +/* stop and free all resources, the outdev pointer is not valid anymore + * after a call to this function! */ +void __devexit tsuka_output_dev_destroy(struct TSUKA_dev_t* tsuka_dev) +{ + struct TSUKA_output_dev_t* outdev = (struct TSUKA_output_dev_t*)tsuka_dev; + TSUKA_IO_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* free the structure */ + kfree(outdev); + TSUKA_IO_LOGOUT(2, "FPGA: struct TSUKA_output_dev_t freed"); + +} diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_output.h linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_output.h --- linuxppc_2_4_devel/drivers/tsuka/tsuka_output.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_output.h 2006-12-19 07:23:54.000000000 +0100 @@ -0,0 +1,69 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Output class. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + + +#ifndef TSUKA_OUTPUT_H +#define TSUKA_OUTPUT_H + + +#define TSUKA_REGION_OUTPUT_DEV 0x60 /* first register of output modul offset (address/4) */ + + +/* FPGA registers offsets */ +#define TSUKA_REG_OUT 0x0 + +// #define SIZEOF_OUTPUT_REGS 1 /* number of 32bit representing an output region */ + + +struct TSUKA_fops_t; + +/* Attention: all TSUKA_xyz_dev_t must contain some values in a given order!!! + * The struct are used as pointer arrays. In tsuka_main.c is the basic type + * containing only the mandatory parameter. Copy and past this to setup a new class.*/ +struct TSUKA_output_dev_t +{ + /* device specific parameters */ + int minor; /* minor number for this device file */ + u32* fpga_base_addr; /* base address of output registers */ + u32 bitmask; /* which bits are handled by this object? */ + spinlock_t *lock; /* lock the fpga region */ +}; + +/***************************************************************************** + * public interface function prototypes + *****************************************************************************/ + +/* return a pointer to kmalloced TSUKA_input_dev_t if successfull, NULL if failed */ +struct TSUKA_input_dev_t* __devinit tsuka_devfile_create(unsigned int* fpga_base_addr); +/* free all resources, the iodev pointer is not valid anymore + * after a call to this function! */ +void __devexit tsuka_devfile_destroy(struct TSUKA_input_dev_t* iodev); + +/* setup TSUKA_output_dev_t internal struct and return a ponter to the new object */ +struct TSUKA_dev_t* __devinit tsuka_output_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor); +/* tidy up what tsuka_output_dev_create initialised */ +void __devexit tsuka_output_dev_destroy(struct TSUKA_dev_t* tsuka_dev); + +#endif /* TSUKA_OUTPUT_H */ diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_timer_output.c linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_timer_output.c --- linuxppc_2_4_devel/drivers/tsuka/tsuka_timer_output.c 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_timer_output.c 2007-02-01 14:57:44.000000000 +0100 @@ -0,0 +1,206 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Output class. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + +/* include this in all files but the module main file */ +#define __NO_VERSION__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tsuka_timer_output.h" +#include "tsuka_devfile.h" +#include "logfunctions.h" +#include "tsuka_main.h" + +/* TIMERS 6 */ +#define GET_IO_1 (gpt->gpt6.sr & 0x00000100UL) >> 8 +#define SET_IO_1 gpt->gpt6.emsr |= (1 << 4) +#define CLEAR_IO_1 gpt->gpt6.emsr &= ~(1 << 4); + +/* TIMERS 7 */ +#define GET_IO_2 (gpt->gpt7.sr & 0x00000100UL) >> 8 +#define SET_IO_2 gpt->gpt7.emsr |= (1 << 4) +#define CLEAR_IO_2 gpt->gpt7.emsr &= ~(1 << 4); + + +static volatile struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5xxx_GPT; + + + +void init_timer_ios(void){ + TSUKA_IO_LOGOUT(3, "timer_outdev: entering %s()\n", __FUNCTION__); + /* TIMERS_6 --> input (I/O) */ + gpt->gpt6.emsr |= 0x00000024UL; + /* TIMERS_7 --> input (I/O) */ + gpt->gpt7.emsr |= 0x00000024UL; +} + +/***************************************************************************** + * private functions prototypes + *****************************************************************************/ + + +/***************************************************************************** + * private variables + *****************************************************************************/ + + +/***************************************************************************** + * private functions implementations + *****************************************************************************/ + + + +/* called by the kernel if device file is opened */ +static int tsuka_timer_output_dev_open(struct TSUKA_dev_t* thisptr, struct inode* inode, struct file* filp) +{ + struct TSUKA_timer_output_dev_t* outdev = (struct TSUKA_timer_output_dev_t*)thisptr; + + TSUKA_IO_LOGOUT(3, "timer_outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + TSUKA_IO_LOGOUT(3, "timer_outdev: device file /dev/%s%d opened\n", TSUKA_DEV_FILENAME, outdev->minor); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is closed */ +static int tsuka_timer_output_dev_release(struct inode * inode, struct file * filp) +{ + struct TSUKA_timer_output_dev_t* outdev = (struct TSUKA_timer_output_dev_t*)filp->private_data; + + TSUKA_IO_LOGOUT(3, "timer_outdev: /dev/%s%d: device file closed\n", TSUKA_DEV_FILENAME, outdev->minor); + + /* if we are here, we were successfull */ + return(0); +} + +/* called by the kernel if device file is read */ +static ssize_t tsuka_timer_output_dev_read(struct file* filp, char* buf, size_t count, loff_t* offset) +{ + struct TSUKA_timer_output_dev_t* outdev = (struct TSUKA_timer_output_dev_t*)filp->private_data; + + TSUKA_IO_LOGOUT(3, "outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + return(0); +} + +/* called by the kernel if device file is written */ +static ssize_t tsuka_timer_output_dev_write(struct file* filp, const char* buf, size_t count, loff_t* offset){ + + struct TSUKA_timer_output_dev_t* outdev = filp->private_data; + u32 value; + + TSUKA_IO_LOGOUT(3, "timer_outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + if(count != sizeof(u32)) + return(-EINVAL); + if(copy_from_user(&value, buf, count)) + return(-EFAULT); + + TSUKA_IO_LOGOUT(3, "timer_outdev: write value: 0x%x\n", value); + + if(value & 0x1) SET_IO_1; else CLEAR_IO_1; + if(value & 0x2) SET_IO_2; else CLEAR_IO_2; + + return(count); +} + +/* called by the kernel if ioctl on device file */ +static int tsuka_timer_output_dev_ioctl(struct inode* inode , struct file* filp, + unsigned int cmd, unsigned long arg) +{ + struct TSUKA_timer_output_dev_t* outdev = (struct TSUKA_timer_output_dev_t*)filp->private_data; + int ret = 0; + + TSUKA_IO_LOGOUT(3, "timer_outdev: entering %s() for minor number %d\n", + __FUNCTION__, outdev->minor); + + return(ret); +} + + +/***************************************************************************** + * public interface functions implementations + *****************************************************************************/ + +/* return a pointer to kmalloced struct TSUKA_output_dev_t if successfull, NULL if failed */ +struct TSUKA_dev_t* __devinit tsuka_timer_output_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor) +{ + struct TSUKA_timer_output_dev_t* outdev; + + TSUKA_IO_LOGOUT(3, "entering %s(), minor: %u\n", __FUNCTION__, minor); + + init_timer_ios(); + + /* allocate a struct, fill it and give it back */ + if ((outdev = kmalloc(sizeof(struct TSUKA_timer_output_dev_t), GFP_KERNEL)) == NULL) + { + TSUKA_ERROUT("allocation of struct TSUKA_timer_output_dev_t failed\n"); + return(NULL); + } + TSUKA_IO_LOGOUT(2, "struct TSUKA_timer_output_dev_t allocated (0x%p)\n", outdev); + + /* initialize struct */ + memset(outdev, 0, sizeof(*outdev)); + + /* init private variables */ + outdev->fpga_base_addr = (u32*)MPC5xxx_GPT; + outdev->minor = minor; + + tsuka_fops->tsuka_dev_open = tsuka_timer_output_dev_open; + tsuka_fops->tsuka_dev_release = tsuka_timer_output_dev_release; + tsuka_fops->tsuka_dev_read = tsuka_timer_output_dev_read; + tsuka_fops->tsuka_dev_write = tsuka_timer_output_dev_write; + tsuka_fops->tsuka_dev_ioctl = tsuka_timer_output_dev_ioctl; + + TSUKA_IO_LOGOUT(2, "timer_outdev: created, registers @ 0x%u\n", outdev->fpga_base_addr); + + /* if we are here, we were successfull */ + return((struct TSUKA_dev_t*)outdev); +} + +/* stop and free all resources, the outdev pointer is not valid anymore + * after a call to this function! */ +void __devexit tsuka_timer_output_dev_destroy(struct TSUKA_dev_t* tsuka_dev) +{ + struct TSUKA_timer_output_dev_t* outdev = (struct TSUKA_timer_output_dev_t*)tsuka_dev; + TSUKA_IO_LOGOUT(3, "entering %s()\n", __FUNCTION__); + + /* free the structure */ + kfree(outdev); + TSUKA_IO_LOGOUT(2, "FPGA: struct TSUKA_timer_output_dev_t freed"); + +} diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/tsuka/tsuka_timer_output.h linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_timer_output.h --- linuxppc_2_4_devel/drivers/tsuka/tsuka_timer_output.h 1970-01-01 01:00:00.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/tsuka/tsuka_timer_output.h 2007-01-30 14:20:11.000000000 +0100 @@ -0,0 +1,67 @@ +/* ************************************************************ * +* _____ ______ _____ * +* |_ _| | ____|/ ____| * +* | | _ __ | |__ | (___ Institute of Embedded Systems * +* | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur * +* _| |_| | | | |____ ____) | (University of Applied Sciences) * +* |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland * +***************************************************************** +* +* Project : Tsuka +* Description : Output class. +* Credits: : basic driver framework is based on Jörg Blattners +* IEEE1588 driver +* +* $LastChangedDate: 2006-12-18 14:10:40 +0100 (Mon, 18 Dec 2006) $ +* $Rev: 127 $ +* $Author: fra $ +*--------------------------------------------------------------- +* +* Change History +* Date |Name |Modification +*----------|----------|----------------------------------------- +* 25.08.06 | fra |file ceated +*---------------------------------------------------------------*/ + + +#ifndef TSUKA_OUTPUT_H +#define TSUKA_OUTPUT_H + + +#define TSUKA_REGION_OUTPUT_DEV 0x120 /* first register of output modul offset (address/4) */ + + +/* FPGA registers offsets */ +#define TSUKA_REG_OUT 0x0 + +// #define SIZEOF_OUTPUT_REGS 1 /* number of 32bit representing an output region */ + + +struct TSUKA_fops_t; + +/* Attention: all TSUKA_xyz_dev_t must contain some values in a given order!!! + * The struct are used as pointer arrays. In tsuka_main.c is the basic type + * containing only the mandatory parameter. Copy and past this to setup a new class.*/ +struct TSUKA_timer_output_dev_t +{ + /* device specific parameters */ + int minor; /* minor number for this device file */ + u32* fpga_base_addr; /* base address of output registers */ +}; + +/***************************************************************************** + * public interface function prototypes + *****************************************************************************/ + +// /* return a pointer to kmalloced TSUKA_timer_output_dev_t if successfull, NULL if failed */ +// struct TSUKA_timer_output_dev_t* __devinit tsuka_devfile_create(unsigned int* fpga_base_addr); +// /* free all resources, the iodev pointer is not valid anymore +// * after a call to this function! */ +// void __devexit tsuka_devfile_destroy(struct TSUKA_timer_output_dev_t* iodev); + +/* setup TSUKA_output_dev_t internal struct and return a pointer to the new object */ +struct TSUKA_dev_t* __devinit tsuka_timer_output_dev_create(struct TSUKA_fops_t* tsuka_fops, unsigned int* fpga_base_addr, unsigned char minor); +/* tidy up what tsuka_output_dev_create initialised */ +void __devexit tsuka_timer_output_dev_destroy(struct TSUKA_dev_t* tsuka_dev); + +#endif /* TSUKA_OUTPUT_H */ diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/Config.in linuxppc_2_4_devel.modified/drivers/usb/gadget/Config.in --- linuxppc_2_4_devel/drivers/usb/gadget/Config.in 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/Config.in 2006-05-15 15:20:37.000000000 +0200 @@ -10,15 +10,15 @@ tristate 'Support for USB Gadgets' CONFIG_USB_GADGET if [ "$CONFIG_USB_GADGET" = "y" -o "$CONFIG_USB_GADGET" = "m" ]; then - + # # really want _exactly one_ device controller driver at a time, # since they control compile options for gadget drivers. # choice 'USB Peripheral Controller Driver' "\ NetChip-2280 CONFIG_USB_GADGET_NET2280 \ + NetChip-2282 CONFIG_USB_GADGET_NET2282 \ Toshiba-TC86C001(Goku-S) CONFIG_USB_GADGET_GOKU \ - Philips-ISP1362 CONFIG_USB_GADGET_ISP1362 \ " NetChip-2280 define_tristate CONFIG_USB_GADGET_CONTROLLER n @@ -27,14 +27,18 @@ define_tristate CONFIG_USB_NET2280 $CONFIG_USB_GADGET define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_NET2280 fi + if [ "$CONFIG_PCI" = "y" -a "$CONFIG_USB_GADGET_NET2282" = "y" ] ; then + define_tristate CONFIG_USB_NET2280 $CONFIG_USB_GADGET + define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_NET2280 + fi if [ "$CONFIG_PCI" = "y" -a "$CONFIG_USB_GADGET_GOKU" = "y" ] ; then define_tristate CONFIG_USB_GOKU $CONFIG_USB_GADGET define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_GOKU fi - if [ "$CONFIG_USB_GADGET_ISP1362" = "y" ] ; then - define_tristate CONFIG_USB_ISP1362_GAPI $CONFIG_USB_GADGET - define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_ISP1362_GAPI - fi + + # or any other controller that supports high speed transfers ... + define_bool CONFIG_USB_GADGET_DUALSPEED $CONFIG_USB_GADGET_NET2280 + define_bool CONFIG_USB_GADGET_DUALSPEED $CONFIG_USB_GADGET_NET2282 if [ "$CONFIG_USB_GADGET_CONTROLLER" = "y" -o "$CONFIG_USB_GADGET_CONTROLLER" = "m" ] ; then @@ -54,13 +58,13 @@ comment 'USB Gadget Drivers' dep_tristate ' Gadget Zero (DEVELOPMENT)' CONFIG_USB_ZERO $CONFIG_USB_GADGET_CONTROLLER - dep_tristate ' Ethernet Gadget (EXPERIMENTAL)' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET + dep_tristate ' Ethernet Gadget' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET if [ "$CONFIG_USB_ETH" = "y" -o "$CONFIG_USB_ETH" = "m" ] ; then dep_bool ' RNDIS support (EXPERIMENTAL)' CONFIG_USB_ETH_RNDIS $CONFIG_EXPERIMENTAL fi dep_tristate ' File-backed Storage Gadget (DEVELOPMENT)' CONFIG_USB_FILE_STORAGE $CONFIG_USB_GADGET_CONTROLLER dep_mbool ' File-backed Storage Gadget test mode' CONFIG_USB_FILE_STORAGE_TEST $CONFIG_USB_FILE_STORAGE - + # enforce the "only one statically linked gadget driver" rule diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/Makefile linuxppc_2_4_devel.modified/drivers/usb/gadget/Makefile --- linuxppc_2_4_devel/drivers/usb/gadget/Makefile 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/Makefile 2006-03-31 14:46:58.000000000 +0200 @@ -9,31 +9,27 @@ list-multi := g_zero.o g_ether.o g_file_storage.o obj-$(CONFIG_USB_NET2280) += net2280.o -obj-$(CONFIG_USB_ISP1362_GAPI) += isp1362gapi.o obj-$(CONFIG_USB_GOKU) += goku_udc.o # only one of these may be statically linked ... controller-$(CONFIG_USB_NET2280) += net2280.o -controller-$(CONFIG_USB_ISP1362_GAPI) += isp1362gapi.o controller-$(CONFIG_USB_GOKU) += goku_udc.o # ... and only one of these, too; kbuild/kconfig don't help though. -g_zero-objs := zero.o usbstring.o +g_zero-objs := zero.o usbstring.o config.o epautoconf.o obj-$(CONFIG_USB_ZERO) += g_zero.o -g_ether-objs := ether.o usbstring.o config.o epautoconf.o +g_ether-objs := ether.o usbstring.o config.o epautoconf.o ifeq ($(CONFIG_USB_ETH_RNDIS),y) - g_ether-objs += rndis.o -endif -ifeq ($(CONFIG_USB_ETH_RNDIS),m) - g_ether-objs += rndis.o + g_ether-objs += rndis.o endif obj-$(CONFIG_USB_ETH) += g_ether.o -g_file_storage-objs := file_storage.o usbstring.o +g_file_storage-objs := file_storage.o usbstring.o config.o \ + epautoconf.o obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o -export-objs := $(controller-y) $(controller-m) rndis.o +export-objs := $(controller-y) $(controller-m) include $(TOPDIR)/Rules.make diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/epautoconf.c linuxppc_2_4_devel.modified/drivers/usb/gadget/epautoconf.c --- linuxppc_2_4_devel/drivers/usb/gadget/epautoconf.c 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/epautoconf.c 2006-03-31 14:46:58.000000000 +0200 @@ -74,7 +74,7 @@ /* endpoint already claimed? */ if (0 != ep->driver_data) return 0; - + /* only support ep0 for portable CONTROL traffic */ type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; if (USB_ENDPOINT_XFER_CONTROL == type) @@ -277,7 +277,7 @@ return ep; } - /* Second, look at endpoints until an unclaimed one looks usable */ + /* Second, look at endpoints until an unclaimed one looks usable */ list_for_each_entry (ep, &gadget->ep_list, ep_list) { if (ep_matches (gadget, ep, desc)) return ep; diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/ether.c linuxppc_2_4_devel.modified/drivers/usb/gadget/ether.c --- linuxppc_2_4_devel/drivers/usb/gadget/ether.c 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/ether.c 2006-06-06 15:54:37.000000000 +0200 @@ -20,8 +20,8 @@ */ -// #define DEBUG 1 -// #define VERBOSE +#define DEBUG 1 +#define VERBOSE 1 #include #include @@ -40,6 +40,10 @@ #include #include #include +#ifdef CONFIG_MPC5200 +# include +# include +#endif #include #include @@ -104,19 +108,9 @@ #include #define work_struct tq_struct -#define flush_scheduled_work flush_scheduled_tasks - -#if 0 /* backport from 2.4.30er version to 2.4.25 */ #define INIT_WORK INIT_TQUEUE #define schedule_work schedule_task -#endif - -#if 1 /* backport from 2.4.30er version to 2.4.25 */ -static inline void *netdev_priv(struct net_device *dev) -{ - return dev->priv; -} -#endif +#define flush_scheduled_work flush_scheduled_tasks static void random_ether_addr (u8 *addr) { @@ -194,13 +188,8 @@ * used with CDC Ethernet, Linux 2.4 hosts will need updates to choose * the non-RNDIS configuration. */ -#ifndef CONFIG_NSCU #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ -#else -#define RNDIS_VENDOR_NUM 0x0681 /*@ Barman_4113 13.05.2004 Siemens VID */ -#define RNDIS_PRODUCT_NUM 0x0027 /*@ OZW775 Product ID */ -#endif /* Some systems will want different product identifers published in the @@ -247,6 +236,10 @@ #define DEV_CONFIG_CDC #endif +#ifdef CONFIG_USB_GADGET_NET2282 +#define DEV_CONFIG_CDC +#endif + #ifdef CONFIG_USB_GADGET_DUMMY_HCD #define DEV_CONFIG_CDC #endif @@ -292,10 +285,6 @@ #define DEV_CONFIG_SUBSET #endif -#ifdef CONFIG_USB_GADGET_ISP1362 -#undef DEV_CONFIG_CDC -#endif - /*-------------------------------------------------------------------------*/ @@ -435,7 +424,7 @@ }; #ifdef CONFIG_USB_ETH_RNDIS -static struct usb_config_descriptor +static struct usb_config_descriptor rndis_config = { .bLength = sizeof rndis_config, .bDescriptorType = USB_DT_CONFIG, @@ -480,7 +469,7 @@ rndis_control_intf = { .bLength = sizeof rndis_control_intf, .bDescriptorType = USB_DT_INTERFACE, - + .bInterfaceNumber = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_COMM, @@ -618,7 +607,7 @@ * RNDIS requires the status endpoint, since it uses that encapsulation * mechanism for its funky RPC scheme. */ - + #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ #define STATUS_BYTECOUNT 8 /* 8 byte header + data */ @@ -1045,7 +1034,7 @@ /* one endpoint writes data back IN to the host */ if (strcmp (ep->name, EP_IN_NAME) == 0) { d = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); - result = usb_ep_enable (ep, d); + result = usb_ep_enable (ep, d); if (result < 0) return result; @@ -1340,7 +1329,7 @@ struct usb_request *req; struct cdc_notification *event; int value; - + DEBUG (dev, "%s, flush old status first\n", __FUNCTION__); /* flush old status @@ -1437,7 +1426,7 @@ { struct eth_dev *dev = ep->driver_data; int status; - + /* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */ spin_lock(&dev->lock); status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); @@ -1632,7 +1621,7 @@ break; #endif /* DEV_CONFIG_CDC */ -#ifdef CONFIG_USB_ETH_RNDIS +#ifdef CONFIG_USB_ETH_RNDIS /* RNDIS uses the CDC command encapsulation mechanism to implement * an RPC scheme, with much getting/setting of attributes by OID. */ @@ -1649,7 +1638,7 @@ req->complete = rndis_command_complete; /* later, rndis_control_ack () sends a notification */ break; - + case CDC_GET_ENCAPSULATED_RESPONSE: if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE) == ctrl->bRequestType @@ -1796,7 +1785,7 @@ #ifdef CONFIG_USB_ETH_RNDIS if (dev->rndis) size += sizeof (struct rndis_packet_msg_type); -#endif +#endif size -= size % dev->out_ep->maxpacket; if ((skb = alloc_skb (size, gfp_flags)) == 0) { @@ -1876,7 +1865,7 @@ case -EOVERFLOW: dev->stats.rx_over_errors++; // FALLTHROUGH - + default: dev->stats.rx_errors++; DEBUG (dev, "rx status %d\n", status); @@ -2051,7 +2040,7 @@ sizeof (struct rndis_packet_msg_type)); if (!skb_rndis) goto drop; - + dev_kfree_skb_any (skb); skb = skb_rndis; rndis_add_hdr (skb); @@ -2112,7 +2101,7 @@ { if (!dev) return; - + if (connect) { if (rndis_signal_connect (dev->rndis_config)) return; @@ -2139,7 +2128,7 @@ struct eth_dev *dev = netdev_priv(net); u32 length; struct usb_request *resp; - + /* in case RNDIS calls this after disconnect */ if (!dev->status_ep) { DEBUG (dev, "status ENODEV\n"); @@ -2152,7 +2141,7 @@ DEBUG (dev, "status ENOMEM\n"); return -ENOMEM; } - + resp->buf = usb_ep_alloc_buffer (dev->status_ep, 8, &resp->dma, GFP_ATOMIC); if (!resp->buf) { @@ -2160,22 +2149,22 @@ usb_ep_free_request (dev->status_ep, resp); return -ENOMEM; } - + /* Send RNDIS RESPONSE_AVAILABLE notification; * CDC_NOTIFY_RESPONSE_AVAILABLE should work too */ resp->length = 8; resp->complete = rndis_control_ack_complete; - + *((u32 *) resp->buf) = __constant_cpu_to_le32 (1); *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0); - + length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC); if (length < 0) { resp->status = 0; rndis_control_ack_complete (dev->status_ep, resp); } - + return 0; } @@ -2188,7 +2177,7 @@ /* fill the rx queue */ rx_fill (dev, gfp_flags); - /* and open the tx floodgates */ + /* and open the tx floodgates */ atomic_set (&dev->tx_qlen, 0); netif_wake_queue (dev->net); #ifdef CONFIG_USB_ETH_RNDIS @@ -2198,7 +2187,7 @@ BITRATE(dev->gadget)); rndis_send_media_state (dev, 1); } -#endif +#endif } static int eth_open (struct net_device *net) @@ -2219,7 +2208,7 @@ netif_stop_queue (net); DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", - dev->stats.rx_packets, dev->stats.tx_packets, + dev->stats.rx_packets, dev->stats.tx_packets, dev->stats.rx_errors, dev->stats.tx_errors ); @@ -2238,7 +2227,7 @@ usb_ep_enable (dev->status_ep, dev->status); } } - + #ifdef CONFIG_USB_ETH_RNDIS if (dev->rndis) { rndis_set_param_medium (dev->rndis_config, @@ -2307,6 +2296,33 @@ if (is_valid_ether_addr (dev_addr)) return; } +#ifdef CONFIG_MPC5200 + u32 fec_addr1; + u16 fec_addr2; + u8 *fec_addr; + static u8 offset = 0; + + fec_addr1 = in_be32((volatile u32 *) (MPC5xxx_FEC + 0x0E4)); + fec_addr2 = in_be16((volatile u16 *) (MPC5xxx_FEC + 0x0E8)); + + fec_addr = (u8*)&fec_addr1; + offset ++; + fec_addr[1] += offset; + dev_addr[0] = fec_addr[0]; + dev_addr[1] = fec_addr[1]; + dev_addr[2] = fec_addr[2]; + dev_addr[3] = fec_addr[3]; + fec_addr = (u8*)&fec_addr2; + dev_addr[4] = fec_addr[0]; + dev_addr[5] = fec_addr[1]; + + dev_addr [0] &= 0xfe; // clear multicast bit + dev_addr [0] |= 0x02; // set local assignment bit (IEEE802) + + if (is_valid_ether_addr (dev_addr)) + return; +#endif + printk ("generating random MAC address\n"); random_ether_addr(dev_addr); } @@ -2364,8 +2380,6 @@ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); } else if (gadget_is_pxa27x(gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211); - } else if (gadget_is_isp1362(gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0001); } else { /* can't assume CDC works. don't want to default to * anything less functional on CDC-capable hardware, @@ -2405,6 +2419,7 @@ __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM); } + /* support optional vendor/distro customization */ if (idVendor) { if (!idProduct) { @@ -2433,7 +2448,7 @@ } EP_IN_NAME = ep->name; ep->driver_data = ep; /* claim */ - + ep = usb_ep_autoconfig (gadget, &fs_sink_desc); if (!ep) goto autoconf_fail; @@ -2455,9 +2470,7 @@ shortname, gadget->name); return -ENODEV; } else if (cdc) { -#ifdef DEV_CONFIG_CDC control_intf.bNumEndpoints = 0; -#endif /* FIXME remove endpoint from descriptor list */ } } @@ -2527,48 +2540,9 @@ * The host side address is used with CDC and RNDIS, and commonly * ends up in a persistent config database. */ -#ifndef CONFIG_NSCU get_ether_addr(dev_addr, net->dev_addr); -#else - /* We own a block of 4 consecutive MAC addresses; use the last - * two for the gadget stuff - */ - { - bd_t *bd = (bd_t *)__res; - unsigned long addr; - - memcpy(net->dev_addr, bd->bi_enetaddr, ETH_ALEN-3); - /* base MAC address + 2 */ - addr = (bd->bi_enetaddr[ETH_ALEN-3] << 16) + - (bd->bi_enetaddr[ETH_ALEN-2] << 8) + - (bd->bi_enetaddr[ETH_ALEN-1] ) + - 2; - net->dev_addr [ETH_ALEN-3] = (addr >> 16) & 0xFF; - net->dev_addr [ETH_ALEN-2] = (addr >> 8) & 0xFF; - net->dev_addr [ETH_ALEN-1] = (addr ) & 0xFF; - } -#endif if (cdc || rndis) { -#ifndef CONFIG_NSCU get_ether_addr(host_addr, dev->host_mac); -#else - /* We own a block of 4 consecutive MAC addresses; use the last - * two for the gadget stuff; - * use base MAC address + 3 fot host-addr - */ - { - bd_t *bd = (bd_t *)__res; - unsigned long addr; - memcpy (dev->host_mac, bd->bi_enetaddr, ETH_ALEN-3); - addr = (bd->bi_enetaddr[ETH_ALEN-3] << 16) + - (bd->bi_enetaddr[ETH_ALEN-2] << 8) + - (bd->bi_enetaddr[ETH_ALEN-1] ) + - 3; - dev->host_mac[ETH_ALEN-3] = (addr >> 16) & 0xFF; - dev->host_mac[ETH_ALEN-2] = (addr >> 8) & 0xFF; - dev->host_mac[ETH_ALEN-1] = (addr ) & 0xFF; - } -#endif #ifdef DEV_CONFIG_CDC snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", dev->host_mac [0], dev->host_mac [1], @@ -2611,7 +2585,7 @@ dev->gadget = gadget; set_gadget_data (gadget, dev); gadget->ep0->driver_data = dev; - + /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" @@ -2646,7 +2620,7 @@ u32 vendorID = 0; /* FIXME RNDIS vendor id == "vendor NIC code" == ? */ - + dev->rndis_config = rndis_register (rndis_control_ack); if (dev->rndis_config < 0) { fail0: @@ -2654,7 +2628,7 @@ status = -ENODEV; goto fail; } - + /* these set up a lot of the OIDs that RNDIS needs */ rndis_set_host_mac (dev->rndis_config, dev->host_mac); if (rndis_set_param_dev (dev->rndis_config, dev->net, @@ -2669,7 +2643,7 @@ goto fail0; INFO (dev, "RNDIS ready\n"); } -#endif +#endif return status; diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/file_storage.c linuxppc_2_4_devel.modified/drivers/usb/gadget/file_storage.c --- linuxppc_2_4_devel/drivers/usb/gadget/file_storage.c 2004-03-11 23:44:07.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/file_storage.c 2006-03-31 14:46:58.000000000 +0200 @@ -1,7 +1,7 @@ /* * file_storage.c -- File-backed USB Storage Gadget, for USB development * - * Copyright (C) 2003 Alan Stern + * Copyright (C) 2003, 2004 Alan Stern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -229,12 +229,14 @@ #include #include +#include "gadget_chips.h" + /*-------------------------------------------------------------------------*/ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "14 January 2004" +#define DRIVER_VERSION "05 June 2004" static const char longname[] = DRIVER_DESC; static const char shortname[] = DRIVER_NAME; @@ -251,165 +253,11 @@ #define DRIVER_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget -/*-------------------------------------------------------------------------*/ - -/* - * Hardware-specific configuration, controlled by which device - * controller driver was configured. - * - * CHIP ... hardware identifier - * DRIVER_VERSION_NUM ... alerts the host side driver to differences - * EP_*_NAME ... which endpoints do we use for which purpose? - * EP_*_NUM ... numbers for them (often limited by hardware) - * FS_BULK_IN_MAXPACKET ... maxpacket value for full-speed bulk-in ep - * FS_BULK_OUT_MAXPACKET ... maxpacket value for full-speed bulk-out ep - * HIGHSPEED ... define if ep0 and descriptors need high speed support - * MAX_USB_POWER ... define if we use other than 100 mA bus current - * SELFPOWER ... if we can run on bus power, zero - * NO_BULK_STALL ... bulk endpoint halts don't work well so avoid them - */ - - -/* - * NetChip 2280, PCI based. - * - * This has half a dozen configurable endpoints, four with dedicated - * DMA channels to manage their FIFOs. It supports high speed. - * Those endpoints can be arranged in any desired configuration. - */ -#ifdef CONFIG_USB_GADGET_NET2280 -#define CHIP "net2280" -#define DRIVER_VERSION_NUM 0x0211 -static const char EP_BULK_IN_NAME[] = "ep-a"; -#define EP_BULK_IN_NUM 1 -#define FS_BULK_IN_MAXPACKET 64 -static const char EP_BULK_OUT_NAME[] = "ep-b"; -#define EP_BULK_OUT_NUM 2 -#define FS_BULK_OUT_MAXPACKET 64 -static const char EP_INTR_IN_NAME[] = "ep-e"; -#define EP_INTR_IN_NUM 5 -#define HIGHSPEED -#endif - - -/* - * Dummy_hcd, software-based loopback controller. - * - * This imitates the abilities of the NetChip 2280, so we will use - * the same configuration. - */ -#ifdef CONFIG_USB_GADGET_DUMMY -#define CHIP "dummy" -#define DRIVER_VERSION_NUM 0x0212 -static const char EP_BULK_IN_NAME[] = "ep-a"; -#define EP_BULK_IN_NUM 1 -#define FS_BULK_IN_MAXPACKET 64 -static const char EP_BULK_OUT_NAME[] = "ep-b"; -#define EP_BULK_OUT_NUM 2 -#define FS_BULK_OUT_MAXPACKET 64 -static const char EP_INTR_IN_NAME[] = "ep-e"; -#define EP_INTR_IN_NUM 5 -#define HIGHSPEED -#endif - - -/* - * PXA-2xx UDC: widely used in second gen Linux-capable PDAs. - * - * This has fifteen fixed-function full speed endpoints, and it - * can support all USB transfer types. - * - * These supports three or four configurations, with fixed numbers. - * The hardware interprets SET_INTERFACE, net effect is that you - * can't use altsettings or reset the interfaces independently. - * So stick to a single interface. - */ -#ifdef CONFIG_USB_GADGET_PXA2XX -#define CHIP "pxa2xx" -#define DRIVER_VERSION_NUM 0x0213 -static const char EP_BULK_IN_NAME[] = "ep1in-bulk"; -#define EP_BULK_IN_NUM 1 -#define FS_BULK_IN_MAXPACKET 64 -static const char EP_BULK_OUT_NAME[] = "ep2out-bulk"; -#define EP_BULK_OUT_NUM 2 -#define FS_BULK_OUT_MAXPACKET 64 -static const char EP_INTR_IN_NAME[] = "ep6in-bulk"; -#define EP_INTR_IN_NUM 6 -#endif - - /* - * SuperH UDC: UDC built-in to some Renesas SH processors. - * - * This has three fixed-function full speed bulk/interrupt endpoints. - * - * Only one configuration and interface is supported (SET_CONFIGURATION - * and SET_INTERFACE are handled completely by the hardware). - */ -#ifdef CONFIG_USB_GADGET_SUPERH -#define CHIP "superh" -#define DRIVER_VERSION_NUM 0x0215 -static const char EP_BULK_IN_NAME[] = "ep2in-bulk"; -#define EP_BULK_IN_NUM 2 -#define FS_BULK_IN_MAXPACKET 64 -static const char EP_BULK_OUT_NAME[] = "ep1out-bulk"; -#define EP_BULK_OUT_NUM 1 -#define FS_BULK_OUT_MAXPACKET 64 -static const char EP_INTR_IN_NAME[] = "ep3in-bulk"; -#define EP_INTR_IN_NUM 3 -#define NO_BULK_STALL -#endif - - -/* - * Toshiba TC86C001 ("Goku-S") UDC - * - * This has three semi-configurable full speed bulk/interrupt endpoints. - */ -#ifdef CONFIG_USB_GADGET_GOKU -#define CHIP "goku" -#define DRIVER_VERSION_NUM 0x0216 -static const char EP_BULK_OUT_NAME [] = "ep1-bulk"; -#define EP_BULK_OUT_NUM 1 -#define FS_BULK_IN_MAXPACKET 64 -static const char EP_BULK_IN_NAME [] = "ep2-bulk"; -#define EP_BULK_IN_NUM 2 -#define FS_BULK_OUT_MAXPACKET 64 -static const char EP_INTR_IN_NAME [] = "ep3-bulk"; -#define EP_INTR_IN_NUM 3 -#endif - - -/*-------------------------------------------------------------------------*/ - -#ifndef CHIP -# error Configure some USB peripheral controller driver! -#endif - -/* Power usage is config specific. - * Hardware that supports remote wakeup defaults to disabling it. + * This driver assumes self-powered hardware and has no way for users to + * trigger remote wakeup. It uses autoconfiguration to select endpoints + * and endpoint addresses. */ -#ifndef SELFPOWER -/* default: say we're self-powered */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER -/* else: - * - SELFPOWER value must be zero - * - MAX_USB_POWER may be nonzero. - */ -#endif - -#ifndef MAX_USB_POWER -/* Any hub supports this steady state bus power consumption */ -#define MAX_USB_POWER 100 /* mA */ -#endif - -/* We don't support remote wake-up */ - -#ifdef NO_BULK_STALL -#define CAN_STALL 0 -#else -#define CAN_STALL 1 -#endif /*-------------------------------------------------------------------------*/ @@ -478,14 +326,15 @@ static char *file[MAX_LUNS] = {NULL, }; static int ro[MAX_LUNS] = {0, }; static unsigned int luns = 0; + // Default values static char *transport = "BBB"; static char *protocol = "SCSI"; static int removable = 0; static unsigned short vendor = DRIVER_VENDOR_ID; static unsigned short product = DRIVER_PRODUCT_ID; -static unsigned short release = DRIVER_VERSION_NUM; +static unsigned short release = 0xffff; // Use controller chip type static unsigned int buflen = 16384; -static int stall = CAN_STALL; +static int stall = 1; static struct { unsigned int nluns; @@ -990,7 +839,7 @@ /* The next three values can be overridden by module parameters */ .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID), .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID), - .bcdDevice = __constant_cpu_to_le16(DRIVER_VERSION_NUM), + .bcdDevice = __constant_cpu_to_le16(0xffff), .iManufacturer = STRING_MANUFACTURER, .iProduct = STRING_PRODUCT, @@ -1003,11 +852,11 @@ .bLength = sizeof config_desc, .bDescriptorType = USB_DT_CONFIG, - /* wTotalLength adjusted during bind() */ + /* wTotalLength computed by usb_gadget_config_buf() */ .bNumInterfaces = 1, .bConfigurationValue = CONFIG_VALUE, - .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER, - .bMaxPower = (MAX_USB_POWER + 1) / 2, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 1, // self-powered }; /* There is only one interface. */ @@ -1017,47 +866,56 @@ .bLength = sizeof intf_desc, .bDescriptorType = USB_DT_INTERFACE, - .bNumEndpoints = 2, // Adjusted during bind() + .bNumEndpoints = 2, // Adjusted during fsg_bind() .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, // Adjusted during bind() - .bInterfaceProtocol = USB_PR_BULK, // Adjusted during bind() + .bInterfaceSubClass = USB_SC_SCSI, // Adjusted during fsg_bind() + .bInterfaceProtocol = USB_PR_BULK, // Adjusted during fsg_bind() }; /* Three full-speed endpoint descriptors: bulk-in, bulk-out, * and interrupt-in. */ -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor fs_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_BULK_IN_NUM | USB_DIR_IN, + .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(FS_BULK_IN_MAXPACKET), + /* wMaxPacketSize set by autoconfiguration */ }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor fs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_BULK_OUT_NUM, + .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(FS_BULK_OUT_MAXPACKET), + /* wMaxPacketSize set by autoconfiguration */ }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor fs_intr_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_INTR_IN_NUM | USB_DIR_IN, + .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = __constant_cpu_to_le16(2), .bInterval = 32, // frames -> 32 ms }; -#ifdef HIGHSPEED +static const struct usb_descriptor_header *fs_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &fs_bulk_in_desc, + (struct usb_descriptor_header *) &fs_bulk_out_desc, + (struct usb_descriptor_header *) &fs_intr_in_desc, + NULL, +}; + + +#ifdef CONFIG_USB_GADGET_DUALSPEED /* * USB 2.0 devices need to expose both high speed and full speed @@ -1067,47 +925,55 @@ * and a "device qualifier" ... plus more construction options * for the config descriptor. */ -static const struct usb_endpoint_descriptor +static struct usb_qualifier_descriptor +dev_qualifier = { + .bLength = sizeof dev_qualifier, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_PER_INTERFACE, + + .bNumConfigurations = 1, +}; + +static struct usb_endpoint_descriptor hs_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_BULK_IN_NUM | USB_DIR_IN, + /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16(512), }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor hs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_BULK_OUT_NUM, + /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16(512), .bInterval = 1, // NAK every 1 uframe }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor hs_intr_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_INTR_IN_NUM | USB_DIR_IN, + /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = __constant_cpu_to_le16(2), .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms }; -static struct usb_qualifier_descriptor -dev_qualifier = { - .bLength = sizeof dev_qualifier, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - - .bNumConfigurations = 1, +static const struct usb_descriptor_header *hs_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &hs_bulk_in_desc, + (struct usb_descriptor_header *) &hs_bulk_out_desc, + (struct usb_descriptor_header *) &hs_intr_in_desc, + NULL, }; /* Maxpacket and other transfer characteristics vary by speed. */ @@ -1115,22 +981,23 @@ #else -/* If there's no high speed support, maxpacket doesn't change. */ +/* If there's no high speed support, always use the full-speed descriptor. */ #define ep_desc(g,fs,hs) fs -#endif /* !HIGHSPEED */ +#endif /* !CONFIG_USB_GADGET_DUALSPEED */ /* The CBI specification limits the serial string to 12 uppercase hexadecimal * characters. */ +static char manufacturer[40]; static char serial[13]; -/* Static strings, in ISO 8859/1 */ +/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ static struct usb_string strings[] = { - { STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, }, - { STRING_PRODUCT, longname, }, - { STRING_SERIAL, serial, }, - { } // end of list + {STRING_MANUFACTURER, manufacturer}, + {STRING_PRODUCT, longname}, + {STRING_SERIAL, serial}, + {} }; static struct usb_gadget_strings stringtab = { @@ -1140,61 +1007,33 @@ /* - * Config descriptors are handcrafted. They must agree with the code - * that sets configurations and with code managing interfaces and their - * altsettings. They must also handle different speeds and other-speed - * requests. + * Config descriptors must agree with the code that sets configurations + * and with code managing interfaces and their altsettings. They must + * also handle different speeds and other-speed requests. */ static int populate_config_buf(enum usb_device_speed speed, - u8 *buf0, u8 type, unsigned index) + u8 *buf, u8 type, unsigned index) { - u8 *buf = buf0; -#ifdef HIGHSPEED - int hs; -#endif + int len; + const struct usb_descriptor_header **function; if (index > 0) return -EINVAL; - if (config_desc.wTotalLength > EP0_BUFSIZE) - return -EDOM; - /* Config (or other speed config) */ - memcpy(buf, &config_desc, USB_DT_CONFIG_SIZE); - buf[1] = type; - buf += USB_DT_CONFIG_SIZE; - - /* Interface */ - memcpy(buf, &intf_desc, USB_DT_INTERFACE_SIZE); - buf += USB_DT_INTERFACE_SIZE; - - /* The endpoints in the interface (at that speed) */ -#ifdef HIGHSPEED - hs = (speed == USB_SPEED_HIGH); +#ifdef CONFIG_USB_GADGET_DUALSPEED if (type == USB_DT_OTHER_SPEED_CONFIG) - hs = !hs; - if (hs) { - memcpy(buf, &hs_bulk_in_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - memcpy(buf, &hs_bulk_out_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - if (transport_is_cbi()) { - memcpy(buf, &hs_intr_in_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - } - } else + speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; + if (speed == USB_SPEED_HIGH) + function = hs_function; + else #endif - { - memcpy(buf, &fs_bulk_in_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - memcpy(buf, &fs_bulk_out_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - if (transport_is_cbi()) { - memcpy(buf, &fs_intr_in_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - } - } + function = fs_function; - return buf - buf0; + len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); + if (len < 0) + return len; + ((struct usb_config_descriptor *) buf)->bDescriptorType = type; + return len; } @@ -1493,22 +1332,26 @@ value = min(ctrl->wLength, (u16) sizeof device_desc); memcpy(req->buf, &device_desc, value); break; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER: VDBG(fsg, "get device qualifier\n"); + if (!fsg->gadget->is_dualspeed) + break; value = min(ctrl->wLength, (u16) sizeof dev_qualifier); memcpy(req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: VDBG(fsg, "get other-speed config descriptor\n"); + if (!fsg->gadget->is_dualspeed) + break; goto get_config; -#endif /* HIGHSPEED */ +#endif case USB_DT_CONFIG: VDBG(fsg, "get configuration descriptor\n"); -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED get_config: -#endif /* HIGHSPEED */ +#endif value = populate_config_buf(fsg->gadget->speed, req->buf, ctrl->wValue >> 8, @@ -1611,6 +1454,7 @@ /* Respond with data/status or defer until later? */ if (rc >= 0 && rc != DELAYED_STATUS) { fsg->ep0req->length = rc; + fsg->ep0req->zero = (rc < ctrl->wLength); fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out"); rc = ep0_queue(fsg); @@ -2148,7 +1992,7 @@ buf[4] = 31; // Additional length // No special options sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id, - DRIVER_VERSION_NUM); + mod_data.release); return 36; } @@ -2196,7 +2040,7 @@ buf[0] = 0x80 | 0x70; // Valid, current error buf[2] = SK(sd); put_be32(&buf[3], sdinfo); // Sense information - buf[7] = 18 - 7; // Additional sense length + buf[7] = 18 - 8; // Additional sense length buf[12] = ASC(sd); buf[13] = ASCQ(sd); return 18; @@ -2643,7 +2487,7 @@ /* Store and send the Bulk-only CSW */ csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); csw->Tag = fsg->tag; - csw->Residue = fsg->residue; + csw->Residue = cpu_to_le32(fsg->residue); csw->Status = status; bh->inreq->length = USB_BULK_CS_WRAP_LEN; @@ -3089,7 +2933,7 @@ fsg->data_dir = DATA_DIR_TO_HOST; else fsg->data_dir = DATA_DIR_FROM_HOST; - fsg->data_size = cbw->DataTransferLength; + fsg->data_size = le32_to_cpu(cbw->DataTransferLength); if (fsg->data_size == 0) fsg->data_dir = DATA_DIR_NONE; fsg->lun = cbw->Lun; @@ -3242,6 +3086,7 @@ if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) goto reset; fsg->bulk_out_enabled = 1; + fsg->bulk_out_maxpacket = d->wMaxPacketSize; if (transport_is_cbi()) { d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc); @@ -3717,6 +3562,34 @@ mod_data.protocol_type = USB_SC_SCSI; mod_data.protocol_name = "Transparent SCSI"; + if (gadget_is_sh(fsg->gadget)) + mod_data.can_stall = 0; + + if (mod_data.release == 0xffff) { // Parameter wasn't set + if (gadget_is_net2280(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0221); + else if (gadget_is_dummy(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0222); + else if (gadget_is_pxa(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0223); + else if (gadget_is_sh(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0224); + + /* The sa1100 controller is not supported */ + + else if (gadget_is_goku(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0226); + else if (gadget_is_mq11xx(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0227); + else if (gadget_is_omap(fsg->gadget)) + mod_data.release = __constant_cpu_to_le16(0x0228); + else { + WARN(fsg, "controller '%s' not recognized\n", + fsg->gadget->name); + mod_data.release = __constant_cpu_to_le16(0x0299); + } + } + prot = simple_strtol(mod_data.protocol_parm, NULL, 0); #ifdef CONFIG_USB_FILE_STORAGE_TEST @@ -3729,7 +3602,7 @@ mod_data.transport_type = USB_PR_CBI; mod_data.transport_name = "Control-Bulk-Interrupt"; } else { - INFO(fsg, "invalid transport: %s\n", mod_data.transport_parm); + ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); return -EINVAL; } @@ -3758,13 +3631,13 @@ mod_data.protocol_type = USB_SC_8070; mod_data.protocol_name = "8070i"; } else { - INFO(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); + ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); return -EINVAL; } mod_data.buflen &= PAGE_CACHE_MASK; if (mod_data.buflen <= 0) { - INFO(fsg, "invalid buflen\n"); + ERROR(fsg, "invalid buflen\n"); return -ETOOSMALL; } #endif /* CONFIG_USB_FILE_STORAGE_TEST */ @@ -3800,7 +3673,7 @@ } } if (i > MAX_LUNS) { - INFO(fsg, "invalid number of LUNs: %d\n", i); + ERROR(fsg, "invalid number of LUNs: %d\n", i); rc = -EINVAL; goto out; } @@ -3827,45 +3700,57 @@ if ((rc = open_backing_file(curlun, file[i])) != 0) goto out; } else if (!mod_data.removable) { - INFO(fsg, "no file given for LUN%d\n", i); + ERROR(fsg, "no file given for LUN%d\n", i); rc = -EINVAL; goto out; } } + /* Find all the endpoints we will use */ + usb_ep_autoconfig_reset(gadget); + ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint + fsg->bulk_in = ep; + + ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint + fsg->bulk_out = ep; + + if (transport_is_cbi()) { + ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc); + if (!ep) + goto autoconf_fail; + ep->driver_data = fsg; // claim the endpoint + fsg->intr_in = ep; + } + /* Fix up the descriptors */ device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; -#ifdef HIGHSPEED - dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; // ??? -#endif device_desc.idVendor = cpu_to_le16(mod_data.vendor); device_desc.idProduct = cpu_to_le16(mod_data.product); device_desc.bcdDevice = cpu_to_le16(mod_data.release); i = (transport_is_cbi() ? 3 : 2); // Number of endpoints - config_desc.wTotalLength = USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE - + USB_DT_ENDPOINT_SIZE * i; intf_desc.bNumEndpoints = i; intf_desc.bInterfaceSubClass = mod_data.protocol_type; intf_desc.bInterfaceProtocol = mod_data.transport_type; + fs_function[i+1] = NULL; - /* Find all the endpoints we will use */ - gadget_for_each_ep(ep, gadget) { - if (strcmp(ep->name, EP_BULK_IN_NAME) == 0) - fsg->bulk_in = ep; - else if (strcmp(ep->name, EP_BULK_OUT_NAME) == 0) - fsg->bulk_out = ep; - else if (strcmp(ep->name, EP_INTR_IN_NAME) == 0) - fsg->intr_in = ep; - } - if (!fsg->bulk_in || !fsg->bulk_out || - (transport_is_cbi() && !fsg->intr_in)) { - DBG(fsg, "unable to find all endpoints\n"); - rc = -ENOTSUPP; - goto out; - } - fsg->bulk_out_maxpacket = (gadget->speed == USB_SPEED_HIGH ? 512 : - FS_BULK_OUT_MAXPACKET); +#ifdef CONFIG_USB_GADGET_DUALSPEED + hs_function[i+1] = NULL; + + /* Assume ep0 uses the same maxpacket value for both speeds */ + dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; + + /* Assume that all endpoint addresses are the same for both speeds */ + hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress; + hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress; + hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress; +#endif rc = -ENOMEM; @@ -3894,6 +3779,10 @@ /* This should reflect the actual gadget power source */ usb_gadget_set_selfpowered(gadget); + snprintf(manufacturer, sizeof manufacturer, + UTS_SYSNAME " " UTS_RELEASE " with %s", + gadget->name); + /* On a real device, serial[] would be loaded from permanent * storage. We just encode it from the driver version string. */ for (i = 0; i < sizeof(serial) - 2; i += 2) { @@ -3942,6 +3831,10 @@ DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid); return 0; +autoconf_fail: + ERROR(fsg, "unable to autoconfigure all endpoints\n"); + rc = -ENOTSUPP; + out: fsg->state = FSG_STATE_TERMINATED; // The thread is dead fsg_unbind(gadget); @@ -3953,7 +3846,7 @@ /*-------------------------------------------------------------------------*/ static struct usb_gadget_driver fsg_driver = { -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED .speed = USB_SPEED_HIGH, #else .speed = USB_SPEED_FULL, diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/gadget_chips.h linuxppc_2_4_devel.modified/drivers/usb/gadget/gadget_chips.h --- linuxppc_2_4_devel/drivers/usb/gadget/gadget_chips.h 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/gadget_chips.h 2007-02-01 09:06:59.000000000 +0100 @@ -8,7 +8,7 @@ * * NOTE: some of these controller drivers may not be available yet. */ -#ifdef CONFIG_USB_GADGET_NET2280 +#if defined(CONFIG_USB_GADGET_NET2280) || defined(CONFIG_USB_GADGET_NET2282) #define gadget_is_net2280(g) !strcmp("net2280", (g)->name) #else #define gadget_is_net2280(g) 0 @@ -74,12 +74,6 @@ #define gadget_is_pxa27x(g) 0 #endif -#ifdef CONFIG_USB_GADGET_ISP1362 -#define gadget_is_isp1362(g) !strcmp("isp1362_udc", (g)->name) -#else -#define gadget_is_isp1362(g) 0 -#endif - // CONFIG_USB_GADGET_AT91RM9200 // CONFIG_USB_GADGET_SX2 // CONFIG_USB_GADGET_AU1X00 diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/isp1362gapi.c linuxppc_2_4_devel.modified/drivers/usb/gadget/isp1362gapi.c --- linuxppc_2_4_devel/drivers/usb/gadget/isp1362gapi.c 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/isp1362gapi.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1420 +0,0 @@ -/* - * ISP1362 USB controller core driver. - * Copyright (C) 2004-2005 DENX Software Engineering, Wolfgang Denk, wd@denx.de - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_NSCU -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "isp1362gapi.h" - -/*#define DEBUG - #define VERBOSE*/ - -#ifdef DEBUG -#undef KERN_DEBUG -#define KERN_DEBUG KERN_WARNING -#define debug(fmt, params...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## params) -#define debug0(fmt) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__) -#else -#define debug(fmt...) -#define debug0(fmt) -#endif - -#ifdef VERBOSE -#define verbose(fmt, params...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## params) -#define verbose0(fmt) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__) -#else -#define verbose(fmt...) -#define verbose0(fmt...) -#endif - -#define DRIVER_VERSION "4-Apr-2004" -#define DRIVER_DESC "isp1362 USB Device Controller driver" - -#define ISP1362_DC_DATA (isp1362_io_base + 4) -#define ISP1362_DC_COM (isp1362_io_base + 6) - -#ifdef CONFIG_NSCU -#define ISP1362_RESET 0x2000 - -static struct timer_list isp1362_timer; -#endif - -static const char driver_name [] = "isp1362_udc"; -static const char ep0name [] = "ep0"; - -static struct isp1362_udc *the_controller; -static void * isp1362_io_base = NULL; - -static ulong isp1362_cnt_int = 0; -static ulong isp1362_cnt_reset = 0; -static ulong isp1362_cnt_resume = 0; -static ulong isp1362_cnt_suspend = 0; -static ulong isp1362_cnt_err_setup = 0; - -static void isp1362_ep_int_hndlr(struct isp1362_ep* ep); - -#if CONFIG_PROC_FS - -#define DEBUG_DEVNAME "debug" -#define DEBUG_USB_DIR "usb" - -typedef struct { - int count; - int size; - wait_queue_head_t wq; -} debug_dev_t; - -static debug_dev_t debug_dev; - -static devfs_handle_t devfs_handle = NULL; - -static struct proc_dir_entry *debug_proc_dir; -static struct proc_dir_entry *debug_proc_usb_dir; - -struct file_operations debug_fops = { -}; - -#define PROC_SUSPEND_NAME "isp1362_suspend" - -#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args ) -#define SAYV( num ) p += sprintf(p, "%25.25s: %8.8lX\n", "Value", num ) -#define SAYC( label, yn ) p += sprintf(p, "%25.25s: %s\n", label, yn ) -#define SAYS( label, v ) p += sprintf(p, "%25.25s: %lu\n", label, v ) - -static int isp1362_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char * p = page; - int len; - - SAY( "ISP1362-Gadget:\n" ); - - SAYS( "Interrupt counter", isp1362_cnt_int ); - SAYS( "Reset counter", isp1362_cnt_reset ); - SAYS( "Resume counter", isp1362_cnt_resume ); - SAYS( "Suspend counter", isp1362_cnt_suspend ); - - SAYS( "SETUP errors", isp1362_cnt_err_setup ); -// SAYS( "IN errors", isp1362_cnt_err_in ); -// SAYS( "OUT errors", isp1362_cnt_err_out ); - - len = ( p - page ) - off; - if ( len < 0 ) - len = 0; - *eof = ( len <=count ) ? 1 : 0; - *start = page + off; - return len; -} - -static void isp1362_reset_device(void); -static void reset_udc(struct isp1362_udc* dev); - -static int isp1362_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - char mydata[0x100]; - volatile immap_t *immr; - volatile cpm8xx_t *cp; - struct isp1362_udc *dev = the_controller; - - immr = (immap_t*)IMAP_ADDR; - cp = (cpm8xx_t*)&immr->im_cpm; - - /* TODO: Check for count > len */ - if (copy_from_user(mydata, buffer, count) ) { - return -EFAULT; - } - - if (strncmp(mydata, "reset", 5) == 0) { - printk("ISP1362-Gadget: reset request!\n"); - cp->cp_pbdat &= ~ISP1362_RESET; - mdelay(1); - cp->cp_pbdat |= ISP1362_RESET; - } else if (strncmp(mydata, "sreset", 6) == 0) { - printk("ISP1362-Gadget: soft-reset request!\n"); - isp1362_reset_device(); - mdelay(500); - reset_udc(dev); - } - - - return count; -} - -#endif /* CONFIG_PROC_FS */ - -#ifdef VERBOSE -static inline void isp1362_print_request( struct usb_ctrlrequest * pReq ) -{ - static char * tnames[] = { "dev", "intf", "ep", "oth" }; - static char * rnames[] = { "std", "class", "vendor", "???" }; - char * psz; - switch( pReq->bRequest ) { - case USB_REQ_GET_STATUS: psz = "get stat"; break; - case USB_REQ_CLEAR_FEATURE: psz = "clr feat"; break; - case USB_REQ_SET_FEATURE: psz = "set feat"; break; - case USB_REQ_SET_ADDRESS: psz = "set addr"; break; - case USB_REQ_GET_DESCRIPTOR: psz = "get desc"; break; - case USB_REQ_SET_DESCRIPTOR: psz = "set desc"; break; - case USB_REQ_GET_CONFIGURATION: psz = "get cfg"; break; - case USB_REQ_SET_CONFIGURATION: psz = "set cfg"; break; - case USB_REQ_GET_INTERFACE: psz = "get intf"; break; - case USB_REQ_SET_INTERFACE: psz = "set intf"; break; - default: psz = "unknown"; break; - } - debug( "- [%s: %s req to %s. dir=%s]\n", psz, - rnames[ (pReq->bRequestType >> 5) & 3 ], - tnames[ pReq->bRequestType & 3 ], - ( pReq->bRequestType & 0x80 ) ? "in" : "out" ); -} -#endif /* VERBOSE */ - -static inline ulong isp1362_inw (volatile unsigned short * port) -{ - ulong res; - mb(); - res = *port; - mb(); - return res; -} - -static inline void isp1362_outw (ulong data, volatile unsigned short * port) -{ - mb(); - *port = data; - mb(); -} - -static ulong isp1362_read_reg32 (ulong reg) -{ - ulong res; - - isp1362_outw (reg, ISP1362_DC_COM); - res = isp1362_inw (ISP1362_DC_DATA); - res |= isp1362_inw (ISP1362_DC_DATA) << 16; - - return res; -} - -static void isp1362_write_reg32 (ulong reg, ulong data) -{ - isp1362_outw (reg, ISP1362_DC_COM); - isp1362_outw (data & 0xFFFF, ISP1362_DC_DATA); - isp1362_outw (data >> 16, ISP1362_DC_DATA); -} - -static ulong isp1362_read_reg16 (ulong reg) -{ - ulong res; - - isp1362_outw (reg, ISP1362_DC_COM); - res = isp1362_inw (ISP1362_DC_DATA); - - return res; -} - -static void isp1362_write_reg16 (ulong reg, ulong data) -{ - isp1362_outw (reg, ISP1362_DC_COM); - isp1362_outw (data, ISP1362_DC_DATA); -} - -static void isp1362_cmd_reg (ulong reg) -{ - isp1362_outw (reg, ISP1362_DC_COM); -} - - /* Set device address - */ -static void isp1362_set_address(ulong devaddr) -{ - isp1362_write_reg16(WR_DcAddress, 0x80 | devaddr); -} - - /* Check endpoint status - */ -ulong isp1362_check_status(ulong ep, ulong dir) -{ - ulong code = ep ? RD_DcEndpointStatusImage + ep : dir == EP_DIR_IN ? - RD_DcEndpointStatusImage0_IN : RD_DcEndpointStatusImage0_OUT; - - return isp1362_read_reg16(code); -} - - /* Acknowledge Set-up. - */ -static void isp1362_acknowledge_setup(void) -{ - isp1362_cmd_reg(DO_AcknowledgeSetup); -} - - /* Validate endpoint buffer. - */ -static void isp1362_validate_buffer(ulong ep) -{ - ulong code = ep ? DO_ValidateEndpointBuffer + ep : - DO_ValidateEndpointBuffer0; - - isp1362_cmd_reg(code); -} - - /* Clear endpoint buffer. - */ -void isp1362_clear_buffer(ulong ep) -{ - ulong code = ep ? DO_ClearEndpointBuffer + ep : - DO_ClearEndpointBuffer0; - - isp1362_cmd_reg(code); -} - - /* Write to endpoint buffer memory - */ -void isp1362_write_buffer (ulong ep, void * buf, ulong size) -{ - ulong code = ep ? DO_WriteEndpointBuffer + ep : DO_WriteEndpointBuffer0; - ushort data; - int i; - -#ifdef VERBOSE - if (size) - { - unsigned char * pdb = (unsigned char *)buf; - int i; - - verbose0("data:"); - for (i = 0; i < size; i++) - printk(" %02X", (int)pdb[i]); - printk("\n"); - } -#endif - - isp1362_cmd_reg (code); - - isp1362_outw (size, ISP1362_DC_DATA); - - for (i = 0; i < size / 2; i ++) - { - data = ((ushort *)buf)[i]; - cpu_to_le16s (&data); - isp1362_outw (data, ISP1362_DC_DATA); - } - if (size & 1) - { - data = ((u_char *)buf)[size - 1]; - isp1362_outw (data, ISP1362_DC_DATA); - } - - isp1362_validate_buffer (ep); -} - - /* Read from endpoint buffer memory - */ -ulong isp1362_read_buffer (ulong ep, void * buf, long size) -{ - ulong code = ep ? DO_ReadEndpointBuffer + ep : DO_ReadEndpointBuffer0; - ulong res; - ushort data; - int i; - - isp1362_cmd_reg (code); - - res = isp1362_inw (ISP1362_DC_DATA); - if (res > size) - { - printk ("isp1362: Packet is too long: %04X > %04X\n", - (uint)res, (uint)size); - res = size; - } - - for (i = 0; i < res / 2; i ++) - { - data = isp1362_inw (ISP1362_DC_DATA); - le16_to_cpus(&data); - ((ushort *)buf)[i] = data; - } - if (res & 1) - { - data = isp1362_inw (ISP1362_DC_DATA); - ((u_char *)buf)[res - 1] = data; - } - - if (ep == 0 && (isp1362_check_status(0, EP_DIR_OUT) & EPSTAT_SETUPT)) - isp1362_acknowledge_setup(); - - isp1362_clear_buffer (ep); - -#ifdef VERBOSE - if (res) - { - unsigned char * pdb = (unsigned char *)buf; - int i; - - verbose("data %d bytes:", (int)res); - for (i = 0; i < res; i++) - printk(" %02X", (int)pdb[i]); - printk("\n"); - } -#endif - - return res; -} - - /* Unlock device - */ -static void isp1362_unlock_device(void) -{ - isp1362_write_reg16(WR_UnlockDevice, 0xAA37); -} - - /* Chip identification code and hardware version number - */ -static ulong isp1362_chip_id(void) -{ - return isp1362_read_reg16(RD_DcChipID); -} - - /* Stall endpoint. - */ -static void isp1362_stall_endpoint(ulong ep, ulong dir) -{ - ulong code = ep ? DO_StallEndpoint + ep : dir == EP_DIR_IN ? - DO_StallEndpoint0_IN : DO_StallEndpoint0_OUT; - - isp1362_cmd_reg(code); -} - - /* Unstall endpoint. - */ -static void isp1362_unstall_endpoint(ulong ep, ulong dir) -{ - ulong code = ep ? DO_UnstallEndpoint + ep : dir == EP_DIR_IN ? - DO_UnstallEndpoint0_IN : DO_UnstallEndpoint0_OUT; - - isp1362_cmd_reg(code); -} - -static void isp1362_send_empty_packet(ulong ep) -{ - isp1362_write_buffer(ep, NULL, 0); -} - -static int isp1362_setup_data_send(void *in, ulong requested, ulong have) -{ - if (requested > have) { - debug("isp1362: Wrong data size requested: %lu>%lu\n", requested, - have); - requested = have; - /* Note: must send an empty packet? */ - /*isp1362_ep0_empty_queued = 1;*/ - } - - isp1362_write_buffer(0, in, requested); - return 0; -} - - /* Resets the DC in the same way as an external hardware reset - */ -static void isp1362_reset_device(void) -{ - isp1362_cmd_reg(DO_ResetDevice); -} - -#ifdef VERBOSE - /* Frame number of the last successfully received SOF - */ -static ulong isp1362_frame_number(void) -{ - return isp1362_read_reg16(RD_DcFrameNumber) & 0x07FF; -} -#endif - - /* Resume handler - */ -static void isp1362_resume(void) -{ - isp1362_unlock_device(); -} - -#ifdef CONFIG_NSCU -static int isp1362_read_susp_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char * p = page; - int len; - - SAY( "ISP1362 Suspend Hangup detected!\n" ); - - len = ( p - page ) - off; - if ( len < 0 ) - len = 0; - *eof = ( len <=count ) ? 1 : 0; - *start = page + off; - return len; -} - -static void isp1362_timer_func(unsigned long data) -{ - debug("%s: ISP1362 Suspend Hangup detected!\n", __FUNCTION__); - - /* - * Create proc file to signal a hangup to user space - */ - create_proc_read_entry (PROC_SUSPEND_NAME, 0, NULL, isp1362_read_susp_proc, NULL); -} -#endif - - /* Suspend handler - */ -static void isp1362_suspend(void) -{ -#ifdef DEBUG - ushort mode = isp1362_read_reg16(RD_DcMode); - debug("done, prev mode %#x\n", (uint)mode); -#endif - -#ifdef CONFIG_NSCU - isp1362_timer.expires = jiffies + 10 * HZ; /* 10 seconds after last suspend irq */ - isp1362_timer.data = 1; - add_timer(&isp1362_timer); -#endif - -/* isp1362_write_reg16(WR_DcMode, mode | MODE_GOSUSP); - isp1362_write_reg16(WR_DcMode, mode & ~MODE_GOSUSP);*/ -} - - /* Read endpoint status - */ -ulong isp1362_read_status(ulong ep, ulong dir) -{ - ulong code = ep ? RD_DcEndpointStatus + ep : dir == EP_DIR_IN ? - RD_DcEndpointStatus0_IN : RD_DcEndpointStatus0_OUT; - - return isp1362_read_reg16(code); -} - -static void request_done(struct isp1362_ep* ep, - struct isp1362_request* req, int flag) -{ - if (!list_empty(&req->queue)) - list_del_init(&req->queue); - - req->zlp_sent = 0; - - req->req.status = flag; - req->req.complete(&ep->ep, &req->req); -} - -static int isp1362_ep_enable (struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct isp1362_ep *ep; - u8 ep_flags = EPCONF_FFOSZ_NONISO_64 | EPCONF_FIFOEN; - u32 int_flags; - - ep = container_of (_ep, struct isp1362_ep, ep); - if (!_ep || !desc || ep->desc || _ep->name == ep0name - || desc->bDescriptorType != USB_DT_ENDPOINT - || ep->bEndpointAddress != desc->bEndpointAddress - || ep->fifo_size < le16_to_cpu - (desc->wMaxPacketSize)) { - printk(KERN_WARNING "bad ep or descriptor\n"); - return -EINVAL; - } - - /* xfer types must match, except that interrupt ~= bulk */ - if (ep->bmAttributes != desc->bmAttributes - && ep->bmAttributes != USB_ENDPOINT_XFER_BULK - && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - printk(KERN_WARNING "%s type mismatch\n", _ep->name); - return -EINVAL; - } - - /* Note: should take in account iso eps and other fifo sizes? */ - /*ep_flags |= ep->bEndpointAddress & USB_DIR_IN ? - EPCONF_EPDIR_IN : EPCONF_EPDIR_OUT; - isp1362_write_reg16 (WR_DcEndpointConfiguration + ep_num(ep), ep_flags);*/ - ep_flags = isp1362_read_reg16(RD_DcEndpointConfiguration + ep_num(ep)); - - /*isp1362_write_reg32 (WR_DcInterruptEnable, - (u32)isp1362_read_reg32 (RD_DcInterruptEnable) | - (INT_EP << ep_num(ep)));*/ - int_flags = isp1362_read_reg32 (RD_DcInterruptEnable); - - ep->desc = desc; - - debug("enabled endpoint %s flags %#x int_flags = %#x\n", _ep->name, - (int)ep_flags, int_flags); - - return 0; -} - -static int isp1362_ep_disable (struct usb_ep *_ep) -{ - struct isp1362_ep *ep; - int ep_num; - - ep = container_of (_ep, struct isp1362_ep, ep); - ep_num = ep->bEndpointAddress & ~USB_DIR_IN; - ep->desc = 0; - /* Note: changing of configuration of an ep needs revalidation - * of all enabled eps' buffers. - * See chapter 16.1.1 (remark) of isp1362 Product Data - */ - /*isp1362_write_reg16 (WR_DcEndpointConfiguration + ep_num, 0); - isp1362_write_reg32 (WR_DcInterruptEnable, - isp1362_read_reg32(WR_DcInterruptEnable) & ~(INT_EP << ep_num));*/ - return 0; -} - -static struct usb_request * -isp1362_ep_alloc_request (struct usb_ep *_ep, int gfp_flags) -{ - struct isp1362_request *req; - - req = kmalloc (sizeof *req, gfp_flags); - if (!req) - return 0; - - memset (req, 0, sizeof *req); - INIT_LIST_HEAD (&req->queue); - return &req->req; -} - -static void -isp1362_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) -{ - struct isp1362_request *req; - - req = container_of (_req, struct isp1362_request, req); - /* WARN_ON (!list_empty (&req->queue));*/ - kfree(req); -} - -static void * -isp1362_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes, - dma_addr_t *dma, int gfp_flags) -{ - *dma = -1; /* dma is not supported so far */ - return kmalloc (bytes, gfp_flags); -} - -static void -isp1362_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, - unsigned bytes) -{ - kfree (buf); -} - - /* Returns nonzero if request is completed - */ -static int do_request(struct isp1362_ep* ep, struct isp1362_request* req) -{ - struct isp1362_udc *dev = the_controller; - ulong dir_in = (!ep->bEndpointAddress && dev->ep0dir_in) || - (ep->bEndpointAddress & USB_DIR_IN); - ulong status = isp1362_read_status(ep_num(ep), dir_in? EP_DIR_IN : EP_DIR_OUT); - uint size; - - if (dir_in) { - if (!(status & EPSTAT_EPFULL0)) { - if (req->req.length == req->req.actual) { - if ((!req->req.length || - (req->req.zero && - !(req->req.length % ep->ep.maxpacket))) && - !req->zlp_sent) { - isp1362_send_empty_packet(ep_num(ep)); - req->zlp_sent = 1; - verbose("zlp sent to %s\n", ep->ep.name); - return 0; - } - return 1; - } - - size = min((uint)ep->ep.maxpacket, - req->req.length - req->req.actual); - isp1362_write_buffer(ep_num(ep), - (char*)req->req.buf + req->req.actual, - size); - req->req.actual += size; - } - } else { - if ((status & EPSTAT_EPFULL0)) { - size = isp1362_read_buffer(ep_num(ep), - (char*)req->req.buf + req->req.actual, - req->req.length - req->req.actual); - req->req.actual += size; - if (req->req.length == req->req.actual || - size < ep->ep.maxpacket) { - if (!ep->bEndpointAddress) { - verbose0("sending OUT packet ACK\n"); - isp1362_send_empty_packet(0); - dev->ep0dir_in = 1; - } - return 1; - } - } - } - return 0; -} - -static int -isp1362_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) -{ - struct isp1362_request *req; - struct isp1362_ep *ep; - struct isp1362_udc *dev = the_controller; - unsigned long flags; - - req = container_of(_req, struct isp1362_request, req); - if (unlikely (!_req || !_req->complete || !_req->buf - || !list_empty(&req->queue))) { - printk(KERN_WARNING "bad params _req = %#x complete %#x empty %d\n", - (int)_req, (int)_req->complete, - (int)list_empty(&req->queue)); - return -EINVAL; - } - - ep = container_of(_ep, struct isp1362_ep, ep); - if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { - printk(KERN_WARNING "bad ep\n"); - return -EINVAL; - } - - _req->status = -EINPROGRESS; - _req->actual = 0; - - spin_lock_irqsave(&dev->lock, flags); - - /* kickstart this i/o queue? */ - if (list_empty (&ep->queue)) { - if (do_request(ep, req)) { - spin_unlock_irqrestore(&dev->lock, flags); - verbose("req to %s done\n", _ep->name); - request_done(ep, req, 0); - return 0; - } - } - - list_add_tail(&req->queue, &ep->queue); - verbose("req %#x queued to ep %s, size = %d fn = %d\n", - (int)req, _ep->name, - (int)_req->length, (int)isp1362_frame_number()); - - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -static int isp1362_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct isp1362_request *req; - struct isp1362_ep *ep; - struct isp1362_udc *dev = the_controller; - unsigned long flags; - - req = container_of(_req, struct isp1362_request, req); - debug("req %#x\n", (int)req); - if (unlikely (!_req || !_req->complete || !_req->buf - || !list_empty(&req->queue))) { - debug0("bad params\n"); - return -EINVAL; - } - - ep = container_of(_ep, struct isp1362_ep, ep); - if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { - debug0("bad ep\n"); - return -EINVAL; - } - - spin_lock_irqsave(&dev->lock, flags); - - /* make sure it's still queued on this endpoint */ - list_for_each_entry (req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - if (&req->req != _req) { - spin_unlock_irqrestore (&dev->lock, flags); - return -EINVAL; - } - - request_done(ep, req, -ECONNRESET); - - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -static void set_halt(struct isp1362_ep* ep, int value) -{ - debug("%s %s halt\n", ep->ep.name, value ? "set" : "clear"); - if (value) { - if (ep_num(ep) == 0) - ; /* Note: stall control ep */ - /*ep->dev->protocol_stall = 1;*/ - else - isp1362_stall_endpoint(ep_num(ep), 0); - } else - isp1362_unstall_endpoint(ep_num(ep), 0); -} - -static int isp1362_ep_set_halt(struct usb_ep *_ep, int value) -{ - struct isp1362_ep *ep; - struct isp1362_udc *dev = the_controller; - unsigned long flags; - int retval = 0; - - debug("ep = %s\n", _ep->name); - - ep = container_of(_ep, struct isp1362_ep, ep); - - spin_lock_irqsave(&dev->lock, flags); - - if (!list_empty(&ep->queue)) - retval = -EAGAIN; - else - set_halt(ep, value); - - spin_unlock_irqrestore(&dev->lock, flags); - - return retval; -} - -static struct usb_ep_ops isp1362_ep_ops = { - .enable = isp1362_ep_enable, - .disable = isp1362_ep_disable, - - .alloc_request = isp1362_ep_alloc_request, - .free_request = isp1362_ep_free_request, - - .alloc_buffer = isp1362_ep_alloc_buffer, - .free_buffer = isp1362_ep_free_buffer, - - .queue = isp1362_ep_queue, - .dequeue = isp1362_ep_dequeue, - - .set_halt = isp1362_ep_set_halt, - - /* Unsupported */ - /*.fifo_status = isp1362_ep_fifo_status, - .fifo_flush = isp1362_ep_fifo_flush,*/ -}; - -static int isp1362_udc_get_frame(struct usb_gadget *_gadget) -{ - return isp1362_read_reg16 (RD_DcFrameNumber) & 0x07FF; -} - -static int isp1362_udc_wakeup(struct usb_gadget *_gadget) -{ - /* unimplemented */ - return -ENOSYS; -} - -static const struct usb_gadget_ops isp1362_udc_ops = { - .get_frame = isp1362_udc_get_frame, - .wakeup = isp1362_udc_wakeup, -}; - - /* The allocation of buffer memory - * only takes place after all 16 endpoints - * have been configured in sequence - */ -static void configure_endpoints (void) -{ - int i; - struct isp1362_udc* dev = the_controller; - - isp1362_write_reg16 ( - WR_DcEndpointConfiguration0_OUT, - EPCONF_FFOSZ_NONISO_64 | EPCONF_EPDIR_OUT | EPCONF_FIFOEN); - - isp1362_write_reg16 ( - WR_DcEndpointConfiguration0_IN, - EPCONF_FFOSZ_NONISO_64 | EPCONF_EPDIR_IN | EPCONF_FIFOEN); - - isp1362_write_reg16 ( - WR_DcEndpointConfiguration + 1, - EPCONF_FFOSZ_NONISO_64 | EPCONF_EPDIR_OUT | EPCONF_FIFOEN); - - isp1362_write_reg16 ( - WR_DcEndpointConfiguration + 2, - EPCONF_FFOSZ_NONISO_64 | EPCONF_EPDIR_IN | EPCONF_FIFOEN); - - isp1362_write_reg16 ( - WR_DcEndpointConfiguration + 3, - EPCONF_FFOSZ_NONISO_8 | EPCONF_EPDIR_IN | EPCONF_FIFOEN); - - for (i = 4; i <= 14; i++) - { - isp1362_write_reg16 (WR_DcEndpointConfiguration + i, 0); - } - - /* device/ep0 records init */ - INIT_LIST_HEAD (&dev->gadget.ep_list); - INIT_LIST_HEAD (&dev->gadget.ep0->ep_list); - - /* basic endpoint records init */ - for (i = 0; i < ISP1362_UDC_NUM_ENDPOINTS; i++) { - struct isp1362_ep *ep = &dev->ep[i]; - - if (!ep->ep.maxpacket) - continue; - - if (i != 0) - list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); - - ep->desc = 0; - INIT_LIST_HEAD (&ep->queue); - } -} - -static int start_udc( void ) -{ - isp1362_write_reg16 ( - WR_DcHardwareConfiguration, - HWCONF_CLKRUN | HWCONF_CKDIV_12MHZ); - - isp1362_write_reg32 ( - WR_DcInterruptEnable, - INT_RST | INT_RESM | INT_SUSP | INT_EOT | - /*INT_SOF |*/ /*INT_PSOF |*/ INT_SP_EOT | - INT_EP0_OUT | INT_EP0_IN | (INT_EP << 1) | (INT_EP << 2) | - (INT_EP << 3)); - - verbose("interrupt status %02lx \n", isp1362_read_reg32 (RD_DcInterrupt)); - isp1362_set_address(0); - - isp1362_write_reg16 (WR_DcMode, MODE_SOFTCT | MODE_INTENA/* | MODE_DBGMOD*/); - - return 0; -} - -static void reset_ep(struct isp1362_ep* ep) -{ - struct isp1362_request* req; - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct isp1362_request, queue); - request_done(ep, req, -ESHUTDOWN); - } -} - - /* Reset handler - */ -static void reset_udc(struct isp1362_udc* dev) -{ - struct isp1362_ep* ep; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* Stop pending IO - */ - reset_ep(&dev->ep[0]); - list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) { - reset_ep(ep); - } - - if (dev->driver) - dev->driver->disconnect(&dev->gadget); - - spin_unlock_irqrestore (&dev->lock, flags); - - configure_endpoints(); - start_udc(); -} - -/* when a driver is successfully registered, it will receive - * control requests including set_configuration(), which enables - * non-control requests. then usb traffic follows until a - * disconnect is reported. then a host may connect again, or - * the driver might get unbound. - */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct isp1362_udc *dev = the_controller; - int retval; - - if (!driver - || driver->speed != USB_SPEED_FULL - || !driver->bind - || !driver->unbind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - - /* - * We need to configure the endpoints _before_ we call the bind - * function. This is needed for the ether.c driver from 2.4.30er - * kernel. - */ - configure_endpoints(); - - /* first hook up the driver ... */ - dev->driver = driver; - - retval = driver->bind(&dev->gadget); - if (retval) { - debug("bind to driver %s --> error %d\n", - driver->driver.name, retval); - dev->driver = 0; - return retval; - } - - /* ... then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. - * NOTE: this shouldn't power up until later. - */ - start_udc(); - - debug("registered gadget driver '%s'\n", driver->driver.name); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - -int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) -{ - struct isp1362_udc *dev = the_controller; - unsigned long flags; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver) - return -EINVAL; - - spin_lock_irqsave (&dev->lock, flags); - /*stop_activity (dev, driver);*/ - isp1362_reset_device(); - spin_unlock_irqrestore (&dev->lock, flags); - - driver->unbind (&dev->gadget); - dev->driver = 0; - - debug ("unregistered driver '%s'\n", driver->driver.name); - return 0; -} -EXPORT_SYMBOL (usb_gadget_unregister_driver); - - /* Get Status request handler - */ -static void isp1362_get_status(struct usb_ctrlrequest * req) -{ - unsigned char status_buf[2] = { 0, 0 }; - int rc = 0; - int n; - - /* return status bit flags */ - n = request_target(req->bRequestType); - switch (n) { - case USB_RECIP_DEVICE: - if (0) /* self_powered */ - status_buf[0] |= 1; - break; - case USB_RECIP_INTERFACE: - break; - case USB_RECIP_ENDPOINT: - /* return stalled bit */ - n = windex_to_ep_num(__le16_to_cpu(req->wIndex)); - if (isp1362_check_status(n, 0) & EPSTAT_EPSTAL) { - status_buf[0] |= 1; - } - break; - default: - printk("isp1362: Unknown target (%d) in GET_STATUS\n", n); - break; - } - - rc = isp1362_setup_data_send(status_buf, - __le16_to_cpu(req->wLength), - sizeof(status_buf)); - if (rc) { - printk("isp1362: Get Status failed. Stall.\n"); - isp1362_cnt_err_setup++; - isp1362_stall_endpoint(0, EP_DIR_IN); - } -} - - /* Endpoint 0 OUT interrupt handler - */ -static void isp1362_ep0_out_int_hndlr (void) -{ - struct isp1362_udc *dev = the_controller; - u8 status = isp1362_read_status (0, EP_DIR_OUT); - struct usb_ctrlrequest req; - ulong res; - - verbose("EP0 OUT status: %02X\n", (uint)status); - - if (dev->gadget.speed == USB_SPEED_UNKNOWN) - { - dev->gadget.speed = USB_SPEED_FULL; - } - - if (!(status & EPSTAT_SETUPT)) - { -#if 0 - dev->ep0dir_in = 0; -#endif - isp1362_ep_int_hndlr(&dev->ep[0]); - goto Done; - } - -#if 0 - isp1362_read_status (0, EP_DIR_OUT); -#endif - - res = isp1362_read_buffer (0, &req, sizeof(req)); - if (res != sizeof(req)) - { - printk ("isp1362: Invalid SETUP size\n"); - isp1362_cnt_err_setup++; - isp1362_stall_endpoint (0, EP_DIR_IN); - goto Done; - } - - le16_to_cpus (&req.wValue); - le16_to_cpus (&req.wIndex); - le16_to_cpus (&req.wLength); - -#ifdef VERBOSE - { - unsigned char * pdb = (unsigned char *) &req; - verbose ("query: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - pdb[0], pdb[1], pdb[2], pdb[3], - pdb[4], pdb[5], pdb[6], pdb[7]); - isp1362_print_request( &req ); - } -#endif - - dev->ep0dir_in = (req.bRequestType & USB_DIR_IN) || !req.wLength; - - if ((req.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) { - res = dev->driver->setup(&dev->gadget, &req); - if (res < 0) { - debug("isp1362: gadget failed to process req, err %i\n", (int)res); - } - return; - } - - /* Handle it */ - switch (req.bRequest) - { - - /* This first bunch have no data phase */ - - case USB_REQ_SET_ADDRESS: - isp1362_set_address(req.wValue & 0x7F); - isp1362_send_empty_packet (0); - break; - - case USB_REQ_CLEAR_FEATURE: - case USB_REQ_SET_FEATURE: - if ( req.wValue == 0 ) { /* setting ENDPOINT_HALT/STALL */ - int ep = windex_to_ep_num(req.wValue); - set_halt(&dev->ep[ep], req.bRequest == USB_REQ_SET_FEATURE); - } - else { - isp1362_cnt_err_setup++; - debug( "isp1362: Unsupported feature selector " - "(%d) in set feature\n", req.wValue); - } - isp1362_send_empty_packet (0); - break; - - case USB_REQ_GET_STATUS: - isp1362_get_status (&req); - break; - - default : - res = dev->driver->setup(&dev->gadget, &req); - if (res < 0) { - debug("isp1362: Failed to change config, err %i\n", (int)res); - } - break; - } - -Done: - return; -} - -static void isp1362_ep_int_hndlr(struct isp1362_ep* ep) -{ - struct isp1362_request* req; - unsigned long flags; - struct isp1362_udc* dev = the_controller; - -again: - spin_lock_irqsave(&dev->lock, flags); - - if (list_empty(&ep->queue)) { - /*verbose("queue empty, status %#x\n", - (int)isp1362_read_status(ep_num(ep), - dev->ep0dir_in ? EP_DIR_IN : EP_DIR_OUT));*/ - isp1362_read_status(ep_num(ep), dev->ep0dir_in ? EP_DIR_IN : EP_DIR_OUT); - spin_unlock_irqrestore(&dev->lock, flags); - return; - } - - req = list_entry(ep->queue.next, struct isp1362_request, queue); - - if (do_request(ep, req)) { - /* Some upper drivers queue the same request - * in their completion routine, so we must - * clean up our portion of request data and - * unlock before signaling about completion. - */ - spin_unlock_irqrestore(&dev->lock, flags); - verbose("req %#x to %s done dir %ud\n", (int)req, ep->ep.name, dev->ep0dir_in); - request_done(ep, req, 0); - if ((ep->bEndpointAddress & USB_DIR_IN) || - (!ep->bEndpointAddress && dev->ep0dir_in)) - goto again; - return; - } - - /*verbose("req %#x to %s remains %d fn %d\n", (int)req, ep->ep.name, - req->req.length-req->req.actual, (int)isp1362_frame_number());*/ - spin_unlock_irqrestore(&dev->lock, flags); -} - - /* ISP1362 DC interrupt handler - */ -static void isp1362_int_hndlr(int irq, void *dev_id, struct pt_regs *regs) -{ - ulong status = isp1362_read_reg32 (RD_DcInterrupt); - struct isp1362_udc* dev = the_controller; - - if (!status) - return; - -#ifdef CONFIG_NSCU - /* stop a running timer */ - if (isp1362_timer.data) { - del_timer_sync(&isp1362_timer); - } -#endif - - isp1362_cnt_int++; - - verbose ("[%lu] DC INTERRUPT: %08X\n", - isp1362_cnt_int, (uint)status); - - if (status & INT_RST) { - isp1362_cnt_reset++; - reset_udc(dev); - return; - } - - if (status & INT_RESM) { - isp1362_cnt_resume++; - isp1362_resume (); - } - - if (status & INT_SUSP) { - isp1362_cnt_suspend++; - isp1362_suspend (); - } - - if (status & INT_EP_ALL) { - int cur_ep; - for (cur_ep = 0; cur_ep < ISP1362_UDC_NUM_ENDPOINTS; cur_ep++) - if (status & (INT_EP << cur_ep)) - isp1362_ep_int_hndlr(&dev->ep[cur_ep]); - } - - if (status & INT_EP0_OUT) { - isp1362_ep0_out_int_hndlr (); - } -} - -static struct isp1362_udc memory = { - .gadget = { - .ops = &isp1362_udc_ops, - .ep0 = &memory.ep[0].ep, - .name = driver_name, - .dev = { - .bus_id = "gadget", - }, - }, - - .ep = { - /* control endpoint */ - /*.ep[0] =*/ { - .ep = { - .name = ep0name, - .ops = &isp1362_ep_ops, - .maxpacket = EP0_FIFO_SIZE, - }, - .dev = &memory, - }, - - /* first group of endpoints */ - /*.ep[1] =*/ { - .ep = { - .name = "ep1out-bulk", - .ops = &isp1362_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = 1, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - }, - /*.ep[2] =*/ { - .ep = { - .name = "ep2in-bulk", - .ops = &isp1362_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 2, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - }, - /*.ep[3] =*/ { - .ep = { - .name = "ep3in-int", - .ops = &isp1362_ep_ops, - .maxpacket = 8, - }, - .dev = &memory, - .fifo_size = 8, - .bEndpointAddress = USB_DIR_IN | 3, - .bmAttributes = USB_ENDPOINT_XFER_INT, - } - - } -}; - -int __init isp1362_init( void ) -{ - int retval = 0; - ushort chip_id; - -#ifdef CONFIG_NSCU - volatile immap_t *immr; - volatile cpm8xx_t *cp; - - immr = (immap_t*)IMAP_ADDR; - cp = (cpm8xx_t*)&immr->im_cpm; - - cp->cp_pbpar &= ~ISP1362_RESET; - cp->cp_pbdir |= ISP1362_RESET; - cp->cp_pbodr &= ~ISP1362_RESET; - cp->cp_pbdat |= ISP1362_RESET; - - /* - * init the timer used for restart upon burst hangup - */ - init_timer(&isp1362_timer); - isp1362_timer.data = 0; - isp1362_timer.function = isp1362_timer_func; -#endif - -#if CONFIG_PROC_FS - devfs_handle = devfs_register(NULL, DEBUG_DEVNAME, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, - &debug_fops, &debug_dev); - - memset(&debug_dev, 0, sizeof(debug_dev_t)); - - debug_proc_dir = proc_mkdir(DEBUG_DEVNAME, NULL); - if (debug_proc_dir == NULL) { - printk(KERN_ERR "debug: Unable to create /proc/%s entry\n", DEBUG_DEVNAME); - return -ENOMEM; - } - - debug_proc_usb_dir = create_proc_entry(DEBUG_USB_DIR, 0644, debug_proc_dir); - if (debug_proc_usb_dir == NULL) { - printk(KERN_ERR "DEBUG: Unable to create /proc/%s/%s entry\n", DEBUG_DEVNAME, DEBUG_USB_DIR); - remove_proc_entry("debug", NULL); - return -ENOMEM; - } - debug_proc_usb_dir->read_proc = isp1362_read_proc; - debug_proc_usb_dir->write_proc = isp1362_write_proc; -#endif - - isp1362_io_base = ioremap(ISP1362_IO_PHYS, PAGE_SIZE); - - chip_id = isp1362_chip_id (); - if (chip_id != 0x3630) - { - printk ("isp1362: Invalid chip identification, %#x\n", chip_id); - return -1; - } - - isp1362_reset_device(); - - retval = request_8xxirq(ISP1362_IRQ_DC, isp1362_int_hndlr, 0, - "ISP1362 DC", NULL); - if (retval) { - printk("isp1362: Couldn't request USB irq rc=%d\n", retval); - iounmap((void *)isp1362_io_base); - return retval; - } - - the_controller = &memory; - - printk( "ISP1362 USB Controller Core Initialized\n"); - return 0; -} -module_init( isp1362_init ); - -void __exit isp1362_exit( void ) -{ - printk("Unloading ISP1362 USB Controller\n"); - -#if CONFIG_PROC_FS - devfs_unregister(devfs_handle); - - remove_proc_entry(DEBUG_USB_DIR, debug_proc_usb_dir); - remove_proc_entry(DEBUG_DEVNAME, NULL); - - remove_proc_entry (PROC_SUSPEND_NAME, NULL); -#endif - - free_irq(ISP1362_IRQ_DC, NULL); - - iounmap((void *)isp1362_io_base); -} -module_exit( isp1362_exit ); - -MODULE_DESCRIPTION (DRIVER_DESC); -MODULE_AUTHOR ("Wolfgang Denk, DENX Software Engineering"); -MODULE_LICENSE ("GPL"); diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/isp1362gapi.h linuxppc_2_4_devel.modified/drivers/usb/gadget/isp1362gapi.h --- linuxppc_2_4_devel/drivers/usb/gadget/isp1362gapi.h 2004-04-12 20:02:33.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/isp1362gapi.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,244 +0,0 @@ - -#ifndef __ISP1362GAPI_H -#define __ISP1362GAPI_H - -/*================================================ - * ISP1362 Device Controller interface - */ - -#define ISP1362_IO_PHYS 0xD0000000 - -#define ISP1362_IRQ_HC 6 -#define ISP1362_IRQ_DC 8 - -/* #define DEBUG */ - -#define EP_DIR_IN 1 -#define EP_DIR_OUT 0 - - /* Initialization commands - */ -#define WR_DcEndpointConfiguration0_OUT 0x20 -#define WR_DcEndpointConfiguration0_IN 0x21 -#define WR_DcEndpointConfiguration 0x21 /* 1..14 */ - -#define RD_DcEndpointConfiguration0_OUT 0x30 -#define RD_DcEndpointConfiguration0_IN 0x31 -#define RD_DcEndpointConfiguration 0x31 /* 1..14 */ - -#define WR_DcAddress 0xB6 -#define RD_DcAddress 0xB7 - -#define WR_DcMode 0xB8 -#define RD_DcMode 0xB9 - -#define WR_DcHardwareConfiguration 0xBA -#define RD_DcHardwareConfiguration 0xBB - -#define WR_DcInterruptEnable 0xC2 -#define RD_DcInterruptEnable 0xC3 - -#define WR_DcDMAConfiguration 0xF0 -#define RD_DcDMAConfiguration 0xF1 - -#define WR_DcDMACounter 0xF2 -#define RD_DcDMACounter 0xF3 - -#define DO_ResetDevice 0xF6 - - /* Data flow commands - */ -#define DO_WriteEndpointBuffer0 0x01 -#define DO_WriteEndpointBuffer 0x01 /* 1..14 */ - -#define DO_ReadEndpointBuffer0 0x10 -#define DO_ReadEndpointBuffer 0x11 /* 1..14 */ - -#define DO_StallEndpoint0_OUT 0x40 -#define DO_StallEndpoint0_IN 0x41 -#define DO_StallEndpoint 0x41 /* 1..14 */ - -#define RD_DcEndpointStatus0_OUT 0x50 -#define RD_DcEndpointStatus0_IN 0x51 -#define RD_DcEndpointStatus 0x51 /* 1..14 */ - -#define DO_ValidateEndpointBuffer0 0x61 -#define DO_ValidateEndpointBuffer 0x61 /* 1..14 */ - -#define DO_ClearEndpointBuffer0 0x70 -#define DO_ClearEndpointBuffer 0x71 /* 1..14 */ - -#define DO_UnstallEndpoint0_OUT 0x80 -#define DO_UnstallEndpoint0_IN 0x81 -#define DO_UnstallEndpoint 0x81 /* 1..14 */ - -#define RD_DcEndpointStatusImage0_OUT 0xD0 -#define RD_DcEndpointStatusImage0_IN 0xD1 -#define RD_DcEndpointStatusImage 0xD1 /* 1..14 */ - -#define DO_AcknowledgeSetup 0xF4 - - /* General commands - */ -#define RD_DcErrorCode0_OUT 0xA0 -#define RD_DcErrorCode0_IN 0xA1 -#define RD_DcErrorCode 0xA1 /* 1..14 */ - -#define WR_UnlockDevice 0xB0 - -#define WR_DcScratch 0xB2 -#define RD_DcScratch 0xB3 - -#define RD_DcFrameNumber 0xB4 - -#define RD_DcChipID 0xB5 - -#define RD_DcInterrupt 0xC0 - - /* DcEndpointConfiguration register: bit allocation - */ -#define EPCONF_FFOSZ_MASK 0x0F -#define EPCONF_FFOSZ_NONISO_8 0x00 -#define EPCONF_FFOSZ_NONISO_16 0x01 -#define EPCONF_FFOSZ_NONISO_32 0x02 -#define EPCONF_FFOSZ_NONISO_64 0x03 -#define EPCONF_FFOSZ_ISO_16 0x00 -#define EPCONF_FFOSZ_ISO_32 0x01 -#define EPCONF_FFOSZ_ISO_48 0x02 -#define EPCONF_FFOSZ_ISO_64 0x03 -#define EPCONF_FFOSZ_ISO_96 0x04 -#define EPCONF_FFOSZ_ISO_128 0x05 -#define EPCONF_FFOSZ_ISO_160 0x06 -#define EPCONF_FFOSZ_ISO_192 0x07 -#define EPCONF_FFOSZ_ISO_256 0x08 -#define EPCONF_FFOSZ_ISO_320 0x09 -#define EPCONF_FFOSZ_ISO_384 0x0a -#define EPCONF_FFOSZ_ISO_512 0x0b -#define EPCONF_FFOSZ_ISO_640 0x0c -#define EPCONF_FFOSZ_ISO_768 0x0d -#define EPCONF_FFOSZ_ISO_896 0x0e -#define EPCONF_FFOSZ_ISO_1023 0x0f - -#define EPCONF_FFOISO 0x10 -#define EPCONF_DBLBUF 0x20 -#define EPCONF_EPDIR_IN 0x40 -#define EPCONF_EPDIR_OUT 0x00 -#define EPCONF_FIFOEN 0x80 - - /* DcMode register: bit allocation - */ -#define MODE_SOFTCT 0x01 -#define MODE_DBGMOD 0x04 -#define MODE_INTENA 0x08 -#define MODE_GOSUSP 0x20 - - /* DcHardwareConfiguration register: bit allocation - */ -#define HWCONF_INTPOL 0x0001 -#define HWCONF_INTLVL 0x0002 -#define HWCONF_WKUPCS 0x0008 -#define HWCONF_DAKPOL 0x0020 -#define HWCONF_DRQPOL 0x0040 -#define HWCONF_DAKOLY 0x0080 -#define HWCONF_CKDIV_MASK 0x0F00 -#define HWCONF_CKDIV_12MHZ 0x0300 -#define HWCONF_CLKRUN 0x1000 -#define HWCONF_NOLAZY 0x2000 -#define HWCONF_EXTPUL 0x4000 - - /* DcInterruptEnable/DcInterrupt registers: bit allocation - */ -#define INT_RST 0x00000001 -#define INT_RESM 0x00000002 -#define INT_SUSP 0x00000004 -#define INT_EOT 0x00000008 -#define INT_SOF 0x00000010 -#define INT_PSOF 0x00000020 -#define INT_SP_EOT 0x00000040 -#define INT_EP0_OUT 0x00000100 -#define INT_EP0_IN 0x00000200 -#define INT_EP 0x00000200 /* 1..14 */ -#define INT_EP_ALL 0x00FFFE00 - - /* DcEndpointStatus register: bit allocation - */ -#define EPSTAT_CPUBUF 0x02 -#define EPSTAT_SETUPT 0x04 -#define EPSTAT_OVERWRITE 0x08 -#define EPSTAT_DATA_PID 0x10 -#define EPSTAT_EPFULL0 0x20 -#define EPSTAT_EPFULL1 0x40 -#define EPSTAT_EPSTAL 0x80 - - /* DcErrorCode register: bit allocation - */ -#define EPERR_RTOK 0x01 -#define EPERR_ERR_MASK 0x1E -#define EPERR_ERR_PID_ENC 0x02 -#define EPERR_ERR_PID_UNKNOWN 0x04 -#define EPERR_ERR_UNEXP_PACKET 0x06 -#define EPERR_ERR_TOKEN_CRC 0x08 -#define EPERR_ERR_DATA_CRC 0x0A -#define EPERR_ERR_TIMEOUT 0x0C -#define EPERR_ERR_BABBLE 0x0E -#define EPERR_ERR_UNEXP_EOP 0x10 -#define EPERR_ERR_NAK 0x12 -#define EPERR_ERR_STALL 0x14 -#define EPERR_ERR_OVERFLOW 0x16 -#define EPERR_ERR_EMPTY_PACKET 0x18 -#define EPERR_ERR_BIT_STUFF 0x1A -#define EPERR_ERR_SYNC 0x1C -#define EPERR_ERR_WRONG_TOGGLE 0x1E -#define EPERR_DATA01 0x40 -#define EPERR_UNREAD 0x80 - -#define ISP1362_UDC_NUM_ENDPOINTS 15 - -#define BULK_FIFO_SIZE 64 -#define EP0_FIFO_SIZE 64 - -struct isp1362_udc; - -struct isp1362_request { - struct usb_request req; - struct list_head queue; - unsigned zlp_sent; -}; - -struct isp1362_ep { - struct usb_ep ep; - struct isp1362_udc *dev; - - const struct usb_endpoint_descriptor *desc; - struct list_head queue; - - unsigned short fifo_size; - u8 bEndpointAddress; - u8 bmAttributes; -}; - -struct isp1362_udc { - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - - spinlock_t lock; - - struct isp1362_ep ep [ISP1362_UDC_NUM_ENDPOINTS]; - unsigned ep0dir_in; -}; - -#ifndef container_of -#define container_of list_entry -#endif - -/* Data extraction from usb_request_t fields */ -static inline int request_target( __u8 b ) { return (int) ( b & 0x0F); } - -static inline int windex_to_ep_num( __u16 w ) { return (int) ( w & 0x000F); } - -static inline int ep_num(struct isp1362_ep* ep) -{ - return ep->bEndpointAddress & ~USB_DIR_IN; -} - -#endif diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/ndis.h linuxppc_2_4_devel.modified/drivers/usb/gadget/ndis.h --- linuxppc_2_4_devel/drivers/usb/gadget/ndis.h 2004-04-12 20:02:33.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/ndis.h 2006-03-31 14:46:58.000000000 +0200 @@ -26,11 +26,41 @@ #define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A #define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B +enum NDIS_DEVICE_POWER_STATE { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3, + NdisDeviceStateMaximum +}; + +struct NDIS_PM_WAKE_UP_CAPABILITIES { + enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; + enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; + enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; +}; + /* NDIS_PNP_CAPABILITIES.Flags constants */ #define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 #define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 #define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 +struct NDIS_PNP_CAPABILITIES { + u32 Flags; + struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; +}; + +struct NDIS_PM_PACKET_PATTERN { + u32 Priority; + u32 Reserved; + u32 MaskSize; + u32 PatternOffset; + u32 PatternSize; + u32 PatternFlags; +}; + + /* Required Object IDs (OIDs) */ #define OID_GEN_SUPPORTED_LIST 0x00010101 #define OID_GEN_HARDWARE_STATUS 0x00010102 diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/net2280.c linuxppc_2_4_devel.modified/drivers/usb/gadget/net2280.c --- linuxppc_2_4_devel/drivers/usb/gadget/net2280.c 2004-03-11 23:44:07.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/net2280.c 2006-08-14 09:16:25.000000000 +0200 @@ -44,8 +44,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#undef DEBUG /* messages on error and most fault paths */ -#undef VERBOSE /* extra debug messages (success too) */ +#define DEBUG 1 /* messages on error and most fault paths */ +#define VERBOSE 1 /* extra debug messages (success too) */ #include #include @@ -71,15 +71,20 @@ #include #include +#include +#ifdef CONFIG_USB_GADGET_NET2282 +#define DRIVER_DESC "NetChip 2282 USB Peripheral Controller" +#else #define DRIVER_DESC "NetChip 2280 USB Peripheral Controller" -#define DRIVER_VERSION "2004 Jan 14" +#endif + +#define DRIVER_VERSION "2005 Sept 27" #define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ -#define USE_RDK_LEDS /* GPIO pins control three LEDs */ - +#undef USE_RDK_LEDS /* GPIO pins control three LEDs */ static const char driver_name [] = "net2280"; static const char driver_desc [] = DRIVER_DESC; @@ -100,7 +105,7 @@ * These two parameters let you use PIO or more aggressive DMA. */ static int use_dma = 1; -static int use_dma_chaining = 0; +static int use_dma_chaining = 1; MODULE_PARM (use_dma, "i"); MODULE_PARM_DESC (use_dma, "true to use dma controllers"); @@ -108,7 +113,6 @@ MODULE_PARM (use_dma_chaining, "i"); MODULE_PARM_DESC (use_dma_chaining, "true to use dma descriptor queues"); - /* mode 0 == ep-{a,b,c,d} 1K fifo each * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable @@ -116,7 +120,11 @@ static ushort fifo_mode = 0; MODULE_PARM (fifo_mode, "h"); +#ifdef CONFIG_USB_GADGET_NET2282 +MODULE_PARM_DESC (fifo_mode, "net2282 fifo mode"); +#else MODULE_PARM_DESC (fifo_mode, "net2280 fifo mode"); +#endif #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") @@ -216,6 +224,11 @@ ep->is_in = (tmp & USB_DIR_IN) != 0; if (!ep->is_in) writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); + else // Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 + { + writel ((1 << CLEAR_NAK_OUT_PACKETS) + | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); + } writel (tmp, &ep->regs->ep_cfg); @@ -307,7 +320,9 @@ /* init to our chosen defaults, notably so that we NAK OUT * packets until the driver queues a read (+note erratum 0112) */ - writel ( (1 << SET_NAK_OUT_PACKETS_MODE) + if (!ep->is_in) + { + writel ( (1 << SET_NAK_OUT_PACKETS_MODE) | (1 << SET_NAK_OUT_PACKETS) | (1 << CLEAR_EP_HIDE_STATUS_PHASE) | (1 << CLEAR_INTERRUPT_MODE) @@ -315,6 +330,18 @@ | (1 << CLEAR_ENDPOINT_TOGGLE) | (1 << CLEAR_ENDPOINT_HALT) , &ep->regs->ep_rsp); + } + else // added for 2282 + { + writel ( (1 << CLEAR_NAK_OUT_PACKETS_MODE) + | (1 << CLEAR_NAK_OUT_PACKETS) + | (1 << CLEAR_EP_HIDE_STATUS_PHASE) + | (1 << CLEAR_INTERRUPT_MODE) + | (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) + | (1 << CLEAR_ENDPOINT_TOGGLE) + | (1 << CLEAR_ENDPOINT_HALT) + , &ep->regs->ep_rsp); + } /* scrub most status bits, and flush any fifo state */ writel ( (1 << TIMEOUT) @@ -537,7 +564,10 @@ } /* write just one packet at a time */ - count = min (ep->ep.maxpacket, total); + count = ep->ep.maxpacket; + if (count > total) /* min() cannot be used on a bitfield */ + count = total; + VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n", ep->ep.name, count, (count != ep->ep.maxpacket) ? " (short)" : "", @@ -1058,9 +1088,36 @@ * 0122, and 0124; not all cases trigger the warning. */ if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { - WARN (ep->dev, "%s lost packet sync!\n", + // As a test see if we are waiting for the dma to complete + tmp = readl (&ep->regs->ep_avail); + if (tmp == 0) + { + WARN (ep->dev, "%s lost packet sync!\n", ep->ep.name); - req->req.status = -EOVERFLOW; + req->req.status = -EOVERFLOW; + } + else + { + // wait for dma to complete, see 2282 section 8.4 + int i; + for (i = 0; i < 10; i++) + { + udelay(1); + tmp = readl (&ep->regs->ep_avail); + if (tmp == 0) + { + tmp = readl (&ep->dma->dmacount) & DMA_BYTE_COUNT_MASK; + printk("Test shows interrupt called before dma complete!\n"); + break; + } + } + if (tmp > 0) + { + WARN (ep->dev, "DMA didn't complete data left in ep %s!\n", + ep->ep.name); + req->req.status = -EOVERFLOW; + } + } // end 2282 test code } else if ((tmp = readl (&ep->regs->ep_avail)) != 0) { /* fifo gets flushed later */ ep->out_overflow = 1; @@ -2056,8 +2113,11 @@ VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", ep->ep.name, t, req ? &req->req : 0); #endif - writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); - + if (!ep->is_in) + writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); + else // Added for 2282 + writel (t, &ep->regs->ep_stat); + /* for ep0, monitor token irqs to catch data stage length errors * and to synchronize on status. * @@ -2160,6 +2220,7 @@ if (likely (req != 0)) { req->td->dmacount = 0; t = readl (&ep->regs->ep_avail); + // short packet completion happening here? dma_done (ep, req, count, t); } @@ -2191,7 +2252,8 @@ unsigned len; len = req->req.length - req->req.actual; - len = min (ep->ep.maxpacket, len); + if (len > ep->ep.maxpacket) + len = ep->ep.maxpacket; req->req.actual += len; /* if we wrote it all, we're usually done */ @@ -2524,6 +2586,9 @@ /* some status we can just ignore */ stat &= ~((1 << CONTROL_STATUS_INTERRUPT) | (1 << RESUME_INTERRUPT) +#ifdef CONFIG_USB_GADGET_NET2282 + | (1 << SOF_DOWNCOUNT_INTERRUPT) +#endif | (1 << SOF_INTERRUPT)); if (!stat) return; @@ -2718,6 +2783,7 @@ spin_lock_init (&dev->lock); dev->pdev = pdev; dev->gadget.ops = &net2280_ops; + dev->gadget.is_dualspeed = 1; dev->gadget.dev.bus_id = pdev->slot_name; dev->gadget.name = driver_name; @@ -2760,18 +2826,18 @@ usb_reinit (dev); /* irq setup after old hardware is cleaned up */ - if (!pdev->irq) { - ERROR (dev, "No IRQ. Check PCI setup!\n"); - retval = -ENODEV; - goto done; - } +// if (!pdev->irq) { +// ERROR (dev, "No IRQ. Check PCI setup!\n"); +// retval = -ENODEV; +// goto done; +// } #ifndef __sparc__ snprintf (buf, sizeof buf, "%d", pdev->irq); bufp = buf; #else bufp = __irq_itoa(pdev->irq); #endif - if (request_irq (pdev->irq, net2280_irq, SA_SHIRQ, driver_name, dev) + if (request_irq (MPC5xxx_IRQ0, net2280_irq, SA_SHIRQ, driver_name, dev) != 0) { ERROR (dev, "request interrupt %s failed\n", bufp); retval = -EBUSY; @@ -2846,7 +2912,11 @@ .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), .class_mask = ~0, .vendor = 0x17cc, +#ifdef CONFIG_USB_GADGET_NET2282 + .device = 0x2282, +#else .device = 0x2280, +#endif .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/net2280.h linuxppc_2_4_devel.modified/drivers/usb/gadget/net2280.h --- linuxppc_2_4_devel/drivers/usb/gadget/net2280.h 2004-03-11 23:44:07.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/net2280.h 2006-05-26 12:46:29.000000000 +0200 @@ -179,6 +179,7 @@ #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 #define PCI_RETRY_ABORT_INTERRUPT 17 #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 +#define SOF_DOWNCOUNT_INTERRUPT 14 #define GPIO_INTERRUPT 13 #define DMA_D_INTERRUPT 12 #define DMA_C_INTERRUPT 11 @@ -346,6 +347,7 @@ #define DMA_ENABLE 1 #define DMA_ADDRESS_HOLD 0 u32 dmastat; +#define DMA_ABORT_DONE_INTERRUPT 27 // added for 2282 #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 #define DMA_TRANSACTION_DONE_INTERRUPT 24 #define DMA_ABORT 1 @@ -357,6 +359,7 @@ #define DMA_DIRECTION 30 #define DMA_DONE_INTERRUPT_ENABLE 29 #define END_OF_CHAIN 28 +#define DMA_OUT_CONTINUE 24 #define DMA_BYTE_COUNT_MASK ((1<<24)-1) #define DMA_BYTE_COUNT 0 u32 dmaaddr; @@ -656,6 +659,7 @@ #define net2280_led_init(dev) do { } while (0) #define net2280_led_speed(dev, speed) do { } while (0) #define net2280_led_shutdown(dev) do { } while (0) +#define net2280_led_active(dev, is_active) do { } while (0) #endif diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/rndis.c linuxppc_2_4_devel.modified/drivers/usb/gadget/rndis.c --- linuxppc_2_4_devel/drivers/usb/gadget/rndis.c 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/rndis.c 2006-05-24 18:06:25.000000000 +0200 @@ -1,21 +1,21 @@ -/* +/* * RNDIS MSG parser - * + * * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $ - * + * * Authors: Benedikt Spranger, Pengutronix * Robert Schwebel, Pengutronix - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * + * version 2, as published by the Free Software Foundation. + * * This software was originally developed in conformance with * Microsoft's Remote NDIS Specification License Agreement. - * + * * 03/12/2004 Kai-Uwe Bloem * Fixed message length bug in init_response - * + * * 03/25/2004 Kai-Uwe Bloem * Fixed rndis_rm_hdr length bug. * @@ -40,7 +40,7 @@ #undef RNDIS_PM -#undef VERBOSE +#define VERBOSE #include "rndis.h" @@ -81,7 +81,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf); static int rndis_set_response (int configNr, rndis_set_msg_type *buf); static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf); -static int rndis_keepalive_response (int configNr, +static int rndis_keepalive_response (int configNr, rndis_keepalive_msg_type *buf); static rndis_resp_t *rndis_add_response (int configNr, u32 length); @@ -95,16 +95,12 @@ u32 *tmp; int i, count; rndis_query_cmplt_type *resp; -#ifdef CONFIG_NSCU - bd_t *bd = (bd_t *)__res; - unsigned long addr; -#endif if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - + switch (OID) { /* general oids (table 4-1) */ @@ -119,21 +115,21 @@ tmp[i] = cpu_to_le32 (oid_supported_list[i]); retval = 0; break; - + /* mandatory */ case OID_GEN_HARDWARE_STATUS: DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); length = 4; - /* Bogus question! + /* Bogus question! * Hardware must be ready to recieve high level protocols. - * BTW: + * BTW: * reddite ergo quae sunt Caesaris Caesari * et quae sunt Dei Deo! */ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - + /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); @@ -142,7 +138,7 @@ rndis_per_dev_params [configNr].medium); retval = 0; break; - + /* mandatory */ case OID_GEN_MEDIA_IN_USE: DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); @@ -152,7 +148,7 @@ rndis_per_dev_params [configNr].medium); retval = 0; break; - + /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); @@ -166,7 +162,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_LINK_SPEED: DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); @@ -190,7 +186,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); @@ -201,7 +197,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_VENDOR_ID: DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); @@ -210,12 +206,12 @@ rndis_per_dev_params [configNr].vendorID); retval = 0; break; - + /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); length = strlen (rndis_per_dev_params [configNr].vendorDescr); - memcpy ((u8 *) resp + 24, + memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].vendorDescr, length); retval = 0; break; @@ -284,7 +280,7 @@ if (rndis_per_dev_params [configNr].stats) { length = 4; *((u32 *) resp + 6) = cpu_to_le32 ( - rndis_per_dev_params [configNr].stats->tx_packets - + rndis_per_dev_params [configNr].stats->tx_packets - rndis_per_dev_params [configNr].stats->tx_errors - rndis_per_dev_params [configNr].stats->tx_dropped); retval = 0; @@ -300,7 +296,7 @@ if (rndis_per_dev_params [configNr].stats) { length = 4; *((u32 *) resp + 6) = cpu_to_le32 ( - rndis_per_dev_params [configNr].stats->rx_packets - + rndis_per_dev_params [configNr].stats->rx_packets - rndis_per_dev_params [configNr].stats->rx_errors - rndis_per_dev_params [configNr].stats->rx_dropped); retval = 0; @@ -309,7 +305,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_XMIT_ERROR: DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__); @@ -324,7 +320,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_RCV_ERROR: DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__); @@ -338,7 +334,7 @@ retval = 0; } break; - + /* mandatory */ case OID_GEN_RCV_NO_BUFFER: DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); @@ -356,7 +352,7 @@ #ifdef RNDIS_OPTIONAL_STATS case OID_GEN_DIRECTED_BYTES_XMIT: DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); - /* + /* * Aunt Tilly's size of shoes * minus antarctica count of penguins * divided by weight of Alpha Centauri @@ -365,7 +361,7 @@ length = 4; *((u32 *) resp + 6) = cpu_to_le32 ( (rndis_per_dev_params [configNr] - .stats->tx_packets - + .stats->tx_packets - rndis_per_dev_params [configNr] .stats->tx_errors - rndis_per_dev_params [configNr] @@ -377,7 +373,7 @@ retval = 0; } break; - + case OID_GEN_DIRECTED_FRAMES_XMIT: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); /* dito */ @@ -385,7 +381,7 @@ length = 4; *((u32 *) resp + 6) = cpu_to_le32 ( (rndis_per_dev_params [configNr] - .stats->tx_packets - + .stats->tx_packets - rndis_per_dev_params [configNr] .stats->tx_errors - rndis_per_dev_params [configNr] @@ -397,7 +393,7 @@ retval = 0; } break; - + case OID_GEN_MULTICAST_BYTES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -410,7 +406,7 @@ retval = 0; } break; - + case OID_GEN_MULTICAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -423,7 +419,7 @@ retval = 0; } break; - + case OID_GEN_BROADCAST_BYTES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -436,7 +432,7 @@ retval = 0; } break; - + case OID_GEN_BROADCAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -449,19 +445,19 @@ retval = 0; } break; - + case OID_GEN_DIRECTED_BYTES_RCV: DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - + case OID_GEN_DIRECTED_FRAMES_RCV: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - + case OID_GEN_MULTICAST_BYTES_RCV: DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -474,7 +470,7 @@ retval = 0; } break; - + case OID_GEN_MULTICAST_FRAMES_RCV: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -487,7 +483,7 @@ retval = 0; } break; - + case OID_GEN_BROADCAST_BYTES_RCV: DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -500,7 +496,7 @@ retval = 0; } break; - + case OID_GEN_BROADCAST_FRAMES_RCV: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -513,7 +509,7 @@ retval = 0; } break; - + case OID_GEN_RCV_CRC_ERROR: DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -526,7 +522,7 @@ retval = 0; } break; - + case OID_GEN_TRANSMIT_QUEUE_LENGTH: DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); @@ -541,58 +537,28 @@ DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; -#ifndef CONFIG_NSCU memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].host_mac, length); -#else - /* We own a block of 4 consecutive MAC addresses; use the last - * two for the gadget stuff; - * use base MAC address + 3 - */ - memcpy ((u8 *) resp + 24, bd->bi_enetaddr, length-3); - addr = (bd->bi_enetaddr[length-3] << 16) + - (bd->bi_enetaddr[length-2] << 8) + - (bd->bi_enetaddr[length-1] ) + - 3; - *((u8 *)resp + 24 + length-3) = (addr >> 16) & 0xFF; - *((u8 *)resp + 24 + length-2) = (addr >> 8) & 0xFF; - *((u8 *)resp + 24 + length-1) = (addr ) & 0xFF; -#endif retval = 0; } else { *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; } break; - + /* mandatory */ case OID_802_3_CURRENT_ADDRESS: DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; -#ifndef CONFIG_NSCU memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].host_mac, length); -#else - /* We own a block of 4 consecutive MAC addresses; use the last - * two for the gadget stuff; - * use base MAC address + 3 - */ - memcpy ((u8 *) resp + 24, bd->bi_enetaddr, length-3); - addr = (bd->bi_enetaddr[length-3] << 16) + - (bd->bi_enetaddr[length-2] << 8) + - (bd->bi_enetaddr[length-1] ) + - 3; - *((u8 *)resp + 24 + length-3) = (addr >> 16) & 0xFF; - *((u8 *)resp + 24 + length-2) = (addr >> 8) & 0xFF; - *((u8 *)resp + 24 + length-1) = (addr ) & 0xFF; -#endif retval = 0; } break; - + /* mandatory */ case OID_802_3_MULTICAST_LIST: DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); @@ -601,7 +567,7 @@ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000); retval = 0; break; - + /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); @@ -610,7 +576,7 @@ *((u32 *) resp + 6) = __constant_cpu_to_le32 (1); retval = 0; break; - + case OID_802_3_MAC_OPTIONS: DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); break; @@ -629,7 +595,7 @@ retval = 0; } break; - + /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); @@ -637,7 +603,7 @@ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - + /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); @@ -645,42 +611,42 @@ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0); retval = 0; break; - + #ifdef RNDIS_OPTIONAL_STATS case OID_802_3_XMIT_DEFERRED: DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_MAX_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_RCV_OVERRUN: DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_UNDERRUN: DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_HEARTBEAT_FAILURE: DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_TIMES_CRS_LOST: DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_LATE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); /* TODO */ - break; + break; #endif /* RNDIS_OPTIONAL_STATS */ #ifdef RNDIS_PM @@ -697,7 +663,7 @@ struct NDIS_PNP_CAPABILITIES *caps = (void *) resp; caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE; - caps->WakeUpCapabilities.MinLinkChangeWakeUp + caps->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateD3; /* FIXME then use usb_gadget_wakeup(), and @@ -714,10 +680,10 @@ #endif default: - printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", + printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", __FUNCTION__, OID); } - + resp->InformationBufferOffset = __constant_cpu_to_le32 (16); resp->InformationBufferLength = cpu_to_le32 (length); resp->MessageLength = cpu_to_le32 (24 + length); @@ -725,7 +691,7 @@ return retval; } -static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, +static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, rndis_resp_t *r) { rndis_set_cmplt_type *resp; @@ -787,9 +753,9 @@ netif_stop_queue (params->dev); } break; - + case OID_802_3_MULTICAST_LIST: - /* I think we can ignore this */ + /* I think we can ignore this */ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); retval = 0; break; @@ -825,32 +791,32 @@ #endif default: - printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", + printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", __FUNCTION__, OID, buf_len); } - + return retval; } -/* - * Response Functions +/* + * Response Functions */ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) { - rndis_init_cmplt_type *resp; + rndis_init_cmplt_type *resp; rndis_resp_t *r; - + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; - + r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); - + if (!r) return -ENOMEM; - + resp = (rndis_init_cmplt_type *) r->buf; - + if (!resp) return -ENOMEM; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_INITIALIZE_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (52); @@ -869,11 +835,11 @@ resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); resp->AFListOffset = __constant_cpu_to_le32 (0); resp->AFListSize = __constant_cpu_to_le32 (0); - + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); - + return 0; } @@ -881,25 +847,25 @@ { rndis_query_cmplt_type *resp; rndis_resp_t *r; - + // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; - - /* - * we need more memory: - * oid_supported_list is the largest answer + + /* + * we need more memory: + * oid_supported_list is the largest answer */ r = rndis_add_response (configNr, sizeof (oid_supported_list)); - + if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *) r->buf; - + if (!resp) return -ENOMEM; - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (24); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - + if (gen_ndis_query_resp (configNr, cpu_to_le32 (buf->OID), r)) { /* OID not supported */ resp->Status = __constant_cpu_to_le32 ( @@ -908,7 +874,7 @@ resp->InformationBufferOffset = __constant_cpu_to_le32 (0); } else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); @@ -920,9 +886,9 @@ u32 BufLength, BufOffset; rndis_set_cmplt_type *resp; rndis_resp_t *r; - + r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); - + if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *) r->buf; if (!resp) return -ENOMEM; @@ -931,29 +897,30 @@ BufOffset = cpu_to_le32 (buf->InformationBufferOffset); #ifdef VERBOSE + int i; DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); DEBUG("%s: InfoBuffer: ", __FUNCTION__); - + for (i = 0; i < BufLength; i++) { DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); } - + DEBUG ("\n"); #endif - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID), + if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID), ((u8 *) buf) + 8 + BufOffset, BufLength, r)) resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); - + return 0; } @@ -961,19 +928,19 @@ { rndis_reset_cmplt_type *resp; rndis_resp_t *r; - + r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); - + if (!r) return -ENOMEM; resp = (rndis_reset_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); /* resent information */ resp->AddressingReset = __constant_cpu_to_le32 (1); - + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); @@ -992,47 +959,47 @@ r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type)); resp = (rndis_keepalive_cmplt_type *) r->buf; if (!resp) return -ENOMEM; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_KEEPALIVE_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); - + return 0; } -/* - * Device to Host Comunication +/* + * Device to Host Comunication */ static int rndis_indicate_status_msg (int configNr, u32 status) { - rndis_indicate_status_msg_type *resp; + rndis_indicate_status_msg_type *resp; rndis_resp_t *r; - + if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) return -ENOTSUPP; - - r = rndis_add_response (configNr, + + r = rndis_add_response (configNr, sizeof (rndis_indicate_status_msg_type)); if (!r) return -ENOMEM; - + resp = (rndis_indicate_status_msg_type *) r->buf; if (!resp) return -ENOMEM; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_INDICATE_STATUS_MSG); resp->MessageLength = __constant_cpu_to_le32 (20); resp->Status = cpu_to_le32 (status); resp->StatusBufferLength = __constant_cpu_to_le32 (0); resp->StatusBufferOffset = __constant_cpu_to_le32 (0); - - if (rndis_per_dev_params [configNr].ack) + + if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); return 0; @@ -1042,7 +1009,7 @@ { rndis_per_dev_params [configNr].media_state = NDIS_MEDIA_STATE_CONNECTED; - return rndis_indicate_status_msg (configNr, + return rndis_indicate_status_msg (configNr, RNDIS_STATUS_MEDIA_CONNECT); } @@ -1059,35 +1026,35 @@ rndis_per_dev_params [configNr].host_mac = addr; } -/* - * Message Parser +/* + * Message Parser */ int rndis_msg_parser (u8 configNr, u8 *buf) { u32 MsgType, MsgLength, *tmp; struct rndis_params *params; - + if (!buf) return -ENOMEM; - - tmp = (u32 *) buf; + + tmp = (u32 *) buf; MsgType = cpu_to_le32p(tmp++); MsgLength = cpu_to_le32p(tmp++); - + if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; params = &rndis_per_dev_params [configNr]; - + /* For USB: responses may take up to 10 seconds */ switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: - DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", + DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __FUNCTION__ ); params->state = RNDIS_INITIALIZED; return rndis_init_response (configNr, (rndis_init_msg_type *) buf); - + case REMOTE_NDIS_HALT_MSG: DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", __FUNCTION__ ); @@ -1097,17 +1064,17 @@ netif_stop_queue (params->dev); } return 0; - + case REMOTE_NDIS_QUERY_MSG: - return rndis_query_response (configNr, + return rndis_query_response (configNr, (rndis_query_msg_type *) buf); - + case REMOTE_NDIS_SET_MSG: - return rndis_set_response (configNr, + return rndis_set_response (configNr, (rndis_set_msg_type *) buf); - + case REMOTE_NDIS_RESET_MSG: - DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", + DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", __FUNCTION__ ); return rndis_reset_response (configNr, (rndis_reset_msg_type *) buf); @@ -1115,20 +1082,20 @@ case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ #ifdef VERBOSE - DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", + DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __FUNCTION__ ); #endif return rndis_keepalive_response (configNr, - (rndis_keepalive_msg_type *) + (rndis_keepalive_msg_type *) buf); - - default: + + default: /* At least Windows XP emits some undefined RNDIS messages. * In one case those messages seemed to relate to the host * suspending itself. */ printk (KERN_WARNING - "%s: unknown RNDIS message 0x%08X len %d\n", + "%s: unknown RNDIS message 0x%08X len %d\n", __FUNCTION__ , MsgType, MsgLength); { unsigned i; @@ -1152,14 +1119,14 @@ } break; } - + return -ENOTSUPP; } int rndis_register (int (* rndis_control_ack) (struct net_device *)) { u8 i; - + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { if (!rndis_per_dev_params [i].used) { rndis_per_dev_params [i].used = 1; @@ -1169,30 +1136,30 @@ } } DEBUG("failed\n"); - + return -1; } void rndis_deregister (int configNr) { DEBUG("%s: \n", __FUNCTION__ ); - + if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params [configNr].used = 0; - + return; } -int rndis_set_param_dev (u8 configNr, struct net_device *dev, +int rndis_set_param_dev (u8 configNr, struct net_device *dev, struct net_device_stats *stats) { DEBUG("%s:\n", __FUNCTION__ ); if (!dev || !stats) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].dev = dev; rndis_per_dev_params [configNr].stats = stats; - + return 0; } @@ -1201,10 +1168,10 @@ DEBUG("%s:\n", __FUNCTION__ ); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].vendorID = vendorID; rndis_per_dev_params [configNr].vendorDescr = vendorDescr; - + return 0; } @@ -1212,10 +1179,10 @@ { DEBUG("%s:\n", __FUNCTION__ ); if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].medium = medium; rndis_per_dev_params [configNr].speed = speed; - + return 0; } @@ -1228,7 +1195,7 @@ *((u32 *) skb->data + 1) = cpu_to_le32(skb->len); *((u32 *) skb->data + 2) = __constant_cpu_to_le32 (36); *((u32 *) skb->data + 3) = cpu_to_le32(skb->len - 44); - + return; } @@ -1236,8 +1203,8 @@ { rndis_resp_t *r; struct list_head *act, *tmp; - - list_for_each_safe (act, tmp, + + list_for_each_safe (act, tmp, &(rndis_per_dev_params [configNr].resp_queue)) { r = list_entry (act, rndis_resp_t, list); @@ -1252,10 +1219,10 @@ { rndis_resp_t *r; struct list_head *act, *tmp; - + if (!length) return NULL; - - list_for_each_safe (act, tmp, + + list_for_each_safe (act, tmp, &(rndis_per_dev_params [configNr].resp_queue)) { r = list_entry (act, rndis_resp_t, list); @@ -1265,22 +1232,22 @@ return r->buf; } } - + return NULL; } static rndis_resp_t *rndis_add_response (int configNr, u32 length) { rndis_resp_t *r; - + r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC); if (!r) return NULL; - + r->buf = (u8 *) (r + 1); r->length = length; r->send = 0; - - list_add_tail (&r->list, + + list_add_tail (&r->list, &(rndis_per_dev_params [configNr].resp_queue)); return r; } @@ -1288,22 +1255,22 @@ int rndis_rm_hdr (u8 *buf, u32 *length) { u32 i, messageLen, dataOffset, *tmp; - - tmp = (u32 *) buf; + + tmp = (u32 *) buf; if (!buf || !length) return -1; if (cpu_to_le32p(tmp++) != 1) return -1; - + messageLen = cpu_to_le32p(tmp++); dataOffset = cpu_to_le32p(tmp++) + 8; if (messageLen < dataOffset || messageLen > *length) return -1; - + for (i = dataOffset; i < messageLen; i++) buf [i - dataOffset] = buf [i]; - + *length = messageLen - dataOffset; - + return 0; } @@ -1312,14 +1279,14 @@ #include -static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, +static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, void *data) { char *out = page; int len; rndis_params *param = (rndis_params *) data; - - out += snprintf (out, count, + + out += snprintf (out, count, "Config Nr. %d\n" "used : %s\n" "state : %s\n" @@ -1327,8 +1294,8 @@ "speed : %d\n" "cable : %s\n" "vendor ID : 0x%08X\n" - "vendor : %s\n", - param->confignr, (param->used) ? "y" : "n", + "vendor : %s\n", + param->confignr, (param->used) ? "y" : "n", ({ char *s = "?"; switch (param->state) { case RNDIS_UNINITIALIZED: @@ -1338,32 +1305,32 @@ case RNDIS_DATA_INITIALIZED: s = "RNDIS_DATA_INITIALIZED"; break; }; s; }), - param->medium, - (param->media_state) ? 0 : param->speed*100, + param->medium, + (param->media_state) ? 0 : param->speed*100, (param->media_state) ? "disconnected" : "connected", - param->vendorID, param->vendorDescr); - + param->vendorID, param->vendorDescr); + len = out - page; len -= off; - + if (len < count) { *eof = 1; if (len <= 0) return 0; } else len = count; - + *start = page + off; return len; } -static int rndis_proc_write (struct file *file, const char __user *buffer, +static int rndis_proc_write (struct file *file, const char __user *buffer, unsigned long count, void *data) { rndis_params *p = data; u32 speed = 0; int i, fl_speed = 0; - + for (i = 0; i < count; i++) { char c; if (get_user(c, buffer)) @@ -1390,15 +1357,15 @@ case 'd': rndis_signal_disconnect(p->confignr); break; - default: + default: if (fl_speed) p->speed = speed; else DEBUG ("%c is not valid\n", c); break; } - + buffer++; } - + return count; } @@ -1419,7 +1386,7 @@ sprintf (name, NAME_TEMPLATE, i); if (!(rndis_connect_state [i] - = create_proc_entry (name, 0660, NULL))) + = create_proc_entry (name, 0660, NULL))) { DEBUG ("%s :remove entries", __FUNCTION__); while (i) { @@ -1443,7 +1410,7 @@ = NDIS_MEDIA_STATE_DISCONNECTED; INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue)); } - + return 0; } @@ -1452,7 +1419,7 @@ #ifdef CONFIG_USB_GADGET_DEBUG_FILES u8 i; char name [20]; - + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { sprintf (name, NAME_TEMPLATE, i); remove_proc_entry (name, NULL); diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/usbstring.c linuxppc_2_4_devel.modified/drivers/usb/gadget/usbstring.c --- linuxppc_2_4_devel/drivers/usb/gadget/usbstring.c 2003-11-15 02:11:39.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/usbstring.c 2006-03-31 14:46:58.000000000 +0200 @@ -11,29 +11,95 @@ #include #include #include -#include +#include #include #include +#include +#include + + +static int utf8_to_utf16le(const char *s, u16 *cp, unsigned len) +{ + int count = 0; + u8 c; + u16 uchar; + + /* this insists on correct encodings, though not minimal ones. + * BUT it currently rejects legit 4-byte UTF-8 code points, + * which need surrogate pairs. (Unicode 3.1 can use them.) + */ + while (len != 0 && (c = (u8) *s++) != 0) { + if (unlikely(c & 0x80)) { + // 2-byte sequence: + // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx + if ((c & 0xe0) == 0xc0) { + uchar = (c & 0x1f) << 6; + + c = (u8) *s++; + if ((c & 0xc0) != 0xc0) + goto fail; + c &= 0x3f; + uchar |= c; + + // 3-byte sequence (most CJKV characters): + // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx + } else if ((c & 0xf0) == 0xe0) { + uchar = (c & 0x0f) << 12; + + c = (u8) *s++; + if ((c & 0xc0) != 0xc0) + goto fail; + c &= 0x3f; + uchar |= c << 6; + + c = (u8) *s++; + if ((c & 0xc0) != 0xc0) + goto fail; + c &= 0x3f; + uchar |= c; + + /* no bogus surrogates */ + if (0xd800 <= uchar && uchar <= 0xdfff) + goto fail; + + // 4-byte sequence (surrogate pairs, currently rare): + // 11101110wwwwzzzzyy + 110111yyyyxxxxxx + // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx + // (uuuuu = wwww + 1) + // FIXME accept the surrogate code points (only) + + } else + goto fail; + } else + uchar = c; + put_unaligned (cpu_to_le16 (uchar), cp++); + count++; + len--; + } + return count; +fail: + return -1; +} + /** * usb_gadget_get_string - fill out a string descriptor - * @table: of c strings using iso latin/1 characters + * @table: of c strings encoded using UTF-8 * @id: string id, from low byte of wValue in get string descriptor * @buf: at least 256 bytes * - * Finds the iso latin/1 string matching the ID, and converts it into a + * Finds the UTF-8 string matching the ID, and converts it into a * string descriptor in utf16-le. * Returns length of descriptor (always even) or negative errno * - * If your driver needs stings in multiple languages, you'll need to - * to use some alternate solution for languages where the ISO 8859/1 - * (latin/1) character set can't be used. For example, they can't be - * used with Chinese (Big5, GB2312, etc), Japanese, Korean, or many other - * languages. You'd likely "switch (wIndex) { ... }" in your ep0 - * string descriptor logic, using this routine in cases where "western - * european" characters suffice for the strings being returned. + * If your driver needs stings in multiple languages, you'll probably + * "switch (wIndex) { ... }" in your ep0 string descriptor logic, + * using this routine after choosing which set of UTF-8 strings to use. + * Note that US-ASCII is a strict subset of UTF-8; any string bytes with + * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 + * characters (which are also widely used in C strings). */ int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) @@ -59,13 +125,12 @@ /* string descriptors have length, tag, then UTF16-LE text */ len = min ((size_t) 126, strlen (s->s)); + memset (buf + 2, 0, 2 * len); /* zero all the bytes */ + len = utf8_to_utf16le(s->s, (u16 *)&buf[2], len); + if (len < 0) + return -EINVAL; buf [0] = (len + 1) * 2; buf [1] = USB_DT_STRING; - memset (buf + 2, 0, 2 * len); /* zero all the high bytes */ - while (len) { - buf [2 * len] = s->s [len - 1]; - len--; - } return buf [0]; } diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/gadget/zero.c linuxppc_2_4_devel.modified/drivers/usb/gadget/zero.c --- linuxppc_2_4_devel/drivers/usb/gadget/zero.c 2004-03-11 23:44:07.000000000 +0100 +++ linuxppc_2_4_devel.modified/drivers/usb/gadget/zero.c 2006-06-06 09:00:11.000000000 +0200 @@ -1,7 +1,7 @@ /* * zero.c -- Gadget Zero, for USB development * - * Copyright (C) 2003 David Brownell + * Copyright (C) 2003-2004 David Brownell * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -87,10 +87,12 @@ #include #include +#include "gadget_chips.h" + /*-------------------------------------------------------------------------*/ -#define DRIVER_VERSION "Bastille Day 2003" +#define DRIVER_VERSION "St Patrick's Day 2004" static const char shortname [] = "zero"; static const char longname [] = "Gadget Zero"; @@ -101,134 +103,14 @@ /*-------------------------------------------------------------------------*/ /* - * hardware-specific configuration, controlled by which device - * controller driver was configured. - * - * CHIP ... hardware identifier - * DRIVER_VERSION_NUM ... alerts the host side driver to differences - * EP_*_NAME ... which endpoints do we use for which purpose? - * EP_*_NUM ... numbers for them (often limited by hardware) - * HIGHSPEED ... define if ep0 and descriptors need high speed support - * MAX_USB_POWER ... define if we use other than 100 mA bus current - * SELFPOWER ... if we can run on bus power, zero - * WAKEUP ... if hardware supports remote wakeup AND we will issue the - * usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP - * - * add other defines for other portability issues, like hardware that - * for some reason doesn't handle full speed bulk maxpacket of 64. - */ - -/* - * DRIVER_VERSION_NUM 0x0000 (?): Martin Diehl's ezusb an21/fx code - */ - -/* - * NetChip 2280, PCI based. - * - * This has half a dozen configurable endpoints, four with dedicated - * DMA channels to manage their FIFOs. It supports high speed. - * Those endpoints can be arranged in any desired configuration. - */ -#ifdef CONFIG_USB_GADGET_NET2280 -#define CHIP "net2280" -#define DRIVER_VERSION_NUM 0x0111 -static const char EP_OUT_NAME [] = "ep-a"; -#define EP_OUT_NUM 2 -static const char EP_IN_NAME [] = "ep-b"; -#define EP_IN_NUM 2 -#define HIGHSPEED -/* specific hardware configs could be bus-powered */ -/* supports remote wakeup, but this driver doesn't */ -#endif - -/* - * PXA-2xx UDC: widely used in second gen Linux-capable PDAs. - * - * This has fifteen fixed-function full speed endpoints, and it - * can support all USB transfer types. - * - * These supports three or four configurations, with fixed numbers. - * The hardware interprets SET_INTERFACE, net effect is that you - * can't use altsettings or reset the interfaces independently. - * So stick to a single interface. - */ -#ifdef CONFIG_USB_GADGET_PXA2XX -#define CHIP "pxa2xx" -#define DRIVER_VERSION_NUM 0x0113 -static const char EP_OUT_NAME [] = "ep12out-bulk"; -#define EP_OUT_NUM 12 -static const char EP_IN_NAME [] = "ep11in-bulk"; -#define EP_IN_NUM 11 -/* doesn't support bus-powered operation */ -/* supports remote wakeup, but this driver doesn't */ -#endif - -/* - * SA-1100 UDC: widely used in first gen Linux-capable PDAs. - * - * This has only two fixed function endpoints, which can only - * be used for bulk (or interrupt) transfers. (Plus control.) + * driver assumes self-powered hardware, and + * has no way for users to trigger remote wakeup. * - * Since it can't flush its TX fifos without disabling the UDC, - * the current configuration or altsettings can't change except - * in special situations. So this is a case of "choose it right - * during enumeration" ... - */ -#ifdef CONFIG_USB_GADGET_SA1100 -#define CHIP "sa1100" -#define DRIVER_VERSION_NUM 0x0115 -static const char EP_OUT_NAME [] = "ep1out-bulk"; -#define EP_OUT_NUM 1 -static const char EP_IN_NAME [] = "ep2in-bulk"; -#define EP_IN_NUM 2 -/* doesn't support bus-powered operation */ -/* doesn't support remote wakeup? */ -#endif - -/* - * Toshiba TC86C001 ("Goku-S") UDC - * - * This has three semi-configurable full speed bulk/interrupt endpoints. - */ -#ifdef CONFIG_USB_GADGET_GOKU -#define CHIP "goku" -#define DRIVER_VERSION_NUM 0x0116 -static const char EP_OUT_NAME [] = "ep1-bulk"; -#define EP_OUT_NUM 1 -static const char EP_IN_NAME [] = "ep2-bulk"; -#define EP_IN_NUM 2 -/* doesn't support remote wakeup */ -#endif - -/*-------------------------------------------------------------------------*/ - -#ifndef EP_OUT_NUM -# error Configure some USB peripheral controller driver! -#endif - -/* power usage is config specific. - * hardware that supports remote wakeup defaults to disabling it. - */ - -#ifndef SELFPOWER -/* default: say we're self-powered */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER -/* else: - * - SELFPOWER value must be zero - * - MAX_USB_POWER may be nonzero. + * this version autoconfigures as much as possible, + * which is reasonable for most "bulk-only" drivers. */ -#endif - -#ifndef MAX_USB_POWER -/* any hub supports this steady state bus power consumption */ -#define MAX_USB_POWER 100 /* mA */ -#endif - -#ifndef WAKEUP -/* default: this driver won't do remote wakeup */ -#define WAKEUP 0 -/* else value must be USB_CONFIG_ATT_WAKEUP */ -#endif +static const char *EP_IN_NAME; /* source */ +static const char *EP_OUT_NAME; /* sink */ /*-------------------------------------------------------------------------*/ @@ -246,6 +128,9 @@ */ u8 config; struct usb_ep *in_ep, *out_ep; + + /* autoresume timer */ + struct timer_list resume; }; #define xprintk(d,level,fmt,args...) \ @@ -253,20 +138,19 @@ ## args) #ifdef DEBUG -#undef DEBUG -#define DEBUG(dev,fmt,args...) \ +#define DBG(dev,fmt,args...) \ xprintk(dev , KERN_DEBUG , fmt , ## args) #else -#define DEBUG(dev,fmt,args...) \ +#define DBG(dev,fmt,args...) \ do { } while (0) #endif /* DEBUG */ #ifdef VERBOSE -#define VDEBUG DEBUG +#define VDBG DBG #else -#define VDEBUG(dev,fmt,args...) \ +#define VDBG(dev,fmt,args...) \ do { } while (0) -#endif /* DEBUG */ +#endif /* VERBOSE */ #define ERROR(dev,fmt,args...) \ xprintk(dev , KERN_ERR , fmt , ## args) @@ -284,8 +168,8 @@ /* * Normally the "loopback" configuration is second (index 1) so * it's not the default. Here's where to change that order, to - * work better with hosts (like Linux ... for now!) where config - * changes are problematic. + * work better with hosts where config changes are problematic. + * Or controllers (like superh) that only support one config. */ static int loopdefault = 0; @@ -302,15 +186,27 @@ MODULE_PARM (loopdefault, "b"); MODULE_PARM_DESC (loopdefault, "true to have default config be loopback"); +/* + * if it's nonzero, autoresume says how many seconds to wait + * before trying to wake up the host after suspend. + */ +static unsigned autoresume = 0; +MODULE_PARM (autoresume, "i"); + /*-------------------------------------------------------------------------*/ /* Thanks to NetChip Technologies for donating this product ID. * - * DO NOT REUSE THESE IDs with any other driver!! Ever!! + * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! * Instead: allocate your own, using normal USB-IF procedures. */ +#ifndef CONFIG_USB_ZERO_HNPTEST #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ +#else +#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ +#define DRIVER_PRODUCT_NUM 0xbadd +#endif /*-------------------------------------------------------------------------*/ @@ -342,14 +238,13 @@ .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), - .bcdDevice = __constant_cpu_to_le16 (DRIVER_VERSION_NUM), .iManufacturer = STRING_MANUFACTURER, .iProduct = STRING_PRODUCT, .iSerialNumber = STRING_SERIAL, .bNumConfigurations = 2, }; -static const struct usb_config_descriptor +static struct usb_config_descriptor source_sink_config = { .bLength = sizeof source_sink_config, .bDescriptorType = USB_DT_CONFIG, @@ -358,11 +253,11 @@ .bNumInterfaces = 1, .bConfigurationValue = CONFIG_SOURCE_SINK, .iConfiguration = STRING_SOURCE_SINK, - .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP, - .bMaxPower = (MAX_USB_POWER + 1) / 2, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 1, /* self-powered */ }; -static const struct usb_config_descriptor +static struct usb_config_descriptor loopback_config = { .bLength = sizeof loopback_config, .bDescriptorType = USB_DT_CONFIG, @@ -371,8 +266,16 @@ .bNumInterfaces = 1, .bConfigurationValue = CONFIG_LOOPBACK, .iConfiguration = STRING_LOOPBACK, - .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP, - .bMaxPower = (MAX_USB_POWER + 1) / 2, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 1, /* self-powered */ +}; + +static struct usb_otg_descriptor +otg_descriptor = { + .bLength = sizeof otg_descriptor, + .bDescriptorType = USB_DT_OTG, + + .bmAttributes = USB_OTG_SRP, }; /* one interface in each configuration */ @@ -399,27 +302,41 @@ /* two full speed bulk endpoints; their use is config-dependent */ -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor fs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_IN_NUM | USB_DIR_IN, + .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16 (64), }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor fs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_OUT_NUM, + .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16 (64), }; -#ifdef HIGHSPEED +static const struct usb_descriptor_header *fs_source_sink_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + (struct usb_descriptor_header *) &source_sink_intf, + (struct usb_descriptor_header *) &fs_sink_desc, + (struct usb_descriptor_header *) &fs_source_desc, + NULL, +}; + +static const struct usb_descriptor_header *fs_loopback_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + (struct usb_descriptor_header *) &loopback_intf, + (struct usb_descriptor_header *) &fs_sink_desc, + (struct usb_descriptor_header *) &fs_source_desc, + NULL, +}; + +#ifdef CONFIG_USB_GADGET_DUALSPEED /* * usb 2.0 devices need to expose both high speed and full speed @@ -430,22 +347,20 @@ * for the config descriptor. */ -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor hs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_IN_NUM | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static const struct usb_endpoint_descriptor +static struct usb_endpoint_descriptor hs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_OUT_NUM, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16 (512), }; @@ -461,6 +376,22 @@ .bNumConfigurations = 2, }; +static const struct usb_descriptor_header *hs_source_sink_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + (struct usb_descriptor_header *) &source_sink_intf, + (struct usb_descriptor_header *) &hs_source_desc, + (struct usb_descriptor_header *) &hs_sink_desc, + NULL, +}; + +static const struct usb_descriptor_header *hs_loopback_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + (struct usb_descriptor_header *) &loopback_intf, + (struct usb_descriptor_header *) &hs_source_desc, + (struct usb_descriptor_header *) &hs_sink_desc, + NULL, +}; + /* maxpacket and other transfer characteristics vary by speed. */ #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) @@ -469,13 +400,14 @@ /* if there's no high speed support, maxpacket doesn't change. */ #define ep_desc(g,hs,fs) fs -#endif /* !HIGHSPEED */ +#endif /* !CONFIG_USB_GADGET_DUALSPEED */ +static char manufacturer [50]; static char serial [40]; -/* static strings, in iso 8859/1 */ +/* static strings, in UTF-8 */ static struct usb_string strings [] = { - { STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, }, + { STRING_MANUFACTURER, manufacturer, }, { STRING_PRODUCT, longname, }, { STRING_SERIAL, serial, }, { STRING_LOOPBACK, loopback, }, @@ -507,60 +439,46 @@ * device?) */ static int -config_buf (enum usb_device_speed speed, +config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { - int is_source_sink; - const unsigned config_len = USB_DT_CONFIG_SIZE - + USB_DT_INTERFACE_SIZE - + 2 * USB_DT_ENDPOINT_SIZE; -#ifdef HIGHSPEED - int hs; + int is_source_sink; + int len; + const struct usb_descriptor_header **function; +#ifdef CONFIG_USB_GADGET_DUALSPEED + int hs = (gadget->speed == USB_SPEED_HIGH); #endif + /* two configurations will always be index 0 and index 1 */ if (index > 1) return -EINVAL; - if (config_len > USB_BUFSIZ) - return -EDOM; is_source_sink = loopdefault ? (index == 1) : (index == 0); - /* config (or other speed config) */ - if (is_source_sink) - memcpy (buf, &source_sink_config, USB_DT_CONFIG_SIZE); - else - memcpy (buf, &loopback_config, USB_DT_CONFIG_SIZE); - buf [1] = type; - ((struct usb_config_descriptor *) buf)->wTotalLength - = __constant_cpu_to_le16 (config_len); - buf += USB_DT_CONFIG_SIZE; - - /* one interface */ - if (is_source_sink) - memcpy (buf, &source_sink_intf, USB_DT_INTERFACE_SIZE); - else - memcpy (buf, &loopback_intf, USB_DT_INTERFACE_SIZE); - buf += USB_DT_INTERFACE_SIZE; - - /* the endpoints in that interface (at that speed) */ -#ifdef HIGHSPEED - hs = (speed == USB_SPEED_HIGH); +#ifdef CONFIG_USB_GADGET_DUALSPEED if (type == USB_DT_OTHER_SPEED_CONFIG) hs = !hs; - if (hs) { - memcpy (buf, &hs_source_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - memcpy (buf, &hs_sink_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - } else + if (hs) + function = is_source_sink + ? hs_source_sink_function + : hs_loopback_function; + else #endif - { - memcpy (buf, &fs_source_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - memcpy (buf, &fs_sink_desc, USB_DT_ENDPOINT_SIZE); - buf += USB_DT_ENDPOINT_SIZE; - } - - return config_len; + function = is_source_sink + ? fs_source_sink_function + : fs_loopback_function; + + /* for now, don't advertise srp-only devices */ + if (!gadget->is_otg) + function++; + + len = usb_gadget_config_buf (is_source_sink + ? &source_sink_config + : &loopback_config, + buf, USB_BUFSIZ, function); + if (len < 0) + return len; + ((struct usb_config_descriptor *) buf)->bDescriptorType = type; + return len; } /*-------------------------------------------------------------------------*/ @@ -577,7 +495,7 @@ &req->dma, GFP_ATOMIC); if (!req->buf) { usb_ep_free_request (ep, req); - req = 0; + req = NULL; } } return req; @@ -594,7 +512,7 @@ /* optionally require specific source/sink data patterns */ -static inline int +static int check_read_data ( struct zero_dev *dev, struct usb_ep *ep, @@ -628,7 +546,7 @@ return 0; } -static inline void +static void reinit_write_data ( struct zero_dev *dev, struct usb_ep *ep, @@ -671,7 +589,7 @@ case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ - VDEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status, + VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, req->actual, req->length); if (ep == dev->out_ep) check_read_data (dev, ep, req); @@ -684,7 +602,7 @@ */ default: #if 1 - DEBUG (dev, "%s complete --> %d, %d/%d\n", ep->name, + DBG (dev, "%s complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); #endif case -EREMOTEIO: /* short read */ @@ -708,7 +626,7 @@ req = alloc_ep_req (ep, buflen); if (!req) - return 0; + return NULL; memset (req->buf, 0, req->length); req->complete = source_sink_complete; @@ -722,7 +640,7 @@ ERROR (dev, "start %s --> %d\n", ep->name, status); free_ep_req (ep, req); - req = 0; + req = NULL; } return req; @@ -775,7 +693,7 @@ break; } if (result == 0) - DEBUG (dev, "buflen %d\n", buflen); + DBG (dev, "buflen %d\n", buflen); /* caller is responsible for cleanup on error */ return result; @@ -886,14 +804,14 @@ req->complete = loopback_complete; result = usb_ep_queue (ep, req, GFP_ATOMIC); if (result) - DEBUG (dev, "%s queue req --> %d\n", + DBG (dev, "%s queue req --> %d\n", ep->name, result); } else result = -ENOMEM; } } if (result == 0) - DEBUG (dev, "qlen %d, buflen %d\n", qlen, buflen); + DBG (dev, "qlen %d, buflen %d\n", qlen, buflen); /* caller is responsible for cleanup on error */ return result; @@ -906,20 +824,21 @@ if (dev->config == 0) return; - DEBUG (dev, "reset config\n"); + DBG (dev, "reset config\n"); /* just disable endpoints, forcing completion of pending i/o. * all our completion handlers free their requests in this case. */ if (dev->in_ep) { usb_ep_disable (dev->in_ep); - dev->in_ep = 0; + dev->in_ep = NULL; } if (dev->out_ep) { usb_ep_disable (dev->out_ep); - dev->out_ep = 0; + dev->out_ep = NULL; } dev->config = 0; + del_timer (&dev->resume); } /* change our operational config. this code must agree with the code @@ -941,13 +860,11 @@ if (number == dev->config) return 0; -#ifdef CONFIG_USB_GADGET_SA1100 - if (dev->config) { + if (gadget_is_sa1100 (gadget) && dev->config) { /* tx fifo is full, but we can't clear it...*/ INFO (dev, "can't change configurations\n"); return -ESPIPE; } -#endif zero_reset_config (dev); switch (number) { @@ -991,7 +908,7 @@ static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) { if (req->status || req->actual != req->length) - DEBUG ((struct zero_dev *) ep->driver_data, + DBG ((struct zero_dev *) ep->driver_data, "setup complete --> %d, %d/%d\n", req->status, req->actual, req->length); } @@ -1013,6 +930,7 @@ /* usually this stores reply data in the pre-allocated ep0 buffer, * but config change events will reconfigure hardware. */ + req->zero = 0; switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: @@ -1024,17 +942,21 @@ value = min (ctrl->wLength, (u16) sizeof device_desc); memcpy (req->buf, &device_desc, value); break; -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER: + if (!gadget->is_dualspeed) + break; value = min (ctrl->wLength, (u16) sizeof dev_qualifier); memcpy (req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: + if (!gadget->is_dualspeed) + break; // FALLTHROUGH -#endif /* HIGHSPEED */ +#endif /* CONFIG_USB_GADGET_DUALSPEED */ case USB_DT_CONFIG: - value = config_buf (gadget->speed, req->buf, + value = config_buf (gadget, req->buf, ctrl->wValue >> 8, ctrl->wValue & 0xff); if (value >= 0) @@ -1044,7 +966,8 @@ case USB_DT_STRING: /* wIndex == language code. * this driver only handles one language, you can - * add others even if they don't use iso8859/1 + * add string tables for other languages, using + * any UTF-8 characters */ value = usb_gadget_get_string (&stringtab, ctrl->wValue & 0xff, req->buf); @@ -1058,6 +981,12 @@ case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != 0) goto unknown; + if (gadget->a_hnp_support) + DBG (dev, "HNP available\n"); + else if (gadget->a_alt_hnp_support) + DBG (dev, "HNP needs a different root port\n"); + else + VDBG (dev, "HNP inactive\n"); spin_lock (&dev->lock); value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC); spin_unlock (&dev->lock); @@ -1135,7 +1064,7 @@ default: unknown: - VDEBUG (dev, + VDBG (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex, ctrl->wLength); @@ -1144,9 +1073,11 @@ /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; + req->zero = value < ctrl->wLength + && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { - DEBUG (dev, "ep_queue --> %d\n", value); + DBG (dev, "ep_queue --> %d\n", value); req->status = 0; zero_setup_complete (gadget->ep0, req); } @@ -1176,6 +1107,21 @@ */ } +static void +zero_autoresume (unsigned long _dev) +{ + struct zero_dev *dev = (struct zero_dev *) _dev; + int status; + + /* normally the host would be woken up for something + * more significant than just a timer firing... + */ + if (dev->gadget->speed != USB_SPEED_UNKNOWN) { + status = usb_gadget_wakeup (dev->gadget); + DBG (dev, "wakeup --> %d\n", status); + } +} + /*-------------------------------------------------------------------------*/ static void @@ -1183,20 +1129,90 @@ { struct zero_dev *dev = get_gadget_data (gadget); - DEBUG (dev, "unbind\n"); + DBG (dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ if (dev->req) free_ep_req (gadget->ep0, dev->req); + del_timer_sync (&dev->resume); kfree (dev); - set_gadget_data (gadget, 0); + set_gadget_data (gadget, NULL); } static int zero_bind (struct usb_gadget *gadget) { struct zero_dev *dev; + struct usb_ep *ep; + + /* Bulk-only drivers like this one SHOULD be able to + * autoconfigure on any sane usb controller driver, + * but there may also be important quirks to address. + */ + usb_ep_autoconfig_reset (gadget); + ep = usb_ep_autoconfig (gadget, &fs_source_desc); + if (!ep) { +autoconf_fail: + printk (KERN_ERR "%s: can't autoconfigure on %s\n", + shortname, gadget->name); + return -ENODEV; + } + EP_IN_NAME = ep->name; + ep->driver_data = ep; /* claim */ + + ep = usb_ep_autoconfig (gadget, &fs_sink_desc); + if (!ep) + goto autoconf_fail; + EP_OUT_NAME = ep->name; + ep->driver_data = ep; /* claim */ + + + /* + * DRIVER POLICY CHOICE: you may want to do this differently. + * One thing to avoid is reusing a bcdDevice revision code + * with different host-visible configurations or behavior + * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc + */ + if (gadget_is_net2280 (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201); + } else if (gadget_is_pxa (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203); +#if 0 + } else if (gadget_is_sh(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204); + /* SH has only one configuration; see "loopdefault" */ + device_desc.bNumConfigurations = 1; + /* FIXME make 1 == default.bConfigurationValue */ +#endif + } else if (gadget_is_sa1100 (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205); + } else if (gadget_is_goku (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206); + } else if (gadget_is_mq11xx (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207); + } else if (gadget_is_omap (gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208); + } else if (gadget_is_lh7a40x(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209); + } else if (gadget_is_n9604(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); + } else if (gadget_is_pxa27x(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211); + } else { + /* gadget zero is so simple (for now, no altsettings) that + * it SHOULD NOT have problems with bulk-capable hardware. + * so warn about unrcognized controllers, don't panic. + * + * things like configuration and altsetting numbering + * can need hardware-specific attention though. + */ + printk (KERN_WARNING "%s: controller '%s' not recognized\n", + shortname, gadget->name); + device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); + } + + /* ok, we made sense of the hardware ... */ dev = kmalloc (sizeof *dev, SLAB_KERNEL); if (!dev) return -ENOMEM; @@ -1217,14 +1233,48 @@ dev->req->complete = zero_setup_complete; device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; -#ifdef HIGHSPEED + +#ifdef CONFIG_USB_GADGET_DUALSPEED /* assume ep0 uses the same value for both speeds ... */ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; + + /* and that all endpoints are dual-speed */ + hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; + hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; #endif + if (gadget->is_otg) { + otg_descriptor.bmAttributes |= USB_OTG_HNP, + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + + if (gadget->is_otg) { + otg_descriptor.bmAttributes |= USB_OTG_HNP, + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + + usb_gadget_set_selfpowered (gadget); + + init_timer (&dev->resume); + dev->resume.function = zero_autoresume; + dev->resume.data = (unsigned long) dev; + if (autoresume) { + source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + gadget->ep0->driver_data = dev; INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); + INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, + EP_OUT_NAME, EP_IN_NAME); + + snprintf (manufacturer, sizeof manufacturer, + UTS_SYSNAME " " UTS_RELEASE " with %s", + gadget->name); + return 0; enomem: @@ -1234,8 +1284,35 @@ /*-------------------------------------------------------------------------*/ +static void +zero_suspend (struct usb_gadget *gadget) +{ + struct zero_dev *dev = get_gadget_data (gadget); + + if (gadget->speed == USB_SPEED_UNKNOWN) + return; + + if (autoresume) { + mod_timer (&dev->resume, jiffies + (HZ * autoresume)); + DBG (dev, "suspend, wakeup in %d seconds\n", autoresume); + } else + DBG (dev, "suspend\n"); +} + +static void +zero_resume (struct usb_gadget *gadget) +{ + struct zero_dev *dev = get_gadget_data (gadget); + + DBG (dev, "resume\n"); + del_timer (&dev->resume); +} + + +/*-------------------------------------------------------------------------*/ + static struct usb_gadget_driver zero_driver = { -#ifdef HIGHSPEED +#ifdef CONFIG_USB_GADGET_DUALSPEED .speed = USB_SPEED_HIGH, #else .speed = USB_SPEED_FULL, @@ -1247,6 +1324,9 @@ .setup = zero_setup, .disconnect = zero_disconnect, + .suspend = zero_suspend, + .resume = zero_resume, + .driver = { .name = (char *) shortname, // .shutdown = ... diff --exclude CVS -uNr linuxppc_2_4_devel/drivers/usb/host/Config.in linuxppc_2_4_devel.modified/drivers/usb/host/Config.in --- linuxppc_2_4_devel/drivers/usb/host/Config.in 2006-07-06 23:28:01.000000000 +0200 +++ linuxppc_2_4_devel.modified/drivers/usb/host/Config.in 2006-12-04 10:10:15.000000000 +0100 @@ -26,9 +26,9 @@ define_bool CONFIG_PCIDUMMY y fi fi - if [ "$CONFIG_USB_USEBOTH" = "y" ]; then - define_bool CONFIG_PPC_5xxx_FEC n - fi +# if [ "$CONFIG_USB_USEBOTH" = "y" ]; then +# define_bool CONFIG_PPC_5xxx_FEC n +# fi else define_bool CONFIG_USB_OHCI_5xxx n fi diff --exclude CVS -uNr linuxppc_2_4_devel/include/asm-ppc/mpc5xxx.h linuxppc_2_4_devel.modified/include/asm-ppc/mpc5xxx.h --- linuxppc_2_4_devel/include/asm-ppc/mpc5xxx.h 2006-04-27 13:07:31.000000000 +0200 +++ linuxppc_2_4_devel.modified/include/asm-ppc/mpc5xxx.h 2007-02-01 09:06:43.000000000 +0100 @@ -118,6 +118,8 @@ #define MPC5xxx_WU_GPIO_DIR (MPC5xxx_WU_GPIO + 0x0008) #define MPC5xxx_WU_GPIO_DATAOUT (MPC5xxx_WU_GPIO + 0x000c) #define MPC5xxx_WU_GPIO_DATAIN (MPC5xxx_WU_GPIO + 0x0020) +#define MPC5xxx_WU_GPIO_ODE (MPC5xxx_WU_GPIO + 0x0004) +#define MPC5xxx_WU_GPIO_IRQ (MPC5xxx_WU_GPIO + 0x0014) /* MSCAN control register 0 (CANCTL0) bits */ #define MPC5xxx_MSCAN_RXFRM 0x80 @@ -823,6 +825,17 @@ volatile u32 sr; /* Status Register */ }; +struct mpc5xxx_gpt_0_7 { + struct mpc5xxx_gpt gpt0; + struct mpc5xxx_gpt gpt1; + struct mpc5xxx_gpt gpt2; + struct mpc5xxx_gpt gpt3; + struct mpc5xxx_gpt gpt4; + struct mpc5xxx_gpt gpt5; + struct mpc5xxx_gpt gpt6; + struct mpc5xxx_gpt gpt7; +}; + #define MPC5xxx_SDMA_VAR_SIZE 256 #define MPC5xxx_SDMA_VAR_ALIGN_SHIFT 8 #define MPC5xxx_SDMA_FDT_SIZE 128 diff --exclude CVS -uNr linuxppc_2_4_devel/include/asm-ppc/termios.h linuxppc_2_4_devel.modified/include/asm-ppc/termios.h --- linuxppc_2_4_devel/include/asm-ppc/termios.h 2003-10-30 01:34:06.000000000 +0100 +++ linuxppc_2_4_devel.modified/include/asm-ppc/termios.h 2006-08-14 14:00:40.000000000 +0200 @@ -87,6 +87,7 @@ #define TIOCMSET 0x5418 #define TIOCGSOFTCAR 0x5419 #define TIOCSSOFTCAR 0x541A +#define MECH_RESET_KATANA 0x5421 #define TIOCLINUX 0x541C #define TIOCCONS 0x541D #define TIOCGSERIAL 0x541E diff --exclude CVS -uNr linuxppc_2_4_devel/include/linux/netdevice.h linuxppc_2_4_devel.modified/include/linux/netdevice.h --- linuxppc_2_4_devel/include/linux/netdevice.h 2004-08-02 23:21:37.000000000 +0200 +++ linuxppc_2_4_devel.modified/include/linux/netdevice.h 2007-02-01 09:02:04.000000000 +0100 @@ -469,6 +469,11 @@ struct packet_type *next; }; +static inline void *netdev_priv(struct net_device *dev) +{ + return dev->priv; +} + #include #include diff --exclude CVS -uNr linuxppc_2_4_devel/include/linux/usb_gadget.h linuxppc_2_4_devel.modified/include/linux/usb_gadget.h --- linuxppc_2_4_devel/include/linux/usb_gadget.h 2005-06-10 18:27:30.000000000 +0200 +++ linuxppc_2_4_devel.modified/include/linux/usb_gadget.h 2006-03-31 14:46:58.000000000 +0200 @@ -115,7 +115,7 @@ void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned bytes); // NOTE: on 2.6, drivers may also use dma_map() and - // dma_sync_single_*() to directly manage dma overhead. + // dma_sync_single_*() to directly manage dma overhead. int (*queue) (struct usb_ep *ep, struct usb_request *req, int gfp_flags); @@ -886,17 +886,10 @@ /* utility wrapping a simple endpoint selection policy */ -#if 0 /* test-only */ extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, struct usb_endpoint_descriptor *) __init; extern void usb_ep_autoconfig_reset (struct usb_gadget *) __init; -#else -extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, - struct usb_endpoint_descriptor *); - -extern void usb_ep_autoconfig_reset (struct usb_gadget *); -#endif #endif /* __KERNEL__ */