diff -urN linux-2.4.24/CREDITS linux-2.4.25/CREDITS --- linux-2.4.24/CREDITS 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/CREDITS 2004-02-18 05:36:30.000000000 -0800 @@ -83,13 +83,13 @@ S: USA N: Erik Andersen -E: andersee@debian.org -W: http://www.xmission.com/~andersen -P: 1024/FC4CFFED 78 3C 6A 19 FA 5D 92 5A FB AC 7B A5 A5 E1 FF 8E +E: andersen@codepoet.org +W: http://www.codepoet.org/ +P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301 0C82 5F9B 643E 30D3 9057 D: Maintainer of ide-cd and Uniform CD-ROM driver, D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update. -S: 4538 South Carnegie Tech Street -S: Salt Lake City, Utah 84120 +S: 352 North 525 East +S: Springville, Utah 84663 S: USA N: Michael Ang @@ -848,8 +848,8 @@ W: http://www.pi.se/blox/ D: Extended support for loadable modules D: D-Link pocket adapter drivers -S: Grevgatan 11 -S: S-114 53 Stockholm +S: Brevia 1043 +S: S-114 79 Stockholm S: Sweden N: Michael Engel @@ -1345,6 +1345,7 @@ N: Marcel Holtmann E: marcel@holtmann.org W: http://www.holtmann.org +D: Maintainer of the Linux Bluetooth Subsystem D: Author and maintainer of the various Bluetooth HCI drivers D: Author and maintainer of the CAPI message transport protocol driver D: Various other Bluetooth related patches, cleanups and fixes @@ -1871,6 +1872,12 @@ S: Niwot, Colorado 80503 S: USA +N: Pete Popov +E: pete_popov@yahoo.com +D: Linux/MIPS AMD/Alchemy Port and mips hacking and debugging +S: San Jose, CA 95134 +S: USA + N: Robert M. Love E: rml@tech9.net E: rml@ufl.edu @@ -2591,9 +2598,9 @@ S: USA N: Luca Risolia -E: luca_ing@libero.it -D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chip -S: Via Libertà 41/a +E: luca.risolia@studio.unibo.it +D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips +S: Via Liberta' 41-A S: Osio Sotto, 24046, Bergamo S: Italy @@ -2662,6 +2669,7 @@ N: Aristeu Sergio Rozanski Filho E: aris@conectiva.com.br D: Support for EtherExpress 10 ISA (i82595) in eepro driver +D: User level driver support for input S: Conectiva S.A. S: R. Tocantins, 89 - Cristo Rei S: 80050-430 - Curitiba - Paraná diff -urN linux-2.4.24/Documentation/Changes linux-2.4.25/Documentation/Changes --- linux-2.4.24/Documentation/Changes 2002-11-28 15:53:08.000000000 -0800 +++ linux-2.4.25/Documentation/Changes 2004-02-18 05:36:30.000000000 -0800 @@ -56,7 +56,9 @@ o e2fsprogs 1.25 # tune2fs o jfsutils 1.0.12 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs +o xfsprogs 2.6.0 # xfs_db -V o pcmcia-cs 3.1.21 # cardmgr -V +o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version @@ -190,6 +192,16 @@ versions of mkreiserfs, resize_reiserfs, debugreiserfs and reiserfsck. These utils work on both i386 and alpha platforms. +Xfsprogs +-------- + +The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the +xfs_repair utilities, among others, for the XFS filesystem. It is +architecture independent and any version from 2.0.0 onward should +work correctly with this version of the XFS kernel code (2.6.0 or +later is recommended, due to some significant improvements). + + Pcmcia-cs --------- @@ -197,6 +209,14 @@ kernel source. Pay attention when you recompile your kernel ;-). Also, be sure to upgrade to the latest pcmcia-cs release. +Quota-tools +----------- + +Support for 32 bit uid's and gid's is required if you want to use +the newer version 2 quota format. Quota-tools version 3.07 and +newer has this support. Use the recommended version or newer +from the table above. + Intel IA32 microcode -------------------- @@ -327,6 +347,10 @@ ------------- o +Xfsprogs +-------- +o + LVM toolset ----------- o @@ -335,6 +359,10 @@ --------- o +Quota-tools +---------- +o + Jade ---- o diff -urN linux-2.4.24/Documentation/Configure.help linux-2.4.25/Documentation/Configure.help --- linux-2.4.24/Documentation/Configure.help 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/Configure.help 2004-02-18 05:36:30.000000000 -0800 @@ -412,6 +412,20 @@ Otherwise low memory pages are used as bounce buffers causing a degrade in performance. +OOM killer support +CONFIG_OOM_KILLER + This option selects the kernel behaviour during total out of memory + condition. + + The default behaviour is to, as soon as no freeable memory and no swap + space are available, kill the task which tries to allocate memory. + The default behaviour is very reliable. + + If you select this option, as soon as no freeable memory is available, + the kernel will try to select the "best" task to be killed. + + If unsure, say N. + Normal floppy disk support CONFIG_BLK_DEV_FD If you want to use the floppy disk drive(s) of your PC under Linux, @@ -1485,12 +1499,15 @@ Amiga Gayle IDE interface support CONFIG_BLK_DEV_GAYLE - This is the IDE driver for the builtin IDE interface on some Amiga - models. It supports both the `A1200 style' (used in A600 and A1200) - and `A4000 style' (used in A4000 and A4000T) of the Gayle IDE - interface. Say Y if you have such an Amiga model and want to use IDE - devices (hard disks, CD-ROM drives, etc.) that are connected to the - builtin IDE interface. + This is the IDE driver for the Amiga Gayle IDE interface. It supports + both the `A1200 style' and `A4000 style' of the Gayle IDE interface, + This includes builtin IDE interfaces on some Amiga models (A600, + A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion + bus (M-Tech E-Matrix 530 expansion card). + Say Y if you have an Amiga with a Gayle IDE interface and want to use + IDE devices (hard disks, CD-ROM drives, etc.) that are connected to it. + Note that you also have to enable Zorro bus support if you want to + use Gayle IDE interfaces on the Zorro expansion bus. Falcon IDE interface support CONFIG_BLK_DEV_FALCON_IDE @@ -1523,12 +1540,6 @@ Say Y if you have an IDE doubler. The driver is enabled at kernel runtime using the "ide=doubler" kernel boot parameter. -WarpEngine SCSI support -CONFIG_WARPENGINE_SCSI - Support for MacroSystem Development's WarpEngine Amiga SCSI-2 - controller. Info at - . - Builtin PowerMac IDE support CONFIG_BLK_DEV_IDE_PMAC This driver provides support for the built-in IDE controller on @@ -2079,7 +2090,7 @@ This is a machine with a R4400 133/150 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for Algorithmics P4032 (EXPERIMENTAL) CONFIG_ALGOR_P4032 @@ -2102,7 +2113,7 @@ CONFIG_BAGET_MIPS This enables support for the Baget, a Russian embedded system. For more details about the Baget see the Linux/MIPS FAQ on - . + . Baget AMD LANCE support CONFIG_BAGETLANCE @@ -2113,7 +2124,7 @@ Support for DECstations CONFIG_DECSTATION This enables support for DEC's MIPS based workstations. For details - see the Linux/MIPS FAQ on and the + see the Linux/MIPS FAQ on and the DECstation porting pages on . If you have one of the following DECstation Models you definitely @@ -2240,6 +2251,13 @@ Handle and keep statistics on the bus error interrupts (COR_ECC, BAD_ECC, IO_BUS). +Bus trace dump on bus error +CONFIG_SIBYTE_BW_TRACE + Run a continuous bus trace, dumping the raw data as soon as a ZBbus + error is detected. Cannot work if ZBbus profiling is turned on, and + also will interfere with JTAG-based trace buffer activity. Raw + buffer data is dumped to console, and must be processed off-line. + Corelis Debugger CONFIG_SB1XXX_CORELIS Select compile flags that produce code that can be processed by the @@ -2264,7 +2282,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Enable Qtronix 990P Keyboard Support CONFIG_QTRONIX_KEYBOARD @@ -2276,7 +2294,7 @@ This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - . + . Support for SNI RM200 PCI CONFIG_SNI_RM200_PCI @@ -3235,11 +3253,32 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +ARP tables support +CONFIG_IP_NF_ARPTABLES + arptables is a general, extensible packet identification framework. + The ARP packet filtering and mangling (manipulation)subsystems + use this: say Y or M here if you want to use either of those. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +ARP packet filtering +CONFIG_IP_NF_ARPFILTER + ARP packet filtering defines a table `filter', which has a series of + rules for simple ARP packet filtering at local input and + local output. See the man page for arptables(8). + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + ARP payload mangling CONFIG_IP_NF_ARP_MANGLE Allows altering the ARP packet payload: source and destination hardware and network addresses. + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + TCP Explicit Congestion Notification support CONFIG_INET_ECN Explicit Congestion Notification (ECN) allows routers to notify @@ -3888,6 +3927,24 @@ via the file /proc/rtc and its behaviour is set by various ioctls on /dev/rtc. +Dallas DS1742 RTC Support +CONFIG_DS1742 + If you say Y here and create a character special file /dev/rtc with + major number 10 and minor number 135 using mknod ("man mknod"), you + will get access to the real time clock present on various Toshiba + MIPS-based boards. It reports status information via the file + /proc/driver/rtc and its behaviour is set by various ioctls on + /dev/rtc or /dev/misc/rtc if using devfs. + + For technical information and application notes, please see the + Dallas Semiconductor website: + . + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called ds1742.o. If you want to compile it as a module, + say M here and read . + Indy/I2 Hardware Watchdog CONFIG_INDYDOG Hardwaredriver for the Indy's/I2's watchdog. This is a @@ -4951,6 +5008,11 @@ DECstation series (Personal DECstation 5000/20, /25, /33, /50, Codename "Maxine"). +PMAG-AA TURBOchannel framebuffer support +CONFIG_FB_PMAG_AA + Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) + used mainly in the MIPS-based DECstation series. + PMAG-BA TURBOchannel framebuffer support CONFIG_FB_PMAG_BA Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) @@ -10585,6 +10647,15 @@ whenever you want). If you want to compile it as a module, say M here and read . +CONFIG_NET_SCH_HFSC + Say Y here if you want to use the Hierarchical Fair Service Curve + (HFSC) packet scheduling algorithm for some of your network devices. + + This code is also available as a module called sch_hfsc.o ( = code + which can be inserted in and removed from the running kernel + whenever you want). If you want to compile it as a module, say M + here and read . + CSZ packet scheduler CONFIG_NET_SCH_CSZ Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet @@ -11114,9 +11185,6 @@ You must say Y to "/proc file system support" (CONFIG_PROC_FS) to use this driver. - If you want to compile this as a module, say M and read - . The module will be called comx.o. - Support for COMX/CMX/HiCOMX boards CONFIG_COMX_HW_COMX Hardware driver for the 'CMX', 'COMX' and 'HiCOMX' boards from the @@ -11310,6 +11378,39 @@ If unsure, say N here. +Cyclades-PC300 support +CONFIG_PC300 + This is a driver for the Cyclades-PC300 synchronous communication + boards. These boards provide synchronous serial interfaces to your + Linux box (interfaces currently available are RS-232/V.35, X.21 and + T1/E1). If you wish to support Multilink PPP, please select the + option below this one and read the file README.mlppp provided by PC300 + package. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called pc300.o. + + If you haven't heard about it, it's safe to say N. + +Cyclades-PC300 Sync TTY (to MLPPP) support +CONFIG_PC300_MLPPP + Say 'Y' to this option if you are planning to use Multilink PPP over the + PC300 synchronous communication boards. + +CONFIG_PCI200SYN + This driver is for PCI200SYN cards made by Goramo sp. j. + If you have such a card, say Y or M here and see + + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called pci200syn.o. + + If unsure, say N here. + SDL RISCom/N2 support CONFIG_N2 This driver is for RISCom/N2 single or dual channel ISA cards @@ -11338,25 +11439,6 @@ If unsure, say N here. -CONFIG_HDLC_DEBUG_PKT - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_HARD_HEADER - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_ECN - This option is for developers only - do NOT use on production - systems. - -CONFIG_HDLC_DEBUG_RINGS - If you answer Y here you will be able to get a diagnostic dump of - port's TX and RX packet rings, using "sethdlc hdlcX private" - command. It does not affect normal operations. - - If unsure, say Y here. - Ethernet (10 or 100Mbit) CONFIG_NET_ETHERNET Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common @@ -11704,9 +11786,11 @@ - EG1032 v2 Instant Gigabit Network Adapter - EG1064 v2 Instant Gigabit Network Adapter - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) + - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) - Marvell RDK-8001 Adapter @@ -11782,6 +11866,24 @@ say M here and read . This is recommended. The module will be called tg3.o. +MV-64340 Ethernet support +CONFIG_MV64340_ETH + This driver supports the Marvell Discovery II MV64340 device + as an Ethernet controller. Say Y here and select Port 0,1,2 + as needed. Otherwise, say N. + +MV-64340 Port 0 +CONFIG_MV64340_ETH_0 + Enable port 0 on the MV64340 Ethernet controller. + +MV-64340 Port 1 +CONFIG_MV64340_ETH_1 + Enable port 1 on the MV64340 Ethernet controller. + +MV-64340 Port 2 +CONFIG_MV64340_ETH_2 + Enable port 2 on the MV64340 Ethernet controller. + MyriCOM Gigabit Ethernet support CONFIG_MYRI_SBUS This driver supports MyriCOM Sbus gigabit Ethernet cards. @@ -14365,7 +14467,7 @@ DEC MS02-NV NVRAM module support CONFIG_MTD_MS02NV - This is a MTD driver for the DEC's MS02-NV (54-20948-01) battery + This is an MTD driver for the DEC's MS02-NV (54-20948-01) battery backed-up NVRAM module. The module was originally meant as an NFS accelerator. Say Y here if you have a DECstation 5000/2x0 or a DECsystem 5900 equipped with such a module. @@ -14804,6 +14906,16 @@ If unsure, say Y. +HP OB600 C/CT Pop-Up Mouse +CONFIG_OBMOUSE + Only add this driver if you have an Omnibook 600C or 600CT laptop. + This driver has no probe routine and must assume ports 0x238-23b + belong to the Pop-Up mouse. Depends on CONFIG_INPUT_MOUSEDEV. + + Best is to use a module and load the obmouse driver at runtime. + Say M here and read . + + Input core support CONFIG_INPUT Say Y here if you want to enable any of the following options for @@ -14870,6 +14982,15 @@ accessible under char device 13:64+ - /dev/input/eventX in a generic way. This is the future ... +CONFIG_INPUT_UINPUT + Say Y here if you want to support user level drivers for input + subsystem accessible under char device 10:223 - /dev/input/uinput. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called uinput.o. If you want to compile it as a + module, say M here and read . + USB Scanner support CONFIG_USB_SCANNER Say Y here if you want to connect a USB scanner to your computer's @@ -15302,19 +15423,18 @@ This driver has an optional plugin, which is distributed as a separate module only (released under GPL). It contains code that - allows you to use higher resolutions and framerates, and can't - be included into the official Linux kernel for performance - purposes. - At the moment the driver needs a third-part module for the CMOS + allows you to use higher resolutions and framerates, and cannot + be included in the official Linux kernel for performance purposes. + At the moment the driver needs a third-party module for the CMOS sensors, which is available on internet: it is recommended to read for more informations and for a list of supported cameras. This driver uses the Video For Linux and the I2C APIs. - You must say Y or M to both "Video For Linux" and - "I2C Support" to use this driver. - Information on this API and pointers to "v4l" programs may be found - on the WWW at . + You must say Y or M to both "Video For Linux" and "I2C Support" + to use this driver. Information on this API and pointers to "v4l" + programs may be found on the WWW at + . This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -15509,24 +15629,6 @@ The module will be called catc.o. If you want to compile it as a module, say M here and read . -USB ASIX AX88172 based ethernet device support -CONFIG_USB_AX8817X - Say Y if you want to use one of the following 10/100 USB2 Ethernet - devices based on the ASIX AX88172 chip. Supported devices are: - Linksys USB200M - Netgear FA120 - D-Link DUB-E100 - Hawking UF200 - - This driver makes the adapter appear as a normal Ethernet interface, - typically on eth0, if it is the only ethernet device, or perhaps on - eth1, if you have a PCI or ISA ethernet card installed. - - This code is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called ax8817x.o. If you want to compile it as a - module, say M here and read . - USB Kodak DC-2xx Camera support CONFIG_USB_DC2XX Say Y here if you want to connect this type of still camera to your @@ -17183,6 +17285,80 @@ Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. +XFS filesystem support +CONFIG_XFS_FS + XFS is a high performance journaling filesystem which originated + on the SGI IRIX platform. It is completely multi-threaded, can + support large files and large filesystems, extended attributes, + variable block sizes, is extent based, and makes extensive use of + Btrees (directories, extents, free space) to aid both performance + and scalability. + + Refer to the documentation at + for complete details. This implementation is on-disk compatible + with the IRIX version of XFS. + + If you want to compile this file system as a module ( = code which + can be inserted in and removed from the running kernel whenever you + want), say M here and read . The + module will be called xfs.o. Be aware, however, that if the file + system of your root partition is compiled as a module, you'll need + to use an initial ramdisk (initrd) to boot. + +Quota support +CONFIG_XFS_QUOTA + If you say Y here, you will be able to set limits for disk usage on + a per user and/or per group basis under XFS. XFS considers quota + information as filesystem metadata and uses journaling to provide a + higher level guarantee of consistency. The on-disk data format for + quota is also compatible with the IRIX version of XFS, allowing a + filesystem to be migrated between Linux and IRIX without any need + for conversion. + + If unsure, say N. More comprehensive documentation can be found in + README.quota in the xfsprogs package. XFS quota can be used either + with or without the generic quota support enabled (CONFIG_QUOTA) - + they are completely independent subsystems. + +Realtime support (EXPERIMENTAL) +CONFIG_XFS_RT + If you say Y here you will be able to mount and use XFS filesystems + which contain a realtime subvolume. The realtime subvolume is a + separate area of disk space where only file data is stored. The + realtime subvolume is designed to provide very deterministic + data rates suitable for media streaming applications. + + See the xfs man page in section 5 for a bit more information. + + This feature is unsupported at this time, is not yet fully + functional, and may cause serious problems. + + If unsure, say N. + +Tracing support (EXPERIMENTAL) +CONFIG_XFS_TRACE + Say Y here to get an XFS build with activity tracing enabled. + Enabling this option will attach historical information to XFS + inodes, pagebufs, certain locks, the log, the IO path, and a + few other key areas within XFS. These traces can be examined + using a kernel debugger. + + Note that for the pagebuf traces, you will also have to enable + the sysctl in /proc/sys/vm/pagebuf/debug for this to work. + + Say N unless you are an XFS developer. + +Debugging support (EXPERIMENTAL) +CONFIG_XFS_DEBUG + Say Y here to get an XFS build with many debugging features, + including ASSERT checks, function wrappers around macros, + and extra sanity-checking functions in various code paths. + + Note that the resulting code will be HUGE and SLOW, and probably + not useful unless you are debugging a particular problem. + + Say N unless you are an XFS developer, or play one on TV. + Advanced partition selection CONFIG_PARTITION_ADVANCED Say Y here if you would like to use hard disks under Linux which @@ -17489,6 +17665,17 @@ smbmount from samba 2.2.0 or later supports this. +Enable Unix Extensions +CONFIG_SMB_UNIX + Enabling this will make smbfs use the CIFS Unix Extensions if + supported by the server. These extensions allows use of unix user + ids, permissions, file modes, symlinks, etc that normally do not + work on smbfs. + + Samba 3.0 servers supports these extensions. + + If you don't know what all this is about, it is safe to say Y. + Coda file system support (advanced network fs) CONFIG_CODA_FS Coda is an advanced network file system, similar to NFS in that it @@ -18819,7 +19006,7 @@ Say Y here to support the on-board sound generator on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . I2C support CONFIG_I2C @@ -18888,9 +19075,9 @@ . The module will be called i2c-elv.o. -Velleman K9000 adapter +Velleman K8000 adapter CONFIG_I2C_VELLEMAN - This supports the Velleman K9000 parallel-port I2C adapter. Say Y + This supports the Velleman K8000 parallel-port I2C adapter. Say Y if you own such an adapter. This driver is also available as a module. If you want to compile @@ -18951,6 +19138,11 @@ sensor. Currently the device is only supported on a SiByte I2C adapter, and the driver prints status updates to the system log. +SGI I2C Algorithm +CONFIG_I2C_ALGO_SGI + Supports the SGI interfaces like the ones found on SGI Indy VINO + or SGI O2 MACE. + I2C device interface CONFIG_I2C_CHARDEV Say Y here to use i2c-* device files, usually found in the /dev @@ -21738,14 +21930,14 @@ This is an evaluation board based on the Galileo GT-64120 single-chip system controller that contains a MIPS R5000 compatible core running at 75/100MHz. Their website is located at - . Say Y here if you wish to build a + . Say Y here if you wish to build a kernel for this platform. Galileo EV96100 Evaluation board CONFIG_MIPS_EV96100 This is an evaluation board based on the Galielo GT-96100 LAN/WAN communications controllers containing a MIPS R5000 compatible core - running at 83MHz. Their website is . Say Y + running at 83MHz. Their website is . Say Y here if you wish to build a kernel for this platform. Support for ITE 8172G board @@ -21761,8 +21953,8 @@ This is an evaluation board built by Globespan to showcase their iVR (Internet Video Recorder) design. It utilizes a QED RM5231 R5000 MIPS core. More information can be found out their website - located at P. Say Y - here if you wish to build a kernel for this platform. + located at . Say Y here if you wish to + build a kernel for this platform. Support for Alchemy Semi PB1000 board CONFIG_MIPS_PB1000 @@ -22850,7 +23042,7 @@ kernel or say M to compile it as module (hci_usb.o). HCI USB SCO (voice) support -CONFIG_BLUEZ_USB_SCO +CONFIG_BLUEZ_HCIUSB_SCO This option enables the SCO support in the HCI USB driver. You need this to transmit voice data with your Bluetooth USB device. And your device must also support sending SCO data over the HCI layer, because some of @@ -22858,14 +23050,6 @@ Say Y here to compile support for HCI SCO data. -HCI USB zero packet support -CONFIG_BLUEZ_USB_ZERO_PACKET - This option is provided only as a work around for buggy Bluetooth USB - devices. Do NOT enable it unless you know for sure that your device - requires zero packets. - - Most people should say N here. - HCI VHCI Virtual HCI device driver CONFIG_BLUEZ_HCIVHCI Bluetooth Virtual HCI device driver. @@ -23010,15 +23194,22 @@ "ser_a2232.o". If you want to do this, answer M here and read "". -A4000T SCSI support -CONFIG_A4000T_SCSI - Support for the NCR53C710 SCSI controller on the Amiga 4000T. - -A4091 SCSI support -CONFIG_A4091_SCSI - Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller - (1993). Very obscure -- the 4091 was part of an Amiga 4000 upgrade - plan at the time the Amiga business was sold to DKB. +Amiga NCR53c710 SCSI support +CONFIG_SCSI_AMIGA7XX + Support for various NCR53c710-based SCSI controllers on the Amiga. + This includes: + - the builtin SCSI controller on the Amiga 4000T, + - the Amiga 4091 Zorro III SCSI-2 controller, + - the MacroSystem Development's WarpEngine Amiga SCSI-2 controller + (info at + ), + - the SCSI controller on the Phase5 Blizzard PowerUP 603e+ + accelerator card for the Amiga 1200, + - the SCSI controller on the GVP Turbo 040/060 accelerator. + Note that all of the above SCSI controllers, except for the builtin + SCSI controller on the Amiga 4000T, reside on the Zorro expansion + bus, so you also have to enable Zorro bus support if you want to use + them. Atari support CONFIG_ATARI @@ -23340,11 +23531,6 @@ 1260 accelerator, and the optional SCSI module, say Y. Otherwise, say N. -Blizzard PowerUP 603e+ SCSI support -CONFIG_BLZ603EPLUS_SCSI - If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+ - accelerator, say Y. Otherwise, say N. - Fastlane SCSI support CONFIG_FASTLANE_SCSI If you have the Phase5 Fastlane Z3 SCSI controller, or plan to use @@ -23744,7 +23930,7 @@ PCMCIA interface (example: IDIF860 systems) Use SMC2 for UART -CONFIG_SMC2_UART +CONFIG_8xx_SMC2 If you would like to use SMC2 as a serial port, say Y here. If in doubt, say Y here. @@ -24264,6 +24450,11 @@ If unsure, say Y. +Support for Lpar Configuration data in /proc +CONFIG_LPARCFG + This option adds lparcfg entry as /proc/ppc64/lparcfg which returns + system configuration info in = pairs. + MESH (Power Mac internal SCSI) support CONFIG_SCSI_MESH Many Power Macintoshes and clones have a MESH (Macintosh Enhanced @@ -24738,8 +24929,8 @@ SGI Vino Video For Linux CONFIG_VIDEO_VINO - Say Y here to build in support for the Vino video input system found - on SGI Indy machines. + Say Y here to include support for SGI VINO (Video In No Out) system + found on SGI Indy workstations. Stradis 4:2:2 MPEG-2 video driver CONFIG_VIDEO_STRADIS @@ -26157,6 +26348,14 @@ here and read . The module will be called smc-ircc.o. +VIA IrCC +CONFIG_VIA_IRCC_FIR + Say Y here if you want to build support for the VIA Fast Infrared + Communications Controller. It is used in all sorts of VIA686a- and + VT1211-based notebooks. If you want to compile it as a module, say M + here and read . The module will be + called via-ircc.o. + ALi M5123 FIR controller driver CONFIG_ALI_FIR Say Y here if you want to build support for the ALi M5123 FIR @@ -27150,16 +27349,11 @@ will run on any supported IA-64 system. However, if you configure a kernel for your specific system, it will be faster and smaller. - To find out what type of IA-64 system you have, you may want to - check the IA-64 Linux web site at . - As of the time of this writing, most hardware is DIG compliant, - so the "DIG-compliant" option is usually the right choice. - - HP-simulator For the HP simulator (). - HP-zx1 For HP zx1 Platforms. - SN1 For SGI SN1 Platforms. - SN2 For SGI SN2 Platforms. - DIG-compliant For DIG ("Developer's Interface Guide") compliant systems. + generic For any supported IA-64 system + DIG-compliant For DIG ("Developer's Interface Guide") compliant systems + HP For HP systems + SGI-SN2 For SGI SN2 systems + Ski-simulator For the HP simulator () If you don't know what to do, choose "generic". @@ -27446,7 +27640,7 @@ Include kgdb kernel debugger CONFIG_KGDB Include in-kernel hooks for kgdb, the Linux kernel source level - debugger. This project has a web page at + debugger. For i386 architecture there is project page at . Include xmon kernel debugger @@ -27893,7 +28087,7 @@ Say Y here to support the on-board IDE controller on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Support ARM926T processor CONFIG_CPU_ARM926T @@ -28061,21 +28255,21 @@ Say Y here to support the older, Revision C version of the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Enable Smart Card Reader 0 Support CONFIG_IT8172_SCR0 Say Y here to support smart-card reader 0 (SCR0) on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . Enable Smart Card Reader 1 Support CONFIG_IT8172_SCR1 Say Y here to support smart-card reader 1 (SCR1) on the Integrated Technology Express, Inc. ITE8172 SBC. Vendor page at ; picture of the - board at . + board at . IT8172 IDE Tuning support CONFIG_IT8172_TUNING @@ -28113,6 +28307,14 @@ This support is also available as a module. If compiled as a module, it will be called scx200.o. +NatSemi SCx200 GPIO support +CONFIG_SCx200_GPIO + Give userspace access to the GPIO pins on the National + Semiconductor SCx200 processors. + + This support is also available as a module. If compiled as a + module, it will be called scx200_gpio.o. + NatSemi SCx200 Watchdog CONFIG_SCx200_WDT Enable the built-in watchdog timer support on the National @@ -28264,7 +28466,7 @@ If compiled as a module, it will be called uclinux.o. NatSemi SCx200 I2C using GPIO pins -CONFIG_SCx200_GPIO +CONFIG_SCx200_I2C Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. If you don't know what to do here, say N. @@ -28493,6 +28695,12 @@ The CAST5 encryption algorithm (synonymous with CAST-128) is described in RFC2144. +CONFIG_CRYPTO_CAST6 + CAST6 (CAST-256) cipher algorithm. + + The CAST6 encryption algorithm (synonymous with CAST-256) is + described in RFC2612. + CONFIG_CRYPTO_DEFLATE This is the Deflate algorithm (RFC1951), specified for use in IPSec with the IPCOMP protocol (RFC3173, RFC2394). diff -urN linux-2.4.24/Documentation/SubmittingDrivers linux-2.4.25/Documentation/SubmittingDrivers --- linux-2.4.24/Documentation/SubmittingDrivers 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/SubmittingDrivers 2004-02-18 05:36:30.000000000 -0800 @@ -35,7 +35,7 @@ Linux 2.4: The same rules apply as 2.2. The final contact point for Linux 2.4 - submissions is Marcelo Tosatti . + submissions is Marcelo Tosatti . Linux 2.5: The same rules apply as 2.4 except that you should follow linux-kernel diff -urN linux-2.4.24/Documentation/crypto/api-intro.txt linux-2.4.25/Documentation/crypto/api-intro.txt --- linux-2.4.24/Documentation/crypto/api-intro.txt 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/crypto/api-intro.txt 2004-02-18 05:36:30.000000000 -0800 @@ -213,7 +213,7 @@ Kyle McMartin Adam J. Richter -CAST5 algorithm contributors: +CAST5/CAST6 algorithm contributors: Kartikey Mahendra Bhatt (original developers unknown, FSF copyright). Generic scatterwalk code by Adam J. Richter diff -urN linux-2.4.24/Documentation/devices.txt linux-2.4.25/Documentation/devices.txt --- linux-2.4.24/Documentation/devices.txt 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/Documentation/devices.txt 2004-02-18 05:36:30.000000000 -0800 @@ -419,6 +419,7 @@ 220 = /dev/mptctl Message passing technology (MPT) control 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver 222 = /dev/mvista/hasi Montavista PICMG high availability + 223 = /dev/input/uinput User level driver support for input 240-255 Reserved for local use 11 char Raw keyboard device diff -urN linux-2.4.24/Documentation/filesystems/00-INDEX linux-2.4.25/Documentation/filesystems/00-INDEX --- linux-2.4.24/Documentation/filesystems/00-INDEX 2002-11-28 15:53:08.000000000 -0800 +++ linux-2.4.25/Documentation/filesystems/00-INDEX 2004-02-18 05:36:30.000000000 -0800 @@ -48,3 +48,5 @@ - info on using the VFAT filesystem used in Windows NT and Windows 95 vfs.txt - Overview of the Virtual File System +xfs.txt + - info and mount options for the XFS filesystem. diff -urN linux-2.4.24/Documentation/filesystems/xfs.txt linux-2.4.25/Documentation/filesystems/xfs.txt --- linux-2.4.24/Documentation/filesystems/xfs.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/Documentation/filesystems/xfs.txt 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,203 @@ + +The SGI XFS Filesystem +====================== + +XFS is a high performance journaling filesystem which originated +on the SGI IRIX platform. It is completely multi-threaded, can +support large files and large filesystems, extended attributes, +variable block sizes, is extent based, and makes extensive use of +Btrees (directories, extents, free space) to aid both performance +and scalability. + +Refer to the documentation at http://oss.sgi.com/projects/xfs/ +for further details. This implementation is on-disk compatible +with the IRIX version of XFS. + + +Mount Options +============= + +When mounting an XFS filesystem, the following options are accepted. + + biosize=size + Sets the preferred buffered I/O size (default size is 64K). + "size" must be expressed as the logarithm (base2) of the + desired I/O size. + Valid values for this option are 14 through 16, inclusive + (i.e. 16K, 32K, and 64K bytes). On machines with a 4K + pagesize, 13 (8K bytes) is also a valid size. + The preferred buffered I/O size can also be altered on an + individual file basis using the ioctl(2) system call. + + ikeep/noikeep + When inode clusters are emptied of inodes, keep them around + on the disk (ikeep) - this is the traditional XFS behaviour + and is still the default for now. Using the noikeep option, + inode clusters are returned to the free space pool. + + logbufs=value + Set the number of in-memory log buffers. Valid numbers range + from 2-8 inclusive. + The default value is 8 buffers for filesystems with a + blocksize of 64K, 4 buffers for filesystems with a blocksize + of 32K, 3 buffers for filesystems with a blocksize of 16K + and 2 buffers for all other configurations. Increasing the + number of buffers may increase performance on some workloads + at the cost of the memory used for the additional log buffers + and their associated control structures. + + logbsize=value + Set the size of each in-memory log buffer. + Size may be specified in bytes, or in kilobytes with a "k" suffix. + Valid sizes for version 1 and version 2 logs are 16384 (16k) and + 32768 (32k). Valid sizes for version 2 logs also include + 65536 (64k), 131072 (128k) and 262144 (256k). + The default value for machines with more than 32MB of memory + is 32768, machines with less memory use 16384 by default. + + logdev=device and rtdev=device + Use an external log (metadata journal) and/or real-time device. + An XFS filesystem has up to three parts: a data section, a log + section, and a real-time section. The real-time section is + optional, and the log section can be separate from the data + section or contained within it. + + noalign + Data allocations will not be aligned at stripe unit boundaries. + + noatime + Access timestamps are not updated when a file is read. + + norecovery + The filesystem will be mounted without running log recovery. + If the filesystem was not cleanly unmounted, it is likely to + be inconsistent when mounted in "norecovery" mode. + Some files or directories may not be accessible because of this. + Filesystems mounted "norecovery" must be mounted read-only or + the mount will fail. + + nouuid + Don't check for double mounted file systems using the file system uuid. + This is useful to mount LVM snapshot volumes. + + osyncisosync + Make O_SYNC writes implement true O_SYNC. WITHOUT this option, + Linux XFS behaves as if an "osyncisdsync" option is used, + which will make writes to files opened with the O_SYNC flag set + behave as if the O_DSYNC flag had been used instead. + This can result in better performance without compromising + data safety. + However if this option is not in effect, timestamp updates from + O_SYNC writes can be lost if the system crashes. + If timestamp updates are critical, use the osyncisosync option. + + quota/usrquota/uqnoenforce + User disk quota accounting enabled, and limits (optionally) + enforced. + + grpquota/gqnoenforce + Group disk quota accounting enabled and limits (optionally) + enforced. + + sunit=value and swidth=value + Used to specify the stripe unit and width for a RAID device or + a stripe volume. "value" must be specified in 512-byte block + units. + If this option is not specified and the filesystem was made on + a stripe volume or the stripe width or unit were specified for + the RAID device at mkfs time, then the mount system call will + restore the value from the superblock. For filesystems that + are made directly on RAID devices, these options can be used + to override the information in the superblock if the underlying + disk layout changes after the filesystem has been created. + The "swidth" option is required if the "sunit" option has been + specified, and must be a multiple of the "sunit" value. + +sysctls +======= + +The following sysctls are available for the XFS filesystem: + + fs.xfs.stats_clear (Min: 0 Default: 0 Max: 1) + Setting this to "1" clears accumulated XFS statistics + in /proc/fs/xfs/stat. It then immediately reset to "0". + + fs.xfs.sync_interval (Min: HZ Default: 30*HZ Max: 60*HZ) + The interval at which the xfssyncd thread for xfs filesystems + flushes metadata out to disk. This thread will flush log + activity out, and do some processing on unlinked inodes + + fs.xfs.error_level (Min: 0 Default: 3 Max: 11) + A volume knob for error reporting when internal errors occur. + This will generate detailed messages & backtraces for filesystem + shutdowns, for example. Current threshold values are: + + XFS_ERRLEVEL_OFF: 0 + XFS_ERRLEVEL_LOW: 1 + XFS_ERRLEVEL_HIGH: 5 + + fs.xfs.panic_mask (Min: 0 Default: 0 Max: 127) + Causes certain error conditions to call BUG(). Value is a bitmask; + AND together the tags which represent errors which should cause panics: + + XFS_NO_PTAG 0 + XFS_PTAG_IFLUSH 0x00000001 + XFS_PTAG_LOGRES 0x00000002 + XFS_PTAG_AILDELETE 0x00000004 + XFS_PTAG_ERROR_REPORT 0x00000008 + XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 + XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 + XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 + + This option is intended for debugging only. + + fs.xfs.irix_symlink_mode (Min: 0 Default: 0 Max: 1) + Controls whether symlinks are created with mode 0777 (default) + or whether their mode is affected by the umask (irix mode). + + fs.xfs.irix_sgid_inherit (Min: 0 Default: 0 Max: 1) + Controls files created in SGID directories. + If the group ID of the new file does not match the effective group + ID or one of the supplementary group IDs of the parent dir, the + ISGID bit is cleared if the irix_sgid_inherit compatibility sysctl + is set. + + fs.xfs.restrict_chown (Min: 0 Default: 1 Max: 1) + Controls whether unprivileged users can use chown to "give away" + a file to another user. + + fs.xfs.refcache_size (Min: 0 Default: 128 Max: 512) + Controls the size of the NFS refcache, which holds references + on files opened via NFS to improve performance. The value + is the maximum number of files which can be in the cache at + any one time. + + fs.xfs.refcache_purge (Min: 0 Default: 32 Max: 512) + Controls the number of entries purged from the NFS refcache + every sync interval. + + fs.xfs.inherit_sync (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "sync" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. + + fs.xfs.inherit_nodump (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "nodump" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. + + fs.xfs.inherit_noatime (Min: 0 Default: 1 Max 1) + Setting this to "1" will cause the "noatime" flag set + by the chattr(1) command on a directory to be + inherited by files in that directory. + + vm.pagebuf.stats_clear (Min: 0 Default: 0 Max: 1) + Setting this to "1" clears accumulated pagebuf statistics + in /proc/fs/pagebuf/stat. It then immediately reset to "0". + + vm.pagebuf.flush_age (Min: 1*HZ Default: 15*HZ Max: 300*HZ) + The age at which dirty metadata buffers are flushed to disk + + vm.pagebuf.flush_int (Min: HZ/2 Default: HZ Max: 30*HZ) + The interval at which the list of dirty metadata buffers is + scanned. diff -urN linux-2.4.24/Documentation/i2c/dev-interface linux-2.4.25/Documentation/i2c/dev-interface --- linux-2.4.24/Documentation/i2c/dev-interface 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/Documentation/i2c/dev-interface 2004-02-18 05:36:30.000000000 -0800 @@ -87,7 +87,7 @@ ioctl(file,I2C_TENBIT,long select) Selects ten bit addresses if select not equals 0, selects normal 7 bit - addresses if select equals 0. + addresses if select equals 0. Default 0. ioctl(file,I2C_FUNCS,unsigned long *funcs) Gets the adapter functionality and puts it in *funcs. diff -urN linux-2.4.24/Documentation/i2c/i2c-protocol linux-2.4.25/Documentation/i2c/i2c-protocol --- linux-2.4.24/Documentation/i2c/i2c-protocol 2000-07-28 12:50:51.000000000 -0700 +++ linux-2.4.25/Documentation/i2c/i2c-protocol 2004-02-18 05:36:30.000000000 -0800 @@ -52,10 +52,10 @@ We have found some I2C devices that needs the following modifications: Flag I2C_M_NOSTART: - In a combined transaction, no 'S Addr' is generated at some point. - For example, setting I2C_M_NOSTART on the second partial message + In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some + point. For example, setting I2C_M_NOSTART on the second partial message generates something like: - S Addr Rd [A] [Data] NA Wr [A] Data [A] P + S Addr Rd [A] [Data] NA Data [A] P If you set the I2C_M_NOSTART variable for the first partial message, we do not generate Addr, but we do generate the startbit S. This will probably confuse all other clients on your bus, so don't try this. @@ -65,4 +65,3 @@ need to emit an Rd instead of a Wr, or vice versa, you set this flag. For example: S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P - diff -urN linux-2.4.24/Documentation/i2c/i2c-velleman linux-2.4.25/Documentation/i2c/i2c-velleman --- linux-2.4.24/Documentation/i2c/i2c-velleman 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/Documentation/i2c/i2c-velleman 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,23 @@ +i2c-velleman driver +------------------- +This is a driver for i2c-hw access for Velleman K8000 and other adapters. + +Useful links +------------ +Velleman: + http://www.velleman.be/ + +Velleman K8000 Howto: + http://howto.htlw16.ac.at/k8000-howto.html + +K8000 and K8005 libraries +------------------------- +The project has lead to new libs for the Velleman K8000 and K8005: +LIBK8000 v1.99.1 and LIBK8005 v0.21 + +With these libs, you can control the K8000 interface card and the K8005 +stepper motor card with the simple commands which are in the original +Velleman software, like SetIOchannel, ReadADchannel, SendStepCCWFull and +many more, using /dev/velleman. + +The libs can be found on http://groups.yahoo.com/group/k8000/files/linux/ diff -urN linux-2.4.24/Documentation/i2c/smbus-protocol linux-2.4.25/Documentation/i2c/smbus-protocol --- linux-2.4.24/Documentation/i2c/smbus-protocol 2001-02-16 15:53:08.000000000 -0800 +++ linux-2.4.25/Documentation/i2c/smbus-protocol 2004-02-18 05:36:30.000000000 -0800 @@ -1,3 +1,10 @@ +SMBus Protocol Summary +====================== +The following is a summary of the SMBus protocol. It applies to +all revisions of the protocol (1.0, 1.1, and 2.0). +Certain protocol features which are not supported by +this package are briefly described at the end of this document. + Some adapters understand only the SMBus (System Management Bus) protocol, which is a subset from the I2C protocol. Fortunately, many devices use only the same subset, which makes it possible to put them on an SMBus. @@ -6,7 +13,7 @@ I2C protocol). This makes it possible to use the device driver on both SMBus adapters and I2C adapters (the SMBus command set is automatically translated to I2C on I2C adapters, but plain I2C commands can not be -handled at all on a pure SMBus adapter). +handled at all on most pure SMBus adapters). Below is a list of SMBus commands. @@ -54,7 +61,7 @@ This is the reverse of Read Byte: it sends a single byte to a device. See Read Byte for more information. -S Addr Wr [A] Data NA P +S Addr Wr [A] Data [A] P SMBus Read Byte Data @@ -109,7 +116,7 @@ SMBus Block Read ================ -This command reads a block of upto 32 bytes from a device, from a +This command reads a block of up to 32 bytes from a device, from a designated register that is specified through the Comm byte. The amount of data is specified by the device in the Count byte. @@ -120,8 +127,90 @@ SMBus Block Write ================= -The opposite of the Block Read command, this writes upto 32 bytes to +The opposite of the Block Read command, this writes up to 32 bytes to a device, to a designated register that is specified through the Comm byte. The amount of data is specified in the Count byte. S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P + + +SMBus Block Process Call +======================== + +SMBus Block Process Call was introduced in Revision 2.0 of the specification. + +This command selects a device register (through the Comm byte), sends +1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return. + +S Addr Wr [A] Comm [A] Count [A] Data [A] ... + S Addr Rd [A] [Count] A [Data] ... NA P + + +SMBus Host Notify +================= + +This command is sent from a SMBus device acting as a master to the +SMBus host acting as a slave. +It is the same form as Write Word, with the command code replaced by the +alerting device's address. + +[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P] + + +Packet Error Checking (PEC) +=========================== +Packet Error Checking was introduced in Revision 1.1 of the specification. + +PEC adds a CRC-8 error-checking byte to all transfers. + + +Address Resolution Protocol (ARP) +================================= +The Address Resolution Protocol was introduced in Revision 2.0 of +the specification. It is a higher-layer protocol which uses the +messages above. + +ARP adds device enumeration and dynamic address assignment to +the protocol. All ARP communications use slave address 0x61 and +require PEC checksums. + + +I2C Block Transactions +====================== +The following I2C block transactions are supported by the +SMBus layer and are described here for completeness. +I2C block transactions do not limit the number of bytes transferred +but the SMBus layer places a limit of 32 bytes. + + +I2C Block Read +============== + +This command reads a block of bytes from a device, from a +designated register that is specified through the Comm byte. + +S Addr Wr [A] Comm [A] + S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P + + +I2C Block Read (2 Comm bytes) +============================= + +This command reads a block of bytes from a device, from a +designated register that is specified through the two Comm bytes. + +S Addr Wr [A] Comm1 [A] Comm2 [A] + S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P + + +I2C Block Write +=============== + +The opposite of the Block Read command, this writes bytes to +a device, to a designated register that is specified through the +Comm byte. Note that command lengths of 0, 2, or more bytes are +supported as they are indistinguishable from data. + +S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P + + diff -urN linux-2.4.24/Documentation/i2c/summary linux-2.4.25/Documentation/i2c/summary --- linux-2.4.24/Documentation/i2c/summary 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/Documentation/i2c/summary 2004-02-18 05:36:30.000000000 -0800 @@ -4,7 +4,7 @@ ============= I2C (pronounce: I squared C) is a protocol developed by Philips. It is a -slow two-wire protocol (10-100 kHz), but it suffices for many types of +slow two-wire protocol (10-400 kHz), but it suffices for many types of devices. SMBus (System Management Bus) is a subset of the I2C protocol. Many @@ -43,15 +43,15 @@ Included Bus Drivers ==================== -Note that not only stable drivers are patched into the kernel by 'mkpatch'. +Note that only stable drivers are patched into the kernel by 'mkpatch'. Base modules ------------ -i2c-core: The basic I2C code, including the /proc interface -i2c-dev: The /dev interface -i2c-proc: The /proc interface for device (client) drivers +i2c-core: The basic I2C code, including the /proc/bus/i2c* interface +i2c-dev: The /dev/i2c-* interface +i2c-proc: The /proc/sys/dev/sensors interface for device (client) drivers Algorithm drivers ----------------- @@ -71,5 +71,5 @@ i2c-ppc405: IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT) i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit) i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT) -i2c-velleman: Velleman K9000 parallel port adapter (uses i2c-algo-bit) +i2c-velleman: Velleman K8000 parallel port adapter (uses i2c-algo-bit) diff -urN linux-2.4.24/Documentation/i2c/writing-clients linux-2.4.25/Documentation/i2c/writing-clients --- linux-2.4.24/Documentation/i2c/writing-clients 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/Documentation/i2c/writing-clients 2004-02-18 05:36:30.000000000 -0800 @@ -365,7 +365,7 @@ The detect client function is called by i2c_probe or i2c_detect. The `kind' parameter contains 0 if this call is due to a `force' -parameter, and 0 otherwise (for i2c_detect, it contains 0 if +parameter, and -1 otherwise (for i2c_detect, it contains 0 if this call is due to the generic `force' parameter, and the chip type number if it is due to a specific `force' parameter). @@ -448,9 +448,9 @@ /* Note that we reserve some space for foo_data too. If you don't need it, remove it. We do it here to help to lessen memory fragmentation. */ - if (! (new_client = kmalloc(sizeof(struct i2c_client)) + + if (! (new_client = kmalloc(sizeof(struct i2c_client) + sizeof(struct foo_data), - GFP_KERNEL)) { + GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } diff -urN linux-2.4.24/Documentation/i386/zero-page.txt linux-2.4.25/Documentation/i386/zero-page.txt --- linux-2.4.24/Documentation/i386/zero-page.txt 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/i386/zero-page.txt 2004-02-18 05:36:30.000000000 -0800 @@ -66,8 +66,12 @@ 0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image 0x220 4 bytes (setup.S) 0x224 unsigned short setup.S heap end pointer +0x228 4 bytes unknown, but writing this in setup.S makes + kernel fail to decompress on some systems +0x2cc 4 bytes DISK80_SIG_BUFFER (setup.S) 0x2d0 - 0x600 E820MAP -0x600 - 0x7D4 EDDBUF (setup.S) +0x600 - 0x7ff EDDBUF (setup.S) for disk signature read sector +0x600 - 0x7de EDDBUF (setup.S) 0x800 string, 2K max COMMAND_LINE, the kernel commandline as copied using CL_OFFSET. diff -urN linux-2.4.24/Documentation/m68k/00-INDEX linux-2.4.25/Documentation/m68k/00-INDEX --- linux-2.4.24/Documentation/m68k/00-INDEX 1997-11-29 10:33:18.000000000 -0800 +++ linux-2.4.25/Documentation/m68k/00-INDEX 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,5 @@ 00-INDEX - this file -framebuffer.txt - - info about the Linux/m68k frame buffer device kernel-options.txt - command line options for Linux/m68k diff -urN linux-2.4.24/Documentation/networking/sk98lin.txt linux-2.4.25/Documentation/networking/sk98lin.txt --- linux-2.4.24/Documentation/networking/sk98lin.txt 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/networking/sk98lin.txt 2004-02-18 05:36:30.000000000 -0800 @@ -2,9 +2,9 @@ All rights reserved =========================================================================== -sk98lin.txt created 23-Sep-2003 +sk98lin.txt created 15-Dec-2003 -Readme File for sk98lin v6.18 +Readme File for sk98lin v6.21 Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX This file contains @@ -466,7 +466,7 @@ Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. These features are only available after installation of open source modules available on the Internet: -For VLAN go to: http://scry.wanfear.com/~greear/vlan.html +For VLAN go to: http://www.candelatech.com/~greear/vlan.html For Link Aggregation go to: http://www.st.rim.or.jp/~yumo NOTE: SysKonnect GmbH does not offer any support for these open source diff -urN linux-2.4.24/Documentation/s390/cds.txt linux-2.4.25/Documentation/s390/cds.txt --- linux-2.4.24/Documentation/s390/cds.txt 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/Documentation/s390/cds.txt 2004-02-18 05:36:30.000000000 -0800 @@ -1122,23 +1122,6 @@ not operational -EBUSY - the console device is already defined -reset_cons_dev - Reset Console Device - -This routine allows for resetting the console device specification. See -wait_cons_dev() for details. - -int reset_cons_dev( int irq); - -irq : subchannel identifying the system console device - -The reset_cons_dev() function returns - - 0 - successful completion --EIO - an unhandled interrupt condition is pending for the - specified subchannel (irq) - status pending --ENODEV - irq doesn't specify a valid subchannel or the devive is - not operational - wait_cons_dev - Synchronously Wait for Console Processing The wait_cons_dev() routine is used by the console device driver when its diff -urN linux-2.4.24/Documentation/usb/w9968cf.txt linux-2.4.25/Documentation/usb/w9968cf.txt --- linux-2.4.24/Documentation/usb/w9968cf.txt 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/Documentation/usb/w9968cf.txt 2004-02-18 05:36:30.000000000 -0800 @@ -1,6 +1,7 @@ - W996[87]CF JPEG USB Dual Mode Camera Chip driver for Linux 2.4 - ============================================================== + W996[87]CF JPEG USB Dual Mode Camera Chip + Linux 2.4 driver (basic version) + ========================================= - Documentation - @@ -11,7 +12,7 @@ 2. License 3. Overview 4. Supported devices -5. Kernel configuration and third-part module compilation +5. Module dependencies 6. Module loading 7. Module paramaters 8. Credits @@ -19,7 +20,7 @@ 1. Copyright ============ -Copyright (C) 2002 2003 by Luca Risolia +Copyright (C) 2002 2003 by Luca Risolia 2. License @@ -45,20 +46,23 @@ Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips, when they are being commanded by USB. -The driver relies on the Video4Linux, USB and I2C core modules of the Linux -kernel, version 2.4.19 or greater, and is not compatible in any way with -previous versions. It has been designed to run properly on SMP systems -as well. At the moment, an additional module, "ovcamchip", is mandatory; it -provides support for some OmniVision CMOS sensors connected to the W996[87]CF -chips. - -The driver is split into two modules: the basic one, "w9968cf", is needed for -the supported devices to work; the second one, "w9968cf-vpp", is an optional -module, which provides some useful video post-processing functions like video -decoding, up-scaling and colour conversions (these routines can't be included -into official kernels). Once the driver is installed, every time an application -tries to open a recognized device, "w9968cf" checks the presence of the -"w9968cf-vpp" module and loads it automatically by default. +The full-featured driver is divided into two modules: the basic one, "w9968cf", +is needed for the supported devices to work; the second one, "w9968cf-vpp", +is an optional module, which provides some useful video post-processing +functions like video decoding, up-scaling and colour conversions. Once the +driver is installed, every time an application tries to open a recognized +device, "w9968cf" checks the presence of the "w9968cf-vpp" module and loads it +automatically by default. + +Please keep in mind that official kernels do NOT include the second module for +performance purposes. However it is always recommended to download and install +the latest and complete release of the driver, replacing the existing one, if +present: it will be still even possible not to load the "w9968cf-vpp" module at +all, if you ever want to. Another important missing feature of the version in +the official Linux 2.4 kernels is the writeable /proc filesystem interface. + +The latest and full-featured version of the W996[87]CF driver can be found at: +http://go.lamarinapunto.com/ Up to 32 cameras can be handled at the same time. They can be connected and disconnected from the host many times without turning off the computer, if @@ -67,15 +71,17 @@ To change the default settings for each camera, many paramaters can be passed through command line when the module is loaded into memory. -It is recommended to install the latest and full featured version of the -W996[87]CF driver, which can be found at: -http://go.lamarinapunto.com/ +The driver relies on the Video4Linux, USB and I2C core modules of the official +Linux kernels, version 2.4.19 or greater, and is not compatible in any way with +previous versions. It has been designed to run properly on SMP systems as well. +At the moment, an additional module, "ovcamchip", is mandatory; it provides +support for some OmniVision CMOS sensors connected to the W996[87]CF chips. -The "ovcamchip" module is part of the OV511 driver, version 2.25, which can be +The "ovcamchip" module is part of the OV511 driver, version 2.27, which can be downloaded from internet: http://alpha.dyndns.org/ov511/ -To know how to patch, compile and load it, read the "Kernel configuration" -paragraph. +To know how to compile it, read the documentation included in the OV511 +package. 4. Supported devices @@ -94,22 +100,21 @@ The list above does NOT imply that all those devices work with this driver: up until now only webcams that have a CMOS sensor supported by the "ovcamchip" module work. -For a list of supported CMOS sensors, please visit the module author homepage: -http://alpha.dyndns.org/ov511/ +For a list of supported CMOS sensors, please visit the the author's homepage on +this module: http://alpha.dyndns.org/ov511/ Possible external microcontrollers of those webcams are not supported: this -means that still images can't be downloaded from the device memory. +means that still images cannot be downloaded from the device memory. Furthermore, it's worth to note that I was only able to run tests on my "Creative Labs Video Blaster WebCam Go". Donations of other models, for additional testing and full support, would be much appreciated. -5. Kernel configuration and third-part module compilation -========================================================= -As noted above, kernel 2.4.19 is the minimum for this driver; for it to work -properly, the driver needs kernel support for Video4Linux, USB and I2C, and a -third-part module for the CMOS sensor. +5. Module dependencies +====================== +The driver needs kernel support for Video4Linux, USB and I2C, and a third-party +module for the CMOS sensor. The following options of the kernel configuration file must be enabled and corresponding modules must be compiled: @@ -128,7 +133,7 @@ # CONFIG_USB=m -In addition, depending on the hardware being used, just one of the modules +In addition, depending on the hardware being used, only one of the modules below is necessary: # USB Host Controller Drivers @@ -138,6 +143,12 @@ CONFIG_USB_UHCI_ALT=m CONFIG_USB_OHCI=m +And finally: + + # USB Multimedia devices + # + CONFIG_USB_W9968CF=m + Also, make sure "Enforce bandwidth allocation" is NOT enabled. The /proc filesystem can be optionally built into the kernel: @@ -150,39 +161,18 @@ # CONFIG_VIDEO_PROC_FS=y - # USB Multimedia devices - # - CONFIG_USB_W9968CF=m - The last module we need is "ovcamchip.o". To obtain it, you have to download -the OV511 driver, version 2.25 - don't use other versions - which is available -at http://alpha.dyndns.org/ov511/ . Then you have to download the latest -version of the full featured W996[87]CF driver, which contains a patch for the -"ovcamchip" module; it is available at http://go.lamarinapunto.com . -Once you have obtained the packages, decompress, patch and compile the -"ovcamchip" module. In other words: - - [user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz - [user@localhost home]$ tar xvjf ov511-2.25.tar.bz2 - [user@localhost home]$ cd ov511-2.25 - [user@localhost ov511-2.25]$ patch -p1 < \ - /path/to/w9968cf-x.x/ov511-2.25.patch - [user@localhost ov511-2.25]$ make - -It's worth to note that the full featured version of the W996[87]CF driver -can also be installed overwriting the one in the kernel; in this case, read the -documentation included in the package. - -If everything went well, the W996[87]CF driver can be immediatly used (see next -paragraph). +the OV511, version 2.27 - don't use other versions - and compile it according +to its documentation. +The package is available at http://alpha.dyndns.org/ov511/ . 6. Module loading ================= To use the driver, it is necessary to load the "w9968cf" module into memory -after every other module required; they are named, in order: "videodev", -"usbcore", then "ehci-hcd", "usb-uhci", "uhci", "usb-ohci" (just one), and also -"i2c-core" and "ovcamchip". +after every other module required: for the 2.4 series of the kernel, they are +named, in order: "videodev", "usbcore", then "ehci-hcd", "usb-uhci", "uhci", +"usb-ohci" (just one), and also "i2c-core" and "ovcamchip". Loading can be done this way, from root: @@ -213,11 +203,10 @@ 7. Module paramaters ==================== - Module paramaters are listed below: ------------------------------------------------------------------------------- Name: vppmod_load -Type: int +Type: bool Syntax: <0|1> Description: Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled. If enabled, every time an application attempts to open a @@ -258,22 +247,22 @@ Name: max_buffers Type: int array (min = 0, max = 32) Syntax: -Description: Only for advanced users. +Description: For advanced users. Specify the maximum number of video frame buffers to allocate for each device, from 2 to 32. Default: 2 ------------------------------------------------------------------------------- Name: double_buffer -Type: int array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Hardware double buffering: 0 disabled, 1 enabled. It should be enabled if you want smooth video output: if you - obtain out of sync. video, disable it at all, or try to + obtain out of sync. video, disable it, or try to decrease the 'clockdiv' module paramater value. Default: 1 for every device. ------------------------------------------------------------------------------- Name: clamping -Type: int array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Video data clamping: 0 disabled, 1 enabled. Default: 0 for every device. @@ -288,13 +277,13 @@ Default: 0 for every device. ------------------------------------------------------------------------------- Name: largeview -Type: int array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Large view: 0 disabled, 1 enabled. Default: 1 for every device. ------------------------------------------------------------------------------- Name: upscaling -Type: int array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Software scaling (for non-compressed video only): 0 disabled, 1 enabled. @@ -316,9 +305,8 @@ YUV420P/YUV420 in any resolutions where width and height are multiples of 16. Default: 2 for every device. -Note: If 'w9968cf-vpp' is not loaded, this paramater is set to, - forcing decompression is not allowed; in this case this - paramater is set to 2. +Note: If 'w9968cf-vpp' is not loaded, forcing decompression is not + allowed; in this case this paramater is set to 2. ------------------------------------------------------------------------------- Name: force_palette Type: int array (min = 0, max = 32) @@ -342,7 +330,7 @@ Note: If 'w9968cf-vpp' is not loaded, this paramater is set to 9. ------------------------------------------------------------------------------- Name: force_rgb -Type: int array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Read RGB video data instead of BGR: 1 = use RGB component ordering. @@ -351,28 +339,28 @@ Default: 0 for every device. ------------------------------------------------------------------------------- Name: autobright -Type: long array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: CMOS sensor automatically changes brightness: 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: autoexp -Type: long array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: CMOS sensor automatically changes exposure: 0 = no, 1 = yes Default: 1 for every device. ------------------------------------------------------------------------------- Name: lightfreq -Type: long array (min = 0, max = 32) +Type: int array (min = 0, max = 32) Syntax: <50|60[,...]> Description: Light frequency in Hz: 50 for European and Asian lighting, 60 for American lighting. Default: 50 for every device. ------------------------------------------------------------------------------- Name: bandingfilter -Type: long array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Banding filter to reduce effects of fluorescent lighting: @@ -382,7 +370,7 @@ Default: 0 for every device. ------------------------------------------------------------------------------- Name: clockdiv -Type: long array (min = 0, max = 32) +Type: int array (min = 0, max = 32) Syntax: <-1|n[,...]> Description: Force pixel clock divisor to a specific value (for experts): n may vary from 0 to 127. @@ -391,21 +379,21 @@ Default: -1 for every device. ------------------------------------------------------------------------------- Name: backlight -Type: long array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Objects are lit from behind: 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: mirror -Type: long array (min = 0, max = 32) +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Reverse image horizontally: 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- -Name: sensor_mono -Type: long array (min = 0, max = 32) +Name: monochrome +Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: The CMOS sensor is monochrome: 0 = no, 1 = yes @@ -446,7 +434,7 @@ Type: int Syntax: Description: Debugging information level, from 0 to 6: - 0 = none (be cautious) + 0 = none (use carefully) 1 = critical errors 2 = significant informations 3 = configuration or general messages @@ -458,7 +446,7 @@ Default: 2 ------------------------------------------------------------------------------- Name: specific_debug -Type: int +Type: bool Syntax: <0|1> Description: Enable or disable specific debugging messages: 0 = print messages concerning every level <= 'debug' level. @@ -479,8 +467,6 @@ - memory management code has been copied from the bttv driver by Ralph Metzler, Marcus Metzler and Gerd Knorr; -- the low-level I2C read function has been written by Frédéric Jouault, who - also gave me commented logs about sniffed USB traffic taken from another - driver for another system; +- the low-level I2C read function has been written by Frederic Jouault; -- the low-level I2C fast write function has been written by Piotr Czerczak; +- the low-level I2C fast write function has been written by Piotr Czerczak. diff -urN linux-2.4.24/MAINTAINERS linux-2.4.25/MAINTAINERS --- linux-2.4.24/MAINTAINERS 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/MAINTAINERS 2004-02-18 05:36:30.000000000 -0800 @@ -73,7 +73,7 @@ 3C359 NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: linux-net@vger.rutgers.edu +L: linux-net@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -322,18 +322,25 @@ S: Maintained BLUETOOTH SUBSYSTEM +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com +L: bluez-devel@lists.sf.net W: http://bluez.sf.net S: Maintained BLUETOOTH RFCOMM LAYER +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net S: Maintained BLUETOOTH BNEP LAYER +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net @@ -346,12 +353,16 @@ S: Maintained BLUETOOTH HCI USB DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net S: Maintained BLUETOOTH HCI UART DRIVER +P: Marcel Holtmann +M: marcel@holtmann.org P: Maxim Krasnyansky M: maxk@qualcomm.com W: http://bluez.sf.net @@ -436,6 +447,12 @@ L: iss_storagedev@hp.com S: Odd Fixes +HP OMNIBOOK 600 C/CT POP-UP MOUSE DRIVER +P: Grant Grundler +M: grundler@parisc-linux.org +L: omnibook@zurich.ai.mit.edu +S: Maintained + HP SMART2 RAID DRIVER P: Francis Wiran @@ -806,7 +823,7 @@ W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi S: Maintained -I2C AND SENSORS DRIVERS +I2C SUBSYSTEM P: Jean Delvare M: khali@linux-fr.org L: sensors@stimpy.netroedge.com @@ -954,7 +971,7 @@ IOC3 DRIVER P: Ralf Baechle -M: ralf@oss.sgi.com +M: ralf@linux-mips.org L: linux-mips@linux-mips.org S: Maintained @@ -1149,6 +1166,13 @@ M: zab@zabbo.net S: Odd Fixes +MARVELL MV64340 ETHERNET DRIVER +P: Manish Lachwani +M: Manish_Lachwani@pmc-sierra.com +L: linux-mips@linux-mips.org +L: netdev@oss.sgi.com +S: Supported + MATROX FRAMEBUFFER DRIVER P: Petr Vandrovec M: vandrove@vc.cvut.cz @@ -1170,7 +1194,7 @@ MIPS P: Ralf Baechle -M: ralf@gnu.org +M: ralf@linux-mips.org W: http://oss.sgi.com/mips/mips-howto.html L: linux-mips@linux-mips.org S: Maintained @@ -1344,8 +1368,8 @@ ONSTREAM SCSI TAPE DRIVER P: Willem Riede M: osst@riede.org -L: osst@linux1.onstream.nl -L: linux-scsi@vger.rutgers.edu +L: osst-users@lists.sourceforge.net +L: linux-scsi@vger.kernel.org S: Maintained OPL3-SA2, SA3, and SAx DRIVER @@ -1682,8 +1706,10 @@ S: Maintained SPARC (sparc32): +P: Keith M. Wesolowski +M: wesolows@foobazco.org L: sparclinux@vger.kernel.org -S: Unmaintained - please send patches to mailing list +S: Maintained SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER P: Roger Wolff @@ -2063,11 +2089,11 @@ S: Maintained USB W9968CF DRIVER -P: Luca Risolia -M: luca_ing@libero.it -L: linux-usb-devel@lists.sourceforge.net -W: http://go.lamarinapunto.com -S: Maintained +P: Luca Risolia +M: luca.risolia@studio.unibo.it +L: linux-usb-devel@lists.sourceforge.net +W: http://go.lamarinapunto.com +S: Maintained VFAT FILESYSTEM: P: Gordon Chaffee @@ -2086,6 +2112,11 @@ M: rl@hellgate.ch S: Maintained +VIA-IRCC IRDA DRIVER +P: Jens David +M: dg1kjd@afthd.tu-darmstadt.de +S: Maintained + USB DIAMOND RIO500 DRIVER P: Cesar Miquel M: miquel@df.uba.ar @@ -2123,6 +2154,14 @@ L: linux-x25@vger.kernel.org S: Maintained +XFS FILESYSTEM +P: Silicon Graphics Inc +M: owner-xfs@oss.sgi.com +M: nathans@sgi.com +L: linux-xfs@oss.sgi.com +W: http://oss.sgi.com/projects/xfs +S: Supported + X86 3-LEVEL PAGING (PAE) SUPPORT P: Ingo Molnar M: mingo@redhat.com diff -urN linux-2.4.24/Makefile linux-2.4.25/Makefile --- linux-2.4.24/Makefile 2004-01-05 05:53:56.000000000 -0800 +++ linux-2.4.25/Makefile 2004-02-18 05:36:32.000000000 -0800 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 24 +SUBLEVEL = 25 EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -175,7 +175,6 @@ DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o -DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a DRIVERS-$(CONFIG_VT) += drivers/video/video.o DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o @@ -221,6 +220,7 @@ drivers/scsi/aic7xxx/aicasm/aicdb.h \ drivers/scsi/aic7xxx/aicasm/y.tab.h \ drivers/scsi/53c700_d.h \ + drivers/tc/lk201-map.c \ net/khttpd/make_times_h \ net/khttpd/times.h \ submenu* diff -urN linux-2.4.24/Rules.make linux-2.4.25/Rules.make --- linux-2.4.24/Rules.make 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/Rules.make 2004-02-18 05:36:30.000000000 -0800 @@ -96,12 +96,12 @@ $(O_TARGET): $(obj-y) rm -f $@ ifneq "$(strip $(obj-y))" "" - $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^) + $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^) else $(AR) rcs $@ endif @ ( \ - echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; \ + echo 'ifeq ($(strip $(subst $(comma),:,$(LDFLAGS) $(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(LDFLAGS) $$(EXTRA_LDFLAGS) $$(obj-y))))' ; \ echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \ echo 'endif' \ ) > $(dir $@)/.$(notdir $@).flags diff -urN linux-2.4.24/arch/alpha/config.in linux-2.4.25/arch/alpha/config.in --- linux-2.4.24/arch/alpha/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/alpha/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -341,7 +341,6 @@ int ' Maximum IDE interfaces' MAX_HWIFS 4 source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/alpha/defconfig linux-2.4.25/arch/alpha/defconfig --- linux-2.4.24/arch/alpha/defconfig 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/alpha/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -270,7 +270,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/config.in linux-2.4.25/arch/arm/config.in --- linux-2.4.24/arch/arm/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/arm/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -585,7 +585,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/arm/def-configs/a5k linux-2.4.25/arch/arm/def-configs/a5k --- linux-2.4.24/arch/arm/def-configs/a5k 2000-11-27 17:07:59.000000000 -0800 +++ linux-2.4.25/arch/arm/def-configs/a5k 2004-02-18 05:36:30.000000000 -0800 @@ -287,7 +287,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/accelent_sa linux-2.4.25/arch/arm/def-configs/accelent_sa --- linux-2.4.24/arch/arm/def-configs/accelent_sa 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/accelent_sa 2004-02-18 05:36:30.000000000 -0800 @@ -506,7 +506,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/adsagc linux-2.4.25/arch/arm/def-configs/adsagc --- linux-2.4.24/arch/arm/def-configs/adsagc 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/adsagc 2004-02-18 05:36:30.000000000 -0800 @@ -535,7 +535,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/adsbitsy linux-2.4.25/arch/arm/def-configs/adsbitsy --- linux-2.4.24/arch/arm/def-configs/adsbitsy 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/adsbitsy 2004-02-18 05:36:30.000000000 -0800 @@ -535,7 +535,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/adsbitsyplus linux-2.4.25/arch/arm/def-configs/adsbitsyplus --- linux-2.4.24/arch/arm/def-configs/adsbitsyplus 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/adsbitsyplus 2004-02-18 05:36:30.000000000 -0800 @@ -535,7 +535,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/anakin linux-2.4.25/arch/arm/def-configs/anakin --- linux-2.4.24/arch/arm/def-configs/anakin 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/anakin 2004-02-18 05:36:30.000000000 -0800 @@ -259,7 +259,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/assabet linux-2.4.25/arch/arm/def-configs/assabet --- linux-2.4.24/arch/arm/def-configs/assabet 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/assabet 2004-02-18 05:36:30.000000000 -0800 @@ -493,7 +493,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/at91rm9200dk linux-2.4.25/arch/arm/def-configs/at91rm9200dk --- linux-2.4.24/arch/arm/def-configs/at91rm9200dk 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/at91rm9200dk 2004-02-18 05:36:30.000000000 -0800 @@ -426,7 +426,6 @@ # ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/badge4 linux-2.4.25/arch/arm/def-configs/badge4 --- linux-2.4.24/arch/arm/def-configs/badge4 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/badge4 2004-02-18 05:36:30.000000000 -0800 @@ -527,7 +527,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/brutus linux-2.4.25/arch/arm/def-configs/brutus --- linux-2.4.24/arch/arm/def-configs/brutus 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/brutus 2004-02-18 05:36:30.000000000 -0800 @@ -123,7 +123,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/cep linux-2.4.25/arch/arm/def-configs/cep --- linux-2.4.24/arch/arm/def-configs/cep 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/cep 2004-02-18 05:36:30.000000000 -0800 @@ -303,7 +303,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/cerfcube linux-2.4.25/arch/arm/def-configs/cerfcube --- linux-2.4.24/arch/arm/def-configs/cerfcube 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/cerfcube 2004-02-18 05:36:30.000000000 -0800 @@ -474,7 +474,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/cerfpda linux-2.4.25/arch/arm/def-configs/cerfpda --- linux-2.4.24/arch/arm/def-configs/cerfpda 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/cerfpda 2004-02-18 05:36:30.000000000 -0800 @@ -504,7 +504,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/cerfpod linux-2.4.25/arch/arm/def-configs/cerfpod --- linux-2.4.24/arch/arm/def-configs/cerfpod 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/cerfpod 2004-02-18 05:36:30.000000000 -0800 @@ -475,7 +475,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/clps7500 linux-2.4.25/arch/arm/def-configs/clps7500 --- linux-2.4.24/arch/arm/def-configs/clps7500 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/clps7500 2004-02-18 05:36:30.000000000 -0800 @@ -298,7 +298,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/ebsa110 linux-2.4.25/arch/arm/def-configs/ebsa110 --- linux-2.4.24/arch/arm/def-configs/ebsa110 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/ebsa110 2004-02-18 05:36:30.000000000 -0800 @@ -387,7 +387,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/edb7211 linux-2.4.25/arch/arm/def-configs/edb7211 --- linux-2.4.24/arch/arm/def-configs/edb7211 2001-10-25 13:53:44.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/edb7211 2004-02-18 05:36:30.000000000 -0800 @@ -225,7 +225,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/epxa10db linux-2.4.25/arch/arm/def-configs/epxa10db --- linux-2.4.24/arch/arm/def-configs/epxa10db 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/epxa10db 2004-02-18 05:36:30.000000000 -0800 @@ -422,7 +422,6 @@ # ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/epxa1db linux-2.4.25/arch/arm/def-configs/epxa1db --- linux-2.4.24/arch/arm/def-configs/epxa1db 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/epxa1db 2004-02-18 05:36:30.000000000 -0800 @@ -404,7 +404,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/flexanet linux-2.4.25/arch/arm/def-configs/flexanet --- linux-2.4.24/arch/arm/def-configs/flexanet 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/flexanet 2004-02-18 05:36:30.000000000 -0800 @@ -479,7 +479,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/footbridge linux-2.4.25/arch/arm/def-configs/footbridge --- linux-2.4.24/arch/arm/def-configs/footbridge 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/footbridge 2004-02-18 05:36:30.000000000 -0800 @@ -437,7 +437,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/fortunet linux-2.4.25/arch/arm/def-configs/fortunet --- linux-2.4.24/arch/arm/def-configs/fortunet 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/fortunet 2004-02-18 05:36:30.000000000 -0800 @@ -295,7 +295,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/freebird linux-2.4.25/arch/arm/def-configs/freebird --- linux-2.4.24/arch/arm/def-configs/freebird 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/freebird 2004-02-18 05:36:30.000000000 -0800 @@ -384,7 +384,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/freebird_new linux-2.4.25/arch/arm/def-configs/freebird_new --- linux-2.4.24/arch/arm/def-configs/freebird_new 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/freebird_new 2004-02-18 05:36:30.000000000 -0800 @@ -398,7 +398,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/frodo linux-2.4.25/arch/arm/def-configs/frodo --- linux-2.4.24/arch/arm/def-configs/frodo 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/frodo 2004-02-18 05:36:30.000000000 -0800 @@ -462,7 +462,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/graphicsclient linux-2.4.25/arch/arm/def-configs/graphicsclient --- linux-2.4.24/arch/arm/def-configs/graphicsclient 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/graphicsclient 2004-02-18 05:36:30.000000000 -0800 @@ -533,7 +533,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/graphicsmaster linux-2.4.25/arch/arm/def-configs/graphicsmaster --- linux-2.4.24/arch/arm/def-configs/graphicsmaster 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/graphicsmaster 2004-02-18 05:36:30.000000000 -0800 @@ -535,7 +535,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/h3600 linux-2.4.25/arch/arm/def-configs/h3600 --- linux-2.4.24/arch/arm/def-configs/h3600 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/h3600 2004-02-18 05:36:30.000000000 -0800 @@ -482,7 +482,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/huw_webpanel linux-2.4.25/arch/arm/def-configs/huw_webpanel --- linux-2.4.24/arch/arm/def-configs/huw_webpanel 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/huw_webpanel 2004-02-18 05:36:30.000000000 -0800 @@ -227,7 +227,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/integrator linux-2.4.25/arch/arm/def-configs/integrator --- linux-2.4.24/arch/arm/def-configs/integrator 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/integrator 2004-02-18 05:36:30.000000000 -0800 @@ -410,7 +410,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/jornada720 linux-2.4.25/arch/arm/def-configs/jornada720 --- linux-2.4.24/arch/arm/def-configs/jornada720 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/jornada720 2004-02-18 05:36:30.000000000 -0800 @@ -482,7 +482,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/lart linux-2.4.25/arch/arm/def-configs/lart --- linux-2.4.24/arch/arm/def-configs/lart 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/lart 2004-02-18 05:36:30.000000000 -0800 @@ -484,7 +484,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/lusl7200 linux-2.4.25/arch/arm/def-configs/lusl7200 --- linux-2.4.24/arch/arm/def-configs/lusl7200 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/lusl7200 2004-02-18 05:36:30.000000000 -0800 @@ -161,7 +161,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/nanoengine linux-2.4.25/arch/arm/def-configs/nanoengine --- linux-2.4.24/arch/arm/def-configs/nanoengine 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/nanoengine 2004-02-18 05:36:30.000000000 -0800 @@ -413,7 +413,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/neponset linux-2.4.25/arch/arm/def-configs/neponset --- linux-2.4.24/arch/arm/def-configs/neponset 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/neponset 2004-02-18 05:36:30.000000000 -0800 @@ -455,7 +455,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/omaha linux-2.4.25/arch/arm/def-configs/omaha --- linux-2.4.24/arch/arm/def-configs/omaha 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/omaha 2004-02-18 05:36:30.000000000 -0800 @@ -358,7 +358,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/omnimeter linux-2.4.25/arch/arm/def-configs/omnimeter --- linux-2.4.24/arch/arm/def-configs/omnimeter 2001-08-12 11:13:59.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/omnimeter 2004-02-18 05:36:30.000000000 -0800 @@ -314,7 +314,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pangolin linux-2.4.25/arch/arm/def-configs/pangolin --- linux-2.4.24/arch/arm/def-configs/pangolin 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pangolin 2004-02-18 05:36:30.000000000 -0800 @@ -434,7 +434,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pfs168_mqtft linux-2.4.25/arch/arm/def-configs/pfs168_mqtft --- linux-2.4.24/arch/arm/def-configs/pfs168_mqtft 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pfs168_mqtft 2004-02-18 05:36:30.000000000 -0800 @@ -458,7 +458,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pfs168_mqvga linux-2.4.25/arch/arm/def-configs/pfs168_mqvga --- linux-2.4.24/arch/arm/def-configs/pfs168_mqvga 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pfs168_mqvga 2004-02-18 05:36:30.000000000 -0800 @@ -458,7 +458,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pfs168_sastn linux-2.4.25/arch/arm/def-configs/pfs168_sastn --- linux-2.4.24/arch/arm/def-configs/pfs168_sastn 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pfs168_sastn 2004-02-18 05:36:30.000000000 -0800 @@ -459,7 +459,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pfs168_satft linux-2.4.25/arch/arm/def-configs/pfs168_satft --- linux-2.4.24/arch/arm/def-configs/pfs168_satft 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pfs168_satft 2004-02-18 05:36:30.000000000 -0800 @@ -458,7 +458,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/pleb linux-2.4.25/arch/arm/def-configs/pleb --- linux-2.4.24/arch/arm/def-configs/pleb 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/pleb 2004-02-18 05:36:30.000000000 -0800 @@ -331,7 +331,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/arm/def-configs/riscstation linux-2.4.25/arch/arm/def-configs/riscstation --- linux-2.4.24/arch/arm/def-configs/riscstation 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/riscstation 2004-02-18 05:36:30.000000000 -0800 @@ -372,7 +372,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/rpc linux-2.4.25/arch/arm/def-configs/rpc --- linux-2.4.24/arch/arm/def-configs/rpc 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/rpc 2004-02-18 05:36:30.000000000 -0800 @@ -412,7 +412,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/arm/def-configs/shannon linux-2.4.25/arch/arm/def-configs/shannon --- linux-2.4.24/arch/arm/def-configs/shannon 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/shannon 2004-02-18 05:36:30.000000000 -0800 @@ -387,7 +387,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # diff -urN linux-2.4.24/arch/arm/def-configs/shark linux-2.4.25/arch/arm/def-configs/shark --- linux-2.4.24/arch/arm/def-configs/shark 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/shark 2004-02-18 05:36:30.000000000 -0800 @@ -391,7 +391,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/def-configs/system3 linux-2.4.25/arch/arm/def-configs/system3 --- linux-2.4.24/arch/arm/def-configs/system3 2002-08-02 17:39:42.000000000 -0700 +++ linux-2.4.25/arch/arm/def-configs/system3 2004-02-18 05:36:30.000000000 -0800 @@ -496,7 +496,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/arm/defconfig linux-2.4.25/arch/arm/defconfig --- linux-2.4.24/arch/arm/defconfig 2001-05-19 17:43:05.000000000 -0700 +++ linux-2.4.25/arch/arm/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -303,7 +303,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/cris/config.in linux-2.4.25/arch/cris/config.in --- linux-2.4.24/arch/cris/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/cris/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -184,7 +184,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/cris/defconfig linux-2.4.25/arch/cris/defconfig --- linux-2.4.24/arch/cris/defconfig 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -282,7 +282,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/cris/drivers/Config.in linux-2.4.25/arch/cris/drivers/Config.in --- linux-2.4.24/arch/cris/drivers/Config.in 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/Config.in 2004-02-18 05:36:30.000000000 -0800 @@ -11,7 +11,10 @@ "LED_on_when_link CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK \ LED_on_when_activity CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY" \ LED_on_when_activity - + choice 'Network LED behavior on no connection' \ + "RED_LED_on_no_connection CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION \ + LED_OFF_on_no_connection CONFIG_ETRAX_NETWORK_OFF_ON_NO_CONNECTION" \ + LED_OFF_on_no_connection else define_bool CONFIG_NET_ETHERNET n fi @@ -32,12 +35,18 @@ fi bool ' Enable external clock on PB6' CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED if [ "$CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED" = "y" ]; then - int ' Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ + int ' Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ 0 fi bool ' Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then - bool ' Serial port 0 uses DMA6 out' CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT - bool ' Serial port 0 uses DMA7 in' CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + choice 'Ser0 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT \ + DMA6_OUT CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT" \ + DMA6_OUT + choice 'Ser0 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN \ + DMA7_IN CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN" \ + DMA7_IN choice 'Ser0 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA \ @@ -73,8 +82,14 @@ bool ' Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then - bool ' Serial port 1 uses DMA8 out' CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT - bool ' Serial port 1 uses DMA9 in' CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + choice 'Ser1 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT \ + DMA8_OUT CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT" \ + DMA8_OUT + choice 'Ser1 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN \ + DMA9_IN CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN" \ + DMA9_IN choice 'Ser1 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PA \ @@ -114,8 +129,14 @@ fi bool ' Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2 if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then - bool ' Serial port 2 uses DMA2 out' CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT - bool ' Serial port 2 uses DMA3 in' CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + choice 'Ser2 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT \ + DMA2_OUT CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT" \ + DMA2_OUT + choice 'Ser2 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN \ + DMA3_IN CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN" \ + DMA3_IN choice 'Ser2 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA \ @@ -149,8 +170,14 @@ fi bool ' Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3 if [ "$CONFIG_ETRAX_SERIAL_PORT3" = "y" ]; then - bool ' Serial port 3 uses DMA4 out' CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT - bool ' Serial port 3 uses DMA5 in' CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + choice 'Ser3 DMA out assignment' \ + "NO_DMA_OUT CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT \ + DMA4_OUT CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT" \ + DMA4_OUT + choice 'Ser3 DMA in assignment' \ + "NO_DMA_IN CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN \ + DMA5_IN CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN" \ + DMA5_IN choice 'Ser3 DTR, RI, DSR and CD assignment' \ "No_DTR_RI_DSR_CD CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE \ DTR_RI_DSR_CD_on_PA CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA \ @@ -194,13 +221,13 @@ bool 'Synchronous serial port support' CONFIG_ETRAX_SYNCHRONOUS_SERIAL if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL" = "y" ]; then - bool ' Synchronous serial port 0 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 + bool ' Synchronous serial port 0 enabled (sser1)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0" = "y" ]; then - bool ' Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA + bool ' Synchronous serial port 0 uses DMA 8,9' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA fi - bool ' Synchronous serial port 1 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 + bool ' Synchronous serial port 1 enabled (sser3)' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1" = "y" ]; then - bool ' Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA + bool ' Synchronous serial port 1 uses DMA 4,5' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA fi fi @@ -253,17 +280,28 @@ # here we define the CONFIG_'s necessary to enable MTD support # for the flash define_bool CONFIG_MTD y - - define_bool CONFIG_MTD_CFI y - define_bool CONFIG_MTD_CFI_AMDSTD y - - define_bool CONFIG_MTD_OBSOLETE_CHIPS y - define_bool CONFIG_MTD_AMDSTD y - + define_bool CONFIG_MTD_PARTITIONS y define_bool CONFIG_MTD_CHAR y define_bool CONFIG_MTD_BLOCK y - define_bool CONFIG_MTD_PARTITIONS y - define_bool CONFIG_MTD_CONCAT y + + if [ "$CONFIG_MTD_CFI" = "n" ] && [ "$CONFIG_MTD_AMDSTD" = "n" ] && \ + [ "$CONFIG_MTD_MTDRAM" = "n" ]; then + # Bad initial configuration, make axisflashmap work by enabling + # all drivers it may need. + + define_bool CONFIG_MTD_CFI y + define_bool CONFIG_MTD_CFI_AMDSTD y + + define_bool CONFIG_MTD_OBSOLETE_CHIPS y + define_bool CONFIG_MTD_AMDSTD y + + define_bool CONFIG_MTD_CONCAT y + + define_bool CONFIG_MTD_MTDRAM y + define_int CONFIG_MTDRAM_TOTAL_SIZE 0 + define_int CONFIG_MTDRAM_ERASE_SIZE 64 + define_int CONFIG_MTDRAM_ABS_POS 0 + fi fi bool 'I2C support' CONFIG_ETRAX_I2C diff -urN linux-2.4.24/arch/cris/drivers/Makefile linux-2.4.25/arch/cris/drivers/Makefile --- linux-2.4.24/arch/cris/drivers/Makefile 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -4,6 +4,8 @@ O_TARGET := drivers.o +export-objs := axisflashmap.o + obj-y := obj-$(CONFIG_ETRAX_VIRTEX_FPGA) += virtex.o diff -urN linux-2.4.24/arch/cris/drivers/axisflashmap.c linux-2.4.25/arch/cris/drivers/axisflashmap.c --- linux-2.4.24/arch/cris/drivers/axisflashmap.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/axisflashmap.c 2004-02-18 05:36:30.000000000 -0800 @@ -11,6 +11,12 @@ * partition split defined below. * * $Log: axisflashmap.c,v $ + * Revision 1.31 2003/11/14 16:55:27 jonashg + * Made it possible to RAM boot without any flash drivers present. + * + * Revision 1.30 2003/09/29 06:37:18 mikaelp + * Exported master mtd device as axisflash_mtd. + * * Revision 1.29 2003/04/01 14:12:06 starvik * Added loglevel for lots of printks * @@ -142,6 +148,9 @@ /* From head.S */ extern unsigned long romfs_start, romfs_length, romfs_in_flash; +/* The master mtd for the entire flash. */ +struct mtd_info* axisflash_mtd = NULL; + /* Map driver functions. */ static __u8 flash_read8(struct map_info *map, unsigned long ofs) @@ -388,7 +397,7 @@ struct mtd_info *mymtd; int err = 0; int pidx = 0; - struct partitiontable_head *ptable_head; + struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; @@ -397,19 +406,22 @@ /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ - panic("axisflashmap found no flash chip!\n"); + printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); + } else { + printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", + mymtd->name, mymtd->size); + axisflash_mtd = mymtd; } - printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", - mymtd->name, mymtd->size); - - mymtd->module = THIS_MODULE; - - ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + - CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); + if (mymtd) { + mymtd->module = THIS_MODULE; + ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + + CONFIG_ETRAX_PTABLE_SECTOR + + PARTITION_TABLE_OFFSET); + } pidx++; /* First partition is always set to the default. */ - if ((ptable_head->magic == PARTITION_TABLE_MAGIC) + if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) @@ -476,22 +488,25 @@ axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; - printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); + printk(KERN_INFO + " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } - if (use_default_ptable) { - printk(KERN_INFO " Using default partition table.\n"); - err = add_mtd_partitions(mymtd, axis_default_partitions, - NUM_DEFAULT_PARTITIONS); - } else { - err = add_mtd_partitions(mymtd, axis_partitions, pidx); - } + if (mymtd) { + if (use_default_ptable) { + printk(KERN_INFO " Using default partition table.\n"); + err = add_mtd_partitions(mymtd, axis_default_partitions, + NUM_DEFAULT_PARTITIONS); + } else { + err = add_mtd_partitions(mymtd, axis_partitions, pidx); + } - if (err) { - panic("axisflashmap could not add MTD partitions!\n"); + if (err) { + panic("axisflashmap could not add MTD partitions!\n"); + } } if (!romfs_in_flash) { @@ -529,3 +544,5 @@ /* This adds the above to the kernels init-call chain. */ module_init(init_axis_flash); + +EXPORT_SYMBOL(axisflash_mtd); diff -urN linux-2.4.24/arch/cris/drivers/ethernet.c linux-2.4.25/arch/cris/drivers/ethernet.c --- linux-2.4.24/arch/cris/drivers/ethernet.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/ethernet.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: ethernet.c,v 1.44 2003/07/01 10:55:07 starvik Exp $ +/* $Id: ethernet.c,v 1.48 2003/12/03 13:44:39 starvik Exp $ * * e100net.c: A network driver for the ETRAX 100LX network controller. * @@ -7,6 +7,19 @@ * The outline of this driver comes from skeleton.c. * * $Log: ethernet.c,v $ + * Revision 1.48 2003/12/03 13:44:39 starvik + * Use hardware pad for short packets. This prevents information leakage + * reported by Nessus. + * + * Revision 1.47 2003/11/25 15:12:38 anderstj + * Make sure the LED always is inititated. + * + * Revision 1.46 2003/08/28 14:35:29 jonasw + * Added support for TDK 2120C and fixed led when not connected + * + * Revision 1.45 2003/08/21 07:22:25 matsfg + * Optional behaviour on networkled when no connection. + * * Revision 1.44 2003/07/01 10:55:07 starvik * Never bring down link to make stupid POE equipment happy * @@ -430,7 +443,8 @@ struct transceiver_ops transceivers[] = { {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ - {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK */ + {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ + {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ }; @@ -800,6 +814,7 @@ static void e100_check_speed(unsigned long dummy) { + static int led_initiated = 0; unsigned long data; int old_speed = current_speed; @@ -810,8 +825,10 @@ transceiver->check_speed(); } - if (old_speed != current_speed) + if ((old_speed != current_speed) || !led_initiated) { + led_initiated = 1; e100_set_network_leds(NO_NETWORK_ACTIVITY); + } /* Reinitialize the timer. */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; @@ -957,6 +974,7 @@ break; } transceiver = ops; + return 0; } @@ -1121,7 +1139,6 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *np = (struct net_local *)dev->priv; - int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; #ifdef ETHDEBUG @@ -1133,7 +1150,7 @@ dev->trans_start = jiffies; - e100_hardware_send_packet(buf, length); + e100_hardware_send_packet(buf, skb->len); myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); @@ -1494,7 +1511,7 @@ struct ethtool_drvinfo info; memset((void *) &info, 0, sizeof (info)); strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1); - strncpy(info.version, "$Revision: 1.44 $", sizeof(info.version) - 1); + strncpy(info.version, "$Revision: 1.48 $", sizeof(info.version) - 1); strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); info.regdump_len = 0; @@ -1692,7 +1709,11 @@ if (!current_speed) { /* Make LED red, link is down */ +#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION) + LED_NETWORK_SET(LED_RED); +#else LED_NETWORK_SET(LED_OFF); +#endif } else if (light_leds) { if (current_speed == 10) { diff -urN linux-2.4.24/arch/cris/drivers/serial.c linux-2.4.25/arch/cris/drivers/serial.c --- linux-2.4.24/arch/cris/drivers/serial.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/serial.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: serial.c,v 1.54 2003/07/08 12:42:19 johana Exp $ +/* $Id: serial.c,v 1.58 2003/08/29 17:32:50 johana Exp $ * * Serial port driver for the ETRAX 100LX chip * @@ -7,6 +7,24 @@ * Many, many authors. Based once upon a time on serial.c for 16x50. * * $Log: serial.c,v $ + * Revision 1.58 2003/08/29 17:32:50 johana + * Fixed CMSPAR (Mark/Space) support. CMSPAR|PARODD = Mark(1) parity. + * + * Revision 1.57 2003/08/26 16:53:06 johana + * Merged in change_branch--johana to get non DMA support etc. + * + * Revision 1.56 2003/07/10 13:18:03 pkj + * Corrected a copy-paste error. + * + * Revision 1.55 2003/07/10 11:00:46 starvik + * Moved all the latest stuff to a branch until it is stable + * + * Revision 1.50.2.2 2003/07/28 09:59:39 johana + * Clear tr_running so next write really starts transmission. + * + * Revision 1.50.2.1 2003/07/10 10:59:54 starvik + * Moved all the latest stuff to a branch until it is stable + * * Revision 1.54 2003/07/08 12:42:19 johana * Removed some test defines within #if 0. * Moved a comment to correct place. @@ -437,7 +455,7 @@ * */ -static char *serial_version = "$Revision: 1.54 $"; +static char *serial_version = "$Revision: 1.58 $"; #include #include @@ -3164,6 +3182,7 @@ info->last_tx_active_usec = GET_JIFFIES_USEC(); info->last_tx_active = jiffies; e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0)); } else { /* We must enable since it is disabled in ser_interrupt */ @@ -3657,20 +3676,14 @@ } if (cflag & CMSPAR) { - /* enable stick parity */ + /* enable stick parity, PARODD mean Mark which matches ETRAX */ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick); info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick); - if (!(cflag & PARODD)) { - /* set mark parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } - } else { - if (cflag & PARODD) { - /* set odd parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } + } + if (cflag & PARODD) { + /* set odd parity (or Mark if CMSPAR) */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); } if (cflag & CRTSCTS) { diff -urN linux-2.4.24/arch/cris/drivers/sync_serial.c linux-2.4.25/arch/cris/drivers/sync_serial.c --- linux-2.4.24/arch/cris/drivers/sync_serial.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/sync_serial.c 2004-02-18 05:36:30.000000000 -0800 @@ -6,9 +6,9 @@ * decoder. The driver can easily be tuned to fit other audio encoder/decoders * and SPI * - * Copyright (c) 2001 Axis Communications AB + * Copyright (c) 2001-2003 Axis Communications AB * - * Author: Mikael Starvik + * Author: Mikael Starvik, Johan Adolfsson * */ #include @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,25 +32,26 @@ /* The receiver is a bit tricky beacuse of the continuous stream of data.*/ /* */ -/* Two DMA descriptors are linked together. Each DMA descriptor is */ -/* responsible for one half of a common buffer. */ +/* Three DMA descriptors are linked together. Each DMA descriptor is */ +/* responsible for port->bufchunk of a common buffer. */ /* */ -/* ------------------------------ */ -/* | ---------- ---------- | */ -/* --> | Descr1 |-->| Descr2 |--- */ -/* ---------- ---------- */ -/* | | */ -/* v v */ -/* ----------------------------- */ -/* | BUFFER | */ -/* ----------------------------- */ -/* | | */ +/* +---------------------------------------------+ */ +/* | +----------+ +----------+ +----------+ | */ +/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */ +/* +----------+ +----------+ +----------+ */ +/* | | | */ +/* v v v */ +/* +-------------------------------------+ */ +/* | BUFFER | */ +/* +-------------------------------------+ */ +/* |<- data_avail ->| */ /* readp writep */ /* */ /* If the application keeps up the pace readp will be right after writep.*/ /* If the application can't keep the pace we have to throw away data. */ /* The idea is that readp should be ready with the data pointed out by */ -/* Descr1 when the DMA has filled in Descr2. Otherwise we will discard */ +/* Descr[i] when the DMA has filled in Descr[i+1]. */ +/* Otherwise we will discard */ /* the rest of the data pointed out by Descr1 and set readp to the start */ /* of Descr2 */ @@ -57,14 +59,22 @@ /* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */ /* words can be handled */ - +#define NUM_IN_DESCR 3 #define IN_BUFFER_SIZE 12288 #define OUT_BUFFER_SIZE 4096 #define DEFAULT_FRAME_RATE 0 #define DEFAULT_WORD_RATE 7 +/* NOTE: Enabling some debug will likely cause overrun or underrun, + * especially if manual mode is use. + */ #define DEBUG(x) +#define DEBUGREAD(x) +#define DEBUGWRITE(x) +#define DEBUGPOLL(x) +#define DEBUGRXINT(x) +#define DEBUGTXINT(x) /* Define some macros to access ETRAX 100 registers */ #define SETF(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \ @@ -75,97 +85,126 @@ typedef struct sync_port { /* Etrax registers and bits*/ - volatile unsigned * const status; + const volatile unsigned * const status; volatile unsigned * const ctrl_data; volatile unsigned * const output_dma_first; volatile unsigned char * const output_dma_cmd; volatile unsigned char * const output_dma_clr_irq; volatile unsigned * const input_dma_first; volatile unsigned char * const input_dma_cmd; + volatile unsigned * const input_dma_descr; + /* 8*4 */ volatile unsigned char * const input_dma_clr_irq; volatile unsigned * const data_out; - volatile unsigned * const data_in; - char data_avail_bit; /* In R_IRQ_MASK1_RD */ - char transmitter_ready_bit; /* In R_IRQ_MASK1_RD */ - char ready_irq_bit; /* In R_IRQ_MASK1_SET and R_IRQ_MASK1_CLR */ + const volatile unsigned * const data_in; + char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ + char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */ - char output_dma_bit; /* In R_IRQ_MASK2_RD */ - int enabled; /* 1 if port is enabled */ - int use_dma; /* 1 if port uses dma */ - int port_nbr; /* Port 0 or 1 */ - unsigned ctrl_data_shadow; /* Register shadow */ + char output_dma_bit; /* In R_IRQ_MASK2_RD */ + /* End of fields initialised in array */ + char started; /* 1 if port has been started */ + char port_nbr; /* Port 0 or 1 */ char busy; /* 1 if port is busy */ - wait_queue_head_t out_wait_q; - wait_queue_head_t in_wait_q; + + char enabled; /* 1 if port is enabled */ + char use_dma; /* 1 if port uses dma */ + char cur_in_descr; + char tr_running; + + unsigned int ctrl_data_shadow; /* Register shadow */ + volatile unsigned int out_count; /* Remaining bytes for current transfer */ + unsigned char* outp; /* Current position in out_buffer */ + /* 16*4 */ + volatile unsigned char* volatile readp; /* Next byte to be read by application */ + volatile unsigned char* volatile writep; /* Next byte to be written by etrax */ + unsigned int in_buffer_size; + unsigned int inbufchunk; struct etrax_dma_descr out_descr; - struct etrax_dma_descr in_descr1; - struct etrax_dma_descr in_descr2; - char out_buffer[OUT_BUFFER_SIZE]; - int out_count; /* Remaining bytes for current transfer */ - char* outp; /* Current position in out_buffer */ - char in_buffer[IN_BUFFER_SIZE]; - volatile char* readp; /* Next byte to be read by application */ - volatile char* writep; /* Next byte to be written by etrax */ - int started; /* 1 if port has been started */ + struct etrax_dma_descr in_descr[NUM_IN_DESCR]; + unsigned char out_buffer[OUT_BUFFER_SIZE]; + unsigned char in_buffer[IN_BUFFER_SIZE]; + + wait_queue_head_t out_wait_q; + wait_queue_head_t in_wait_q; } sync_port; static int etrax_sync_serial_init(void); static void initialize_port(int portnbr); +static inline int sync_data_avail(struct sync_port *port); + static int sync_serial_open(struct inode *, struct file*); static int sync_serial_release(struct inode*, struct file*); +static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); + static int sync_serial_ioctl(struct inode*, struct file*, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos); -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos); static ssize_t sync_serial_read(struct file *file, char *buf, size_t count, loff_t *ppos); + +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_DMA +#endif + static void send_word(sync_port* port); static void start_dma(struct sync_port *port, const char* data, int count); static void start_dma_in(sync_port* port); +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif +#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ + !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) +#define SYNC_SER_MANUAL +#endif +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs); +#endif /* The ports */ static struct sync_port ports[]= { { - R_SYNC_SERIAL1_STATUS, /* status */ - R_SYNC_SERIAL1_CTRL, /* ctrl_data */ - R_DMA_CH8_FIRST, /* output_dma_first */ - R_DMA_CH8_CMD, /* output_dma_cmd */ - R_DMA_CH8_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH9_FIRST, /* input_dma_first */ - R_DMA_CH9_CMD, /* input_dma_cmd */ - R_DMA_CH9_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL1_TR_DATA, /* data_out */ - R_SYNC_SERIAL1_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser1_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL1_STATUS, + .ctrl_data = R_SYNC_SERIAL1_CTRL, + .output_dma_first = R_DMA_CH8_FIRST, + .output_dma_cmd = R_DMA_CH8_CMD, + .output_dma_clr_irq = R_DMA_CH8_CLR_INTR, + .input_dma_first = R_DMA_CH9_FIRST, + .input_dma_cmd = R_DMA_CH9_CMD, + .input_dma_descr = R_DMA_CH9_DESCR, + .input_dma_clr_irq = R_DMA_CH9_CLR_INTR, + .data_out = R_SYNC_SERIAL1_TR_DATA, + .data_in = R_SYNC_SERIAL1_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), }, { - R_SYNC_SERIAL3_STATUS, /* status */ - R_SYNC_SERIAL3_CTRL, /* ctrl_data */ - R_DMA_CH4_FIRST, /* output_dma_first */ - R_DMA_CH4_CMD, /* output_dma_cmd */ - R_DMA_CH4_CLR_INTR, /* output_dma_clr_irq */ - R_DMA_CH5_FIRST, /* input_dma_first */ - R_DMA_CH5_CMD, /* input_dma_cmd */ - R_DMA_CH5_CLR_INTR, /* input_dma_clr_irq */ - R_SYNC_SERIAL3_TR_DATA, /* data_out */ - R_SYNC_SERIAL3_REC_DATA,/* data in */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_data), /* data_avail_bit */ - IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), /* transmitter_ready_bit */ - IO_BITNR(R_IRQ_MASK1_SET, ser3_ready), /* ready_irq_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), /* input_dma_descr_bit */ - IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), /* output_dma_bit */ + .status = R_SYNC_SERIAL3_STATUS, + .ctrl_data = R_SYNC_SERIAL3_CTRL, + .output_dma_first = R_DMA_CH4_FIRST, + .output_dma_cmd = R_DMA_CH4_CMD, + .output_dma_clr_irq = R_DMA_CH4_CLR_INTR, + .input_dma_first = R_DMA_CH5_FIRST, + .input_dma_cmd = R_DMA_CH5_CMD, + .input_dma_descr = R_DMA_CH5_DESCR, + .input_dma_clr_irq = R_DMA_CH5_CLR_INTR, + .data_out = R_SYNC_SERIAL3_TR_DATA, + .data_in = R_SYNC_SERIAL3_REC_DATA, + .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_data), + .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), + .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), + .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), } }; @@ -176,12 +215,13 @@ #define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port)) static struct file_operations sync_serial_fops = { - owner: THIS_MODULE, - write: sync_serial_write, - read: sync_serial_read, - ioctl: sync_serial_ioctl, - open: sync_serial_open, - release: sync_serial_release + .owner = THIS_MODULE, + .write = sync_serial_write, + .read = sync_serial_read, + .poll = sync_serial_poll, + .ioctl = sync_serial_ioctl, + .open = sync_serial_open, + .release = sync_serial_release }; static int __init etrax_sync_serial_init(void) @@ -238,9 +278,9 @@ ports[1].use_dma = 1; initialize_port(1); if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1])) - panic("Can't allocate sync serial port 1 IRQ"); + panic("Can't allocate sync serial port 3 IRQ"); RESET_DMA(4); WAIT_DMA(4); RESET_DMA(5); WAIT_DMA(5); *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | @@ -254,7 +294,7 @@ #else ports[1].use_dma = 0; initialize_port(1); - if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ + if (!ports[0].enabled || ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */ { if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1])) panic("Can't allocate sync serial manual irq"); @@ -282,7 +322,7 @@ return 0; } -static void initialize_port(int portnbr) +static void __init initialize_port(int portnbr) { struct sync_port* port = &ports[portnbr]; @@ -290,13 +330,21 @@ port->started = 0; port->port_nbr = portnbr; - port->busy = 0; + port->busy = 0; + port->cur_in_descr = 0; + port->tr_running = 0; + + port->out_count = 0; + port->outp = port->out_buffer; + port->readp = port->in_buffer; port->writep = port->in_buffer; + port->in_buffer_size = IN_BUFFER_SIZE; + port->inbufchunk = port->in_buffer_size/NUM_IN_DESCR; init_waitqueue_head(&port->out_wait_q); init_waitqueue_head(&port->in_wait_q); - + port->ctrl_data_shadow = IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) | IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | @@ -329,9 +377,53 @@ *port->ctrl_data = port->ctrl_data_shadow; } +static inline int sync_data_avail(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- - ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer_size - (start - end); + return avail; +} + +static inline int sync_data_avail_to_end(struct sync_port *port) +{ + int avail; + unsigned char *start; + unsigned char *end; + + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + /* 0123456789 0123456789 + * ----- ----- + * ^rp ^wp ^wp ^rp + */ + + if (end >= start) + avail = end - start; + else + avail = port->in_buffer + port->in_buffer_size - start; + return avail; +} + + static int sync_serial_open(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + int mode; + DEBUG(printk("Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -339,33 +431,87 @@ DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - if (ports[dev].busy) + port = &ports[dev]; + /* Allow open this device twice (assuming one reader and one writer) */ + if (port->busy == 2) { DEBUG(printk("Device is busy.. \n")); return -EBUSY; } - ports[dev].busy = 1; + port->busy++; + /* Start port if we use it as input */ + mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow); + if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) || + mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); + port->started = 1; + *port->ctrl_data = port->ctrl_data_shadow; + if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + DEBUG(printk("sser%d rec started\n", dev)); + } return 0; } static int sync_serial_release(struct inode *inode, struct file *file) { int dev = MINOR(inode->i_rdev); + sync_port* port; + if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } - ports[dev].busy = 0; + port = &ports[dev]; + if (port->busy) + port->busy--; + if (!port->busy) + *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) | + (1 << port->transmitter_ready_bit)); + return 0; } + + +static unsigned int sync_serial_poll(struct file *file, poll_table *wait) +{ + int dev = MINOR(file->f_dentry->d_inode->i_rdev); + unsigned int mask = 0; + sync_port* port; + DEBUGPOLL( static unsigned int prev_mask = 0; ); + + port = &ports[dev]; + poll_wait(file, &port->out_wait_q, wait); + poll_wait(file, &port->in_wait_q, wait); + /* Some room to write */ + if (port->out_count < OUT_BUFFER_SIZE) + mask |= POLLOUT | POLLWRNORM; + /* At least an inbufchunk of data */ + if (sync_data_avail(port) >= port->inbufchunk) + mask |= POLLIN | POLLRDNORM; + + DEBUGPOLL(if (mask != prev_mask) + printk("sync_serial_poll: mask 0x%08X %s %s\n", mask, + mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":""); + prev_mask = mask; + ); + return mask; +} + static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; + unsigned long flags; + int dev = MINOR(file->f_dentry->d_inode->i_rdev); - sync_port* port; + sync_port* port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -374,197 +520,199 @@ } port = &ports[dev]; + save_flags(flags); + cli(); /* Disable port while changing config */ if (dev) { - RESET_DMA(4); WAIT_DMA(4); - *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(4); WAIT_DMA(4); + *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); } else { - RESET_DMA(8); WAIT_DMA(8); - *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | - IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + if (port->use_dma) { + RESET_DMA(8); WAIT_DMA(8); + *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | + IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); + } SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); } *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); switch(cmd) { - case SSP_SPEED: - if (GET_SPEED(arg) == CODEC) - { - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); - - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); - SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); - } + case SSP_SPEED: + if (GET_SPEED(arg) == CODEC) + { + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); else - { - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); - if (dev) - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); - else - SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); - } - break; - case SSP_MODE: - if (arg > 5) - return -EINVAL; - if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) - *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); + + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); + SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); + } + else + { + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); + if (dev) + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); else - *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); - break; - case SSP_FRAME_SYNC: - if (arg & NORMAL_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - else if (arg & EARLY_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); - - if (arg & BIT_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); - else if (arg & WORD_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); - else if (arg & EXTENDED_SYNC) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); - - if (arg & SYNC_ON) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - else if (arg & SYNC_OFF) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); - - if (arg & WORD_SIZE_8) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - else if (arg & WORD_SIZE_12) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); - else if (arg & WORD_SIZE_16) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); - else if (arg & WORD_SIZE_24) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); - else if (arg & WORD_SIZE_32) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); - - if (arg & BIT_ORDER_MSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - else if (arg & BIT_ORDER_LSB) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); - - if (arg & FLOW_CONTROL_ENABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); - else if (arg & FLOW_CONTROL_DISABLE) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - - if (arg & CLOCK_NOT_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); - else if (arg & CLOCK_GATED) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); - - break; - case SSP_IPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); - break; - case SSP_OPOLARITY: - if (arg & CLOCK_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); - else if (arg & CLOCK_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - - if (arg & FRAME_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); - else if (arg & FRAME_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - - if (arg & STATUS_NORMAL) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); - else if (arg & STATUS_INVERT) - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); - break; - case SSP_SPI: - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); + } + break; + case SSP_MODE: + if (arg > 5) + return -EINVAL; + if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) + *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; + else if (!port->use_dma) + *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); + break; + case SSP_FRAME_SYNC: + if (arg & NORMAL_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); - if (arg & SPI_SLAVE) - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); - } - else - { - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); - SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); - SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + else if (arg & EARLY_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); + + if (arg & BIT_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); + else if (arg & WORD_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + else if (arg & EXTENDED_SYNC) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); + + if (arg & SYNC_ON) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + else if (arg & SYNC_OFF) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); + + if (arg & WORD_SIZE_8) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + else if (arg & WORD_SIZE_12) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); + else if (arg & WORD_SIZE_16) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); + else if (arg & WORD_SIZE_24) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); + else if (arg & WORD_SIZE_32) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); + + if (arg & BIT_ORDER_MSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + else if (arg & BIT_ORDER_LSB) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); + + if (arg & FLOW_CONTROL_ENABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); + else if (arg & FLOW_CONTROL_DISABLE) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + + if (arg & CLOCK_NOT_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); + else if (arg & CLOCK_GATED) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); + + break; + case SSP_IPOLARITY: + /* NOTE!! negedge is considered NORMAL */ + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); + break; + case SSP_OPOLARITY: + if (arg & CLOCK_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); + else if (arg & CLOCK_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + + if (arg & FRAME_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); + else if (arg & FRAME_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + + if (arg & STATUS_NORMAL) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); + else if (arg & STATUS_INVERT) + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); + break; + case SSP_SPI: + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); + if (arg & SPI_SLAVE) + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); + } + else + { + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); + SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); + SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); + } + break; + case SSP_INBUFCHUNK: + if (arg > port->in_buffer_size/NUM_IN_DESCR) + return -EINVAL; + port->inbufchunk = arg; + /* Make sure in_buffer_size is a multiple of inbufchunk */ + port->in_buffer_size = (port->in_buffer_size/port->inbufchunk) * port->inbufchunk; + DEBUG(printk("inbufchunk %i in_buffer_size: %i\n", port->inbufchunk, port->in_buffer_size)); + if (port->use_dma) { + if (port->port_nbr == 0) { + RESET_DMA(9); + WAIT_DMA(9); + } else { + RESET_DMA(5); + WAIT_DMA(5); } - break; - default: - return_val = -1; + start_dma_in(port); + } + break; + default: + return_val = -1; } + /* Make sure we write the config without interruption */ + save_flags(flags); + cli(); /* Set config and enable port */ *port->ctrl_data = port->ctrl_data_shadow; + nop(); nop(); nop(); nop(); *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow; + nop(); nop(); nop(); nop(); if (dev) SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); else SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); *R_GEN_CONFIG_II = gen_config_ii_shadow; + restore_flags(flags); return return_val; } -static ssize_t sync_serial_manual_write(struct file * file, const char * buf, - size_t count, loff_t *ppos) -{ - int dev = MINOR(file->f_dentry->d_inode->i_rdev); - DECLARE_WAITQUEUE(wait, current); - sync_port* port; - - if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) - { - DEBUG(printk("Invalid minor %d\n", dev)); - return -ENODEV; - } - - port = &ports[dev]; - copy_from_user(port->out_buffer, buf, count); - port->outp = port->out_buffer; - port->out_count = count; - add_wait_queue(&port->out_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - send_word(port); /* Start sender by sending first word */ - *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */ - schedule(); - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->out_wait_q, &wait); - if (signal_pending(current)) - { - return -EINTR; - } - return count; -} static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos) @@ -572,6 +720,11 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); DECLARE_WAITQUEUE(wait, current); sync_port *port; + unsigned long flags; + unsigned long c, c1; + unsigned long free_outp; + unsigned long outp; + unsigned long out_buffer; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { @@ -580,9 +733,52 @@ } port = &ports[dev]; - DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count)); + DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); + /* Space to end of buffer */ + /* + * out_buffer 012345<- c ->OUT_BUFFER_SIZE + * outp^ +out_count + ^free_outp + * out_buffer 45<- c ->0123OUT_BUFFER_SIZE + * +out_count outp^ + * free_outp + * + */ - count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count; + /* Read variables that may be updated by interrupts */ + save_flags(flags); + cli(); + count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count; + outp = (unsigned long)port->outp; + free_outp = outp + port->out_count; + restore_flags(flags); + out_buffer = (unsigned long)port->out_buffer; + + /* Find out where and how much to write */ + if (free_outp >= out_buffer + OUT_BUFFER_SIZE) + free_outp -= OUT_BUFFER_SIZE; + if (free_outp >= outp) + c = out_buffer + OUT_BUFFER_SIZE - free_outp; + else + c = outp - free_outp; + if (c > count) + c = count; + +// DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c)); + if (copy_from_user((void*)free_outp, buf, c)) + return -EFAULT; + + if (c != count) { + buf += c; + c1 = count - c; + DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1)); + if (copy_from_user((void*)out_buffer, buf, c1)) + return -EFAULT; + } + save_flags(flags); + cli(); + port->out_count += count; + restore_flags(flags); /* Make sure transmitter/receiver is running */ if (!port->started) @@ -595,15 +791,42 @@ *port->ctrl_data = port->ctrl_data_shadow; - if (!port->use_dma) - { - return sync_serial_manual_write(file, buf, count, ppos); + if (file->f_flags & O_NONBLOCK) { + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, (unsigned char* volatile )port->outp, c); + } + } + restore_flags(flags); + DEBUGWRITE(printk("w d%d c %lu NB\n", + port->port_nbr, count)); + return count; } - - copy_from_user(port->out_buffer, buf, count); + + /* Sleep until all sent */ + add_wait_queue(&port->out_wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); - start_dma(port, buf, count); + save_flags(flags); + cli(); + if (!port->tr_running) { + if (!port->use_dma) { + /* Start sender by writing data */ + send_word(port); + /* and enable transmitter ready IRQ */ + *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; + } else { + start_dma(port, port->outp, c); + } + } + restore_flags(flags); schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(&port->out_wait_q, &wait); @@ -611,6 +834,7 @@ { return -EINTR; } + DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count)); return count; } @@ -620,8 +844,8 @@ int dev = MINOR(file->f_dentry->d_inode->i_rdev); int avail; sync_port *port; - char* start; - char* end; + unsigned char* start; + unsigned char* end; unsigned long flags; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) @@ -631,7 +855,7 @@ } port = &ports[dev]; - DEBUG(printk("Read dev %d count %d\n", dev, count)); + DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->in_buffer, port->writep - port->in_buffer, port->in_buffer_size)); if (!port->started) { @@ -640,11 +864,17 @@ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable); port->started = 1; } - *port->ctrl_data = port->ctrl_data_shadow; + /* Calculate number of available bytes */ - while (port->readp == port->writep) /* No data */ + /* Save pointers to avoid that they are modified by interrupt */ + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); + while (start == end) /* No data */ { if (file->f_flags & O_NONBLOCK) return -EAGAIN; @@ -653,127 +883,137 @@ { return -EINTR; } + save_flags(flags); + cli(); + start = (unsigned char*)port->readp; /* cast away volatile */ + end = (unsigned char*)port->writep; /* cast away volatile */ + restore_flags(flags); } - - /* Save pointers to avoid that they are modified by interrupt */ - start = port->readp; - end = port->writep; /* Lazy read, never return wrapped data. */ if (end > start) avail = end - start; else - avail = port->in_buffer + IN_BUFFER_SIZE - start; + avail = port->in_buffer + port->in_buffer_size - start; count = count > avail ? avail : count; - copy_to_user(buf, start, count); + if (copy_to_user(buf, start, count)) + return -EFAULT; /* Disable interrupts while updating readp */ save_flags(flags); cli(); port->readp += count; - if (port->readp == port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->readp = port->in_buffer; restore_flags(flags); - - DEBUG(printk("%d bytes read\n", count)); + DEBUGREAD(printk("r %d\n", count)); return count; } static void send_word(sync_port* port) { - switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) + switch(IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, port->ctrl_data_shadow)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - port->out_count--; - *port->data_out = *port->outp++; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = (*port->outp++) << 8; - data |= *port->outp++; - port->out_count-=2; - *port->data_out = data; - } - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - port->out_count-=2; - *port->data_out = *(unsigned short *)port->outp; - port->outp+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - port->out_count-=3; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - port->out_count-=4; - *port->data_out = *(unsigned int *)port->outp; - port->outp+=4; - break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + port->out_count--; + *port->data_out = *port->outp++; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = (*port->outp++) << 8; + data |= *port->outp++; + port->out_count-=2; + *port->data_out = data; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + } + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + port->out_count-=2; + *port->data_out = *(unsigned short *)port->outp; + port->outp+=2; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + port->out_count-=3; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=3; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; + case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + port->out_count-=4; + *port->data_out = *(unsigned int *)port->outp; + port->outp+=4; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + break; } } + static void start_dma(struct sync_port* port, const char* data, int count) { + port->tr_running = 1; port->out_descr.hw_len = 0; port->out_descr.next = 0; - port->out_descr.ctrl = d_eol | d_eop | d_wait; + port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */ port->out_descr.sw_len = count; - port->out_descr.buf = virt_to_phys(port->out_buffer); + port->out_descr.buf = virt_to_phys((char*)data); port->out_descr.status = 0; *port->output_dma_first = virt_to_phys(&port->out_descr); *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); + DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count)); } static void start_dma_in(sync_port* port) { - if (port->writep > port->in_buffer + IN_BUFFER_SIZE) + int i; + unsigned long buf; + port->cur_in_descr = 0; + port->writep = port->in_buffer; + + if (port->writep > port->in_buffer + port->in_buffer_size) { panic("Offset too large in sync serial driver\n"); return; } - port->in_descr1.hw_len = 0; - port->in_descr1.ctrl = d_int; - port->in_descr1.status = 0; - port->in_descr1.next = virt_to_phys(&port->in_descr2); - port->in_descr2.hw_len = 0; - port->in_descr2.next = virt_to_phys(&port->in_descr1); - port->in_descr2.ctrl = d_int; - port->in_descr2.status = 0; - - /* Find out which descriptor to start */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Start descriptor 2 */ - port->in_descr1.sw_len = IN_BUFFER_SIZE/2; /* All data available in 1 */ - port->in_descr1.buf = virt_to_phys(port->in_buffer); - port->in_descr2.sw_len = port->in_buffer + IN_BUFFER_SIZE - port->writep; - port->in_descr2.buf = virt_to_phys(port->writep); - *port->input_dma_first = virt_to_phys(&port->in_descr2); - } - else - { - /* Start descriptor 1 */ - port->in_descr1.sw_len = port->in_buffer + IN_BUFFER_SIZE/2 - port->writep; - port->in_descr1.buf = virt_to_phys(port->writep); - port->in_descr2.sw_len = IN_BUFFER_SIZE/2; - port->in_descr2.buf = virt_to_phys(port->in_buffer + IN_BUFFER_SIZE / 2); - *port->input_dma_first = virt_to_phys(&port->in_descr1); - } + buf = virt_to_phys(port->in_buffer); + for (i = 0; i < NUM_IN_DESCR; i++) { + port->in_descr[i].sw_len = port->inbufchunk; + port->in_descr[i].ctrl = d_int; + port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]); + port->in_descr[i].buf = buf; + port->in_descr[i].hw_len = 0; + port->in_descr[i].status = 0; + port->in_descr[i].fifo_len = 0; + buf += port->inbufchunk; + prepare_rx_descriptor(&port->in_descr[i]); + } + /* Link the last descriptor to the first */ + port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]); + *port->input_dma_first = virt_to_phys(&port->in_descr[(int)port->cur_in_descr]); *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); } +#ifdef SYNC_SER_DMA static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; int i; + struct etrax_dma_descr *descr; + unsigned int sentl; + for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */ @@ -782,54 +1022,89 @@ *port->output_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); + + descr = &port->out_descr; + if (!(descr->status & d_stop)) { + sentl = descr->sw_len; + } else + /* otherwise we find the amount of data sent here */ + sentl = descr->hw_len; + port->out_count -= sentl; + port->outp += sentl; + if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) + port->outp = port->out_buffer; + if (port->out_count) { + int c; + c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; + if (c > port->out_count) + c = port->out_count; + DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c)); + start_dma(port, port->outp, c); + } else { + DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl)); + port->tr_running = 0; + } wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */ } } -} +} /* tr_interrupt */ static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ireg = *R_IRQ_MASK2_RD; - int i; + int i; for (i = 0; i < NUMBER_OF_PORTS; i++) { sync_port *port = &ports[i]; - if (!port->enabled) + if (!port->enabled || !port->use_dma ) continue; if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */ { + struct etrax_dma_descr *descr; + unsigned recvl; + unsigned long oldbuf, buf; + /* DMA has reached end of descriptor */ *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); - - /* Find out which descriptor that is ready */ - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) - { - /* Descr 2 was ready. Restart DMA at descriptor 1 */ - port->writep = port->in_buffer; - - /* Throw away data? */ - if (port->readp < port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer + IN_BUFFER_SIZE/2; - } - else - { - /* Descr 1 was ready. Restart DMA at descriptor 2 */ - port->writep = port->in_buffer + IN_BUFFER_SIZE/2; - - /* Throw away data? */ - if (port->readp >= port->in_buffer + IN_BUFFER_SIZE/2) - port->readp = port->in_buffer; + + descr = &port->in_descr[(int)port->cur_in_descr]; + if (descr == phys_to_virt(*port->input_dma_descr)) + printk("sser: desc = *input_dma_descr\n"); + + if (!(descr->status & d_eop)) { + recvl = descr->sw_len; + } else { + /* otherwise we find the amount of data received here */ + recvl = descr->hw_len; } - start_dma_in(port); + port->writep += recvl; + if (port->writep >= port->in_buffer+ port->in_buffer_size) + port->writep = port->in_buffer; + descr->sw_len = port->inbufchunk; + /* Reset the status information */ + descr->status = 0; + /* Change the buf pointer to new position */ + oldbuf = descr->buf; + + descr->buf += NUM_IN_DESCR * port->inbufchunk; + buf = virt_to_phys(port->in_buffer); + if (descr->buf >= buf + port->in_buffer_size) + descr->buf -= port->in_buffer_size; + DEBUGRXINT(printk("rx_int descr %i %X recvl: %i writep %lu obuf %lu %08lX buf 0x%08lX\n", port->cur_in_descr, (unsigned long) (*port->input_dma_descr), recvl, (unsigned long)(port->writep - port->in_buffer), oldbuf, oldbuf, (unsigned long)descr->buf)); + if (++port->cur_in_descr == NUM_IN_DESCR) + port->cur_in_descr = 0; + wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */ } } -} +} /* rx_interrupt */ +#endif /* SYNC_SER_DMA */ +#ifdef SYNC_SER_MANUAL static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int i; @@ -838,7 +1113,7 @@ { sync_port* port = &ports[i]; - if (!port->enabled) + if (!port->enabled || port->use_dma) { continue; } @@ -848,34 +1123,42 @@ /* Read data */ switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) { - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): - *port->writep++ = *(volatile char *)port->data_in; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): - { - int data = *(unsigned short *)port->data_in; - *port->writep = (data & 0x0ff0) >> 4; - *(port->writep + 1) = data & 0x0f; - port->writep+=2; - } + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): + *port->writep++ = *(volatile char *)port->data_in; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): + { + int data = *(unsigned short *)port->data_in; + *port->writep = (data & 0x0ff0) >> 4; + *(port->writep + 1) = data & 0x0f; + port->writep+=2; + } + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): + *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; + port->writep+=2; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=3; + break; + case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): + *(unsigned int*)port->writep = *port->data_in; + port->writep+=4; break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): - *(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in; - port->writep+=2; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=3; - break; - case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): - *(unsigned int*)port->writep = *port->data_in; - port->writep+=4; - break; } - if (port->writep >= port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */ + if (port->writep >= port->in_buffer + port->in_buffer_size) /* Wrap? */ port->writep = port->in_buffer; - wake_up_interruptible(&port->in_wait_q); /* Wake up application */ + if (port->writep == port->readp) { + /* receive buffer overrun, discard oldest data + */ + port->readp++; + if (port->readp >= port->in_buffer + port->in_buffer_size) /* Wrap? */ + port->readp = port->in_buffer; + } + if (sync_data_avail(port) >= port->inbufchunk) + wake_up_interruptible(&port->in_wait_q); /* Wake up application */ } if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */ @@ -884,11 +1167,12 @@ send_word(port); else /* transmission finished */ { - *R_IRQ_MASK1_CLR = 1 << port->ready_irq_bit; /* Turn off IRQ */ + *R_IRQ_MASK1_CLR = 1 << port->transmitter_ready_bit; /* Turn off IRQ */ wake_up_interruptible(&port->out_wait_q); /* Wake up application */ } } } } +#endif module_init(etrax_sync_serial_init); diff -urN linux-2.4.24/arch/cris/drivers/usb-host.c linux-2.4.25/arch/cris/drivers/usb-host.c --- linux-2.4.24/arch/cris/drivers/usb-host.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/drivers/usb-host.c 2004-02-18 05:36:30.000000000 -0800 @@ -41,7 +41,7 @@ #define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR #define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR -static const char *usb_hcd_version = "$Revision: 1.18 $"; +static const char *usb_hcd_version = "$Revision: 1.19 $"; #undef KERN_DEBUG #define KERN_DEBUG "" @@ -1540,9 +1540,18 @@ ctrl pipes are not. */ if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) { + __u32 r_usb_ept_data; + warn("error in rx desc->status, epid %d, first urb = 0x%lx", epid, (unsigned long)urb); __dump_in_desc(myNextRxDesc); + + *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); + nop(); + r_usb_ept_data = *R_USB_EPT_DATA; + warn("R_USB_EPT_DATA for epid %d = 0x%x", epid, r_usb_ept_data); + warn("R_USB_STATUS = 0x%x", *R_USB_STATUS); + etrax_usb_complete_urb(urb, -EPROTO); goto skip_out; } diff -urN linux-2.4.24/arch/cris/kernel/debug.c linux-2.4.25/arch/cris/kernel/debug.c --- linux-2.4.24/arch/cris/kernel/debug.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/kernel/debug.c 2004-02-18 05:36:30.000000000 -0800 @@ -2,7 +2,7 @@ * arch/cris/kernel/debug.c * Various debug routines: * o Logging of interrupt enabling/disabling. /proc/debug_interrupt - * gives result and toggles if it is enabled or not. + * gives result and enables logging when read. * * Copyright (C) 2003 Axis Communications AB */ @@ -24,7 +24,7 @@ int log_int_trig0_pos = 0; int log_int_trig1_pos = 0; -int log_int_enable = 0; /* toggled every read of /proc/debug_interrupt */ +int log_int_enable = 0; /* Enabled every read of /proc/debug_interrupt */ struct log_int_struct { diff -urN linux-2.4.24/arch/cris/kernel/hexify.c linux-2.4.25/arch/cris/kernel/hexify.c --- linux-2.4.24/arch/cris/kernel/hexify.c 2001-02-08 16:32:44.000000000 -0800 +++ linux-2.4.25/arch/cris/kernel/hexify.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,31 +0,0 @@ -#include - - -void main() -{ - int c; - int comma=0; - int count=0; - while((c=getchar())!=EOF) - { - unsigned char x=c; - if(comma) - printf(","); - else - comma=1; - if(count==8) - { - count=0; - printf("\n"); - } - if(count==0) - printf("\t"); - printf("0x%02X",c); - count++; - } - if(count) - printf("\n"); - exit(0); -} - - diff -urN linux-2.4.24/arch/cris/kernel/ksyms.c linux-2.4.25/arch/cris/kernel/ksyms.c --- linux-2.4.24/arch/cris/kernel/ksyms.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/cris/kernel/ksyms.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void dump_thread(struct pt_regs *, struct user *); -extern unsigned long get_cmos_time(void); -extern void __Udiv(void); -extern void __Umod(void); -extern void __ashrdi3(void); -extern void iounmap(void *addr); - -/* Platform dependent support */ -EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(get_cmos_time); -EXPORT_SYMBOL(loops_per_usec); - -/* String functions */ -EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(strtok); -EXPORT_SYMBOL(strpbrk); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strcpy); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strncat); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); - -/* Math functions */ -EXPORT_SYMBOL(__Udiv); -EXPORT_SYMBOL(__Umod); -EXPORT_SYMBOL(__ashrdi3); - -/* Memory functions */ -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(iounmap); - -/* Semaphore functions */ -EXPORT_SYMBOL(__up); -EXPORT_SYMBOL(__down); - -/* Export shadow registers for the CPU I/O pins */ -EXPORT_SYMBOL(genconfig_shadow); -EXPORT_SYMBOL(port_pa_data_shadow); -EXPORT_SYMBOL(port_pa_dir_shadow); -EXPORT_SYMBOL(port_pb_data_shadow); -EXPORT_SYMBOL(port_pb_dir_shadow); -EXPORT_SYMBOL(port_pb_config_shadow); -EXPORT_SYMBOL(port_g_data_shadow); - -/* Userspace access functions */ -EXPORT_SYMBOL(__copy_user_zeroing); -EXPORT_SYMBOL(__copy_user); - -/* Cache flush functions */ -EXPORT_SYMBOL(flush_etrax_cache); -EXPORT_SYMBOL(prepare_rx_descriptor); - -#undef memcpy -#undef memset -extern void * memset(void *, int, __kernel_size_t); -extern void * memcpy(void *, const void *, __kernel_size_t); -EXPORT_SYMBOL_NOVERS(memcpy); -EXPORT_SYMBOL_NOVERS(memset); - - diff -urN linux-2.4.24/arch/cris/kernel/ptrace.c linux-2.4.25/arch/cris/kernel/ptrace.c --- linux-2.4.24/arch/cris/kernel/ptrace.c 2002-02-25 11:37:52.000000000 -0800 +++ linux-2.4.25/arch/cris/kernel/ptrace.c 2004-02-18 05:36:30.000000000 -0800 @@ -8,6 +8,10 @@ * Authors: Bjorn Wesen * * $Log: ptrace.c,v $ + * Revision 1.9 2003/10/01 11:34:23 aurer + * * Allow PTRACE_PEEKUSR and PTRACE_POKEUSR to access USP. + * * Removed nonsensical comment about ptrace behavior. + * * Revision 1.8 2001/11/12 18:26:21 pkj * Fixed compiler warnings. * @@ -96,14 +100,6 @@ /* Todo - pending singlesteps? */ } -/* Note that this implementation of ptrace behaves differently from vanilla - * ptrace. Contrary to what the man page says, in the PTRACE_PEEKTEXT, - * PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not - * ignored. Instead, the data variable is expected to point at a location - * (in user space) where the result of the ptrace call is written (instead of - * being returned). - */ - asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -163,17 +159,13 @@ /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; - + ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - - tmp = 0; /* Default return condition */ - ret = -EIO; - if (addr < sizeof(struct pt_regs)) { - tmp = get_reg(child, addr >> 2); - ret = put_user(tmp, (unsigned long *)data); - } + + tmp = get_reg(child, addr >> 2); + ret = put_user(tmp, (unsigned long *)data); break; } @@ -188,23 +180,21 @@ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - if (addr < sizeof(struct pt_regs)) { - addr >>= 2; + addr >>= 2; - if (addr == PT_DCCR) { + if (addr == PT_DCCR) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ - data &= DCCR_MASK; - data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; - } - if (put_reg(child, addr, data)) - break; - ret = 0; + data &= DCCR_MASK; + data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } + if (put_reg(child, addr, data)) + break; + ret = 0; break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ diff -urN linux-2.4.24/arch/cris/kernel/sys_cris.c linux-2.4.25/arch/cris/kernel/sys_cris.c --- linux-2.4.24/arch/cris/kernel/sys_cris.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/kernel/sys_cris.c 2004-02-18 05:36:30.000000000 -0800 @@ -109,7 +109,10 @@ switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + return sys_semtimedop (first, (struct sembuf *)ptr, second, NULL); + case SEMTIMEDOP: + return sys_semtimedop (first, (struct sembuf *)ptr, second, + (const struct timespec *)fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { @@ -163,7 +166,7 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -urN linux-2.4.24/arch/cris/kernel/time.c linux-2.4.25/arch/cris/kernel/time.c --- linux-2.4.24/arch/cris/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -328,7 +328,7 @@ int retval = 0; int real_seconds, real_minutes, cmos_minutes; - printk(KERN_INFO "set_rtc_mmss(%lu)\n", nowtime); + printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime); if(!have_rtc) return 0; @@ -514,7 +514,7 @@ mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); - printk(KERN_INFO + printk(KERN_DEBUG "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", sec, min, hour, day, mon, year); diff -urN linux-2.4.24/arch/cris/lib/dram_init.S linux-2.4.25/arch/cris/lib/dram_init.S --- linux-2.4.24/arch/cris/lib/dram_init.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/lib/dram_init.S 2004-02-18 05:36:30.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: dram_init.S,v 1.14 2003/03/31 07:07:08 starvik Exp $ +/* $Id: dram_init.S,v 1.15 2003/09/22 09:22:22 starvik Exp $ * * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files @@ -11,6 +11,10 @@ * Authors: Mikael Starvik (starvik@axis.com) * * $Log: dram_init.S,v $ + * Revision 1.15 2003/09/22 09:22:22 starvik + * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx + * so we need to mask off 12 bits. + * * Revision 1.14 2003/03/31 07:07:08 starvik * Corrected calculation of end of sdram init commands * @@ -149,9 +153,9 @@ ; Issue initialization command sequence move.d _sdram_commands_start, $r2 - and.d 0x00ffffff, $r2 ; Make sure commands are read from flash + and.d 0x000fffff, $r2 ; Make sure commands are read from flash move.d _sdram_commands_end, $r3 - and.d 0x00ffffff, $r3 + and.d 0x000fffff, $r3 1: clear.d $r4 move.b [$r2+], $r4 lslq 9, $r4 ; Command starts at bit 9 diff -urN linux-2.4.24/arch/cris/mm/fault.c linux-2.4.25/arch/cris/mm/fault.c --- linux-2.4.24/arch/cris/mm/fault.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/cris/mm/fault.c 2004-02-18 05:36:30.000000000 -0800 @@ -6,6 +6,9 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ + * Revision 1.23 2003/10/16 05:32:32 starvik + * Only read TLB_SELECT if DEBUG + * * Revision 1.22 2003/07/07 09:07:04 johana * Added special CONFIG_ETRAX_DEBUG_INTERRUPT handling here * to deal with a di in entry.S @@ -119,8 +122,9 @@ void handle_mmu_bus_fault(struct pt_regs *regs) { - int cause, select; + int cause; #ifdef DEBUG + int select; int index; int page_id; int acc, inv; @@ -135,11 +139,11 @@ log_int(rdpc(), regs->dccr, 0); #endif cause = *R_MMU_CAUSE; - select = *R_TLB_SELECT; address = cause & PAGE_MASK; /* get faulting address */ #ifdef DEBUG + select = *R_TLB_SELECT; page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); diff -urN linux-2.4.24/arch/i386/boot/setup.S linux-2.4.25/arch/i386/boot/setup.S --- linux-2.4.24/arch/i386/boot/setup.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/boot/setup.S 2004-02-18 05:36:30.000000000 -0800 @@ -49,6 +49,8 @@ * by Matt Domsch October 2002 * conformant to T13 Committee www.t13.org * projects 1572D, 1484D, 1386D, 1226DT + * disk signature read by Matt Domsch + * and Andrew Wilks September 2003 */ #include @@ -549,6 +551,25 @@ #endif #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +# Read the first sector of device 80h and store the 4-byte signature + movl $0xFFFFFFFF, %eax + movl %eax, (DISK80_SIG_BUFFER) # assume failure + movb $READ_SECTORS, %ah + movb $1, %al # read 1 sector + movb $0x80, %dl # from device 80 + movb $0, %dh # at head 0 + movw $1, %cx # cylinder 0, sector 0 + pushw %es + pushw %ds + popw %es + movw $EDDBUF, %bx + int $0x13 + jc disk_sig_done + movl (EDDBUF+MBR_SIG_OFFSET), %eax + movl %eax, (DISK80_SIG_BUFFER) # store success +disk_sig_done: + popw %es + # Do the BIOS Enhanced Disk Drive calls # This consists of two calls: # int 13h ah=41h "Check Extensions Present" diff -urN linux-2.4.24/arch/i386/config.in linux-2.4.25/arch/i386/config.in --- linux-2.4.24/arch/i386/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -328,6 +328,7 @@ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER bool 'Power Management support' CONFIG_PM @@ -370,7 +371,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/i386/defconfig linux-2.4.25/arch/i386/defconfig --- linux-2.4.24/arch/i386/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -288,7 +288,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/i386/kernel/acpi.c linux-2.4.25/arch/i386/kernel/acpi.c --- linux-2.4.24/arch/i386/kernel/acpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/acpi.c 2004-02-18 05:36:30.000000000 -0800 @@ -333,8 +333,10 @@ * Initialize the ACPI boot-time table parser. */ result = acpi_table_init(); - if (result) + if (result) { + acpi_disabled = 1; return result; + } result = acpi_blacklisted(); if (result) { diff -urN linux-2.4.24/arch/i386/kernel/edd.c linux-2.4.25/arch/i386/kernel/edd.c --- linux-2.4.24/arch/i386/kernel/edd.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/edd.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,8 @@ /* * linux/arch/i386/kernel/edd.c - * Copyright (C) 2002 Dell Computer Corporation + * Copyright (C) 2002, 2003 Dell, Inc. * by Matt Domsch + * disk80 signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya * * BIOS Enhanced Disk Drive Services (EDD) * conformant to T13 Committee www.t13.org @@ -27,7 +28,6 @@ /* * TODO: * - move edd.[ch] to better locations if/when one is decided - * - keep current with 2.5 EDD code changes */ #include @@ -46,7 +46,7 @@ MODULE_DESCRIPTION("proc interface to BIOS EDD information"); MODULE_LICENSE("GPL"); -#define EDD_VERSION "0.09 2003-Jan-21" +#define EDD_VERSION "0.10 2003-Dec-05" #define EDD_DEVICE_NAME_SIZE 16 #define REPORT_URL "http://domsch.com/linux/edd30/results.html" @@ -333,6 +333,18 @@ } static int +edd_show_disk80_sig(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + char *p = page; + if ( !page || off) { + return proc_calc_metrics(page, start, off, count, eof, 0); + } + + p += snprintf(p, left, "0x%08x\n", edd_disk80_sig); + return proc_calc_metrics(page, start, off, count, eof, (p - page)); +} + +static int edd_show_extensions(char *page, char **start, off_t off, int count, int *eof, void *data) { struct edd_info *info = data; @@ -491,6 +503,15 @@ return 1; } +static int +edd_has_disk80_sig(struct edd_device *edev) +{ + struct edd_info *info = edd_dev_get_info(edev); + if (!edev || !info) + return 0; + return info->device == 0x80; +} + static EDD_DEVICE_ATTR(raw_data, edd_show_raw_data, NULL); static EDD_DEVICE_ATTR(version, edd_show_version, NULL); static EDD_DEVICE_ATTR(extensions, edd_show_extensions, NULL); @@ -505,6 +526,7 @@ edd_has_default_sectors_per_track); static EDD_DEVICE_ATTR(interface, edd_show_interface,edd_has_edd30); static EDD_DEVICE_ATTR(host_bus, edd_show_host_bus, edd_has_edd30); +static EDD_DEVICE_ATTR(mbr_signature, edd_show_disk80_sig, edd_has_disk80_sig); static struct edd_attribute *def_attrs[] = { &edd_attr_raw_data, @@ -517,6 +539,7 @@ &edd_attr_default_sectors_per_track, &edd_attr_interface, &edd_attr_host_bus, + &edd_attr_mbr_signature, NULL, }; diff -urN linux-2.4.24/arch/i386/kernel/i386_ksyms.c linux-2.4.25/arch/i386/kernel/i386_ksyms.c --- linux-2.4.24/arch/i386/kernel/i386_ksyms.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/i386_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -185,4 +185,5 @@ #ifdef CONFIG_EDD_MODULE EXPORT_SYMBOL(edd); EXPORT_SYMBOL(eddnr); +EXPORT_SYMBOL(edd_disk80_sig); #endif diff -urN linux-2.4.24/arch/i386/kernel/ldt.c linux-2.4.25/arch/i386/kernel/ldt.c --- linux-2.4.24/arch/i386/kernel/ldt.c 2001-10-17 14:46:29.000000000 -0700 +++ linux-2.4.25/arch/i386/kernel/ldt.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,37 +12,139 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ +static void flush_ldt(void *mm) +{ + if (current->active_mm) + load_LDT(¤t->active_mm->context); +} +#endif + +static int alloc_ldt(mm_context_t *pc, int mincount, int reload) +{ + void *oldldt; + void *newldt; + int oldsize; + + if (mincount <= pc->size) + return 0; + oldsize = pc->size; + mincount = (mincount+511)&(~511); + if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) + newldt = vmalloc(mincount*LDT_ENTRY_SIZE); + else + newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); + + if (!newldt) + return -ENOMEM; + + if (oldsize) + memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); + + oldldt = pc->ldt; + memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); + wmb(); + pc->ldt = newldt; + pc->size = mincount; + if (reload) { + load_LDT(pc); +#ifdef CONFIG_SMP + if (current->mm->cpu_vm_mask != (1< PAGE_SIZE) + vfree(oldldt); + else + kfree(oldldt); + } + return 0; +} + +static inline int copy_ldt(mm_context_t *new, mm_context_t *old) +{ + int err = alloc_ldt(new, old->size, 0); + if (err < 0) { + printk(KERN_WARNING "ldt allocation failed\n"); + new->size = 0; + return err; + } + memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); + return 0; +} + +/* + * we do not have to muck with descriptors here, that is + * done in switch_mm() as needed. + */ +int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + struct mm_struct * old_mm; + int retval = 0; + + init_MUTEX(&mm->context.sem); + mm->context.size = 0; + old_mm = current->mm; + if (old_mm && old_mm->context.size > 0) { + down(&old_mm->context.sem); + retval = copy_ldt(&mm->context, &old_mm->context); + up(&old_mm->context.sem); + } + return retval; +} + /* - * read_ldt() is not really atomic - this is not a problem since - * synchronization of reads and writes done to the LDT has to be - * assured by user-space anyway. Writes are atomic, to protect - * the security checks done on new descriptors. + * No need to lock the MM as we are the last user + * Do not touch the ldt register, we are already + * in the next thread. */ +void destroy_context(struct mm_struct *mm) +{ + if (mm->context.size) { + if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) + vfree(mm->context.ldt); + else + kfree(mm->context.ldt); + mm->context.size = 0; + } +} + static int read_ldt(void * ptr, unsigned long bytecount) { int err; unsigned long size; struct mm_struct * mm = current->mm; - err = 0; - if (!mm->context.segments) - goto out; + if (!mm->context.size) + return 0; + if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) + bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - size = LDT_ENTRIES*LDT_ENTRY_SIZE; + down(&mm->context.sem); + size = mm->context.size*LDT_ENTRY_SIZE; if (size > bytecount) size = bytecount; - err = size; - if (copy_to_user(ptr, mm->context.segments, size)) + err = 0; + if (copy_to_user(ptr, mm->context.ldt, size)) err = -EFAULT; -out: - return err; + up(&mm->context.sem); + if (err < 0) + return err; + if (size != bytecount) { + /* zero-fill the rest */ + clear_user(ptr+size, bytecount-size); + } + return bytecount; } static int read_default_ldt(void * ptr, unsigned long bytecount) @@ -53,7 +155,7 @@ err = 0; address = &default_ldt[0]; - size = sizeof(struct desc_struct); + size = 5*sizeof(struct desc_struct); if (size > bytecount) size = bytecount; @@ -88,24 +190,14 @@ goto out; } - /* - * the GDT index of the LDT is allocated dynamically, and is - * limited by MAX_LDT_DESCRIPTORS. - */ - down_write(&mm->mmap_sem); - if (!mm->context.segments) { - void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - error = -ENOMEM; - if (!segments) + down(&mm->context.sem); + if (ldt_info.entry_number >= mm->context.size) { + error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1); + if (error < 0) goto out_unlock; - memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); - wmb(); - mm->context.segments = segments; - mm->context.cpuvalid = 1UL << smp_processor_id(); - load_LDT(mm); } - lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.segments); + lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt); /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { @@ -143,7 +235,7 @@ error = 0; out_unlock: - up_write(&mm->mmap_sem); + up(&mm->context.sem); out: return error; } diff -urN linux-2.4.24/arch/i386/kernel/microcode.c linux-2.4.25/arch/i386/kernel/microcode.c --- linux-2.4.24/arch/i386/kernel/microcode.c 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/i386/kernel/microcode.c 2004-02-18 05:36:30.000000000 -0800 @@ -57,351 +57,456 @@ * nature of implementation. * 1.11 22 Mar 2002 Tigran Aivazian * Fix the panic when writing zero-length microcode chunk. + * 1.12 29 Sep 2003 Nitin Kamble , + * Jun Nakajima + * Support for the microcode updates in the new format. + * 1.13 10 Oct 2003 Tigran Aivazian + * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl + * because we no longer hold a copy of applied microcode + * in kernel memory. */ + #include #include #include #include #include #include -#include #include +#include #include #include #include - -static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED; - -#define MICROCODE_VERSION "1.11" - MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver"); MODULE_AUTHOR("Tigran Aivazian "); MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; - -#define MICRO_DEBUG 0 +#define MICROCODE_VERSION "1.13" +#define MICRO_DEBUG 1 #if MICRO_DEBUG -#define printf(x...) printk(##x) +#define dprintk(x...) printk(KERN_INFO x) #else -#define printf(x...) +#define dprintk(x...) #endif -/* VFS interface */ -static int microcode_open(struct inode *, struct file *); -static ssize_t microcode_read(struct file *, char *, size_t, loff_t *); -static ssize_t microcode_write(struct file *, const char *, size_t, loff_t *); -static int microcode_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - -static int do_microcode_update(void); -static void do_update_one(void *); - -/* read()/write()/ioctl() are serialized on this */ -static DECLARE_RWSEM(microcode_rwsem); - -static struct microcode *microcode; /* array of 2048byte microcode blocks */ -static unsigned int microcode_num; /* number of chunks in microcode */ -static char *mc_applied; /* array of applied microcode blocks */ -static unsigned int mc_fsize; /* file size of /dev/cpu/microcode */ +#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ +#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ +#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ +#define EXT_HEADER_SIZE (sizeof (struct extended_sigtable)) /* 20 bytes */ +#define EXT_SIGNATURE_SIZE (sizeof (struct extended_signature)) /* 12 bytes */ +#define DWSIZE (sizeof (u32)) +#define get_totalsize(mc) \ + (((microcode_t *)mc)->hdr.totalsize ? \ + ((microcode_t *)mc)->hdr.totalsize : DEFAULT_UCODE_TOTALSIZE) +#define get_datasize(mc) \ + (((microcode_t *)mc)->hdr.datasize ? \ + ((microcode_t *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) +#define sigmatch(s1, s2, p1, p2) (((s1) == (s2)) && ((p1) & (p2))) +#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) -/* we share file_operations between misc and devfs mechanisms */ -static struct file_operations microcode_fops = { - owner: THIS_MODULE, - read: microcode_read, - write: microcode_write, - ioctl: microcode_ioctl, - open: microcode_open, -}; +/* serialize access to the physical write to MSR 0x79 */ +static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED; -static struct miscdevice microcode_dev = { - minor: MICROCODE_MINOR, - name: "microcode", - fops: µcode_fops, -}; +/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ +static DECLARE_MUTEX(microcode_sem); -static devfs_handle_t devfs_handle; +static void *user_buffer; /* user area microcode data buffer */ +static unsigned int user_buffer_size; /* it's size */ -static int __init microcode_init(void) +typedef enum mc_error_code { + MC_SUCCESS = 0, + MC_NOTFOUND = 1, + MC_MARKED = 2, + MC_ALLOCATED = 3, +} mc_error_code_t; + +static struct ucode_cpu_info { + unsigned int sig; + unsigned int pf; + unsigned int rev; + unsigned int cksum; + mc_error_code_t err; + microcode_t *mc; +} ucode_cpu_info[NR_CPUS]; + +static int microcode_open (struct inode *unused1, struct file *unused2) { - int error; + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} - error = misc_register(µcode_dev); - if (error) - printk(KERN_WARNING - "microcode: can't misc_register on minor=%d\n", - MICROCODE_MINOR); +static void collect_cpu_info (void *unused) +{ + int cpu_num = smp_processor_id(); + struct cpuinfo_x86 *c = cpu_data + cpu_num; + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + unsigned int val[2]; + + uci->sig = uci->pf = uci->rev = uci->cksum = 0; + uci->err = MC_NOTFOUND; + uci->mc = NULL; + + if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || + cpu_has(c, X86_FEATURE_IA64)) { + printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); + return; + } else { + uci->sig = cpuid_eax(0x00000001); - devfs_handle = devfs_register(NULL, "cpu/microcode", - DEVFS_FL_DEFAULT, 0, 0, S_IFREG | S_IRUSR | S_IWUSR, - µcode_fops, NULL); - if (devfs_handle == NULL && error) { - printk(KERN_ERR "microcode: failed to devfs_register()\n"); + if ((c->x86_model >= 5) || (c->x86 > 6)) { + /* get processor flags from MSR 0x17 */ + rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); + uci->pf = 1 << ((val[1] >> 18) & 7); + } + } + + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* get the current revision from MSR 0x8B */ + rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); + dprintk("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", + uci->sig, uci->pf, uci->rev); +} + +static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) +{ + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + + dprintk("Microcode Found.\n"); + dprintk(" Header Revision 0x%x\n", mc_header->hdrver); + dprintk(" Loader Revision 0x%x\n", mc_header->ldrver); + dprintk(" Revision 0x%x \n", mc_header->rev); + dprintk(" Date %x/%x/%x\n", + ((mc_header->date >> 24 ) & 0xff), + ((mc_header->date >> 16 ) & 0xff), + (mc_header->date & 0xFFFF)); + dprintk(" Signature 0x%x\n", sig); + dprintk(" Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n", + ((sig >> 12) & 0x3), + ((sig >> 8) & 0xf), + ((sig >> 4) & 0xf), + ((sig & 0xf))); + dprintk(" Processor Flags 0x%x\n", pf); + dprintk(" Checksum 0x%x\n", cksum); + + if (mc_header->rev < uci->rev) { + printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + goto out; + } else if (mc_header->rev == uci->rev) { + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + printk(KERN_ERR "microcode: CPU%d already at revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); goto out; } - error = 0; - printk(KERN_INFO - "IA-32 Microcode Update Driver: v%s \n", - MICROCODE_VERSION); + dprintk("microcode: CPU%d found a matching microcode update with " + " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + uci->cksum = cksum; + uci->pf = pf; /* keep the original mc pf for cksum calculation */ + uci->err = MC_MARKED; /* found the match */ out: - return error; + return; } -static void __exit microcode_exit(void) +static int find_matching_ucodes (void) { - misc_deregister(µcode_dev); - devfs_unregister(devfs_handle); - if (mc_applied) - kfree(mc_applied); - printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", - MICROCODE_VERSION); -} + int cursor = 0; + int error = 0; -module_init(microcode_init) -module_exit(microcode_exit) + while (cursor + MC_HEADER_SIZE < user_buffer_size) { + microcode_header_t mc_header; + void *newmc = NULL; + int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size; + + if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; + } -static int microcode_open(struct inode *unused1, struct file *unused2) -{ - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} + total_size = get_totalsize(&mc_header); + if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } -/* - * update_req[cpu].err is set to 1 if update failed on 'cpu', 0 otherwise - * if err==0, microcode[update_req[cpu].slot] points to applied block of microcode - */ -struct update_req { - int err; - int slot; -} update_req[NR_CPUS]; + data_size = get_datasize(&mc_header); + if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } -static int do_microcode_update(void) -{ - int i, error = 0, err; - struct microcode *m; + if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { + printk(KERN_ERR "microcode: error! Unknown microcode update format\n"); + error = -EINVAL; + goto out; + } + + for (cpu_num = 0; cpu_num < smp_num_cpus; cpu_num++) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; - if (smp_call_function(do_update_one, NULL, 1, 1) != 0) { - printk(KERN_ERR "microcode: IPI timeout, giving up\n"); - return -EIO; - } - do_update_one(NULL); + if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf)) + mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); + } - for (i=0; ierr != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; + if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) { + mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); + } + } + } } - } + /* now check if any cpu has matched */ + for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num < smp_num_cpus; cpu_num++) { + if (ucode_cpu_info[cpu_num].err == MC_MARKED) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (!allocated_flag) { + allocated_flag = 1; + newmc = vmalloc(total_size); + if (!newmc) { + printk(KERN_ERR "microcode: error! Can not allocate memory\n"); + error = -ENOMEM; + goto out; + } + if (copy_from_user(newmc + MC_HEADER_SIZE, + user_buffer + cursor + MC_HEADER_SIZE, + total_size - MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + vfree(newmc); + error = -EFAULT; + goto out; + } + memcpy(newmc, &mc_header, MC_HEADER_SIZE); + /* check extended table checksum */ + if (ext_table_size) { + int * ext_tablep; + int ext_table_sum = 0; + i = ext_table_size / DWSIZE; + ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size); + while (i--) ext_table_sum += ext_tablep[i]; + if (ext_table_sum) { + printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n"); + vfree(newmc); + error = -EINVAL; + goto out; + } + } + + /* calculate the checksum */ + i = (MC_HEADER_SIZE + data_size) / DWSIZE; + while (i--) sum += ((int *)newmc)[i]; + sum -= (mc_header.sig + mc_header.pf + mc_header.cksum); + } + ucode_cpu_info[cpu_num].mc = newmc; + ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */ + if (sum + uci->sig + uci->pf + uci->cksum != 0) { + printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num); + error = -EINVAL; + goto out; + } + } + } + cursor += total_size; /* goto the next update patch */ + } /* end of while */ +out: return error; } -static void do_update_one(void *unused) +static void do_update_one (void * unused) { - int cpu_num = smp_processor_id(); - struct cpuinfo_x86 *c = cpu_data + cpu_num; - struct update_req *req = update_req + cpu_num; - unsigned int pf = 0, val[2], rev, sig; unsigned long flags; - int i; - - req->err = 1; /* assume update will fail on this cpu */ + unsigned int val[2]; + int cpu_num = smp_processor_id(); + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || - test_bit(X86_FEATURE_IA64, &c->x86_capability)){ - printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); + if (uci->mc == NULL) { + printk(KERN_INFO "microcode: No suitable data for cpu %d\n", cpu_num); return; } - sig = c->x86_mask + (c->x86_model<<4) + (c->x86<<8); + /* serialize access to the physical write to MSR 0x79 */ + spin_lock_irqsave(µcode_update_lock, flags); - if ((c->x86_model >= 5) || (c->x86 > 6)) { - /* get processor flags from MSR 0x17 */ - rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); - pf = 1 << ((val[1] >> 18) & 7); - } - - for (i=0; i> 24 ) & 0xff), - ((microcode[i].date >> 16 ) & 0xff), - (microcode[i].date & 0xFFFF)); - printf(" Type %x Family %x Model %x Stepping %x\n", - ((microcode[i].sig >> 12) & 0x3), - ((microcode[i].sig >> 8) & 0xf), - ((microcode[i].sig >> 4) & 0xf), - ((microcode[i].sig & 0xf))); - printf(" Checksum %x\n",microcode[i].cksum); - printf(" Loader Revision %x\n",microcode[i].ldrver); - printf(" Processor Flags %x\n\n",microcode[i].pf); - - req->slot = i; - - /* serialize access to update decision */ - spin_lock_irqsave(µcode_update_lock, flags); - - /* trick, to work even if there was no prior update by the BIOS */ - wrmsr(MSR_IA32_UCODE_REV, 0, 0); - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* write microcode via MSR 0x79 */ + wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(uci->mc->bits), 0); + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + + __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + /* get the current revision from MSR 0x8B */ + rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); + + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + spin_unlock_irqrestore(µcode_update_lock, flags); + printk(KERN_INFO "microcode: CPU%d updated from revision " + "0x%x to 0x%x, date = %08x \n", + cpu_num, uci->rev, val[1], uci->mc->hdr.date); + return; +} - /* get current (on-cpu) revision into rev (ignore val[0]) */ - rdmsr(MSR_IA32_UCODE_REV, val[0], rev); - - if (microcode[i].rev < rev) { - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR - "microcode: CPU%d not 'upgrading' to earlier revision" - " %d (current=%d)\n", cpu_num, microcode[i].rev, rev); - return; - } else if (microcode[i].rev == rev) { - /* notify the caller of success on this cpu */ - req->err = 0; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR - "microcode: CPU%d already at revision" - " %d (current=%d)\n", cpu_num, microcode[i].rev, rev); - return; - } +static int do_microcode_update (void) +{ + int i, error; - /* Verify the checksum */ - while (--sump >= (unsigned int *)m) - sum += *sump; - if (sum != 0) { - req->err = 1; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_ERR "microcode: CPU%d aborting, " - "bad checksum\n", cpu_num); - return; - } - - /* write microcode via MSR 0x79 */ - wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(m->bits), 0); + if (smp_call_function(collect_cpu_info, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + goto out; + } + collect_cpu_info(NULL); - /* serialize */ - __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); + if ((error = find_matching_ucodes())) { + printk(KERN_ERR "microcode: Error in the microcode data\n"); + goto out_free; + } - /* get the current revision from MSR 0x8B */ - rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); + if (smp_call_function(do_update_one, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + } + do_update_one(NULL); - /* notify the caller of success on this cpu */ - req->err = 0; - spin_unlock_irqrestore(µcode_update_lock, flags); - printk(KERN_INFO "microcode: CPU%d updated from revision " - "%d to %d, date=%08x\n", - cpu_num, rev, val[1], microcode[i].date); - return; +out_free: + for (i = 0; i < smp_num_cpus; i++) { + if (ucode_cpu_info[i].mc) { + int j; + void *tmp = ucode_cpu_info[i].mc; + vfree(tmp); + for (j = i; j < smp_num_cpus; j++) { + if (ucode_cpu_info[j].mc == tmp) + ucode_cpu_info[j].mc = NULL; + } } - - printk(KERN_ERR - "microcode: CPU%d no microcode found! (sig=%x, pflags=%d)\n", - cpu_num, sig, pf); -} - - -static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos) -{ - ssize_t ret = 0; - - down_read(µcode_rwsem); - if (*ppos >= mc_fsize) - goto out; - if (*ppos + len > mc_fsize) - len = mc_fsize - *ppos; - ret = -EFAULT; - if (copy_to_user(buf, mc_applied + *ppos, len)) - goto out; - *ppos += len; - ret = len; + } out: - up_read(µcode_rwsem); - return ret; + return error; } -static ssize_t microcode_write(struct file *file, const char *buf, size_t len, loff_t *ppos) +static ssize_t microcode_write (struct file *file, const char *buf, size_t len, loff_t *ppos) { ssize_t ret; - if (!len || len % sizeof(struct microcode) != 0) { - printk(KERN_ERR "microcode: can only write in N*%d bytes units\n", - sizeof(struct microcode)); + if (len < DEFAULT_UCODE_TOTALSIZE) { + printk(KERN_ERR "microcode: not enough data\n"); return -EINVAL; } + if ((len >> PAGE_SHIFT) > num_physpages) { printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); return -EINVAL; } - down_write(µcode_rwsem); - if (!mc_applied) { - mc_applied = kmalloc(smp_num_cpus*sizeof(struct microcode), - GFP_KERNEL); - if (!mc_applied) { - up_write(µcode_rwsem); - printk(KERN_ERR "microcode: out of memory for saved microcode\n"); - return -ENOMEM; - } - } - - microcode_num = len/sizeof(struct microcode); - microcode = vmalloc(len); - if (!microcode) { - ret = -ENOMEM; - goto out_unlock; - } - - if (copy_from_user(microcode, buf, len)) { - ret = -EFAULT; - goto out_fsize; - } - - if(do_microcode_update()) { - ret = -EIO; - goto out_fsize; - } else { - mc_fsize = smp_num_cpus * sizeof(struct microcode); + + down(µcode_sem); + + user_buffer = (void *) buf; + user_buffer_size = (int) len; + + ret = do_microcode_update(); + if (!ret) ret = (ssize_t)len; - } -out_fsize: - devfs_set_file_size(devfs_handle, mc_fsize); - vfree(microcode); -out_unlock: - up_write(µcode_rwsem); + + up(µcode_sem); + return ret; } -static int microcode_ioctl(struct inode *inode, struct file *file, +static int microcode_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - switch(cmd) { + switch (cmd) { + /* + * XXX: will be removed after microcode_ctl + * is updated to ignore failure of this ioctl() + */ case MICROCODE_IOCFREE: - down_write(µcode_rwsem); - if (mc_applied) { - int bytes = smp_num_cpus * sizeof(struct microcode); - - devfs_set_file_size(devfs_handle, 0); - kfree(mc_applied); - mc_applied = NULL; - printk(KERN_INFO "microcode: freed %d bytes\n", bytes); - mc_fsize = 0; - up_write(µcode_rwsem); - return 0; - } - up_write(µcode_rwsem); - return -ENODATA; - + return 0; default: - printk(KERN_ERR "microcode: unknown ioctl cmd=%d\n", cmd); return -EINVAL; } return -EINVAL; } + +static struct file_operations microcode_fops = { + .owner = THIS_MODULE, + .write = microcode_write, + .ioctl = microcode_ioctl, + .open = microcode_open, +}; + +static struct miscdevice microcode_dev = { + .minor = MICROCODE_MINOR, + .name = "microcode", + .fops = µcode_fops, +}; + +static int __init microcode_init (void) +{ + int error; + + error = misc_register(µcode_dev); + if (error) { + printk(KERN_ERR + "microcode: can't misc_register on minor=%d\n", + MICROCODE_MINOR); + return error; + } + + printk(KERN_INFO + "IA-32 Microcode Update Driver: v%s \n", + MICROCODE_VERSION); + return 0; +} + +static void __exit microcode_exit (void) +{ + misc_deregister(µcode_dev); + printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", + MICROCODE_VERSION); +} + +module_init(microcode_init) +module_exit(microcode_exit) diff -urN linux-2.4.24/arch/i386/kernel/mpparse.c linux-2.4.25/arch/i386/kernel/mpparse.c --- linux-2.4.24/arch/i386/kernel/mpparse.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/mpparse.c 2004-02-18 05:36:30.000000000 -0800 @@ -1280,8 +1280,14 @@ ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start; + /* + * MPS INTI flags: + * trigger: 0=default, 1=edge, 3=level + * polarity: 0=default, 1=high, 3=low + * Per ACPI spec, default for SCI means level/low. + */ io_apic_set_pci_routing(ioapic, ioapic_pin, irq, - (flags.trigger >> 1) , (flags.polarity >> 1)); + (flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1)); } diff -urN linux-2.4.24/arch/i386/kernel/process.c linux-2.4.25/arch/i386/kernel/process.c --- linux-2.4.24/arch/i386/kernel/process.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/process.c 2004-02-18 05:36:30.000000000 -0800 @@ -153,7 +153,6 @@ __setup("idle=", idle_setup); -static long no_idt[2]; static int reboot_mode; int reboot_thru_bios; @@ -224,7 +223,8 @@ unsigned long long * base __attribute__ ((packed)); } real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries }, -real_mode_idt = { 0x3ff, 0 }; +real_mode_idt = { 0x3ff, 0 }, +no_idt = { 0, 0 }; /* This is 16-bit protected mode code to disable paging and the cache, switch to real mode and jump to the BIOS reset code. @@ -476,23 +476,6 @@ } /* - * No need to lock the MM as we are the last user - */ -void release_segments(struct mm_struct *mm) -{ - void * ldt = mm->context.segments; - - /* - * free the LDT - */ - if (ldt) { - mm->context.segments = NULL; - clear_LDT(); - vfree(ldt); - } -} - -/* * Create a kernel thread */ int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -545,45 +528,19 @@ void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { - void * ldt = dead_task->mm->context.segments; - // temporary debugging check - if (ldt) { - printk("WARNING: dead process %8s still has LDT? <%p>\n", - dead_task->comm, ldt); + if (dead_task->mm->context.size) { + printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", + dead_task->comm, + dead_task->mm->context.ldt, + dead_task->mm->context.size); BUG(); } } - release_x86_irqs(dead_task); } /* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) -{ - struct mm_struct * old_mm; - void *old_ldt, *ldt; - - ldt = NULL; - old_mm = current->mm; - if (old_mm && (old_ldt = old_mm->context.segments) != NULL) { - /* - * Completely new LDT, we initialize it from the parent: - */ - ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!ldt) - printk(KERN_WARNING "ldt allocation failed\n"); - else - memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE); - } - new_mm->context.segments = ldt; - new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */ -} - -/* * Save a segment. */ #define savesegment(seg,value) \ diff -urN linux-2.4.24/arch/i386/kernel/setup.c linux-2.4.25/arch/i386/kernel/setup.c --- linux-2.4.24/arch/i386/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -211,6 +211,7 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) +#define DISK80_SIGNATURE_BUFFER (*(unsigned int*) (PARAM+DISK80_SIG_BUFFER)) #define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) #define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE ((char *) (PARAM+2048)) @@ -720,6 +721,7 @@ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) unsigned char eddnr; struct edd_info edd[EDDMAXNR]; +unsigned int edd_disk80_sig; /** * copy_edd() - Copy the BIOS EDD information * from empty_zero_page into a safe place. @@ -729,6 +731,7 @@ { eddnr = EDD_NR; memcpy(edd, EDD_BUF, sizeof(edd)); + edd_disk80_sig = DISK80_SIGNATURE_BUFFER; } #else static inline void copy_edd(void) {} @@ -3188,7 +3191,7 @@ set_tss_desc(nr,t); gdt_table[__TSS(nr)].b &= 0xfffffdff; load_TR(nr); - load_LDT(&init_mm); + load_LDT(&init_mm.context); /* * Clear all 6 debug registers: diff -urN linux-2.4.24/arch/i386/kernel/smpboot.c linux-2.4.25/arch/i386/kernel/smpboot.c --- linux-2.4.24/arch/i386/kernel/smpboot.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/smpboot.c 2004-02-18 05:36:30.000000000 -0800 @@ -1106,7 +1106,7 @@ */ Dprintk("CPU present map: %lx\n", phys_cpu_present_map); - for (bit = 0; bit < NR_CPUS; bit++) { + for (bit = 0; bit < BITS_PER_LONG; bit++) { apicid = cpu_present_to_apicid(bit); /* don't try to boot BAD_APICID */ diff -urN linux-2.4.24/arch/i386/kernel/time.c linux-2.4.25/arch/i386/kernel/time.c --- linux-2.4.24/arch/i386/kernel/time.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/i386/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -432,7 +432,6 @@ const int use_cyclone = 0; static void mark_timeoffset_cyclone(void) {} -static unsigned long do_gettimeoffset_cyclone(void) {return 0;} static void init_cyclone_clock(void) {} void __cyclone_delay(unsigned long loops) {} #endif /* CONFIG_X86_SUMMIT */ diff -urN linux-2.4.24/arch/i386/math-emu/fpu_system.h linux-2.4.25/arch/i386/math-emu/fpu_system.h --- linux-2.4.24/arch/i386/math-emu/fpu_system.h 2000-12-29 14:07:20.000000000 -0800 +++ linux-2.4.25/arch/i386/math-emu/fpu_system.h 2004-02-18 05:36:30.000000000 -0800 @@ -20,7 +20,7 @@ of the stack frame of math_emulate() */ #define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg -#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.segments)[(s) >> 3]) +#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) #define SEG_D_SIZE(x) ((x).b & (3 << 21)) #define SEG_G_BIT(x) ((x).b & (1 << 23)) #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) diff -urN linux-2.4.24/arch/i386/mm/fault.c linux-2.4.25/arch/i386/mm/fault.c --- linux-2.4.24/arch/i386/mm/fault.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/i386/mm/fault.c 2004-02-18 05:36:30.000000000 -0800 @@ -270,7 +270,8 @@ /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; info.si_signo = SIGSEGV; info.si_errno = 0; diff -urN linux-2.4.24/arch/ia64/config.in linux-2.4.25/arch/ia64/config.in --- linux-2.4.24/arch/ia64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -33,9 +33,9 @@ choice 'IA-64 system type' \ "generic CONFIG_IA64_GENERIC \ DIG-compliant CONFIG_IA64_DIG \ - HP-simulator CONFIG_IA64_HP_SIM \ - HP-zx1 CONFIG_IA64_HP_ZX1 \ - SGI-SN2 CONFIG_IA64_SGI_SN2" generic + HP CONFIG_IA64_HP_ZX1 \ + SGI-SN2 CONFIG_IA64_SGI_SN2 \ + Ski-simulator CONFIG_IA64_HP_SIM" generic if [ "$CONFIG_ITANIUM" = "y" ]; then choice 'Kernel page size' \ @@ -84,13 +84,37 @@ define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. +define_int CONFIG_FORCE_MAX_ZONEORDER 19 + +if [ "$CONFIG_HUGETLB_PAGE" = "y" ]; then + if [ "$CONFIG_MCKINLEY" = "y" ]; then + choice ' IA-64 Huge TLB Page Size' \ + "4GB CONFIG_HUGETLB_PAGE_SIZE_4GB \ + 1GB CONFIG_HUGETLB_PAGE_SIZE_1GB \ + 256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + else + choice ' IA-64 Huge TLB Page Size' \ + "256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + fi +fi + bool 'Use PAL_HALT_LIGHT in idle loop' CONFIG_IA64_PAL_IDLE bool 'SMP support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 fi -tristate 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT +bool 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT bool 'Performance monitor support' CONFIG_PERFMON tristate '/proc/pal support' CONFIG_IA64_PALINFO tristate '/proc/efi/vars support' CONFIG_EFI_VARS @@ -147,7 +171,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/ia64/configs/dig linux-2.4.25/arch/ia64/configs/dig --- linux-2.4.24/arch/ia64/configs/dig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/configs/dig 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ CONFIG_IA64_DIG=y # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -52,6 +50,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set # CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -113,6 +112,12 @@ # CONFIG_SYN_COOKIES 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 @@ -167,6 +172,7 @@ # 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 @@ -284,7 +290,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -339,6 +344,7 @@ # 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 @@ -366,7 +372,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -438,7 +443,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -584,6 +588,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -601,12 +606,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -615,6 +625,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -690,6 +701,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -844,6 +856,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -914,6 +928,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -949,6 +964,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -971,3 +991,4 @@ CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/configs/generic linux-2.4.25/arch/ia64/configs/generic --- linux-2.4.24/arch/ia64/configs/generic 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/configs/generic 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -52,6 +50,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set # CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -113,6 +112,12 @@ # CONFIG_SYN_COOKIES 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 @@ -167,6 +172,7 @@ # 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 @@ -275,6 +281,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -284,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -339,6 +345,7 @@ # 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 @@ -371,7 +378,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -443,7 +449,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -588,7 +593,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -606,12 +613,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -620,6 +632,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -695,6 +708,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -849,6 +863,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -919,6 +935,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -954,6 +971,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -994,3 +1016,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/configs/numa linux-2.4.25/arch/ia64/configs/numa --- linux-2.4.24/arch/ia64/configs/numa 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/configs/numa 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -44,7 +43,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -53,6 +51,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -115,6 +114,12 @@ # CONFIG_SYN_COOKIES 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 @@ -169,6 +174,7 @@ # 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 @@ -277,6 +283,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -286,7 +293,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -341,6 +347,7 @@ # 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 @@ -373,7 +380,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -445,7 +451,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -590,7 +595,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -608,12 +615,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -622,6 +634,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -697,6 +710,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -851,6 +865,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -921,6 +937,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -956,6 +973,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -996,3 +1018,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/configs/ski linux-2.4.25/arch/ia64/configs/ski --- linux-2.4.24/arch/ia64/configs/ski 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/configs/ski 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_SIM=y # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -40,7 +39,6 @@ CONFIG_IA64_L1_CACHE_SHIFT=6 CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -49,6 +47,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -80,6 +79,12 @@ # CONFIG_SYN_COOKIES 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 @@ -161,6 +166,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -252,6 +258,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -265,6 +272,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -337,6 +348,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -478,3 +490,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/configs/zx1 linux-2.4.25/arch/ia64/configs/zx1 --- linux-2.4.24/arch/ia64/configs/zx1 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/configs/zx1 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set CONFIG_IA64_HP_ZX1=y -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -42,7 +41,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_4GB is not set # CONFIG_HUGETLB_PAGE_SIZE_1GB is not set # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set @@ -53,6 +51,7 @@ # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_IA32_SUPPORT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y @@ -114,6 +113,12 @@ # CONFIG_SYN_COOKIES 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 @@ -168,6 +173,7 @@ # 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 @@ -285,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -340,6 +345,7 @@ # 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 @@ -367,7 +373,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -439,7 +444,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -585,6 +589,7 @@ # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -602,12 +607,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -616,6 +626,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -691,6 +702,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -845,6 +857,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -915,6 +929,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -950,6 +965,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -983,3 +1003,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/defconfig linux-2.4.25/arch/ia64/defconfig --- linux-2.4.24/arch/ia64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -30,7 +30,6 @@ # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,7 +42,6 @@ CONFIG_PM=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=19 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_HUGETLB_PAGE_SIZE_16MB=y @@ -114,6 +112,12 @@ # CONFIG_SYN_COOKIES 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 @@ -168,6 +172,7 @@ # 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 @@ -276,6 +281,7 @@ # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SGIIOC4 is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set @@ -285,7 +291,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -340,6 +345,7 @@ # 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 @@ -372,7 +378,6 @@ # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y -# CONFIG_SCSI_QLOGIC_QLA2100 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set @@ -444,7 +449,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -589,7 +593,9 @@ # # CONFIG_WATCHDOG is not set # CONFIG_SCx200_GPIO is not set +# CONFIG_FETCHOP is not set # CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -607,12 +613,17 @@ # CONFIG_AGP_I810 is not set # CONFIG_AGP_VIA is not set # CONFIG_AGP_AMD is not set -# CONFIG_AGP_AMD_8151 is not set +# CONFIG_AGP_AMD_K8 is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_ALI is not set # CONFIG_AGP_SWORKS is not set CONFIG_AGP_I460=y CONFIG_AGP_HP_ZX1=y +# CONFIG_AGP_ATI is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# CONFIG_DRM=y # CONFIG_DRM_OLD is not set @@ -621,6 +632,7 @@ # CONFIG_DRM_NEW=y # CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set @@ -696,6 +708,7 @@ # CONFIG_TMPFS is not set CONFIG_RAMFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set @@ -850,6 +863,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -920,6 +935,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set @@ -955,6 +971,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Cryptographic options # # CONFIG_CRYPTO is not set @@ -995,3 +1016,4 @@ # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ia64/hp/common/sba_iommu.c linux-2.4.25/arch/ia64/hp/common/sba_iommu.c --- linux-2.4.24/arch/ia64/hp/common/sba_iommu.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/hp/common/sba_iommu.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,9 +1,9 @@ /* ** IA64 System Bus Adapter (SBA) I/O MMU manager ** -** (c) Copyright 2002-2003 Alex Williamson +** (c) Copyright 2002-2004 Alex Williamson ** (c) Copyright 2002-2003 Grant Grundler -** (c) Copyright 2002-2003 Hewlett-Packard Company +** (c) Copyright 2002-2004 Hewlett-Packard Company ** ** Portions (c) 2000 Grant Grundler (from parisc I/O MMU code) ** Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code) @@ -38,11 +38,18 @@ #include #include /* PAGE_OFFSET */ #include /* wmb() */ +#include /* hweight64() */ #define PFX "IOC: " /* +** Enabling timing search of the pdir resource map. Output in /proc. +** Disabled by default to optimize performance. +*/ +#undef PDIR_SEARCH_TIMING + +/* ** This option allows cards capable of 64bit DMA to bypass the IOMMU. If ** not defined, all DMA will be 32bit and go through the TLB. */ @@ -121,7 +128,7 @@ #endif /* -** The number of pdir entries to "free" before issueing +** The number of pdir entries to "free" before issuing ** a read to PCOM register to flush out PCOM writes. ** Interacts with allocation granularity (ie 4 or 8 entries ** allocated and free'd/purged at a time might make this @@ -133,6 +140,7 @@ #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -148,21 +156,18 @@ #define ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL /* -** IOC supports 4/8/16/64KB page sizes (see TCNFG register) -** It's safer (avoid memory corruption) to keep DMA page mappings -** equivalently sized to VM PAGE_SIZE. +** The zx1 IOC supports 4/8/16/64KB page sizes (see TCNFG register) ** -** We really can't avoid generating a new mapping for each -** page since the Virtual Coherence Index has to be generated -** and updated for each page. +** Some IOCs (sx1000) can run at the above pages sizes, but are +** really only supported using the IOC at a 4k page size. ** -** IOVP_SIZE could only be greater than PAGE_SIZE if we are +** iovp_size could only be greater than PAGE_SIZE if we are ** confident the drivers really only touch the next physical ** page iff that driver instance owns it. */ -#define IOVP_SIZE PAGE_SIZE -#define IOVP_SHIFT PAGE_SHIFT -#define IOVP_MASK PAGE_MASK +static unsigned long iovp_size; +static unsigned long iovp_shift; +static unsigned long iovp_mask; struct ioc { void *ioc_hpa; /* I/O MMU base address */ @@ -186,30 +191,16 @@ } saved[DELAYED_RESOURCE_CNT]; #endif -#ifdef CONFIG_PROC_FS +#ifdef PDIR_SEARCH_TIMING #define SBA_SEARCH_SAMPLE 0x100 unsigned long avg_search[SBA_SEARCH_SAMPLE]; unsigned long avg_idx; /* current index into avg_search */ - unsigned long used_pages; - unsigned long msingle_calls; - unsigned long msingle_pages; - unsigned long msg_calls; - unsigned long msg_pages; - unsigned long usingle_calls; - unsigned long usingle_pages; - unsigned long usg_calls; - unsigned long usg_pages; -#ifdef ALLOW_IOV_BYPASS - unsigned long msingle_bypass; - unsigned long usingle_bypass; - unsigned long msg_bypass; -#endif #endif /* Stuff we don't need in performance path */ struct ioc *next; /* list of IOC's in system */ acpi_handle handle; /* for multiple IOC's */ - char *name; + const char *name; unsigned int func_id; unsigned int rev; /* HW revision of chip */ u32 iov_size; @@ -231,7 +222,11 @@ static u64 prefetch_spill_page; #endif -#define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) +#ifdef CONFIG_PCI +# define GET_IOC(dev) ((struct ioc *) PCI_CONTROLLER(dev)->iommu) +#else +# define GET_IOC(dev) NULL +#endif /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up @@ -240,7 +235,7 @@ ** rather than the HW. I/O MMU allocation alogorithms can be ** faster with smaller size is (to some degree). */ -#define DMA_CHUNK_SIZE (BITS_PER_LONG*PAGE_SIZE) +#define DMA_CHUNK_SIZE (BITS_PER_LONG*iovp_size) #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1)) @@ -404,18 +399,37 @@ #define PAGES_PER_RANGE 1 /* could increase this to 4 or 8 if needed */ /* Convert from IOVP to IOVA and vice versa. */ -#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | \ - ((hint_reg)<<(ioc->hint_shift_pdir))) -#define SBA_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase)) +#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset)) +#define SBA_IOVP(ioc,iova) ((iova) & ~(ioc->ibase)) -/* FIXME : review these macros to verify correctness and usage */ -#define PDIR_INDEX(iovp) ((iovp)>>IOVP_SHIFT) +#define PDIR_ENTRY_SIZE sizeof(u64) + +#define PDIR_INDEX(iovp) ((iovp)>>iovp_shift) #define RESMAP_MASK(n) ~(~0UL << (n)) #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) /** + * For most cases the normal get_order is sufficient, however it limits us + * to PAGE_SIZE being the minimum mapping alignment and TC flush granularity. + * It only incurs about 1 clock cycle to use this one with the static variable + * and makes the code more intuitive. + */ +static SBA_INLINE int +get_iovp_order (unsigned long size) +{ + long double d = size - 1; + long order; + + __asm__ ("getf.exp %0=%1" : "=r"(order) : "f"(d)); + order = order - iovp_shift - 0xffff + 1; + if (order < 0) + order = 0; + return order; +} + +/** * sba_search_bitmap - find free space in IO PDIR resource bitmap * @ioc: IO MMU structure which owns the pdir we are interested in. * @bits_wanted: number of entries we need. @@ -453,7 +467,7 @@ ** We need the alignment to invalidate I/O TLB using ** SBA HW features in the unmap path. */ - unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT); + unsigned long o = 1 << get_iovp_order(bits_wanted << iovp_shift); uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o); unsigned long mask; @@ -509,16 +523,15 @@ static int sba_alloc_range(struct ioc *ioc, size_t size) { - unsigned int pages_needed = size >> IOVP_SHIFT; -#ifdef CONFIG_PROC_FS + unsigned int pages_needed = size >> iovp_shift; +#ifdef PDIR_SEARCH_TIMING unsigned long itc_start = ia64_get_itc(); #endif unsigned long pide; ASSERT(pages_needed); - ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE); ASSERT(pages_needed <= BITS_PER_LONG); - ASSERT(0 == (size & ~IOVP_MASK)); + ASSERT(0 == (size & ~iovp_mask)); /* ** "seek and ye shall find"...praying never hurts either... @@ -534,7 +547,7 @@ #ifdef ASSERT_PDIR_SANITY /* verify the first enable bit is clear */ - if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) { + if(0x00 != ((u8 *) ioc->pdir_base)[pide*PDIR_ENTRY_SIZE + 7]) { sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide); } #endif @@ -544,17 +557,9 @@ (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map), ioc->res_bitshift ); -#ifdef CONFIG_PROC_FS - { - unsigned long itc_end = ia64_get_itc(); - unsigned long tmp = itc_end - itc_start; - /* check for roll over */ - itc_start = (itc_end < itc_start) ? -(tmp) : (tmp); - } - ioc->avg_search[ioc->avg_idx++] = itc_start; +#ifdef PDIR_SEARCH_TIMING + ioc->avg_search[ioc->avg_idx++] = ia64_get_itc() - itc_start; ioc->avg_idx &= SBA_SEARCH_SAMPLE - 1; - - ioc->used_pages += pages_needed; #endif return (pide); @@ -577,7 +582,7 @@ unsigned int ridx = pide >> 3; /* convert bit to byte address */ unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]); - int bits_not_wanted = size >> IOVP_SHIFT; + int bits_not_wanted = size >> iovp_shift; /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */ unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1)); @@ -586,13 +591,9 @@ __FUNCTION__, (uint) iova, size, bits_not_wanted, m, pide, res_ptr, *res_ptr); -#ifdef CONFIG_PROC_FS - ioc->used_pages -= bits_not_wanted; -#endif - ASSERT(m != 0); ASSERT(bits_not_wanted); - ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE); + ASSERT((bits_not_wanted * iovp_size) <= DMA_CHUNK_SIZE); ASSERT(bits_not_wanted <= BITS_PER_LONG); ASSERT((*res_ptr & m) == m); /* verify same bits are set */ *res_ptr &= ~m; @@ -690,7 +691,7 @@ /* Must be non-zero and rounded up */ ASSERT(byte_cnt > 0); - ASSERT(0 == (byte_cnt & ~IOVP_MASK)); + ASSERT(0 == (byte_cnt & ~iovp_mask)); #ifdef ASSERT_PDIR_SANITY /* Assert first pdir entry is set */ @@ -699,11 +700,11 @@ } #endif - if (byte_cnt <= IOVP_SIZE) + if (byte_cnt <= iovp_size) { ASSERT(off < ioc->pdir_size); - iovp |= IOVP_SHIFT; /* set "size" field for PCOM */ + iovp |= iovp_shift; /* set "size" field for PCOM */ #ifndef FULL_VALID_PDIR /* @@ -722,7 +723,7 @@ ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page); #endif } else { - u32 t = get_order(byte_cnt) + PAGE_SHIFT; + u32 t = get_iovp_order(byte_cnt) + iovp_shift; iovp |= t; ASSERT(t <= 31); /* 2GB! Max value of "size" field */ @@ -737,7 +738,7 @@ ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page); #endif off++; - byte_cnt -= IOVP_SIZE; + byte_cnt -= iovp_size; } while (byte_cnt > 0); } @@ -749,12 +750,12 @@ * @dev: instance of PCI owned by the driver that's asking. * @addr: driver buffer to map. * @size: number of bytes to map in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ dma_addr_t -sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction) +sba_map_single(struct pci_dev *dev, void *addr, size_t size, int dir) { struct ioc *ioc; unsigned long flags; @@ -778,11 +779,6 @@ ** Device is bit capable of DMA'ing to the buffer... ** just return the PCI address of ptr */ -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->msingle_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif DBG_BYPASS("sba_map_single() bypass mask/addr: 0x%lx/0x%lx\n", dev->dma_mask, pci_addr); return pci_addr; @@ -793,10 +789,10 @@ ASSERT(size <= DMA_CHUNK_SIZE); /* save offset bits */ - offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK; + offset = ((dma_addr_t) (long) addr) & ~iovp_mask; - /* round up to nearest IOVP_SIZE */ - size = (size + offset + ~IOVP_MASK) & IOVP_MASK; + /* round up to nearest iovp_size */ + size = (size + offset + ~iovp_mask) & iovp_mask; spin_lock_irqsave(&ioc->res_lock, flags); #ifdef ASSERT_PDIR_SANITY @@ -804,12 +800,8 @@ panic("Sanity check failed"); #endif -#ifdef CONFIG_PROC_FS - ioc->msingle_calls++; - ioc->msingle_pages += size >> IOVP_SHIFT; -#endif pide = sba_alloc_range(ioc, size); - iovp = (dma_addr_t) pide << IOVP_SHIFT; + iovp = (dma_addr_t) pide << iovp_shift; DBG_RUN("%s() 0x%p -> 0x%lx\n", __FUNCTION__, addr, (long) iovp | offset); @@ -822,8 +814,8 @@ DBG_RUN(" pdir 0x%p %lx\n", pdir_start, *pdir_start); - addr += IOVP_SIZE; - size -= IOVP_SIZE; + addr += iovp_size; + size -= iovp_size; pdir_start++; } /* force pdir update */ @@ -842,12 +834,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @iova: IOVA of driver buffer previously mapped. * @size: number of bytes mapped in driver buffer. - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, - int direction) +void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int dir) { struct ioc *ioc; #if DELAYED_RESOURCE_CNT > 0 @@ -864,35 +855,26 @@ /* ** Address does not fall w/in IOVA, must be bypassing */ -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->usingle_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova); #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { mark_clean(phys_to_virt(iova), size); } #endif return; } #endif - offset = iova & ~IOVP_MASK; + offset = iova & ~iovp_mask; DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size); iova ^= offset; /* clear offset bits */ size += offset; - size = ROUNDUP(size, IOVP_SIZE); + size = ROUNDUP(size, iovp_size); spin_lock_irqsave(&ioc->res_lock, flags); -#ifdef CONFIG_PROC_FS - ioc->usingle_calls++; - ioc->usingle_pages += size >> IOVP_SHIFT; -#endif #if DELAYED_RESOURCE_CNT > 0 d = &(ioc->saved[ioc->saved_cnt]); @@ -914,12 +896,12 @@ READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ #endif /* DELAYED_RESOURCE_CNT == 0 */ #ifdef ENABLE_MARK_CLEAN - if (direction == PCI_DMA_FROMDEVICE) { + if (dir == PCI_DMA_FROMDEVICE) { u32 iovp = (u32) SBA_IOVP(ioc,iova); int off = PDIR_INDEX(iovp); void *addr; - if (size <= IOVP_SIZE) { + if (size <= iovp_size) { addr = phys_to_virt(ioc->pdir_base[off] & ~0xE000000000000FFFULL); mark_clean(addr, size); @@ -929,9 +911,9 @@ do { addr = phys_to_virt(ioc->pdir_base[off] & ~0xE000000000000FFFULL); - mark_clean(addr, min(byte_cnt, IOVP_SIZE)); + mark_clean(addr, min(byte_cnt, iovp_size)); off++; - byte_cnt -= IOVP_SIZE; + byte_cnt -= iovp_size; } while (byte_cnt > 0); } @@ -951,55 +933,51 @@ /** - * sba_alloc_consistent - allocate/map shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_alloc_coherent - allocate/map shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * * See Documentation/DMA-mapping.txt */ void * -sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +sba_alloc_coherent (struct pci_dev *dev, size_t size, dma_addr_t *dma_handle) { struct ioc *ioc; - void *ret; + void *addr; - if (!hwdev) { - /* only support PCI */ - *dma_handle = 0; - return 0; - } + if (!dev) + return NULL; /* only support PCI */ - ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + addr = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + if (!addr) + return NULL; - if (ret) { - memset(ret, 0, size); - /* - * REVISIT: if sba_map_single starts needing more - * than dma_mask from the device, this needs to be - * updated. - */ - ioc = GET_IOC(hwdev); - *dma_handle = sba_map_single(ioc->sac_only_dev, ret, size, 0); - } + /* + * REVISIT: if sba_map_single starts needing more than dma_mask from the + * device, this needs to be updated. + */ + ioc = GET_IOC(dev); + ASSERT(ioc); + *dma_handle = sba_map_single(ioc->sac_only_dev, addr, size, 0); - return ret; + memset(addr, 0, size); + return addr; } /** - * sba_free_consistent - free/unmap shared mem for DMA - * @hwdev: instance of PCI owned by the driver that's asking. + * sba_free_coherent - free/unmap shared mem for DMA + * @dev: instance of PCI owned by the driver that's asking. * @size: number of bytes mapped in driver buffer. * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * * See Documentation/DMA-mapping.txt */ -void sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle) +void sba_free_coherent (struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - sba_unmap_single(hwdev, dma_handle, size, 0); + sba_unmap_single(dev, dma_handle, size, 0); free_pages((unsigned long) vaddr, get_order(size)); } @@ -1057,11 +1035,11 @@ */ if (startsg->dma_address & PIDE_FLAG) { u32 pide = startsg->dma_address & ~PIDE_FLAG; - dma_offset = (unsigned long) pide & ~IOVP_MASK; + dma_offset = (unsigned long) pide & ~iovp_mask; startsg->dma_address = 0; dma_sg++; dma_sg->dma_address = pide | ioc->ibase; - pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]); + pdirp = &(ioc->pdir_base[pide >> iovp_shift]); n_mappings++; } @@ -1078,14 +1056,11 @@ dma_sg->dma_length += cnt; cnt += dma_offset; dma_offset=0; /* only want offset on first chunk */ - cnt = ROUNDUP(cnt, IOVP_SIZE); -#ifdef CONFIG_PROC_FS - ioc->msg_pages += cnt >> IOVP_SHIFT; -#endif + cnt = ROUNDUP(cnt, iovp_size); do { sba_io_pdir_entry(pdirp, vaddr); - vaddr += IOVP_SIZE; - cnt -= IOVP_SIZE; + vaddr += iovp_size; + cnt -= iovp_size; pdirp++; } while (cnt > 0); } @@ -1103,12 +1078,12 @@ /* ** Two address ranges are DMA contiguous *iff* "end of prev" and -** "start of next" are both on a page boundry. +** "start of next" are both on an IOV page boundary. ** ** (shift left is a quick trick to mask off upper bits) */ #define DMA_CONTIG(__X, __Y) \ - (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL) + (((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - iovp_shift)) == 0UL) /** @@ -1121,7 +1096,7 @@ * in the DMA stream. Allocates PDIR entries but does not fill them. * Returns the number of DMA chunks. * - * Doing the fill seperate from the coalescing/allocation keeps the + * Doing the fill separate from the coalescing/allocation keeps the * code simpler. Future enhancement could make one pass through * the sglist do both. */ @@ -1146,7 +1121,7 @@ dma_sg = vcontig_sg = startsg; dma_len = vcontig_len = vcontig_end = startsg->length; vcontig_end += vaddr; - dma_offset = vaddr & ~IOVP_MASK; + dma_offset = vaddr & ~iovp_mask; /* PARANOID: clear entries */ startsg->dma_address = startsg->dma_length = 0; @@ -1171,7 +1146,7 @@ ** exceed DMA_CHUNK_SIZE if we coalesce the ** next entry. */ - if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) + if (((dma_len + dma_offset + startsg->length + ~iovp_mask) & iovp_mask) > DMA_CHUNK_SIZE) break; @@ -1190,7 +1165,7 @@ } #ifdef DEBUG_LARGE_SG_ENTRIES - dump_run_sg = (vcontig_len > IOVP_SIZE); + dump_run_sg = (vcontig_len > iovp_size); #endif /* @@ -1229,10 +1204,10 @@ ** Allocate space for DMA stream. */ vcontig_sg->dma_length = vcontig_len; - dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK; + dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask; ASSERT(dma_len <= DMA_CHUNK_SIZE); dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG - | (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT) + | (sba_alloc_range(ioc, dma_len) << iovp_shift) | dma_offset); n_mappings++; } @@ -1246,11 +1221,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction) +int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int dir) { struct ioc *ioc; int coalesced, filled = 0; @@ -1269,26 +1244,14 @@ sg->dma_length = sg->length; sg->dma_address = virt_to_phys(sba_sg_address(sg)); } -#ifdef CONFIG_PROC_FS - spin_lock_irqsave(&ioc->res_lock, flags); - ioc->msg_bypass++; - spin_unlock_irqrestore(&ioc->res_lock, flags); -#endif return filled; } #endif /* Fast path single entry scatterlists. */ if (nents == 1) { sglist->dma_length = sglist->length; - sglist->dma_address = sba_map_single(dev, - sba_sg_address(sglist), - sglist->length, direction); -#ifdef CONFIG_PROC_FS - /* - ** Should probably do some stats counting, but trying to - ** be precise quickly starts wasting CPU time. - */ -#endif + sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length, + dir); return 1; } @@ -1302,10 +1265,6 @@ } #endif -#ifdef CONFIG_PROC_FS - ioc->msg_calls++; -#endif - /* ** First coalesce the chunks and allocate I/O pdir space ** @@ -1348,12 +1307,11 @@ * @dev: instance of PCI owned by the driver that's asking. * @sglist: array of buffer/length pairs * @nents: number of entries in list - * @direction: R/W or both. + * @dir: R/W or both. * * See Documentation/DMA-mapping.txt */ -void sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, - int direction) +void sba_unmap_sg (struct pci_dev *dev, struct scatterlist *sglist, int nents, int dir) { struct ioc *ioc; #ifdef ASSERT_PDIR_SANITY @@ -1366,10 +1324,6 @@ ioc = GET_IOC(dev); ASSERT(ioc); -#ifdef CONFIG_PROC_FS - ioc->usg_calls++; -#endif - #ifdef ASSERT_PDIR_SANITY spin_lock_irqsave(&ioc->res_lock, flags); sba_check_pdir(ioc,"Check before sba_unmap_sg()"); @@ -1378,18 +1332,7 @@ while (nents && sglist->dma_length) { - sba_unmap_single(dev, sglist->dma_address, - sglist->dma_length, direction); -#ifdef CONFIG_PROC_FS - /* - ** This leaves inconsistent data in the stats, but we can't - ** tell which sg lists were mapped by map_single and which - ** were coalesced to a single entry. The stats are fun, - ** but speed is more important. - */ - ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length - + IOVP_SIZE - 1) >> PAGE_SHIFT; -#endif + sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); sglist++; nents--; } @@ -1413,10 +1356,9 @@ static void __init ioc_iova_init(struct ioc *ioc) { - u32 iova_space_mask; - int iov_order, tcnfg; + int tcnfg; int agp_found = 0; - struct pci_dev *device; + struct pci_dev *device = NULL; #ifdef FULL_VALID_PDIR unsigned long index; #endif @@ -1427,23 +1369,27 @@ ** IBASE and IMASK registers. */ ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL; - ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1; + ioc->imask = READ_REG(ioc->ioc_hpa + IOC_IMASK) | 0xFFFFFFFF00000000UL; - /* - ** iov_order is always based on a 1GB IOVA space since we want to - ** turn on the other half for AGP GART. - */ - iov_order = get_order(ioc->iov_size >> (IOVP_SHIFT - PAGE_SHIFT)); - ioc->pdir_size = (ioc->iov_size / IOVP_SIZE) * sizeof(u64); + ioc->iov_size = ~ioc->imask + 1; - DBG_INIT("%s() hpa %p IOV %dMB (%d bits) PDIR size 0x%x\n", - __FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20, - iov_order + PAGE_SHIFT, ioc->pdir_size); - - /* FIXME : DMA HINTs not used */ - ioc->hint_shift_pdir = iov_order + PAGE_SHIFT; - ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT)); + DBG_INIT("%s() hpa %p IOV base 0x%lx mask 0x%lx (%dMB)\n", + __FUNCTION__, ioc->ioc_hpa, ioc->ibase, ioc->imask, + ioc->iov_size >> 20); + + switch (iovp_size) { + case 4*1024: tcnfg = 0; break; + case 8*1024: tcnfg = 1; break; + case 16*1024: tcnfg = 2; break; + case 64*1024: tcnfg = 3; break; + default: + panic(PFX "Unsupported IOTLB page size %ldK", + iovp_size >> 10); + break; + } + WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG); + ioc->pdir_size = (ioc->iov_size / iovp_size) * PDIR_ENTRY_SIZE; ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(ioc->pdir_size)); if (!ioc->pdir_base) @@ -1451,61 +1397,12 @@ memset(ioc->pdir_base, 0, ioc->pdir_size); - DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n", - __FUNCTION__, ioc->pdir_base, ioc->pdir_size, - ioc->hint_shift_pdir, ioc->hint_mask_pdir); + DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __FUNCTION__, + iovp_size >> 10, ioc->pdir_base, ioc->pdir_size); - ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base); + ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base); WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE); - DBG_INIT(" base %p\n", ioc->pdir_base); - - /* build IMASK for IOC and Elroy */ - iova_space_mask = 0xffffffff; - iova_space_mask <<= (iov_order + PAGE_SHIFT); - ioc->imask = iova_space_mask; - - DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", - __FUNCTION__, ioc->ibase, ioc->imask); - - /* - ** FIXME: Hint registers are programmed with default hint - ** values during boot, so hints should be sane even if we - ** can't reprogram them the way drivers want. - */ - WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK); - - /* - ** Setting the upper bits makes checking for bypass addresses - ** a little faster later on. - */ - ioc->imask |= 0xFFFFFFFF00000000UL; - - /* Set I/O PDIR Page size to system page size */ - switch (PAGE_SHIFT) { - case 12: tcnfg = 0; break; /* 4K */ - case 13: tcnfg = 1; break; /* 8K */ - case 14: tcnfg = 2; break; /* 16K */ - case 16: tcnfg = 3; break; /* 64K */ - default: - panic(PFX "Unsupported system page size %d", - 1 << PAGE_SHIFT); - break; - } - WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG); - - /* - ** Program the IOC's ibase and enable IOVA translation - ** Bit zero == enable bit. - */ - WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE); - - /* - ** Clear I/O TLB of any possible entries. - ** (Yes. This is a bit paranoid...but so what) - */ - WRITE_REG(ioc->ibase | (iov_order+PAGE_SHIFT), ioc->ioc_hpa + IOC_PCOM); - /* ** If an AGP device is present, only use half of the IOV space ** for PCI DMA. Unfortunately we can't know ahead of time @@ -1514,12 +1411,12 @@ ** We program the next pdir index after we stop w/ a key for ** the GART code to handshake on. */ - pci_for_each_dev(device) + while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP); if (agp_found && reserve_sba_gart) { - DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", - __FUNCTION__); + printk(KERN_INFO PFX "reserving %dMb of IOVA space at 0x%lx for agpgart\n", + ioc->iov_size/2 >> 20, ioc->ibase + ioc->iov_size/2); ioc->pdir_size /= 2; ((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE; } @@ -1533,12 +1430,12 @@ int poison_size = 16; void *poison_addr, *addr; - addr = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE)); + addr = (void *)__get_free_pages(GFP_KERNEL, get_order(iovp_size)); if (!addr) panic(PFX "Couldn't allocate PDIR spill page\n"); poison_addr = addr; - for ( ; (u64) poison_addr < addr + IOVP_SIZE; poison_addr += poison_size) + for ( ; (u64) poison_addr < addr + iovp_size; poison_addr += poison_size) memcpy(poison_addr, spill_poison, poison_size); prefetch_spill_page = virt_to_phys(addr); @@ -1548,10 +1445,17 @@ /* ** Set all the PDIR entries valid w/ the spill page as the target */ - for (index = 0 ; index < (ioc->pdir_size / sizeof(u64)) ; index++) + for (index = 0 ; index < (ioc->pdir_size / PDIR_ENTRY_SIZE) ; index++) ((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page); #endif + /* Clear I/O TLB of any possible entries */ + WRITE_REG(ioc->ibase | (get_iovp_order(ioc->iov_size) + iovp_shift), ioc->ioc_hpa + IOC_PCOM); + READ_REG(ioc->ioc_hpa + IOC_PCOM); + + /* Enable IOVA translation */ + WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE); + READ_REG(ioc->ioc_hpa + IOC_IBASE); } static void __init @@ -1560,7 +1464,7 @@ spin_lock_init(&ioc->res_lock); /* resource map size dictated by pdir_size */ - ioc->res_size = ioc->pdir_size / sizeof(u64); /* entries */ + ioc->res_size = ioc->pdir_size / PDIR_ENTRY_SIZE; /* entries */ ioc->res_size >>= 3; /* convert bit count to byte count */ DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size); @@ -1581,7 +1485,7 @@ #ifdef FULL_VALID_PDIR /* Mark the last resource used so we don't prefetch beyond IOVA space */ ioc->res_map[ioc->res_size - 1] |= 0x80UL; /* res_map is chars */ - ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FF + ioc->pdir_base[(ioc->pdir_size / PDIR_ENTRY_SIZE) - 1] = (0x80000000000000FF | prefetch_spill_page); #endif @@ -1596,7 +1500,7 @@ struct pci_controller *controller = NULL; /* - * pci_alloc_consistent() must return a DMA address which is + * pci_alloc_coherent() must return a DMA address which is * SAC (single address cycle) addressable, so allocate a * pseudo-device to enforce that. */ @@ -1623,6 +1527,23 @@ panic(PFX "IOC 2.0 or later required for IOMMU support\n"); ioc->dma_mask = 0xFFFFFFFFFFUL; + + if (!iovp_shift) { + /* 64k is max iommu page size */ + iovp_shift = min(PAGE_SHIFT, 16); + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } +} + +static void __init +ioc_sx1000_init(struct ioc *ioc) +{ + if (!iovp_shift) { + iovp_shift = 12; /* 4K for now */ + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } } typedef void (initfunc)(struct ioc *); @@ -1635,7 +1556,8 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, - { REO_IOC_ID, "REO" }, + { REO_IOC_ID, "REO", ioc_sx1000_init }, + { SX1000_IOC_ID, "sx1000", ioc_sx1000_init }, }; static struct ioc * __init @@ -1660,6 +1582,11 @@ ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL; ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL; /* conservative */ + if (iovp_shift) { + iovp_size = (1 << iovp_shift); + iovp_mask = ~(iovp_size - 1); + } + for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) { if (ioc->func_id == info->func_id) { ioc->name = info->name; @@ -1667,13 +1594,14 @@ (info->init)(ioc); } } + DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __FUNCTION__, + PAGE_SIZE >> 10, iovp_size >> 10); if (!ioc->name) { ioc->name = kmalloc(24, GFP_KERNEL); if (ioc->name) - sprintf(ioc->name, "Unknown (%04x:%04x)", - ioc->func_id & 0xFFFF, - (ioc->func_id >> 16) & 0xFFFF); + sprintf((char *) ioc->name, "Unknown (%04x:%04x)", + ioc->func_id & 0xFFFF, (ioc->func_id >> 16) & 0xFFFF); else ioc->name = "Unknown"; } @@ -1733,57 +1661,37 @@ ioc_show(struct seq_file *s, void *v) { struct ioc *ioc = v; - int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ - unsigned long i = 0, avg = 0, min, max; + unsigned long *res_ptr = (unsigned long *)ioc->res_map; + int i, used = 0; seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n", ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF)); - seq_printf(s, "IO PDIR size : %d bytes (%d entries)\n", - (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ - total_pages); - - seq_printf(s, "IO PDIR entries : %ld free %ld used (%d%%)\n", - total_pages - ioc->used_pages, ioc->used_pages, - (int) (ioc->used_pages * 100 / total_pages)); - - seq_printf(s, "Resource bitmap : %d bytes (%d pages)\n", - ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ - - min = max = ioc->avg_search[0]; - for (i = 0; i < SBA_SEARCH_SAMPLE; i++) { - avg += ioc->avg_search[i]; - if (ioc->avg_search[i] > max) max = ioc->avg_search[i]; - if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; - } - avg /= SBA_SEARCH_SAMPLE; - seq_printf(s, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", - min, avg, max); - - seq_printf(s, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", - ioc->msingle_calls, ioc->msingle_pages, - (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); -#ifdef ALLOW_IOV_BYPASS - seq_printf(s, "pci_map_single(): %12ld bypasses\n", ioc->msingle_bypass); -#endif - - seq_printf(s, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", - ioc->usingle_calls, ioc->usingle_pages, - (int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls)); -#ifdef ALLOW_IOV_BYPASS - seq_printf(s, "pci_unmap_single: %12ld bypasses\n", ioc->usingle_bypass); -#endif + seq_printf(s, "IOVA size : %d MB\n", ioc->iov_size/(1024*1024)); + seq_printf(s, "IOVA page size : %ld kb\n", iovp_size/1024); - seq_printf(s, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - ioc->msg_calls, ioc->msg_pages, - (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); -#ifdef ALLOW_IOV_BYPASS - seq_printf(s, "pci_map_sg() : %12ld bypasses\n", ioc->msg_bypass); -#endif + for (i = 0; i < (ioc->res_size / sizeof(unsigned long)); ++i, ++res_ptr) + used += hweight64(*res_ptr); - seq_printf(s, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - ioc->usg_calls, ioc->usg_pages, - (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); + seq_printf(s, "PDIR size : %d entries\n", ioc->res_size << 3); + seq_printf(s, "PDIR used : %d entries\n", used); +#ifdef PDIR_SEARCH_TIMING + { + unsigned long i = 0, avg = 0, min, max; + min = max = ioc->avg_search[0]; + for (i = 0; i < SBA_SEARCH_SAMPLE; i++) { + avg += ioc->avg_search[i]; + if (ioc->avg_search[i] > max) max = ioc->avg_search[i]; + if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; + } + avg /= SBA_SEARCH_SAMPLE; + seq_printf(s, "Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", + min, avg, max); + } +#endif +#ifndef ALLOW_IOV_BYPASS + seq_printf(s, "IOVA bypass disabled\n"); +#endif return 0; } @@ -1807,66 +1715,35 @@ .release = seq_release }; -static int -ioc_map_show(struct seq_file *s, void *v) -{ - struct ioc *ioc = v; - unsigned int *res_ptr = (unsigned int *)ioc->res_map; - int i; - - for (i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) - seq_printf(s, "%s%08x", (i & 7) ? " " : "\n ", *res_ptr); - seq_printf(s, "\n"); - - return 0; -} - -static struct seq_operations ioc_map_ops = { - .start = ioc_start, - .next = ioc_next, - .stop = ioc_stop, - .show = ioc_map_show -}; - -static int -ioc_map_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &ioc_map_ops); -} - -static struct file_operations ioc_map_fops = { - .open = ioc_map_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release -}; - static void __init ioc_proc_init(void) { - if (ioc_list) { - struct proc_dir_entry *dir, *entry; + struct proc_dir_entry *dir, *entry; - dir = proc_mkdir("bus/mckinley", 0); - entry = create_proc_entry(ioc_list->name, 0, dir); - if (entry) - entry->proc_fops = &ioc_fops; + dir = proc_mkdir("bus/mckinley", 0); + if (!dir) + return; - entry = create_proc_entry("bitmap", 0, dir); - if (entry) - entry->proc_fops = &ioc_map_fops; - } + entry = create_proc_entry(ioc_list->name, 0, dir); + if (entry) + entry->proc_fops = &ioc_fops; } #endif -void -sba_enable_device(struct pci_dev *dev) +static void +sba_connect_bus(struct pci_bus *bus) { acpi_handle handle, parent; acpi_status status; struct ioc *ioc; - handle = PCI_CONTROLLER(dev)->acpi_handle; + if (!PCI_CONTROLLER(bus)) + panic(PFX "no sysdata on bus %d!\n", bus->number); + + if (PCI_CONTROLLER(bus)->iommu) + return; + + handle = PCI_CONTROLLER(bus)->acpi_handle; if (!handle) return; @@ -1878,7 +1755,7 @@ do { for (ioc = ioc_list; ioc; ioc = ioc->next) if (ioc->handle == handle) { - PCI_CONTROLLER(dev)->iommu = ioc; + PCI_CONTROLLER(bus)->iommu = ioc; return; } @@ -1886,9 +1763,11 @@ handle = parent; } while (ACPI_SUCCESS(status)); - printk(KERN_WARNING "No IOC for %s in ACPI\n", dev->slot_name); + printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", PCI_SEGMENT(bus), bus->number); } +extern acpi_status acpi_hp_csr_space (acpi_handle obj, u64 *csr_base, u64 *csr_length); + static int __init acpi_sba_ioc_add(struct acpi_device *device) { @@ -1924,17 +1803,27 @@ } static struct acpi_driver acpi_sba_ioc_driver = { - name: "IOC IOMMU Driver", - ids: "HWP0001,HWP0004", - ops: { - add: acpi_sba_ioc_add, - }, + .name = "IOC IOMMU Driver", + .ids = "HWP0001,HWP0004", + .ops = { + .add = acpi_sba_ioc_add, + }, }; void __init sba_init(void) { acpi_bus_register_driver(&acpi_sba_ioc_driver); + if (!ioc_list) + return; + +#ifdef CONFIG_PCI + { + struct pci_bus *b = NULL; + pci_for_each_bus(b) + sba_connect_bus(b); + } +#endif #ifdef CONFIG_PROC_FS ioc_proc_init(); @@ -1957,11 +1846,34 @@ __setup("nosbagart", nosbagart); +static int __init +sba_page_override(char *str) +{ + unsigned long page_size; + + page_size = memparse(str, &str); + switch (page_size) { + case 4096: + case 8192: + case 16384: + case 65536: + iovp_shift = ffs(page_size) - 1; + break; + default: + printk("%s: unknown/unsupported iommu page size %ld\n", + __FUNCTION__, page_size); + } + + return 1; +} + +__setup("sbapagesize=",sba_page_override); + EXPORT_SYMBOL(sba_init); EXPORT_SYMBOL(sba_map_single); EXPORT_SYMBOL(sba_unmap_single); EXPORT_SYMBOL(sba_map_sg); EXPORT_SYMBOL(sba_unmap_sg); EXPORT_SYMBOL(sba_dma_supported); -EXPORT_SYMBOL(sba_alloc_consistent); -EXPORT_SYMBOL(sba_free_consistent); +EXPORT_SYMBOL(sba_alloc_coherent); +EXPORT_SYMBOL(sba_free_coherent); diff -urN linux-2.4.24/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.25/arch/ia64/hp/zx1/hpzx1_machvec.c --- linux-2.4.24/arch/ia64/hp/zx1/hpzx1_machvec.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/hp/zx1/hpzx1_machvec.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,3 +1,3 @@ -#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_NAME hp #define MACHVEC_PLATFORM_HEADER #include diff -urN linux-2.4.24/arch/ia64/hp/zx1/hpzx1_misc.c linux-2.4.25/arch/ia64/hp/zx1/hpzx1_misc.c --- linux-2.4.24/arch/ia64/hp/zx1/hpzx1_misc.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/hp/zx1/hpzx1_misc.c 2004-02-18 05:36:30.000000000 -0800 @@ -17,7 +17,7 @@ #include #include -#define PFX "hpzx1: " +#define PFX static int hpzx1_devices; @@ -50,7 +50,14 @@ fake_dev->sizing = 0; \ return PCIBIOS_SUCCESSFUL; \ } \ - *value = read##sz(fake_dev->mapped_csrs + where); \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + *value = 0; \ + break; \ + default: \ + *value = read##sz(fake_dev->mapped_csrs + where); \ + } \ if (where == PCI_COMMAND) \ *value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \ return PCIBIOS_SUCCESSFUL; \ @@ -68,8 +75,14 @@ if (value == (u##bits) ~0) \ fake_dev->sizing = 1; \ return PCIBIOS_SUCCESSFUL; \ - } else \ - write##sz(value, fake_dev->mapped_csrs + where); \ + } \ + switch (where & ~0x7) { \ + case 0x48: /* initiates config cycles */ \ + case 0x78: /* elroy suspend mode register */ \ + break; \ + default: \ + write##sz(value, fake_dev->mapped_csrs + where); \ + } \ return PCIBIOS_SUCCESSFUL; \ } diff -urN linux-2.4.24/arch/ia64/ia32/ia32_entry.S linux-2.4.25/arch/ia64/ia32/ia32_entry.S --- linux-2.4.24/arch/ia64/ia32/ia32_entry.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/ia32/ia32_entry.S 2004-02-18 05:36:30.000000000 -0800 @@ -138,6 +138,19 @@ ;; st8 [r2]=r3 // initialize return code to -ENOSYS br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args + // Need to reload arguments (they may be changed by the tracing process) + adds r2=IA64_PT_REGS_R9_OFFSET+16,sp // r2 = &pt_regs.r9 + adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 + ;; + ld4 r33=[r2],8 // r9 == ecx + ld4 r37=[r3],16 // r13 == ebp + ;; + ld4 r34=[r2],8 // r10 == edx + ld4 r36=[r3],8 // r15 == edi + ;; + ld4 r32=[r2],8 // r11 == ebx + ld4 r35=[r3],8 // r14 == esi + ;; .ret2: br.call.sptk.few rp=b6 // do the syscall .ia32_strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? diff -urN linux-2.4.24/arch/ia64/ia32/sys_ia32.c linux-2.4.25/arch/ia64/ia32/sys_ia32.c --- linux-2.4.24/arch/ia64/ia32/sys_ia32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/ia32/sys_ia32.c 2004-02-18 05:36:30.000000000 -0800 @@ -74,6 +74,7 @@ #define OFFSET4K(a) ((a) & 0xfff) #define PAGE_START(addr) ((addr) & PAGE_MASK) #define PAGE_OFF(addr) ((addr) & ~PAGE_MASK) +#define MINSIGSTKSZ_IA32 2048 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *); extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long); @@ -201,13 +202,18 @@ asmlinkage long sys32_newstat (char *filename, struct stat32 *statbuf) { + char *name; int ret; struct stat s; mm_segment_t old_fs = get_fs(); + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -218,13 +224,18 @@ asmlinkage long sys32_newlstat (char *filename, struct stat32 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; int ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat(statbuf, &s)) return -EFAULT; return ret; @@ -698,13 +709,18 @@ asmlinkage long sys32_statfs (const char *path, struct statfs32 *buf) { + const char *name; int ret; struct statfs s; mm_segment_t old_fs = get_fs(); + name = getname(path); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_statfs(path, &s); + ret = sys_statfs(name, &s); set_fs(old_fs); + putname(name); if (put_statfs(buf, &s)) return -EFAULT; return ret; @@ -3388,10 +3404,18 @@ return -EFAULT; uss.ss_sp = (void *) (long) buf32.ss_sp; uss.ss_flags = buf32.ss_flags; - uss.ss_size = buf32.ss_size; + /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the + check and set it to the user requested value later */ + if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) { + ret = -ENOMEM; + goto out; + } + uss.ss_size = MINSIGSTKSZ; set_fs(KERNEL_DS); ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12); + current->sas_ss_size = buf32.ss_size; set_fs(old_fs); +out: if (ret < 0) return(ret); if (uoss32) { @@ -3689,13 +3713,18 @@ asmlinkage long sys32_stat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); + ret = sys_newstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; @@ -3704,13 +3733,18 @@ asmlinkage long sys32_lstat64 (char *filename, struct stat64 *statbuf) { + char *name; mm_segment_t old_fs = get_fs(); struct stat s; long ret; + name = getname(filename); + if (IS_ERR(name)) + return PTR_ERR(name); set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); + ret = sys_newlstat(name, &s); set_fs(old_fs); + putname(name); if (putstat64(statbuf, &s)) return -EFAULT; return ret; diff -urN linux-2.4.24/arch/ia64/kernel/acpi.c linux-2.4.25/arch/ia64/kernel/acpi.c --- linux-2.4.24/arch/ia64/kernel/acpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/acpi.c 2004-02-18 05:36:30.000000000 -0800 @@ -96,7 +96,7 @@ } if (!strcmp(hdr->oem_id, "HP")) { - return "hpzx1"; + return "hp"; } else if (!strcmp(hdr->oem_id, "SGI")) { return "sn2"; @@ -107,7 +107,7 @@ # if defined (CONFIG_IA64_HP_SIM) return "hpsim"; # elif defined (CONFIG_IA64_HP_ZX1) - return "hpzx1"; + return "hp"; # elif defined (CONFIG_IA64_SGI_SN2) return "sn2"; # elif defined (CONFIG_IA64_DIG) @@ -820,4 +820,22 @@ return gsi_to_vector(irq); } +int +acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) +{ + int vector = 0; + + if (has_8259 && gsi < 16) + return isa_irq_to_vector(gsi); + + if (!iosapic_register_intr) + return 0; + + /* Turn it on */ + vector = iosapic_register_intr(gsi, + (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); + return vector; +} + #endif /* CONFIG_ACPI_BOOT */ diff -urN linux-2.4.24/arch/ia64/kernel/efi.c linux-2.4.25/arch/ia64/kernel/efi.c --- linux-2.4.24/arch/ia64/kernel/efi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/efi.c 2004-02-18 05:36:30.000000000 -0800 @@ -30,6 +30,7 @@ #include #include #include +#include #define EFI_DEBUG 0 @@ -297,9 +298,9 @@ u64 start; u64 end; } prev, curr; - void *efi_map_start, *efi_map_end, *p, *q, *r; + void *efi_map_start, *efi_map_end, *p, *q; efi_memory_desc_t *md, *check_md; - u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0; + u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -312,41 +313,34 @@ if (!(md->attribute & EFI_MEMORY_WB)) continue; - if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) { - /* - * Search for the next run of contiguous WB memory. Start search - * at first granule boundary covered by md. - */ - granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1) - & -IA64_GRANULE_SIZE); - first_non_wb_addr = granule_addr; - for (q = p; q < efi_map_end; q += efi_desc_size) { - check_md = q; - - if (check_md->attribute & EFI_MEMORY_WB) - trim_bottom(check_md, granule_addr); - - if (check_md->phys_addr < granule_addr) - continue; + /* + * granule_addr is the base of md's first granule. + * [granule_addr - first_non_wb_addr) is guaranteed to + * be contiguous WB memory. + */ + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); - if (!(check_md->attribute & EFI_MEMORY_WB)) - break; /* hit a non-WB region; stop search */ + if (first_non_wb_addr < md->phys_addr) { + trim_bottom(md, granule_addr + IA64_GRANULE_SIZE); + granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1); + first_non_wb_addr = max(first_non_wb_addr, granule_addr); + } - if (check_md->phys_addr != first_non_wb_addr) - break; /* hit a memory hole; stop search */ + for (q = p; q < efi_map_end; q += efi_desc_size) { + check_md = q; + if ((check_md->attribute & EFI_MEMORY_WB) && + (check_md->phys_addr == first_non_wb_addr)) first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT; - } - /* round it down to the previous granule-boundary: */ - first_non_wb_addr &= -IA64_GRANULE_SIZE; - - if (!(first_non_wb_addr > granule_addr)) - continue; /* couldn't find enough contiguous memory */ - - for (r = p; r < q; r += efi_desc_size) - trim_top(r, first_non_wb_addr); + else + break; /* non-WB or hole */ } + last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1); + if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) + trim_top(md, last_granule_addr); + if (is_available_memory(md)) { if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { if (md->phys_addr > mem_limit) @@ -402,6 +396,9 @@ int pal_code_count = 0; u64 mask, psr; u64 vaddr; +#ifdef CONFIG_IA64_MCA + int cpu; +#endif efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -446,10 +443,12 @@ panic("Woah! PAL code size bigger than a granule!"); mask = ~((1 << IA64_GRANULE_SHIFT) - 1); +#if EFI_DEBUG printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); +#endif /* * Cannot write to CRx with PSR.ic=1 @@ -459,6 +458,14 @@ pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), IA64_GRANULE_SHIFT); ia64_set_psr(psr); /* restore psr */ ia64_srlz_i(); + +#ifdef CONFIG_IA64_MCA + cpu = smp_processor_id(); + + /* insert this TR into our list for MCA recovery purposes */ + ia64_mca_tlb_list[cpu].pal_base=vaddr & mask; + ia64_mca_tlb_list[cpu].pal_paddr= pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)); +#endif } } @@ -688,8 +695,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->type; } return 0; @@ -709,8 +715,7 @@ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if ((md->phys_addr <= phys_addr) && (phys_addr <= - (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1))) + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md->attribute; } return 0; diff -urN linux-2.4.24/arch/ia64/kernel/gate.S linux-2.4.25/arch/ia64/kernel/gate.S --- linux-2.4.24/arch/ia64/kernel/gate.S 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/kernel/gate.S 2004-02-18 05:36:30.000000000 -0800 @@ -88,10 +88,10 @@ ld8 r15=[base1] // get address of new RBS base (or NULL) cover // push args in interrupted frame onto backing store ;; - cmp.ne p8,p0=r15,r0 // do we need to switch the rbs? + cmp.ne p1,p0=r15,r0 // do we need to switch rbs? (note: pr is saved by kernel) mov.m r9=ar.bsp // fetch ar.bsp - .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF -(p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16) + .spillsp.p p1, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF +(p1) br.cond.spnt setup_rbs // yup -> (clobbers p8, r14-r16, and r18-r20) back_from_setup_rbs: alloc r8=ar.pfs,0,0,3,0 ld8 out0=[base0],16 // load arg0 (signum) @@ -130,8 +130,8 @@ ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF mov r14=ar.bsp ;; - cmp.ne p8,p0=r14,r15 // do we need to restore the rbs? -(p8) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) + cmp.ne p1,p0=r14,r15 // do we need to restore the rbs? +(p1) br.cond.spnt restore_rbs // yup -> (clobbers r14-r18, f6 & f7) ;; back_from_restore_rbs: adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp @@ -160,26 +160,30 @@ setup_rbs: mov ar.rsc=0 // put RSE into enforced lazy mode ;; - .save ar.rnat, r16 - mov r16=ar.rnat // save RNaT before switching backing store area + .save ar.rnat, r19 + mov r19=ar.rnat // save RNaT before switching backing store area adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp + mov r18=ar.bspstore mov ar.bspstore=r15 // switch over to new register backing store area ;; + .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF - st8 [r14]=r16 // save sc_ar_rnat + st8 [r14]=r19 // save sc_ar_rnat .body - adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp - mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 + adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp ;; invala sub r15=r16,r15 + extr.u r20=r18,3,6 ;; + mov ar.rsc=0xf // set RSE into eager mode, pl 3 + cmp.eq p8,p0=63,r20 shl r15=r15,16 ;; st8 [r14]=r15 // save sc_loadrs - mov ar.rsc=0xf // set RSE into eager mode, pl 3 +(p8) st8 [r18]=r19 // if bspstore points at RNaT slot, store RNaT there now .restore sp // pop .prologue br.cond.sptk back_from_setup_rbs diff -urN linux-2.4.24/arch/ia64/kernel/ia64_ksyms.c linux-2.4.25/arch/ia64/kernel/ia64_ksyms.c --- linux-2.4.24/arch/ia64/kernel/ia64_ksyms.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/kernel/ia64_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -169,3 +169,7 @@ EXPORT_SYMBOL(pfm_install_alternate_syswide_subsystem); EXPORT_SYMBOL(pfm_remove_alternate_syswide_subsystem); #endif + +#include +extern acpi_status acpi_hp_csr_space(acpi_handle, u64 *, u64 *); +EXPORT_SYMBOL(acpi_hp_csr_space); diff -urN linux-2.4.24/arch/ia64/kernel/ivt.S linux-2.4.25/arch/ia64/kernel/ivt.S --- linux-2.4.24/arch/ia64/kernel/ivt.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/ivt.S 2004-02-18 05:36:30.000000000 -0800 @@ -118,6 +118,10 @@ * - the faulting virtual address has no L1, L2, or L3 mapping */ mov r16=cr.ifa // get address that caused the TLB miss +#ifdef CONFIG_HUGETLB_PAGE + movl r18=PAGE_SHIFT + mov r25=cr.itir +#endif ;; rsm psr.dt // use physical addressing for data mov r31=pr // save the predicate registers @@ -125,8 +129,18 @@ shl r21=r16,3 // shift bit 60 into sign bit shr.u r17=r16,61 // get the region number into r17 ;; + shr r22=r21,3 +#ifdef CONFIG_HUGETLB_PAGE + extr.u r26=r25,2,6 + ;; + cmp.eq p8,p0=HPAGE_SHIFT,r26 + ;; +(p8) dep r25=r18,r25,2,6 +(p8) shr r22=r22,HPAGE_SHIFT-PAGE_SHIFT +#endif + ;; cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? - shr.u r18=r16,PGDIR_SHIFT // get bits 33-63 of the faulting address + shr.u r18=r22,PGDIR_SHIFT // get bits 33-63 of the faulting address ;; (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d // ensure "rsm psr.dt" has taken effect @@ -137,7 +151,7 @@ (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? - shr.u r18=r16,PMD_SHIFT // shift L2 index into position + shr.u r18=r22,PMD_SHIFT // shift L2 index into position ;; ld8 r17=[r17] // fetch the L1 entry (may be 0) ;; @@ -145,7 +159,7 @@ dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry ;; (p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) - shr.u r19=r16,PAGE_SHIFT // shift L3 index into position + shr.u r19=r22,PAGE_SHIFT // shift L3 index into position ;; (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry @@ -164,6 +178,10 @@ (p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) mov cr.ifa=r22 +#ifdef CONFIG_HUGETLB_PAGE +(p8) mov cr.itir=r25 // change to default page-size for VHPT +#endif + /* * Now compute and insert the TLB entry for the virtual page table. We never * execute in a page table page so there is no need to set the exception deferral diff -urN linux-2.4.24/arch/ia64/kernel/mca.c linux-2.4.25/arch/ia64/kernel/mca.c --- linux-2.4.24/arch/ia64/kernel/mca.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/mca.c 2004-02-18 05:36:30.000000000 -0800 @@ -36,6 +36,10 @@ * SAL 3.0 spec. * 00/03/29 C. Fleckenstein Fixed PAL/SAL update issues, began MCA bug fixes, logging issues, * added min save state dump, added INIT handler. + * + * 2003-12-08 Keith Owens + * smp_call_function() must not be called from interrupt context (can + * deadlock on tasklist_lock). Use keventd to call smp_call_function(). */ #include #include @@ -50,6 +54,7 @@ #include #include #include +#include #include #include @@ -80,19 +85,19 @@ u64 ia64_mca_stackframe[32]; u64 ia64_mca_bspstore[1024]; u64 ia64_init_stack[INIT_TASK_SIZE/8] __attribute__((aligned(16))); -u64 ia64_mca_sal_data_area[1356]; -u64 ia64_tlb_functional; u64 ia64_os_mca_recovery_successful; -/* TODO: need to assign min-state structure to UC memory */ -u64 ia64_mca_min_state_save_info[MIN_STATE_AREA_SIZE] __attribute__((aligned(512))); +u64 ia64_mca_serialize; static void ia64_mca_wakeup_ipi_wait(void); static void ia64_mca_wakeup(int cpu); static void ia64_mca_wakeup_all(void); static void ia64_log_init(int); extern void ia64_monarch_init_handler (void); extern void ia64_slave_init_handler (void); +static u64 ia64_log_get(int sal_info_type, u8 **buffer); extern struct hw_interrupt_type irq_type_iosapic_level; +struct ia64_mca_tlb_info ia64_mca_tlb_list[NR_CPUS]; + static struct irqaction cmci_irqaction = { .handler = ia64_mca_cmc_int_handler, .flags = SA_INTERRUPT, @@ -151,7 +156,9 @@ */ static int cpe_poll_enabled = 1; -extern void salinfo_log_wakeup(int); +extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size); + +static struct tq_struct cmc_disable_tq, cmc_enable_tq; /* * ia64_mca_log_sal_error_record @@ -166,11 +173,13 @@ int ia64_mca_log_sal_error_record(int sal_info_type, int called_from_init) { - int platform_err = 0; + u8 *buffer; + u64 size; + int platform_err; - /* Get the MCA error record */ - if (!ia64_log_get(sal_info_type, (prfunc_t)printk)) - return platform_err; /* no record retrieved */ + size = ia64_log_get(sal_info_type, &buffer); + if (!size) + return 0; /* TODO: * 1. analyze error logs to determine recoverability @@ -178,8 +187,11 @@ * 3. set ia64_os_mca_recovery_successful flag, if applicable */ - salinfo_log_wakeup(sal_info_type); + salinfo_log_wakeup(sal_info_type, buffer, size); platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk); + /* Clear logs from corrected errors in case there's no user-level logger */ + if (sal_info_type == SAL_INFO_TYPE_CPE || sal_info_type == SAL_INFO_TYPE_CMC) + ia64_sal_clear_state_info(sal_info_type); return platform_err; } @@ -462,26 +474,6 @@ #endif /* PLATFORM_MCA_HANDLERS */ /* - * routine to process and prepare to dump min_state_save - * information for debugging purposes. - */ -void -ia64_process_min_state_save (pal_min_state_area_t *pmss) -{ - int i, max = MIN_STATE_AREA_SIZE; - u64 *tpmss_ptr = (u64 *)pmss; - u64 *return_min_state_ptr = ia64_mca_min_state_save_info; - - for (i=0;icc == 1 && psp->bc == 1 && psp->rc == 1 && psp->uc == 1) + ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT; + else + ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED; /* Default = tell SAL to return to same context */ ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT; - /* Register pointer to new min state values */ ia64_os_to_sal_handoff_state.imots_new_min_state = - ia64_mca_min_state_save_info; + (u64 *)ia64_sal_to_os_handoff_state.pal_min_state; + } /* @@ -1056,14 +1091,7 @@ cmc_polling_enabled = 1; spin_unlock(&cmc_history_lock); - - /* - * We rely on the local_irq_enable() above so - * that this can't deadlock. - */ - ia64_mca_cmc_vector_disable(NULL); - - smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 0); + schedule_task(&cmc_disable_tq); /* * Corrected errors will still be corrected, but @@ -1157,19 +1185,7 @@ if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) { printk(KERN_WARNING "%s: Returning to interrupt driven CMC handler\n", __FUNCTION__); - - /* - * The cmc interrupt handler enabled irqs, so - * this can't deadlock. - */ - smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 0); - - /* - * Turn off interrupts before re-enabling the - * cmc vector locally. Make sure we get out. - */ - local_irq_disable(); - ia64_mca_cmc_vector_enable(NULL); + schedule_task(&cmc_enable_tq); cmc_polling_enabled = 0; } else { @@ -1416,12 +1432,12 @@ * Get the current MCA log from SAL and copy it into the OS log buffer. * * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) - * prfunc (fn ptr of log output function) * Outputs : size (total record length) + * *buffer (ptr to error record) * */ u64 -ia64_log_get(int sal_info_type, prfunc_t prfunc) +ia64_log_get(int sal_info_type, u8 **buffer) { sal_log_record_header_t *log_buffer; u64 total_len = 0; @@ -1439,6 +1455,7 @@ IA64_LOG_UNLOCK(sal_info_type); IA64_MCA_DEBUG("ia64_log_get: SAL error record type %d retrieved. " "Record length = %ld\n", sal_info_type, total_len); + *buffer = (u8 *) log_buffer; return total_len; } else { IA64_LOG_UNLOCK(sal_info_type); @@ -1483,7 +1500,7 @@ void ia64_log_rec_header_print (sal_log_record_header_t *lh, prfunc_t prfunc) { - prfunc("+Err Record ID: %d SAL Rev: %2x.%02x\n", lh->id, + prfunc("+Err Record ID: %ld SAL Rev: %2x.%02x\n", lh->id, lh->revision.major, lh->revision.minor); prfunc("+Time: %02x/%02x/%02x%02x %02x:%02x:%02x Severity %d\n", lh->timestamp.slh_month, lh->timestamp.slh_day, @@ -1606,13 +1623,13 @@ if (info->dl) prfunc(" Line: Data,"); prfunc(" Operation: %s,", pal_cache_op[info->op]); - if (info->wv) + if (info->wiv) prfunc(" Way: %d,", info->way); if (cache_check_info->valid.target_identifier) /* Hope target address is saved in target_identifier */ if (info->tv) prfunc(" Target Addr: 0x%lx,", target_addr); - if (info->mc) + if (info->mcc) prfunc(" MC: Corrected"); prfunc("\n"); } @@ -1648,13 +1665,13 @@ prfunc(" Failure: Data Translation Cache"); if (info->itr) { prfunc(" Failure: Instruction Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); + prfunc(" ,Slot: %ld", info->tr_slot); } if (info->dtr) { prfunc(" Failure: Data Translation Register"); - prfunc(" ,Slot: %d", info->tr_slot); + prfunc(" ,Slot: %ld", info->tr_slot); } - if (info->mc) + if (info->mcc) prfunc(" ,MC: Corrected"); prfunc("\n"); } @@ -1700,7 +1717,7 @@ prfunc(" ,Error: Internal"); if (info->eb) prfunc(" ,Error: External"); - if (info->mc) + if (info->mcc) prfunc(" ,MC: Corrected"); if (info->tv) prfunc(" ,Target Address: 0x%lx", targ_addr); @@ -2148,9 +2165,6 @@ if (slpi->valid.psi_static_struct) { spsi = (sal_processor_static_info_t *)p_data; - /* copy interrupted context PAL min-state info */ - ia64_process_min_state_save(&spsi->min_state_area); - /* Print branch register contents if valid */ if (spsi->valid.br) ia64_log_processor_regs_print(spsi->br, 8, "Branch", "br", @@ -2376,7 +2390,8 @@ ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); break; case SAL_INFO_TYPE_INIT: - prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n"); + prfunc("+CPU %d: SAL log contains INIT error record\n", smp_processor_id()); + ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc); break; case SAL_INFO_TYPE_CMC: prfunc("+BEGIN HARDWARE ERROR STATE AT CMC\n"); diff -urN linux-2.4.24/arch/ia64/kernel/mca_asm.S linux-2.4.25/arch/ia64/kernel/mca_asm.S --- linux-2.4.24/arch/ia64/kernel/mca_asm.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/mca_asm.S 2004-02-18 05:36:30.000000000 -0800 @@ -14,6 +14,7 @@ // 3. Move stack ptr 16 bytes to conform to C calling convention // #include +#include #include #include @@ -22,20 +23,15 @@ #include /* - * When we get an machine check, the kernel stack pointer is no longer + * When we get a machine check, the kernel stack pointer is no longer * valid, so we need to set a new stack pointer. */ #define MINSTATE_PHYS /* Make sure stack access is physical for MINSTATE */ /* - * Needed for ia64_sal call - */ -#define SAL_GET_STATE_INFO 0x01000001 - -/* * Needed for return context to SAL */ -#define IA64_MCA_SAME_CONTEXT 0x0 +#define IA64_MCA_SAME_CONTEXT 0 #define IA64_MCA_COLD_BOOT -2 #include "minstate.h" @@ -72,21 +68,36 @@ * returns ptr to SAL rtn save loc in _tmp */ #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp) \ -(p6) movl _tmp=ia64_sal_to_os_handoff_state;; \ -(p7) movl _tmp=ia64_os_to_sal_handoff_state;; \ + movl _tmp=ia64_os_to_sal_handoff_state;; \ DATA_VA_TO_PA(_tmp);; \ -(p6) movl r8=IA64_MCA_COLD_BOOT; \ -(p6) movl r10=IA64_MCA_SAME_CONTEXT; \ -(p6) add _tmp=0x18,_tmp;; \ -(p6) ld8 r9=[_tmp],0x10; \ -(p6) movl r22=ia64_mca_min_state_save_info;; \ -(p7) ld8 r8=[_tmp],0x08;; \ -(p7) ld8 r9=[_tmp],0x08;; \ -(p7) ld8 r10=[_tmp],0x08;; \ -(p7) ld8 r22=[_tmp],0x08;; \ - DATA_VA_TO_PA(r22) + ld8 r8=[_tmp],0x08;; \ + ld8 r9=[_tmp],0x08;; \ + ld8 r10=[_tmp],0x08;; \ + ld8 r22=[_tmp],0x08;; // now _tmp is pointing to SAL rtn save location +/* + * COLD_BOOT_HANDOFF_STATE() sets ia64_mca_os_to_sal_state + * imots_os_status=IA64_MCA_COLD_BOOT + * imots_sal_gp=SAL GP + * imots_context=IA64_MCA_SAME_CONTEXT + * imots_new_min_state=Min state save area pointer + * imots_sal_check_ra=Return address to location within SAL_CHECK + * + */ +#define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\ + movl tmp=IA64_MCA_COLD_BOOT; \ + movl sal_to_os_handoff=__pa(ia64_sal_to_os_handoff_state); \ + movl os_to_sal_handoff=__pa(ia64_os_to_sal_handoff_state);; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff],48;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + movl tmp=IA64_MCA_SAME_CONTEXT;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff],-8;; \ + st8 [os_to_sal_handoff]=tmp,8;; \ + ld8 tmp=[sal_to_os_handoff];; \ + st8 [os_to_sal_handoff]=tmp;; .global ia64_os_mca_dispatch .global ia64_os_mca_dispatch_end @@ -97,21 +108,20 @@ .global ia64_mca_stackframe .global ia64_mca_bspstore .global ia64_init_stack - .global ia64_mca_sal_data_area - .global ia64_tlb_functional - .global ia64_mca_min_state_save_info .text .align 16 ia64_os_mca_dispatch: -#if defined(MCA_TEST) - // Pretend that we are in interrupt context - mov r2=psr - dep r2=0, r2, PSR_IC, 2; - mov psr.l = r2 -#endif /* #if defined(MCA_TEST) */ + // Serialize all MCA processing + movl r2=ia64_mca_serialize + mov r3=1;; + DATA_VA_TO_PA(r2);; +ia64_os_mca_spin: + xchg8 r4=[r2],r3;; + cmp.ne p6,p0=r4,r0 +(p6) br ia64_os_mca_spin // Save the SAL to OS MCA handoff state as defined // by SAL SPEC 3.0 @@ -128,6 +138,182 @@ ia64_os_mca_done_dump: + movl r16=__pa(ia64_sal_to_os_handoff_state)+56 + ;; + ld8 r18=[r16] // Get processor state parameter on existing PALE_CHECK. + ;; + tbit.nz p6,p7=r18,60 +(p7) br.spnt done_tlb_purge_and_reload + + // The following code purges TC and TR entries. Then reload all TC entries. + // Purge percpu data TC entries. +begin_tlb_purge_and_reload: + mov r16=cr.lid + movl r17=__pa(ia64_mca_tlb_list) // Physical address of ia64_mca_tlb_list + mov r19=0 + mov r20=NR_CPUS + ;; +1: cmp.eq p6,p7=r19,r20 +(p6) br.spnt.few err + ld8 r18=[r17],IA64_MCA_TLB_INFO_SIZE + ;; + add r19=1,r19 + cmp.eq p6,p7=r18,r16 +(p7) br.sptk.few 1b + ;; + adds r17=-IA64_MCA_TLB_INFO_SIZE,r17 + ;; + mov r23=r17 // save current ia64_mca_percpu_info addr pointer. + adds r17=16,r17 + ;; + ld8 r18=[r17],8 // r18=ptce_base + ;; + ld4 r19=[r17],4 // r19=ptce_count[0] + ;; + ld4 r20=[r17],4 // r20=ptce_count[1] + ;; + ld4 r21=[r17],4 // r21=ptce_stride[0] + mov r24=0 + ;; + ld4 r22=[r17],4 // r22=ptce_stride[1] + adds r20=-1,r20 + ;; +2: + cmp.ltu p6,p7=r24,r19 +(p7) br.cond.dpnt.few 4f + mov ar.lc=r20 +3: + ptc.e r18 + ;; + add r18=r22,r18 + br.cloop.sptk.few 3b + ;; + add r18=r21,r18 + add r24=1,r24 + ;; + br.sptk.few 2b +4: + srlz.i // srlz.i implies srlz.d + ;; + + // Now purge addresses formerly mapped by TR registers + // 1. Purge ITR&DTR for kernel. + movl r16=KERNEL_START + mov r18=KERNEL_TR_PAGE_SHIFT<<2 + ;; + ptr.i r16, r18 + ptr.d r16, r18 + ;; + srlz.i + ;; + srlz.d + ;; + // 2. Purge DTR for PERCPU data. + movl r16=PERCPU_ADDR + mov r18=PAGE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.d + ;; + // 3. Purge ITR for PAL code. + adds r17=48,r23 + ;; + ld8 r16=[r17] + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.i r16,r18 + ;; + srlz.i + ;; + // 4. Purge DTR for stack. + mov r16=IA64_KR(CURRENT_STACK) + ;; + shl r16=r16,IA64_GRANULE_SHIFT + movl r19=PAGE_OFFSET + ;; + add r16=r19,r16 + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.i + ;; + // Finally reload the TR registers. + // 1. Reload DTR/ITR registers for kernel. + mov r18=KERNEL_TR_PAGE_SHIFT<<2 + movl r17=KERNEL_START + ;; + mov cr.itir=r18 + mov cr.ifa=r17 + mov r16=IA64_TR_KERNEL + movl r18=((1 << KERNEL_TR_PAGE_SHIFT) | PAGE_KERNEL) + ;; + itr.i itr[r16]=r18 + ;; + itr.d dtr[r16]=r18 + ;; + srlz.i + srlz.d + ;; + // 2. Reload DTR register for PERCPU data. + adds r17=8,r23 + movl r16=PERCPU_ADDR // vaddr + movl r18=PAGE_SHIFT<<2 + ;; + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + ld8 r18=[r17] // pte + mov r16=IA64_TR_PERCPU_DATA; + ;; + itr.d dtr[r16]=r18 + ;; + srlz.d + ;; + // 3. Reload ITR for PAL code. + adds r17=40,r23 + ;; + ld8 r18=[r17],8 // pte + ;; + ld8 r16=[r17] // vaddr + mov r19=IA64_GRANULE_SHIFT<<2 + ;; + mov cr.itir=r19 + mov cr.ifa=r16 + mov r20=IA64_TR_PALCODE + ;; + itr.i itr[r20]=r18 + ;; + srlz.i + ;; + // 4. Reload DTR for stack. + mov r16=IA64_KR(CURRENT_STACK) + ;; + shl r16=r16,IA64_GRANULE_SHIFT + movl r19=PAGE_OFFSET + ;; + add r18=r19,r16 + movl r20=PAGE_KERNEL + ;; + add r16=r20,r16 + mov r19=IA64_GRANULE_SHIFT<<2 + ;; + mov cr.itir=r19 + mov cr.ifa=r18 + mov r20=IA64_TR_CURRENT_STACK + ;; + itr.d dtr[r20]=r16 + ;; + srlz.d + ;; + br.sptk.many done_tlb_purge_and_reload +err: + COLD_BOOT_HANDOFF_STATE(r20,r21,r22) + br.sptk.many ia64_os_mca_done_restore + +done_tlb_purge_and_reload: + // Setup new stack frame for OS_MCA handling movl r2=ia64_mca_bspstore;; // local bspstore area location in r2 DATA_VA_TO_PA(r2);; @@ -141,17 +327,11 @@ // (C calling convention) DATA_VA_TO_PA(r12);; - // Check to see if the MCA resulted from a TLB error -begin_tlb_error_check: - br ia64_os_mca_tlb_error_check;; - -done_tlb_error_check: - - // If TLB is functional, enter virtual mode from physical mode + // Enter virtual mode from physical mode VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4) ia64_os_mca_virtual_begin: - // call our handler + // Call virtual mode handler movl r2=ia64_mca_ucmc_handler;; mov b6=r2;; br.call.sptk.many b0=b6;; @@ -160,13 +340,6 @@ PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4) ia64_os_mca_virtual_end: -#if defined(MCA_TEST) - // Pretend that we are in interrupt context - mov r2=psr;; - dep r2=0, r2, PSR_IC, 2;; - mov psr.l = r2;; -#endif /* #if defined(MCA_TEST) */ - // restore the original stack frame here movl r2=ia64_mca_stackframe // restore stack frame from memory at r2 ;; @@ -182,14 +355,16 @@ br ia64_os_mca_proc_state_restore;; ia64_os_mca_done_restore: - movl r3=ia64_tlb_functional;; - DATA_VA_TO_PA(r3);; - ld8 r3=[r3];; - cmp.eq p6,p7=r0,r3;; OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2);; // branch back to SALE_CHECK ld8 r3=[r2];; mov b0=r3;; // SAL_CHECK return address + + // release lock + movl r3=ia64_mca_serialize;; + DATA_VA_TO_PA(r3);; + st8.rel [r3]=r0 + br b0 ;; ia64_os_mca_dispatch_end: @@ -267,15 +442,15 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 - mov r3=cr0 // cr.dcr - mov r5=cr1 // cr.itm - mov r7=cr2;; // cr.iva + mov r3=cr.dcr + mov r5=cr.itm + mov r7=cr.iva;; st8 [r2]=r3,8*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; // 48 byte rements - mov r3=cr8;; // cr.pta + mov r3=cr.pta;; st8 [r2]=r3,8*8;; // 64 byte rements // if PSR.ic=0, reading interruption registers causes an illegal operation fault @@ -288,23 +463,23 @@ add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr16 // cr.ipsr - mov r5=cr17 // cr.isr - mov r7=r0;; // cr.ida => cr18 (reserved) + mov r3=cr.ipsr + mov r5=cr.isr + mov r7=r0;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr19 // cr.iip - mov r5=cr20 // cr.idtr - mov r7=cr21;; // cr.iitr + mov r3=cr.iip + mov r5=cr.ifa + mov r7=cr.itir;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr22 // cr.iipa - mov r5=cr23 // cr.ifs - mov r7=cr24;; // cr.iim + mov r3=cr.iipa + mov r5=cr.ifs + mov r7=cr.iim;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; @@ -313,104 +488,101 @@ st8 [r2]=r3,160;; // 160 byte rement SkipIntrRegs: - st8 [r2]=r0,168 // another 168 byte . - - mov r3=cr66;; // cr.lid - st8 [r2]=r3,40 // 40 byte rement + st8 [r2]=r0,152;; // another 152 byte . - mov r3=cr71;; // cr.ivr - st8 [r2]=r3,8 + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr72;; // cr.tpr - st8 [r2]=r3,24 // 24 byte increment - - mov r3=r0;; // cr.eoi => cr75 - st8 [r2]=r3,168 // 168 byte inc. - - mov r3=r0;; // cr.irr0 => cr96 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr1 => cr98 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr2 => cr100 - st8 [r2]=r3,16 // 16 byte inc - - mov r3=r0;; // cr.irr3 => cr100 - st8 [r2]=r3,16 // 16b inc. - - mov r3=r0;; // cr.itv => cr114 - st8 [r2]=r3,16 // 16 byte inc. + mov r3=cr.lid +// mov r5=cr.ivr // cr.ivr, don't read it + mov r7=cr.tpr;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.pmv => cr116 - st8 [r2]=r3,8 + mov r3=r0 // cr.eoi => cr67 + mov r5=r0 // cr.irr0 => cr68 + mov r7=r0;; // cr.irr1 => cr69 + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr0 => cr117 - st8 [r2]=r3,8 + mov r3=r0 // cr.irr2 => cr70 + mov r5=r0 // cr.irr3 => cr71 + mov r7=cr.itv;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr1 => cr118 - st8 [r2]=r3,8 + mov r3=cr.pmv + mov r5=cr.cmcv;; + st8 [r2]=r3,7*8 + st8 [r4]=r5,7*8;; + + mov r3=r0 // cr.lrr0 => cr80 + mov r5=r0;; // cr.lrr1 => cr81 + st8 [r2]=r3,23*8 + st8 [r4]=r5,23*8;; - mov r3=r0;; // cr.cmcv => cr119 - st8 [r2]=r3,8*10;; + adds r2=25*8,r2;; cSaveARs: // save ARs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=ar0 // ar.kro - mov r5=ar1 // ar.kr1 - mov r7=ar2;; // ar.kr2 + mov r3=ar.k0 + mov r5=ar.k1 + mov r7=ar.k2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar3 // ar.kr3 - mov r5=ar4 // ar.kr4 - mov r7=ar5;; // ar.kr5 + mov r3=ar.k3 + mov r5=ar.k4 + mov r7=ar.k5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar6 // ar.kr6 - mov r5=ar7 // ar.kr7 + mov r3=ar.k6 + mov r5=ar.k7 mov r7=r0;; // ar.kr8 st8 [r2]=r3,10*8 st8 [r4]=r5,10*8 st8 [r6]=r7,10*8;; // rement by 72 bytes - mov r3=ar16 // ar.rsc - mov ar16=r0 // put RSE in enforced lazy mode - mov r5=ar17 // ar.bsp + mov r3=ar.rsc + mov ar.rsc=r0 // put RSE in enforced lazy mode + mov r5=ar.bsp ;; - mov r7=ar18;; // ar.bspstore + mov r7=ar.bspstore;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar19;; // ar.rnat + mov r3=ar.rnat;; st8 [r2]=r3,8*13 // increment by 13x8 bytes - mov r3=ar32;; // ar.ccv + mov r3=ar.ccv;; st8 [r2]=r3,8*4 - mov r3=ar36;; // ar.unat + mov r3=ar.unat;; st8 [r2]=r3,8*4 - mov r3=ar40;; // ar.fpsr + mov r3=ar.fpsr;; st8 [r2]=r3,8*4 - mov r3=ar44;; // ar.itc + mov r3=ar.itc;; st8 [r2]=r3,160 // 160 - mov r3=ar64;; // ar.pfs + mov r3=ar.pfs;; st8 [r2]=r3,8 - mov r3=ar65;; // ar.lc + mov r3=ar.lc;; st8 [r2]=r3,8 - mov r3=ar66;; // ar.ec + mov r3=ar.ec;; st8 [r2]=r3 add r2=8*62,r2 //padding @@ -419,7 +591,8 @@ movl r4=0x00;; cStRR: - mov r3=rr[r4];; + dep.z r5=r4,61,3;; + mov r3=rr[r5];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR @@ -503,12 +676,12 @@ ld8 r3=[r2],8*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; // 48 byte increments - mov cr0=r3 // cr.dcr - mov cr1=r5 // cr.itm - mov cr2=r7;; // cr.iva + mov cr.dcr=r3 + mov cr.itm=r5 + mov cr.iva=r7;; ld8 r3=[r2],8*8;; // 64 byte increments -// mov cr8=r3 // cr.pta +// mov cr.pta=r3 // if PSR.ic=1, reading interruption registers causes an illegal operation fault @@ -525,64 +698,66 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr16=r3 // cr.ipsr - mov cr17=r5 // cr.isr is read only -// mov cr18=r7;; // cr.ida (reserved - don't restore) + mov cr.ipsr=r3 +// mov cr.isr=r5 // cr.isr is read only ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr19=r3 // cr.iip - mov cr20=r5 // cr.idtr - mov cr21=r7;; // cr.iitr + mov cr.iip=r3 + mov cr.ifa=r5 + mov cr.itir=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr22=r3 // cr.iipa - mov cr23=r5 // cr.ifs - mov cr24=r7 // cr.iim + mov cr.iipa=r3 + mov cr.ifs=r5 + mov cr.iim=r7 ld8 r3=[r2],160;; // 160 byte increment - mov cr25=r3 // cr.iha + mov cr.iha=r3 rSkipIntrRegs: - ld8 r3=[r2],168;; // another 168 byte inc. - - ld8 r3=[r2],40;; // 40 byte increment - mov cr66=r3 // cr.lid - - ld8 r3=[r2],8;; -// mov cr71=r3 // cr.ivr is read only - ld8 r3=[r2],24;; // 24 byte increment - mov cr72=r3 // cr.tpr + ld8 r3=[r2],152;; // another 152 byte inc. - ld8 r3=[r2],168;; // 168 byte inc. -// mov cr75=r3 // cr.eoi + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2;; // duplicate r2 in r6 - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr96=r3 // cr.irr0 is read only + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; + mov cr.lid=r3 +// mov cr.ivr=r5 // cr.ivr is read only + mov cr.tpr=r7;; + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.eoi=r3 +// mov cr.irr0=r5 // cr.irr0 is read only +// mov cr.irr1=r7;; // cr.irr1 is read only + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.irr2=r3 // cr.irr2 is read only +// mov cr.irr3=r5 // cr.irr3 is read only + mov cr.itv=r7;; + + ld8 r3=[r2],8*7 + ld8 r5=[r4],8*7;; + mov cr.pmv=r3 + mov cr.cmcv=r5;; + + ld8 r3=[r2],8*23 + ld8 r5=[r4],8*23;; + adds r2=8*23,r2 + adds r4=8*23,r4;; +// mov cr.lrr0=r3 +// mov cr.lrr1=r5 - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr98=r3 // cr.irr1 is read only - - ld8 r3=[r2],16;; // 16 byte inc -// mov cr100=r3 // cr.irr2 is read only - - ld8 r3=[r2],16;; // 16b inc. -// mov cr102=r3 // cr.irr3 is read only - - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr114=r3 // cr.itv - - ld8 r3=[r2],8;; -// mov cr116=r3 // cr.pmv - ld8 r3=[r2],8;; -// mov cr117=r3 // cr.lrr0 - ld8 r3=[r2],8;; -// mov cr118=r3 // cr.lrr1 - ld8 r3=[r2],8*10;; -// mov cr119=r3 // cr.cmcv + adds r2=8*2,r2;; restore_ARs: add r4=8,r2 // duplicate r2 in r4 @@ -591,67 +766,67 @@ ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar0=r3 // ar.kro - mov ar1=r5 // ar.kr1 - mov ar2=r7;; // ar.kr2 + mov ar.k0=r3 + mov ar.k1=r5 + mov ar.k2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar3=r3 // ar.kr3 - mov ar4=r5 // ar.kr4 - mov ar5=r7;; // ar.kr5 + mov ar.k3=r3 + mov ar.k4=r5 + mov ar.k5=r7;; ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; - mov ar6=r3 // ar.kr6 - mov ar7=r5 // ar.kr7 -// mov ar8=r6 // ar.kr8 + mov ar.k6=r3 + mov ar.k7=r5 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; -// mov ar16=r3 // ar.rsc -// mov ar17=r5 // ar.bsp is read only - mov ar16=r0 // make sure that RSE is in enforced lazy mode +// mov ar.rsc=r3 +// mov ar.bsp=r5 // ar.bsp is read only + mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode ;; - mov ar18=r7;; // ar.bspstore + mov ar.bspstore=r7;; ld8 r9=[r2],8*13;; - mov ar19=r9 // ar.rnat + mov ar.rnat=r9 - mov ar16=r3 // ar.rsc + mov ar.rsc=r3 ld8 r3=[r2],8*4;; - mov ar32=r3 // ar.ccv + mov ar.ccv=r3 ld8 r3=[r2],8*4;; - mov ar36=r3 // ar.unat + mov ar.unat=r3 ld8 r3=[r2],8*4;; - mov ar40=r3 // ar.fpsr + mov ar.fpsr=r3 ld8 r3=[r2],160;; // 160 -// mov ar44=r3 // ar.itc +// mov ar.itc=r3 ld8 r3=[r2],8;; - mov ar64=r3 // ar.pfs + mov ar.pfs=r3 ld8 r3=[r2],8;; - mov ar65=r3 // ar.lc + mov ar.lc=r3 ld8 r3=[r2];; - mov ar66=r3 // ar.ec + mov ar.ec=r3 add r2=8*62,r2;; // padding restore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 - movl r4=0x00 + movl r4=0x00;; cStRRr: + dep.z r7=r4,61,3 ld8 r3=[r2],8;; -// mov rr[r4]=r3 // what are its access previledges? + mov rr[r7]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; @@ -662,79 +837,6 @@ //EndStub////////////////////////////////////////////////////////////////////// -//++ -// Name: -// ia64_os_mca_tlb_error_check() -// -// Stub Description: -// -// This stub checks to see if the MCA resulted from a TLB error -// -//-- - -ia64_os_mca_tlb_error_check: - - // Retrieve sal data structure for uncorrected MCA - - // Make the ia64_sal_get_state_info() call - movl r4=ia64_mca_sal_data_area;; - movl r7=ia64_sal;; - mov r6=r1 // save gp - DATA_VA_TO_PA(r4) // convert to physical address - DATA_VA_TO_PA(r7);; // convert to physical address - ld8 r7=[r7] // get addr of pdesc from ia64_sal - movl r3=SAL_GET_STATE_INFO;; - DATA_VA_TO_PA(r7);; // convert to physical address - ld8 r8=[r7],8;; // get pdesc function pointer - dep r8=0,r8,61,3;; // convert SAL VA to PA - ld8 r1=[r7];; // set new (ia64_sal) gp - dep r1=0,r1,61,3;; // convert SAL VA to PA - mov b6=r8 - - alloc r5=ar.pfs,8,0,8,0;; // allocate stack frame for SAL call - mov out0=r3 // which SAL proc to call - mov out1=r0 // error type == MCA - mov out2=r0 // null arg - mov out3=r4 // data copy area - mov out4=r0 // null arg - mov out5=r0 // null arg - mov out6=r0 // null arg - mov out7=r0;; // null arg - - br.call.sptk.few b0=b6;; - - mov r1=r6 // restore gp - mov ar.pfs=r5;; // restore ar.pfs - - movl r6=ia64_tlb_functional;; - DATA_VA_TO_PA(r6) // needed later - - cmp.eq p6,p7=r0,r8;; // check SAL call return address -(p7) st8 [r6]=r0 // clear tlb_functional flag -(p7) br tlb_failure // error; return to SAL - - // examine processor error log for type of error - add r4=40+24,r4;; // parse past record header (length=40) - // and section header (length=24) - ld4 r4=[r4] // get valid field of processor log - mov r5=0xf00;; - and r5=r4,r5;; // read bits 8-11 of valid field - // to determine if we have a TLB error - movl r3=0x1 - cmp.eq p6,p7=r0,r5;; - // if no TLB failure, set tlb_functional flag -(p6) st8 [r6]=r3 - // else clear flag -(p7) st8 [r6]=r0 - - // if no TLB failure, continue with normal virtual mode logging -(p6) br done_tlb_error_check - // else no point in entering virtual mode for logging -tlb_failure: - br ia64_os_mca_virtual_end - -//EndStub////////////////////////////////////////////////////////////////////// - // ok, the issue here is that we need to save state information so // it can be useable by the kernel debugger and show regs routines. diff -urN linux-2.4.24/arch/ia64/kernel/pci.c linux-2.4.25/arch/ia64/kernel/pci.c --- linux-2.4.24/arch/ia64/kernel/pci.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/pci.c 2004-02-18 05:36:30.000000000 -0800 @@ -298,6 +298,9 @@ status = acpi_resource_to_address64(res, &addr); if (ACPI_SUCCESS(status)) { + if (!addr.address_length) + return AE_OK; + if (addr.resource_type == ACPI_MEMORY_RANGE) { flags = IORESOURCE_MEM; root = &iomem_resource; @@ -311,13 +314,6 @@ } else return AE_OK; - if (addr.min_address_range == addr.max_address_range) { - printk(KERN_INFO "ACPI reports bogus %s %s range 0x%lx-0x%lx; ignoring it\n", - info->name, root->name, addr.min_address_range + offset, - addr.max_address_range + offset); - return AE_OK; - } - window = &info->controller->window[info->controller->windows++]; window->resource.flags |= flags; window->resource.start = addr.min_address_range; @@ -523,8 +519,6 @@ if (ret < 0) return ret; - platform_pci_enable_device(dev); - printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name); return 0; diff -urN linux-2.4.24/arch/ia64/kernel/perfmon.c linux-2.4.25/arch/ia64/kernel/perfmon.c --- linux-2.4.24/arch/ia64/kernel/perfmon.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/perfmon.c 2004-02-18 05:36:30.000000000 -0800 @@ -1527,7 +1527,7 @@ * - system-wide session: PMCx.pm=1 (privileged monitor) * - per-task : PMCx.pm=0 (user monitor) */ - if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) { + if ((is_monitor || is_counting) && value != PMC_DFL_VAL(cnum) && PFM_CHECK_PMC_PM(ctx, cnum, value)) { DBprintk(("pmc%u pmc_pm=%ld fl_system=%d\n", cnum, PMC_PM(cnum, value), @@ -4013,6 +4013,10 @@ if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) { nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid)); + /* + * downgrade parent: once means only first child! + */ + ctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE; } /* * task is not yet visible in the tasklist, so we do diff -urN linux-2.4.24/arch/ia64/kernel/salinfo.c linux-2.4.25/arch/ia64/kernel/salinfo.c --- linux-2.4.24/arch/ia64/kernel/salinfo.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/salinfo.c 2004-02-18 05:36:30.000000000 -0800 @@ -3,19 +3,29 @@ * * Creates entries in /proc/sal for various system features. * - * Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. * Copyright (c) 2003 Hewlett-Packard Co * Bjorn Helgaas * * 10/30/2001 jbarnes@sgi.com copied much of Stephane's palinfo * code to create this file + * Oct 23 2003 kaos@sgi.com + * Replace IPI with set_cpus_allowed() to read a record from the required cpu. + * Redesign salinfo log processing to separate interrupt and user space + * contexts. + * Cache the record across multi-block reads from user space. + * Support > 64 cpus. + * Delete module_exit and MOD_INC/DEC_COUNT, salinfo cannot be a module. */ #include #include #include #include +#include +#include +#include #include #include @@ -57,48 +67,175 @@ (2 * ARRAY_SIZE(salinfo_log_name)) + /* /proc/sal/mca/{event,data} */ 1]; /* /proc/sal */ -struct salinfo_log_data { - int type; - u8 *log_buffer; - u64 log_size; -}; +/* Allow build with or without large SSI support */ +#ifdef CPU_MASK_NONE +#define SCA(x, y) set_cpus_allowed((x), &(y)) +#else +#define cpumask_t unsigned long +#define SCA(x, y) set_cpus_allowed((x), (y)) +#endif -struct salinfo_event { - int type; - int cpu; /* next CPU to check */ - volatile unsigned long cpu_mask; - wait_queue_head_t queue; +/* Some records we get ourselves, some are accessed as saved data in buffers + * that are owned by mca.c. + */ +struct salinfo_data_saved { + u8* buffer; + u64 size; + u64 id; + int cpu; }; -static struct salinfo_event *salinfo_event[ARRAY_SIZE(salinfo_log_name)]; +/* State transitions. Actions are :- + * Write "read " to the data file. + * Write "clear " to the data file. + * Write "oemdata to the data file. + * Read from the data file. + * Close the data file. + * + * Start state is NO_DATA. + * + * NO_DATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> return -EINVAL. + * read data -> return EOF. + * close -> unchanged. Free record areas. + * + * LOG_RECORD + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the INIT/MCA/CMC/CPE record. + * close -> unchanged. Keep record areas. + * + * OEMDATA + * write "read " -> NO_DATA or LOG_RECORD. + * write "clear " -> NO_DATA or LOG_RECORD. + * write "oemdata -> format the oem data, goto OEMDATA. + * read data -> return the formatted oemdata. + * close -> unchanged. Keep record areas. + * + * Closing the data file does not change the state. This allows shell scripts + * to manipulate salinfo data, each shell redirection opens the file, does one + * action then closes it again. The record areas are only freed at close when + * the state is NO_DATA. + */ +enum salinfo_state { + STATE_NO_DATA, + STATE_LOG_RECORD, + STATE_OEMDATA, +}; struct salinfo_data { - int open; /* single-open to prevent races */ - int type; - int cpu; /* "current" cpu for reads */ + volatile cpumask_t cpu_event; /* which cpus have outstanding events */ + struct semaphore sem; /* count of cpus with outstanding events (bits set in cpu_event) */ + u8 *log_buffer; + u64 log_size; + u8 *oemdata; /* decoded oem data */ + u64 oemdata_size; + int open; /* single-open to prevent races */ + u8 type; + u8 saved_num; /* using a saved record? */ + enum salinfo_state state :8; /* processing state */ + u8 padding; + int cpu_check; /* next CPU to check */ + struct salinfo_data_saved data_saved[5];/* save last 5 records from mca.c, must be < 255 */ }; static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; -static spinlock_t data_lock; +static spinlock_t data_lock, data_saved_lock; +/** salinfo_platform_oemdata - optional callback to decode oemdata from an error + * record. + * @sect_header: pointer to the start of the section to decode. + * @oemdata: returns vmalloc area containing the decded output. + * @oemdata_size: returns length of decoded output (strlen). + * + * Description: If user space asks for oem data to be decoded by the kernel + * and/or prom and the platform has set salinfo_platform_oemdata to the address + * of a platform specific routine then call that routine. salinfo_platform_oemdata + * vmalloc's and formats its output area, returning the address of the text + * and its strlen. Returns 0 for success, -ve for error. The callback is + * invoked on the cpu that generated the error record. + */ +int (*salinfo_platform_oemdata)(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size); + +struct salinfo_platform_oemdata_parms { + const u8 *efi_guid; + u8 **oemdata; + u64 *oemdata_size; + int ret; +}; + +static void +salinfo_platform_oemdata_cpu(void *context) +{ + struct salinfo_platform_oemdata_parms *parms = context; + parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); +} + +static void +shift1_data_saved (struct salinfo_data *data, int shift) +{ + memcpy(data->data_saved+shift, data->data_saved+shift+1, + (ARRAY_SIZE(data->data_saved) - (shift+1)) * sizeof(data->data_saved[0])); + memset(data->data_saved + ARRAY_SIZE(data->data_saved) - 1, 0, + sizeof(data->data_saved[0])); +} + +/* This routine is invoked in interrupt context. Note: mca.c enables + * interrupts before calling this code for CMC/CPE. MCA and INIT events are + * not irq safe, do not call any routines that use spinlocks, they may deadlock. + * + * The buffer passed from mca.c points to the output from ia64_log_get. This is + * a persistent buffer but its contents can change between the interrupt and + * when user space processes the record. Save the record id to identify + * changes. + */ void -salinfo_log_wakeup(int type) +salinfo_log_wakeup(int type, u8 *buffer, u64 size) { - if (type < ARRAY_SIZE(salinfo_log_name)) { - struct salinfo_event *event = salinfo_event[type]; + struct salinfo_data *data = salinfo_data + type; + struct salinfo_data_saved *data_saved; + unsigned long flags = 0; + int i, irqsafe = type != SAL_INFO_TYPE_MCA && type != SAL_INFO_TYPE_INIT; + int saved_size = ARRAY_SIZE(data->data_saved); + + BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); + + if (irqsafe) + spin_lock_irqsave(&data_saved_lock, flags); + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (!data_saved->buffer) + break; + } + if (i == saved_size) { + if (!data->saved_num) { + shift1_data_saved(data, 0); + data_saved = data->data_saved + saved_size - 1; + } else + data_saved = NULL; + } + if (data_saved) { + data_saved->cpu = smp_processor_id(); + data_saved->id = ((sal_log_record_header_t *)buffer)->id; + data_saved->size = size; + data_saved->buffer = buffer; + } + if (irqsafe) + spin_unlock_irqrestore(&data_saved_lock, flags); - if (event) { - set_bit(smp_processor_id(), &event->cpu_mask); - wake_up_interruptible(&event->queue); - } + if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { + if (irqsafe) + up(&data->sem); } } static int salinfo_event_open(struct inode *inode, struct file *file) { - if (!suser()) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -107,24 +244,23 @@ salinfo_event_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; - struct salinfo_event *event = entry->data; + struct proc_dir_entry *entry = PDE(inode); + struct salinfo_data *data = entry->data; char cmd[32]; size_t size; int i, n, cpu = -1; retry: - if (!event->cpu_mask) { + if (down_trylock(&data->sem)) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; - interruptible_sleep_on(&event->queue); - if (signal_pending(current)) - return -EINTR; + if (down_interruptible(&data->sem)) + return -ERESTARTSYS; } - n = event->cpu; + n = data->cpu_check; for (i = 0; i < NR_CPUS; i++) { - if (event->cpu_mask & 1UL << n) { + if (test_bit(n, &data->cpu_event)) { cpu = n; break; } @@ -135,10 +271,13 @@ if (cpu == -1) goto retry; + /* events are sticky until the user says "clear" */ + up(&data->sem); + /* for next read, start checking at next CPU */ - event->cpu = cpu; - if (++event->cpu == NR_CPUS) - event->cpu = 0; + data->cpu_check = cpu; + if (++data->cpu_check == NR_CPUS) + data->cpu_check = 0; snprintf(cmd, sizeof(cmd), "read %d\n", cpu); @@ -159,10 +298,10 @@ static int salinfo_log_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; - if (!suser()) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; spin_lock(&data_lock); @@ -173,15 +312,27 @@ data->open = 1; spin_unlock(&data_lock); + if (data->state == STATE_NO_DATA && + !(data->log_buffer = vmalloc(ia64_sal_get_state_info_size(data->type)))) { + data->open = 0; + return -ENOMEM; + } + return 0; } static int salinfo_log_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; + if (data->state == STATE_NO_DATA) { + vfree(data->log_buffer); + vfree(data->oemdata); + data->log_buffer = NULL; + data->oemdata = NULL; + } spin_lock(&data_lock); data->open = 0; spin_unlock(&data_lock); @@ -191,95 +342,136 @@ static void call_on_cpu(int cpu, void (*fn)(void *), void *arg) { - if (cpu == smp_processor_id()) - (*fn)(arg); -#ifdef CONFIG_SMP - else if (cpu_online(cpu)) /* cpu may not have been validated */ - smp_call_function_single(cpu, fn, arg, 0, 1); -#endif + cpumask_t save_cpus_allowed, new_cpus_allowed; + memcpy(&save_cpus_allowed, ¤t->cpus_allowed, sizeof(save_cpus_allowed)); + memset(&new_cpus_allowed, 0, sizeof(new_cpus_allowed)); + set_bit(cpu, &new_cpus_allowed); + SCA(current, new_cpus_allowed); + (*fn)(arg); + SCA(current, save_cpus_allowed); } static void salinfo_log_read_cpu(void *context) { - struct salinfo_log_data *info = context; - struct salinfo_event *event = salinfo_event[info->type]; - u64 size; - - size = ia64_sal_get_state_info_size(info->type); - info->log_buffer = kmalloc(size, GFP_ATOMIC); - if (!info->log_buffer) - return; - - clear_bit(smp_processor_id(), &event->cpu_mask); - info->log_size = ia64_sal_get_state_info(info->type, (u64 *) info->log_buffer); - if (info->log_size) - salinfo_log_wakeup(info->type); + struct salinfo_data *data = context; + data->log_size = ia64_sal_get_state_info(data->type, (u64 *) data->log_buffer); + if (data->type == SAL_INFO_TYPE_CPE || data->type == SAL_INFO_TYPE_CMC) + ia64_sal_clear_state_info(data->type); +} + +static void +salinfo_log_new_read(int cpu, struct salinfo_data *data) +{ + struct salinfo_data_saved *data_saved; + unsigned long flags; + int i; + int saved_size = ARRAY_SIZE(data->data_saved); + + data->saved_num = 0; + spin_lock_irqsave(&data_saved_lock, flags); +retry: + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { + if (data_saved->buffer && data_saved->cpu == cpu) { + sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer); + data->log_size = data_saved->size; + memcpy(data->log_buffer, rh, data->log_size); + barrier(); /* id check must not be moved */ + if (rh->id == data_saved->id) { + data->saved_num = i+1; + break; + } + /* saved record changed by mca.c since interrupt, discard it */ + shift1_data_saved(data, i); + goto retry; + } + } + spin_unlock_irqrestore(&data_saved_lock, flags); + + if (!data->saved_num) + call_on_cpu(cpu, salinfo_log_read_cpu, data); + data->state = data->log_size ? STATE_LOG_RECORD : STATE_NO_DATA; } static ssize_t salinfo_log_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; - struct salinfo_log_data info; - int ret; void *saldata; size_t size; + u8 *buf; + u64 bufsize; - info.type = data->type; - info.log_buffer = 0; - call_on_cpu(data->cpu, salinfo_log_read_cpu, &info); - if (!info.log_buffer || *ppos >= info.log_size) { - ret = 0; - goto out; + if (data->state == STATE_LOG_RECORD) { + buf = data->log_buffer; + bufsize = data->log_size; + } else if (data->state == STATE_OEMDATA) { + buf = data->oemdata; + bufsize = data->oemdata_size; + } else { + buf = NULL; + bufsize = 0; } + if (*ppos >= bufsize) + return 0; - saldata = info.log_buffer + file->f_pos; - size = info.log_size - file->f_pos; + saldata = buf + file->f_pos; + size = bufsize - file->f_pos; if (size > count) size = count; - if (copy_to_user(buffer, saldata, size)) { - ret = -EFAULT; - goto out; - } + if (copy_to_user(buffer, saldata, size)) + return -EFAULT; *ppos += size; - ret = size; - -out: - kfree(info.log_buffer); - return ret; + return size; } static void salinfo_log_clear_cpu(void *context) { struct salinfo_data *data = context; - struct salinfo_event *event = salinfo_event[data->type]; - struct salinfo_log_data info; - - clear_bit(smp_processor_id(), &event->cpu_mask); ia64_sal_clear_state_info(data->type); +} - /* clearing one record may make another visible */ - info.type = data->type; - salinfo_log_read_cpu(&info); - if (info.log_buffer && info.log_size) - salinfo_log_wakeup(data->type); - - kfree(info.log_buffer); +static int +salinfo_log_clear(struct salinfo_data *data, int cpu) +{ + data->state = STATE_NO_DATA; + if (!test_bit(cpu, &data->cpu_event)) + return 0; + down(&data->sem); + clear_bit(cpu, &data->cpu_event); + if (data->saved_num) { + unsigned long flags; + spin_lock_irqsave(&data_saved_lock, flags); + shift1_data_saved(data, data->saved_num - 1 ); + data->saved_num = 0; + spin_unlock_irqrestore(&data_saved_lock, flags); + } + /* ia64_mca_log_sal_error_record or salinfo_log_read_cpu already cleared + * CPE and CMC errors + */ + if (data->type != SAL_INFO_TYPE_CPE && data->type != SAL_INFO_TYPE_CMC) + call_on_cpu(cpu, salinfo_log_clear_cpu, data); + /* clearing a record may make a new record visible */ + salinfo_log_new_read(cpu, data); + if (data->state == STATE_LOG_RECORD && + !test_and_set_bit(cpu, &data->cpu_event)) + up(&data->sem); + return 0; } static ssize_t salinfo_log_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode; - struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; size_t size; + u32 offset; int cpu; size = sizeof(cmd); @@ -288,10 +480,31 @@ if (copy_from_user(cmd, buffer, size)) return -EFAULT; - if (sscanf(cmd, "read %d", &cpu) == 1) - data->cpu = cpu; - else if (sscanf(cmd, "clear %d", &cpu) == 1) - call_on_cpu(cpu, salinfo_log_clear_cpu, data); + if (sscanf(cmd, "read %d", &cpu) == 1) { + salinfo_log_new_read(cpu, data); + } else if (sscanf(cmd, "clear %d", &cpu) == 1) { + int ret; + if ((ret = salinfo_log_clear(data, cpu))) + count = ret; + } else if (sscanf(cmd, "oemdata %d %d", &cpu, &offset) == 2) { + if (data->state != STATE_LOG_RECORD && data->state != STATE_OEMDATA) + return -EINVAL; + if (offset > data->log_size - sizeof(efi_guid_t)) + return -EINVAL; + data->state = STATE_OEMDATA; + if (salinfo_platform_oemdata) { + struct salinfo_platform_oemdata_parms parms = { + .efi_guid = data->log_buffer + offset, + .oemdata = &data->oemdata, + .oemdata_size = &data->oemdata_size + }; + call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms); + if (parms.ret) + count = parms.ret; + } else + data->oemdata_size = 0; + } else + return -EINVAL; return count; } @@ -309,9 +522,8 @@ struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */ struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */ struct proc_dir_entry *dir, *entry; - struct salinfo_event *event; struct salinfo_data *data; - int i, j; + int i, j, online; salinfo_dir = proc_mkdir("sal", NULL); if (!salinfo_dir) @@ -324,6 +536,9 @@ } for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { + data = salinfo_data + i; + data->type = i; + sema_init(&data->sem, 0); dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); if (!dir) continue; @@ -331,32 +546,26 @@ entry = create_proc_entry("event", S_IRUSR, dir); if (!entry) continue; - - event = kmalloc(sizeof(*event), GFP_KERNEL); - if (!event) - continue; - memset(event, 0, sizeof(*event)); - event->type = i; - init_waitqueue_head(&event->queue); - salinfo_event[i] = event; - /* we missed any events before now */ - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - set_bit(j, &event->cpu_mask); - entry->data = event; + entry->data = data; entry->proc_fops = &salinfo_event_fops; *sdir++ = entry; entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir); if (!entry) continue; - - data = &salinfo_data[i]; - data->type = i; entry->data = data; entry->proc_fops = &salinfo_data_fops; *sdir++ = entry; + /* we missed any events before now */ + online = 0; + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) { + set_bit(j, &data->cpu_event); + ++online; + } + sema_init(&data->sem, online); + *sdir++ = dir; } @@ -365,17 +574,6 @@ return 0; } -static void __exit -salinfo_exit(void) -{ - int i = 0; - - for (i = 0; i < ARRAY_SIZE(salinfo_proc_entries); i++) { - if (salinfo_proc_entries[i]) - remove_proc_entry (salinfo_proc_entries[i]->name, NULL); - } -} - /* * 'data' contains an integer that corresponds to the feature we're * testing @@ -385,8 +583,6 @@ { int len = 0; - MOD_INC_USE_COUNT; - len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n"); if (len <= off+count) *eof = 1; @@ -397,10 +593,7 @@ if (len>count) len = count; if (len<0) len = 0; - MOD_DEC_USE_COUNT; - return len; } module_init(salinfo_init); -module_exit(salinfo_exit); diff -urN linux-2.4.24/arch/ia64/kernel/setup.c linux-2.4.25/arch/ia64/kernel/setup.c --- linux-2.4.24/arch/ia64/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM # include @@ -64,6 +65,7 @@ struct cpuinfo_ia64 *_cpu_data[NR_CPUS]; #else struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section"))); + mmu_gather_t mmu_gathers[NR_CPUS]; #endif unsigned long ia64_cycles_per_usec; @@ -376,7 +378,6 @@ saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; /* for safety */ efi_init(); - find_memory(); #ifdef CONFIG_ACPI_BOOT /* Initialize the ACPI boot-time table parser */ @@ -392,6 +393,7 @@ #endif /* CONFIG_APCI_BOOT */ iomem_resource.end = ~0UL; /* FIXME probably belongs elsewhere */ + find_memory(); #if 0 /* XXX fix me */ @@ -659,6 +661,7 @@ _cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data; #else my_cpu_data = cpu_data(smp_processor_id()); + my_cpu_data->mmu_gathers = &mmu_gathers[smp_processor_id()]; #endif /* diff -urN linux-2.4.24/arch/ia64/kernel/sys_ia64.c linux-2.4.25/arch/ia64/kernel/sys_ia64.c --- linux-2.4.24/arch/ia64/kernel/sys_ia64.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/kernel/sys_ia64.c 2004-02-18 05:36:30.000000000 -0800 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,10 @@ if (len > RGN_MAP_LIMIT) return -ENOMEM; +#ifdef CONFIG_HUGETLB_PAGE + if (rgn_index(addr)==REGION_HPAGE) + addr = 0; +#endif if (!addr) addr = TASK_UNMAPPED_BASE; diff -urN linux-2.4.24/arch/ia64/kernel/time.c linux-2.4.25/arch/ia64/kernel/time.c --- linux-2.4.24/arch/ia64/kernel/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/ia64/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -93,7 +93,6 @@ * it! */ tv->tv_usec -= gettimeoffset(); - tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); while (tv->tv_usec < 0) { tv->tv_usec += 1000000; diff -urN linux-2.4.24/arch/ia64/kernel/traps.c linux-2.4.25/arch/ia64/kernel/traps.c --- linux-2.4.24/arch/ia64/kernel/traps.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/kernel/traps.c 2004-02-18 05:36:30.000000000 -0800 @@ -221,10 +221,6 @@ unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long stack) { - struct pt_regs *regs = (struct pt_regs *) &stack; - - printk(KERN_DEBUG "%s(%d): \n", current->comm, current->pid, - regs->r15, arg0, arg1, arg2, arg3); return -ENOSYS; } diff -urN linux-2.4.24/arch/ia64/lib/Makefile linux-2.4.25/arch/ia64/lib/Makefile --- linux-2.4.24/arch/ia64/lib/Makefile 2003-06-13 07:51:29.000000000 -0700 +++ linux-2.4.25/arch/ia64/lib/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -18,6 +18,7 @@ obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o +obj-$(CONFIG_MD_RAID5) += xor.o IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o diff -urN linux-2.4.24/arch/ia64/lib/xor.S linux-2.4.25/arch/ia64/lib/xor.S --- linux-2.4.24/arch/ia64/lib/xor.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ia64/lib/xor.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,184 @@ +/* + * arch/ia64/lib/xor.S + * + * Optimized RAID-5 checksumming functions for IA-64. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * (for example /usr/src/linux/COPYING); if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +GLOBAL_ENTRY(xor_ia64_2) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 3, 0, 13, 16 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov ar.lc = in0 + mov pr.rot = 1 << 16 + ;; + .rotr s1[6+1], s2[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[6+1])st8.nta [r8] = d[1], 8 + nop.f 0 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_2) + +GLOBAL_ENTRY(xor_ia64_3) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 4, 0, 20, 24 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] + ;; +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], s3[6] + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_3) + +GLOBAL_ENTRY(xor_ia64_4) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 5, 0, 27, 32 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + mov r19 = in4 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[0]) ld8.nta s4[0] = [r19], 8 +(p[6]) xor r20 = s3[6], s4[6] + ;; +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], r20 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_4) + +GLOBAL_ENTRY(xor_ia64_5) + .prologue + .fframe 0 + .save ar.pfs, r31 + alloc r31 = ar.pfs, 6, 0, 34, 40 + .save ar.lc, r30 + mov r30 = ar.lc + .save pr, r29 + mov r29 = pr + ;; + .body + mov r8 = in1 + mov ar.ec = 6 + 2 + shr in0 = in0, 3 + ;; + adds in0 = -1, in0 + mov r16 = in1 + mov r17 = in2 + ;; + mov r18 = in3 + mov ar.lc = in0 + mov pr.rot = 1 << 16 + mov r19 = in4 + mov r20 = in5 + ;; + .rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2] + .rotp p[6+2] +0: +(p[0]) ld8.nta s1[0] = [r16], 8 +(p[0]) ld8.nta s2[0] = [r17], 8 +(p[6]) xor d[0] = s1[6], s2[6] +(p[0]) ld8.nta s3[0] = [r18], 8 +(p[0]) ld8.nta s4[0] = [r19], 8 +(p[6]) xor r21 = s3[6], s4[6] + ;; +(p[0]) ld8.nta s5[0] = [r20], 8 +(p[6+1])st8.nta [r8] = d[1], 8 +(p[6]) xor d[0] = d[0], r21 + ;; +(p[6]) xor d[0] = d[0], s5[6] + nop.f 0 + br.ctop.dptk.few 0b + ;; + mov ar.lc = r30 + mov pr = r29, -1 + br.ret.sptk.few rp +END(xor_ia64_5) diff -urN linux-2.4.24/arch/ia64/mm/Makefile linux-2.4.25/arch/ia64/mm/Makefile --- linux-2.4.24/arch/ia64/mm/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/mm/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -14,5 +14,6 @@ obj-y := init.o fault.o tlb.o extable.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/ia64/mm/hugetlbpage.c linux-2.4.25/arch/ia64/mm/hugetlbpage.c --- linux-2.4.24/arch/ia64/mm/hugetlbpage.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ia64/mm/hugetlbpage.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,513 @@ +/* + * IA-64 Huge TLB Page Support for Kernel. + * + * Copyright (C) 2002, Rohit Seth + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define TASK_HPAGE_BASE (REGION_HPAGE << REGION_SHIFT) + +static long htlbpagemem; +int htlbpage_max; +static long htlbzone_pages; + +struct vm_operations_struct hugetlb_vm_ops; +static LIST_HEAD(htlbpage_freelist); +static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; + +static struct page *alloc_hugetlb_page(void) +{ + int i; + struct page *page; + + spin_lock(&htlbpage_lock); + if (list_empty(&htlbpage_freelist)) { + spin_unlock(&htlbpage_lock); + return NULL; + } + + page = list_entry(htlbpage_freelist.next, struct page, list); + list_del(&page->list); + htlbpagemem--; + spin_unlock(&htlbpage_lock); + set_page_count(page, 1); + for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) + clear_highpage(&page[i]); + return page; +} + +static pte_t * +huge_pte_alloc (struct mm_struct *mm, unsigned long addr) +{ + unsigned long taddr = htlbpage_to_page(addr); + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte = NULL; + + pgd = pgd_offset(mm, taddr); + pmd = pmd_alloc(mm, pgd, taddr); + if (pmd) + pte = pte_alloc(mm, pmd, taddr); + return pte; +} + +static pte_t * +huge_pte_offset (struct mm_struct *mm, unsigned long addr) +{ + unsigned long taddr = htlbpage_to_page(addr); + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte = NULL; + + pgd = pgd_offset(mm, taddr); + pmd = pmd_offset(pgd, taddr); + pte = pte_offset(pmd, taddr); + return pte; +} + +#define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; } + +static void +set_huge_pte (struct mm_struct *mm, struct vm_area_struct *vma, + struct page *page, pte_t * page_table, int write_access) +{ + pte_t entry; + + mm->rss += (HPAGE_SIZE / PAGE_SIZE); + if (write_access) { + entry = + pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); + } else + entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); + entry = pte_mkyoung(entry); + mk_pte_huge(entry); + set_pte(page_table, entry); + return; +} +/* + * This function checks for proper alignment of input addr and len parameters. + */ +int is_aligned_hugepage_range(unsigned long addr, unsigned long len) +{ + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) + return -EINVAL; + if (REGION_NUMBER(addr) != REGION_HPAGE) + return -EINVAL; + + return 0; +} +/* This function checks if the address and address+len falls out of HugeTLB region. It + * return -EINVAL if any part of address range falls in HugeTLB region. + */ +int is_invalid_hugepage_range(unsigned long addr, unsigned long len) +{ + if (REGION_NUMBER(addr) == REGION_HPAGE) + return -EINVAL; + if (REGION_NUMBER(addr+len) == REGION_HPAGE) + return -EINVAL; + return 0; +} + +/* + * Same as generic free_pgtables(), except constant PGDIR_* and pgd_offset + * are hugetlb region specific. + */ +void hugetlb_free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev, + unsigned long start, unsigned long end) +{ + unsigned long first = start & HUGETLB_PGDIR_MASK; + unsigned long last = end + HUGETLB_PGDIR_SIZE - 1; + unsigned long start_index, end_index; + + if (!prev) { + prev = mm->mmap; + if (!prev) + goto no_mmaps; + if (prev->vm_end > start) { + if (last > prev->vm_start) + last = prev->vm_start; + goto no_mmaps; + } + } + for (;;) { + struct vm_area_struct *next = prev->vm_next; + + if (next) { + if (next->vm_start < start) { + prev = next; + continue; + } + if (last > next->vm_start) + last = next->vm_start; + } + if (prev->vm_end > first) + first = prev->vm_end + HUGETLB_PGDIR_SIZE - 1; + break; + } +no_mmaps: + if (last < first) + return; + /* + * If the PGD bits are not consecutive in the virtual address, the + * old method of shifting the VA >> by PGDIR_SHIFT doesn't work. + */ + start_index = pgd_index(htlbpage_to_page(first)); + end_index = pgd_index(htlbpage_to_page(last)); + if (end_index > start_index) { + clear_page_tables(mm, start_index, end_index - start_index); + flush_tlb_pgtables(mm, first & HUGETLB_PGDIR_MASK, + last & HUGETLB_PGDIR_MASK); + } +} + +int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, + struct vm_area_struct *vma) +{ + pte_t *src_pte, *dst_pte, entry; + struct page *ptepage; + unsigned long addr = vma->vm_start; + unsigned long end = vma->vm_end; + + while (addr < end) { + dst_pte = huge_pte_alloc(dst, addr); + if (!dst_pte) + goto nomem; + src_pte = huge_pte_offset(src, addr); + entry = *src_pte; + ptepage = pte_page(entry); + get_page(ptepage); + set_pte(dst_pte, entry); + dst->rss += (HPAGE_SIZE / PAGE_SIZE); + addr += HPAGE_SIZE; + } + return 0; +nomem: + return -ENOMEM; +} + +int +follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, + struct page **pages, struct vm_area_struct **vmas, + unsigned long *st, int *length, int i) +{ + pte_t *ptep, pte; + unsigned long start = *st; + unsigned long pstart; + int len = *length; + struct page *page; + + do { + pstart = start; + ptep = huge_pte_offset(mm, start); + pte = *ptep; + +back1: + page = pte_page(pte); + if (pages) { + page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); + pages[i] = page; + } + if (vmas) + vmas[i] = vma; + i++; + len--; + start += PAGE_SIZE; + if (((start & HPAGE_MASK) == pstart) && len && + (start < vma->vm_end)) + goto back1; + } while (len && start < vma->vm_end); + *length = len; + *st = start; + return i; +} + +void free_huge_page(struct page *page) +{ + BUG_ON(page_count(page)); + BUG_ON(page->mapping); + + INIT_LIST_HEAD(&page->list); + + spin_lock(&htlbpage_lock); + list_add(&page->list, &htlbpage_freelist); + htlbpagemem++; + spin_unlock(&htlbpage_lock); +} + +void huge_page_release(struct page *page) +{ + if (!put_page_testzero(page)) + return; + + free_huge_page(page); +} + +void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long address; + pte_t *pte; + struct page *page; + + BUG_ON(start & (HPAGE_SIZE - 1)); + BUG_ON(end & (HPAGE_SIZE - 1)); + + for (address = start; address < end; address += HPAGE_SIZE) { + pte = huge_pte_offset(mm, address); + if (pte_none(*pte)) + continue; + page = pte_page(*pte); + huge_page_release(page); + pte_clear(pte); + } + mm->rss -= (end - start) >> PAGE_SHIFT; + flush_tlb_range(mm, start, end); +} + +void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length) +{ + struct mm_struct *mm = vma->vm_mm; + spin_lock(&mm->page_table_lock); + unmap_hugepage_range(vma, start, start + length); + spin_unlock(&mm->page_table_lock); +} + +int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) +{ + struct mm_struct *mm = current->mm; + struct inode *inode = mapping->host; + unsigned long addr; + int ret = 0; + + BUG_ON(vma->vm_start & ~HPAGE_MASK); + BUG_ON(vma->vm_end & ~HPAGE_MASK); + + spin_lock(&mm->page_table_lock); + for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { + unsigned long idx; + pte_t *pte = huge_pte_alloc(mm, addr); + struct page *page; + + if (!pte) { + ret = -ENOMEM; + goto out; + } + if (!pte_none(*pte)) + continue; + + idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); + page = find_get_page(mapping, idx); + if (!page) { + /* charge the fs quota first */ + if (hugetlb_get_quota(mapping)) { + ret = -ENOMEM; + goto out; + } + page = alloc_hugetlb_page(); + if (!page) { + hugetlb_put_quota(mapping); + ret = -ENOMEM; + goto out; + } + add_to_page_cache(page, mapping, idx); + unlock_page(page); + } + set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); + } +out: + spin_unlock(&mm->page_table_lock); + return ret; +} + +unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) +{ + struct vm_area_struct *vmm; + + if (len > RGN_MAP_LIMIT) + return -ENOMEM; + if (len & ~HPAGE_MASK) + return -EINVAL; + /* This code assumes that REGION_HPAGE != 0. */ + if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE - 1))) + addr = TASK_HPAGE_BASE; + else + addr = COLOR_HALIGN(addr); + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (REGION_OFFSET(addr) + len > RGN_MAP_LIMIT) + return -ENOMEM; + if (!vmm || (addr + len) <= vmm->vm_start) + return addr; + addr = COLOR_HALIGN(vmm->vm_end); + } +} +void update_and_free_page(struct page *page) +{ + int j; + struct page *map; + + map = page; + htlbzone_pages--; + for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { + map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced | + 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved); + set_page_count(map, 0); + map++; + } + set_page_count(page, 1); + __free_pages(page, HUGETLB_PAGE_ORDER); +} + +int try_to_free_low(int count) +{ + struct list_head *p; + struct page *page, *map; + + map = NULL; + spin_lock(&htlbpage_lock); + list_for_each(p, &htlbpage_freelist) { + if (map) { + list_del(&map->list); + update_and_free_page(map); + htlbpagemem--; + map = NULL; + if (++count == 0) + break; + } + page = list_entry(p, struct page, list); + if ((page_zone(page))->name[0] != 'H') //Look for non-Highmem zones. + map = page; + } + if (map) { + list_del(&map->list); + update_and_free_page(map); + htlbpagemem--; + count++; + } + spin_unlock(&htlbpage_lock); + return count; +} + +int set_hugetlb_mem_size(int count) +{ + int j, lcount; + struct page *page, *map; + + if (count < 0) + lcount = count; + else + lcount = count - htlbzone_pages; + + if (lcount == 0) + return (int)htlbzone_pages; + if (lcount > 0) { /* Increase the mem size. */ + while (lcount--) { + page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); + if (page == NULL) + break; + map = page; + for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { + SetPageReserved(map); + map++; + } + spin_lock(&htlbpage_lock); + list_add(&page->list, &htlbpage_freelist); + htlbpagemem++; + htlbzone_pages++; + spin_unlock(&htlbpage_lock); + } + return (int) htlbzone_pages; + } + /* Shrink the memory size. */ + lcount = try_to_free_low(lcount); + while (lcount++ < 0) { + page = alloc_hugetlb_page(); + if (page == NULL) + break; + spin_lock(&htlbpage_lock); + update_and_free_page(page); + spin_unlock(&htlbpage_lock); + } + return (int) htlbzone_pages; +} + +int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length) +{ + proc_dointvec(table, write, file, buffer, length); + htlbpage_max = set_hugetlb_mem_size(htlbpage_max); + return 0; +} + +static int __init hugetlb_setup(char *s) +{ + if (sscanf(s, "%d", &htlbpage_max) <= 0) + htlbpage_max = 0; + return 1; +} +__setup("hugepages=", hugetlb_setup); + +static int __init hugetlb_init(void) +{ + int i, j; + struct page *page; + + for (i = 0; i < htlbpage_max; ++i) { + page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); + if (!page) + break; + for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j) + SetPageReserved(&page[j]); + spin_lock(&htlbpage_lock); + list_add(&page->list, &htlbpage_freelist); + spin_unlock(&htlbpage_lock); + } + htlbpage_max = htlbpagemem = htlbzone_pages = i; + printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem); + return 0; +} +module_init(hugetlb_init); + +int hugetlb_report_meminfo(char *buf) +{ + return sprintf(buf, + "HugePages_Total: %5lu\n" + "HugePages_Free: %5lu\n" + "Hugepagesize: %5lu kB\n", + htlbzone_pages, + htlbpagemem, + HPAGE_SIZE/1024); +} + +int is_hugepage_mem_enough(size_t size) +{ + if (size > (htlbpagemem << HPAGE_SHIFT)) + return 0; + return 1; +} + +static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused) +{ + BUG(); + return NULL; +} + +struct vm_operations_struct hugetlb_vm_ops = { + .nopage = hugetlb_nopage, +}; diff -urN linux-2.4.24/arch/ia64/mm/init.c linux-2.4.25/arch/ia64/mm/init.c --- linux-2.4.24/arch/ia64/mm/init.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -28,9 +28,7 @@ #include #include #include -#include - -mmu_gather_t mmu_gathers[NR_CPUS]; +#include /* References to section boundaries: */ extern char _stext, _etext, _edata, __init_begin, __init_end; @@ -284,6 +282,10 @@ { unsigned long psr, rid, pta, impl_va_bits; extern void __init tlb_init (void); +#ifdef CONFIG_IA64_MCA + int cpu; +#endif + #ifdef CONFIG_DISABLE_VHPT # define VHPT_ENABLE_BIT 0 #else @@ -354,6 +356,22 @@ ia64_set_pta(pta | (0 << 8) | (vmlpt_bits << 2) | VHPT_ENABLE_BIT); ia64_tlb_init(); + +#ifdef CONFIG_IA64_MCA + cpu = smp_processor_id(); + + /* mca handler uses cr.lid as key to pick the right entry */ + ia64_mca_tlb_list[cpu].cr_lid = ia64_get_lid(); + + /* insert this percpu data information into our list for MCA recovery purposes */ + ia64_mca_tlb_list[cpu].percpu_paddr = pte_val(mk_pte_phys(__pa(my_cpu_data), PAGE_KERNEL)); + /* Also save per-cpu tlb flush recipe for use in physical mode mca handler */ + ia64_mca_tlb_list[cpu].ptce_base = local_cpu_data->ptce_base; + ia64_mca_tlb_list[cpu].ptce_count[0] = local_cpu_data->ptce_count[0]; + ia64_mca_tlb_list[cpu].ptce_count[1] = local_cpu_data->ptce_count[1]; + ia64_mca_tlb_list[cpu].ptce_stride[0] = local_cpu_data->ptce_stride[0]; + ia64_mca_tlb_list[cpu].ptce_stride[1] = local_cpu_data->ptce_stride[1]; +#endif } static int @@ -488,7 +506,8 @@ { char byte; - return __get_user(byte, (char *) page) == 0; + return (__get_user(byte, (char *) page) == 0) + && (__get_user(byte, (char *) (page + 1) - 1) == 0); } #define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1)) diff -urN linux-2.4.24/arch/ia64/mm/tlb.c linux-2.4.25/arch/ia64/mm/tlb.c --- linux-2.4.24/arch/ia64/mm/tlb.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/mm/tlb.c 2004-02-18 05:36:30.000000000 -0800 @@ -75,7 +75,7 @@ * and because interrupts are disabled during context switch. */ for (i = 0; i < NR_CPUS; ++i) - if (i != smp_processor_id()) + if (cpu_online(i) && (i != smp_processor_id())) cpu_data(i)->need_tlb_flush = 1; local_flush_tlb_all(); } diff -urN linux-2.4.24/arch/ia64/tools/Makefile linux-2.4.25/arch/ia64/tools/Makefile --- linux-2.4.24/arch/ia64/tools/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/ia64/tools/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -33,7 +33,7 @@ comma := , -print_offsets: print_offsets.c FORCE_RECOMPILE +print_offsets: emptyoffsets print_offsets.c FORCE_RECOMPILE $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) print_offsets.c -o $@ FORCE_RECOMPILE: @@ -43,9 +43,20 @@ offsets.h: print_offsets.s $(AWK) -f print_offsets.awk $^ > $@ -print_offsets.s: print_offsets.c +print_offsets.s: emptyoffsets print_offsets.c $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S print_offsets.c -o $@ endif +# +# The TARGET offsets.h is included by ptrace.h, which is included by +# print_offsets.c, so can't compile print_offsets.c to create offsets.h +# until we already have offsets.h. Break the chicken-and-egg cycle by +# creating a dummy offsets.h with sufficient define's to bootstrap +# the first compilation of print_offsets.c. +# + +emptyoffsets: + test -f ${TARGET} || echo '#define IA64_TASK_THREAD_OFFSET 0' > ${TARGET} + .PHONY: all modules modules_install diff -urN linux-2.4.24/arch/ia64/tools/print_offsets.c linux-2.4.25/arch/ia64/tools/print_offsets.c --- linux-2.4.24/arch/ia64/tools/print_offsets.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ia64/tools/print_offsets.c 2004-02-18 05:36:30.000000000 -0800 @@ -21,6 +21,7 @@ #include #include #include +#include #include "../kernel/sigframe.h" @@ -179,6 +180,7 @@ { "IA64_CPU_IRQ_COUNT_OFFSET", offsetof (struct cpuinfo_ia64, irq_stat.f.irq_count) }, { "IA64_CPU_BH_COUNT_OFFSET", offsetof (struct cpuinfo_ia64, irq_stat.f.bh_count) }, { "IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET",offsetof (struct cpuinfo_ia64, phys_stacked_size_p8)}, + { "IA64_MCA_TLB_INFO_SIZE", sizeof (struct ia64_mca_tlb_info) }, }; static const char *tabs = "\t\t\t\t\t\t\t\t\t\t"; diff -urN linux-2.4.24/arch/m68k/amiga/config.c linux-2.4.25/arch/m68k/amiga/config.c --- linux-2.4.24/arch/m68k/amiga/config.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/m68k/amiga/config.c 2004-02-18 05:36:30.000000000 -0800 @@ -877,7 +877,7 @@ savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; - savekmsg->magicptr = virt_to_phys(savekmsg); + savekmsg->magicptr = ZTWO_PADDR(savekmsg); savekmsg->size = 0; } diff -urN linux-2.4.24/arch/m68k/config.in linux-2.4.25/arch/m68k/config.in --- linux-2.4.24/arch/m68k/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/m68k/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -185,7 +185,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -227,7 +226,7 @@ if [ "$CONFIG_AMIGA" = "y" ]; then dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4000T SCSI support (EXPERIMENTAL)' CONFIG_A4000T_SCSI + bool 'Amiga NCR53c710 SCSI support (EXPERIMENTAL)' CONFIG_SCSI_AMIGA7XX fi fi if [ "$CONFIG_ZORRO" = "y" ]; then @@ -239,12 +238,8 @@ dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4091 SCSI support (EXPERIMENTAL)' CONFIG_A4091_SCSI - bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI - bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI -# bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI fi fi if [ "$CONFIG_ATARI" = "y" ]; then diff -urN linux-2.4.24/arch/m68k/defconfig linux-2.4.25/arch/m68k/defconfig --- linux-2.4.24/arch/m68k/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/m68k/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -124,7 +124,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/m68k/kernel/m68k_ksyms.c linux-2.4.25/arch/m68k/kernel/m68k_ksyms.c --- linux-2.4.24/arch/m68k/kernel/m68k_ksyms.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/m68k/kernel/m68k_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include asmlinkage long long __ashldi3 (long long, int); asmlinkage long long __ashrdi3 (long long, int); @@ -47,6 +49,9 @@ EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(kernel_set_cachemode); +#ifndef mm_cachebits +EXPORT_SYMBOL(mm_cachebits); +#endif #endif /* !CONFIG_SUN3 */ EXPORT_SYMBOL(m68k_debug_device); EXPORT_SYMBOL(mach_hwclk); @@ -65,6 +70,8 @@ #ifdef CONFIG_VME EXPORT_SYMBOL(vme_brdtype); #endif +EXPORT_SYMBOL(hwreg_present); +EXPORT_SYMBOL(hwreg_write); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); diff -urN linux-2.4.24/arch/m68k/kernel/traps.c linux-2.4.25/arch/m68k/kernel/traps.c --- linux-2.4.24/arch/m68k/kernel/traps.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/m68k/kernel/traps.c 2004-02-18 05:36:30.000000000 -0800 @@ -446,7 +446,7 @@ /* sun3 version of bus_error030 */ -extern inline void bus_error030 (struct frame *fp) +static inline void bus_error030(struct frame *fp) { unsigned char buserr_type = sun3_get_buserr (); unsigned long addr, errorcode; @@ -574,12 +574,9 @@ unsigned short mmusr; unsigned long addr, errorcode; unsigned short ssw = fp->un.fmtb.ssw; - int user_space_fault = 1; #if DEBUG unsigned long desc; -#endif -#if DEBUG printk ("pid = %x ", current->pid); printk ("SSW=%#06x ", ssw); @@ -596,128 +593,116 @@ space_names[ssw & DFC], fp->ptregs.pc); #endif - if (fp->ptregs.sr & PS_S) { - /* kernel fault must be a data fault to user space */ - if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { - /* instruction fault or kernel data fault! */ - if (ssw & (FC | FB)) - printk ("Instruction fault at %#010lx\n", - fp->ptregs.pc); - if (ssw & DF) { - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", - ssw & RW ? "read" : "write", - fp->un.fmtb.daddr, - space_names[ssw & DFC], fp->ptregs.pc); - } - printk ("BAD KERNEL BUSERR\n"); - die_if_kernel("Oops",&fp->ptregs,0); - force_sig(SIGKILL, current); - return; - } - } else { - /* user fault */ - if (!(ssw & (FC | FB)) && !(ssw & DF)) - /* not an instruction fault or data fault! BAD */ - panic ("USER BUSERR w/o instruction or data fault"); - user_space_fault = 1; -#if DEBUG - printk("User space bus-error\n"); -#endif - } - /* ++andreas: If a data fault and an instruction fault happen at the same time map in both pages. */ /* First handle the data fault, if any. */ - if (ssw & DF) - { - addr = fp->un.fmtb.daddr; + if (ssw & DF) { + addr = fp->un.fmtb.daddr; - mmusr = MMU_I; - if (user_space_fault) { #if DEBUG - asm volatile ("ptestr #1,%2@,#7,%0\n\t" - "pmove %/psr,%1@" - : "=a&" (desc) - : "a" (&temp), "a" (addr)); + asm volatile ("ptestr %3,%2@,#7,%0\n\t" + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr), "d" (ssw)); #else - asm volatile ("ptestr #1,%1@,#7\n\t" - "pmove %/psr,%0@" - : : "a" (&temp), "a" (addr)); -#endif - mmusr = temp; - } - -#if DEBUG - printk ("mmusr is %#x for addr %#lx in task %p\n", - mmusr, addr, current); - printk ("descriptor address is %#lx, contents %#lx\n", - __va(desc), *(unsigned long *)__va(desc)); + asm volatile ("ptestr %2,%1@,#7\n\t" + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr), "d" (ssw)); #endif + mmusr = temp; - errorcode = (mmusr & MMU_I) ? 0 : 1; - if (!(ssw & RW) || (ssw & RM)) - errorcode |= 2; - - if (mmusr & (MMU_I | MMU_WP)) { - /* Don't try to do anything further if an exception was - handled. */ - if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) +#if DEBUG + printk("mmusr is %#x for addr %#lx in task %p\n", + mmusr, addr, current); + printk("descriptor address is %#lx, contents %#lx\n", + __va(desc), *(unsigned long *)__va(desc)); +#endif + + errorcode = (mmusr & MMU_I) ? 0 : 1; + if (!(ssw & RW) || (ssw & RM)) + errorcode |= 2; + + if (mmusr & (MMU_I | MMU_WP)) { + if (ssw & 4) { + printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", + ssw & RW ? "read" : "write", + fp->un.fmtb.daddr, + space_names[ssw & DFC], fp->ptregs.pc); + goto buserr; + } + /* Don't try to do anything further if an exception was + handled. */ + if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) + return; + } else if (!(mmusr & MMU_I)) { + /* propably a 020 cas fault */ + if (!(ssw & RM)) + printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); + } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { + printk("invalid %s access at %#lx from pc %#lx\n", + !(ssw & RW) ? "write" : "read", addr, + fp->ptregs.pc); + die_if_kernel("Oops",&fp->ptregs,mmusr); + force_sig(SIGSEGV, current); return; - } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { - printk ("invalid %s access at %#lx from pc %#lx\n", - !(ssw & RW) ? "write" : "read", addr, - fp->ptregs.pc); - die_if_kernel("Oops",&fp->ptregs,mmusr); - force_sig(SIGSEGV, current); - return; - } else { + } else { #if 0 - static volatile long tlong; + static volatile long tlong; #endif - printk ("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", - !(ssw & RW) ? "write" : "read", addr, - fp->ptregs.pc, ssw); - asm volatile ("ptestr #1,%1@,#0\n\t" - "pmove %/psr,%0@" - : /* no outputs */ - : "a" (&temp), "a" (addr)); - mmusr = temp; + printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", + !(ssw & RW) ? "write" : "read", addr, + fp->ptregs.pc, ssw); + asm volatile ("ptestr #1,%1@,#0\n\t" + "pmove %%psr,%0@" + : /* no outputs */ + : "a" (&temp), "a" (addr)); + mmusr = temp; - printk ("level 0 mmusr is %#x\n", mmusr); + printk ("level 0 mmusr is %#x\n", mmusr); #if 0 - asm volatile ("pmove %/tt0,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt0 is %#lx, ", tlong); - asm volatile ("pmove %/tt1,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt1 is %#lx\n", tlong); + asm volatile ("pmove %%tt0,%0@" + : /* no outputs */ + : "a" (&tlong)); + printk("tt0 is %#lx, ", tlong); + asm volatile ("pmove %%tt1,%0@" + : /* no outputs */ + : "a" (&tlong)); + printk("tt1 is %#lx\n", tlong); #endif #if DEBUG - printk("Unknown SIGSEGV - 1\n"); + printk("Unknown SIGSEGV - 1\n"); #endif - die_if_kernel("Oops",&fp->ptregs,mmusr); - force_sig(SIGSEGV, current); - return; - } - - /* setup an ATC entry for the access about to be retried */ - if (!(ssw & RW)) - asm volatile ("ploadw %1,%0@" : /* no outputs */ - : "a" (addr), "d" (ssw)); - else - asm volatile ("ploadr %1,%0@" : /* no outputs */ - : "a" (addr), "d" (ssw)); - } + die_if_kernel("Oops",&fp->ptregs,mmusr); + force_sig(SIGSEGV, current); + return; + } + + /* setup an ATC entry for the access about to be retried */ + if (!(ssw & RW) || (ssw & RM)) + asm volatile ("ploadw %1,%0@" : /* no outputs */ + : "a" (addr), "d" (ssw)); + else + asm volatile ("ploadr %1,%0@" : /* no outputs */ + : "a" (addr), "d" (ssw)); + } /* Now handle the instruction fault. */ if (!(ssw & (FC|FB))) return; + if (fp->ptregs.sr & PS_S) { + printk("Instruction fault at %#010lx\n", + fp->ptregs.pc); + buserr: + printk ("BAD KERNEL BUSERR\n"); + die_if_kernel("Oops",&fp->ptregs,0); + force_sig(SIGKILL, current); + return; + } + /* get the fault address */ if (fp->ptregs.format == 10) addr = fp->ptregs.pc + 4; @@ -731,21 +716,18 @@ should still create the ATC entry. */ goto create_atc_entry; - mmusr = MMU_I; - if (user_space_fault) { #if DEBUG - asm volatile ("ptestr #1,%2@,#7,%0\n\t" - "pmove %/psr,%1@" - : "=a&" (desc) - : "a" (&temp), "a" (addr)); + asm volatile ("ptestr #1,%2@,#7,%0\n\t" + "pmove %%psr,%1@" + : "=a&" (desc) + : "a" (&temp), "a" (addr)); #else - asm volatile ("ptestr #1,%1@,#7\n\t" - "pmove %/psr,%0@" - : : "a" (&temp), "a" (addr)); + asm volatile ("ptestr #1,%1@,#7\n\t" + "pmove %%psr,%0@" + : : "a" (&temp), "a" (addr)); #endif - mmusr = temp; - } - + mmusr = temp; + #ifdef DEBUG printk ("mmusr is %#x for addr %#lx in task %p\n", mmusr, addr, current); diff -urN linux-2.4.24/arch/m68k/mac/mac_ksyms.c linux-2.4.25/arch/m68k/mac/mac_ksyms.c --- linux-2.4.24/arch/m68k/mac/mac_ksyms.c 1999-09-04 13:06:41.000000000 -0700 +++ linux-2.4.25/arch/m68k/mac/mac_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,8 +1,7 @@ #include -#include -#include - -/* Says whether we're using A/UX interrupts or not */ -extern int via_alt_mapping; +#include +#include +#include EXPORT_SYMBOL(via_alt_mapping); +EXPORT_SYMBOL(macintosh_config); diff -urN linux-2.4.24/arch/m68k/mac/misc.c linux-2.4.25/arch/m68k/mac/misc.c --- linux-2.4.24/arch/m68k/mac/misc.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/m68k/mac/misc.c 2004-02-18 05:36:30.000000000 -0800 @@ -39,6 +39,7 @@ extern struct mac_booter_data mac_bi_data; static void (*rom_reset)(void); +#ifdef CONFIG_ADB /* * Return the current time as the number of seconds since January 1, 1904. */ @@ -103,6 +104,7 @@ (offset >> 8) & 0xFF, offset & 0xFF, data); } +#endif /* CONFIG_ADB */ /* * VIA PRAM/RTC access routines @@ -357,7 +359,11 @@ macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2 || macintosh_config->adb_type == MAC_ADB_CUDA) { +#ifdef CONFIG_ADB func = adb_read_pram; +#else + return; +#endif } else { func = via_read_pram; } @@ -375,7 +381,11 @@ macintosh_config->adb_type == MAC_ADB_PB1 || macintosh_config->adb_type == MAC_ADB_PB2 || macintosh_config->adb_type == MAC_ADB_CUDA) { +#ifdef CONFIG_ADB func = adb_write_pram; +#else + return; +#endif } else { func = via_write_pram; } @@ -602,12 +612,16 @@ if (!op) { /* read */ if (macintosh_config->adb_type == MAC_ADB_II) { now = via_read_time(); - } else if ((macintosh_config->adb_type == MAC_ADB_IISI) || + } else +#ifdef CONFIG_ADB + if ((macintosh_config->adb_type == MAC_ADB_IISI) || (macintosh_config->adb_type == MAC_ADB_PB1) || (macintosh_config->adb_type == MAC_ADB_PB2) || (macintosh_config->adb_type == MAC_ADB_CUDA)) { now = adb_read_time(); - } else if (macintosh_config->adb_type == MAC_ADB_IOP) { + } else +#endif + if (macintosh_config->adb_type == MAC_ADB_IOP) { now = via_read_time(); } else { now = 0; diff -urN linux-2.4.24/arch/m68k/math-emu/multi_arith.h linux-2.4.25/arch/m68k/math-emu/multi_arith.h --- linux-2.4.24/arch/m68k/math-emu/multi_arith.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/m68k/math-emu/multi_arith.h 2004-02-18 05:36:30.000000000 -0800 @@ -38,17 +38,14 @@ /* Convenience functions to stuff various integer values into int128s */ -extern inline void zero128(int128 a) +static inline void zero128(int128 a) { a[LSW128] = a[NLSW128] = a[NMSW128] = a[MSW128] = 0; } /* Human-readable word order in the arguments */ -extern inline void set128(unsigned int i3, - unsigned int i2, - unsigned int i1, - unsigned int i0, - int128 a) +static inline void set128(unsigned int i3, unsigned int i2, unsigned int i1, + unsigned int i0, int128 a) { a[LSW128] = i0; a[NLSW128] = i1; @@ -57,21 +54,19 @@ } /* Convenience functions (for testing as well) */ -extern inline void int64_to_128(unsigned long long src, - int128 dest) +static inline void int64_to_128(unsigned long long src, int128 dest) { dest[LSW128] = (unsigned int) src; dest[NLSW128] = src >> 32; dest[NMSW128] = dest[MSW128] = 0; } -extern inline void int128_to_64(const int128 src, - unsigned long long *dest) +static inline void int128_to_64(const int128 src, unsigned long long *dest) { *dest = src[LSW128] | (long long) src[NLSW128] << 32; } -extern inline void put_i128(const int128 a) +static inline void put_i128(const int128 a) { printk("%08x %08x %08x %08x\n", a[MSW128], a[NMSW128], a[NLSW128], a[LSW128]); @@ -82,7 +77,7 @@ Note that these are only good for 0 < count < 32. */ -extern inline void _lsl128(unsigned int count, int128 a) +static inline void _lsl128(unsigned int count, int128 a) { a[MSW128] = (a[MSW128] << count) | (a[NMSW128] >> (32 - count)); a[NMSW128] = (a[NMSW128] << count) | (a[NLSW128] >> (32 - count)); @@ -90,7 +85,7 @@ a[LSW128] <<= count; } -extern inline void _lsr128(unsigned int count, int128 a) +static inline void _lsr128(unsigned int count, int128 a) { a[LSW128] = (a[LSW128] >> count) | (a[NLSW128] << (32 - count)); a[NLSW128] = (a[NLSW128] >> count) | (a[NMSW128] << (32 - count)); @@ -100,7 +95,7 @@ /* Should be faster, one would hope */ -extern inline void lslone128(int128 a) +static inline void lslone128(int128 a) { asm volatile ("lsl.l #1,%0\n" "roxl.l #1,%1\n" @@ -118,7 +113,7 @@ "3"(a[MSW128])); } -extern inline void lsrone128(int128 a) +static inline void lsrone128(int128 a) { asm volatile ("lsr.l #1,%0\n" "roxr.l #1,%1\n" @@ -140,7 +135,7 @@ These bit-shift to a multiple of 32, then move whole longwords. */ -extern inline void lsl128(unsigned int count, int128 a) +static inline void lsl128(unsigned int count, int128 a) { int wordcount, i; @@ -159,7 +154,7 @@ } } -extern inline void lsr128(unsigned int count, int128 a) +static inline void lsr128(unsigned int count, int128 a) { int wordcount, i; @@ -177,18 +172,18 @@ } } -extern inline int orl128(int a, int128 b) +static inline int orl128(int a, int128 b) { b[LSW128] |= a; } -extern inline int btsthi128(const int128 a) +static inline int btsthi128(const int128 a) { return a[MSW128] & 0x80000000; } /* test bits (numbered from 0 = LSB) up to and including "top" */ -extern inline int bftestlo128(int top, const int128 a) +static inline int bftestlo128(int top, const int128 a) { int r = 0; @@ -206,7 +201,7 @@ /* Aargh. We need these because GCC is broken */ /* FIXME: do them in assembly, for goodness' sake! */ -extern inline void mask64(int pos, unsigned long long *mask) +static inline void mask64(int pos, unsigned long long *mask) { *mask = 0; @@ -218,7 +213,7 @@ HI_WORD(*mask) = (1 << (pos - 32)) - 1; } -extern inline void bset64(int pos, unsigned long long *dest) +static inline void bset64(int pos, unsigned long long *dest) { /* This conditional will be optimized away. Thanks, GCC! */ if (pos < 32) @@ -229,7 +224,7 @@ (HI_WORD(*dest)):"id"(pos - 32)); } -extern inline int btst64(int pos, unsigned long long dest) +static inline int btst64(int pos, unsigned long long dest) { if (pos < 32) return (0 != (LO_WORD(dest) & (1 << pos))); @@ -237,7 +232,7 @@ return (0 != (HI_WORD(dest) & (1 << (pos - 32)))); } -extern inline void lsl64(int count, unsigned long long *dest) +static inline void lsl64(int count, unsigned long long *dest) { if (count < 32) { HI_WORD(*dest) = (HI_WORD(*dest) << count) @@ -250,7 +245,7 @@ LO_WORD(*dest) = 0; } -extern inline void lsr64(int count, unsigned long long *dest) +static inline void lsr64(int count, unsigned long long *dest) { if (count < 32) { LO_WORD(*dest) = (LO_WORD(*dest) >> count) @@ -264,7 +259,7 @@ } #endif -extern inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) +static inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) { reg->exp += cnt; @@ -306,7 +301,7 @@ } } -extern inline int fp_overnormalize(struct fp_ext *reg) +static inline int fp_overnormalize(struct fp_ext *reg) { int shift; @@ -324,7 +319,7 @@ return shift; } -extern inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src) +static inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src) { int carry; @@ -340,7 +335,7 @@ return carry; } -extern inline int fp_addcarry(struct fp_ext *reg) +static inline int fp_addcarry(struct fp_ext *reg) { if (++reg->exp == 0x7fff) { if (reg->mant.m64) @@ -357,7 +352,8 @@ return 1; } -extern inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, struct fp_ext *src2) +static inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, + struct fp_ext *src2) { /* we assume here, gcc only insert move and a clr instr */ asm volatile ("sub.b %1,%0" : "=d,g" (dest->lowmant) @@ -407,7 +403,8 @@ carry; \ }) -extern inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1, struct fp_ext *src2) +static inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1, + struct fp_ext *src2) { union fp_mant64 temp; @@ -421,7 +418,8 @@ fp_addx96(dest, temp); } -extern inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, struct fp_ext *div) +static inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, + struct fp_ext *div) { union fp_mant128 tmp; union fp_mant64 tmp64; @@ -484,7 +482,7 @@ } #if 0 -extern inline unsigned int fp_fls128(union fp_mant128 *src) +static inline unsigned int fp_fls128(union fp_mant128 *src) { unsigned long data; unsigned int res, off; @@ -504,7 +502,7 @@ return res + off; } -extern inline void fp_shiftmant128(union fp_mant128 *src, int shift) +static inline void fp_shiftmant128(union fp_mant128 *src, int shift) { unsigned long sticky; @@ -594,7 +592,8 @@ } #endif -extern inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, int shift) +static inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, + int shift) { unsigned long tmp; @@ -639,7 +638,7 @@ } #if 0 /* old code... */ -extern inline int fls(unsigned int a) +static inline int fls(unsigned int a) { int r; @@ -649,7 +648,7 @@ } /* fls = "find last set" (cf. ffs(3)) */ -extern inline int fls128(const int128 a) +static inline int fls128(const int128 a) { if (a[MSW128]) return fls(a[MSW128]); @@ -668,12 +667,12 @@ return -1; } -extern inline int zerop128(const int128 a) +static inline int zerop128(const int128 a) { return !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); } -extern inline int nonzerop128(const int128 a) +static inline int nonzerop128(const int128 a) { return (a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); } @@ -681,7 +680,7 @@ /* Addition and subtraction */ /* Do these in "pure" assembly, because "extended" asm is unmanageable here */ -extern inline void add128(const int128 a, int128 b) +static inline void add128(const int128 a, int128 b) { /* rotating carry flags */ unsigned int carry[2]; @@ -699,7 +698,7 @@ } /* Note: assembler semantics: "b -= a" */ -extern inline void sub128(const int128 a, int128 b) +static inline void sub128(const int128 a, int128 b) { /* rotating borrow flags */ unsigned int borrow[2]; @@ -717,9 +716,7 @@ } /* Poor man's 64-bit expanding multiply */ -extern inline void mul64(unsigned long long a, - unsigned long long b, - int128 c) +static inline void mul64(unsigned long long a, unsigned long long b, int128 c) { unsigned long long acc; int128 acc128; @@ -756,7 +753,7 @@ } /* Note: unsigned */ -extern inline int cmp128(int128 a, int128 b) +static inline int cmp128(int128 a, int128 b) { if (a[MSW128] < b[MSW128]) return -1; diff -urN linux-2.4.24/arch/mips/Makefile linux-2.4.25/arch/mips/Makefile --- linux-2.4.24/arch/mips/Makefile 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -5,7 +5,7 @@ # # Copyright (C) 1994, 1995, 1996 by Ralf Baechle # DECStation modifications by Paul M. Antoine, 1996 -# Copyright (C) 2002 Maciej W. Rozycki +# Copyright (C) 2002, 2003 Maciej W. Rozycki # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -43,63 +43,124 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe -GCCFLAGS += $(call check_gcc, -mabi=32,) +GCCFLAGS += $(call check_gcc, -finline-limit=100000,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_KGDB +ifdef CONFIG_DEBUG_INFO GCCFLAGS += -g ifdef CONFIG_SB1XXX_CORELIS GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer endif endif +# +# Use: $(call set_gccflags,,,,,) +# +# , -- preferred CPU and ISA designations (may require +# recent tools) +# , -- fallback CPU and ISA designations (have to work +# with up to the oldest supported tools) +# -- an ISA designation used as an ABI selector for +# gcc versions that do not support "-mabi=32" +# (depending on the CPU type, either "mips1" or +# "mips2") +# +set_gccflags = $(shell \ +while :; do \ + cpu=$(1); isa=-$(2); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + cpu=$(3); isa=-$(4); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + break; \ +done; \ +gcc_abi=-mabi=32; gcc_cpu=$$cpu; \ +if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \ + gcc_isa=$$isa; \ +else \ + gcc_abi=; gcc_isa=-$(5); \ +fi; \ +gas_abi=-Wa,-32; gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \ +while :; do \ + for gas_opt in -Wa,-march= -Wa,-mcpu=; do \ + $(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \ + -o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \ + break; \ +done; \ +echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa) + +# # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R3000 -GCCFLAGS += -mcpu=r3000 -mips1 +GCCFLAGS += $(call set_gccflags,r3000,mips1,r3000,mips1,mips1) endif ifdef CONFIG_CPU_TX39XX -GCCFLAGS += -mcpu=r3000 -mips1 +GCCFLAGS += $(call set_gccflags,r3900,mips1,r3000,mips1,mips1) endif ifdef CONFIG_CPU_R6000 -GCCFLAGS += -mcpu=r6000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R4300 -GCCFLAGS += -mcpu=r4300 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_VR41XX -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R4X00 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_TX49XX -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_MIPS32 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_MIPS64 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R5000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_R5432 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_NEVADA -# Cannot use -mmad with currently recommended tools -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \ + -Wa,--trap +#GCCFLAGS += $(call check_gcc,-mmad,) endif ifdef CONFIG_CPU_RM7000 -GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ - -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \ + -Wa,--trap +endif +ifdef CONFIG_CPU_RM9000 +GCCFLAGS += $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ + -Wa,--trap endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) \ - -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ + -Wa,--trap ifdef CONFIG_SB1_PASS_1_WORKAROUNDS MODFLAGS += -msb1-pass1-workarounds endif @@ -195,6 +256,13 @@ LOADADDR += 0x80100000 endif +ifdef CONFIG_MIPS_HYDROGEN3 +LIBS += arch/mips/au1000/hydrogen3/hydrogen3.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/hydrogen3 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + ifdef CONFIG_MIPS_BOSPORUS LIBS += arch/mips/au1000/db1x00/db1x00.o \ arch/mips/au1000/common/au1000.o @@ -223,6 +291,24 @@ LOADADDR += 0x80100000 endif +ifdef CONFIG_MIPS_PB1550 +LIBS += arch/mips/au1000/pb1550/pb1550.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/pb1550 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + + +# +# Cogent CSB250 +# +ifdef CONFIG_COGENT_CSB250 +LIBS += arch/mips/au1000/csb250/csb250.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/csb250 arch/mips/au1000/common +LOADADDR := 0x80100000 +endif + ifdef CONFIG_PCI CORE_FILES += arch/mips/pci/pci-core.o SUBDIRS += arch/mips/pci @@ -377,6 +463,16 @@ LOADADDR := 0x80100000 endif +ifdef CONFIG_MOMENCO_JAGUAR_ATX +LIBS += arch/mips/momentum/jaguar_atx/jaguar_atx.o +SUBDIRS += arch/mips/momentum/jaguar_atx +ifdef CONFIG_JAGUAR_DMALOW +LOADADDR := 0x88000000 +else +LOADADDR := 0x80100000 +endif +endif + # # NEC DDB Vrc-5074 # @@ -632,6 +728,9 @@ vmlinux.ecoff: vmlinux @$(MAKEBOOT) $@ +vmlinux.srec: vmlinux + @$(MAKEBOOT) $@ + archclean: @$(MAKEBOOT) clean rm -f arch/$(ARCH)/ld.script diff -urN linux-2.4.24/arch/mips/Makefile.lib linux-2.4.25/arch/mips/Makefile.lib --- linux-2.4.24/arch/mips/Makefile.lib 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/Makefile.lib 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1 @@ +obj-$(CONFIG_LASAT) += crc32.o diff -urN linux-2.4.24/arch/mips/arc/identify.c linux-2.4.25/arch/mips/arc/identify.c --- linux-2.4.24/arch/mips/arc/identify.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/arc/identify.c 2004-02-18 05:36:30.000000000 -0800 @@ -44,11 +44,6 @@ MACH_GROUP_SGI, MACH_SGI_IP28, PROM_FLAG_ARCS - }, { "SGI-IP32", - "SGI IP32", - MACH_GROUP_SGI, - MACH_SGI_IP32, - PROM_FLAG_ARCS }, { "Microsoft-Jazz", "Jazz MIPS_Magnum_4000", MACH_GROUP_JAZZ, @@ -63,7 +58,7 @@ "SNI RM200_PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, - 0 + PROM_FLAG_DONT_FREE_TEMP } }; diff -urN linux-2.4.24/arch/mips/arc/memory.c linux-2.4.25/arch/mips/arc/memory.c --- linux-2.4.24/arch/mips/arc/memory.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/mips/arc/memory.c 2004-02-18 05:36:30.000000000 -0800 @@ -26,6 +26,12 @@ #undef DEBUG +/* + * For ARC firmware memory functions the unit of meassuring memory is always + * a 4k page of memory + */ +#define ARC_PAGE_SHIFT 12 + struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) { return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); @@ -127,20 +133,23 @@ unsigned long base, size; long type; - base = p->base << PAGE_SHIFT; - size = p->pages << PAGE_SHIFT; + base = p->base << ARC_PAGE_SHIFT; + size = p->pages << ARC_PAGE_SHIFT; type = prom_memtype_classify(p->type); add_memory_region(base, size, type); } } -void __init prom_free_prom_memory (void) +void __init prom_free_prom_memory(void) { unsigned long freed = 0; unsigned long addr; int i; + if (prom_flags & PROM_FLAG_DONT_FREE_TEMP) + return 0; + for (i = 0; i < boot_mem_map.nr_map; i++) { if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; diff -urN linux-2.4.24/arch/mips/au1000/common/Makefile linux-2.4.25/arch/mips/au1000/common/Makefile --- linux-2.4.24/arch/mips/au1000/common/Makefile 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -19,7 +19,7 @@ export-objs = prom.o clocks.o power.o usbdev.o obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \ - clocks.o power.o setup.o + clocks.o power.o setup.o sleeper.o obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o obj-$(CONFIG_KGDB) += dbg_io.o diff -urN linux-2.4.24/arch/mips/au1000/common/dma.c linux-2.4.25/arch/mips/au1000/common/dma.c --- linux-2.4.24/arch/mips/au1000/common/dma.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/common/dma.c 2004-02-18 05:36:30.000000000 -0800 @@ -40,7 +40,7 @@ #include #include - +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100) /* * A note on resource allocation: @@ -95,7 +95,6 @@ {I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC} }; - int au1000_dma_read_proc(char *buf, char **start, off_t fpos, int length, int *eof, void *data) { @@ -198,7 +197,6 @@ return i; } - void free_au1000_dma(unsigned int dmanr) { struct dma_chan *chan = get_dma_chan(dmanr); @@ -215,3 +213,4 @@ chan->irq_dev = NULL; chan->dev_id = -1; } +#endif // AU1000 AU1500 AU1100 diff -urN linux-2.4.24/arch/mips/au1000/common/irq.c linux-2.4.25/arch/mips/au1000/common/irq.c --- linux-2.4.24/arch/mips/au1000/common/irq.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -81,10 +81,12 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr); static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr); +static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr); inline void local_enable_irq(unsigned int irq_nr); inline void local_disable_irq(unsigned int irq_nr); extern void __init init_generic_irq(void); +void (*board_init_irq)(void); #ifdef CONFIG_PM extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs); @@ -108,6 +110,11 @@ au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); break; + case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1SET); + au_writel(1<<(irq_nr-32), IC1_CFG0SET); + break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); @@ -150,6 +157,11 @@ au_writel(1< AU1000_LAST_INTC0_INT) { + au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); + au_writel(1<<(irq_nr-32), IC1_RISINGCLR); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); + } + else { + au_writel(1<im_irq].handler = &rise_edge_irq_type; break; + case INTC_INT_FALL_EDGE: + irq_desc[imp->im_irq].handler = &fall_edge_irq_type; + break; + + case INTC_INT_RISE_AND_FALL_EDGE: + irq_desc[imp->im_irq].handler = &either_edge_irq_type; + break; + default: panic("Unknown au1xxx irq map"); break; @@ -420,6 +468,12 @@ } set_c0_status(ALLINTS); + + /* Board specific IRQ initialization. + */ + if (board_init_irq) + (*board_init_irq)(); + #ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); @@ -520,3 +574,86 @@ irq += 32; do_IRQ(irq, regs); } + +#ifdef CONFIG_PM + +/* Save/restore the interrupt controller state. + * Called from the save/restore core registers as part of the + * au_sleep function in power.c.....maybe I should just pm_register() + * them instead? + */ +static uint sleep_intctl_config0[2]; +static uint sleep_intctl_config1[2]; +static uint sleep_intctl_config2[2]; +static uint sleep_intctl_src[2]; +static uint sleep_intctl_assign[2]; +static uint sleep_intctl_wake[2]; +static uint sleep_intctl_mask[2]; + +void +save_au1xxx_intctl(void) +{ + sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); + sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); + sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); + sleep_intctl_src[0] = au_readl(IC0_SRCRD); + sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); + sleep_intctl_wake[0] = au_readl(IC0_WAKERD); + sleep_intctl_mask[0] = au_readl(IC0_MASKRD); + + sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); + sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); + sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); + sleep_intctl_src[1] = au_readl(IC1_SRCRD); + sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); + sleep_intctl_wake[1] = au_readl(IC1_WAKERD); + sleep_intctl_mask[1] = au_readl(IC1_MASKRD); +} + +/* For most restore operations, we clear the entire register and + * then set the bits we found during the save. + */ +void +restore_au1xxx_intctl(void) +{ + au_writel(0xffffffff, IC0_MASKCLR); au_sync(); + + au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); + au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); + au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); + au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); + au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); + au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); + au_writel(0xffffffff, IC0_SRCCLR); au_sync(); + au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); + au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); + au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); + au_writel(0xffffffff, IC0_WAKECLR); au_sync(); + au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); + au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); + au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); + au_writel(0x00000000, IC0_TESTBIT); au_sync(); + + au_writel(0xffffffff, IC1_MASKCLR); au_sync(); + + au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); + au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); + au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); + au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); + au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); + au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); + au_writel(0xffffffff, IC1_SRCCLR); au_sync(); + au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); + au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); + au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); + au_writel(0xffffffff, IC1_WAKECLR); au_sync(); + au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); + au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); + au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); + au_writel(0x00000000, IC1_TESTBIT); au_sync(); + + au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); + + au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); +} +#endif /* CONFIG_PM */ diff -urN linux-2.4.24/arch/mips/au1000/common/pci_fixup.c linux-2.4.25/arch/mips/au1000/common/pci_fixup.c --- linux-2.4.24/arch/mips/au1000/common/pci_fixup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/pci_fixup.c 2004-02-18 05:36:30.000000000 -0800 @@ -25,6 +25,12 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * CTG 11/18/2003 Added supoprt for Au1550 SOC. The PCI block did not + * change from Au1500 to the Au1550. However, the boards are now + * using INTB for second PCI slot. + * This is reflected in pcibios_fixup_irqs. + * */ #include @@ -36,7 +42,6 @@ #include #include -//#include #ifdef CONFIG_MIPS_PB1000 #include #endif @@ -49,7 +54,7 @@ #endif static void fixup_resource(int r_num, struct pci_dev *dev) ; -#ifdef CONFIG_SOC_AU1500 +#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 ) static unsigned long virt_io_addr; #endif @@ -60,7 +65,7 @@ void __init pcibios_fixup(void) { -#ifdef CONFIG_SOC_AU1500 +#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 ) int i; struct pci_dev *dev; @@ -100,7 +105,7 @@ void __init pcibios_fixup_irqs(void) { -#ifdef CONFIG_SOC_AU1500 +#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 ) unsigned int slot, func; unsigned char pin; struct pci_dev *dev; @@ -111,14 +116,26 @@ dev->irq = 0xff; slot = PCI_SLOT(dev->devfn); +#if defined( CONFIG_SOC_AU1500 ) switch (slot) { case 12: case 13: default: dev->irq = AU1000_PCI_INTA; break; - } +#elif defined( CONFIG_SOC_AU1550 ) + switch (slot) { + default: + case 12: + dev->irq = AU1000_PCI_INTA; + break; + case 13: + dev->irq = AU1000_PCI_INTB; + break; + } +#endif + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); DBG("slot %d irq %d\n", slot, dev->irq); } diff -urN linux-2.4.24/arch/mips/au1000/common/pci_ops.c linux-2.4.25/arch/mips/au1000/common/pci_ops.c --- linux-2.4.24/arch/mips/au1000/common/pci_ops.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/pci_ops.c 2004-02-18 05:36:30.000000000 -0800 @@ -6,7 +6,8 @@ * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * Support for all devices (greater than 16) added by David Gathright. + * - Support for all devices (greater than 16) added by David Gathright. + * - Wired tlb fix for ioremap calls in interrupt routines by Embedded Edge. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -36,6 +37,7 @@ #include #include #include +#include #include #ifdef CONFIG_MIPS_PB1000 @@ -53,6 +55,8 @@ #define DBG(x...) #endif +int (*board_pci_idsel)(unsigned int devsel, int assert); + /* TBD */ static struct resource pci_io_resource = { "pci IO space", @@ -120,76 +124,154 @@ #else + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop;\t" \ + ".set reorder\n\t") + +void mod_wired_entry(int entry, unsigned long entrylo0, + unsigned long entrylo1, unsigned long entryhi, + unsigned long pagemask) +{ + unsigned long old_pagemask; + unsigned long old_ctx; + + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + write_c0_index(entry); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); +} + +struct vm_struct *pci_cfg_vm; +static int pci_cfg_wired_entry; +static int first_cfg = 1; +unsigned long last_entryLo0, last_entryLo1; + static int config_access(unsigned char access_type, struct pci_dev *dev, unsigned char where, u32 * data) { -#ifdef CONFIG_SOC_AU1500 +#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 ) unsigned char bus = dev->bus->number; unsigned int dev_fn = dev->devfn; unsigned int device = PCI_SLOT(dev_fn); unsigned int function = PCI_FUNC(dev_fn); - unsigned long config, status; - unsigned long cfg_addr; + unsigned long offset, status; + unsigned long cfg_base; + unsigned long flags; + int error = PCIBIOS_SUCCESSFUL; + unsigned long entryLo0, entryLo1; if (device > 19) { *data = 0xffffffff; return -1; } + local_irq_save(flags); au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), Au1500_PCI_STATCMD); - //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); au_sync_udelay(1); + /* + * We can't ioremap the entire pci config space because it's + * too large. Nor can we call ioremap dynamically because some + * device drivers use the pci config routines from within + * interrupt handlers and that becomes a problem in get_vm_area(). + * We use one wired tlb to handle all config accesses for all + * busses. To improve performance, if the current device + * is the same as the last device accessed, we don't touch the + * tlb. + */ + if (first_cfg) { + /* reserve a wired entry for pci config accesses */ + first_cfg = 0; + pci_cfg_vm = get_vm_area(0x2000, 0); + if (!pci_cfg_vm) + panic (KERN_ERR "PCI unable to get vm area\n"); + pci_cfg_wired_entry = read_c0_wired(); + add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, + PM_4K); + last_entryLo0 = last_entryLo1 = 0xffffffff; + } + + /* Since the Au1xxx doesn't do the idsel timing exactly to spec, + * many board vendors implement their own off-chip idsel, so call + * it now. If it doesn't succeed, may as well bail out at this point. + */ + if (board_pci_idsel) { + if (board_pci_idsel(device, 1) == 0) { + *data = 0xffffffff; + local_irq_restore(flags); + return -1; + } + } + /* setup the config window */ if (bus == 0) { - cfg_addr = ioremap( Au1500_EXT_CFG | ((1<> 6) | (2 << 3) | 7; + entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7; + + if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) { + mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1, + (unsigned long)pci_cfg_vm->addr, PM_4K); + last_entryLo0 = entryLo0; + last_entryLo1 = entryLo1; + } if (access_type == PCI_ACCESS_WRITE) { - au_writel(*data, config); + au_writel(*data, (int)(pci_cfg_vm->addr + offset)); } else { - *data = au_readl(config); + *data = au_readl((int)(pci_cfg_vm->addr + offset)); } au_sync_udelay(2); - DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", - access_type, bus, device, where, *data, config); - - /* unmap io space */ - iounmap( cfg_addr ); + access_type, bus, device, where, *data, offset); /* check master abort */ status = au_readl(Au1500_PCI_STATCMD); -#if 0 -printk("cfg access: status %x, data %x\n", status, *data ); -#endif + if (status & (1<<29)) { *data = 0xffffffff; - return -1; + error = -1; } else if ((status >> 28) & 0xf) { DBG("PCI ERR detected: status %x\n", status); *data = 0xffffffff; - return -1; - } else { - return PCIBIOS_SUCCESSFUL; + error = -1; + } + + /* Take away the idsel. + */ + if (board_pci_idsel) { + (void)board_pci_idsel(device, 0); } + + local_irq_restore(flags); + return error; #endif } #endif diff -urN linux-2.4.24/arch/mips/au1000/common/power.c linux-2.4.25/arch/mips/au1000/common/power.c --- linux-2.4.24/arch/mips/au1000/common/power.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/power.c 2004-02-18 05:36:30.000000000 -0800 @@ -29,12 +29,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include + #include #include #include #include -#include #include #include @@ -49,13 +48,12 @@ # define DPRINTK(fmt, args...) #endif -extern void au1k_wait(void); static void calibrate_delay(void); -extern void set_au1000_speed(unsigned int new_freq); -extern unsigned int get_au1000_speed(void); -extern unsigned long get_au1000_uart_baud_base(void); -extern void set_au1000_uart_baud_base(unsigned long new_baud_base); +extern void set_au1x00_speed(unsigned int new_freq); +extern unsigned int get_au1x00_speed(void); +extern unsigned long get_au1x00_uart_baud_base(void); +extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); extern unsigned long save_local_and_disable(int controller); extern void restore_local_and_enable(int controller, unsigned long mask); extern void local_enable_irq(unsigned int irq_nr); @@ -69,6 +67,141 @@ static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED; +/* We need to save/restore a bunch of core registers that are + * either volatile or reset to some state across a processor sleep. + * If reading a register doesn't provide a proper result for a + * later restore, we have to provide a function for loading that + * register and save a copy. + * + * We only have to save/restore registers that aren't otherwise + * done as part of a driver pm_* function. + */ +static uint sleep_aux_pll_cntrl; +static uint sleep_cpu_pll_cntrl; +static uint sleep_pin_function; +static uint sleep_uart0_inten; +static uint sleep_uart0_fifoctl; +static uint sleep_uart0_linectl; +static uint sleep_uart0_clkdiv; +static uint sleep_uart0_enable; +static uint sleep_usbhost_enable; +static uint sleep_usbdev_enable; +static uint sleep_static_memctlr[4][3]; + +/* Define this to cause the value you write to /proc/sys/pm/sleep to + * set the TOY timer for the amount of time you want to sleep. + * This is done mainly for testing, but may be useful in other cases. + * The value is number of 32KHz ticks to sleep. + */ +#define SLEEP_TEST_TIMEOUT 1 +#ifdef SLEEP_TEST_TIMEOUT +static int sleep_ticks; +void wakeup_counter0_set(int ticks); +#endif + +static void +save_core_regs(void) +{ + extern void save_au1xxx_intctl(void); + extern void pm_eth0_shutdown(void); + + /* Do the serial ports.....these really should be a pm_* + * registered function by the driver......but of course the + * standard serial driver doesn't understand our Au1xxx + * unique registers. + */ + sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER); + sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR); + sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); + sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); + sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); + + /* Shutdown USB host/device. + */ + sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); + + /* There appears to be some undocumented reset register.... + */ + au_writel(0, 0xb0100004); au_sync(); + au_writel(0, USB_HOST_CONFIG); au_sync(); + + sleep_usbdev_enable = au_readl(USBD_ENABLE); + au_writel(0, USBD_ENABLE); au_sync(); + + /* Save interrupt controller state. + */ + save_au1xxx_intctl(); + + /* Clocks and PLLs. + */ + sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); + + /* We don't really need to do this one, but unless we + * write it again it won't have a valid value if we + * happen to read it. + */ + sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL); + + sleep_pin_function = au_readl(SYS_PINFUNC); + + /* Save the static memory controller configuration. + */ + sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); + sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); + sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); + sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); + sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); + sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); + sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); + sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); + sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); + sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); + sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); + sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); +} + +static void +restore_core_regs(void) +{ + extern void restore_au1xxx_intctl(void); + extern void wakeup_counter0_adjust(void); + + au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync(); + au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); + au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); + + /* Restore the static memory controller configuration. + */ + au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); + au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); + au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); + au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); + au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); + au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); + au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); + au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); + au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); + au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); + au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); + au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); + + /* Enable the UART if it was enabled before sleep. + * I guess I should define module control bits........ + */ + if (sleep_uart0_enable & 0x02) { + au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); + } + + restore_au1xxx_intctl(); + wakeup_counter0_adjust(); +} + unsigned long suspend_mode; void wakeup_from_suspend(void) @@ -79,33 +212,48 @@ int au_sleep(void) { unsigned long wakeup, flags; + extern void save_and_sleep(void); + spin_lock_irqsave(&pm_lock,flags); + save_core_regs(); + flush_cache_all(); - /* pin 6 is gpio */ + + /** The code below is all system dependent and we should probably + ** have a function call out of here to set this up. You need + ** to configure the GPIO or timer interrupts that will bring + ** you out of sleep. + ** For testing, the TOY counter wakeup is useful. + **/ + +#if 0 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); /* gpio 6 can cause a wake up event */ wakeup = au_readl(SYS_WAKEMSK); wakeup &= ~(1 << 8); /* turn off match20 wakeup */ wakeup |= 1 << 6; /* turn on gpio 6 wakeup */ - au_writel(wakeup, SYS_WAKEMSK); - +#else + /* For testing, allow match20 to wake us up. + */ +#ifdef SLEEP_TEST_TIMEOUT + wakeup_counter0_set(sleep_ticks); +#endif + wakeup = 1 << 8; /* turn on match20 wakeup */ + wakeup = 0; +#endif au_writel(1, SYS_WAKESRC); /* clear cause */ - au_writel(1, SYS_SLPPWR); /* prepare to sleep */ + au_sync(); + au_writel(wakeup, SYS_WAKEMSK); + au_sync(); - __asm__("la $4, 1f\n\t" - "lui $5, 0xb190\n\t" - "ori $5, 0x18\n\t" - "sw $4, 0($5)\n\t" - "li $4, 1\n\t" - "lui $5, 0xb190\n\t" - "ori $5, 0x7c\n\t" - "sw $4, 0($5)\n\t" "sync\n\t" "1:\t\n\t" "nop\n\t"); + save_and_sleep(); /* after a wakeup, the cpu vectors back to 0x1fc00000 so * it's up to the boot code to get us back here. */ + restore_core_regs(); spin_unlock_irqrestore(&pm_lock, flags); return 0; } @@ -114,11 +262,27 @@ void *buffer, size_t * len) { int retval = 0; +#ifdef SLEEP_TEST_TIMEOUT +#define TMPBUFLEN2 16 + char buf[TMPBUFLEN2], *p; +#endif if (!write) { *len = 0; } else { +#ifdef SLEEP_TEST_TIMEOUT + if (*len > TMPBUFLEN2 - 1) { + return -EFAULT; + } + if (copy_from_user(buf, buffer, *len)) { + return -EFAULT; + } + buf[*len] = 0; + p = buf; + sleep_ticks = simple_strtoul(p, &p, 0); +#endif retval = pm_send_all(PM_SUSPEND, (void *) 2); + if (retval) return retval; @@ -132,6 +296,7 @@ void *buffer, size_t * len) { int retval = 0; + void au1k_wait(void); if (!write) { *len = 0; @@ -188,13 +353,13 @@ return -EFAULT; } - old_baud_base = get_au1000_uart_baud_base(); - old_cpu_freq = get_au1000_speed(); + old_baud_base = get_au1x00_uart_baud_base(); + old_cpu_freq = get_au1x00_speed(); new_cpu_freq = pll * 12 * 1000000; new_baud_base = (new_cpu_freq / 4) / 16; - set_au1000_speed(new_cpu_freq); - set_au1000_uart_baud_base(new_baud_base); + set_au1x00_speed(new_cpu_freq); + set_au1x00_uart_baud_base(new_baud_base); old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; new_refresh = @@ -324,10 +489,4 @@ loops_per_jiffy &= ~loopbit; } } - -void au1k_wait(void) -{ - __asm__("nop\n\t" "nop\n\t"); -} - #endif /* CONFIG_PM */ diff -urN linux-2.4.24/arch/mips/au1000/common/reset.c linux-2.4.25/arch/mips/au1000/common/reset.c --- linux-2.4.24/arch/mips/au1000/common/reset.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/reset.c 2004-02-18 05:36:30.000000000 -0800 @@ -54,6 +54,10 @@ au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb0520000); /* macen0 */ au_writel(0x00, 0xb0520004); /* macen1 */ au_writel(0x00, 0xb1000008); /* i2s_enable */ @@ -66,6 +70,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; case 0x01000000: /* Au1500 */ @@ -74,6 +80,10 @@ asm("sync"); au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb1520000); /* macen0 */ au_writel(0x00, 0xb1520004); /* macen1 */ au_writel(0x00, 0xb1100100); /* uart0_enable */ @@ -81,6 +91,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; case 0x02000000: /* Au1100 */ @@ -90,6 +102,10 @@ au_writel(0x00, 0xb017fffc); /* usbh_enable */ au_writel(0x00, 0xb0200058); /* usbd_enable */ au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb4004104); /* mac dma */ + au_writel(0x00, 0xb4004114); /* mac dma */ + au_writel(0x00, 0xb4004124); /* mac dma */ + au_writel(0x00, 0xb4004134); /* mac dma */ au_writel(0x00, 0xb0520000); /* macen0 */ au_writel(0x00, 0xb1000008); /* i2s_enable */ au_writel(0x00, 0xb1100100); /* uart0_enable */ @@ -100,6 +116,8 @@ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x10, 0xb1900060); /* sys_cpupll */ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ au_writel(0x00, 0xb1900100); /* sys_pininputen */ break; diff -urN linux-2.4.24/arch/mips/au1000/common/setup.c linux-2.4.25/arch/mips/au1000/common/setup.c --- linux-2.4.24/arch/mips/au1000/common/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -44,11 +44,7 @@ #include #include #include - -#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif +#include #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start, initrd_end; @@ -72,6 +68,8 @@ extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size); #endif +extern void au1xxx_time_init(void); +extern void au1xxx_timer_setup(void); void __init au1x00_setup(void) { @@ -96,14 +94,22 @@ argptr = prom_getcmdline(); /* default panel */ //strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); +#ifdef CONFIG_MIPS_HYDROGEN3 + strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor"); +#else strcat(argptr, " video=au1100fb:panel:s10,nohwcursor"); +#endif } #endif #ifdef CONFIG_FB_E1356 if ((argptr = strstr(argptr, "video=")) == NULL) { argptr = prom_getcmdline(); +#ifdef CONFIG_MIPS_PB1000 + strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1"); +#else strcat(argptr, " video=e1356fb:system:pb1500"); +#endif } #endif @@ -126,6 +132,9 @@ fixup_bigphys_addr = au1500_fixup_bigphys_addr; #endif + board_time_init = au1xxx_time_init; + board_timer_setup = au1xxx_timer_setup; + // IO/MEM resources. set_io_port_base(0); ioport_resource.start = IOPORT_RESOURCE_START; @@ -174,7 +183,10 @@ #endif #ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; + /* Board setup takes precedence for unique devices. + */ + if (ide_ops == NULL) + ide_ops = &std_ide_ops; #endif while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); @@ -184,7 +196,7 @@ au_writel(0, SYS_TOYTRIM); } -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)) /* This routine should be valid for all Au1500 based boards */ static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size) { diff -urN linux-2.4.24/arch/mips/au1000/common/sleeper.S linux-2.4.25/arch/mips/au1000/common/sleeper.S --- linux-2.4.24/arch/mips/au1000/common/sleeper.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/common/sleeper.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,150 @@ +/* + * Copyright 2002 Embedded Edge, LLC + * Author: dan@embeddededge.com + * + * Sleep helper for Au1xxx sleep mode. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include + + .text + .set macro + .set noat + .align 5 + +/* Save all of the processor general registers and go to sleep. + * A wakeup condition will get us back here to restore the registers. + */ +LEAF(save_and_sleep) + + subu sp, PT_SIZE + sw $1, PT_R1(sp) + sw $2, PT_R2(sp) + sw $3, PT_R3(sp) + sw $4, PT_R4(sp) + sw $5, PT_R5(sp) + sw $6, PT_R6(sp) + sw $7, PT_R7(sp) + sw $8, PT_R8(sp) + sw $9, PT_R9(sp) + sw $10, PT_R10(sp) + sw $11, PT_R11(sp) + sw $12, PT_R12(sp) + sw $13, PT_R13(sp) + sw $14, PT_R14(sp) + sw $15, PT_R15(sp) + sw $16, PT_R16(sp) + sw $17, PT_R17(sp) + sw $18, PT_R18(sp) + sw $19, PT_R19(sp) + sw $20, PT_R20(sp) + sw $21, PT_R21(sp) + sw $22, PT_R22(sp) + sw $23, PT_R23(sp) + sw $24, PT_R24(sp) + sw $25, PT_R25(sp) + sw $26, PT_R26(sp) + sw $27, PT_R27(sp) + sw $28, PT_R28(sp) + sw $29, PT_R29(sp) + sw $30, PT_R30(sp) + sw $31, PT_R31(sp) + mfc0 k0, CP0_STATUS + sw k0, 0x20(sp) + mfc0 k0, CP0_CONTEXT + sw k0, 0x1c(sp) + mfc0 k0, CP0_PAGEMASK + sw k0, 0x18(sp) + mfc0 k0, CP0_CONFIG + sw k0, 0x14(sp) + + /* Now set up the scratch registers so the boot rom will + * return to this point upon wakeup. + */ + la k0, 1f + lui k1, 0xb190 + ori k1, 0x18 + sw sp, 0(k1) + ori k1, 0x1c + sw k0, 0(k1) + +/* Put SDRAM into self refresh. Preload instructions into cache, + * issue a precharge, then auto refresh, then sleep commands to it. + */ + la t0, sdsleep + .set mips3 + cache 0x14, 0(t0) + cache 0x14, 32(t0) + cache 0x14, 64(t0) + cache 0x14, 96(t0) + .set mips0 + +sdsleep: + lui k0, 0xb400 + sw zero, 0x001c(k0) /* Precharge */ + sw zero, 0x0020(k0) /* Auto refresh */ + sw zero, 0x0030(k0) /* SDRAM sleep */ + sync + + lui k1, 0xb190 + sw zero, 0x0078(k1) /* get ready to sleep */ + sync + sw zero, 0x007c(k1) /* Put processor to sleep */ + sync + + /* This is where we return upon wakeup. + * Reload all of the registers and return. + */ +1: nop + lw k0, 0x20(sp) + mtc0 k0, CP0_STATUS + lw k0, 0x1c(sp) + mtc0 k0, CP0_CONTEXT + lw k0, 0x18(sp) + mtc0 k0, CP0_PAGEMASK + lw k0, 0x14(sp) + mtc0 k0, CP0_CONFIG + lw $1, PT_R1(sp) + lw $2, PT_R2(sp) + lw $3, PT_R3(sp) + lw $4, PT_R4(sp) + lw $5, PT_R5(sp) + lw $6, PT_R6(sp) + lw $7, PT_R7(sp) + lw $8, PT_R8(sp) + lw $9, PT_R9(sp) + lw $10, PT_R10(sp) + lw $11, PT_R11(sp) + lw $12, PT_R12(sp) + lw $13, PT_R13(sp) + lw $14, PT_R14(sp) + lw $15, PT_R15(sp) + lw $16, PT_R16(sp) + lw $17, PT_R17(sp) + lw $18, PT_R18(sp) + lw $19, PT_R19(sp) + lw $20, PT_R20(sp) + lw $21, PT_R21(sp) + lw $22, PT_R22(sp) + lw $23, PT_R23(sp) + lw $24, PT_R24(sp) + lw $25, PT_R25(sp) + lw $26, PT_R26(sp) + lw $27, PT_R27(sp) + lw $28, PT_R28(sp) + lw $29, PT_R29(sp) + lw $30, PT_R30(sp) + lw $31, PT_R31(sp) + addiu sp, PT_SIZE + + jr ra +END(save_and_sleep) diff -urN linux-2.4.24/arch/mips/au1000/common/time.c linux-2.4.25/arch/mips/au1000/common/time.c --- linux-2.4.24/arch/mips/au1000/common/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/common/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -25,6 +25,11 @@ * * Setting up the clock on the MIPS boards. * + * Update. Always configure the kernel with CONFIG_NEW_TIME_C. This + * will use the user interface gettimeofday() functions from the + * arch/mips/kernel/time.c, and we provide the clock interrupt processing + * and the timer offset compute functions. If CONFIG_PM is selected, + * we also ensure the 32KHz timer is available. -- Dan */ #include @@ -44,6 +49,10 @@ #include #include +#if !defined(CONFIG_NEW_TIME_C) +#error "Alchemy processors need CONFIG_NEW_TIME_C defined" +#endif + extern void startup_match20_interrupt(void); extern void do_softirq(void); extern volatile unsigned long wall_jiffies; @@ -52,7 +61,8 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ extern rwlock_t xtime_lock; -unsigned int mips_counter_frequency = 0; +int no_au1xxx_32khz; +void (*au1k_wait_ptr)(void); /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi = 0, timerlo = 0; @@ -85,12 +95,6 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; -#ifdef CONFIG_PM - printk(KERN_ERR "Unexpected CP0 interrupt\n"); - regs->cp0_status &= ~IE_IRQ5; /* disable CP0 interrupt */ - return; -#endif - if (r4k_offset == 0) goto null; @@ -160,115 +164,148 @@ do_timer(regs); /* increment jiffies by one */ } } -#endif -/* - * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. - * Use the Programmable Counter 1 to do this. +/* When we wakeup from sleep, we have to "catch up" on all of the + * timer ticks we have missed. */ -unsigned long cal_r4koff(void) +void +wakeup_counter0_adjust(void) { - unsigned long count; - unsigned long cpu_speed; - unsigned long start, end; - unsigned long counter; - int trim_divide = 16; - unsigned long flags; + unsigned long pc0; + int time_elapsed; - spin_lock_irqsave(&time_lock, flags); + pc0 = au_readl(SYS_TOYREAD); + if (pc0 < last_match20) { + /* counter overflowed */ + time_elapsed = (0xffffffff - last_match20) + pc0; + } + else { + time_elapsed = pc0 - last_match20; + } - counter = au_readl(SYS_COUNTER_CNTRL); - au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); + while (time_elapsed > 0) { + time_elapsed -= MATCH20_INC; + last_match20 += MATCH20_INC; + } + + last_pc0 = pc0; + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); - au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */ - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); - au_writel (0, SYS_TOYWRITE); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); - - start = au_readl(SYS_RTCREAD); - start += 2; - /* wait for the beginning of a new tick */ - while (au_readl(SYS_RTCREAD) < start); - - /* Start r4k counter. */ - write_c0_count(0); - end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */ +} - while (end > au_readl(SYS_RTCREAD)); +/* This is just for debugging to set the timer for a sleep delay. +*/ +void +wakeup_counter0_set(int ticks) +{ + unsigned long pc0; - count = read_c0_count(); - cpu_speed = count * 2; - mips_counter_frequency = count; - set_au1x00_uart_baud_base(((cpu_speed) / 4) / 16); - spin_unlock_irqrestore(&time_lock, flags); - return (cpu_speed / HZ); + pc0 = au_readl(SYS_TOYREAD); + last_pc0 = pc0; + au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2); + au_sync(); } +#endif +/* I haven't found anyone that doesn't use a 12 MHz source clock, + * but just in case..... + */ +#ifdef CONFIG_AU1000_SRC_CLK +#define AU1000_SRC_CLK CONFIG_AU1000_SRC_CLK +#else +#define AU1000_SRC_CLK 12000000 +#endif -void __init time_init(void) +/* + * We read the real processor speed from the PLL. This is important + * because it is more accurate than computing it from the 32KHz + * counter, if it exists. If we don't have an accurate processor + * speed, all of the peripherals that derive their clocks based on + * this advertised speed will introduce error and sometimes not work + * properly. This function is futher convoluted to still allow configurations + * to do that in case they have really, really old silicon with a + * write-only PLL register, that we need the 32KHz when power management + * "wait" is enabled, and we need to detect if the 32KHz isn't present + * but requested......got it? :-) -- Dan + */ +unsigned long cal_r4koff(void) { - unsigned int est_freq; + unsigned long count; + unsigned long cpu_speed; + unsigned long flags; + unsigned long counter; - printk("calculating r4koff... "); - r4k_offset = cal_r4koff(); - printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + spin_lock_irqsave(&time_lock, flags); - //est_freq = 2*r4k_offset*HZ; - est_freq = r4k_offset*HZ; - est_freq += 5000; /* round */ - est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); - set_au1x00_speed(est_freq); - set_au1x00_lcd_clock(); // program the LCD clock - r4k_cur = (read_c0_count() + r4k_offset); + /* Power management cares if we don't have a 32KHz counter. + */ + no_au1xxx_32khz = 0; + counter = au_readl(SYS_COUNTER_CNTRL); + if (counter & SYS_CNTRL_E0) { + int trim_divide = 16; - write_c0_compare(r4k_cur); + au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); - /* no RTC on the pb1000 */ - xtime.tv_sec = 0; - xtime.tv_usec = 0; + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + /* RTC now ticks at 32.768/16 kHz */ + au_writel(trim_divide-1, SYS_RTCTRIM); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + au_writel (0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + +#if defined(CONFIG_AU1000_USE32K) + { + unsigned long start, end; + + start = au_readl(SYS_RTCREAD); + start += 2; + /* wait for the beginning of a new tick + */ + while (au_readl(SYS_RTCREAD) < start); + + /* Start r4k counter. + */ + write_c0_count(0); + + /* Wait 0.5 seconds. + */ + end = start + (32768 / trim_divide)/2; -#ifdef CONFIG_PM - /* - * setup counter 0, since it keeps ticking after a - * 'wait' instruction has been executed. The CP0 timer and - * counter 1 do NOT continue running after 'wait' - * - * It's too early to call request_irq() here, so we handle - * counter 0 interrupt as a special irq and it doesn't show - * up under /proc/interrupts. - */ - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); - au_writel(0, SYS_TOYWRITE); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + while (end > au_readl(SYS_RTCREAD)); - au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); - au_writel(~0, SYS_WAKESRC); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); - - /* setup match20 to interrupt once every 10ms */ - last_pc0 = last_match20 = au_readl(SYS_TOYREAD); - au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); - startup_match20_interrupt(); + count = read_c0_count(); + cpu_speed = count * 2; + } +#else + cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * + AU1000_SRC_CLK; + count = cpu_speed / 2; #endif - - //set_c0_status(ALLINTS); - au_sync(); + } + else { + /* The 32KHz oscillator isn't running, so assume there + * isn't one and grab the processor speed from the PLL. + * NOTE: some old silicon doesn't allow reading the PLL. + */ + cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; + count = cpu_speed / 2; + no_au1xxx_32khz = 1; + } + mips_hpt_frequency = count; + // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) + set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); + spin_unlock_irqrestore(&time_lock, flags); + return (cpu_speed / HZ); } /* This is for machines which generate the exact clock. */ #define USECS_PER_JIFFY (1000000/HZ) #define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) -#ifndef CONFIG_PM + static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) { @@ -276,30 +313,9 @@ do_div64_32(r0, v1, v2, v3); return r0; } -#endif -static unsigned long do_fast_gettimeoffset(void) +static unsigned long do_fast_cp0_gettimeoffset(void) { -#ifdef CONFIG_PM - unsigned long pc0; - unsigned long offset; - - pc0 = au_readl(SYS_TOYREAD); - if (pc0 < last_pc0) { - offset = 0xffffffff - last_pc0 + pc0; - printk("offset over: %x\n", (unsigned)offset); - } - else { - offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10); - } - if ((pc0-last_pc0) > 2*MATCH20_INC) { - printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", - (unsigned)offset, (unsigned)last_pc0, - (unsigned)last_match20, (unsigned)pc0); - } - au_sync(); - return offset; -#else u32 count; unsigned long res, tmp; unsigned long r0; @@ -340,60 +356,118 @@ "r" (quotient)); /* - * Due to possible jiffies inconsistencies, we need to check + * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) res = USECS_PER_JIFFY-1; return res; -#endif } -void do_gettimeofday(struct timeval *tv) +#ifdef CONFIG_PM +static unsigned long do_fast_pm_gettimeoffset(void) { - unsigned long flags; - - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - read_unlock_irqrestore (&xtime_lock, flags); + unsigned long pc0; + unsigned long offset; - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + pc0 = au_readl(SYS_TOYREAD); + au_sync(); + offset = pc0 - last_pc0; + if (offset > 2*MATCH20_INC) { + printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", + (unsigned)offset, (unsigned)last_pc0, + (unsigned)last_match20, (unsigned)pc0); } + offset = (unsigned long)((offset * 305) / 10); + return offset; } +#endif -void do_settimeofday(struct timeval *tv) +void __init au1xxx_timer_setup(void) { - write_lock_irq (&xtime_lock); + unsigned int est_freq; + extern unsigned long (*do_gettimeoffset)(void); + extern void au1k_wait(void); + + printk("calculating r4koff... "); + r4k_offset = cal_r4koff(); + printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + + //est_freq = 2*r4k_offset*HZ; + est_freq = r4k_offset*HZ; + est_freq += 5000; /* round */ + est_freq -= est_freq%10000; + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); // program the LCD clock + + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); - /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is value at the last tick. - * Discover what correction gettimeofday would have done, and then - * undo it! + /* no RTC on the pb1000 */ + xtime.tv_sec = 0; + xtime.tv_usec = 0; + +#ifdef CONFIG_PM + /* + * setup counter 0, since it keeps ticking after a + * 'wait' instruction has been executed. The CP0 timer and + * counter 1 do NOT continue running after 'wait' + * + * It's too early to call request_irq() here, so we handle + * counter 0 interrupt as a special irq and it doesn't show + * up under /proc/interrupts. + * + * Check to ensure we really have a 32KHz oscillator before + * we do this. */ - tv->tv_usec -= do_fast_gettimeoffset(); + if (no_au1xxx_32khz) { + unsigned int c0_status; + + printk("WARNING: no 32KHz clock found.\n"); + do_gettimeoffset = do_fast_cp0_gettimeoffset; - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; + /* Ensure we get CPO_COUNTER interrupts. + */ + c0_status = read_c0_status(); + c0_status |= IE_IRQ5; + write_c0_status(c0_status); + } + else { + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + au_writel(0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + + au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); + au_writel(~0, SYS_WAKESRC); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + + /* setup match20 to interrupt once every 10ms */ + last_pc0 = last_match20 = au_readl(SYS_TOYREAD); + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + startup_match20_interrupt(); + + do_gettimeoffset = do_fast_pm_gettimeoffset; + + /* We can use the real 'wait' instruction. + */ + au1k_wait_ptr = au1k_wait; } - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; +#else + /* We have to do this here instead of in timer_init because + * the generic code in arch/mips/kernel/time.c will write + * over our function pointer. + */ + do_gettimeoffset = do_fast_cp0_gettimeoffset; +#endif +} - write_unlock_irq (&xtime_lock); +void __init au1xxx_time_init(void) +{ } diff -urN linux-2.4.24/arch/mips/au1000/csb250/Makefile linux-2.4.25/arch/mips/au1000/csb250/Makefile --- linux-2.4.24/arch/mips/au1000/csb250/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/csb250/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,18 @@ +# +# Copyright 2002 Cogent Computer Systems +# dan@embeddededge.com +# +# Makefile for the Cogent CSB250 Au1500 board. Copied from Pb1500. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := csb250.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/au1000/csb250/board_setup.c linux-2.4.25/arch/mips/au1000/csb250/board_setup.c --- linux-2.4.24/arch/mips/au1000/csb250/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/csb250/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,250 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Cogent CSB250 board setup. + * + * Copyright 2002 Cogent Computer Systems, Inc. + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops csb250_rtc_ops; +#endif + +extern int (*board_pci_idsel)(unsigned int devsel, int assert); +int csb250_pci_idsel(unsigned int devsel, int assert); + +void __init board_setup(void) +{ + u32 pin_func, pin_val; + u32 sys_freqctrl, sys_clksrc; + + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + /* GPIO201 is input for PCMCIA card detect */ + /* GPIO203 is input for PCMCIA interrupt request */ + au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + /* Configure GPIO2....it's used by PCI among other things. + */ + + /* Make everything but GP200 (PCI RST) an input until we get + * the pins set correctly. + */ + au_writel(0x00000001, GPIO2_DIR); + + /* Set the pins used for output. + * A zero bit will leave PCI reset, LEDs off, power up USB, + * IDSEL disabled. + */ + pin_val = ((3 << 30) | (7 << 19) | (1 << 17) | (1 << 16)); + au_writel(pin_val, GPIO2_OUTPUT); + + /* Set the output direction. + */ + pin_val = ((3 << 14) | (7 << 3) | (1 << 1) | (1 << 0)); + au_writel(pin_val, GPIO2_DIR); + +#ifdef CONFIG_PCI + /* Use FREQ1 for the PCI output clock. We use the + * CPU clock of 384 MHz divided by 12 to get 32 MHz PCI. + * If Michael changes the CPU speed, we need to adjust + * that here as well :-). + */ + + /* zero and disable FREQ1 + */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0x000ffc00; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable PCI clock + */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x000f8000; + au_writel(sys_clksrc, SYS_CLKSRC); + + /* Get current values (which really should match above). + */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0x000ffc00; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x000f8000; + + /* FREQ1 = cpu/12 = 32 MHz + */ + sys_freqctrl |= ((5<<12) | (1<<11) | (0<<10)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* Just connect the clock without further dividing. + */ + sys_clksrc |= ((3<<17) | (0<<16) | (0<<15)); + au_writel(sys_clksrc, SYS_CLKSRC); + + udelay(1); + + /* Now that clocks should be running, take PCI out of reset. + */ + pin_val = au_readl(GPIO2_OUTPUT); + pin_val |= ((1 << 16) | 1); + au_writel(pin_val, GPIO2_OUTPUT); + + // Setup PCI bus controller + au_writel(0, Au1500_PCI_CMEM); + au_writel(0x00003fff, Au1500_CFG_BASE); + + /* We run big endian without any of the software byte swapping, + * so configure the PCI bridge to help us out. + */ + au_writel(0xf | (2<<6) | (1<<5) | (1<<4), Au1500_PCI_CFG); + + au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); + au_writel(0, Au1500_PCI_MWBASE_REV_CCL); + au_writel(0x02a00356, Au1500_PCI_STATCMD); + au_writel(0x00003c04, Au1500_PCI_HDRTYPE); + au_writel(0x00000008, Au1500_PCI_MBAR); + au_sync(); + + board_pci_idsel = csb250_pci_idsel; +#endif + + /* Enable sys bus clock divider when IDLE state or no bus activity. */ + au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); + +#ifdef CONFIG_RTC + rtc_ops = &csb250_rtc_ops; + // Enable the RTC if not already enabled + if (!(au_readl(0xac000028) & 0x20)) { + printk("enabling clock ...\n"); + au_writel((au_readl(0xac000028) | 0x20), 0xac000028); + } + // Put the clock in BCD mode + if (readl(0xac00002C) & 0x4) { /* reg B */ + au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} + +/* The IDSEL is selected in the GPIO2 register. We will make device + * 12 appear in slot 0 and device 13 appear in slot 1. + */ +int +csb250_pci_idsel(unsigned int devsel, int assert) +{ + int retval; + unsigned int gpio2_pins; + + retval = 1; + + /* First, disable both selects, then assert the one requested. + */ + au_writel(0xc000c000, GPIO2_OUTPUT); + au_sync(); + + if (assert) { + if (devsel == 12) + gpio2_pins = 0x40000000; + else if (devsel == 13) + gpio2_pins = 0x80000000; + else { + gpio2_pins = 0xc000c000; + retval = 0; + } + au_writel(gpio2_pins, GPIO2_OUTPUT); + } + au_sync(); + + return retval; +} diff -urN linux-2.4.24/arch/mips/au1000/csb250/init.c linux-2.4.25/arch/mips/au1000/csb250/init.c --- linux-2.4.24/arch/mips/au1000/csb250/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/csb250/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,95 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Cogent CSB250 board setup + * + * Copyright 2002 Cogent Computer Systems, Inc. + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +/* When we get initrd working someday......... +*/ +int my_initrd_start, my_initrd_size; + +/* Start arguments and environment. +*/ +static char *csb_env[2]; +static char *csb_arg[4]; +static char *arg1 = "console=ttyS3,38400"; +static char *arg2 = "root=/dev/nfs rw ip=any"; +static char *env1 = "ethaddr=00:30:23:50:00:00"; + +const char *get_system_type(void) +{ + return "Cogent CSB250"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + /* We use a0 and a1 to pass initrd start and size. + */ + if (((uint) argc > 0) && ((uint)argv > 0)) { + my_initrd_start = (uint)argc; + my_initrd_size = (uint)argv; + } + + /* First argv is ignored. + */ + prom_argc = 3; + prom_argv = csb_arg; + prom_envp = csb_env; + csb_arg[1] = arg1; + csb_arg[2] = arg2; + csb_env[0] = env1; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_CSB250; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x02000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.24/arch/mips/au1000/csb250/irqmap.c linux-2.4.25/arch/mips/au1000/csb250/irqmap.c --- linux-2.4.24/arch/mips/au1000/csb250/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/csb250/irqmap.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,100 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.24/arch/mips/au1000/db1x00/board_setup.c linux-2.4.25/arch/mips/au1000/db1x00/board_setup.c --- linux-2.4.24/arch/mips/au1000/db1x00/board_setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/db1x00/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -62,7 +62,7 @@ au_writel(pin_func, SYS_PINFUNC); #endif -#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1000)) +#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) /* set IRFIRSEL instead of GPIO15 */ pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); au_writel(pin_func, SYS_PINFUNC); diff -urN linux-2.4.24/arch/mips/au1000/hydrogen3/Makefile linux-2.4.25/arch/mips/au1000/hydrogen3/Makefile --- linux-2.4.24/arch/mips/au1000/hydrogen3/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/hydrogen3/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,22 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor PB1000 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := hydrogen3.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/au1000/hydrogen3/board_setup.c linux-2.4.25/arch/mips/au1000/hydrogen3/board_setup.c --- linux-2.4.24/arch/mips/au1000/hydrogen3/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/hydrogen3/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,71 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Db1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + +#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) + /* set IRFIRSEL instead of GPIO15 */ + pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); + au_writel(pin_func, SYS_PINFUNC); + au_sync(); +#endif + + printk("AMD Alchemy Hydrogen3 Board\n"); +} diff -urN linux-2.4.24/arch/mips/au1000/hydrogen3/init.c linux-2.4.25/arch/mips/au1000/hydrogen3/init.c --- linux-2.4.24/arch/mips/au1000/hydrogen3/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/hydrogen3/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,77 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1000 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ +#ifdef CONFIG_MIPS_BOSPORUS + return "Alchemy Bosporus Gateway Reference"; +#else + return "Alchemy Db1x00"; +#endif +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_DB1000; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.24/arch/mips/au1000/hydrogen3/irqmap.c linux-2.4.25/arch/mips/au1000/hydrogen3/irqmap.c --- linux-2.4.24/arch/mips/au1000/hydrogen3/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/hydrogen3/irqmap.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,90 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + +// { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.24/arch/mips/au1000/mtx-1/Makefile linux-2.4.25/arch/mips/au1000/mtx-1/Makefile --- linux-2.4.24/arch/mips/au1000/mtx-1/Makefile 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/mtx-1/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -2,7 +2,7 @@ # Copyright 2003 MontaVista Software Inc. # Author: MontaVista Software, Inc. # ppopov@mvista.com or source@mvista.com -# Bruno Randolf +# Bruno Randolf # # Makefile for 4G Systems MTX-1 board. # diff -urN linux-2.4.24/arch/mips/au1000/mtx-1/board_setup.c linux-2.4.25/arch/mips/au1000/mtx-1/board_setup.c --- linux-2.4.24/arch/mips/au1000/mtx-1/board_setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/mtx-1/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,12 +1,12 @@ /* * * BRIEF MODULE DESCRIPTION - * MTX-1 board setup. + * 4G Systems MTX-1 board setup. * * Copyright 2003 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com - * Bruno Randolf + * Bruno Randolf * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -50,12 +50,9 @@ void __init board_setup(void) { - u32 pin_func; - rtc_ops = &no_rtc_ops; #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) - #ifdef CONFIG_AU1X00_USB_DEVICE // 2nd USB port is USB device au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); @@ -63,10 +60,8 @@ // enable USB power switch au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); au_writel( 0x100000, GPIO2_OUTPUT ); - #endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - #ifdef CONFIG_PCI #if defined(__MIPSEB__) au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); @@ -80,8 +75,11 @@ // set U3/GPIO23 to GPIO23 (SYS_PF_U3) au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); - // initialize GPIO: none used ATM + // initialize GPIO au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); + au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF + au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF + au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF // enable LED and set it to green au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); diff -urN linux-2.4.24/arch/mips/au1000/mtx-1/init.c linux-2.4.25/arch/mips/au1000/mtx-1/init.c --- linux-2.4.24/arch/mips/au1000/mtx-1/init.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/mtx-1/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,12 +1,12 @@ /* * * BRIEF MODULE DESCRIPTION - * MTX-1 board setup + * 4G Systems MTX-1 board setup * * Copyright 2003 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com - * Bruno Randolf + * Bruno Randolf * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff -urN linux-2.4.24/arch/mips/au1000/pb1000/board_setup.c linux-2.4.25/arch/mips/au1000/pb1000/board_setup.c --- linux-2.4.24/arch/mips/au1000/pb1000/board_setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/pb1000/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -186,7 +186,9 @@ case 0x02: /* HB */ break; default: /* HC and newer */ - au_writel(0x00000060, 0xb190003c); + /* Enable sys bus clock divider when IDLE state or no bus + activity. */ + au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); break; } } diff -urN linux-2.4.24/arch/mips/au1000/pb1100/board_setup.c linux-2.4.25/arch/mips/au1000/pb1100/board_setup.c --- linux-2.4.24/arch/mips/au1000/pb1100/board_setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/pb1100/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -67,16 +67,6 @@ udelay(100); #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif // configure pins GPIO[14:9] as GPIO pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); @@ -120,7 +110,8 @@ au_writel(pin_func, SYS_PINFUNC); #endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) - au_writel(0x00000060, 0xb190003c); + /* Enable sys bus clock divider when IDLE state or no bus activity. */ + au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); #ifdef CONFIG_RTC rtc_ops = &pb1500_rtc_ops; diff -urN linux-2.4.24/arch/mips/au1000/pb1500/board_setup.c linux-2.4.25/arch/mips/au1000/pb1500/board_setup.c --- linux-2.4.24/arch/mips/au1000/pb1500/board_setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/au1000/pb1500/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -132,8 +132,8 @@ au_sync(); #endif - /* Enable BCLK switching */ - au_writel(0x00000060, 0xb190003c); + /* Enable sys bus clock divider when IDLE state or no bus activity. */ + au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); #ifdef CONFIG_RTC rtc_ops = &pb1500_rtc_ops; diff -urN linux-2.4.24/arch/mips/au1000/pb1550/Makefile linux-2.4.25/arch/mips/au1000/pb1550/Makefile --- linux-2.4.24/arch/mips/au1000/pb1550/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/pb1550/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,22 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor PB1000 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := pb1550.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/au1000/pb1550/board_setup.c linux-2.4.25/arch/mips/au1000/pb1550/board_setup.c --- linux-2.4.24/arch/mips/au1000/pb1550/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/pb1550/board_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,67 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1550 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +static BCSR * const bcsr = (BCSR *)0xB3000000; + +void __init board_setup(void) +{ + u32 pin_func; + rtc_ops = &no_rtc_ops; + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + + au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ + + printk("AMD Alchemy Pb1550 Board\n"); +} diff -urN linux-2.4.24/arch/mips/au1000/pb1550/init.c linux-2.4.25/arch/mips/au1000/pb1550/init.c --- linux-2.4.24/arch/mips/au1000/pb1550/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/pb1550/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,73 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1550 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "AMD Alchemy PbAu1550"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_PB1000; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.24/arch/mips/au1000/pb1550/irqmap.c linux-2.4.25/arch/mips/au1000/pb1550/irqmap.c --- linux-2.4.24/arch/mips/au1000/pb1550/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/au1000/pb1550/irqmap.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,93 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_TOY_MATCH0_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_TOY_MATCH1_INT,INTC_INT_RISE_EDGE, 0 }, + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1550_TOY_MATCH2_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_RTC_MATCH0_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_RTC_MATCH1_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_RTC_MATCH2_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_RTC_MATCH2_INT,INTC_INT_RISE_EDGE, 0 }, + { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + + /* + * Need to define platform dependant GPIO ints here + */ + #warning PbAu1550 needs GPIO Interrupts defined + +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.24/arch/mips/boot/Makefile linux-2.4.25/arch/mips/boot/Makefile --- linux-2.4.24/arch/mips/boot/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.25/arch/mips/boot/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -24,7 +24,7 @@ drop-sections = .reginfo .mdebug strip-flags = $(addprefix --remove-section=,$(drop-sections)) -all: vmlinux.ecoff addinitrd +all: vmlinux.ecoff vmlinux.srec addinitrd vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) @@ -32,6 +32,9 @@ elf2ecoff: elf2ecoff.c $(HOSTCC) -o $@ $^ +vmlinux.srec: $(CONFIGURE) $(TOPDIR)/vmlinux + $(OBJCOPY) -S -O srec $(strip-flags) $(TOPDIR)/vmlinux vmlinux.srec + addinitrd: addinitrd.c $(HOSTCC) -o $@ $^ @@ -40,10 +43,12 @@ clean: rm -f vmlinux.ecoff + rm -f vmlinux.srec rm -f zImage zImage.tmp mrproper: rm -f vmlinux.ecoff + rm -f vmlinux.srec rm -f addinitrd rm -f elf2ecoff diff -urN linux-2.4.24/arch/mips/config-shared.in linux-2.4.25/arch/mips/config-shared.in --- linux-2.4.24/arch/mips/config-shared.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/mips/config-shared.in 2004-02-18 05:36:30.000000000 -0800 @@ -31,8 +31,11 @@ fi dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32 dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 +dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32 dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55 dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL @@ -53,6 +56,9 @@ bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET bool 'Support for IBM WorkPad z50' CONFIG_IBM_WORKPAD +if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then + tristate ' NEC VRC4171 support' CONFIG_VRC4171 +fi bool 'Support for LASAT Networks platforms' CONFIG_LASAT if [ "$CONFIG_LASAT" = "y" ]; then tristate ' PICVUE LCD display driver' CONFIG_PICVUE @@ -71,6 +77,11 @@ bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G bool 'Support for Momentum Ocelot-C and -CS boards' CONFIG_MOMENCO_OCELOT_C +bool 'Support for Momentum Jaguar-ATX boards' CONFIG_MOMENCO_JAGUAR_ATX +bool 'Support PMC-Sierra Yosemite board' CONFIG_PMC_YOSEMITE +if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then + bool ' Hypertransport Support for PMC-Sierra Yosemite' CONFIG_HYPERTRANSPORT +fi dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476 bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477 @@ -117,10 +128,10 @@ if [ "$CONFIG_SIBYTE_UNKNOWN" = "y" ]; then choice ' BCM1xxx SOC Type' \ - "BCM91250 CONFIG_SIBYTE_SB1250 \ - BCM91120 CONFIG_SIBYTE_BCM1120 \ - BCM91125 CONFIG_SIBYTE_BCM1125 \ - BCM91125H CONFIG_SIBYTE_BCM1125H" CONFIG_SIBYTE_SB1250 + "BCM1250 CONFIG_SIBYTE_SB1250 \ + BCM1120 CONFIG_SIBYTE_BCM1120 \ + BCM1125 CONFIG_SIBYTE_BCM1125 \ + BCM1125H CONFIG_SIBYTE_BCM1125H" CONFIG_SIBYTE_SB1250 unset CONFIG_SIBYTE_BOARD else define_bool CONFIG_SIBYTE_BOARD y @@ -173,6 +184,10 @@ fi bool ' Support for Bus Watcher statistics' CONFIG_SIBYTE_BUS_WATCHER + if [ "$CONFIG_SIBYTE_TBPROF" = "n" ]; then + dep_bool ' Capture bus trace before bus error' CONFIG_SIBYTE_BW_TRACE $CONFIG_SIBYTE_BUS_WATCHER + fi + bool ' Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF bool ' Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF @@ -224,7 +239,6 @@ # # Select some configuration options automatically based on user selections. # - if [ "$CONFIG_ACER_PICA_61" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_I8259 y @@ -237,7 +251,6 @@ if [ "$CONFIG_CASIO_E55" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_ISA y define_bool CONFIG_DUMMY_KEYB y @@ -246,6 +259,7 @@ if [ "$CONFIG_MIPS_MIRAGE" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y @@ -255,6 +269,7 @@ if [ "$CONFIG_MIPS_BOSPORUS" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y @@ -264,6 +279,7 @@ if [ "$CONFIG_MIPS_PB1000" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1000 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y @@ -274,6 +290,7 @@ if [ "$CONFIG_MIPS_PB1100" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_PCI_AUTO n define_bool CONFIG_NEW_PCI y @@ -285,6 +302,7 @@ if [ "$CONFIG_MIPS_PB1500" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -294,6 +312,7 @@ if [ "$CONFIG_MIPS_DB1000" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1000 y + define_bool CONFIG_NEW_TIME_C y # CONFIG_PCI needed for USB define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y @@ -305,6 +324,7 @@ if [ "$CONFIG_MIPS_DB1500" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -314,6 +334,17 @@ if [ "$CONFIG_MIPS_DB1100" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_SWAP_IO_SPACE y +fi +if [ "$CONFIG_MIPS_HYDROGEN3" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y @@ -323,6 +354,7 @@ if [ "$CONFIG_MIPS_XXS1500" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -332,12 +364,34 @@ if [ "$CONFIG_MIPS_MTX1" = "y" ]; then define_bool CONFIG_SOC_AU1X00 y define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y +fi +if [ "$CONFIG_COGENT_CSB250" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_PB1550" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1550 y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO n + define_bool CONFIG_PC_KEYB y fi if [ "$CONFIG_MIPS_COBALT" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y define_bool CONFIG_COBALT_LCD y define_bool CONFIG_I8259 y define_bool CONFIG_PCI y @@ -353,13 +407,11 @@ fi if [ "$CONFIG_MIPS_EV64120" = "y" ]; then define_bool CONFIG_PCI y - define_bool CONFIG_ISA n define_bool CONFIG_MIPS_GT64120 y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_EV96100" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y define_bool CONFIG_MIPS_GT64120 y define_bool CONFIG_MIPS_GT96100 y @@ -389,10 +441,8 @@ if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_ISA y - define_bool CONFIG_DUMMY_KEYB y define_bool CONFIG_SCSI n fi if [ "$CONFIG_LASAT" = "y" ]; then @@ -461,7 +511,6 @@ define_bool CONFIG_PCI n fi if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y define_bool CONFIG_SYSCLK_100 y define_bool CONFIG_SWAP_IO_SPACE_W y @@ -482,7 +531,27 @@ define_bool CONFIG_SWAP_IO_SPACE y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_BOOT_ELF32 y fi +if [ "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then + define_bool CONFIG_PCI y + define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_BOOT_ELF32 y +fi + +if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then + define_bool CONFIG_PCI y + define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_BOOT_ELF32 y + define_bool CONFIG_HIGHMEM y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y +fi + if [ "$CONFIG_DDB5074" = "y" ]; then define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y @@ -528,9 +597,7 @@ if [ "$CONFIG_NEC_EAGLE" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_ISA n define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -585,9 +652,7 @@ if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_ISA n define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -597,9 +662,7 @@ if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_ISA n define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -630,9 +693,7 @@ if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_ISA n define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -642,9 +703,7 @@ if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_VR41XX_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_ISA n define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y @@ -676,8 +735,19 @@ R8000 CONFIG_CPU_R8000 \ R10000 CONFIG_CPU_R10000 \ RM7000 CONFIG_CPU_RM7000 \ + RM9000 CONFIG_CPU_RM9000 \ SB1 CONFIG_CPU_SB1" R4x00 +if [ "$CONFIG_CPU_R3000" = "n" -a "$CONFIG_CPU_TX39XX" = "n" -a \ + "$CONFIG_EXPERIMENTAL" = "y" ]; then + choice 'Kernel page size' \ + "4KB CONFIG_PAGE_SIZE_4KB \ + 16KB CONFIG_PAGE_SIZE_16KB \ + 64KB CONFIG_PAGE_SIZE_64KB" 4KB +else + define_bool CONFIG_PAGE_SIZE_4KB y +fi + if [ "$CONFIG_SMP_CAPABLE" = "y" ]; then bool ' Multi-Processing support' CONFIG_SMP fi @@ -693,7 +763,14 @@ fi if [ "$CONFIG_CPU_RM7000" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y + define_bool CONFIG_CPU_HAS_PREFETCH y + define_bool CONFIG_RM7000_CPU_SCACHE y +fi +if [ "$CONFIG_CPU_RM9000" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_CPU_HAS_PREFETCH y + define_bool CONFIG_RM7000_CPU_SCACHE y fi if [ "$CONFIG_CPU_SB1" = "y" ]; then @@ -720,6 +797,7 @@ if [ "$CONFIG_CPU_R4X00" = "y" -o \ "$CONFIG_CPU_R5000" = "y" -o \ "$CONFIG_CPU_RM7000" = "y" -o \ + "$CONFIG_CPU_RM9000" = "y" -o \ "$CONFIG_CPU_R10000" = "y" -o \ "$CONFIG_CPU_SB1" = "y" -o \ "$CONFIG_CPU_MIPS32" = "y" -o \ @@ -811,10 +889,6 @@ fi fi -if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then - bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742 -fi - if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX fi @@ -827,28 +901,24 @@ bool 'ARC console support' CONFIG_ARC_CONSOLE fi -if [ "$CONFIG_SGI_IP22" = "y" ]; then - dep_bool 'Indigo-2 (IP22) EISA bus support' CONFIG_IP22_EISA $CONFIG_EXPERIMENTAL -fi +bool 'Networking support' CONFIG_NET -if [ "$CONFIG_IP22_EISA" = "y" ]; then - define_bool CONFIG_EISA y - bool ' ISA bus support' CONFIG_ISA +if [ "$CONFIG_SGI_IP22" = "y" -o "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \ + "$CONFIG_OLIVETTI_M700" = "y" -o "$CONFIG_SNI_RM200_PCI" = "y" ]; then + bool 'EISA bus support' CONFIG_EISA fi -bool 'Networking support' CONFIG_NET - if [ "$CONFIG_PCI" != "y" ]; then define_bool CONFIG_PCI n fi source drivers/pci/Config.in +if [ "$CONFIG_EISA" = "y" -a "$CONFIG_ISA" != "y" ]; then + define_bool CONFIG_ISA y +fi if [ "$CONFIG_ISA" != "y" ]; then define_bool CONFIG_ISA n - define_bool CONFIG_EISA n -else - define_bool CONFIG_EISA y fi dep_bool 'TURBOchannel support' CONFIG_TC $CONFIG_DECSTATION @@ -885,6 +955,7 @@ fi tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER if [ "$CONFIG_SOC_AU1X00" = "y" ]; then bool 'Power Management support' CONFIG_PM @@ -924,7 +995,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -939,6 +1009,10 @@ fi endmenu +source drivers/message/fusion/Config.in + +source drivers/ieee1394/Config.in + if [ "$CONFIG_PCI" = "y" -a "$CONFIG_MIPS32" = "y" ]; then source drivers/message/i2o/Config.in fi @@ -1033,14 +1107,25 @@ bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG bool 'Remote GDB kernel debugging' CONFIG_KGDB dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB +if [ "$CONFIG_KGDB" = "y" ]; then + define_bool CONFIG_DEBUG_INFO y +else + bool 'Debugging symbols' CONFIG_DEBUG_INFO +fi if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then - bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS + dep_bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS $CONFIG_DEBUG_INFO fi bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ if [ "$CONFIG_SMP" != "y" ]; then bool 'Run uncached' CONFIG_MIPS_UNCACHED else - int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 + if [ "$CONFIG_MIPS32" = "y" ]; then + int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 + else + if [ "$CONFIG_MIPS64" = "y" ]; then + int 'Maximum number of CPUs (2-64)' CONFIG_NR_CPUS 64 + fi + fi fi int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 diff -urN linux-2.4.24/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.25/arch/mips/ddb5xxx/ddb5074/setup.c --- linux-2.4.24/arch/mips/ddb5xxx/ddb5074/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/ddb5xxx/ddb5074/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -36,10 +36,6 @@ extern void breakpoint(void); #endif -#if defined(CONFIG_SERIAL_CONSOLE) -extern void console_setup(char *); -#endif - extern struct ide_ops std_ide_ops; extern struct kbd_ops std_kbd_ops; extern struct rtc_ops ddb_rtc_ops; diff -urN linux-2.4.24/arch/mips/ddb5xxx/ddb5476/setup.c linux-2.4.25/arch/mips/ddb5xxx/ddb5476/setup.c --- linux-2.4.24/arch/mips/ddb5xxx/ddb5476/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/ddb5xxx/ddb5476/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -84,7 +84,7 @@ static void __init ddb_time_init(void) { #if defined(USE_CPU_COUNTER_TIMER) - mips_counter_frequency = CPU_COUNTER_FREQUENCY; + mips_hpt_frequency = CPU_COUNTER_FREQUENCY; #endif /* we have ds1396 RTC chip */ diff -urN linux-2.4.24/arch/mips/ddb5xxx/ddb5477/setup.c linux-2.4.25/arch/mips/ddb5xxx/ddb5477/setup.c --- linux-2.4.24/arch/mips/ddb5xxx/ddb5477/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/ddb5xxx/ddb5477/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -138,11 +138,11 @@ bus_frequency = detect_bus_frequency(rtc_base); } - /* mips_counter_frequency is 1/2 of the cpu core freq */ + /* mips_hpt_frequency is 1/2 of the cpu core freq */ i = (read_c0_config() >> 28 ) & 7; if ((current_cpu_data.cputype == CPU_R5432) && (i == 3)) i = 4; - mips_counter_frequency = bus_frequency*(i+4)/4; + mips_hpt_frequency = bus_frequency*(i+4)/4; } extern int setup_irq(unsigned int irq, struct irqaction *irqaction); diff -urN linux-2.4.24/arch/mips/dec/setup.c linux-2.4.25/arch/mips/dec/setup.c --- linux-2.4.24/arch/mips/dec/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/dec/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -48,6 +48,11 @@ extern asmlinkage void decstation_handle_int(void); +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + spinlock_t ioasic_ssr_lock; volatile u32 *ioasic_base; @@ -131,6 +136,11 @@ void __init decstation_setup(void) { +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif board_be_init = dec_be_init; board_time_init = dec_time_init; board_timer_setup = dec_timer_setup; diff -urN linux-2.4.24/arch/mips/dec/time.c linux-2.4.25/arch/mips/dec/time.c --- linux-2.4.24/arch/mips/dec/time.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/dec/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -8,22 +8,15 @@ * found in some MIPS systems. * */ -#include #include #include +#include #include -#include +#include #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +#include + +#include #include #include @@ -31,9 +24,6 @@ #include #include -#include -#include - static unsigned long dec_rtc_get_time(void) { @@ -144,6 +134,11 @@ } +static int dec_timer_state(void) +{ + return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0; +} + static void dec_timer_ack(void) { CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */ @@ -169,19 +164,23 @@ rtc_get_time = dec_rtc_get_time; rtc_set_mmss = dec_rtc_set_mmss; + mips_timer_state = dec_timer_state; mips_timer_ack = dec_timer_ack; + if (!cpu_has_counter && IOASIC) { /* For pre-R4k systems we use the I/O ASIC's counter. */ mips_hpt_read = dec_ioasic_hpt_read; mips_hpt_init = dec_ioasic_hpt_init; } + + /* Set up the rate of periodic DS1287 interrupts. */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); } void __init dec_timer_setup(struct irqaction *irq) { + setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); + /* Enable periodic DS1287 interrupts. */ - CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); - - setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); } diff -urN linux-2.4.24/arch/mips/defconfig linux-2.4.25/arch/mips/defconfig --- linux-2.4.24/arch/mips/defconfig 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,7 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -114,11 +122,10 @@ # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y CONFIG_ARC_CONSOLE=y -# CONFIG_IP22_EISA is not set CONFIG_NET=y +# CONFIG_EISA is not set # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -137,6 +144,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -163,6 +171,7 @@ # 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 is not set @@ -207,6 +216,12 @@ # CONFIG_SYN_COOKIES 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 @@ -252,7 +267,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -298,6 +312,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -324,6 +339,15 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -415,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -485,14 +510,15 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -CONFIG_INDYDOG=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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_MIPS_RTC is not set -CONFIG_SGI_DS1286=y +CONFIG_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -502,6 +528,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -560,6 +590,11 @@ # 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 @@ -656,6 +691,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -663,6 +700,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -674,8 +716,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-atlas linux-2.4.25/arch/mips/defconfig-atlas --- linux-2.4.24/arch/mips/defconfig-atlas 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-atlas 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -97,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -115,7 +123,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -134,6 +141,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -160,6 +168,7 @@ # 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 @@ -205,6 +214,12 @@ # CONFIG_SYN_COOKIES 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 @@ -250,7 +265,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -294,6 +308,7 @@ # 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 @@ -334,6 +349,20 @@ # 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 @@ -470,6 +499,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -516,6 +546,7 @@ # 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 @@ -530,6 +561,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -588,6 +623,11 @@ # 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 @@ -654,6 +694,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -665,8 +710,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-bosporus linux-2.4.25/arch/mips/defconfig-bosporus --- linux-2.4.24/arch/mips/defconfig-bosporus 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-bosporus 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PC_KEYB=y CONFIG_PCI=y CONFIG_NEW_PCI=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -142,6 +150,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -191,6 +200,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -238,6 +249,7 @@ # 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 @@ -331,8 +343,19 @@ # 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 @@ -378,7 +401,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -424,6 +446,7 @@ # 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 @@ -458,6 +481,20 @@ # 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 @@ -541,6 +578,7 @@ # CONFIG_AIRO is not set # CONFIG_HERMES is not set # CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set # CONFIG_PCI_HERMES is not set CONFIG_NET_WIRELESS=y @@ -582,6 +620,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -676,10 +715,12 @@ # 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=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -689,6 +730,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # CONFIG_AU1X00_GPIO is not set # CONFIG_TS_AU1X00_ADS7846 is not set @@ -749,6 +794,11 @@ # 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 @@ -904,6 +954,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -915,8 +970,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -929,3 +986,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-capcella linux-2.4.25/arch/mips/defconfig-capcella --- linux-2.4.24/arch/mips/defconfig-capcella 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-capcella 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,9 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -99,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -113,7 +119,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -132,6 +137,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -158,6 +164,7 @@ # 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 is not set @@ -202,6 +209,12 @@ # CONFIG_SYN_COOKIES 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 @@ -278,7 +291,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -290,6 +302,20 @@ # CONFIG_SCSI 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 @@ -426,6 +452,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -436,6 +463,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -493,8 +521,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -509,6 +537,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -567,6 +599,11 @@ # 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 @@ -643,6 +680,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -654,8 +696,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-cobalt linux-2.4.25/arch/mips/defconfig-cobalt --- linux-2.4.24/arch/mips/defconfig-cobalt 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-cobalt 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set CONFIG_MIPS_COBALT=y @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -67,6 +71,7 @@ # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_COBALT_LCD=y CONFIG_I8259=y CONFIG_PCI=y @@ -92,7 +97,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -106,7 +115,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -125,6 +133,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -151,6 +160,7 @@ # 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 @@ -191,6 +201,12 @@ # CONFIG_SYN_COOKIES 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 @@ -304,7 +320,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -316,6 +331,20 @@ # CONFIG_SCSI 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 @@ -454,6 +483,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -500,6 +530,7 @@ # 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 @@ -514,6 +545,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -572,6 +607,11 @@ # 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 @@ -637,6 +677,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -648,8 +693,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-csb250 linux-2.4.25/arch/mips/defconfig-csb250 --- linux-2.4.24/arch/mips/defconfig-csb250 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/defconfig-csb250 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,903 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +CONFIG_COGENT_CSB250=y +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_BINFMT_IRIX is not set +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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 is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# 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 is not set + +# +# 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI 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_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY 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_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# 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 + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA 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 + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX 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_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# 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 is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +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 is not set +# 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_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 is not set + +# +# 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 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# 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 + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# 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 + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# 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_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-db1000 linux-2.4.25/arch/mips/defconfig-db1000 --- linux-2.4.24/arch/mips/defconfig-db1000 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-db1000 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1000=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y # CONFIG_PCI_AUTO is not set @@ -97,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -114,7 +123,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -132,7 +140,6 @@ # CONFIG_PCMCIA_PB1X00 is not set CONFIG_PCMCIA_DB1X00=y # CONFIG_PCMCIA_XXS1500 is not set -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -152,6 +159,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -203,6 +211,8 @@ CONFIG_MTD_DB1X00=y CONFIG_MTD_DB1X00_BOOT=y CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -250,6 +260,7 @@ # 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 @@ -303,8 +314,19 @@ # 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 @@ -381,7 +403,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -393,6 +414,20 @@ # CONFIG_SCSI 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 @@ -538,6 +573,7 @@ # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -554,6 +590,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -648,10 +685,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -661,6 +700,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -727,6 +770,11 @@ # 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 @@ -849,6 +897,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -953,6 +1003,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -964,8 +1019,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -978,3 +1035,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-db1100 linux-2.4.25/arch/mips/defconfig-db1100 --- linux-2.4.24/arch/mips/defconfig-db1100 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-db1100 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1100=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,7 +139,6 @@ # CONFIG_PCMCIA_PB1X00 is not set CONFIG_PCMCIA_DB1X00=y # CONFIG_PCMCIA_XXS1500 is not set -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -151,6 +158,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -202,6 +210,8 @@ CONFIG_MTD_DB1X00=y # CONFIG_MTD_DB1X00_BOOT is not set CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -249,6 +259,7 @@ # 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 @@ -302,8 +313,19 @@ # 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 @@ -380,7 +402,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -392,6 +413,20 @@ # CONFIG_SCSI 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 @@ -537,6 +572,7 @@ # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -553,6 +589,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -647,10 +684,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -660,6 +699,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -726,6 +769,11 @@ # 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 @@ -837,6 +885,7 @@ # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set CONFIG_FB_AU1100=y +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -888,6 +937,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -992,6 +1043,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -1003,8 +1059,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -1017,3 +1075,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-db1500 linux-2.4.25/arch/mips/defconfig-db1500 --- linux-2.4.24/arch/mips/defconfig-db1500 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-db1500 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,7 +139,6 @@ # CONFIG_PCMCIA_PB1X00 is not set CONFIG_PCMCIA_DB1X00=y # CONFIG_PCMCIA_XXS1500 is not set -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -151,6 +158,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -178,6 +186,7 @@ # 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 @@ -231,8 +240,19 @@ # 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 @@ -346,7 +366,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -358,6 +377,20 @@ # CONFIG_SCSI 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 @@ -476,6 +509,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -570,10 +604,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -583,6 +619,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -649,6 +689,11 @@ # 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 @@ -728,6 +773,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -832,6 +879,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -843,8 +895,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -857,3 +911,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-ddb5476 linux-2.4.25/arch/mips/defconfig-ddb5476 --- linux-2.4.24/arch/mips/defconfig-ddb5476 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ddb5476 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set CONFIG_DDB5476=y # CONFIG_DDB5477 is not set @@ -97,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -110,7 +118,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_NET=y # CONFIG_PCI_NAMES is not set -CONFIG_EISA=y # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -129,6 +136,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -155,6 +163,7 @@ # 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 is not set @@ -198,6 +207,12 @@ # CONFIG_SYN_COOKIES 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 @@ -310,7 +325,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -322,6 +336,20 @@ # CONFIG_SCSI 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 @@ -468,6 +496,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -519,6 +548,7 @@ # 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 @@ -533,6 +563,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -591,6 +625,11 @@ # 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 @@ -658,6 +697,7 @@ # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -679,6 +719,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -690,8 +735,10 @@ CONFIG_RUNTIME_DEBUG=y # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-ddb5477 linux-2.4.25/arch/mips/defconfig-ddb5477 --- linux-2.4.24/arch/mips/defconfig-ddb5477 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ddb5477 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set CONFIG_DDB5477=y @@ -96,7 +100,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -110,7 +118,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -129,6 +136,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -155,6 +163,7 @@ # 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 is not set @@ -198,6 +207,12 @@ # CONFIG_SYN_COOKIES 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 @@ -243,7 +258,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -252,6 +266,20 @@ # CONFIG_SCSI 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 @@ -390,6 +418,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -436,6 +465,7 @@ # 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 @@ -450,6 +480,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -508,6 +542,11 @@ # 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 @@ -576,6 +615,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -583,6 +624,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -594,8 +640,10 @@ CONFIG_RUNTIME_DEBUG=y # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-decstation linux-2.4.25/arch/mips/defconfig-decstation --- linux-2.4.24/arch/mips/defconfig-decstation 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-decstation 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -94,7 +98,9 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -108,7 +114,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set CONFIG_TC=y # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -127,6 +132,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -153,6 +159,7 @@ # 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 is not set @@ -196,6 +203,12 @@ # CONFIG_SYN_COOKIES 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 @@ -241,7 +254,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -286,6 +298,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -312,6 +325,15 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -403,6 +425,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -474,6 +497,7 @@ # 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 @@ -488,6 +512,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -546,6 +574,11 @@ # 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 @@ -611,6 +644,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -622,8 +660,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-e55 linux-2.4.25/arch/mips/defconfig-e55 --- linux-2.4.24/arch/mips/defconfig-e55 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-e55 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set CONFIG_CASIO_E55=y # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,7 +75,6 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_ISA=y CONFIG_DUMMY_KEYB=y @@ -96,7 +99,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -109,7 +116,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_NET=y # CONFIG_PCI is not set -CONFIG_EISA=y # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +134,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +161,7 @@ # 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 is not set @@ -195,6 +203,12 @@ # CONFIG_SYN_COOKIES 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 @@ -270,7 +284,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -282,6 +295,15 @@ # CONFIG_SCSI 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -380,6 +402,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -395,6 +418,7 @@ # CONFIG_SERIAL_MULTIPORT is not set # CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -452,8 +476,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -468,6 +492,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -526,6 +554,11 @@ # 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 @@ -602,6 +635,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -613,8 +651,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-eagle linux-2.4.25/arch/mips/defconfig-eagle --- linux-2.4.24/arch/mips/defconfig-eagle 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-eagle 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -72,9 +76,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -100,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -114,7 +120,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -148,6 +153,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -203,6 +209,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -250,6 +258,7 @@ # 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 is not set @@ -294,6 +303,12 @@ # CONFIG_SYN_COOKIES 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 @@ -370,7 +385,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -382,6 +396,20 @@ # CONFIG_SCSI 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 @@ -534,6 +562,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -544,6 +573,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -605,8 +635,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -621,6 +651,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -688,6 +722,11 @@ # 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 @@ -867,6 +906,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -878,8 +922,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -892,3 +938,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-ev64120 linux-2.4.25/arch/mips/defconfig-ev64120 --- linux-2.4.24/arch/mips/defconfig-ev64120 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ev64120 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -53,6 +55,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -74,7 +78,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_PCI=y -# CONFIG_ISA is not set CONFIG_MIPS_GT64120=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y @@ -98,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -114,7 +121,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -133,6 +139,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -159,6 +166,7 @@ # 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 is not set @@ -201,6 +209,12 @@ # CONFIG_SYN_COOKIES 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 @@ -246,7 +260,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -255,6 +268,20 @@ # CONFIG_SCSI 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 @@ -398,6 +425,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -444,6 +472,7 @@ # 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 @@ -457,6 +486,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -515,6 +548,11 @@ # 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 @@ -566,6 +604,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -577,8 +620,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-ev96100 linux-2.4.25/arch/mips/defconfig-ev96100 --- linux-2.4.24/arch/mips/defconfig-ev96100 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ev96100 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -69,7 +73,6 @@ # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BOARD_SCACHE=y CONFIG_PCI=y CONFIG_MIPS_GT64120=y CONFIG_MIPS_GT96100=y @@ -98,8 +101,14 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -115,7 +124,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -134,6 +142,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -160,6 +169,7 @@ # 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 is not set @@ -202,6 +212,12 @@ # CONFIG_SYN_COOKIES 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 @@ -247,7 +263,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -256,6 +271,20 @@ # CONFIG_SCSI 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 @@ -395,6 +424,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -441,6 +471,7 @@ # 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 @@ -454,6 +485,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -512,6 +547,11 @@ # 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 @@ -563,6 +603,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -574,8 +619,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-hp-lj linux-2.4.25/arch/mips/defconfig-hp-lj --- linux-2.4.24/arch/mips/defconfig-hp-lj 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-hp-lj 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -94,7 +98,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -109,7 +117,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +135,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -180,6 +188,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -229,6 +239,7 @@ # 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 is not set @@ -272,6 +283,12 @@ # CONFIG_SYN_COOKIES 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 @@ -385,7 +402,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -397,6 +413,20 @@ # CONFIG_SCSI 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 @@ -507,6 +537,7 @@ # CONFIG_AIRO is not set # CONFIG_HERMES is not set # CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set # CONFIG_PCI_HERMES is not set CONFIG_NET_WIRELESS=y @@ -546,6 +577,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -591,6 +623,7 @@ # 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 @@ -605,6 +638,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -664,6 +701,11 @@ # 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 @@ -716,6 +758,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -727,8 +774,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-hydrogen3 linux-2.4.25/arch/mips/defconfig-hydrogen3 --- linux-2.4.24/arch/mips/defconfig-hydrogen3 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/defconfig-hydrogen3 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,1076 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +CONFIG_MIPS_HYDROGEN3=y +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1100=y +CONFIG_NEW_TIME_C=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PM 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 is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL 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_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# 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_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +CONFIG_MTD_HYDIII=y +# CONFIG_MTD_MIRAGE is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# 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 + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# 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 is not set + +# +# 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI 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_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY 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_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# 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 + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX 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_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# 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 is not set +# CONFIG_JBD is not set +# 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 is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +CONFIG_FB_AU1100=y +# CONFIG_FB_IT8181 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# 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 + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# 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 + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# 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_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# 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 + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-ip22 linux-2.4.25/arch/mips/defconfig-ip22 --- linux-2.4.24/arch/mips/defconfig-ip22 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ip22 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,7 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -114,11 +122,10 @@ # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y CONFIG_ARC_CONSOLE=y -# CONFIG_IP22_EISA is not set CONFIG_NET=y +# CONFIG_EISA is not set # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -137,6 +144,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -163,6 +171,7 @@ # 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 is not set @@ -207,6 +216,12 @@ # CONFIG_SYN_COOKIES 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 @@ -252,7 +267,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -298,6 +312,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -324,6 +339,15 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -415,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -423,30 +448,7 @@ CONFIG_VT_CONSOLE=y # 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_SERIAL_TX3912 is not set -# CONFIG_SERIAL_TX3912_CONSOLE is not set -# CONFIG_SERIAL_TXX9 is not set -# CONFIG_SERIAL_TXX9_CONSOLE is not set -# CONFIG_TXX927_SERIAL is not set -CONFIG_IP22_SERIAL=y +# CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -508,14 +510,15 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -CONFIG_INDYDOG=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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_MIPS_RTC is not set -CONFIG_SGI_DS1286=y +CONFIG_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -525,6 +528,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -583,6 +590,11 @@ # 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 @@ -679,6 +691,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -686,6 +700,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -697,8 +716,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-it8172 linux-2.4.25/arch/mips/defconfig-it8172 --- linux-2.4.24/arch/mips/defconfig-it8172 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-it8172 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -50,6 +52,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -98,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -112,7 +120,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,6 +138,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -183,6 +191,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -230,6 +240,7 @@ # 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 @@ -273,6 +284,12 @@ # CONFIG_SYN_COOKIES 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 @@ -387,7 +404,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -399,6 +415,20 @@ # CONFIG_SCSI 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 @@ -537,6 +567,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -587,11 +618,12 @@ # 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_MIPS_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -601,6 +633,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # CONFIG_ITE_GPIO is not set @@ -660,6 +696,11 @@ # 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 @@ -729,6 +770,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -736,6 +779,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -747,8 +795,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-ivr linux-2.4.25/arch/mips/defconfig-ivr --- linux-2.4.24/arch/mips/defconfig-ivr 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ivr 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -96,7 +100,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -110,7 +118,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -129,6 +136,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -155,6 +163,7 @@ # 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 is not set @@ -198,6 +207,12 @@ # CONFIG_SYN_COOKIES 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 @@ -312,7 +327,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -324,6 +338,20 @@ # CONFIG_SCSI 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 @@ -464,6 +492,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -536,6 +565,7 @@ # 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 @@ -550,6 +580,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -608,6 +642,11 @@ # 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 @@ -767,6 +806,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -778,8 +822,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-jmr3927 linux-2.4.25/arch/mips/defconfig-jmr3927 --- linux-2.4.24/arch/mips/defconfig-jmr3927 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-jmr3927 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -96,7 +100,9 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -107,12 +113,10 @@ # General setup # # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_RTC_DS1742=y # CONFIG_BINFMT_IRIX is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,6 +135,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -157,6 +162,7 @@ # 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 is not set @@ -200,6 +206,12 @@ # CONFIG_SYN_COOKIES 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 @@ -245,7 +257,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -254,6 +265,20 @@ # CONFIG_SCSI 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 @@ -391,6 +416,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -458,11 +484,13 @@ # 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_MIPS_RTC is not set +CONFIG_DS1742=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -472,6 +500,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -530,6 +562,11 @@ # 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 @@ -597,6 +634,7 @@ # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y CONFIG_FBCON_MFB=y @@ -631,6 +669,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -642,8 +685,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-lasat linux-2.4.25/arch/mips/defconfig-lasat --- linux-2.4.24/arch/mips/defconfig-lasat 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-lasat 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -53,6 +55,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,7 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -115,7 +123,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -134,6 +141,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -183,6 +191,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set CONFIG_MTD_LASAT=y @@ -230,6 +240,7 @@ # 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 is not set @@ -269,6 +280,12 @@ # CONFIG_SYN_COOKIES 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 @@ -382,7 +399,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -394,6 +410,20 @@ # CONFIG_SCSI 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 @@ -530,6 +560,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -576,6 +607,7 @@ # 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 @@ -590,6 +622,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -648,6 +684,11 @@ # 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 @@ -714,6 +755,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -725,8 +771,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-malta linux-2.4.25/arch/mips/defconfig-malta --- linux-2.4.24/arch/mips/defconfig-malta 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-malta 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -102,7 +106,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -119,7 +127,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -138,6 +145,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -164,6 +172,7 @@ # 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 is not set @@ -207,6 +216,12 @@ # CONFIG_SYN_COOKIES 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 @@ -252,7 +267,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -296,6 +310,7 @@ # 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 @@ -330,6 +345,20 @@ # 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 @@ -466,6 +495,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -512,6 +542,7 @@ # 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 @@ -526,6 +557,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -584,6 +619,11 @@ # 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 @@ -636,6 +676,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -647,8 +692,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-mirage linux-2.4.25/arch/mips/defconfig-mirage --- linux-2.4.24/arch/mips/defconfig-mirage 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-mirage 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PC_KEYB=y CONFIG_PCI=y CONFIG_NEW_PCI=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -142,6 +150,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -169,6 +178,7 @@ # 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 @@ -222,8 +232,19 @@ # 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 @@ -269,7 +290,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -278,6 +298,20 @@ # CONFIG_SCSI 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 @@ -391,6 +425,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -485,10 +520,12 @@ # 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=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -498,6 +535,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # CONFIG_AU1X00_GPIO is not set # CONFIG_TS_AU1X00_ADS7846 is not set @@ -558,6 +599,11 @@ # 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 @@ -637,6 +683,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -741,6 +789,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -752,8 +805,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -766,3 +821,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-mpc30x linux-2.4.25/arch/mips/defconfig-mpc30x --- linux-2.4.24/arch/mips/defconfig-mpc30x 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-mpc30x 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -72,9 +76,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -100,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -114,7 +120,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -133,6 +138,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -159,6 +165,7 @@ # 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 is not set @@ -203,6 +210,12 @@ # CONFIG_SYN_COOKIES 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 @@ -248,7 +261,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -257,6 +269,20 @@ # CONFIG_SCSI 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 @@ -359,6 +385,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -369,6 +396,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -406,6 +434,7 @@ # 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 @@ -420,6 +449,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -478,6 +511,11 @@ # 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 @@ -657,6 +695,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -668,8 +711,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-mtx-1 linux-2.4.25/arch/mips/defconfig-mtx-1 --- linux-2.4.24/arch/mips/defconfig-mtx-1 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-mtx-1 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set CONFIG_MIPS_MTX1=y +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -95,7 +100,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -112,7 +121,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,6 +139,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -180,6 +189,8 @@ # CONFIG_MTD_XXS1500 is not set CONFIG_MTD_MTX1=y # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -227,11 +238,13 @@ # 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 is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_BLK_STATS is not set @@ -251,39 +264,102 @@ # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_NAT=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_TOS=y +CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=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_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES 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_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_MIRROR is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +# CONFIG_IP_NF_ARP_MANGLE 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_VLAN_8021Q=m # # @@ -296,7 +372,7 @@ # # CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set +CONFIG_BRIDGE=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set @@ -309,12 +385,34 @@ # # QoS and/or fair queueing # -# CONFIG_NET_SCHED is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +# CONFIG_NET_SCH_CSZ is not set +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +# CONFIG_NET_CLS_RSVP6 is not set +CONFIG_NET_CLS_POLICE=y # # Network testing # -# CONFIG_NET_PKTGEN is not set +CONFIG_NET_PKTGEN=m # # Telephony Support @@ -327,13 +425,98 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # # SCSI support # -# CONFIG_SCSI is not set +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# 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 @@ -354,10 +537,10 @@ # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m # CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set +CONFIG_TUN=m # CONFIG_ETHERTAP is not set # @@ -396,13 +579,32 @@ # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -# CONFIG_PPP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m # CONFIG_SLIP is not set # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -440,6 +642,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -511,10 +714,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -524,8 +729,12 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set -# CONFIG_AU1X00_GPIO is not set +CONFIG_AU1X00_GPIO=m # CONFIG_TS_AU1X00_ADS7846 is not set # @@ -535,7 +744,7 @@ # 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_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set @@ -546,28 +755,29 @@ # 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_EXT3_FS=m +CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 # CONFIG_CRAMFS is not set CONFIG_TMPFS=y CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +CONFIG_ISO9660_FS=m +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_FS=m # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y @@ -578,12 +788,17 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +CONFIG_EXT2_FS=m # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set +CONFIG_UDF_FS=m # 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 @@ -600,7 +815,8 @@ CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -610,35 +826,333 @@ # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set +CONFIG_ZISOFS_FS=m # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-15" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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=m +# 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=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m # # Multimedia devices # -# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# +# CONFIG_VIDEO_PROC_FS is not set +# CONFIG_I2C_PARPORT is not set + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=m +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_AU1X00 is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_KAHLUA is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +CONFIG_USB_EMI26=m + +# +# USB Bluetooth can only be used with disabled Bluetooth subsystem +# +CONFIG_USB_MIDI=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_DEBUG=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +CONFIG_USB_DC2XX=m +CONFIG_USB_MDC800=m +CONFIG_USB_SCANNER=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +# CONFIG_USB_W9968CF is not set +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_DABUSB=m + +# +# USB Network adaptors +# +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_KAWETH=m +CONFIG_USB_CATC=m +# CONFIG_USB_AX8817X is not set +CONFIG_USB_CDCETHER=m +CONFIG_USB_USBNET=m + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_RIO500=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_TIGL=m +CONFIG_USB_BRLVGER=m +CONFIG_USB_LCD=m + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set # # Bluetooth support # -# CONFIG_BLUEZ is not set +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +# CONFIG_BLUEZ_HCIUSB_SCO is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y +# CONFIG_BLUEZ_HCIBFUSB is not set +# CONFIG_BLUEZ_HCIDTL1 is not set +# CONFIG_BLUEZ_HCIBT3C is not set +# CONFIG_BLUEZ_HCIBLUECARD is not set +# CONFIG_BLUEZ_HCIBTUART is not set +CONFIG_BLUEZ_HCIVHCI=m # # Kernel hacking @@ -647,8 +1161,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -659,5 +1175,5 @@ # Library routines # # CONFIG_CRC32 is not set -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.24/arch/mips/defconfig-nino linux-2.4.25/arch/mips/defconfig-nino --- linux-2.4.24/arch/mips/defconfig-nino 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-nino 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -95,7 +99,9 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -109,7 +115,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +133,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +160,7 @@ # 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 is not set @@ -200,6 +207,12 @@ # CONFIG_SYN_COOKIES 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 @@ -245,7 +258,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -254,6 +266,15 @@ # CONFIG_SCSI 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 + +# # Network device support # # CONFIG_NETDEVICES is not set @@ -281,6 +302,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -348,6 +370,7 @@ # 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 @@ -362,6 +385,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -420,6 +447,11 @@ # 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 @@ -507,6 +539,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -518,8 +555,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-ocelot linux-2.4.25/arch/mips/defconfig-ocelot --- linux-2.4.24/arch/mips/defconfig-ocelot 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ocelot 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ CONFIG_MOMENCO_OCELOT=y # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -67,7 +71,6 @@ # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BOARD_SCACHE=y CONFIG_PCI=y CONFIG_SYSCLK_100=y CONFIG_SWAP_IO_SPACE_W=y @@ -94,8 +97,14 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -111,7 +120,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -130,6 +138,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -179,6 +188,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set CONFIG_MTD_OCELOT=y # CONFIG_MTD_LASAT is not set @@ -231,6 +242,7 @@ # 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 is not set @@ -273,6 +285,12 @@ # CONFIG_SYN_COOKIES 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 @@ -318,7 +336,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -327,6 +344,20 @@ # CONFIG_SCSI 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 @@ -463,6 +494,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -509,6 +541,7 @@ # 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 @@ -522,6 +555,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -580,6 +617,11 @@ # 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 @@ -631,6 +673,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -642,8 +689,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-osprey linux-2.4.25/arch/mips/defconfig-osprey --- linux-2.4.24/arch/mips/defconfig-osprey 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-osprey 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -95,7 +99,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -109,7 +117,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +135,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +162,7 @@ # 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 is not set @@ -197,6 +206,12 @@ # CONFIG_SYN_COOKIES 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 @@ -242,7 +257,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -251,6 +265,15 @@ # CONFIG_SCSI 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -342,6 +365,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -357,6 +381,7 @@ # CONFIG_SERIAL_MULTIPORT is not set # CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -394,6 +419,7 @@ # 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 @@ -408,6 +434,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -466,6 +496,11 @@ # 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 @@ -528,6 +563,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -539,8 +579,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-pb1000 linux-2.4.25/arch/mips/defconfig-pb1000 --- linux-2.4.24/arch/mips/defconfig-pb1000 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-pb1000 2004-02-18 05:36:30.000000000 -0800 @@ -30,8 +30,10 @@ CONFIG_PCI_AUTO=y # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -50,6 +52,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -72,6 +76,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1000=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y @@ -98,7 +103,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -115,7 +124,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -133,7 +141,6 @@ CONFIG_PCMCIA_PB1X00=y # CONFIG_PCMCIA_DB1X00 is not set # CONFIG_PCMCIA_XXS1500 is not set -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -153,6 +160,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -202,6 +210,8 @@ # CONFIG_MTD_XXS1500 is not set # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -249,6 +259,7 @@ # 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 is not set @@ -292,6 +303,12 @@ # CONFIG_SYN_COOKIES 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 @@ -368,7 +385,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -380,6 +396,20 @@ # CONFIG_SCSI 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 @@ -529,6 +559,7 @@ # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -545,6 +576,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -639,10 +671,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -652,6 +686,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -719,6 +757,11 @@ # 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 @@ -789,6 +832,7 @@ CONFIG_PB1000_CRT=y # CONFIG_PB1000_NTSC is not set # CONFIG_PB1000_TFT is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -840,6 +884,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -944,6 +990,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -955,8 +1006,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -969,3 +1022,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-pb1100 linux-2.4.25/arch/mips/defconfig-pb1100 --- linux-2.4.24/arch/mips/defconfig-pb1100 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-pb1100 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set CONFIG_MIPS_PB1100=y # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1100=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y # CONFIG_PCI_AUTO is not set CONFIG_NEW_PCI=y @@ -98,7 +103,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -115,7 +124,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -134,6 +142,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -185,6 +194,8 @@ CONFIG_MTD_PB1500_BOOT=y CONFIG_MTD_PB1500_USER=y # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -232,6 +243,7 @@ # 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 @@ -285,8 +297,19 @@ # 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 @@ -363,7 +386,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -375,6 +397,20 @@ # CONFIG_SCSI 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 @@ -515,6 +551,7 @@ # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set # # ISDN subsystem @@ -531,6 +568,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -625,10 +663,12 @@ # 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=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -638,6 +678,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # CONFIG_AU1X00_GPIO is not set # CONFIG_TS_AU1X00_ADS7846 is not set @@ -701,6 +745,11 @@ # 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 @@ -812,6 +861,7 @@ # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set CONFIG_FB_AU1100=y +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -863,6 +913,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -967,6 +1019,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -978,8 +1035,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-pb1500 linux-2.4.25/arch/mips/defconfig-pb1500 --- linux-2.4.24/arch/mips/defconfig-pb1500 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-pb1500 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set CONFIG_MIPS_PB1500=y +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,7 +139,6 @@ CONFIG_PCMCIA_PB1X00=y # CONFIG_PCMCIA_DB1X00 is not set # CONFIG_PCMCIA_XXS1500 is not set -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -151,6 +158,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -202,6 +210,8 @@ CONFIG_MTD_PB1500_BOOT=y # CONFIG_MTD_PB1500_USER is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -249,6 +259,7 @@ # 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 @@ -302,8 +313,19 @@ # 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 @@ -417,7 +439,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -429,6 +450,20 @@ # CONFIG_SCSI 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 @@ -592,6 +627,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -686,10 +722,12 @@ # 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=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -699,6 +737,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -768,6 +810,11 @@ # 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 @@ -880,6 +927,7 @@ CONFIG_FB_E1356=y CONFIG_PB1500_CRT=y # CONFIG_PB1500_TFT is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -931,6 +979,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -1035,6 +1085,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -1046,8 +1101,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -1060,3 +1117,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-pb1550 linux-2.4.25/arch/mips/defconfig-pb1550 --- linux-2.4.24/arch/mips/defconfig-pb1550 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/defconfig-pb1550 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,890 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1550=y +CONFIG_NEW_TIME_C=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +# CONFIG_NONCOHERENT_IO is not set +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# 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 is not set + +# +# 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_IDEDISK is not set +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +CONFIG_PDC202XX_BURST=y +CONFIG_BLK_DEV_PDC202XX_NEW=y +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_PDC202XX=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI 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_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY 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_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# 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=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_IRCC_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX 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_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# 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 is not set +# CONFIG_JBD is not set +# 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 is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# 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 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +# CONFIG_FB_IT8181 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.24/arch/mips/defconfig-rbtx4927 linux-2.4.25/arch/mips/defconfig-rbtx4927 --- linux-2.4.24/arch/mips/defconfig-rbtx4927 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/defconfig-rbtx4927 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,665 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +CONFIG_TOSHIBA_RBTX4927=y +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_NEW_TIME_C=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y +CONFIG_ISA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +CONFIG_CPU_TX49XX=y +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_ADVANCED=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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 is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER 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_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI 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_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_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +CONFIG_NET_ISA=y +# CONFIG_E2100 is not set +# CONFIG_EWRK3 is not set +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set +CONFIG_NE2000=y +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 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_FDDI 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 + +# +# 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 + +# +# 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_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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +CONFIG_SERIAL_TXX9=y +CONFIG_SERIAL_TXX9_CONSOLE=y +# CONFIG_TXX927_SERIAL is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_MIPS_RTC is not set +CONFIG_DS1742=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# 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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips/defconfig-rm200 linux-2.4.25/arch/mips/defconfig-rm200 --- linux-2.4.24/arch/mips/defconfig-rm200 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-rm200 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -98,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -112,8 +120,8 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_ARC_CONSOLE is not set CONFIG_NET=y -# CONFIG_PCI_NAMES is not set CONFIG_EISA=y +# CONFIG_PCI_NAMES is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -132,6 +140,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -158,6 +167,7 @@ # 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 is not set @@ -198,6 +208,12 @@ # CONFIG_SYN_COOKIES 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 @@ -243,7 +259,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -252,6 +267,20 @@ # CONFIG_SCSI 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 @@ -294,6 +323,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -340,6 +370,7 @@ # 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 @@ -353,6 +384,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -411,6 +446,11 @@ # 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 @@ -487,6 +527,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -498,8 +543,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-sb1250-swarm linux-2.4.25/arch/mips/defconfig-sb1250-swarm --- linux-2.4.24/arch/mips/defconfig-sb1250-swarm 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-sb1250-swarm 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -77,6 +81,7 @@ CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set # CONFIG_SIBYTE_BUS_WATCHER is not set +# CONFIG_SIBYTE_BW_TRACE is not set # CONFIG_SIBYTE_SB1250_PROF is not set # CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set @@ -117,7 +122,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SMP=y # CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y @@ -138,7 +147,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -157,6 +165,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -183,6 +192,7 @@ # 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 is not set @@ -223,6 +233,12 @@ # CONFIG_SYN_COOKIES 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 @@ -299,7 +315,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -311,6 +326,15 @@ # CONFIG_SCSI 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -402,6 +426,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -472,6 +497,7 @@ # 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 @@ -486,6 +512,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -544,6 +574,11 @@ # 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 @@ -596,6 +631,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -607,8 +647,11 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=32 +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-sead linux-2.4.25/arch/mips/defconfig-sead --- linux-2.4.24/arch/mips/defconfig-sead 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-sead 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -92,7 +96,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set # CONFIG_64BIT_PHYS_ADDR is not set @@ -109,7 +117,6 @@ # CONFIG_NET is not set # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +135,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +162,7 @@ # 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 @@ -191,7 +200,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -200,6 +208,15 @@ # CONFIG_SCSI 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 + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -212,6 +229,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -257,6 +275,7 @@ # 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 @@ -271,6 +290,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -329,6 +352,11 @@ # 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 # CONFIG_NCPFS_NLS is not set # CONFIG_SMB_FS is not set # CONFIG_ZISOFS_FS is not set @@ -371,14 +399,21 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-tb0226 linux-2.4.25/arch/mips/defconfig-tb0226 --- linux-2.4.24/arch/mips/defconfig-tb0226 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-tb0226 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,9 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -99,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -113,7 +119,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -132,6 +137,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -158,6 +164,7 @@ # 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 is not set @@ -202,6 +209,12 @@ # CONFIG_SYN_COOKIES 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 @@ -247,7 +260,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -293,6 +305,7 @@ # 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 @@ -327,6 +340,20 @@ # 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 @@ -463,6 +490,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -473,6 +501,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -530,8 +559,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -546,6 +575,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -604,6 +637,11 @@ # 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 @@ -779,6 +817,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -790,8 +833,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-tb0229 linux-2.4.25/arch/mips/defconfig-tb0229 --- linux-2.4.24/arch/mips/defconfig-tb0229 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-tb0229 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -72,9 +76,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y -# CONFIG_ISA is not set CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -100,7 +102,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -114,7 +120,6 @@ CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -133,6 +138,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -159,6 +165,7 @@ # 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 @@ -204,6 +211,12 @@ # CONFIG_SYN_COOKIES 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 @@ -249,7 +262,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -258,6 +270,20 @@ # CONFIG_SCSI 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 @@ -402,6 +428,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -412,6 +439,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -469,8 +497,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -485,6 +513,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -543,6 +575,11 @@ # 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 @@ -619,6 +656,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -630,8 +672,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-ti1500 linux-2.4.25/arch/mips/defconfig-ti1500 --- linux-2.4.24/arch/mips/defconfig-ti1500 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-ti1500 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set CONFIG_MIPS_XXS1500=y # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,7 +139,6 @@ # CONFIG_PCMCIA_PB1X00 is not set # CONFIG_PCMCIA_DB1X00 is not set CONFIG_PCMCIA_XXS1500=y -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -151,6 +158,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -200,6 +208,8 @@ CONFIG_MTD_XXS1500=y # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -247,6 +257,7 @@ # 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 @@ -300,8 +311,19 @@ # 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 @@ -378,7 +400,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -390,6 +411,20 @@ # CONFIG_SCSI 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 @@ -519,6 +554,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -562,6 +598,7 @@ # CONFIG_I2C=m # CONFIG_I2C_ALGOBIT is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_ALGOPCF is not set CONFIG_I2C_CHARDEV=m CONFIG_I2C_PROC=m @@ -617,10 +654,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -630,6 +669,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -696,6 +739,11 @@ # 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 @@ -806,6 +854,7 @@ # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set +# CONFIG_FB_IT8181 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -857,6 +906,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -961,6 +1012,11 @@ # CONFIG_USB_LCD is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -972,8 +1028,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -986,3 +1044,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-workpad linux-2.4.25/arch/mips/defconfig-workpad --- linux-2.4.24/arch/mips/defconfig-workpad 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-workpad 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -40,6 +42,7 @@ # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set CONFIG_IBM_WORKPAD=y +# CONFIG_VRC4171 is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set @@ -49,6 +52,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,10 +76,8 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y -CONFIG_VR41XX_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_ISA=y -CONFIG_DUMMY_KEYB=y # CONFIG_SCSI is not set # CONFIG_MIPS_AU1000 is not set @@ -96,7 +99,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set @@ -109,7 +116,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_NET=y # CONFIG_PCI is not set -CONFIG_EISA=y # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -128,6 +134,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -154,6 +161,7 @@ # 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 is not set @@ -195,6 +203,12 @@ # CONFIG_SYN_COOKIES 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 @@ -270,7 +284,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -282,6 +295,15 @@ # CONFIG_SCSI 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -380,6 +402,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -395,6 +418,7 @@ # CONFIG_SERIAL_MULTIPORT is not set # CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_VR41XX_KIU is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -452,8 +476,8 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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 @@ -468,6 +492,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -526,6 +554,11 @@ # 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 @@ -602,6 +635,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -613,8 +651,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options diff -urN linux-2.4.24/arch/mips/defconfig-xxs1500 linux-2.4.25/arch/mips/defconfig-xxs1500 --- linux-2.4.24/arch/mips/defconfig-xxs1500 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/defconfig-xxs1500 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set CONFIG_MIPS_XXS1500=y # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -71,6 +75,7 @@ # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_SOC_AU1X00=y CONFIG_SOC_AU1500=y +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y @@ -96,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y @@ -113,7 +122,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -131,7 +139,6 @@ # CONFIG_PCMCIA_PB1X00 is not set # CONFIG_PCMCIA_DB1X00 is not set CONFIG_PCMCIA_XXS1500=y -# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -151,6 +158,7 @@ # CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_PM is not set # @@ -200,6 +208,8 @@ CONFIG_MTD_XXS1500=y # CONFIG_MTD_MTX1 is not set # CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_HYDIII is not set +# CONFIG_MTD_MIRAGE is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set # CONFIG_MTD_LASAT is not set @@ -247,6 +257,7 @@ # 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 @@ -300,8 +311,19 @@ # 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 @@ -415,7 +437,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -427,6 +448,20 @@ # CONFIG_SCSI 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 @@ -588,6 +623,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -660,10 +696,12 @@ # 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=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -673,6 +711,10 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # @@ -739,6 +781,11 @@ # 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 @@ -861,6 +908,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -868,6 +917,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -879,8 +933,10 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 # # Cryptographic options @@ -893,3 +949,4 @@ # CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/mips/defconfig-yosemite linux-2.4.25/arch/mips/defconfig-yosemite --- linux-2.4.24/arch/mips/defconfig-yosemite 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/defconfig-yosemite 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,662 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +CONFIG_CPU_RM9000=y +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_BINFMT_IRIX is not set +CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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=y +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER 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_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA 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 + +# +# SCSI support type (disk, tape, CD-ROM) +# +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=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# 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_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_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_SIM710 is not set +# CONFIG_SCSI_SYM53C416 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 + +# +# 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_SUNLANCE 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_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_FDDI 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 + +# +# 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 + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +# CONFIG_EXT2_FS is not set +# 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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/Makefile linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/Makefile --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,177 +0,0 @@ -# ============================================================= -# -# linux/arch/mips/galileo/compressed/Makefile -# -# By RidgeRun Inc. -# -# Description: -# Create a system containing a copy of the compressed vmlinux kernel. -# The system knows how to decompress the contained kernel and then -# jump to it resulting in a linux kernel boot. -# -# The system comes in three forms: -# -# 1. - ramsys - -# to be loaded into ram then run. When run -# it decompresses the kernel housed in its internal -# data structures and then jumps to the image which -# results in a linux kernel boot. -# -# 2. - flashsys - -# to be loaded into ram so that it can be -# burned into the onboard flash. Then the board jumpers -# can be switched so that the next power cycle caused -# the system in flash to run which then proceeds as -# described by #1 above. -# Note: burner.srec is the utility that will allow -# the user to get this image into flash. -# -# 3. - flashsys2 - -# to be loaded into ram so that it can be -# burned into the onboard flash. Then on each power -# cycle when the standard PMON prompt is presented -# the user can type `call 0xbf000000` to invoke -# the system in flash which then proceeds as -# described by #1 above. -# Note: burner.srec is the utility that will allow -# the user to get this image into flash. -# -# 4. - burner.srec - -# related to #2 and #3 above. -# -# ============================================================= - -USE_STANDARD_AS_RULE := true - -all: ramsys.srec \ - flashsys.srec \ - flashsys2.srec \ - burner.srec - -SYSTEM = $(TOPDIR)/vmlinux - -CFLAGS_2 = -DCONSOLE_SERIAL -DDELIMITERLINES -DGALILEO_PORT \ - -DANSIESC -DELF_IMAGE -DELF_IMAGE -DDOWNLOAD_PROTO_TFTP \ - -DEVB64120A -D__MIPSEB__ -DINCLUDE_EEPRO100 \ - -DINCLUDE_GETH0 -DNOPRINTK -DPROM -DCOMPRESSEDVMLINUX - -sbdreset_evb64120A.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c sbdreset_evb64120A.S -o $*.o -memory.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c memory.c -o $*.o -pci.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c pci.c -o $*.o -pci_etherboot.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c pci_etherboot.c -o $*.o -load.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c load.c -o $*.o -flashdrv.o: - $(CC) $(CFLAGS) $(CFLAGS_2) -c flashdrv.c -o $*.o - -gz2asm: gz2asm.c - g++ -o gz2asm gz2asm.c - -doit: doit.c - gcc -o doit doit.c - -piggy.gz: $(SYSTEM) - rm -f piggy piggy.gz - $(OBJCOPY) -S -O binary $(SYSTEM) piggy - gzip -f -9 < piggy > piggy.gz - -piggy.S: doit fixit piggy.gz - ./doit < piggy.gz > piggy.S; . ./fixit piggy.S - -OBJECTS_ramsys = head.o misc.o piggy.o ../serialGT.o -OBJECTS_flashsys = sbdreset_evb64120A.o evb64120A_Setup.o pci_etherboot.o memory.o pci.o head.o misc.o piggy.o ../serialGT.o -OBJECTS_flashsys2 = xfer.o head.o misc.o piggy.o ../serialGT.o -OBJECTS_burner = burner.o load.o flashdrv.o - -ramsys.srec : $(OBJECTS_ramsys) ld.script.gal - @# Note: this image is intended to run out of ram. No flash involved. - $(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys) - $(NM) ramsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_ramsys.map - $(OBJCOPY) -O srec ramsys ramsys.srec - cp ramsys.srec $(TOPDIR)/. - -flashsys.srec : $(OBJECTS_flashsys) ld.sys.big.Flash - @# Note1: Use the burn utility to get this image into flash. - @# Note2: This image is intended to run out of flash as invoked - @# directly at powerup when EVB64120A jumpers are configured to - @# bypass the onboard eprom. - @# Assumes that 0xBFC00000 is the bootup run address (normal MIPS). - @# And assumes that EVB64120A jumber J11 is added to the board and jumber - @# J20 is moved from the 2&3 position to the 1&2 position instead. Without - @# the jumper settings the system will execute at address 0xBFC00000, - @# as normal, yet that address will map to the onboard eeprom instead - @# of the onboard flash. - @# - $(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys) - $(NM) flashsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys.map - @# - @# Next, Create the image that we want to place in the flash part. - $(OBJCOPY) -S -g --strip-unneeded \ - --adjust-section-vma=.text+0x3f820000 \ - --adjust-section-vma=.rodata+0x3f820000 \ - --adjust-section-vma=.reginfo+0x3f820000 \ - --adjust-section-vma=.data+0x3f820000 \ - --remove-section=.bss \ - --remove-section=.scommon \ - --remove-section=.note \ - --remove-section=.comment \ - flashsys flashsys.temp - @# - @# Next, change the addresses so that when we download to - @# to the board's ram it will land starting at address 0xA0300000 - @# because this is where we have choosen to have the image temporarily sit - @# while we subsequently burn it (using some method not revealed here) into - @# the board's flash. After the burn the system can be setup (via jumpers) - @# to boot this image directory from the flash part. - $(OBJCOPY) -O srec --adjust-vma=0xe0700000 flashsys.temp flashsys.srec - cp flashsys.srec $(TOPDIR)/. - -flashsys2.srec : $(OBJECTS_flashsys2) ld.sys.big.Flash2 - @# Note1: Use the burn utility to get this image into flash. - @# Note2: This image is intended to be run out of flash as invoked - @# manually from the standard PMON running in eprom. This means that - @# the image will be set to run from location 0xBF000000 which is the - @# location the flash is mapped to when the board jumpers are set to - @# the standard location such that the board boots out of onboard - @# eprom. From the PMON prompt the user can type `call 0xbf000000` - @# to transfer control to the image we are constructing here. - @# - $(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2) - $(NM) flashsys2 | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys2.map - @# - @# Next, Create the image that we want to place in the flash part. - $(OBJCOPY) -S -g --strip-unneeded \ - --adjust-section-vma=.text+0x3ec20000 \ - --adjust-section-vma=.rodata+0x3ec20000 \ - --adjust-section-vma=.reginfo+0x3ec20000 \ - --adjust-section-vma=.data+0x3ec20000 \ - --remove-section=.bss \ - --remove-section=.scommon \ - --remove-section=.note \ - --remove-section=.comment \ - flashsys2 flashsys2.temp - @# - @# Next, change the addresses so that when we download to - @# to the board's ram it will land starting at address 0xA0300000 - @# because this is where we have choosen to have the image temporarily sit - @# while we subsequently burn it (using some method not revealed here) into - @# the board's flash. After the burn a user will then be able to type - @# `call 0xbf000000` at the PMON prompt (following a power cycle) to invoke - @# the linux kernel. - $(OBJCOPY) -O srec --adjust-vma=0xe1300000 flashsys2.temp flashsys2.srec - cp flashsys2.srec $(TOPDIR)/. - -burner.srec : $(OBJECTS_burner) ld.sys.big.burner - @# This utility can be used to burn the flashsys.srec or flashsys2.srec - @# into the EVB64120A's on board flash part (1Meg minimum). - $(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner) - $(NM) burner | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_burner.map - $(OBJCOPY) -O srec burner burner.srec - cp burner.srec $(TOPDIR)/. - -clean: - rm -f doit piggy.S piggy.gz piggy burner *.o ramsys* flashsys* System*.map *.srec diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/README linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/README --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/README 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/README 1969-12-31 16:00:00.000000000 -0800 @@ -1,131 +0,0 @@ -+------------------------------------------------+ -| $TOPDIR/arch/mips/galileo/compressed/README | -| | -| By RidgeRun Inc, | -| Aug, 2000 | -+------------------------------------------------+ - -Description: -============ - It is intended that this makefile be wired in to run as - part of a top level linux build. For example, at the - time of this writing, if the user types "make gboot" at - the top level then in addition to building vmlinux the - build system's makefiles will descend into this - directory and build the "all:" target of this - Makefile. This will have the result of compressing the - vmlinux system and producing four separate systems. The - following snippet is pulled from this directory's - Makefile and describes each system. - - Four systems are availalbe for download to the EVB64120A - board. - - 1. - ramsys - - To be loaded into ram then run. When run - it decompresses the "vmlinux" kernel housed in its internal - data structures and then jumps to the image which - results in a linux kernel boot. - - 2. - flashsys - - To be loaded into ram so that it can be - burned into the onboard flash. Then the board jumpers - can be switched so that the next power cycle caused - the system in flash to run which then proceeds as - described by #1 above. - Note: burner.srec is the utility that will allow - the user to get this image into flash. - - 3. - flashsys2 - - To be loaded into ram so that it can be - burned into the onboard flash. Then on each power - cycle when the standard PMON prompt is presented - the user can type `call 0xbf000000` to invoke - the system in flash which then proceeds as - described by #1 above. - Note: burner.srec is the utility that will allow - the user to get this image into flash. - - 4. - burner.srec - - Related to #2 and #3 above. - -Example: Running from Ram -========================== - - In this scenario the compressed system is downloaded - into ram and run directly from there. No flash is involved - in this scenario. Naturally, the download must be repeated - on every power cycle. - - 1. At the PMON prompt type `load` - 2. Assuming you have your host connected to /dev/ttyS0 - type the following command in a host shell window. - `cat ramsys.srec > /dev/ttyS0` - 3. When the download completes type the following - at the PMON prompt: `g` - - -Example: Running from flash: Scenario #1 -======================================== - - In this scenario vmlinux runs out of flash code - automatically on every power up. This means that - standard PMON code (of eprom) never runs. - - 1. Place the boot jumpers in the Boot-from-eprom - state. This is the normal state and how the jumpers - are found when booting PMON. - - Jumper settings. J11 - Removed - J20 - Moved from the 1&2 position to - the 2&3 position instead - - 2. Use PMON to "load" the burner.srec image and then - run it. This utility will prompt you to download - the image that you want burned into the flash - part. - - 3. Send the flashsys.srec image to the running burner - utility. The utililty will indicate when the burn - process has completed. - - 4. Now switch off power and change the jumpers to - the boot-from-flash position. The next power cycle - will run the flash based system automatically. - - Jumper settings. J11 - Added. - J20 - Moved from the 2&3 position to - the 1&2 position instead - -Example: Running from flash: Scenario #2 -======================================== - - In this scenario vmlinux runs out of flash only if the - PMON user decides to jump there by issuing a command to - PMON. Every power cycle would continue to bring up PMON - and a user will have to reissue the jump command to - force control transfer to the flash system. - - 1. Insure that the boot jumpers are in the Boot-from-eprom - state. This is the normal state and how the jumpers - are found when booting PMON. - - Jumper settings. J11 - Removed - J20 - Moved from the 1&2 position to - the 2&3 position instead - - 2. Use PMON to "load" the burner.srec image and then - run it. This utility will prompt you to download - the image that you want burned into the flash - part. - - 3. Send the flashsys2.srec image to the running burner - utility. The utililty will indicate when the burn - process has completed. - - 4. Now that the image is in flash the user can invoke - the following PMON command whenever a vmlinux - boot is desired: - - call 0xbf000000 - diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/burner.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/burner.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/burner.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/burner.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,230 +0,0 @@ -/* - * arch/mips/galileo/compressed/burner.c - * - * By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc). - * - * Burn image from ram to flash - * For use with Galileo EVB64120A MIPS eval board. - */ -#include -#include -#include -#include - -#define IMAGEOFFSET 0x00300000 - -static void burn_image_from_memory(void); -static char *sprintf(char *buf, const char *fmt, ...); -static void printf(const char *fmt, ...); - -unsigned int FlashSize; - -/****************************** - Routine: - Description: - ******************************/ -int main(void) -{ - printf("\n"); - printf("\n"); - printf("\n"); - printf("\n"); - printf(" +--------------------+\n"); - printf(" | |\n"); - printf(" | Flash Burn Utility |\n"); - printf(" | |\n"); - printf(" +--------------------+\n"); - printf("\n"); - printf("Please send your *.srec image to the parallel port\n"); - printf("\n"); - printf("Note: The *.srec image should be setup to\n"); - printf(" load into address 0xa0300000 where\n"); - printf(" it will then be transferred to flash\n"); - printf("\n"); - - SET_REG_BITS(0x468, BIT20); // Set Flash to be 16 bit wide - FlashSize = flashInit(0xbf000000, 2, X16); - - galileo_dl(); // read in the users *.srec image. - burn_image_from_memory(); // put it in flash. - - printf("\n"); - printf("\n"); - printf("+---------------+\n"); - printf("| Done |\n"); - printf("|(please reboot)|\n"); - printf("+---------------+\n"); - printf("\n"); - - while (1) { - } - return 0; -} - -/****************************** - Routine: - Description: - ******************************/ -static void burn_image_from_memory(void) -{ - unsigned int count, delta, temp, temp1; - unsigned int to_sector, last_sector; - - /* Find how many sectors needed to be erased */ - to_sector = flashInWhichSector(FlashSize - 4); // skranz, modified. - if (to_sector == 0xffffffff) { - printf - ("Flash Burning Error - Flash too small - Cannot burn image\n"); // skranz, modified. - return; - } - - /* Which is the last sector */ - last_sector = flashInWhichSector(FlashSize - 4); - delta = 0; - printf("\nErasing first %d sectors\n", to_sector); - for (count = 0; count < to_sector + 1; count++) { - printf("Erasing sector %d\n", count); - flashEraseSector(count); - } - printf("flash region size = %d\n", FlashSize); // skranz, added - printf("Sdram IMAGEOFFSET = %d\n", IMAGEOFFSET); // skranz, added - - printf("Burning from Sdram to %d mark; full burn.\n", FlashSize); - for (count = 0; count < (FlashSize - delta); count = count + 4) { - flashWriteWord(count, - *(unsigned int *) ((count | NONE_CACHEABLE) - + IMAGEOFFSET)); // skranz, modified. - temp = flashReadWord(count); - temp1 = *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET); // skranz, modified. - if (((unsigned int) temp) != ((unsigned int) temp1)) { - printf - ("Burning error at address %X : flash(%X) sdram(%X)\n", - count, flashReadWord(count), - *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET)); // skranz, modified. - printf("Aborting Prematurally.\n"); - break; - } - } - printf("Finished burning Image\n"); -} - -/****************************** - Routine: - Description: - Formats: - %X - 4 byte ASCII (8 hex digits) - %x - 2 byte ASCII (4 hex digits) - %b - 1 byte ASCII (2 hex digits) - %d - decimal (also %i) - %c - ASCII char - %s - ASCII string - %I - Internet address in x.x.x.x notation - ******************************/ -static char hex[] = "0123456789ABCDEF"; -static char *do_printf(char *buf, const char *fmt, const int *dp) -{ - register char *p; - char tmp[16]; - while (*fmt) { - if (*fmt == '%') { /* switch() uses more space */ - fmt++; - - if (*fmt == 'X') { - const long *lp = (const long *) dp; - register long h = *lp++; - dp = (const int *) lp; - *(buf++) = hex[(h >> 28) & 0x0F]; - *(buf++) = hex[(h >> 24) & 0x0F]; - *(buf++) = hex[(h >> 20) & 0x0F]; - *(buf++) = hex[(h >> 16) & 0x0F]; - *(buf++) = hex[(h >> 12) & 0x0F]; - *(buf++) = hex[(h >> 8) & 0x0F]; - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if (*fmt == 'x') { - register int h = *(dp++); - *(buf++) = hex[(h >> 12) & 0x0F]; - *(buf++) = hex[(h >> 8) & 0x0F]; - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if (*fmt == 'b') { - register int h = *(dp++); - *(buf++) = hex[(h >> 4) & 0x0F]; - *(buf++) = hex[h & 0x0F]; - } - if ((*fmt == 'd') || (*fmt == 'i')) { - register int dec = *(dp++); - p = tmp; - if (dec < 0) { - *(buf++) = '-'; - dec = -dec; - } - do { - *(p++) = '0' + (dec % 10); - dec = dec / 10; - } while (dec); - while ((--p) >= tmp) - *(buf++) = *p; - } - if (*fmt == 'I') { - union { - long l; - unsigned char c[4]; - } u; - const long *lp = (const long *) dp; - u.l = *lp++; - dp = (const int *) lp; - buf = sprintf(buf, "%d.%d.%d.%d", - u.c[0], u.c[1], u.c[2], - u.c[3]); - } - if (*fmt == 'c') - *(buf++) = *(dp++); - if (*fmt == 's') { - p = (char *) *dp++; - while (*p) - *(buf++) = *p++; - } - } else - *(buf++) = *fmt; - fmt++; - } - *buf = 0; - return (buf); -} - -/****************************** - Routine: - Description: - ******************************/ -static char *sprintf(char *buf, const char *fmt, ...) -{ - return do_printf(buf, fmt, ((const int *) &fmt) + 1); -} - -/****************************** - Routine: - Description: - ******************************/ -void putchar(int c) -{ - if (c == '\n') { - serial_putc('\r'); - } - serial_putc(c); -} - -/****************************** - Routine: - Description: - ******************************/ -static void printf(const char *fmt, ...) -{ - char buf[256], *p; - p = buf; - do_printf(buf, fmt, ((const int *) &fmt) + 1); - while (*p) - putchar(*p++); -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/doit.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/doit.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/doit.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/doit.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,75 +0,0 @@ -/* - * By RidgeRun Inc. - * - * The input to this program is intended to be - * a compressed linux kernel. The output of this - * program is then a constructed *.S file which - * defines a large data structure -- the contents - * of which represent the compressed kernel which - * can subsequently be used in a program designed - * to access that struture for decompression at - * runtime and then subsequent kernel bootup. - * - * Example Usage: - * ./doit < piggy.gz > piggy.S - * - */ - -#include - -void printval(int i) -{ - int tth, th, h, t, d; - - if (i > 99999) { - printf("Error - printval outofbounds\n"); - return; - } - - tth = 0; - th = 0; - //tth = (i) / 10000; - //th = (i - (tth * 10000)) / 1000; - h = (i - ((tth * 10000) + (th * 1000))) / 100; - t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10; - d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10))); - //putchar(tth + '0'); - //putchar(th + '0'); - putchar(h + '0'); - putchar(t + '0'); - putchar(d + '0'); -} - -main(int argc, char **argv) -{ - int val; - int size = 0; - unsigned char c; - - printf("gcc2_compiled.:\n"); - printf("__gnu_compiled_c:\n"); - printf("\t.globl linux_compressed_start\n"); - printf("\t.text\n"); - printf("\t.align 2\n"); - printf("\t.type linux_compressed_start,@object\n"); - printf("linux_compressed_start:\n"); - - - val = getchar(); - while (val != EOF) { - size++; - c = (unsigned char) (val & 0x00ff); - printf("\t.byte "); - printval((int) c); - printf("\n"); - val = getchar(); - } - printf("\t.size linux_compressed_start,%d\n", size); - printf("\t.globl linux_compressed_size\n"); - printf("\t.text\n"); - printf("\t.align 2\n"); - printf("\t.type linux_compressed_size,@object\n"); - printf("\t.size linux_compressed_size,4\n"); - printf("linux_compressed_size:\n"); - printf("\t.word %d\n", size); -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/etherboot.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/etherboot.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/etherboot.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/etherboot.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,566 +0,0 @@ -/************************************************************************** -ETHERBOOT - BOOTP/TFTP Bootstrap Program - -Author: Martin Renters - Date: Dec/93 - -**************************************************************************/ - -#include "osdep.h" - -/* These could be customised for different languages perhaps */ -#define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? " -#define ANS_NETWORK 'N' -#define ANS_LOCAL 'L' -#ifndef ANS_DEFAULT /* in case left out in Makefile */ -#define ANS_DEFAULT ANS_NETWORK -#endif - -#define TAGGED_IMAGE /* eventually optional */ -#if !defined(TAGGED_IMAGE) && !defined(AOUT_IMAGE) && !defined(ELF_IMAGE) -#define TAGGED_IMAGE /* choose at least one */ -#endif - -#define ESC 0x1B - -#ifndef DEFAULT_BOOTFILE -#define DEFAULT_BOOTFILE "/tftpboot/kernel" -#endif - -/* Clean up console settings... mainly CONSOLE_CRT and CONSOLE_SERIAL are used - * in the sources (except start.S and serial.S which cannot include - * etherboot.h). At least one of the CONSOLE_xxx has to be set, and - * CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL. If none is set, - * CONSOLE_CRT is assumed. */ -#ifdef CONSOLE_DUAL -#undef CONSOLE_CRT -#define CONSOLE_CRT -#undef CONSOLE_SERIAL -#define CONSOLE_SERIAL -#endif -#if defined(CONSOLE_CRT) && defined(CONSOLE_SERIAL) -#undef CONSOLE_DUAL -#define CONSOLE_DUAL -#endif -#if !defined(CONSOLE_CRT) && !defined(CONSOLE_SERIAL) -#define CONSOLE_CRT -#endif - -#ifndef DOWNLOAD_PROTO_NFS -#undef DOWNLOAD_PROTO_TFTP -#define DOWNLOAD_PROTO_TFTP /* default booting protocol */ -#endif - -#ifdef DOWNLOAD_PROTO_TFTP -#define download(fname,loader) tftp((fname),(loader)) -#endif -#ifdef DOWNLOAD_PROTO_NFS -#define download(fname,loader) nfs((fname),(loader)) -#endif - -#ifndef MAX_TFTP_RETRIES -#define MAX_TFTP_RETRIES 20 -#endif - -#ifndef MAX_BOOTP_RETRIES -#define MAX_BOOTP_RETRIES 20 -#endif - -#ifndef MAX_BOOTP_EXTLEN -#if (RELOC < 0x94000) -/* Force internal buffer (if external buffer would overlap with our code...) */ -#undef INTERNAL_BOOTP_DATA -#define INTERNAL_BOOTP_DATA -#endif -/* sizeof(struct bootp_t) == 0x240 */ -#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94240) -#define MAX_BOOTP_EXTLEN 1024 -#else -#define MAX_BOOTP_EXTLEN (1024-sizeof(struct bootp_t)) -#endif -#endif - -#ifndef MAX_ARP_RETRIES -#define MAX_ARP_RETRIES 20 -#endif - -#ifndef MAX_RPC_RETRIES -#define MAX_RPC_RETRIES 20 -#endif - -#define TICKS_PER_SEC 18 - -/* Inter-packet retry in ticks */ -#define TIMEOUT (10*TICKS_PER_SEC) - -/* These settings have sense only if compiled with -DCONGESTED */ -/* total retransmission timeout in ticks */ -#define TFTP_TIMEOUT (30*TICKS_PER_SEC) -/* packet retransmission timeout in ticks */ -#define TFTP_REXMT (3*TICKS_PER_SEC) - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define TRUE 1 -#define FALSE 0 - -#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */ -#define ETHER_HDR_SIZE 14 /* Size of ethernet header */ -#define ETH_MIN_PACKET 64 -#define ETH_MAX_PACKET 1518 - -#define VENDOR_NONE 0 -#define VENDOR_WD 1 -#define VENDOR_NOVELL 2 -#define VENDOR_3COM 3 -#define VENDOR_3C509 4 -#define VENDOR_CS89x0 5 - -#define FLAG_PIO 0x01 -#define FLAG_16BIT 0x02 -#define FLAG_790 0x04 - -#define ARP_CLIENT 0 -#define ARP_SERVER 1 -#define ARP_GATEWAY 2 -#define ARP_ROOTSERVER 3 -#define ARP_SWAPSERVER 4 -#define MAX_ARP ARP_SWAPSERVER+1 - -#define RARP_REQUEST 3 -#define RARP_REPLY 4 - -#define IP 0x0800 -#define ARP 0x0806 -#define RARP 0x8035 - -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 -#define TFTP_PORT 69 -#define SUNRPC_PORT 111 - -#define IP_UDP 17 -/* Same after going through htonl */ -#define IP_BROADCAST 0xFFFFFFFF - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 - -#define TAG_LEN(p) (*((p)+1)) -#define RFC1533_COOKIE 99, 130, 83, 99 -#define RFC1533_PAD 0 -#define RFC1533_NETMASK 1 -#define RFC1533_TIMEOFFSET 2 -#define RFC1533_GATEWAY 3 -#define RFC1533_TIMESERVER 4 -#define RFC1533_IEN116NS 5 -#define RFC1533_DNS 6 -#define RFC1533_LOGSERVER 7 -#define RFC1533_COOKIESERVER 8 -#define RFC1533_LPRSERVER 9 -#define RFC1533_IMPRESSSERVER 10 -#define RFC1533_RESOURCESERVER 11 -#define RFC1533_HOSTNAME 12 -#define RFC1533_BOOTFILESIZE 13 -#define RFC1533_MERITDUMPFILE 14 -#define RFC1533_DOMAINNAME 15 -#define RFC1533_SWAPSERVER 16 -#define RFC1533_ROOTPATH 17 -#define RFC1533_EXTENSIONPATH 18 -#define RFC1533_IPFORWARDING 19 -#define RFC1533_IPSOURCEROUTING 20 -#define RFC1533_IPPOLICYFILTER 21 -#define RFC1533_IPMAXREASSEMBLY 22 -#define RFC1533_IPTTL 23 -#define RFC1533_IPMTU 24 -#define RFC1533_IPMTUPLATEAU 25 -#define RFC1533_INTMTU 26 -#define RFC1533_INTLOCALSUBNETS 27 -#define RFC1533_INTBROADCAST 28 -#define RFC1533_INTICMPDISCOVER 29 -#define RFC1533_INTICMPRESPOND 30 -#define RFC1533_INTROUTEDISCOVER 31 -#define RFC1533_INTROUTESOLICIT 32 -#define RFC1533_INTSTATICROUTES 33 -#define RFC1533_LLTRAILERENCAP 34 -#define RFC1533_LLARPCACHETMO 35 -#define RFC1533_LLETHERNETENCAP 36 -#define RFC1533_TCPTTL 37 -#define RFC1533_TCPKEEPALIVETMO 38 -#define RFC1533_TCPKEEPALIVEGB 39 -#define RFC1533_NISDOMAIN 40 -#define RFC1533_NISSERVER 41 -#define RFC1533_NTPSERVER 42 -#define RFC1533_VENDOR 43 -#define RFC1533_NBNS 44 -#define RFC1533_NBDD 45 -#define RFC1533_NBNT 46 -#define RFC1533_NBSCOPE 47 -#define RFC1533_XFS 48 -#define RFC1533_XDM 49 -#ifndef NO_DHCP_SUPPORT -#define RFC2132_REQ_ADDR 50 -#define RFC2132_MSG_TYPE 53 -#define RFC2132_SRV_ID 54 -#define RFC2132_PARAM_LIST 55 -#define RFC2132_MAX_SIZE 57 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPACK 5 -#endif /* NO_DHCP_SUPPORT */ - -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 - -#define RFC1533_VENDOR_MAGIC 128 -#define RFC1533_VENDOR_ADDPARM 129 -#ifdef IMAGE_FREEBSD -#define RFC1533_VENDOR_HOWTO 132 -#endif -#define RFC1533_VENDOR_MNUOPTS 160 -#define RFC1533_VENDOR_SELECTION 176 -#define RFC1533_VENDOR_MOTD 184 -#define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 - -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#ifndef NO_DHCP_SUPPORT -#define DHCP_OPT_LEN 312 -#endif /* NO_DHCP_SUPPORT */ - -#define TFTP_DEFAULTSIZE_PACKET 512 -#define TFTP_MAX_PACKET 1432 /* 512 */ - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 -#define TFTP_OACK 6 - -#define TFTP_CODE_EOF 1 -#define TFTP_CODE_MORE 2 -#define TFTP_CODE_ERROR 3 -#define TFTP_CODE_BOOT 4 -#define TFTP_CODE_CFG 5 - -#define AWAIT_ARP 0 -#define AWAIT_BOOTP 1 -#define AWAIT_TFTP 2 -#define AWAIT_RARP 3 -#define AWAIT_RPC 4 -#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */ - -typedef struct { - unsigned long s_addr; -} in_addr; - -struct arptable_t { - in_addr ipaddr; - unsigned char node[6]; -}; - -/* - * A pity sipaddr and tipaddr are not longword aligned or we could use - * in_addr. No, I don't want to use #pragma packed. - */ -struct arprequest { - unsigned short hwtype; - unsigned short protocol; - char hwlen; - char protolen; - unsigned short opcode; - char shwaddr[6]; - char sipaddr[4]; - char thwaddr[6]; - char tipaddr[4]; -}; - -struct iphdr { - char verhdrlen; - char service; - unsigned short len; - unsigned short ident; - unsigned short frags; - char ttl; - char protocol; - unsigned short chksum; - in_addr src; - in_addr dest; -}; - -struct udphdr { - unsigned short src; - unsigned short dest; - unsigned short len; - unsigned short chksum; -}; - -struct bootp_t { - struct iphdr ip; - struct udphdr udp; - char bp_op; - char bp_htype; - char bp_hlen; - char bp_hops; - unsigned long bp_xid; - unsigned short bp_secs; - unsigned short unused; - in_addr bp_ciaddr; - in_addr bp_yiaddr; - in_addr bp_siaddr; - in_addr bp_giaddr; - char bp_hwaddr[16]; - char bp_sname[64]; - char bp_file[128]; -#ifdef NO_DHCP_SUPPORT - char bp_vend[BOOTP_VENDOR_LEN]; -#else - char bp_vend[DHCP_OPT_LEN]; -#endif /* NO_DHCP_SUPPORT */ -}; - -struct bootpd_t { - struct bootp_t bootp_reply; - unsigned char bootp_extension[MAX_BOOTP_EXTLEN]; -}; - -struct tftp_t { - struct iphdr ip; - struct udphdr udp; - unsigned short opcode; - union { - char rrq[TFTP_DEFAULTSIZE_PACKET]; - struct { - unsigned short block; - char download[TFTP_MAX_PACKET]; - } data; - struct { - unsigned short block; - } ack; - struct { - unsigned short errcode; - char errmsg[TFTP_DEFAULTSIZE_PACKET]; - } err; - struct { - char data[TFTP_DEFAULTSIZE_PACKET + 2]; - } oack; - } u; -}; - -#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4) - -struct rpc_t { - struct iphdr ip; - struct udphdr udp; - union { - char data[300]; /* longest RPC call must fit!!!! */ - struct { - long id; - long type; - long rpcvers; - long prog; - long vers; - long proc; - long data[1]; - } call; - struct { - long id; - long type; - long rstatus; - long verifier; - long v2; - long astatus; - long data[1]; - } reply; - } u; -}; - -#define PROG_PORTMAP 100000 -#define PROG_NFS 100003 -#define PROG_MOUNT 100005 - -#define MSG_CALL 0 -#define MSG_REPLY 1 - -#define PORTMAP_GETPORT 3 - -#define MOUNT_ADDENTRY 1 -#define MOUNT_UMOUNTALL 4 - -#define NFS_LOOKUP 4 -#define NFS_READ 6 - -#define NFS_FHSIZE 32 - -#define NFSERR_PERM 1 -#define NFSERR_NOENT 2 -#define NFSERR_ACCES 13 - -/* Block size used for NFS read accesses. A RPC reply packet (including all - * headers) must fit within a single Ethernet frame to avoid fragmentation. - * Chosen to be a power of two, as most NFS servers are optimized for this. */ -#define NFS_READ_SIZE 1024 - -#define FLOPPY_BOOT_LOCATION 0x7c00 - -#define ROM_INFO_LOCATION 0x7dfa -/* at end of floppy boot block */ - -struct rom_info { - unsigned short rom_segment; - unsigned short rom_length; -}; - -/*************************************************************************** -External prototypes -***************************************************************************/ -/* main.c */ -extern void print_bytes P((unsigned char *bytes, int len)); -extern void load P((void)); -extern int load_linux P((int root_mount_port, int swap_mount_port, - int root_nfs_port, char *kernel_handle)); -extern int downloadkernel P((unsigned char *, int, int, int)); -extern int tftp -P((const char *name, int (*)(unsigned char *, int, int, int))); -extern void rpc_init(void); -extern int nfs -P((const char *name, int (*)(unsigned char *, int, int, int))); -extern void nfs_umountall P((int)); -extern int bootp P((void)); -extern int rarp P((void)); -extern int udp_transmit P((unsigned long destip, unsigned int srcsock, - unsigned int destsock, int len, - const void *buf)); - -extern int await_reply P((int type, int ival, void *ptr, int timeout)); -extern int decode_rfc1533 P((unsigned char *, int, int, int)); -extern unsigned short ipchksum P((unsigned short *, int len)); -extern void rfc951_sleep P((int)); -extern void cleanup_net P((void)); -extern void cleanup P((void)); - -/* config.c */ -extern void print_config(void); -extern void eth_reset(void); -extern int eth_probe(void); -extern int eth_poll(void); -extern void eth_transmit(const char *d, unsigned int t, unsigned int s, - const void *p); -extern void eth_disable(void); - -/* bootmenu.c */ -extern int execute P((char *string)); -extern void bootmenu P((int)); -extern void show_motd P((void)); -extern void parse_menuopts P((char *, int)); -extern int getoptvalue P((char **, int *, int *)); -extern void selectImage P((char **)); - -/* osloader.c */ -#if defined(AOUT_IMAGE) || defined(ELF_IMAGE) -extern int howto; -#endif -extern int os_download P((unsigned int, unsigned char *, unsigned int)); - -/* misc.c */ -extern void twiddle P((void)); -extern void sleep P((int secs)); -extern int strcasecmp P((char *a, char *b)); -extern char *substr P((char *a, char *b)); -extern int getdec P((char **)); -extern void printf P((const char *, ...)); -extern char *sprintf P((char *, const char *, ...)); -extern int inet_aton P((char *p, in_addr * i)); -extern void gateA20_set P((void)); -extern void gateA20_unset P((void)); -extern void putchar P((int)); -extern int getchar P((void)); -extern int iskey P((void)); - -/* start*.S */ -extern int getc P((void)); -extern void putc P((int)); -extern int ischar P((void)); -extern int getshift P((void)); -extern unsigned int memsize P((void)); -extern unsigned short basememsize P((void)); -extern void disk_init P((void)); -extern unsigned int disk_read P((int drv, int c, int h, int s, char *buf)); -extern void xstart P((unsigned long, unsigned long, char *)); -extern unsigned long currticks P((void)); -extern int setjmp P((void *jmpbuf)); -extern void longjmp P((void *jmpbuf, int where)); -extern void exit P((int status)); -extern void slowdownio P((void)); - -/* serial.S */ -extern int serial_getc P((void)); -extern void serial_putc P((int)); -extern int serial_ischar P((void)); -extern int serial_init P((void)); - -/* ansiesc.c */ -extern void ansi_reset P((void)); -extern void enable_cursor P((int)); -extern void handleansi P((unsigned char)); - -/* md5.c */ -extern void md5_put P((unsigned int ch)); -extern void md5_done P((unsigned char *buf)); - -/* floppy.c */ -extern int bootdisk P((int dev, int part)); - -/*************************************************************************** -External variables -***************************************************************************/ -/* main.c */ -extern const char *kernel; -extern char kernel_buf[128]; -extern struct rom_info rom; -extern int hostnamelen; -extern unsigned long netmask; -extern int jmp_bootmenu[10]; -extern struct arptable_t arptable[MAX_ARP]; -#ifdef IMAGE_MENU -extern char *motd[RFC1533_VENDOR_NUMOFMOTD]; -extern int menutmo, menudefault; -extern unsigned char *defparams; -extern int defparams_max; -#endif -#if defined(ETHERBOOT32) && !defined(INTERNAL_BOOTP_DATA) -#define BOOTP_DATA_ADDR ((struct bootpd_t *)0x93C00) -#else -extern struct bootpd_t bootp_data; -#define BOOTP_DATA_ADDR (&bootp_data) -#endif -extern unsigned char *end_of_rfc1533; -#ifdef IMAGE_FREEBSD -extern int freebsd_howto; -#endif - -/* config.c */ -extern struct nic nic; - -/* bootmenu.c */ - -/* osloader.c */ - -/* created by linker */ -extern char _start[], _edata[], _end[]; - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,197 +0,0 @@ -/* - * arch/mips/galileo/compressed/evb64120A_memSetup.c - * - * By RidgeRun Inc, (Leveraged from Galileo's sbd.c) - * - * Xfer an image from flash to ram. - * For use with Galileo EVB64120A MIPS eval board. - */ -#include "ns16550.h" -#include -#include -#include - -void XferToRam(void); -bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length, - unsigned int bank1Base, unsigned int bank1Length); -bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length, - unsigned int bank3Base, unsigned int bank3Length); -bool mapDevices0_1and2MemorySpace(unsigned int device0Base, - unsigned int device0Length, - unsigned int device1Base, - unsigned int device1Length, - unsigned int device2Base, - unsigned int device2Length); - -#define RUNNINGFROMFLASH -#include "./xfer.c" - -/****************************** - Routine: - Description: - ******************************/ -unsigned int readWord(unsigned int addr) -{ - unsigned int tmp; - tmp = *(unsigned int *) (addr | NONE_CACHEABLE); - return WORDSWAP(tmp); -} - -/****************************** - Routine: - Description: - ******************************/ -void writeWord(unsigned int addr, unsigned int data) -{ - *((unsigned int *) (addr | NONE_CACHEABLE)) = WORDSWAP(data); -} - -/****************************** - Routine: - Description: - ******************************/ -unsigned int GetExtendedMemorySize(void) -{ - unsigned int address, data = 0x11223344, type; - unsigned int bank1_ef = false, bank2_ef = false, bank3_ef = false; - unsigned int bank0_size, bank2_size, bank3_size, total_size = 0; - - mapMemoryBanks0and1(0, 0x800000, 0x800000, 0x800000); - mapMemoryBanks2and3(0x1000000, 0x800000, 0x1800000, 0x800000); - type = readWord(0x14000810); - switch (type) { - case 16: - bank0_size = 0x1000000; - break; - case 64: - bank0_size = 0x4000000; - break; - case 128: - bank0_size = 0x8000000; - break; - case 256: - bank0_size = 0x10000000; - break; - default: - bank0_size = 0x1000000; - break; - } - - type = readWord(0x14000814); - switch (type) { - case 16: - bank2_size = 0x1000000; - bank3_size = 0x1000000; - break; - case 64: - bank2_size = 0x4000000; - bank3_size = 0x4000000; - break; - case 128: - bank2_size = 0x8000000; - bank3_size = 0x8000000; - break; - case 256: - bank2_size = 0x10000000; - bank3_size = 0x10000000; - break; - default: - bank2_size = 0x1000000; - bank3_size = 0x1000000; - break; - } - - /* Check which banks exist */ - /* Bank 1 */ - for (address = 0xffff00; address < 0x1000000; address += 4) - writeWord(address, data); - for (address = 0xffff00; address < 0x1000000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x1000000) - bank1_ef = true; - // Bank 2 - for (address = 0x17fff00; address < 0x1800000; address += 4) - writeWord(address, data); - for (address = 0x17fff00; address < 0x1800000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x1800000) - bank2_ef = true; - else - bank2_size = 0x0; - // Bank 3 - for (address = 0x1ffff00; address < 0x2000000; address += 4) - writeWord(address, data); - for (address = 0x1ffff00; address < 0x2000000; address += 4) { - if (readWord(address) != data) - break; - } - if (address == 0x2000000) - bank3_ef = true; - - // Reconfig the system with the new bank0 (and maybe bank1) size. - if (bank0_size == 0x10000000) - bank1_ef = false; - if (bank1_ef == true) { - mapMemoryBanks0and1(0, bank0_size, bank0_size, bank0_size); - // Fix the PCI bars - pci0MapMemoryBanks0_1(0, bank0_size * 2); - pci1MapMemoryBanks0_1(0, bank0_size * 2); - total_size += bank0_size * 2; - } else { - mapMemoryBanks0and1(0, bank0_size, bank0_size, 0); - // Fix the PCI bars - pci0MapMemoryBanks0_1(0, bank0_size); - pci1MapMemoryBanks0_1(0, bank0_size); - total_size += bank0_size; - } - if (total_size == 0x10000000) { - bank2_ef = false; - bank3_ef = false; - } else { - if ((total_size + bank2_size) > 0x10000000) { - bank2_size = 0x10000000 - total_size; - bank3_ef = false; - } else { - if (bank3_size + total_size + bank2_size > - 0x10000000) { - bank3_size = - 0x10000000 - (total_size + bank2_size); - } - } - } - if (bank2_ef == true) { - if (bank3_ef == true) { - mapMemoryBanks2and3(total_size, bank2_size, - total_size + bank2_size, - bank3_size); - // Fix the PCI bars - pci0MapMemoryBanks2_3(total_size, - bank2_size + bank3_size); - pci1MapMemoryBanks2_3(total_size, - bank2_size + bank3_size); - total_size += (bank2_size + bank3_size); - } else { - mapMemoryBanks2and3(total_size, bank2_size, - total_size + bank2_size, 0); - // Fix the PCI bars - pci0MapMemoryBanks2_3(total_size, bank2_size); - pci1MapMemoryBanks2_3(total_size, bank2_size); - total_size += bank2_size; - } - } else { - mapMemoryBanks2and3(total_size, 0, total_size, 0); - pci0MapMemoryBanks2_3(total_size, 0); - pci1MapMemoryBanks2_3(total_size, 0); - } - /* Reorganize the devices memory map */ - mapDevices0_1and2MemorySpace(0x1c000000, 0x800000, 0x1a000000, - 0xc00000, 0x1d000000, 0x800000); - - XferToRam(); - return 0; // Not that we'll ever get to this line of code, but - // it does satisfy a compiler warning. -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/fixit linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/fixit --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/fixit 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/fixit 1969-12-31 16:00:00.000000000 -0800 @@ -1,17 +0,0 @@ -#!/bin/ksh - -# By RidgeRun Inc. -# -# The input to this script is -# intended to be a *.S file which -# was previously created by the doit -# program. That program constructs -# a *.S file which has a defined data -# table containing values with leading -# zeroes. To satisfy our assembler those -# leading zeroes need to be stripped off -# and that is the purpose of this script. - -echo "Removing leading zeros" -sed -e "s/ 0\(.\)/ \1/g" $1 | sed -e "s/ 0\(.\)/ \1/g" > $1.new -mv $1.new $1 diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1560 +0,0 @@ -/* flashdrv.c - FLASH memory functions and definitions*/ - -/* Copyright Galileo Technology. */ - -/* -DESCRIPTION -This flash driver gives the user a convenient interface to FLASH memory located -on the user`s board, it supports various layout configurations such as: -1. One pure 8 bit device (Such as AMD`s AM29LV040B). -2. 1,2,4 or 8 devices 16 bit wide configured to operate in 8 bit mode. -3. 1,2 or 4 devices each 16 bit wide. -Before using the driver you must call the initialization function at least once -or when ever you are changing the FLASH base address. -The list bellow contains the supported FLASH memory devices, new devices can be -added easily in the future. -*/ - -/*includes*/ -#ifdef __linux__ -#include -#else -#include "flashdrv.h" -#endif -/* locals */ - -#ifdef __MIPSEB__ // skranz, add -#define BE // skranz, add -#endif // skranz, add - -/****************************************************************************** -* Those two tables contain the supported flash devices information needed by -* the driver: -* The first table "flashParametrs" starts with 10 shared fields -* (currently 6 are reserved): -* index 0 => Pointer to an entry in the second table list -* index 1 => baseAddress - Flash memory device base address. -* index 2 => width - 1, 2, 4 or 8 Bytes. -* index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only) -* The second table (flashTypes) contains: -* Entry`s structure: -* Manufacture ID,Device ID,number of sectors,list of sector`s sizes -* (in Kbytes starting with sector number 0). -* The end of the list is pointed with a zero. -******************************************************************************/ -unsigned int flashParametrs[10]; /* 0 Entry pointer */ - /* 0 Base address */ - /* 0 Width */ - /* 0 Mode */ - /* 0,0,0,0,0,0, spare entries. */ -unsigned int flashTypes[] = { - - /* 0 */ AMD_FLASH, AM29F400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64, - 64, 64, 64, - /* 1 */ AMD_FLASH, AM29F400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32, - 8, 8, 16, - /* 2 */ ST_FLASH, M29W040, 8, 64, 64, 64, 64, 64, 64, 64, 64, - /* 3 */ AMD_FLASH, AM29LV040B, 8, 64, 64, 64, 64, 64, 64, 64, 64, - /* 4 */ AMD_FLASH, AM29LV800BT, 19, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 32, 8, 8, 16, - /* 5 */ INTEL_FLASH, I28F320J3A, 32, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, - /* 6 */ INTEL_FLASH, I28F640J3A, 64, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, - /* 7 */ INTEL_FLASH, I28F128J3A, 128, 128, 128, 128, 128, 128, 128, - 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - /* 8 */ AMD_FLASH, AM29LV400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64, - 64, 64, 64, - /* 9 */ AMD_FLASH, AM29LV400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32, - 8, 8, 16, - /* 10 */ INTEL_FLASH, I28F320B3_T, 71, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 8, 8, 8, 8, 8, 8, 8, 8, - /* 11 */ INTEL_FLASH, I28F320B3_B, 71, 8, 8, 8, 8, 8, 8, 8, 8, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - /* 12 */ INTEL_FLASH, I28F160B3_B, 39, 8, 8, 8, 8, 8, 8, 8, 8, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - /* 13 */ INTEL_FLASH, I28F160B3_T, 39, 64, 64, 64, 64, 64, 64, 64, - 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 8, 8, 8, 8, 8, 8, 8, 8, - - 0 /* End of list indicator */ -}; - -/******************************************************************** -* flashInit - Initializes the FLASH memory driver`s parameters, this function -* must be called at least once before using the FLASH memory. -* If you are changing the FLASH base address call this function -* again. -* -* INPUTS: unsigned int flashBaseAddress - The flash base Address. -* unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8. -* flashMode - PURE8, X8 or X16. -* RETURNS: Flash Size, zero when operation (flashInit) failed. -*********************************************************************/ -unsigned int flashInit(unsigned int flashBaseAddress, - unsigned int flashWidth, FLASHmode flashMode) -{ - unsigned short mfrId = 0; - unsigned short devId = 0xffff; - unsigned int FirstAddr, SecondAddr, ThirdAddr; - unsigned int pArray = 0; - unsigned int counter; - unsigned int flashSize = 0; - - /* update the list with relevant parametrs */ - flashParametrs[0] = 0; /* Default initialization */ - flashParametrs[1] = flashBaseAddress; - flashParametrs[2] = flashWidth; - flashParametrs[3] = flashMode; - /* Get the FLASH`s ID */ - switch (FLASH_WIDTH) { - case 1: - /* AMD or ST ?? * */ - if (flashMode == PURE8) { /* Boot Flash */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { /* X16 device configured to 8bit Mode */ - - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - } - flashReset(); - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90); - READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); - if (mfrId == AMD_FLASH || mfrId == ST_FLASH) { - flashReset(); - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90); - READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); - break; - } - /* Micron or Intel ?? * */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */ - /* Flash reset for Intel/Micron */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */ - READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); /*Address for ManufactureID */ - if (mfrId == INTEL_FLASH || mfrId == MICRON_FLASH) { - WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */ - /*Flash reset for Intel/Micron */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */ - READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); /*Address for DeviceID */ - } - break; - case 2: - case 4: - case 8: - /* AMD or ST ??? */ - flashReset(); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH, - 0xaa); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x2aaa * FLASH_WIDTH, - 0x55); - WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH, - 0x90); - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - flashReset(); - /* Read the device ID */ - if (mfrId == AMD_FLASH || mfrId == ST_FLASH) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x5555 * FLASH_WIDTH, 0xaa); - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x2aaa * FLASH_WIDTH, 0x55); - WRITE_SHORT(FLASH_BASE_ADDRESS + - 0x5555 * FLASH_WIDTH, 0x90); - READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH, - &devId); - break; - } - /* Micron or Intel ?? * */ - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090); - if ((FLASH_WIDTH == 4) || (FLASH_WIDTH == 8)) { /* 32 or 64 bit */ - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - } else { /* FLASH_WIDTH = 2 */ - - READ_SHORT(FLASH_BASE_ADDRESS, &mfrId); - } - if ((mfrId == INTEL_FLASH) || (mfrId == MICRON_FLASH)) { - /* Flash reset for Intel/Micron */ - flashReset(); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff); - WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090); - READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH, - &devId); - } - break; - - } - /* Try to locate the device in the supported flashes list (FLASH_TYPE). - according to the keys: - 1) mfrId - manufactor ID. - 2) devId - device ID. - */ - - while (true) { - if (flashTypes[pArray] == 0) { - flashReset(); - return 0; /* Device not in the list */ - } - if ((flashTypes[pArray] == mfrId) && - (flashTypes[pArray + 1] == devId)) { - POINTER_TO_FLASH = pArray; - for (counter = 0; - counter < flashTypes[NUMBER_OF_SECTORS]; - counter++) { - flashSize = - flashSize + - flashTypes[FIRST_SECTOR_SIZE + - counter]; - } - if (FLASH_MODE != PURE8) { - flashReset(); - return (flashSize * _1K * - (FLASH_WIDTH / (FLASH_MODE / 8))); - } else { - flashReset(); - return (flashSize * _1K * FLASH_WIDTH); - } - } - pArray += (3 + flashTypes[pArray + 2]); /* Move to next entry */ - } -} - -/******************************************************************** -* flashReset - Resets the Flash memory (FLASH`s internal protocol reset). -* -* INTPUTS: N/A -* OUTPUT: N/A -*********************************************************************/ -void flashReset() -{ - unsigned char ucData; - unsigned short usData; - unsigned int uiData; - - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || - (flashTypes[POINTER_TO_FLASH]) == ST_FLASH) { - if (FLASH_MODE == X16) { - ucData = 0xf0; - usData = 0xf0; - uiData = 0x00f000f0; - } else { /* case of PURE8 or X8 */ - - ucData = 0xf0; - usData = 0xf0f0; - uiData = 0xf0f0f0f0; - } - } else { - if (FLASH_MODE == X16) { - ucData = 0xff; - usData = 0xff; - uiData = 0x00ff00ff; - } else { /* case of PURE8 or X8 */ - - ucData = 0xff; - usData = 0xffff; - uiData = 0xffffffff; - } - } - switch (FLASH_WIDTH) { - case 1: - WRITE_CHAR(FLASH_BASE_ADDRESS, ucData); - break; - case 2: - WRITE_SHORT(FLASH_BASE_ADDRESS, usData); - break; - case 4: - WRITE_WORD(FLASH_BASE_ADDRESS, uiData); - break; - case 8: - WRITE_WORD(FLASH_BASE_ADDRESS, uiData); - WRITE_WORD(FLASH_BASE_ADDRESS + 0x4, uiData); - break; - } -} - -/******************************************************************** -* flashErase - The function erases the WHOLE flash memory. -* -* -* RETURNS: true on success,false on failure -*********************************************************************/ -bool flashErase() -{ - unsigned int totalFlashSize; - unsigned int address; - unsigned int readData; - unsigned int nextSector; - - flashReset(); - totalFlashSize = flashGetSize(); - /* scan all flash memory space. */ - address = 0; - while (address < totalFlashSize) { - readData = flashReadWord(address); - if (readData != 0xffffffff) { /* offset with dirty data. */ - flashEraseSector(flashInWhichSector(address)); - nextSector = flashInWhichSector(address) + 1; - if (nextSector < flashTypes[NUMBER_OF_SECTORS]) - /* jump to next sector. */ - address = flashGetSectorOffset(nextSector); - else - /* end of erasing. */ - address = totalFlashSize; - } else - address += 4; - } - return true; -} - -/******************************************************************** -* flashEraseSector - The function erases a specific sector in the flash memory. -* -* INPUTS: Sector number. -* RETURNS: true on success,false on failure. -*********************************************************************/ -bool flashEraseSector(unsigned int sectorNumber) -{ - volatile unsigned int spin; - unsigned int regValue; - unsigned int sectorBaseAddress = 0; - unsigned int i; - unsigned int data20, dataD0, data70; - unsigned int dataPoll; - unsigned int FirstAddr, SecondAddr, ThirdAddr, FourthAddr, - FifthAddr; - unsigned int FirstData, SecondData, ThirdData; - unsigned int FourthData, FifthData, SixthData; - - /* calculate the sector base Address according to the following parametrs: - 1: FLASH_WIDTH - 2: the size of each sector which it detailed in the table */ - - /* checking the if the sectorNumber is legal. */ - if (sectorNumber > flashTypes[NUMBER_OF_SECTORS] - 1) - return false; - /* now the calculation begining of the sector Address */ - for (i = 0; i < sectorNumber; i++) { - sectorBaseAddress = - sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i]; - } - /* In case of X8 wide the address should be */ - if (FLASH_MODE == PURE8) - sectorBaseAddress = _1K * sectorBaseAddress; - if (FLASH_MODE == X8) - sectorBaseAddress = _1K * sectorBaseAddress; - /* In case of X16 wide the address should be */ - if (FLASH_MODE == X16) - sectorBaseAddress = _1K * sectorBaseAddress / 2; - flashReset(); - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \ - (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) { - switch (FLASH_WIDTH) { - case 1: - if (FLASH_MODE == PURE8) { /* Boot Flash PURE8 */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - FourthAddr = 0x5555; - FifthAddr = 0x2aaa; - } else { - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - FourthAddr = 0xaaaa; - FifthAddr = 0x5555; - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x80); - WRITE_CHAR(FLASH_BASE_ADDRESS + FourthAddr, 0xAA); - WRITE_CHAR(FLASH_BASE_ADDRESS + FifthAddr, 0x55); - WRITE_CHAR( - (FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00)), - 0x30); - /* Poll on the flash */ - do { - READ_CHAR(FLASH_BASE_ADDRESS + - sectorBaseAddress, ®Value); - } while ((regValue & 0x80) != 0x80); - - break; - case 2: - if (FLASH_MODE == X16) { - FirstData = 0xaa; /* Data for the First Cycle */ - SecondData = 0x55; /* Data for the Second Cycle */ - ThirdData = 0x80; /* Data for the Third Cycle */ - FourthData = 0xaa; /* Data for the Fourth Cycle */ - FifthData = 0x55; /* Data for the Fifth Cycle */ - SixthData = 0x30; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* (FLASH_MODE = 8) */ - - FirstData = 0xaaaa; /* Data for the First Cycle */ - SecondData = 0x5555; /* Data for the Second Cycle */ - ThirdData = 0x8080; /* Data for the Third Cycle */ - FourthData = 0xaaaa; /* Data for the Fourth Cycle */ - FifthData = 0x5555; /* Data for the Fifth Cycle */ - SixthData = 0x3030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 1 device of 16 bit */ - dataPoll = 0x0080; - } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */ - - dataPoll = 0x8080; - } - do { - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - for (spin = 0; spin < 100; spin++) { - } // skranz, added spin loop. - } while ((regValue & dataPoll) != dataPoll); - break; - case 4: - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; /* Data for the First Cycle */ - SecondData = 0x00550055; /* Data for the Second Cycle */ - ThirdData = 0x00800080; /* Data for the Third Cycle */ - FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */ - FifthData = 0x00550055; /* Data for the Fifth Cycle */ - SixthData = 0x00300030; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* if (FLASH_MODE == 8) */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0x80808080; /* Data for the Third Cycle */ - FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */ - FifthData = 0x55555555; /* Data for the Fifth Cycle */ - SixthData = 0x30303030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - dataPoll = 0x00800080; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - dataPoll = 0x80808080; - } - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - } while ((regValue & dataPoll) != dataPoll); - break; - case 8: /* In case of 64bit width the transformation is 1->8 */ - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; /* Data for the First Cycle */ - SecondData = 0x00550055; /* Data for the Second Cycle */ - ThirdData = 0x00800080; /* Data for the Third Cycle */ - FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */ - FifthData = 0x00550055; /* Data for the Fifth Cycle */ - SixthData = 0x00300030; /* Data for the Sixth Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - FourthAddr = 0x5555; /* Address for the Fourth Cycle */ - FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */ - } else { /* (FLASH_MODE = 8 */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0x80808080; /* Data for the Third Cycle */ - FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */ - FifthData = 0x55555555; /* Data for the Fifth Cycle */ - SixthData = 0x30303030; /* Data for the Sixth Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */ - FifthAddr = 0x5555; /* Address for the Fifth Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH, FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) * - FLASH_WIDTH, SixthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH + 4, FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH + 4, - SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH + 4, ThirdData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FourthAddr * FLASH_WIDTH + 4, - FourthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - FifthAddr * FLASH_WIDTH + 4, FifthData); - WRITE_WORD(FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00) - * FLASH_WIDTH + 4, SixthData); - /* Poll on the flash */ - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - dataPoll = 0x00800080; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - dataPoll = 0x80808080; - } - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH, - ®Value); - } while ((regValue & dataPoll) != dataPoll); - do { - READ_WORD(FLASH_BASE_ADDRESS + - sectorBaseAddress * FLASH_WIDTH + - 4, ®Value); - } while ((regValue & dataPoll) != dataPoll); - break; - default: - return false; - } - } /* End of 'flash erase sector' for AMD/ST */ - else { /* Intel/Micron */ - - switch (FLASH_WIDTH) { - case 1: - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x20); - WRITE_CHAR( - (FLASH_BASE_ADDRESS + - (sectorBaseAddress & 0xffffff00)), - 0xd0); - /* Poll on the flash */ - while (true) { - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - READ_CHAR(FLASH_BASE_ADDRESS, ®Value); - if ((regValue & 0x80) == 0x80) - break; - } - break; - case 2: - if (FLASH_MODE == X16) { /* 1 device 16 bit. */ - data20 = 0x0020;; - dataD0 = 0x00d0;; - } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */ - - data20 = 0x2020; - dataD0 = 0xd0d0; - } - WRITE_SHORT(FLASH_BASE_ADDRESS, data20); - WRITE_SHORT( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 2) & - 0xffffff00)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 2, data70); - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 2, - ®Value); - if ((regValue & 0x0080) == 0x0080) - break; - } - break; - case 4: - if (FLASH_MODE == X16) { /* 2 devices , 16 bit each => 32bit */ - data20 = 0x00200020; - dataD0 = 0x00d000d0; - } else { /* (FLASH_MODE = 8) ==> 4 devices , 8 bit each => 32bit */ - - data20 = 0x20202020; - dataD0 = 0xd0d0d0d0; - } - WRITE_WORD(FLASH_BASE_ADDRESS, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 4) & - 0xffffff00)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS, data70); - READ_SHORT(FLASH_BASE_ADDRESS, ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 2, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - break; - case 8: - if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */ - data20 = 0x00200020; - dataD0 = 0x00d000d0; - } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */ - - data20 = 0x20202020; - dataD0 = 0xd0d0d0d0; - } - WRITE_WORD(FLASH_BASE_ADDRESS, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 8) & - 0xffffff00)), dataD0); - WRITE_WORD(FLASH_BASE_ADDRESS + 4, data20); - WRITE_WORD( - (FLASH_BASE_ADDRESS + - ((sectorBaseAddress * 8) & 0xffffff00 + - 4)), dataD0); - /* Poll on the flash */ - if (FLASH_MODE == X16) { - dataPoll = 0x0080; - data70 = 0x0070; - } else { /* (FLASH_MODE = 8) */ - - dataPoll = 0x8080; - data70 = 0x7070; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 8, data70); - READ_SHORT(FLASH_BASE_ADDRESS + - sectorBaseAddress * 8, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 2, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 4, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 4, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 6, - data70); - READ_SHORT(FLASH_BASE_ADDRESS + 6, - ®Value); - if ((regValue & dataPoll) == dataPoll) - break; - } - break; - default: - return false; - } - } - flashReset(); - return true; -} - -/******************************************************************** -* flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the -* FLASH base address. -* address 0 = 0x00000000 !! -* Attention!!! data "0" cannot be programed back to -* "1" (only by first performing an earase operation). -* The function takes care of Big/Little endian conversion -* -* INPUTS: offset - The offset from the flash`s base address. -* data - The data that should be written. -* RETURNS: true on success,false on failure -*********************************************************************/ -bool flashWriteWord(unsigned int offset, unsigned int data) -{ - unsigned char c, rc; - unsigned short s, rs; - register unsigned int rw; - register unsigned int regValue; - register unsigned int FirstAddr, SecondAddr, ThirdAddr; - register unsigned int FirstData, SecondData, ThirdData; - register unsigned int data10, data20, data70, data80; - - if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \ - (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) { - switch (FLASH_WIDTH) { - case 1: /* Split the 32 bit write into four 8bit Writings */ - if (FLASH_MODE == PURE8) { /* Boot Flash */ - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { - FirstAddr = 0xaaaa; - SecondAddr = 0x5555; - ThirdAddr = 0xaaaa; - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 24); -#else - c = data; -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c); - /* Writing first Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 16); -#else - c = (data >> 8); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c); - /* Writing second Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 1, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 1, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = (data >> 8); -#else - c = (data >> 16); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c); - /* Writing third Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 2, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 2, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa); - WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55); - WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0); -#ifdef BE - c = data; -#else - c = (data >> 24); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c); - /* Writing fourth Byte */ - while (true) { - READ_CHAR(FLASH_BASE_ADDRESS + offset + 3, - &rc); - if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */ - READ_CHAR(FLASH_BASE_ADDRESS + - offset + 3, &rc); - if ((rc & 0x80) == (c & 0x80)) - break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - break; - case 2: /* Split the 32 bit write into two 8/16 bit Writings - (16bit width). */ - if (FLASH_MODE == X16) { - FirstData = 0xaa; /* Data for the First Cycle */ - SecondData = 0x55; /* Data for the Second Cycle */ - ThirdData = 0xa0; /* Data for the Third Cycle */ - FirstAddr = 0x5555; /* Address for the First Cycle */ - SecondAddr = 0x2aaa; /* Address for the Second Cycle */ - ThirdAddr = 0x5555; /* Address for the Third Cycle */ - } else { /* if (FLASH_MODE == 8) */ - - FirstData = 0xaaaa; /* Data for the First Cycle */ - SecondData = 0x5555; /* Data for the Second Cycle */ - ThirdData = 0xa0a0; /* Data for the Third Cycle */ - FirstAddr = 0xaaaa; /* Address for the First Cycle */ - SecondAddr = 0x5555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaa; /* Address for the Third Cycle */ - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s); - /* Writing Two Bytes */ - if (FLASH_MODE == X16) { - data80 = 0x80;; - data20 = 0x20;; - } else { /* if (FLASH_MODE == 8) */ - - data80 = 0x8080; - data20 = 0x2020; - } - while (true) { - READ_SHORT(FLASH_BASE_ADDRESS + offset, - &rs); - if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rs & data20) == data20) { /* DQ5 =? DATA */ - READ_SHORT(FLASH_BASE_ADDRESS + - offset, &rs); - if ((rs & data80) == (s & data80)) - break; /* DQ7 = DATA */ - else { - flashReset(); - return false; /* DQ7 != DATA */ - } - } - } - WRITE_SHORT(FLASH_BASE_ADDRESS + - FirstAddr * FLASH_WIDTH, FirstData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH, SecondData); - WRITE_SHORT(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH, ThirdData); -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s); - /* Writing Two Bytes */ - while (true) { - READ_SHORT(FLASH_BASE_ADDRESS + offset + 2, - &rs); - if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */ - break; /* DQ7 = DATA */ - if ((rs & data20) == data20) { /* DQ5 =? '1' */ - READ_SHORT(FLASH_BASE_ADDRESS + - offset + 2, &rs); - if ((rs & data80) == (s & data80)) - break; /* DQ7 = DATA */ - else { - flashReset(); - return false; /* DQ7 != DATA */ - } - } - } - return true; - case 4: - case 8: - if (FLASH_MODE == X16) { - FirstData = 0x00aa00aa; - SecondData = 0x00550055; - ThirdData = 0x00a000a0; - FirstAddr = 0x5555; - SecondAddr = 0x2aaa; - ThirdAddr = 0x5555; - } else { /* (FLASH_MODE == 8) */ - - FirstData = 0xaaaaaaaa; /* Data for the First Cycle */ - SecondData = 0x55555555; /* Data for the Second Cycle */ - ThirdData = 0xa0a0a0a0; /* Data for the Third Cycle */ - FirstAddr = 0xaaaaaaaa; /* Address for the First Cycle */ - SecondAddr = 0x55555555; /* Address for the Second Cycle */ - ThirdAddr = 0xaaaaaaaa; /* Address for the Third Cycle */ - } - WRITE_WORD(FLASH_BASE_ADDRESS + FirstAddr * - FLASH_WIDTH + offset % FLASH_WIDTH, - FirstData); - WRITE_WORD(FLASH_BASE_ADDRESS + - SecondAddr * FLASH_WIDTH + - offset % FLASH_WIDTH, SecondData); - WRITE_WORD(FLASH_BASE_ADDRESS + - ThirdAddr * FLASH_WIDTH + - offset % FLASH_WIDTH, ThirdData); - /* writting the word. */ - WRITE_WORD(FLASH_BASE_ADDRESS + offset, data); - /* preparing the polling patterns. */ - if (FLASH_MODE == X16) { - data80 = 0x00800080; - data20 = 0x00200020; - } else { /* (FLASH_MODE == 8) */ - - data80 = 0x80808080; - data20 = 0x20202020; - } - while (true) { /* polling loop. */ - rw = READWORD(FLASH_BASE_ADDRESS + offset); - /* DQ7 =? DATA */ - if ((rw & data80) == (data & data80)) - break; /* DQ7 = DATA */ - if ((rw & data20) == data20) { /* DQ5 =? '1' */ - rw = - READWORD(FLASH_BASE_ADDRESS + - offset); - if ((rw & data80) == - (data & data80)) break; /* DQ7 = DATA */ - else - return false; /* DQ7 != DATA */ - } - } - return true; - default: - return false; /* case of invalid flash Width. */ - } - } else { /* Intel/Micron */ - - switch (FLASH_WIDTH) { - case 1: - /* Writing First Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x10); -#ifdef BE - c = (data >> 24); -#else - c = data; -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & 0x80) == 0x80) - break; /* Case of Write-Operation had Ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Second Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x10); -#ifdef BE - c = (data >> 16); -#else - c = (data >> 8); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 1); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 1); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Third Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x10); -#ifdef BE - c = (data >> 8); -#else - c = (data >> 16); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 2); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 2); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - - /* Writing Fourth Byte */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x10); -#ifdef BE - c = data; -#else - c = (data >> 24); -#endif - WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c); - while (true) { - /* Reading STATUS Register */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70); - regValue = - READCHAR(FLASH_BASE_ADDRESS + 3); - if ((regValue & 0x80) == 0x80) - break; /* Write operation ended */ - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70); - regValue = READCHAR(FLASH_BASE_ADDRESS + 3); - if ((regValue & 0x10) == 0x10) - return false; /* Write failure */ - flashReset(); - return true; - case 2: - if (FLASH_MODE == X16) { /* Case of one X16 bit device */ - FirstData = 0x0010; /* Data for the First Cycle */ - } else { /* if (FLASH_MODE == 8) ==> Case of two X8 bit devices */ - - FirstData = 0x1010; /* Data for the First Cycle */ - } - /* Writing First two Bytes */ - WRITE_SHORT(FLASH_BASE_ADDRESS, FirstData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s); - if (FLASH_MODE == X16) { - data70 = 0x0070; - data80 = 0x0080; - data10 = 0x0010; - } else { /* case of (FLASH_MODE == X8) */ - - data70 = 0x7070; - data80 = 0x8080; - data10 = 0x1010; - } - /* polling on writing action => when done break. */ - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS, data70); - regValue = READSHORT(FLASH_BASE_ADDRESS); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - /* Writing Last two Bytes */ - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, FirstData); -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s); - /* polling on writing action => when done break. */ - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + 2, - data70); - regValue = - READSHORT(FLASH_BASE_ADDRESS + 2); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - flashReset(); - return true; - case 4: - case 8: - if (FLASH_MODE == X16) { /* Case of one X16 bit device */ - FirstData = 0x00100010; /* Data for the First Cycle */ - } else { /* (FLASH_MODE == 8) ==> Case of two X8 bit devices */ - - FirstData = 0x10101010; /* Data for the First Cycle */ - } - /* Writing First two Bytes */ - WRITE_WORD(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH, FirstData); -#ifdef BE - s = (data >> 16); -#else - s = data; -#endif - /* writing the 32-bit data to flash. */ - WRITE_WORD(FLASH_BASE_ADDRESS + offset, data); - if (FLASH_MODE == X16) { - data70 = 0x0070; - data80 = 0x0080; - data10 = 0x0010; - } else { /* (FLASH_MODE == 8) */ - - data70 = 0x7070; - data80 = 0x8080; - data10 = 0x1010; - } - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH, data70); - regValue = READSHORT(FLASH_BASE_ADDRESS); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - - /* Writing Last two Bytes */ -#ifdef BE - s = data; -#else - s = (data >> 16); -#endif - while (true) { - WRITE_SHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH + 2, - data70); - regValue = - READSHORT(FLASH_BASE_ADDRESS + - offset % FLASH_WIDTH + 2); - if ((regValue & data80) == data80) - break; - } - /* Reading STATUS Register for Writing Verification */ - WRITE_CHAR(FLASH_BASE_ADDRESS, data70); - regValue = READCHAR(FLASH_BASE_ADDRESS); - if ((regValue & data10) == data10) - return false; /* Write failure */ - - flashReset(); - return true; - default: - flashReset(); - return false; - } - } - flashReset(); - return true; -} - -/******************************************************************** -* flashReadWord - Read 32Bit from the FLASH memory at a given offset -* from the FLASH base address. -* address 0 = 0x00000000 !! -* The function takes care of Big/Little endian conversion -* INPUTS: offset,the offset from the flash`s base address -* RETURNS: data -*********************************************************************/ -unsigned int flashReadWord(unsigned int offset) -{ - unsigned int regValue; - flashReset(); - READ_WORD(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashInWhichSector - Returns the sector`s number at which offset is at. -* -* INPUTS: Offset -* RETURNS: Sector number,or 0xffffffff in case the address is out of range or -* flash wasn't initialize. -*********************************************************************/ -unsigned int flashInWhichSector(unsigned int offset) -{ - unsigned int sectorNumber, numberOfDevices; - unsigned int accMemory = 0; - - if ((FLASH_MODE == PURE8) || (FLASH_MODE == X8)) { - numberOfDevices = FLASH_WIDTH; - } else { /* X16 mode */ - - numberOfDevices = FLASH_WIDTH / 2; - } - for (sectorNumber = 0; - sectorNumber < flashTypes[NUMBER_OF_SECTORS]; sectorNumber++) { - accMemory = - accMemory + flashTypes[FIRST_SECTOR_SIZE + - sectorNumber]; - if (offset < accMemory * numberOfDevices * 1024) - return sectorNumber; - } - return 0xffffffff; -} - -/******************************************************************** -* flashGetSectorSize - When given a Valid sector Number returns its Size. -* -* INPUTS: unsigned int sectorNumber. -* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't -* initialize return 0.) -*********************************************************************/ -unsigned int flashGetSectorSize(unsigned int sectorNumber) -{ - if (sectorNumber >= flashTypes[NUMBER_OF_SECTORS]) - return 0; - else { - if (FLASH_MODE != PURE8) - return (flashTypes - [FIRST_SECTOR_SIZE + - sectorNumber] * _1K * (FLASH_WIDTH * 8 / - FLASH_MODE)); - else /* in case of PUR8 */ - return (flashTypes - [FIRST_SECTOR_SIZE + - sectorNumber] * _1K * FLASH_WIDTH); - } -} - -/******************************************************************** -* getFlashSize - Return Total flash size. -* -* INPUTS: N/A. -* RETURNS: Flash size. (If flash wasn't initialize return 0) -*********************************************************************/ -unsigned int flashGetSize() -{ - unsigned int sectorNum; - unsigned int totalSize = 0; - - if (POINTER_TO_FLASH == 0) - return 0; /* case of flash not initialize */ - for (sectorNum = 0; sectorNum < flashTypes[NUMBER_OF_SECTORS]; - sectorNum++) { - totalSize += flashGetSectorSize(sectorNum); - } - return (totalSize); - -} - -/******************************************************************** -* flashGetSectorOffset - Returns sector base address. -* -* INPUTS: unsigned int sectorNum. -* RETURNS: Sector Base Address. -*********************************************************************/ -unsigned int flashGetSectorOffset(unsigned int sectorNum) -{ - unsigned int i; - unsigned int sectorBaseAddress = 0; - unsigned int numOfDevices; - - if (sectorNum > (flashParametrs[NUMBER_OF_SECTORS] - 1)) - return 0xffffffff; - for (i = 0; i < sectorNum; i++) { - sectorBaseAddress = - sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i]; - } - if (FLASH_MODE == X16) - numOfDevices = FLASH_WIDTH * 8 / FLASH_MODE; - else - numOfDevices = FLASH_WIDTH; - return (_1K * sectorBaseAddress * numOfDevices); - -} - -/******************************************************************** -* flashWriteBlock - Write block of chars to flash. -* -* INPUTS: unsigned int offset - flash destination address. -* unsigned int numOfByte - block size. -* unsigned char * blockAddress - block source address. -* RETURNS: Number of Bytes written. -*********************************************************************/ -unsigned int flashWriteBlock(unsigned int offset, unsigned int numOfByte, - unsigned char *blockAddress) -{ - register unsigned int flashWrite; - register unsigned int align; - register unsigned int num; - register unsigned int i; - - if ((offset + numOfByte) > flashGetSize()) - numOfByte = flashGetSize() - offset; /* getting to flash boundary. */ - num = numOfByte; - align = offset % 4; /* alignment toward flash. */ - /* writes chars until the offset toward flash will be align. */ - for (i = align; (i < 4) && (numOfByte > 0) && (align != 0); i++) { - flashWriteChar(offset, blockAddress[0]); - numOfByte--; - offset++; - blockAddress++; - } - while (numOfByte > 3) { -#ifdef LE - flashWrite = blockAddress[0] | (blockAddress[1] << 8) | - (blockAddress[2] << 16) | (blockAddress[3] << 24); -#else - flashWrite = blockAddress[3] | (blockAddress[2] << 8) | - (blockAddress[1] << 16) | (blockAddress[0] << 24); -#endif - if (flashWrite != 0xffffffff) /* for optimization. */ - flashWriteWord(offset, flashWrite); - numOfByte -= 4; - blockAddress += 4; - offset += 4; - } - while (numOfByte > 0) { - flashWriteChar(offset, blockAddress[0]); - numOfByte--; - blockAddress++; - offset++; - } - return num; -} - -/******************************************************************** -* flashReadBlock - Read block of chars from flash. -* -* INPUTS: unsigned int offset - flash source address. -* unsigned int numOfByte - block size. -* unsigned char * blockAddress - block destination address. -* RETURNS: Number of Bytes written. -*********************************************************************/ -unsigned int flashReadBlock(unsigned int offset, unsigned int numOfByte, - unsigned char *blockAddress) -{ - unsigned int i; - for (i = 0; i < numOfByte; i++) { - blockAddress[i] = flashReadChar(offset + i); - } - return numOfByte; -} - -/******************************************************************** -* flashReadChar - read one charecter form given flash offset. -* -* INPUTS: unsigned int offset - required offset to be read from. -* RETURNS: read charecter. -*********************************************************************/ -unsigned char flashReadChar(unsigned int offset) -{ - unsigned char regValue; - - flashReset(); - READ_CHAR(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashReadShort - read 16bit form given flash offset. -* -* INPUTS: unsigned int offset - required offset to be read from. -* RETURNS: 16bit data. -*********************************************************************/ -unsigned short flashReadShort(unsigned int offset) -{ - unsigned short regValue; - - flashReset(); - READ_SHORT(FLASH_BASE_ADDRESS + offset, ®Value); - return regValue; -} - -/******************************************************************** -* flashWriteShort - write 16bit data to a given flash offset. -* It reads the whole word 32bit wide, modify the short -* and write back the word. -* -* INPUTS: unsigned int offset - required offset to be write to. -* unsigned short sdata - data to be written. -* RETURNS: true if writting successesed false otherwise. -*********************************************************************/ -bool flashWriteShort(unsigned int offset, unsigned short sdata) -{ - unsigned int align; - unsigned int flashWrite; - unsigned int flashRead; - - align = offset % 4; - if ((align == 1) || (align == 3)) - return false; /* offset misaligned. */ - flashRead = flashReadWord(offset - align); - if (align == 0) -#ifdef BE - flashWrite = (flashRead & 0x0000ffff) | (sdata << 16); -#else - flashWrite = (flashRead & 0xffff0000) | sdata; -#endif - else /* (align == 2) */ -#ifdef BE - flashWrite = (flashRead & 0xffff0000) | sdata; -#else - flashWrite = (flashRead & 0x0000ffff) | (sdata << 16); -#endif - flashWriteWord(offset - align, flashWrite); - return true; - -} - -/******************************************************************** -* flashWriteChar - write one charecter (8 bit) to a given flash offset. -* It reads the whole word 32bit wide, modify the charecter -* and write back the word. -* -* INPUTS: unsigned int offset - required offset to be write to. -* unsigned short sdata - data to be written. -* RETURNS: true if writting successed. -*********************************************************************/ -bool flashWriteChar(unsigned int offset, unsigned char cdata) -{ - unsigned int align; - unsigned int flashWrite; - unsigned int flashRead; - - align = offset % 4; - flashRead = flashReadWord(offset - align); -#ifdef BE - flashWrite = (flashRead & ~(0xff000000 >> (8 * align))) | - (cdata << (8 * (3 - align))); -#else - flashWrite = (flashRead & ~(0xff000000 << (8 * align))) | - (cdata << (8 * align)); -#endif - flashWriteWord(offset - align, flashWrite); - return true; -} - -/******************************************************************** -* flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset. -* It reads the whole word 32bit wide, modify the -* charecter and write back the word. -* -* INPUTS: N/A. -* RETURNS: Number of sectors. -*********************************************************************/ -unsigned int flashGetNumOfSectors(void) -{ - return (flashTypes[NUMBER_OF_SECTORS]); -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,8 +0,0 @@ -#define GFP_KERNEL 0 -#define GFP_ATOMIC 1 -#define KERN_ERR "" - -void *kmalloc(unsigned int, int); -void *memset(void *, char, unsigned int); -int memcmp(char *, char *, unsigned int); -void *memcpy(void *to, const void *from, unsigned int); diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/gt64011.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/gt64011.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/gt64011.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/gt64011.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,279 +0,0 @@ -/* - * gt64011.h: Galileo PCI system controller - * Copyright (c) 1998 Algorithmics Ltd - */ - -#ifdef __ASSEMBLY__ - -/* offsets from base register */ -#define GT64011(x) (x) - -/* device is littleendian, so data may need to be swapped */ -#ifdef GALILEO_PORT -#define htoll(x) ((((x) & 0x00ff) << 24) | \ - (((x) & 0xff00) << 8) | \ - (((x) >> 8) & 0xff00) | \ - (((x) >> 24) & 0x00ff)) -/*#define ltohl(x) htoll(x)*/ -#else -#define htoll(x) (x) -/* #define ltohl(x) (x) */ -#endif - -#else /* !__ASSEMBLY__ */ - -/* offsets from base pointer, this construct allows optimisation */ -static char *const _gt64011p = (char *) PA_TO_KVA1(GT64011_BASE); - -#define GT64011(x) *(volatile unsigned long *)(_gt64011p + (x)) - -/* device is littleendian, so data may need to be swapped */ -#ifdef GALILEO_PORT -#define htoll(x) ({ \ - unsigned int v = (unsigned int)(x); \ - v = (((v & 0x00ff) << 24) | \ - ((v & 0xff00) << 8) | \ - ((v >> 8) & 0xff00) | \ - ((v >> 24) & 0x00ff)); \ - v; \ - }) -#define ltohl(x) htoll(x) - -#else -asjdsajd -#define htoll(x) (x) -#define ltohl(x) (x) -#endif -#endif /* __ASSEMBLY__ */ -/* CPU configuration */ -#define GT_CPU_CFG GT64011(0x000) -#define GT_CPU_CFG_WriteMode (1<<11) -#define GT_CPU_CFG_Endianess (1<<12) -/* Processor Address Space */ -#define GT_PAS_RAS10LO GT64011(0x008) -#define GT_PAS_RAS10HI GT64011(0x010) -#define GT_PAS_RAS32LO GT64011(0x018) -#define GT_PAS_RAS32HI GT64011(0x020) -#define GT_PAS_CS20LO GT64011(0x028) -#define GT_PAS_CS20HI GT64011(0x030) -#define GT_PAS_CS3BOOTLO GT64011(0x038) -#define GT_PAS_CS3BOOTHI GT64011(0x040) -#define GT_PAS_PCIIOLO GT64011(0x048) -#define GT_PAS_PCIIOHI GT64011(0x050) -#define GT_PAS_PCIMEMLO GT64011(0x058) -#define GT_PAS_PCIMEMHI GT64011(0x060) -#define GT_PAS_INTDEC GT64011(0x068) -#define GT_PAS_BUSERRLO GT64011(0x070) -#define GT_PAS_PCIMEM1LO GT64011(0x080) -#define GT_PAS_PCIMEM1HI GT64011(0x088) -#define GT_PAS_LOMASK_Low 0x7ff -#define GT_PAS_LOSHIFT_Low 0 -#define GT_PAS_HIMASK_High 0x07f -#define GT_PAS_HISHIFT_High 0 -/* DRAM and Device Address Space */ -#define GT_DDAS_RAS0LO GT64011(0x400) -#define GT_DDAS_RAS0HI GT64011(0x404) -#define GT_DDAS_RAS1LO GT64011(0x408) -#define GT_DDAS_RAS1HI GT64011(0x40c) -#define GT_DDAS_RAS2LO GT64011(0x410) -#define GT_DDAS_RAS2HI GT64011(0x414) -#define GT_DDAS_RAS3LO GT64011(0x418) -#define GT_DDAS_RAS3HI GT64011(0x41c) -#define GT_DDAS_CS0LO GT64011(0x420) -#define GT_DDAS_CS0HI GT64011(0x424) -#define GT_DDAS_CS1LO GT64011(0x428) -#define GT_DDAS_CS1HI GT64011(0x42c) -#define GT_DDAS_CS2LO GT64011(0x430) -#define GT_DDAS_CS2HI GT64011(0x434) -#define GT_DDAS_CS3LO GT64011(0x438) -#define GT_DDAS_CS3HI GT64011(0x43c) -#define GT_DDAS_BOOTCSLO GT64011(0x440) -#define GT_DDAS_BOOTCSHI GT64011(0x444) -#define GT_DDAS_ERROR GT64011(0x470) -#define GT_DDAS_LOMASK_Low 0xff -#define GT_DDAS_LOSHIFT_Low 0 -#define GT_DDAS_HIMASK_High 0xff -#define GT_DDAS_HISHIFT_High 0 -/* DRAM Configuration */ -#define GT_DRAM_CFG GT64011(0x448) -#define GT_DRAM_CFG_RefIntCntMASK 0x00003fff -#define GT_DRAM_CFG_RefIntCntSHIFT 0 -#define GT_DRAM_CFG_RefIntCnt(x) (((x)< -#include - - .text -NESTED(startup, 16, sp) - .set noreorder - - jal decompress_kernel - nop - - jal kernel_location_start+0x584 - nop - - END(startup) diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal 1969-12-31 16:00:00.000000000 -0800 @@ -1,19 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(startup) -SECTIONS -{ - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} - diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash 1969-12-31 16:00:00.000000000 -0800 @@ -1,29 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(sbdreset) - -SECTIONS -{ - . = 0xBFC00000; - .got : {*(.got)} - .reset : { - sbdreset = ABSOLUTE(.); - sbdreset_evb64120A.o - evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */ - pci_etherboot.o - memory.o - pci.o - } - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 1969-12-31 16:00:00.000000000 -0800 @@ -1,24 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(XferToRam) - -SECTIONS -{ - . = 0xBF000000; - .got : {*(.got)} - .reset : { - xfer.o - } - kernel_location_start = 0x80100000; - . = 0x80400000; - .text : { - *(.text) - } - .bss : { - *(.bss) - } - .data :{ - *(.data) - } - malloc_start = .; -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner 1969-12-31 16:00:00.000000000 -0800 @@ -1,11 +0,0 @@ -OUTPUT_FORMAT("elf32-bigmips") -OUTPUT_ARCH(mips) -ENTRY(main) - -SECTIONS -{ - . = 0xA0400000; - .text : {*(.text)} - .data : {*(.data)} - .bss : {*(.bss)} -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/load.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/load.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/load.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/load.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,244 +0,0 @@ - -/* control character used for download */ -#define ETX CNTRL('c') -#define ACK CNTRL('f') -#define NAK CNTRL('u') -#define XON CNTRL('q') -#define XOFF CNTRL('s') - -unsigned int csum; -unsigned int dl_entry; - -static const unsigned char hextab[256] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, - 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, - 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, -}; - - -unsigned char ascii_to_bin(unsigned char c) -{ - return hextab[c]; -} - -unsigned char read_char_direct(void) -{ - unsigned char c, *cp; - cp = (unsigned char *) 0xbd000020; - while (1) { - if (*(cp + 0x14) & 0x01) { - c = (volatile unsigned char) *cp; - return c; - } - cp++; - cp--; - } -} - -unsigned char get_pair(void) -{ - unsigned char byte; - - byte = ascii_to_bin(read_char_direct()) << 4; - byte |= ascii_to_bin(read_char_direct()); - csum += byte; - return (byte); -} - - -void serial_putc(int ch) -{ - unsigned long temp; - for (temp = 0; temp < 1000; temp++) { - } - *(char *) 0xbd000020 = (char) ch; -} - - -int inline serial_getc(void) -{ - return read_char_direct(); -} - -int serial_ischar(void) -{ - - unsigned char c, *cp; - unsigned count; - cp = (unsigned char *) 0xbd000020; - count = 0; - while (count != 100) { - if (*(cp + 0x14) & 0x01) { - c = (volatile unsigned char) *cp; - return c; - } - cp++; - cp--; - count++; - } - return 0; -} - -int serial_init(void) -{ - return 0; -} - - -int galileo_dl(void) -{ -#define display_char '.' -#define display_error 'E' -#define display_error_bad_7 '7' -#define display_error_unknown 'U' -#define display_error_length 'L' - - register int length, address, save_csum; - int i, first, done, eof, reccount, type, client_pc; - int src, dbl_length; - unsigned char *buffptr, databuff[258], tempo; - register int display_counter, chunks, leftovers, putter, - bytes_per_chunk; - display_counter = 0; - bytes_per_chunk = 16; - csum = 0; - - reccount = 1; - for (first = 1, done = 0; !done; first = 0, reccount++) { - while (read_char_direct() != 'S') - continue; - csum = 0; - type = read_char_direct(); - length = get_pair(); - if (length < 0 || length >= 256) { - *(char *) 0xbd000020 = display_error_length; - // *(char*)0xbd00000c = display_error_length; - return 0; - } - length--; - switch (type) { - case '0': - while (length-- > 0) - get_pair(); - break; - case '3': - address = 0; - for (i = 0; i < 4; i++) { - address <<= 8; - address |= get_pair(); - length--; - } - if (address == -1) { - eof = 1; - continue; - } - buffptr = &databuff[0]; - dbl_length = length << 1; - chunks = dbl_length / bytes_per_chunk; - leftovers = dbl_length % bytes_per_chunk; - putter = bytes_per_chunk >> 1; - while (chunks--) { - for (i = 0; i < bytes_per_chunk; i++) - databuff[i] = read_char_direct(); - src = i = 0; - while (i++ < putter) { - tempo = - (ascii_to_bin(databuff[src++]) - << 4) | - ascii_to_bin(databuff[src++]); - csum += tempo; - *(char *) address++ = tempo; - } - } - if (leftovers) { - putter = leftovers / 2; - for (i = 0; i < leftovers; i++) - databuff[i] = read_char_direct(); - src = i = 0; - while (i++ < putter) { - tempo = - (ascii_to_bin(databuff[src++]) - << 4) | - ascii_to_bin(databuff[src++]); - csum += tempo; - *(char *) address++ = tempo; - } - } - break; - - case '7': - address = 0; - for (i = 0; i < 4; i++) { - address <<= 8; - address |= get_pair(); - length--; - } - if (address == -1) { - eof = 1; - continue; - } - client_pc = address; - if (length) { - *(char *) 0xbd000020 = display_error_bad_7; - // *(char*)0xbd00000c = display_error_bad_7; - } - - done = 1; - break; - - default: - *(char *) 0xbd000020 = display_error_unknown; - // *(char*)0xbd00000c = display_error_unknown; - - break; - } - save_csum = (~csum) & 0xff; - if ((csum = get_pair()) < 0) { - eof = 1; - continue; - } - if (csum != save_csum) { - *(char *) 0xbd000020 = display_error; - // *(char*)0xbd00000c = display_error; - } else { - - if (display_counter % 50 == 0) { - *(char *) 0xbd000020 = display_char; - display_counter = 0; - } - display_counter++; - - } - } - --reccount; - dl_entry = client_pc; - return dl_entry; /* Success */ -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/meminit.S linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/meminit.S --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/meminit.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/meminit.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,187 +0,0 @@ -/* - * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming - * 2-way interleaving). This is so that the test pattern and - * inverted pattern are written to the same bank of memory, which - * prevents us reading back data sitting in the dram buffers and - * getting a false match. - */ - -#ifndef BUSWIDTH -# if #cpu(r3000) || #cpu(r4300) || #cpu(r4650) -# define BUSWIDTH 8 /* 32 bit memory, bank interleaved */ -# elif #cpu(r4000) -# define BUSWIDTH 16 /* 64 bit memory, bank interleaved */ -# endif -#endif - -#ifndef RAM_BASE -#define RAM_BASE KSEG1_BASE -#endif - -#ifndef MEMSTART -#define MEMSTART 0x0 /* start of physical memory */ -#endif - -#ifndef MEMINCR -# define MEMINCR 0x10000 /* work up in 64Kb increments */ -#endif - -SLEAF(size_mem) - mfc0 t8,C0_STATUS -#if #cpu(r4000) - /* disable cache and memory parity checking */ - or t0,t8,SR_DE - mtc0 t0,C0_STATUS -#endif - - li t0,RAM_BASE+MEMSTART # start at bottom of phys mem - move t1,t0 # remember start address - li t2,0xaa55aa55 # pattern - not t3,t2 # ~pattern - - move t7,k0 - la t4,.fail # bus error exception catcher - addu k0,t4,s8 # RELOC - - /* fill first 64Kb with zero (for cache init) */ - move t4,t0 - li t5,0x10000 -1: sw zero,0(t4) - sw zero,4(t4) - sw zero,8(t4) - sw zero,12(t4) - subu t5,16 - addu t4,16 - bnez t5,1b - -.loop: - addu t0,MEMINCR - move t4,t0 - - /* store pattern in bank 0, line 0 */ - sw t2,0(t4) - addu t4,4 - -#if BUSWIDTH > 4 - /* fill remainder of line with zeros */ - li t5,BUSWIDTH-4 -1: sw zero,0(t4) - subu t5,4 - addu t4,4 - bnez t5,1b -#endif - - /* store inverse pattern in bank 0, line 1 */ - sw t3,0(t4) - addu t4,4 - -#if BUSWIDTH > 4 - /* fill remainder of line with zeros */ - li t5,BUSWIDTH-4 -1: sw zero,0(t4) - subu t5,4 - addu t4,4 - bnez t5,1b -#endif - - /* defeat write buffering */ -#if #cpu(r4000) - sync -#else - lw zero,-4(t4) -#endif - - lw t4,0(t0) # read first word of line - lw t5,0(t1) # read start of memory (should be zero) - bne t4,t2,.fail # this line wrong? - beq t5,zero,.loop # start of mem overwritten? - -.fail: - move k0,t7 # clear exception catcher - - /* restore Status register */ - mtc0 t8,C0_STATUS - - /* return top of memory offset (normally == size) */ - subu v0,t0,RAM_BASE - j ra -END(size_mem) - - -/* - * We must often initialise memory so that it has good parity/ecc, - * and this must be done before the caches are used. - */ - -/* - clear_mem (size) - - clear memory from RAM_BASE+MEMSTART to RAM_BASE+MEMSTART+size - clear_mem_range (size, start) - - clear memory from start to start+size -*/ - -SLEAF(clear_mem) - li a1,RAM_BASE+MEMSTART # start at bottom of phys mem -clear_mem_range: - beqz a0,9f - addu a0,a1 # end of memory - - /* XXX should run cached, but caches may not be initialised yet */ - .set noreorder -#if __mips >= 3 -1: sd zero,0(a1) - sd zero,8(a1) - sd zero,16(a1) - sd zero,24(a1) - sd zero,32(a1) - sd zero,40(a1) - sd zero,48(a1) - addu a1,64 - bne a1,a0,1b - sd zero,-8(a1) # BDSLOT -#else -1: sw zero,0(a1) - sw zero,4(a1) - sw zero,8(a1) - sw zero,12(a1) - sw zero,16(a1) - sw zero,20(a1) - sw zero,24(a1) - sw zero,28(a1) - sw zero,32(a1) - sw zero,36(a1) - sw zero,40(a1) - sw zero,44(a1) - sw zero,48(a1) - sw zero,52(a1) - sw zero,56(a1) - addu a1,64 - bne a1,a0,1b - sw zero,-4(a1) # BDSLOT -#endif - .set reorder - -9: j ra -END(clear_mem) - - -SLEAF(init_tlb) - /* initialise tlb */ - mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */ - mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */ - mtc0 zero,C0_PGMASK - li t8,K1BASE /* tlbhi = impossible vpn */ - li t9,(NTLBENTRIES-1) /* index */ - - .set noreorder - nop -1: mtc0 t8,C0_TLBHI - mtc0 t9,C0_INX - addu t8,0x2000 /* inc vpn */ - tlbwi - bnez t9,1b - subu t9,1 # BDSLOT - .set reorder - - j ra -END(init_tlb) diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/memory.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/memory.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/memory.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/memory.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,593 +0,0 @@ -/* Memory.c - Memory mappings and remapping functions */ - -/* Copyright - Galileo technology. */ - -/* -DESCRIPTION -This file contains function which gives the user the ability to remap the -SDRAM memory and devices windows, please pay attention to overlapping windows -since the function do not take care of that for you. -When remapping the SDRAM or devices memory space pay attention to the PCI -mappings and make sure to coordinate between the two interfaces!!! -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "Memory.h" -#endif - -/******************************************************************** -* getMemoryBankBaseAddress - Extract the base address of a memory bank -* - If the memory bank size is 0 then this base address has no meaning !!! -* -* INPUTS: MEMORY_BANK bank - SDRAM Bank number. -* OUTPUT: N/A -* RETURNS: Memory bank base address. -*********************************************************************/ -unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank) -{ - unsigned int base, regBase; - GT_REG_READ((SCS_1_0_LOW_DECODE_ADDRESS + (bank / 2) * 0x10), - &base); - base = base << 21; - GT_REG_READ((SCS_0_LOW_DECODE_ADDRESS + bank * 8), ®Base); - base = base | (regBase << 20); - return base; -} - -/******************************************************************** -* getDeviceBaseAddress - Extract the base address of a device. -* - If the device size is 0 then this base address has no meaning!!! -* -* INPUT: DEVICE device - Bank number. -* OUTPUT: N/A -* RETURNS: Device base address. -*********************************************************************/ -unsigned int getDeviceBaseAddress(DEVICE device) -{ - unsigned int base, regBase; - GT_REG_READ((CS_2_0_LOW_DECODE_ADDRESS + (device / 3) * 0x10), - &base); - base = base << 21; - GT_REG_READ((CS_0_LOW_DECODE_ADDRESS + device * 0x8), ®Base); - base = base | (regBase << 20); - return base; -} - -/******************************************************************** -* getMemoryBankSize - Extract the size of a memory bank. -* -* INPUT: MEMORY_BANK bank - Bank number -* OUTPUT: N/A -* RETURNS: Memory bank size. -*********************************************************************/ -unsigned int getMemoryBankSize(MEMORY_BANK bank) -{ - unsigned int size, base, value; - base = getMemoryBankBaseAddress(bank); - GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &size); - size = ((size + 1) << 20) - (base & 0x0fffffff); - GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &value); - if (value == 0) - return 0; - else - return size; -} - -/******************************************************************** -* getDeviceSize - Extract the size of a device memory space -* -* INPUT: DEVICE device - Device number -* OUTPUT: N/A -* RETURNS: Size of a device memory space. -*********************************************************************/ -unsigned int getDeviceSize(DEVICE device) -{ - unsigned int size, base, value; - base = getDeviceBaseAddress(device); - GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &size); - size = ((size + 1) << 20) - (base & 0x0fffffff); - GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &value); - if ((value + 1) == 0) - return 0; - else - return size; -} - -/******************************************************************** -* getDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width. -* The width is determine in registers: 'Device Parameters' -* registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device. -* at bits: [21:20]. -* -* INPUT: DEVICE device - Device number -* OUTPUT: N/A -* RETURNS: Device width in Bytes (1,2,4, or 8), 0 if error had occurred. -*********************************************************************/ -unsigned int getDeviceWidth(DEVICE device) -{ - unsigned int width; - unsigned int regValue; - - GT_REG_READ(DEVICE_BANK0PARAMETERS + device * 4, ®Value); - width = (regValue & 0x00300000) >> 20; - switch (width) { - case 0: - return 1; - case 1: - return 2; - case 2: - return 4; - case 3: - return 8; - default: - return 0; - } -} - -/******************************************************************** -* mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It is the programmer`s responsibility to make sure -* there are no conflicts with other memory spaces!!! -* - If a bank needs to be closed , give it a 0 length -* -* -* INPUTS: unsigned int bank0Base - required bank 0 base address. -* unsigned int bank0Length - required bank 0 size. -* unsigned int bank1Base - required bank 1 base address. -* unsigned int bank1Length - required bank 1 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length, - unsigned int bank1Base, unsigned int bank1Length) -{ - unsigned int mainBank0Top = bank0Base + bank0Length; - unsigned int mainBank1Top = bank1Base + bank1Length; - unsigned int memBank0Base, bank0Top; - unsigned int memBank1Base, bank1Top; - - if (bank0Base <= bank1Base) { - if ((bank0Base + bank0Length) > bank1Base) - return false; - } else { - if ((bank1Base + bank1Length) > bank0Base) - return false; - } - - if (bank0Length == 0) - mainBank0Top++; - if (bank1Length == 0) - mainBank1Top++; - - memBank0Base = ((unsigned int) (bank0Base & 0x0fffffff)) >> 20; - bank0Top = ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 20; - memBank1Base = ((unsigned int) (bank1Base & 0x0fffffff)) >> 20; - bank1Top = ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 20; - - if (mainBank1Top > mainBank0Top) { - bank0Base >>= 21; - mainBank0Top = - ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 21; - } else { - bank0Base = bank1Base >> 21; - mainBank0Top = - ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(SCS_1_0_LOW_DECODE_ADDRESS, bank0Base); - if ((bank0Length + bank1Length) != 0) { - GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, - mainBank0Top - 1); - } else { - GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, 0x0); - } - if (bank1Length != 0) { - GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, bank1Top - 1); - } else { - GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_1_LOW_DECODE_ADDRESS, memBank1Base); - if (bank0Length != 0) { - GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, bank0Top - 1); - } else { - GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_0_LOW_DECODE_ADDRESS, memBank0Base); - return true; -} - -/******************************************************************** -* mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It`s the programmer`s responsibility to make sure there -* are no conflicts with other memory spaces!!! -* - If a bank needs to be closed , give it a 0 length. -* -* -* INPUTS: unsigned int bank2Base - required bank 2 base address. -* unsigned int bank2Length - required bank 2 size. -* unsigned int bank3Base - required bank 3 base address. -* unsigned int bank3Length - required bank 3 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length, - unsigned int bank3Base, unsigned int bank3Length) -{ - unsigned int mainBank2Top = - (unsigned int) (bank2Base + bank2Length); - unsigned int mainBank3Top = - (unsigned int) (bank3Base + bank3Length); - unsigned int memBank2Base, bank2Top; - unsigned int memBank3Base, bank3Top; - - if (bank2Base <= bank3Base) { - if ((bank2Base + bank2Length) > bank3Base) - return false; - } else { - if ((bank3Base + bank3Length) > bank2Base) - return false; - } - if (bank2Length == 0) - mainBank2Top++; - if (bank3Length == 0) - mainBank3Top++; - - memBank2Base = ((unsigned int) (bank2Base & 0x0fffffff)) >> 20; - bank2Top = ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 20; - memBank3Base = ((unsigned int) (bank3Base & 0x0fffffff)) >> 20; - bank3Top = ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 20; - - if (mainBank3Top > mainBank2Top) { - bank2Base >>= 21; - mainBank2Top = - ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 21; - } else { - bank2Base = bank3Base >> 21; - mainBank2Top = - ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(SCS_3_2_LOW_DECODE_ADDRESS, bank2Base); - if ((bank2Length + bank3Length) != 0) { - GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, - mainBank2Top - 1); - } else { - GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, 0x0); - } - if (bank3Length != 0) { - GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, bank3Top - 1); - } else { - GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_3_LOW_DECODE_ADDRESS, memBank3Base); - if (bank2Length != 0) { - GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, bank2Top - 1); - } else { - GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(SCS_2_LOW_DECODE_ADDRESS, memBank2Base); - return true; -} - -/******************************************************************** -* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1 -* and 2 -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It`s the programmer`s responsibility to make sure there -* are no conflicts with other memory spaces!!! -* - If a device needs to be closed , give it a 0 length -* -* -* INPUTS: unsigned int device0Base - required cs_0 base address. -* unsigned int device0Length - required cs_0 size. -* unsigned int device1Base - required cs_1 base address. -* unsigned int device1Length - required cs_0 size. -* unsigned int device2Base - required cs_2 base address. -* unsigned int device2Length - required cs_2 size. -* RETURNS: true on success, false on failure or if one of the parameters is -* erroneous. -*********************************************************************/ -bool mapDevices0_1and2MemorySpace(unsigned int device0Base, - unsigned int device0Length, - unsigned int device1Base, - unsigned int device1Length, - unsigned int device2Base, - unsigned int device2Length) -{ - unsigned int deviceBank0Top = - (unsigned int) (device0Base + device0Length); - unsigned int deviceBank1Top = - (unsigned int) (device1Base + device1Length); - unsigned int deviceBank2Top = - (unsigned int) (device2Base + device2Length); - unsigned int device0BaseTemp = 0, device0TopTemp = 0; - unsigned int bank0Base, bank0Top; - unsigned int bank1Base, bank1Top; - unsigned int bank2Base, bank2Top; - bank0Base = ((unsigned int) (device0Base & 0x0fffffff)) >> 20; - bank0Top = ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 20; - bank1Base = ((unsigned int) (device1Base & 0x0fffffff)) >> 20; - bank1Top = ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 20; - bank2Base = ((unsigned int) (device2Base & 0x0fffffff)) >> 20; - bank2Top = ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 20; - - if (device0Length == 0) - deviceBank0Top++; - if (device1Length == 0) - deviceBank1Top++; - if (device2Length == 0) - deviceBank2Top++; - - if (device0Base <= device1Base && device0Base <= device2Base) { - if ((device0Base + device0Length) > device1Base || \ - (device0Base + device0Length) > device2Base) - return false; - if (device1Base <= device2Base) { - if ((device1Base + device1Length) > device2Base) - return false; - } else { - if ((device2Base + device2Length) > device1Base) - return false; - } - } - - if (device1Base <= device0Base && device1Base <= device2Base) { - if ((device1Base + device1Length) > device0Base || - (device1Base + device1Length) > device2Base) - return false; - if (device0Base <= device2Base) { - if ((device0Base + device0Length) > device2Base) - return false; - } else { - if ((device2Base + device2Length) > device0Base) - return false; - } - } - - if (device2Base <= device1Base && device2Base <= device0Base) { - if ((device2Base + device2Length) > device1Base || - (device2Base + device2Length) > device0Base) - return false; - if (device0Base <= device1Base) { - if ((device0Base + device0Length) > device1Base) - return false; - } else { - if ((device1Base + device1Length) > device0Base) - return false; - } - } - - if ((deviceBank2Top > deviceBank1Top) && (deviceBank1Top > - deviceBank0Top)) { - device0BaseTemp = device0Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21; - } - if ((deviceBank2Top > deviceBank0Top) - && (deviceBank0Top > deviceBank1Top)) { - device0BaseTemp = device1Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21; - } - if ((deviceBank1Top > deviceBank2Top) - && (deviceBank2Top > deviceBank0Top)) { - device0BaseTemp = device0Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21; - } - if ((deviceBank1Top > deviceBank0Top) - && (deviceBank0Top > deviceBank2Top)) { - device0BaseTemp = device2Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21; - } - if ((deviceBank0Top > deviceBank2Top) - && (deviceBank2Top > deviceBank1Top)) { - device0BaseTemp = device1Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21; - } - if ((deviceBank0Top > deviceBank1Top) - && (deviceBank1Top > deviceBank2Top)) { - device0BaseTemp = device2Base >> 21; - device0TopTemp = - ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(CS_2_0_LOW_DECODE_ADDRESS, device0BaseTemp); - if ((device0Length + device1Length + device2Length) != 0) { - GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, - device0TopTemp - 1); - } else { - GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_0_LOW_DECODE_ADDRESS, bank0Base); - if (device0Length != 0) { - GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, bank0Top - 1); - } else { - GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_1_LOW_DECODE_ADDRESS, bank1Base); - if (device1Length != 0) { - GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, bank1Top - 1); - } else { - GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_2_LOW_DECODE_ADDRESS, bank2Base); - if (device2Length != 0) { - GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, bank2Top - 1); - } else { - GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, 0x0); - } - return true; -} - -/******************************************************************** -* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices: -* 3 and boot -* - Pay attention to the PCI mappings and make sure to -* coordinate between the two interfaces!!! -* - It is the programmer`s responsibility to make sure -* there are no conflicts with other memory spaces!!! -* - If a device needs to be closed , give it a 0 length. -* -* INPUTS: base and length of device 3and boot -* RETURNS: true on success, false on failure -*********************************************************************/ -bool mapDevices3andBootMemorySpace(unsigned int device3Base, - unsigned int device3Length, - unsigned int bootDeviceBase, - unsigned int bootDeviceLength) -{ - unsigned int deviceBank3Top = - (unsigned int) (device3Base + device3Length); - unsigned int deviceBankBootTop = - (unsigned int) (bootDeviceBase + bootDeviceLength); - unsigned int bank3Base, bank3Top; - unsigned int bank4Base, bank4Top; - unsigned int Device1Base, Device1Top; - - bank3Top = ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 20; - bank4Top = ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> 20; - bank3Base = ((unsigned int) (device3Base & 0x0fffffff)) >> 20; - bank4Base = ((unsigned int) (bootDeviceBase & 0x0fffffff)) >> 20; - - if (device3Base <= bootDeviceBase) { - if (deviceBank3Top > bootDeviceBase) - return false; - } else { - if (deviceBankBootTop > device3Base) - return false; - } - - if (deviceBankBootTop > deviceBank3Top) { - Device1Base = device3Base >> 21; - Device1Top = - ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> - 21; - } else { - Device1Base = bootDeviceBase >> 21; - Device1Top = - ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 21; - } - GT_REG_WRITE(CS_3_BOOTCS_LOW_DECODE_ADDRESS, Device1Base); - if ((device3Length + bootDeviceLength) != 0) { - GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, - Device1Top - 1); - } else { - GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(CS_3_LOW_DECODE_ADDRESS, bank3Base); - if (device3Length != 0) { - GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, bank3Top - 1); - } else { - GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, 0x0); - } - GT_REG_WRITE(BOOTCS_LOW_DECODE_ADDRESS, bank4Base); - if (bootDeviceLength != 0) { - GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, bank4Top - 1); - } else { - GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, 0x0); - } - return true; -} - -/******************************************************************** -* modifyDeviceParameters - This function can be used to modify a device`s -* parameters. -* - Be advised to check the spec before modifying them. -* Inputs: -* Returns: false if one of the parameters is erroneous,true otherwise. -*********************************************************************/ -bool modifyDeviceParameters(DEVICE device, unsigned int turnOff, - unsigned int accToFirst, - unsigned int accToNext, unsigned int aleToWr, - unsigned int wrActive, unsigned int wrHigh, - unsigned int width, bool paritySupport) -{ - unsigned int data, oldValue; - - if ((turnOff > 0x7 && turnOff != DONT_MODIFY) - || (accToFirst > 0xf && accToFirst != DONT_MODIFY) - || (accToNext > 0xf && accToNext != DONT_MODIFY) - || (aleToWr > 0x7 && aleToWr != DONT_MODIFY) - || (wrActive > 0x7 && wrActive != DONT_MODIFY) - || (wrHigh > 0x7 && wrHigh != DONT_MODIFY)) { - return false; - } - - GT_REG_READ((DEVICE_BANK0PARAMETERS + device * 4), &oldValue); - if (turnOff == DONT_MODIFY) - turnOff = oldValue & 0x00000007; - else - turnOff = turnOff; - - if (accToFirst == DONT_MODIFY) - accToFirst = oldValue & 0x00000078; - else - accToFirst = accToFirst << 3; - - if (accToNext == DONT_MODIFY) - accToNext = oldValue & 0x00000780; - else - accToNext = accToNext << 7; - - if (aleToWr == DONT_MODIFY) - aleToWr = oldValue & 0x00003800; - else - aleToWr = aleToWr << 11; - - if (wrActive == DONT_MODIFY) - wrActive = oldValue & 0x0001c000; - else - wrActive = wrActive << 14; - - if (wrHigh == DONT_MODIFY) - wrHigh = oldValue & 0x000e0000; - else - wrHigh = wrHigh << 17; - - data = - turnOff | accToFirst | accToNext | aleToWr | wrActive | wrHigh; - switch (width) { - case _8BIT: - break; - case _16BIT: - data = data | _16BIT; - break; - case _32BIT: - data = data | _32BIT; - break; - case _64BIT: - data = data | _64BIT; - break; - default: - return false; - } - if (paritySupport == true) - data = data | PARITY_SUPPORT; - GT_REG_WRITE(DEVICE_BANK0PARAMETERS + device * 4, data); - return true; -} - -/******************************************************************** -* remapAddress - This fubction used for address remapping -* Inputs: - regOffset: remap register -* remapHeader : remapped address -* Returns: false if one of the parameters is erroneous,true otherwise. -*********************************************************************/ -bool remapAddress(unsigned int remapReg, unsigned int remapValue) -{ - unsigned int valueForReg; - valueForReg = (remapValue & 0xffe00000) >> 21; - GT_REG_WRITE(remapReg, valueForReg); - return true; -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/misc.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/misc.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/misc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/misc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,313 +0,0 @@ -/* - * arch/mips/galileo/misc.c - * - * This is a collection of several routines from gzip-1.0.3 - * adapted for Linux. - * - * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 - * puts by Nick Holloway 1993, better puts by Martin Mares 1995 - * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 - * - * Modified by RidgeRun Inc. - */ - -#include -#include -/* - * gzip declarations - */ - -#define OF(args) args -#define STATIC static - -#define channel 1 - -#undef memset -#undef memcpy -#define memzero(s, n) memset ((s), 0, (n)) - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize = 0; /* valid bytes in inbuf */ -static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -static unsigned outcnt = 0; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -void variable_init(); -static void puts(const char *); - -void int2hex(int i) -{ - int tth, th, h, t, d; - - if (i > 99999) { - serial_putc(channel, "Error - int2hex outofbounds"); - return; - } - - tth = (i) / 10000; - th = (i - (tth * 10000)) / 1000; - h = (i - ((tth * 10000) + (th * 1000))) / 100; - t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10; - d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10))); - serial_putc(channel, tth + '0'); - serial_putc(channel, th + '0'); - serial_putc(channel, h + '0'); - serial_putc(channel, t + '0'); - serial_putc(channel, d + '0'); -} - -int checksum; -int byte_count; -static unsigned char *input_data; - -static int printCnt = 0; - -int get_byte() -{ - unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf()); - byte_count++; - checksum += c; - - // if (printCnt++ < 150) - // { - // puts("\n"); - // puts("byte count = "); - // int2hex(byte_count & 0xff); - // puts(" byte val = "); - // int2hex(c); - // puts(" checksum = "); - // int2hex(checksum & 0xff); - // puts("\n"); - // } - return c; -} - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond,msg) {if(!(cond)) error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -static int fill_inbuf(void); -static void flush_window(void); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -/* - * This is set up by the setup-routine at boot-time - */ - - -#define STACK_SIZE (4096) -long user_stack[STACK_SIZE]; -long *stack_start = &user_stack[STACK_SIZE]; - -extern int linux_compressed_start; -extern int linux_compressed_size; -extern int malloc_start; - -static int input_len; - -static long bytes_out = 0; -extern int kernel_location_start; -static uch *output_data; -static unsigned long output_ptr = 0; - - -static void *malloc(int size); -static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -static unsigned long free_mem_ptr; -static unsigned long free_mem_end_ptr; - -#include "../../../../../lib/inflate.c" - -static void *malloc(int size) -{ - void *p; - - if (size < 0) - error("Malloc error\n"); - // if (free_mem_ptr <= 0) error("Memory error\n"); - - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ - - p = (void *) free_mem_ptr; - free_mem_ptr += size; - - if (free_mem_ptr >= free_mem_end_ptr) - error("\nOut of memory\n"); - - return p; -} - -static void free(void *where) -{ /* Don't care */ -} - -static void gzip_mark(void **ptr) -{ - *ptr = (void *) free_mem_ptr; -} - -static void gzip_release(void **ptr) -{ - free_mem_ptr = (long) *ptr; -} - -static void puts(const char *s) -{ - while (*s) { - if (*s == 10) - serial_putc(channel, 13); - serial_putc(channel, *s++); - } -} - -void *memset(void *s, int c, size_t n) -{ - int i; - char *ss = (char *) s; - - for (i = 0; i < n; i++) - ss[i] = c; - return s; -} - -void *memcpy(void *__dest, __const void *__src, size_t __n) -{ - int i; - char *d = (char *) __dest, *s = (char *) __src; - - for (i = 0; i < __n; i++) - d[i] = s[i]; - return __dest; -} - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -static int fill_inbuf(void) -{ - if (insize != 0) { - error("ran out of input data\n"); - } - - inbuf = input_data; - insize = input_len; - inptr = 1; - return inbuf[0]; -} - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg) outcnt; - output_ptr += (ulg) outcnt; - outcnt = 0; -} - -check_mem() -{ - int i; - - puts("\ncplens = "); - for (i = 0; i < 10; i++) { - int2hex(cplens[i]); - puts(" "); - } - puts("\ncplext = "); - for (i = 0; i < 10; i++) { - int2hex(cplext[i]); - puts(" "); - } - puts("\nborder = "); - for (i = 0; i < 10; i++) { - int2hex(border[i]); - puts(" "); - } - puts("\n"); -} - -static void error(char *x) -{ - check_mem(); - puts("\n\n"); - puts(x); - puts("byte_count = "); - int2hex(byte_count); - puts("\n"); - puts("\n\n -- System halted"); - while (1); /* Halt */ -} - -void variable_init() -{ - byte_count = 0; - checksum = 0; - input_data = (unsigned char *) &linux_compressed_start; - input_len = linux_compressed_size; - output_data = &kernel_location_start; - free_mem_ptr = (long) &malloc_start; - free_mem_end_ptr = (long) ((char *) &malloc_start + 0x400000); -} - -int decompress_kernel() -{ - //check_mem(); - - variable_init(); - - makecrc(); - puts("Uncompressing Linux... \n"); - gunzip(); // ...see inflate.c - puts("Ok, booting the kernel.\n"); - return 0; -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ns16550.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ns16550.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/ns16550.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/ns16550.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,126 +0,0 @@ -/* NS16550 UART registers */ - -#ifndef NS16550H -#define NS16550H - -#define UART_BASE 0xbd000000 -#define NS16550_CHANA PHYS_TO_K1(UART_BASE + 0x20) -#define NS16550_CHANB PHYS_TO_K1(UART_BASE) - -#ifndef NS16550_HZ -#define NS16550_HZ 3686400 -#endif - -#ifdef __ASSEMBLY__ - -#ifndef NSREG -#define NSREG(x) ((x)*4) -#endif - -#define DATA NSREG(0) /* data register (R/W) */ -#define IER NSREG(1) /* interrupt enable (W) */ -#define IIR NSREG(2) /* interrupt identification (R) */ -#define FIFO IIR /* 16550 fifo control (W) */ -#define CFCR NSREG(3) /* line control register (R/W) */ -#define MCR NSREG(4) /* modem control register (R/W) */ -#define LSR NSREG(5) /* line status register (R/W) */ -#define MSR NSREG(6) /* modem status register (R/W) */ -#define SCR NSREG(7) /* scratch register (R/W) */ - -#else - -#ifndef nsreg -#if #endian(little) -#define nsreg(x) unsigned :24; unsigned char x; -#else -/*#define nsreg(x) unsigned char x; unsigned :24;*/ -#define nsreg(x) unsigned int x:8;unsigned int :24; -#endif -#endif - -typedef struct { - nsreg(data); /* data register (R/W) */ - nsreg(ier); /* interrupt enable (W) */ - nsreg(iir); /* interrupt identification (R) */ -#define fifo iir /* 16550 fifo control (W) */ - nsreg(cfcr); /* line control register (R/W) */ - nsreg(mcr); /* modem control register (R/W) */ - nsreg(lsr); /* line status register (R/W) */ - nsreg(msr); /* modem status register (R/W) */ - nsreg(scr); /* scratch register (R/W) */ -} ns16550dev; -#endif - - -/* 16 bit baud rate divisor (lower byte in dca_data, upper in dca_ier) */ -#define BRTC(x) (NS16550_HZ / (16*(x))) - -/* interrupt enable register */ -#define IER_ERXRDY 0x1 /* int on rx ready */ -#define IER_ETXRDY 0x2 /* int on tx ready */ -#define IER_ERLS 0x4 /* int on line status change */ -#define IER_EMSC 0x8 /* int on modem status change */ - -/* interrupt identification register */ -#define IIR_IMASK 0xf /* mask */ -#define IIR_RXTOUT 0xc /* receive timeout */ -#define IIR_RLS 0x6 /* receive line status */ -#define IIR_RXRDY 0x4 /* receive ready */ -#define IIR_TXRDY 0x2 /* transmit ready */ -#define IIR_NOPEND 0x1 /* nothing */ -#define IIR_MLSC 0x0 /* modem status */ -#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */ - -/* fifo control register */ -#define FIFO_ENABLE 0x01 /* enable fifo */ -#define FIFO_RCV_RST 0x02 /* reset receive fifo */ -#define FIFO_XMT_RST 0x04 /* reset transmit fifo */ -#define FIFO_DMA_MODE 0x08 /* enable dma mode */ -#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */ -#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */ -#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */ -#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */ - -/* character format control register */ -#define CFCR_DLAB 0x80 /* divisor latch */ -#define CFCR_SBREAK 0x40 /* send break */ -#define CFCR_PZERO 0x30 /* zero parity */ -#define CFCR_PONE 0x20 /* one parity */ -#define CFCR_PEVEN 0x10 /* even parity */ -#define CFCR_PODD 0x00 /* odd parity */ -#define CFCR_PENAB 0x08 /* parity enable */ -#define CFCR_STOPB 0x04 /* 2 stop bits */ -#define CFCR_8BITS 0x03 /* 8 data bits */ -#define CFCR_7BITS 0x02 /* 7 data bits */ -#define CFCR_6BITS 0x01 /* 6 data bits */ -#define CFCR_5BITS 0x00 /* 5 data bits */ - -/* modem control register */ -#define MCR_LOOPBACK 0x10 /* loopback */ -#define MCR_IENABLE 0x08 /* output 2 = int enable */ -#define MCR_DRS 0x04 /* output 1 = xxx */ -#define MCR_RTS 0x02 /* enable RTS */ -#define MCR_DTR 0x01 /* enable DTR */ - -/* line status register */ -#define LSR_RCV_FIFO 0x80 /* error in receive fifo */ -#define LSR_TSRE 0x40 /* transmitter empty */ -#define LSR_TXRDY 0x20 /* transmitter ready */ -#define LSR_BI 0x10 /* break detected */ -#define LSR_FE 0x08 /* framing error */ -#define LSR_PE 0x04 /* parity error */ -#define LSR_OE 0x02 /* overrun error */ -#define LSR_RXRDY 0x01 /* receiver ready */ -#define LSR_RCV_MASK 0x1f - -/* modem status register */ -#define MSR_DCD 0x80 /* DCD active */ -#define MSR_RI 0x40 /* RI active */ -#define MSR_DSR 0x20 /* DSR active */ -#define MSR_CTS 0x10 /* CTS active */ -#define MSR_DDCD 0x08 /* DCD changed */ -#define MSR_TERI 0x04 /* RI changed */ -#define MSR_DDSR 0x02 /* DSR changed */ -#define MSR_DCTS 0x01 /* CTS changed */ - -#endif diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/osdep.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/osdep.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/osdep.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/osdep.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -#ifndef __OSDEP_H__ -#define __OSDEP_H__ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - */ - -#if defined(__linux__) || defined(__FreeBSD__) || defined (__MIPSEB__) -#define ETHERBOOT32 -#define ntohl(x) (x) -#define htonl(x) (x) -#define ntohs(x) (x) -#define htons(x) (x) - -#endif - - - - -/* ANSI prototyping macro */ -#ifdef __STDC__ -#define P(x) x -#else -#define P(x) () -#endif - -#endif - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1336 +0,0 @@ -/* PCI.c - PCI functions */ - -/* Copyright - Galileo technology. */ - -#ifdef __linux__ -#include -#include -#ifndef PROM -#include -#endif - -#undef PCI_DEBUG - -#ifdef PCI_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#else -#include "core.h" -#include "pci.h" -#include -#endif - -/******************************************************************** -* pci0ScanDevices - This function scan PCI0 bus, if found any device on -* this bus it interrogate the Device for the information -* it can discover. -* The fields with all information are the following: -* char type[20]; -* unsigned int deviceNum; -* unsigned int venID; -* unsigned int deviceID; -* unsigned int bar0Base; -* unsigned int bar0Size; -* unsigned int bar1Base; -* unsigned int bar1Size; -* unsigned int bar2Base; -* unsigned int bar2Size; -* unsigned int bar3Base; -* unsigned int bar3Size; -* unsigned int bar4Base; -* unsigned int bar4Size; -* unsigned int bar5Base; -* unsigned int bar5Size; -* -* Inputs: PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE. -* unsigned int numberOfElment - The PCI0_DEVICE Array length. -* Output: None. -*********************************************************************/ - -void pci0ScanDevices(PCI_DEVICE * pci0Detect, unsigned int numberOfElment) -{ - PCI_DEVICE *pci0ArrayPointer = pci0Detect; - unsigned int id; /* PCI Configuration register 0x0. */ - unsigned int device; /* device`s Counter. */ - unsigned int classCode; /* PCI Configuration register 0x8 */ - unsigned int arrayCounter = 0; - unsigned int memBaseAddress; - unsigned int memSize; - unsigned int c18RegValue; - - PCI0_MASTER_ENABLE(SELF); - /* According to PCI REV 2.1 MAX agents on the bus are -21- */ - for (device = 6; device < 8; device++) { - id = pci0ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device); - GT_REG_READ(INTERRUPT_CAUSE_REGISTER, &c18RegValue); - /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */ - GT_REG_WRITE(INTERRUPT_CAUSE_REGISTER, - c18RegValue & 0xfffbffff); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - classCode = - pci0ReadConfigReg - (PCI_0CLASS_CODE_AND_REVISION_ID, device); - pci0ArrayPointer->deviceNum = device; - pci0ArrayPointer->venID = (id & 0xffff); - pci0ArrayPointer->deviceID = - ((id & 0xffff0000) >> 16); - DBG("\nrr: venID %x devID %x\n", - pci0ArrayPointer->venID, - pci0ArrayPointer->deviceID); - DBG("rr: device found %x\n", - pci0ArrayPointer->deviceNum); - /* BAR0 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR0, device); - pci0ArrayPointer->bar0Type = memBaseAddress & 1; - pci0ArrayPointer->bar0Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR0, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR0, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar0Size = 0; - } else { - if (pci0ArrayPointer->bar0Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar0Size = memSize; - } - DBG("rr: device BAR0 size %x\n", memSize); - DBG("rr: device BAR0 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR0, device, memBaseAddress); - /* BAR1 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR1, device); - pci0ArrayPointer->bar1Type = memBaseAddress & 1; - pci0ArrayPointer->bar1Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR1, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR1, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar1Size = 0; - } else { - if (pci0ArrayPointer->bar1Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar1Size = memSize; - } - DBG("rr: device BAR1 size %x\n", memSize); - DBG("rr: device BAR1 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR1, device, memBaseAddress); - /* BAR2 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR2, device); - pci0ArrayPointer->bar2Type = memBaseAddress & 1; - pci0ArrayPointer->bar2Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR2, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR2, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar2Size = 0; - } else { - if (pci0ArrayPointer->bar2Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar2Size = memSize; - } - DBG("rr: device BAR2 size %x\n", memSize); - DBG("rr: device BAR2 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR2, device, memBaseAddress); - /* BAR3 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR3, device); - pci0ArrayPointer->bar3Type = memBaseAddress & 1; - pci0ArrayPointer->bar3Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR3, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR3, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar3Size = 0; - } else { - if (pci0ArrayPointer->bar3Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar3Size = memSize; - } - DBG("rr: device BAR3 size %x\n", memSize); - DBG("rr: device BAR3 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR3, device, memBaseAddress); - /* BAR4 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR4, device); - pci0ArrayPointer->bar4Type = memBaseAddress & 1; - pci0ArrayPointer->bar4Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR4, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR4, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar4Size = 0; - } else { - if (pci0ArrayPointer->bar4Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar4Size = memSize; - } - DBG("rr: device BAR4 size %x\n", memSize); - DBG("rr: device BAR4 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR4, device, memBaseAddress); - /* BAR5 parameters */ - memBaseAddress = pci0ReadConfigReg(BAR5, device); - pci0ArrayPointer->bar5Type = memBaseAddress & 1; - pci0ArrayPointer->bar5Base = - memBaseAddress & 0xfffff000; - pci0WriteConfigReg(BAR5, device, 0xffffffff); - memSize = pci0ReadConfigReg(BAR5, device); - if (memSize == 0) { /* case of an empty BAR */ - pci0ArrayPointer->bar5Size = 0; - } else { - if (pci0ArrayPointer->bar5Type == 1) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci0ArrayPointer->bar5Size = memSize; - } - DBG("rr: device BAR5 size %x\n", memSize); - DBG("rr: device BAR5 address %x\n", - memBaseAddress); - pci0WriteConfigReg(BAR5, device, memBaseAddress); - /* End of BARs Detection. */ - - classCode = ((classCode & 0xff000000) >> 24); - switch (classCode) { - case 0x0: - strcpy(pci0ArrayPointer->type, - "Old generation device"); - break; - case 0x1: - strcpy(pci0ArrayPointer->type, - "Mass storage controller"); - break; - case 0x2: - strcpy(pci0ArrayPointer->type, - "Network controller"); - break; - case 0x3: - strcpy(pci0ArrayPointer->type, - "Display controller"); - break; - case 0x4: - strcpy(pci0ArrayPointer->type, - "Multimedia device"); - break; - case 0x5: - strcpy(pci0ArrayPointer->type, - "Memory controller"); - break; - case 0x6: - strcpy(pci0ArrayPointer->type, - "Bridge Device"); - break; - case 0x7: - strcpy(pci0ArrayPointer->type, - "Simple Communication controllers"); - break; - case 0x8: - strcpy(pci0ArrayPointer->type, - "Base system peripherals"); - break; - case 0x9: - strcpy(pci0ArrayPointer->type, - "Input Devices"); - break; - case 0xa: - strcpy(pci0ArrayPointer->type, - "Docking stations"); - break; - case 0xb: - strcpy(pci0ArrayPointer->type, - "Processors"); - break; - case 0xc: - strcpy(pci0ArrayPointer->type, - "Serial bus controllers"); - break; - case 0xd: - strcpy(pci0ArrayPointer->type, - "Wireless controllers"); - break; - case 0xe: - strcpy(pci0ArrayPointer->type, - "Intelligent I/O controllers"); - break; - case 0xf: - strcpy(pci0ArrayPointer->type, - "Satellite communication controllers"); - break; - case 0x10: - strcpy(pci0ArrayPointer->type, - "Encryption/Decryption controllers"); - break; - case 0x11: - strcpy(pci0ArrayPointer->type, - "Data acquisition and signal processing controllers"); - break; - default: - break; - - } - arrayCounter++; /* point to the next element in the Array. */ - if (arrayCounter == numberOfElment) - return; /* When the Array is fully used, return. */ - /* Else, points to next free Element. */ - pci0ArrayPointer = &pci0Detect[arrayCounter]; - } - } - pci0ArrayPointer->deviceNum = 0; /* 0 => End of List */ -} - - -/******************************************************************** -* pci1ScanDevices - This function scan PCI1 bus, if found any device on -* this bus it interrogate the Device for the information -* it can discover. -* The fields with all information are the following: -* char type[20]; -* unsigned int deviceNum; -* unsigned int venID; -* unsigned int deviceID; -* unsigned int bar0Base; -* unsigned int bar0Size; -* unsigned int bar1Base; -* unsigned int bar1Size; -* unsigned int bar2Base; -* unsigned int bar2Size; -* unsigned int bar3Base; -* unsigned int bar3Size; -* unsigned int bar4Base; -* unsigned int bar4Size; -* unsigned int bar5Base; -* unsigned int bar5Size; -* -* Inputs: Pointer to an array of STRUCT PCI1_DEVICE. -* Output: None. -*********************************************************************/ - -void pci1ScanDevices(PCI_DEVICE * pci1Detect, unsigned int numberOfElment) -{ - PCI_DEVICE *pci1ArrayPointer = pci1Detect; - unsigned int id; /* PCI Configuration register 0x0. */ - unsigned int device; /* device`s Counter. */ - unsigned int classCode; /* PCI Configuration register 0x8 */ - unsigned int arrayCounter = 0; - unsigned int memBaseAddress; - unsigned int memSize; - unsigned int c98RegValue; - - PCI1_MASTER_ENABLE(SELF); - /* According to PCI REV 2.1 MAX agents on the bus are -21- */ - for (device = 1; device < 22; device++) { - id = pci1ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device); - GT_REG_READ(HIGH_INTERRUPT_CAUSE_REGISTER, &c98RegValue); - /* Clearing bit 18 of in the High Cause Register 0xc98 */ - GT_REG_WRITE(HIGH_INTERRUPT_CAUSE_REGISTER, - c98RegValue & 0xfffbffff); - if ((id != 0xffffffff) && !(c98RegValue & 0x40000)) { - classCode = - pci1ReadConfigReg - (PCI_0CLASS_CODE_AND_REVISION_ID, device); - pci1ArrayPointer->deviceNum = device; - pci1ArrayPointer->venID = (id & 0xffff); - pci1ArrayPointer->deviceID = - ((id & 0xffff0000) >> 16); - - /* BAR0 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR0, device); - pci1ArrayPointer->bar0Type = memBaseAddress & 1; - pci1ArrayPointer->bar0Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR0, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR0, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar0Size = 0; - } else { - if (pci1ArrayPointer->bar0Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar0Size = memSize; - } - pci1WriteConfigReg(BAR0, device, memBaseAddress); - /* BAR1 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR1, device); - pci1ArrayPointer->bar1Type = memBaseAddress & 1; - pci1ArrayPointer->bar1Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR1, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR1, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar1Size = 0; - } else { - if (pci1ArrayPointer->bar1Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar1Size = memSize; - } - pci1WriteConfigReg(BAR1, device, memBaseAddress); - /* BAR2 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR2, device); - pci1ArrayPointer->bar2Type = memBaseAddress & 1; - pci1ArrayPointer->bar2Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR2, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR2, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar2Size = 0; - } else { - if (pci1ArrayPointer->bar2Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar2Size = memSize; - } - pci1WriteConfigReg(BAR2, device, memBaseAddress); - /* BAR3 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR3, device); - pci1ArrayPointer->bar3Type = memBaseAddress & 1; - pci1ArrayPointer->bar3Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR3, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR3, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar3Size = 0; - } else { - if (pci1ArrayPointer->bar3Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar3Size = memSize; - } - pci1WriteConfigReg(BAR3, device, memBaseAddress); - /* BAR4 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR4, device); - pci1ArrayPointer->bar4Type = memBaseAddress & 1; - pci1ArrayPointer->bar4Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR4, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR4, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar4Size = 0; - } else { - if (pci1ArrayPointer->bar4Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar4Size = memSize; - } - pci1WriteConfigReg(BAR4, device, memBaseAddress); - /* BAR5 parameters */ - memBaseAddress = pci1ReadConfigReg(BAR5, device); - pci1ArrayPointer->bar5Type = memBaseAddress & 1; - pci1ArrayPointer->bar5Base = - memBaseAddress & 0xfffff000; - pci1WriteConfigReg(BAR5, device, 0xffffffff); - memSize = pci1ReadConfigReg(BAR5, device); - if (memSize == 0) { /* case of an empty BAR */ - pci1ArrayPointer->bar5Size = 0; - } else { - if (pci1ArrayPointer->bar5Type == 0) /* memory space */ - memSize = - ~(memSize & 0xfffffff0) + 1; - else /* IO space */ - memSize = - ~(memSize & 0xfffffffc) + 1; - pci1ArrayPointer->bar5Size = memSize; - } - pci1WriteConfigReg(BAR5, device, memBaseAddress); - /* End of BARs Detection. */ - - classCode = ((classCode & 0xff000000) >> 24); - switch (classCode) { - case 0x0: - strcpy(pci1ArrayPointer->type, - "Old generation device"); - break; - case 0x1: - strcpy(pci1ArrayPointer->type, - "Mass storage controller"); - break; - case 0x2: - strcpy(pci1ArrayPointer->type, - "Network controller"); - break; - case 0x3: - strcpy(pci1ArrayPointer->type, - "Display controller"); - break; - case 0x4: - strcpy(pci1ArrayPointer->type, - "Multimedia device"); - break; - case 0x5: - strcpy(pci1ArrayPointer->type, - "Memory controller"); - break; - case 0x6: - strcpy(pci1ArrayPointer->type, - "Bridge Device"); - break; - case 0x7: - strcpy(pci1ArrayPointer->type, - "Simple Communication controllers"); - break; - case 0x8: - strcpy(pci1ArrayPointer->type, - "Base system peripherals"); - break; - case 0x9: - strcpy(pci1ArrayPointer->type, - "Input Devices"); - break; - case 0xa: - strcpy(pci1ArrayPointer->type, - "Docking stations"); - break; - case 0xb: - strcpy(pci1ArrayPointer->type, - "Processors"); - break; - case 0xc: - strcpy(pci1ArrayPointer->type, - "Serial bus controllers"); - break; - case 0xd: - strcpy(pci1ArrayPointer->type, - "Wireless controllers"); - break; - case 0xe: - strcpy(pci1ArrayPointer->type, - "Intelligent I/O controllers"); - break; - case 0xf: - strcpy(pci1ArrayPointer->type, - "Satellite communication controllers"); - break; - case 0x10: - strcpy(pci1ArrayPointer->type, - "Encryption/Decryption controllers"); - break; - case 0x11: - strcpy(pci1ArrayPointer->type, - "Data acquisition and signal processing controllers"); - break; - } - arrayCounter++; /* point to the next element in the Array. */ - if (arrayCounter == numberOfElment) - return; /* When the Array is fully used, return. */ - /* Else, points to next free Element. */ - pci1ArrayPointer = &pci1Detect[arrayCounter]; - } - } - pci1ArrayPointer->deviceNum = 0; /* 0 => End of List */ -} - -/******************************************************************** -* pci0WriteConfigReg - Write to a PCI configuration register -* - Make sure the GT is configured as a master before -* writingto another device on the PCI. -* - The function takes care of Big/Little endian conversion. -* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec -* (or any other PCI device spec) -* pciDevNum: The device number needs to be addressed. -* -* Configuration Address 0xCF8: -* -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number -* |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name -* -*********************************************************************/ - -void pci0WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum, - unsigned int data) -{ - unsigned int DataForRegCf8; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - if (pciDevNum == SELF) { /* This board */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - data); - } else { /* configuration Transaction over the pci. */ - - /* The PCI is working in LE Mode So it swap the Data. */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - WORDSWAP(data)); - } -} - -/******************************************************************** -* pci1WriteConfigReg - Write to a PCI configuration register -* - Make sure the GT is configured as a master before writing -* to another device on the PCI. -* - The function takes care of Big/Little endian conversion. -* Inputs: unsigned int regOffset: The register offset as it apears in the -* GT spec (or any other PCI device spec) -* pciDevNum: The device number needs to be addressed. -* -* Configuration Address 0xCF8: -* -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number -* |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name -* -*********************************************************************/ - -void pci1WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum, - unsigned int data) -{ - unsigned int DataForRegCf8; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - if (pciDevNum == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 = - (regOffset | pciDevNum | functionNum | 0x80) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - } else { - DataForRegCf8 = - (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8); - } - if (pciDevNum == SELF) { /* This board */ - GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - data); - } else { - GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, - WORDSWAP(data)); - } -} - -/******************************************************************** -* pci0ReadConfigReg - Read from a PCI0 configuration register -* - Make sure the GT is configured as a master before -* reading from another device on the PCI. -* - The function takes care of Big/Little endian conversion. -* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI -* spec) -* pciDevNum: The device number needs to be addressed. -* RETURNS: data , if the data == 0xffffffff check the master abort bit in the -* cause register to make sure the data is valid -* -* Configuration Address 0xCF8: -* -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number -* |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name -* -*********************************************************************/ - -unsigned int pci0ReadConfigReg(unsigned int regOffset, - unsigned int pciDevNum) -{ - unsigned int DataForRegCf8; - unsigned int data; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - if (pciDevNum == SELF) { /* This board */ - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return data; - } else { /* The PCI is working in LE Mode So it swap the Data. */ - - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return WORDSWAP(data); - } -} - -/******************************************************************** -* pci1ReadConfigReg - Read from a PCI1 configuration register -* - Make sure the GT is configured as a master before -* reading from another device on the PCI. -* - The function takes care of Big/Little endian conversion. -* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI -* spec) -* pciDevNum: The device number needs to be addressed. -* RETURNS: data , if the data == 0xffffffff check the master abort bit in the -* cause register to make sure the data is valid -* -* Configuration Address 0xCF8: -* -* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number -* |congif|Reserved| Bus |Device|Function|Register|00| -* |Enable| |Number|Number| Number | Number | | <=field Name -* -*********************************************************************/ - -unsigned int pci1ReadConfigReg(unsigned int regOffset, - unsigned int pciDevNum) -{ - unsigned int DataForRegCf8; - unsigned int data; - unsigned int functionNum; - - functionNum = regOffset & 0x00000700; - pciDevNum = pciDevNum << 11; - regOffset = regOffset & 0x0fffffff; - if (pciDevNum == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 = - (regOffset | pciDevNum | functionNum | 0x80) | BIT31; - GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8); - } else { - DataForRegCf8 = - (regOffset | pciDevNum | functionNum) | BIT31; - GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8); - } - if (pciDevNum == SELF) { /* This board */ - GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return data; - } else { - GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER, - &data); - return WORDSWAP(data); - } -} - -/******************************************************************** -* pci0MapIOspace - Maps PCI0 IO space for the master. -* Inputs: base and length of pci0Io -*********************************************************************/ - -void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength) -{ - unsigned int pci0IoTop = - (unsigned int) (pci0IoBase + pci0IoLength); - - if (pci0IoLength == 0) - pci0IoTop++; - - pci0IoBase = (unsigned int) (pci0IoBase >> 21); - pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); - GT_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS, pci0IoBase); - GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS, pci0IoTop); -} - -/******************************************************************** -* pci1MapIOspace - Maps PCI1 IO space for the master. -* Inputs: base and length of pci1Io -*********************************************************************/ - -void pci1MapIOspace(unsigned int pci1IoBase, unsigned int pci1IoLength) -{ - unsigned int pci1IoTop = - (unsigned int) (pci1IoBase + pci1IoLength); - - if (pci1IoLength == 0) - pci1IoTop++; - - pci1IoBase = (unsigned int) (pci1IoBase >> 21); - pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); - GT_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS, pci1IoBase); - GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS, pci1IoTop); -} - -/******************************************************************** -* pci0MapMemory0space - Maps PCI0 memory0 space for the master. -* Inputs: base and length of pci0Mem0 -*********************************************************************/ - - -void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length) -{ - unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; - - if (pci0Mem0Length == 0) - pci0Mem0Top++; - - pci0Mem0Base = pci0Mem0Base >> 21; - pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; - GT_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS, pci0Mem0Base); - GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, pci0Mem0Top); -} - -/******************************************************************** -* pci1MapMemory0space - Maps PCI1 memory0 space for the master. -* Inputs: base and length of pci1Mem0 -*********************************************************************/ - -void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length) -{ - unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; - - if (pci1Mem0Length == 0) - pci1Mem0Top++; - - pci1Mem0Base = pci1Mem0Base >> 21; - pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; - GT_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS, pci1Mem0Base); - GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS, pci1Mem0Top); -} - -/******************************************************************** -* pci0MapMemory1space - Maps PCI0 memory1 space for the master. -* Inputs: base and length of pci0Mem1 -*********************************************************************/ - -void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length) -{ - unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; - - if (pci0Mem1Length == 0) - pci0Mem1Top++; - - pci0Mem1Base = pci0Mem1Base >> 21; - pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; - GT_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS, pci0Mem1Base); - GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, pci0Mem1Top); -#ifndef PROM - DBG(KERN_INFO "pci0Mem1Base %x\n", pci0Mem1Base); - DBG(KERN_INFO "pci0Mem1Top %x\n", pci0Mem1Top); - GT_REG_READ(PCI_0MEMORY0_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/0 remap %x\n", pci0Mem1Base); - GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/1 remap %x\n", pci0Mem1Base); - GT_REG_WRITE(PCI_0MEMORY1_ADDRESS_REMAP, 0x500); - GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base); - DBG(KERN_INFO "Mem 0/1 remapped %x\n", pci0Mem1Base); -#endif -} - -/******************************************************************** -* pci1MapMemory1space - Maps PCI1 memory1 space for the master. -* Inputs: base and length of pci1Mem1 -*********************************************************************/ - -void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length) -{ - unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; - - if (pci1Mem1Length == 0) - pci1Mem1Top++; - - pci1Mem1Base = pci1Mem1Base >> 21; - pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; - GT_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS, pci1Mem1Base); - GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, pci1Mem1Top); -} - -/******************************************************************** -* pci0GetIOspaceBase - Return PCI0 IO Base Address. -* Inputs: N/A -* Returns: PCI0 IO Base Address. -*********************************************************************/ - -unsigned int pci0GetIOspaceBase() -{ - unsigned int base; - GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetIOspaceSize - Return PCI0 IO Bar Size. -* Inputs: N/A -* Returns: PCI0 IO Bar Size. -*********************************************************************/ - -unsigned int pci0GetIOspaceSize() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0I_O_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. -* Inputs: N/A -* Returns: PCI0 Memory 0 Base Address. -*********************************************************************/ - -unsigned int pci0GetMemory0Base() -{ - unsigned int base; - GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. -* Inputs: N/A -* Returns: PCI0 Memory 0 Bar Size. -*********************************************************************/ - -unsigned int pci0GetMemory0Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. -* Inputs: N/A -* Returns: PCI0 Memory 1 Base Address. -*********************************************************************/ - -unsigned int pci0GetMemory1Base() -{ - unsigned int base; - GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. -* Inputs: N/A -* Returns: PCI0 Memory 1 Bar Size. -*********************************************************************/ - -unsigned int pci0GetMemory1Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci1GetIOspaceBase - Return PCI1 IO Base Address. -* Inputs: N/A -* Returns: PCI1 IO Base Address. -*********************************************************************/ - -unsigned int pci1GetIOspaceBase() -{ - unsigned int base; - GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetIOspaceSize - Return PCI1 IO Bar Size. -* Inputs: N/A -* Returns: PCI1 IO Bar Size. -*********************************************************************/ - -unsigned int pci1GetIOspaceSize() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1I_O_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. -* Inputs: N/A -* Returns: PCI1 Memory 0 Base Address. -*********************************************************************/ - -unsigned int pci1GetMemory0Base() -{ - unsigned int base; - GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. -* Inputs: N/A -* Returns: PCI1 Memory 0 Bar Size. -*********************************************************************/ - -unsigned int pci1GetMemory0Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. -* Inputs: N/A -* Returns: PCI1 Memory 1 Base Address. -*********************************************************************/ - -unsigned int pci1GetMemory1Base() -{ - unsigned int base; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - return base; -} - -/******************************************************************** -* pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. -* Inputs: N/A -* Returns: PCI1 Memory 1 Bar Size. -*********************************************************************/ - -unsigned int pci1GetMemory1Size() -{ - unsigned int top, base, size; - GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base); - base = base << 21; - GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/******************************************************************** -* pci0MapInternalRegSpace - Maps the internal registers memory space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci0 internal register -*********************************************************************/ - -void pci0MapInternalRegSpace(unsigned int pci0InternalBase) -{ - pci0InternalBase = pci0InternalBase & 0xfffff000; - pci0InternalBase = - pci0InternalBase | - (pci0ReadConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci0WriteConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF, - pci0InternalBase); -} - -/******************************************************************** -* pci1MapInternalRegSpace - Maps the internal registers memory space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci1 internal register -*********************************************************************/ - -void pci1MapInternalRegSpace(unsigned int pci1InternalBase) -{ - pci1InternalBase = pci1InternalBase & 0xfffff000; - pci1InternalBase = - pci1InternalBase | - (pci1ReadConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci1WriteConfigReg - (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF, - pci1InternalBase); -} - -/******************************************************************** -* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci0 internal io register -*********************************************************************/ - -void pci0MapInternalRegIOSpace(unsigned int pci0InternalBase) -{ - pci0InternalBase = pci0InternalBase & 0xfffff000; - pci0InternalBase = - pci0InternalBase | - (pci0ReadConfigReg - (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - 0) & 0x00000fff); - pci0WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF, pci0InternalBase); -} - -/******************************************************************** -* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the -* slave. -* Stays the same for all GT devices Disco include -* Inputs: base of pci1 internal io register -*********************************************************************/ - -void pci1MapInternalRegIOSpace(unsigned int pci1InternalBase) -{ - pci1InternalBase = pci1InternalBase & 0xfffff000; - pci1InternalBase = - pci1InternalBase | - (pci1ReadConfigReg - (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF) & 0x00000fff); - pci1WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS, - SELF, pci1InternalBase); -} - -/******************************************************************** -* pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave. -* for Discovery we need two function: SCS0 & SCS1 -* (instead of SCS[1:0]) -* Inputs: base and size of pci0 dram -*********************************************************************/ - - -void pci0MapMemoryBanks0_1(unsigned int pci0Dram0_1Base, - unsigned int pci0Dram0_1Size) -{ - pci0Dram0_1Base = pci0Dram0_1Base & 0xfffff000; - pci0Dram0_1Base = - pci0Dram0_1Base | - (pci0ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF, - pci0Dram0_1Base); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF, - pci0Dram0_1Base); - if (pci0Dram0_1Size == 0) - pci0Dram0_1Size++; - GT_REG_WRITE(PCI_0SCS_1_0_BANK_SIZE, pci0Dram0_1Size - 1); -} - -/******************************************************************** -* pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave. -* for Discovery we need two function: SCS0 & SCS1 -* (instead of SCS[1:0]) -* Inputs: base and size of pci1 dram -*********************************************************************/ - -void pci1MapMemoryBanks0_1(unsigned int pci1Dram0_1Base, - unsigned int pci1Dram0_1Size) -{ - pci1Dram0_1Base = pci1Dram0_1Base & 0xfffff000; - pci1Dram0_1Base = - pci1Dram0_1Base | - (pci1ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF, - pci1Dram0_1Base); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF, - pci1Dram0_1Base); - if (pci1Dram0_1Size == 0) - pci1Dram0_1Size++; - GT_REG_WRITE(PCI_1SCS_1_0_BANK_SIZE, pci1Dram0_1Size - 1); -} - -/******************************************************************** -* pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave. -* for Discovery we need two function: SCS2 & SCS3 -* (instead of SCS[3:2]) -* Inputs: base and size of pci0 dram -*********************************************************************/ - -void pci0MapMemoryBanks2_3(unsigned int pci0Dram2_3Base, - unsigned int pci0Dram2_3Size) -{ - pci0Dram2_3Base = pci0Dram2_3Base & 0xfffff000; - pci0Dram2_3Base = - pci0Dram2_3Base | - (pci0ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF, - pci0Dram2_3Base); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF, - pci0Dram2_3Base); - if (pci0Dram2_3Size == 0) - pci0Dram2_3Size++; - GT_REG_WRITE(PCI_0SCS_3_2_BANK_SIZE, pci0Dram2_3Size - 1); -} - -/******************************************************************** -* pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave. -* for Discovery we need two function: SCS2 & SCS3 -* (instead of SCS[3:2]) -* Inputs: base and size of pci1 dram -*********************************************************************/ - -void pci1MapMemoryBanks2_3(unsigned int pci1Dram2_3Base, - unsigned int pci1Dram2_3Size) -{ - pci1Dram2_3Base = pci1Dram2_3Base & 0xfffff000; - pci1Dram2_3Base = - pci1Dram2_3Base | - (pci1ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF, - pci1Dram2_3Base); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF, - pci1Dram2_3Base); - if (pci1Dram2_3Size == 0) - pci1Dram2_3Size++; - GT_REG_WRITE(PCI_1SCS_3_2_BANK_SIZE, pci1Dram2_3Size - 1); -} - -/******************************************************************** -* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces -* for the slave. -* For the Discovery there are 3 separate -* fucnction's -* Inputs: base and lengthof pci0 devises012 -*********************************************************************/ - - -void pci0MapDevices0_1and2MemorySpace(unsigned int pci0Dev012Base, - unsigned int pci0Dev012Length) -{ - pci0Dev012Base = pci0Dev012Base & 0xfffff000; - pci0Dev012Base = - pci0Dev012Base | - (pci0ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci0Dev012Base); - if (pci0Dev012Length == 0) - pci0Dev012Length++; - GT_REG_WRITE(PCI_0CS_2_0_BANK_SIZE, pci0Dev012Length - 1); -} - -/******************************************************************** -* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces -* for the slave. -* For the Discovery there are 3 separate -* fucnction's -* Inputs: base and lengthof pci1 devises012 -*********************************************************************/ - -void pci1MapDevices0_1and2MemorySpace(unsigned int pci1Dev012Base, - unsigned int pci1Dev012Length) -{ - pci1Dev012Base = pci1Dev012Base & 0xfffff000; - pci1Dev012Base = - pci1Dev012Base | - (pci1ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci1Dev012Base); - if (pci1Dev012Length == 0) - pci1Dev012Length++; - GT_REG_WRITE(PCI_1CS_2_0_BANK_SIZE, pci1Dev012Length - 1); -} - -/******************************************************************** -* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory -* spaces for the slave. -* For the Discovery there are 2 separate -* fucnction's -* Inputs: base and length of pci0 device3/ boot -*********************************************************************/ - -void pci0MapDevices3andBootMemorySpace(unsigned int pci0Dev3andBootBase, - unsigned int pci0Dev3andBootLength) -{ - pci0Dev3andBootBase = pci0Dev3andBootBase & 0xfffff000; - pci0Dev3andBootBase = - pci0Dev3andBootBase | - (pci0ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) & - 0x00000fff); - pci0WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci0Dev3andBootBase); - /* swapped Bar */ - pci0WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci0Dev3andBootBase); - if (pci0Dev3andBootLength == 0) - pci0Dev3andBootLength++; - GT_REG_WRITE(PCI_0CS_3_BOOTCS_BANK_SIZE, - pci0Dev3andBootLength - 1); -} - -/******************************************************************** -* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory -* spaces for the slave. -* For the Discovery there are 2 separate -* fucnction's -* Inputs: base and length of pci1 device3/ boot -*********************************************************************/ - -void pci1MapDevices3andBootMemorySpace(unsigned int pci1Dev3andBootBase, - unsigned int pci1Dev3andBootLength) -{ - pci1Dev3andBootBase = pci1Dev3andBootBase & 0xfffff000; - pci1Dev3andBootBase = - pci1Dev3andBootBase | - (pci1ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) & - 0x00000fff); - pci1WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci1Dev3andBootBase); - /* swapped Bar */ - pci1WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF, - pci1Dev3andBootBase); - if (pci1Dev3andBootLength == 0) - pci1Dev3andBootLength++; - GT_REG_WRITE(PCI_1CS_3_BOOTCS_BANK_SIZE, - pci1Dev3andBootLength - 1); -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,318 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - */ -#include -#include -#include - -#include "etherboot.h" -#include "pci_etherboot.h" -#include "galileo_port.h" - -#define MAX_PCI_DEVS 10 -PCI_DEVICE pci0_devices[MAX_PCI_DEVS]; -PCI_DEVICE pci1_devices[MAX_PCI_DEVS]; - -static int pci_range_ck(unsigned char bus, unsigned char dev) -{ - if ((bus == 0) && (dev >= 0) && (dev < 30)) - return 0; // Bus/Device Number OK - - return -1; // Bus/Device Number not OK -} - -/******************************************************************** - * pcibios_(read/write)_config_(byte/word/dword) - * - *Inputs : - *bus - bus number - *dev - device number - *offset - register offset in the configuration space - *val - value to be written / read - * - *Outputs : - *Sucees/Failure - *********************************************************************/ -#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc) -#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8) - -#define PCI_CFG_SET(dev,fun,off) \ - ((*PCI_CFG_CTRL) = cpu_to_le32((0x80000000 | ((dev)<<11) | ((fun)<<8) | (off)))) - -int pcibios_read_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int *val) -{ - - if (offset & 0x3) { - return PCIBIOS_BAD_REGISTER_NUMBER; - } - if (pci_range_ck(bus, dev)) { - *val = 0xFFFFFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, offset); - if (dev != 0) { - *val = *PCI_CFG_DATA; - } else { - *val = cpu_to_le32(*PCI_CFG_DATA); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short *val) -{ - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - *val = *PCI_CFG_DATA >> ((offset & 3) * 8); - } else { - *val = cpu_to_le32(*PCI_CFG_DATA) >> ((offset & 3) * 8); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_read_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char *val) -{ - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - *val = *PCI_CFG_DATA >> ((offset & 3) * 8); - } else { - *val = cpu_to_le32(*PCI_CFG_DATA >> ((offset & 3) * 8)); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int val) -{ - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, offset); - if (dev != 0) { - *PCI_CFG_DATA = val; - } else { - *PCI_CFG_DATA = cpu_to_le32(val); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short val) -{ - unsigned long tmp; - - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - tmp = *PCI_CFG_DATA; - } else { - tmp = cpu_to_le32(*PCI_CFG_DATA); - } - tmp &= ~(0xffff << ((offset & 0x3) * 8)); - tmp |= (val << ((offset & 0x3) * 8)); - if (dev != 0) { - *PCI_CFG_DATA = tmp; - } else { - *PCI_CFG_DATA = cpu_to_le32(tmp); - } - return PCIBIOS_SUCCESSFUL; -} - -int pcibios_write_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char val) -{ - unsigned long tmp; - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - PCI_CFG_SET(dev, 0, (offset & ~0x3)); - if (dev != 0) { - tmp = *PCI_CFG_DATA; - } else { - tmp = cpu_to_le32(*PCI_CFG_DATA); - } - tmp &= ~(0xff << ((offset & 0x3) * 8)); - tmp |= (val << ((offset & 0x3) * 8)); - *PCI_CFG_DATA = cpu_to_le32(tmp); - return PCIBIOS_SUCCESSFUL; -} - - -/******************************************************************** - * eth_pci_init - Fill pci_devi - * - *Inputs : - *bus - bus number - *dev - device number - *offset - register offset in the configuration space - *val - value to be written / read - * - *Outputs : - *Sucees/Failure - *********************************************************************/ -void eth_pci_init(struct pci_device *pcidev) -{ - int i, count; - pcibios_write_config_word(0, 0, 4, 0x7); - pcibios_write_config_dword(0, 8, BAR0, 0x12000000); - pcibios_write_config_dword(0, 8, BAR1, 0x10000001); - pcibios_write_config_dword(0, 8, BAR2, 0x12100000); - strcpy(pci0_devices[0].type, "Network Controller"); - pci0_devices[0].deviceNum = 8; - pci0_devices[0].venID = 0x8086; - pci0_devices[0].deviceID = 0x1229; - - pci0_devices[0].bar0Base = 0x12000000; - pci0_devices[0].bar0Size = 0x00001000; - pci0_devices[0].bar0Type = 0; - pci0_devices[0].bar1Base = 0x10000000; - pci0_devices[0].bar1Size = 0x40; - pci0_devices[0].bar1Type = 1; - pci0_devices[0].bar2Base = 0x12100000; - pci0_devices[0].bar2Size = 0x00100000; - pci0_devices[0].bar2Type = 0; - for (i = 0; pcidev[i].vendor != 0; i++) { - /* Look for device in PCI0 first */ - for (count = 0; count < MAX_PCI_DEVS; count++) { - if ((pci0_devices[count].type[0] != 0) - && ((unsigned short) pci0_devices[count]. - venID == (unsigned short) pcidev[i].vendor) - && ((unsigned short) pci0_devices[count]. - deviceID == - (unsigned short) pcidev[i].dev_id)) { - if ((pci0_devices[count].bar0Type == 1) - && (pci0_devices[count].bar0Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar0Base; - if ((pci0_devices[count].bar1Type == 1) - && (pci0_devices[count].bar1Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar1Base; - if ((pci0_devices[count].bar2Type == 1) - && (pci0_devices[count].bar2Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar2Base; - if ((pci0_devices[count].bar3Type == 1) - && (pci0_devices[count].bar3Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar3Base; - if ((pci0_devices[count].bar4Type == 1) - && (pci0_devices[count].bar4Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar4Base; - if ((pci0_devices[count].bar5Type == 1) - && (pci0_devices[count].bar5Size != 0)) - pcidev[i].ioaddr = - pci0_devices[count].bar5Base; - - if ((pci0_devices[count].bar0Type == 0) - && (pci0_devices[count].bar0Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar0Base; - if ((pci0_devices[count].bar1Type == 0) - && (pci0_devices[count].bar1Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar1Base; - if ((pci0_devices[count].bar2Type == 0) - && (pci0_devices[count].bar2Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar2Base; - if ((pci0_devices[count].bar3Type == 0) - && (pci0_devices[count].bar3Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar3Base; - if ((pci0_devices[count].bar4Type == 0) - && (pci0_devices[count].bar4Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar4Base; - if ((pci0_devices[count].bar5Type == 0) - && (pci0_devices[count].bar5Size != 0)) - pcidev[i].membase = - pci0_devices[count].bar5Base; - pcidev[i].bus = 0; - pcidev[i].devfn = - pci0_devices[count].deviceNum; - } -#ifdef CONFIG_EVB_PCI1 - if ((pci1_devices[count].type[0] != 0) - && (pci1_devices[count].venID == - pcidev[i].vendor) - && (pci1_devices[count].deviceID == - pcidev[i].dev_id)) { - if ((pci1_devices[count].bar0Type == 1) - && (pci1_devices[count].bar0Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar0Base; - if ((pci1_devices[count].bar1Type == 1) - && (pci1_devices[count].bar1Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar1Base; - if ((pci1_devices[count].bar2Type == 1) - && (pci1_devices[count].bar2Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar2Base; - if ((pci1_devices[count].bar3Type == 1) - && (pci1_devices[count].bar3Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar3Base; - if ((pci1_devices[count].bar4Type == 1) - && (pci1_devices[count].bar4Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar4Base; - if ((pci1_devices[count].bar5Type == 1) - && (pci1_devices[count].bar5Size != 0)) - pcidev[i].ioaddr = - pci1_devices[count].bar5Base; - - if ((pci1_devices[count].bar0Type == 0) - && (pci1_devices[count].bar0Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar0Base; - if ((pci1_devices[count].bar1Type == 0) - && (pci1_devices[count].bar1Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar1Base; - if ((pci1_devices[count].bar2Type == 0) - && (pci1_devices[count].bar2Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar2Base; - if ((pci1_devices[count].bar3Type == 0) - && (pci1_devices[count].bar3Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar3Base; - if ((pci1_devices[count].bar4Type == 0) - && (pci1_devices[count].bar4Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar4Base; - if ((pci1_devices[count].bar5Type == 0) - && (pci1_devices[count].bar5Size != 0)) - pcidev[i].membase = - pci1_devices[count].bar5Base; - - pcidev[i].bus = 1; - pcidev[i].devfn = - pci1_devices[count].deviceNum; - } -#endif - } - } -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,144 +0,0 @@ -#ifndef PCI_H -#define PCI_H - -/* -** Support for NE2000 PCI clones added David Monro June 1997 -** Generalised for other PCI NICs by Ken Yap July 1997 -** -** Most of this is taken from: -** -** /usr/src/linux/drivers/pci/pci.c -** /usr/src/linux/include/linux/pci.h -** /usr/src/linux/arch/i386/bios32.c -** /usr/src/linux/include/linux/bios32.h -** /usr/src/linux/drivers/net/ne.c -*/ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - */ - -#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ -#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ - - -#define PCI_VENDOR_ID 0x00 /* 16 bits */ -#define PCI_DEVICE_ID 0x02 /* 16 bits */ -#define PCI_COMMAND 0x04 /* 16 bits */ - -#define PCI_CLASS_CODE 0x0b /* 8 bits */ -#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */ -#define PCI_HEADER_TYPE 0x0e /* 8 bits */ - -#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ -#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */ -#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */ -#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ -#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ -#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ - -#ifndef PCI_BASE_ADDRESS_IO_MASK -#define PCI_BASE_ADDRESS_IO_MASK (~0x03) -#endif -#define PCI_BASE_ADDRESS_SPACE_IO 0x01 -#define PCI_ROM_ADDRESS 0x30 /* 32 bits */ -#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM, - bits 31..11 are address, - 10..2 are reserved */ - -#define PCI_FUNC(devfn) ((devfn) & 0x07) - -#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) - -/* PCI signature: "PCI " */ -#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24)) - -/* PCI service signature: "$PCI" */ -#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24)) - -#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */ - -#define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_DEVICE_ID_REALTEK_8029 0x8029 -#define PCI_DEVICE_ID_REALTEK_8139 0x8139 -#define PCI_VENDOR_ID_WINBOND2 0x1050 -#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 -#define PCI_VENDOR_ID_COMPEX 0x11f6 -#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 -#define PCI_VENDOR_ID_KTI 0x8e2e -#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 -#define PCI_VENDOR_ID_NETVIN 0x4a14 -#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 -#define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 -#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200 -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_DEVICE_ID_INTEL_82557 0x1229 -#define PCI_VENDOR_ID_AMD 0x1022 -#define PCI_DEVICE_ID_AMD_LANCE 0x2000 -#define PCI_VENDOR_ID_SMC_1211 0x1113 -#define PCI_DEVICE_ID_SMC_1211 0x1211 -#define PCI_VENDOR_ID_DEC 0x1011 -#define PCI_DEVICE_ID_DEC_TULIP 0x0002 -#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 -#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 -#define PCI_DEVICE_ID_DEC_21142 0x0019 -#define PCI_VENDOR_ID_SMC 0x10B8 -#ifndef PCI_DEVICE_ID_SMC_EPIC100 -# define PCI_DEVICE_ID_SMC_EPIC100 0x0005 -#endif -#define PCI_VENDOR_ID_MACRONIX 0x10d9 -#define PCI_DEVICE_ID_MX987x5 0x0531 -#define PCI_VENDOR_ID_LINKSYS 0x11AD -#define PCI_DEVICE_ID_LC82C115 0xC115 -#define PCI_VENDOR_ID_VIATEC 0x1106 -#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043 -#define PCI_DEVICE_ID_VIA_86C100A 0x6100 -#define PCI_VENDOR_ID_DAVICOM 0x1282 -#define PCI_DEVICE_ID_DM9102 0x9102 - -struct pci_device { - unsigned short vendor, dev_id; - const char *name; - unsigned int membase; - unsigned int ioaddr; - unsigned short devfn; - unsigned short bus; -}; - -extern void eth_pci_init(struct pci_device *); -int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val); -int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val); -int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val); -int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val); -int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val); -int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val); - -/* - * Error values that may be returned by the PCI bios. - */ -#define PCIBIOS_SUCCESSFUL 0x00 -#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 -#define PCIBIOS_BAD_VENDOR_ID 0x83 -#define PCIBIOS_DEVICE_NOT_FOUND 0x86 -#define PCIBIOS_BAD_REGISTER_NUMBER 0x87 -#define PCIBIOS_SET_FAILED 0x88 -#define PCIBIOS_BUFFER_TOO_SMALL 0x89 - - - -#endif /* PCI_H */ diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/sbd.h linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/sbd.h --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/sbd.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/sbd.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,52 +0,0 @@ -/* - * sbd.h: cpu board definitions for Galileo-9 - * Copyright (c) 1997 Algorithmics Ltd - */ - -#ifndef MHZ -/* fastest possible pipeline clock */ -#define MHZ 150 -#endif - -/* FIXME These timings are completely fictional */ -#define RAMCYCLE 60 /* 60ns dram cycle */ -#define ROMCYCLE 750 /* ~750ns rom cycle */ -#define CACHECYCLE (1000/MHZ) /* internal clock */ -#define CYCLETIME CACHECYCLE -#define CACHEMISS (CYCLETIME * 6) - -/* - * rough scaling factors for 2 instruction DELAY loop to get 1ms and 1us delays - */ -#define ASMDELAY(ns,icycle) \ - (((ns) + (icycle)) / ((icycle) * 2)) - -#define CACHEUS ASMDELAY(1000, CACHECYCLE) -#define RAMUS ASMDELAY(1000, CACHEMISS+RAMCYCLE) -#define ROMUS ASMDELAY(1000, CACHEMISS+ROMCYCLE) -#define CACHEMS ASMDELAY(1000000, CACHECYCLE) -#define RAMMS ASMDELAY(1000000, CACHEMISS+RAMCYCLE) -#define ROMMS ASMDELAY(1000000, CACHEMISS+ROMCYCLE) - -#ifndef __ASSEMBLY__ -#define nsdelay(ns) mips_cycle (ASMDELAY (ns, CACHECYCLE)) -#define usdelay(us) mips_cycle (ASMDELAY ((us)*1000, CACHECYCLE)) -#endif - -#define DRAM_BASE 0x00000000 -#define PCI_IO_BASE 0x10000000 -#define PCI_IO_SIZE 0x02000000 -#define PCI_MEM_BASE 0x12000000 -#define PCI_MEM_SIZE 0x02000000 -#define GT64011_BASE 0x14000000 -#define DUART_BASE 0x1d000000 -#define FLASH_BASE 0x1f000000 -#define PROM_BASE 0x1fc00000 - - -#define LOCAL_MEM DRAM_BASE -#define LOCAL_MEM_SIZE (128*1024*1024) /* SDRAM size (16MB) */ - -#define BOOTPROM_BASE PROM_BASE - -#define DUART_CLOCK 3686400 diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,1049 +0,0 @@ -/* - * Copyright 1997 Algorithmics Ltd - * All Rights Reserved - * - * gal9/sbdreset.sx -- low level board dependent routines - */ - -#ifdef EVB64120A - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sbd.h" - - -#include "gt64011.h" -#include "ns16550.h" - -#ifdef GALILEO_PORT // miniBios crack -#define C0_CONFIG CP0_CONFIG -#define C0_STATUS CP0_STATUS -#define C0_TLBLO0 CP0_ENTRYLO0 -#define C0_TLBLO1 CP0_ENTRYLO1 -#define C0_PGMASK CP0_PAGEMASK -#define C0_TLBHI CP0_ENTRYHI -#define C0_INX CP0_INDEX -#define NTLBENTRIES 48 - - -#define CFG_IB CONF_IB -#define CFG_DB CONF_DB -#define CFG_C_NONCOHERENT CONF_CM_CACHABLE_NONCOHERENT -#define C0_SR CP0_STATUS -#define SR_DE ST0_DE - - - #define SLEAF(x) LEAF(x) - #define SEND(x) END(x) - #define XLEAF(x) LEAF(x) - #define SBD_DISPLAY(a,b,c,d,e) ; - -#define K0BASE 0x80000000 -#define K0SIZE 0x20000000 -#define K1BASE 0xa0000000 -#define K1SIZE 0x20000000 -#define K2BASE 0xc0000000 - -#define PHYS_TO_K0(pa) ((pa)|K0BASE) -#define PHYS_TO_K1(pa) ((pa)|K1BASE) -#define K0_TO_PHYS(va) ((va)&(K0SIZE-1)) -#define K1_TO_PHYS(va) ((va)&(K1SIZE-1)) -#define K0_TO_K1(va) ((va)|K1SIZE) -#define K1_TO_K0(va) ((va)&~K1SIZE) - -#define PA_TO_KVA0(pa) PHYS_TO_K0(pa) -#define PA_TO_KVA1(pa) PHYS_TO_K1(pa) -#define KVA_TO_PA(pa) K1_TO_PHYS(pa) -#define KSEG0_BASE K0BASE -#define KSEG1_BASE K1BASE - - -#endif - -#define MB 0x100000 - -#define MemTypeNone 0x8000 -#define MemRasMask 0x0f00 -#define MemRasShift 8 -#define MemCasMask 0x000f -#define MemCasShift 0 - -#define rasave s0 -#define p64011 s1 -#define bank0 s2 -#define bank1 s3 -#define bank2 s4 -#define bank3 s5 -#define memtop s6 -#define membase s7 - -/*#if #endian(big) */ -#ifdef __MIPSEB__ - -#define HTOLL(sr,tr) \ - .set noat ; \ - srl AT,sr,24 ; \ - srl tr,sr,8 ; \ - and tr,0xff00 ; \ - or AT,tr ; \ - and tr,sr,0xff00 ; \ - sll tr,8 ; \ - or AT,tr ; \ - sll tr,sr,24 ; \ - or sr,AT,tr ; \ - .set at -#else -#define HTOLL(sr,tr) -#endif - -#undef DBGSBD - -#ifdef DBGSBD -#define DBG(s) \ - .rdata ; \ -88: .asciiz s ; \ - .text ; \ - la a0, 88b ; \ - jal _dbgmsg - -LEAF(_dbgmsg) - .set noat - li AT,PHYS_TO_K1(NS16550_CHANB) -waitrdy: - lbu v1,LSR(AT) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - and v1,LSR_TXRDY - beqz v1,waitrdy - - lbu v1,(a0) - addu a0,1 - beqz v1,9f - sb v1,DATA(AT) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - b waitrdy -9: j ra - .set at -END(_dbgmsg) - -LEAF(_dbghex) - li a1,PHYS_TO_K1(NS16550_CHANB) - li t0,8 -1: - lbu t1,LSR(a1) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - and t1,LSR_TXRDY - beqz t1,1b - - srl t1,a0,28 - addu t1,'0' - ble t1,'9',2f - addu t1,'a'-'0'-10 -2: sb t1,DATA(a1) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - - sll a0,4 - sub t0,1 - bnez t0,1b - - j ra - .set at -END(_dbghex) - - .rdata -initb_str: - .byte 9,0x40 /* Reset CH B */ - .byte 1,0x00 /* Interrupt disabled */ - .byte 3,0xc1 /* 8 bits/char rx enable */ - .byte 4,0x44 /* x16 clk mode 1 stop bit */ - .byte 5,0x6a /* tx 8/bit RTS & tx enable */ - .byte 9,0x0a /* MIE Master int enab. and NV No Vector */ - .byte 11,0x50 /* Select BR gen. out for both rx and ts */ - .byte 0,0x10 - .byte 0,0x10 - .byte 14,0x01 /* enable baud rate gen. */ - .byte 15,0x00 /* known state for reg 15 */ - - .byte 14,0x00 /* disable baud rate gen. */ - .byte 12,0x0a /* 0x0a = 9600 baud time const. - lower 8 bits */ - .byte 13,0x00 /* 9600 buad time const. - upper 8 bits */ - .byte 14,0x01 /* enable baud rate gen. */ - .byte 0xff - - .text - -SLEAF(_dbginit) - /* - li v0,PHYS_TO_K1(NS16550_CHANB) - la a0,initb_str - or a0,K1BASE -1: lbu t0,0(a0) - beq t0,0xff,1f - sb t0,LSR(v0) - .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder - addu a0,1 - b 1b - */ - jal init_ns16550_chan_b # Debug channel - j ra -SEND(_dbginit) -#else -#define DBG(s) -#endif - -LEAF(sbdreset) - move rasave,ra - - /* if launched by ITROM, leave Config alone */ -#ifndef ITBASE - /* set config register for 32b/32b cachelines, kseg0 cacheable */ - mfc0 t1,C0_CONFIG - and t1,~0x3f # set bits 5..0 only - or t1,CFG_IB | CFG_DB | CFG_C_NONCOHERENT - mtc0 t1,C0_CONFIG -#endif - - /* Initialize stack pointer to 6MB address */ - li sp,0xa0600000 - - - /* - * slight amount of kludgery here to stop RAM resident - * program from overwriting itself... - */ -// li v1,0x1fc00000 /* check return address is in ROM */ -// and v0,ra,v1 -// bne v0,v1,.noinit - - /* table driven hardware register initialization */ - la a0, reginittab - or a0, K1BASE /* force to kseg1 */ - -1: lw v0,0(a0) - lw v1,4(a0) - addu a0,8 - beqz v0,8f - - sw v1,0(v0) - b 1b -8: - -#ifdef DBGSBD - jal init_ns16550_chan_b # was - _dbginit - DBG("sbdreset\r\n") -#endif -#define DEVICE_BANK0PARAMETERS 0x45C -#define DEVICE_BANK1PARAMETERS 0x460 -#define DEVICE_BANK2PARAMETERS 0x464 -#define DEVICE_BANK3PARAMETERS 0x468 -#define DEVICE_BOOT_BANK_PARAMETERS 0x46C -#define GT_INTERNAL_REG_BASE 0xb4000000 - - li p64011, PA_TO_KVA1(GT64011_BASE) - - li v0,0xb400046c /* Boot Device */ - lw t0,0(v0) - and t0,0x00003000 /* Keep the correct boot size */ - or t0,htoll(0x3847de70) - sw t0,0(v0) - - li v0,0xb4000468 /* CS3 Device - 16 bit FLASH memory */ - li t0,htoll(0x3859e6e8) - sw t0,0(v0) - - - li v0,0xb4000c84 /* PCI 1 timeout register */ - li t0,htoll(0xffff) - sw t0,0(v0) - - - li v0,0xb4000c3c /* Enable I/O response on PCI0 */ - li t0,htoll(0x7) - sw t0,0(v0) - - li v0,0xb4000cbc /* Enable I/O response on PCI1 */ - li t0,htoll(0x7) - sw t0,0(v0) - - /* GT-64120 Initialization */ - - li p64011, PA_TO_KVA1(GT64011_BASE) - - /*********************************************************************/ - /************************* SDRAM initializing ************************/ - /******************************* START *******************************/ - - - /* SDRAM banks 0,1,2,3 parameters */ - li t0,htoll(0x01908200) /* - Standard Monitor: Interleave enabled */ - li v0,0xb4000448 /* - Registered SDRAM (Bit 23) */ - sw t0,0(v0) /* - Duplicate Dadr11,BankSel1 and Dadr12 */ - /* - Cas latency: 2 Cycles */ - /* - Flow Through enable: One sample */ - /* - SRAS - precharge time: 3 Cycles */ - /* - No ECC */ - /* - No ByPass */ - /* - Burst length: 8 */ - - /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM0 */ - /* Set bank0`s range to: 0 - 0x10000000 (256 MByte) */ -_DIMM0: - li v0,0xb4000008 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000010 - li t0,htoll(0x7f) - sw t0,0(v0) - - /* Close banks 2 and 3 */ - li v0,0xb4000018 - li t0,htoll(0x7ff) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x00) - sw t0,0(v0) - - /* Extend bank0 to 0x10000000 and Close bank1,2 and 3 */ - DBG("Extend bank0 to 0x10000000 and Close bank1,2 and 3...\r\n") - li v0,0xb4000400 - li t0,htoll(0x0) - sw t0,0(v0) - li v0,0xb4000404 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x00) - sw t0,0(v0) - - /* Configure bank0 to 256 Mbit */ - DBG("Configure bank0 to 256 Mbit...\r\n") - li v0,0xb400044c - li t0,htoll(0x00004c69) - sw t0,0(v0) - - /* Config the SDRAM banks decode system */ - li v0,0xb400047c - li t0,htoll(2) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Write to address 0x2000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr12 */ - li v0,0xa2000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - bne t0,v0,_256MBIT - - /* Write to address 0x1000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate bank select1*/ - li v0,0xa0001000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_16MBIT - - /* Write to address 0x8000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit - device */ - li v0,0xa8000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_64MBIT - b _128MBIT - -_16MBIT: - DBG("16 Mbit SDRAM detected...\r\n") - /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(16) - sw t0,0(v0) - li t1,htoll(0x00000449) - b _DIMM1 - -_64MBIT: - DBG("64 Mbit SDRAM detected...\r\n") - /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(64) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _DIMM1 - -_128MBIT: - DBG("128 Mbit SDRAM detected...\r\n") - /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(128) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _DIMM1 - -_256MBIT: - DBG("256 Mbit SDRAM detected...\r\n") - /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000810 - li t0,htoll(256) - sw t0,0(v0) - li t1,htoll(0x00004c69) - b _DIMM1 - -_DIMM1: - li v0,0xb400044c - sw t1,0(v0) # Bank0 - sw t1,4(v0) # Bank1 - - /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM1 */ - /* Close banks 0 and 1 */ - li v0,0xb4000008 - li t0,htoll(0xff) - sw t0,0(v0) - - li v0,0xb4000010 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Set bank2`s range to: 0 - 0x10000000 (256 MByte) */ - li v0,0xb4000018 - li t0,htoll(0x0) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x7f) - sw t0,0(v0) - - /* Extend bank2 to 0x10000000 and Close bank0,1 and 3 */ - DBG("Extend bank2 to 0x10000000 and Close banks 0,1 and 3...\r\n") - li v0,0xb4000400 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000404 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0x00) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0xff) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x00) - sw t0,0(v0) - - /* Configure bank2 to 256 Mbit */ - DBG("Configure bank2 to 256 Mbit...\r\n") - li v0,0xb4000454 - li t0,htoll(0x00004c69) - sw t0,0(v0) - - /* Config the SDRAM banks decode system */ - li v0,0xb400047c - li t0,htoll(2) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /* Write to address 0x2000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr12 */ - li v0,0xa2000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - bne t0,v0,_256MBIT2 - - /* Write to address 0x1000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate bank select1*/ - li v0,0xa0001000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_16MBIT2 - - /* Write to address 0x8000000 and check if 0x00000000 is being written too */ - DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n") - li v0,0xa0000000 - li t1,0xa0000010 - li t0,htoll(0x0) -1: sw t0,0(v0) - addu v0,4 - bne t1,v0,1b - - /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit - device */ - li v0,0xa8000000 - li t0,0x11111111 - sw t0,0(v0) - li v0,0xa0000010 - li t1,0xa0000100 - li t0,0x22222222 -2: sw t0,0(v0) - addu v0,4 - bne t1,v0,2b - - DBG("Check address 0x00000000 for duplications...\r\n") - li t0,0xa0000000 - li v0,0x11111111 - lw t0,(t0) - beq t0,v0,_64MBIT2 - b _128MBIT2 - -_16MBIT2: - DBG("16 Mbit SDRAM detected...\r\n") - /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(16) - sw t0,0(v0) - li t1,htoll(0x00000449) - b _INIT_SDRAM - -_64MBIT2: - DBG("64 Mbit SDRAM detected...\r\n") - /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(64) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _INIT_SDRAM - -_128MBIT2: - DBG("128 Mbit SDRAM detected...\r\n") - /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(128) - sw t0,0(v0) - li t1,htoll(0x00000c69) - b _INIT_SDRAM - -_256MBIT2: - DBG("256 Mbit SDRAM detected...\r\n") - /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */ - li v0,0xb4000814 - li t0,htoll(256) - sw t0,0(v0) - li t1,htoll(0x00004c69) - b _INIT_SDRAM - -_INIT_SDRAM: - /* Restore defaults */ - DBG("Restoring defaults...\r\n") - li v0,0xb4000404 - li t0,htoll(0x07) - sw t0,0(v0) - li v0,0xb4000408 - li t0,htoll(0x08) - sw t0,0(v0) - li v0,0xb400040c - li t0,htoll(0x0f) - sw t0,0(v0) - li v0,0xb4000410 - li t0,htoll(0x10) - sw t0,0(v0) - li v0,0xb4000414 - li t0,htoll(0x17) - sw t0,0(v0) - li v0,0xb4000418 - li t0,htoll(0x18) - sw t0,0(v0) - li v0,0xb400041c - li t0,htoll(0x1f) - sw t0,0(v0) - li v0,0xb4000010 - li t0,htoll(0x07) - sw t0,0(v0) - li v0,0xb4000018 - li t0,htoll(0x008) - sw t0,0(v0) - li v0,0xb4000020 - li t0,htoll(0x0f) - sw t0,0(v0) - - li v0,0xb400044c - sw t1,8(v0) # Bank2 - sw t1,12(v0) # Bank3 - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa0800000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa1000000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x3) - sw t0,0(v0) - - li v0,0xa1800000 - li t0,0 - sw t0,0(v0) - - li v0,0xb4000474 - li t0,htoll(0x0) - sw t0,0(v0) - - /*********************************************************************/ - /************************* SDRAM initializing ************************/ - /******************************* END *********************************/ - - li p64011, PA_TO_KVA1(GT64011_BASE) - - li t0,htoll(0x00000000) /* RAS[1:0] low decode address */ - sw t0,0x008(p64011) - - li t0,htoll(0x00000007) /* RAS[1:0] high decode address */ - sw t0,0x010(p64011) - - li t0,htoll(0x00000000) /* RAS[0] Low decode address */ - sw t0,0x400(p64011) - - li t0,htoll(0x0000000f) /* RAS[0] High decode address */ - sw t0,0x404(p64011) - - li t0,htoll(0x00000008) /* RAS[3:2] low decode address */ - sw t0,0x018(p64011) - - li t0,htoll(0x0000000f) /* RAS[3:2] high decode address */ - sw t0,0x020(p64011) - - li t0,htoll(0x0000000f) /* RAS[1] Low Decode Address */ - sw t0,0x408(p64011) - - li t0,htoll(0x00000008) /* RAS[1] High Decode Address */ - sw t0,0x40c(p64011) - - li t0,htoll(0x00000010) /* RAS[2] Low Decode Address */ - sw t0,0x410(p64011) - - li t0,htoll(0x00000017) /* RAS[2] High Decode Address */ - sw t0,0x414(p64011) - - li t0,htoll(0x00000018) /* RAS[3] Low Decode Address */ - sw t0,0x418(p64011) - - li t0,htoll(0x0000001f) /* RAS[3] High Decode Address <<<<<< 1*/ - sw t0,0x41c(p64011) - -#ifdef DBGSBD -#define DREG(str,rname) \ - DBG(str); \ - DBG(":\t") ; \ - lw a0,rname(p64011) ; \ - HTOLL(a0,t0) ; \ - jal _dbghex ; \ - DBG("\r\n") - - DBG("GT-64120 settings:\r\n") - DREG("DRAMPAR_BANK0 (44c)",GT_DRAMPAR_BANK0) - DREG("DRAMPAR_BANK1 (450)",GT_DRAMPAR_BANK1) - DREG("DRAMPAR_BANK2 (454)",GT_DRAMPAR_BANK2) - DREG("DRAMPAR_BANK3 (458)",GT_DRAMPAR_BANK3) - DREG("PAS_RAS10LO (008)",GT_PAS_RAS10LO) - DREG("PAS_RAS10HI (010)",GT_PAS_RAS10HI) - DREG("PAS_RAS32LO (018)",GT_PAS_RAS32LO) - DREG("PAS_RAS32HI (020)",GT_PAS_RAS32HI) - DREG("DDAS_RAS0LO (400)",GT_DDAS_RAS0LO) - DREG("DDAS_RAS0HI (404)",GT_DDAS_RAS0HI) - DREG("DDAS_RAS1LO (408)",GT_DDAS_RAS1LO) - DREG("DDAS_RAS1HI (40c)",GT_DDAS_RAS1HI) - DREG("DDAS_RAS2LO (410)",GT_DDAS_RAS2LO) - DREG("DDAS_RAS2HI (414)",GT_DDAS_RAS2HI) - DREG("DDAS_RAS3LO (418)",GT_DDAS_RAS3LO) - DREG("DDAS_RAS3HI (41c)",GT_DDAS_RAS3HI) - DREG("GT_DRAM_CFG (448)",GT_DRAM_CFG) - DREG("GT_DEVPAR_BANK0 (45c)",GT_DEVPAR_BANK0) - DREG("GT_DEVPAR_BANK1 (460)",GT_DEVPAR_BANK1) - DREG("GT_DEVPAR_BANK2 (464)",GT_DEVPAR_BANK2) - DREG("GT_DEVPAR_BANK3 (468)",GT_DEVPAR_BANK3) - DREG("GT_IPCI_TOR (c04)",GT_IPCI_TOR) -#endif - - /* we can now initialise the caches for a fast clear_mem */ - SBD_DISPLAY ('C','A','C','H',CHKPNT_CACH) - DBG("init_cache\r\n") -// jal mips_init_cache - -.noinit: - - /* initialise tlb */ - SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB) - DBG("init_tlb\r\n") -// bal init_tlb - -// DBG("sbdreset completed\r\n") -// move ra,rasave - j GetExtendedMemorySize - nop - -END(sbdreset) - -LEAF(_sbd_memfail) - SBD_DISPLAY ('!','M','E','M',CHKPNT_0MEM) -1: b 1b - j ra -END(_sbd_memfail) - - .rdata -RefreshBits: - .word htoll(GT_DRAMPAR_Refresh512) - .word htoll(GT_DRAMPAR_Refresh1024) - .word htoll(GT_DRAMPAR_Refresh2048) - .word htoll(GT_DRAMPAR_Refresh4096) - .text - -/* DRAM: */ -#define GT_DRAM_CFG_INIT \ - GT_DRAM_CFG_RefIntCnt(160) | \ - GT_DRAM_CFG_StagRefOn | \ - GT_DRAM_CFG_ADSFunctDRAM | \ - GT_DRAM_CFG_DRAMLatchActive - -/* serial port: widest timings even 8 bit bus, latch enabled no parity */ -#define GT_DEVPAR_SERIALINIT \ - GT_DEVPAR_TurnOff(7) | \ - GT_DEVPAR_AccToFirst(15) | \ - GT_DEVPAR_AccToNext(15) | \ - GT_DEVPAR_ADStoWr(7) | \ - GT_DEVPAR_WrActive(7) | \ - GT_DEVPAR_WrHigh(7) | \ - GT_DEVPAR_DevWidth8 | \ - GT_DEVPAR_DevLocEven | \ - GT_DEVPAR_LatchFunctTransparent | \ - GT_DEVPAR_ParityDisable | \ - GT_DEVPAR_Reserved - -/* PCI: */ -#define GT_IPCI_TOR_INIT \ - GT_IPCI_TOR_Timeout0(255) | \ - GT_IPCI_TOR_Timeout1(255) | \ - GT_IPCI_TOR_RetryCtr(0) - -#define INIT(addr,val) \ - .word addr, val -#define GTINIT(addr,val) \ - INIT(PHYS_TO_K1(GT64011_BASE+(addr)), htoll(val)) - - .rdata -reginittab: - - /* disable ras1:0 and ras3:2 decodes */ - GTINIT(GT_PAS_RAS10LO, GT_PAS_LOMASK_Low); - GTINIT(GT_PAS_RAS10HI, 0); - GTINIT(GT_PAS_RAS32LO, GT_PAS_LOMASK_Low); - GTINIT(GT_PAS_RAS32HI, 0); - - /* disable RAS[0123] */ - GTINIT(GT_DDAS_RAS0LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS0HI, 0); - GTINIT(GT_DDAS_RAS1LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS1HI, 0); - GTINIT(GT_DDAS_RAS2LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS2HI, 0); - GTINIT(GT_DDAS_RAS3LO, GT_DDAS_LOMASK_Low) - GTINIT(GT_DDAS_RAS3HI, 0); - - /* 0x45c, 0x460, 0x464, 0x468 */ - /*GTINIT(GT_DEVPAR_BANK0, GT_DEVPAR_SERIALINIT)*/ - GTINIT(GT_DEVPAR_BANK0, 0x3847de60) - GTINIT(GT_DEVPAR_BANK1, 0x146fffff) - GTINIT(GT_DEVPAR_BANK2, 0x144fffff) - GTINIT(GT_DEVPAR_BANK3, 0x167fffff) - - GTINIT(GT_IPCI_TOR, GT_IPCI_TOR_INIT) - INIT(0,0) - .text - - .globl sbddelay - -LEAF(sbdberrenb) - mfc0 v0,C0_SR - li t0,SR_DE - bnez a0,1f - or t1,v0,t0 # disable cache/parity errors (SR_DE = 1) - b 2f -1: not t1,t0 # enable cache/parity errors (SR_DE = 0) - and t1,v0 -2: mtc0 t1,C0_SR - and v0,t0 # get old SR_DE bit - xor v0,t0 # and invert to make it an enable bit - j ra -END(sbdberrenb) - - -LEAF(sbdberrcnt) - move v0,zero - j ra -END(sbdberrcnt) - - .lcomm wbfltmp,4 - -LEAF(wbflush) -//XLEAF(mips_wbflush) - sync - la t0,wbfltmp - or t0,K1BASE - lw zero,0(t0) - j ra -END(wbflush) - - -LEAF(sbddelay) - li t1,CACHEUS - and t0,ra,0x20000000 - beqz t0,1f - li t1,ROMUS -1: mul a0,t1 - subu a0,15 # approx number of loops so far - - .set noreorder - .set nomacro - nop -2: bgtz a0,2b - subu a0,1 - .set macro - .set reorder - - j ra -END(sbddelay) - -#include "meminit.S" - - -LEAF(mips_cycle) - .set noreorder - .set nomacro -1: bgtz a0,1b - subu a0,1 - .set macro - .set reorder - j ra -END(mips_cycle) - -LEAF(init_ns16550_chan_b) - # enable 16550 fifo if it is there - li a0,NS16550_CHANB - li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4 - sb t0,FIFO(a0) - - /* convert baud rate in a1 into register value */ - li t2,NS16550_HZ/(16*115200) # brtc = CLK/16/speed - - li t0,CFCR_DLAB # select brtc divisor - sb t0,CFCR(a0) - sb t2,DATA(a0) # store divisor lsb - srl t2,8 - sb t2,IER(a0) # store divisor msb - - li t0,CFCR_8BITS # set 8N1 mode - sb t0,CFCR(a0) - - li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS - sb t0,MCR(a0) - li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!) - sb t0,IER(a0) - - move v0,zero # indicate success - j ra - -END(init_ns16550_chan_b) - -LEAF(init_ns16550_chan_a) - # enable 16550 fifo if it is there - li a0,NS16550_CHANA - li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4 - sb t0,FIFO(a0) - - /* convert baud rate in a1 into register value */ - li t2,NS16550_HZ/(16*9600) # brtc = CLK/16/speed - - li t0,CFCR_DLAB # select brtc divisor - sb t0,CFCR(a0) - sb t2,DATA(a0) # store divisor lsb - srl t2,8 - sb t2,IER(a0) # store divisor msb - - li t0,CFCR_8BITS # set 8N1 mode - sb t0,CFCR(a0) - - li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS - sb t0,MCR(a0) - li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!) - sb t0,IER(a0) - - move v0,zero # indicate success - j ra - -END(init_ns16550_chan_a) - -#endif /* EVB64120A */ diff -urN linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/xfer.c linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/xfer.c --- linux-2.4.24/arch/mips/galileo-boards/ev64120/compressed/xfer.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev64120/compressed/xfer.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,114 +0,0 @@ -/* - * arch/mips/galileo/compressed/xfer.c - * - * By RidgeRun Inc, - * - * Xfer an image from flash to ram. - * For use with Galileo EVB64120A MIPS eval board. - */ - -#include "linux/serial_reg.h" - -#define port 0xbd000000 -#define inb(addr) (*(volatile unsigned char *) ((unsigned long)(addr))) -#define outb(b,addr) (*(volatile unsigned char *) ((unsigned long)(addr)) = (b)) - -#ifdef RUNNINGFROMFLASH -// This is where our image of interest is mapped to -// when the jumbers are set for booting out of flash. -// (flash part starts at address 0xbfC00000) -#define srcAddr 0xbfC20000 -#else -// This is where our image of interest is mapped to -// when the jumbers are set for booting out of eprom. -// (flash part starts at address 0xbf000000) -#define srcAddr 0xbf020000 -#endif - -static int PortAddress(unsigned int channel, unsigned char reg); -static void inline cons_hook(void); -static void print_message(const char *string); - -/****************************** - Routine: - Description: - ******************************/ -void XferToRam(void) -{ - unsigned int temp; - void (*entry_point) (void); - - cons_hook(); - - print_message("Copying image from Flash to Ram.\n"); - for (temp = 0; temp < (0x100000 - 0x20000); temp = temp + 4) { - *(volatile unsigned int *) (temp + 0xa0400000) = - *(volatile unsigned int *) (temp + srcAddr); - if (*(volatile unsigned int *) (temp + 0xa0400000) != - *(volatile unsigned int *) (temp + srcAddr)) { - print_message - ("Error!: copy verification failed.\n"); - break; - } - } - - print_message("Now jumping to the code just xferred to ram.\n"); - entry_point = (void *) 0x80400000; - entry_point(); -} - -/****************************** - Routine: - Description: - ******************************/ -static int PortAddress(unsigned int channel, unsigned char reg) -{ - unsigned int channelOffset = 0x20; - unsigned int regDelta = 4; - return (port + (channel * channelOffset) + (reg * regDelta)); -} - -/****************************** - Routine: - Description: - ******************************/ -static void cons_hook(void) -{ - register int comstat; - unsigned temp; - unsigned int channel = 1; // Channel 1 is the main serial - // connector of the EVB64120A. Channel 0 - // is the secondary serial port (typically - // the unsoldered connector of the board). - - temp = *(unsigned int *) 0xb4000464; - *(unsigned int *) 0xb4000464 = 0xffff4f14; - - // Set Baud Rate, baud=115K - outb(0x83, PortAddress(channel, UART_LCR)); - outb(0x00, PortAddress(channel, UART_DLM)); - outb(0x02, PortAddress(channel, UART_DLL)); - outb(0x03, PortAddress(channel, UART_LCR)); - - comstat = inb(PortAddress(channel, UART_LSR)); - comstat = inb(PortAddress(channel, UART_RX)); - outb(0x00, PortAddress(channel, UART_IER)); -} - -/****************************** - Routine: - Description: - ******************************/ -static void print_message(const char *string) -{ - register int count, loop; - /* Display Opening Message */ - for (count = 0; string[count]; count++) { - if (string[count] == '\n') { - *(char *) 0xbd000020 = '\r'; - } - *(char *) 0xbd000020 = string[count]; - for (loop = 0; loop < 2000; loop++) { - } - } -} diff -urN linux-2.4.24/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.25/arch/mips/galileo-boards/ev96100/setup.c --- linux-2.4.24/arch/mips/galileo-boards/ev96100/setup.c 2003-08-25 04:44:39.000000000 -0700 +++ linux-2.4.25/arch/mips/galileo-boards/ev96100/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -50,11 +50,6 @@ #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - extern char * __init prom_getcmdline(void); extern void mips_reboot_setup(void); diff -urN linux-2.4.24/arch/mips/ite-boards/generic/it8172_setup.c linux-2.4.25/arch/mips/ite-boards/generic/it8172_setup.c --- linux-2.4.24/arch/mips/ite-boards/generic/it8172_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/ite-boards/generic/it8172_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -48,11 +48,6 @@ #include #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - extern struct resource ioport_resource; #ifdef CONFIG_BLK_DEV_IDE extern struct ide_ops std_ide_ops; diff -urN linux-2.4.24/arch/mips/ite-boards/generic/time.c linux-2.4.25/arch/mips/ite-boards/generic/time.c --- linux-2.4.24/arch/mips/ite-boards/generic/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/ite-boards/generic/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -114,7 +114,7 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ -extern unsigned int mips_counter_frequency; +extern unsigned int mips_hpt_frequency; /* * Figure out the r4k offset, the amount to increment the compare @@ -138,12 +138,12 @@ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_c0_count(); + mips_hpt_frequency = read_c0_count(); /* restore interrupts */ local_irq_restore(flags); - return (mips_counter_frequency / HZ); + return (mips_hpt_frequency / HZ); } static unsigned long diff -urN linux-2.4.24/arch/mips/jazz/jazzdma.c linux-2.4.25/arch/mips/jazz/jazzdma.c --- linux-2.4.24/arch/mips/jazz/jazzdma.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.25/arch/mips/jazz/jazzdma.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ */ #define CONF_DEBUG_VDMA 0 +static spinlock_t jazz_dma_lock = SPIN_LOCK_UNLOCKED; + static unsigned long vdma_pagetable_start; /* @@ -42,10 +45,9 @@ */ static inline void vdma_pgtbl_init(void) { - int i; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; unsigned long paddr = 0; - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int i; for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) { pgtbl[i].frame = paddr; @@ -88,15 +90,9 @@ */ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) { - VDMA_PGTBL_ENTRY *entry = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; - int first; - int last; - int pages; - unsigned int frame; - unsigned long laddr; - int i; - unsigned long flags; + VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int first, last, pages, frame, i; + unsigned long laddr, flags; /* check arguments */ @@ -112,7 +108,8 @@ return VDMA_ERROR; /* invalid physical address */ } - save_and_cli(flags); + spin_lock_saveirq(&jazz_dma_lock, flags); + /* * Find free chunk */ @@ -121,8 +118,9 @@ while (1) { while (entry[first].owner != VDMA_PAGE_EMPTY && first < VDMA_PGTBL_ENTRIES) first++; - if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */ - restore_flags(flags); + if (first + pages > VDMA_PGTBL_ENTRIES) { + /* nothing free */ + spin_unlock_restoreirq(&jazz_dma_lock, flags); return VDMA_ERROR; } @@ -153,8 +151,7 @@ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); if (vdma_debug > 1) - printk - ("vdma_alloc: Allocated %d pages starting from %08lx\n", + printk("vdma_alloc: Allocated %d pages starting from %08lx\n", pages, laddr); if (vdma_debug > 2) { @@ -170,7 +167,8 @@ printk("\n"); } - restore_flags(flags); + spin_unlock_restoreirq(&jazz_dma_lock, flags); + return laddr; } @@ -181,8 +179,7 @@ */ int vdma_free(unsigned long laddr) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; int i; i = laddr >> 12; @@ -213,27 +210,23 @@ int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; int first, pages, npages; if (laddr > 0xffffff) { if (vdma_debug) - printk - ("vdma_map: Invalid logical address: %08lx\n", + printk("vdma_map: Invalid logical address: %08lx\n", laddr); return -EINVAL; /* invalid logical address */ } if (paddr > 0x1fffffff) { if (vdma_debug) - printk - ("vdma_map: Invalid physical address: %08lx\n", + printk("vdma_map: Invalid physical address: %08lx\n", paddr); return -EINVAL; /* invalid physical address */ } - npages = pages = - (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; + npages = pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; first = laddr >> 12; if (vdma_debug) printk("vdma_remap: first=%x, pages=%x\n", first, pages); @@ -287,10 +280,8 @@ */ unsigned long vdma_phys2log(unsigned long paddr) { - int i; - int frame; - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + int frame, i; frame = paddr & ~(VDMA_PAGESIZE - 1); @@ -310,8 +301,7 @@ */ unsigned long vdma_log2phys(unsigned long laddr) { - VDMA_PGTBL_ENTRY *pgtbl = - (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; + VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1)); } @@ -347,9 +337,8 @@ printk("\n"); printk("vdma_chnl_enables: "); for (i = 0; i < 8; i++) - printk("%04x ", - (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + - (i << 5))); + printk("%04x ", r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + + (i << 5))); printk("\n"); } @@ -399,8 +388,7 @@ void vdma_disable(int channel) { if (vdma_debug) { - int status = - r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + + int status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5)); printk("vdma_disable: channel %d\n", channel); diff -urN linux-2.4.24/arch/mips/jmr3927/common/Makefile linux-2.4.25/arch/mips/jmr3927/common/Makefile --- linux-2.4.24/arch/mips/jmr3927/common/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/jmr3927/common/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -10,6 +10,6 @@ O_TARGET:= tx3927.o -obj-y += prom.o puts.o rtc_ds1742.o +obj-y += prom.o puts.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/jmr3927/common/rtc_ds1742.c linux-2.4.25/arch/mips/jmr3927/common/rtc_ds1742.c --- linux-2.4.24/arch/mips/jmr3927/common/rtc_ds1742.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/jmr3927/common/rtc_ds1742.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,173 +0,0 @@ -/*********************************************************************** - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * arch/mips/jmr3927/common/rtc_ds1742.c - * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c - * low-level RTC hookups for s for Dallas 1742 chip. - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - *********************************************************************** - */ - - -/* - * This file exports a function, rtc_ds1386_init(), which expects an - * uncached base address as the argument. It will set the two function - * pointers expected by the MIPS generic timer code. - */ - -#include -#include -#include - -#include -#include - -#include -#include - -#define EPOCH 2000 - -#undef BCD_TO_BIN -#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) - -#undef BIN_TO_BCD -#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) - -static unsigned long rtc_base; - -static unsigned long -rtc_ds1742_get_time(void) -{ - unsigned int year, month, day, hour, minute, second; - unsigned int century; - - CMOS_WRITE(RTC_READ, RTC_CONTROL); - second = BCD_TO_BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - minute = BCD_TO_BIN(CMOS_READ(RTC_MINUTES)); - hour = BCD_TO_BIN(CMOS_READ(RTC_HOURS)); - day = BCD_TO_BIN(CMOS_READ(RTC_DATE)); - month = BCD_TO_BIN(CMOS_READ(RTC_MONTH)); - year = BCD_TO_BIN(CMOS_READ(RTC_YEAR)); - century = BCD_TO_BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); - CMOS_WRITE(0, RTC_CONTROL); - - year += century * 100; - - return mktime(year, month, day, hour, minute, second); -} -extern void to_tm(unsigned long tim, struct rtc_time * tm); - -static int -rtc_ds1742_set_time(unsigned long t) -{ - struct rtc_time tm; - u8 year, month, day, hour, minute, second; - u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; - int cmos_century; - - CMOS_WRITE(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - cmos_minute = (u8)CMOS_READ(RTC_MINUTES); - cmos_hour = (u8)CMOS_READ(RTC_HOURS); - cmos_day = (u8)CMOS_READ(RTC_DATE); - cmos_month = (u8)CMOS_READ(RTC_MONTH); - cmos_year = (u8)CMOS_READ(RTC_YEAR); - cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; - - CMOS_WRITE(RTC_WRITE, RTC_CONTROL); - - /* convert */ - to_tm(t, &tm); - - /* check each field one by one */ - year = BIN_TO_BCD(tm.tm_year - EPOCH); - if (year != cmos_year) { - CMOS_WRITE(year,RTC_YEAR); - } - - month = BIN_TO_BCD(tm.tm_mon); - if (month != (cmos_month & 0x1f)) { - CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); - } - - day = BIN_TO_BCD(tm.tm_mday); - if (day != cmos_day) { - - CMOS_WRITE(day, RTC_DATE); - } - - if (cmos_hour & 0x40) { - /* 12 hour format */ - hour = 0x40; - if (tm.tm_hour > 12) { - hour |= 0x20 | (BIN_TO_BCD(hour-12) & 0x1f); - } else { - hour |= BIN_TO_BCD(tm.tm_hour); - } - } else { - /* 24 hour format */ - hour = BIN_TO_BCD(tm.tm_hour) & 0x3f; - } - if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); - - minute = BIN_TO_BCD(tm.tm_min); - if (minute != cmos_minute) { - CMOS_WRITE(minute, RTC_MINUTES); - } - - second = BIN_TO_BCD(tm.tm_sec); - if (second != cmos_second) { - CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); - } - - /* RTC_CENTURY and RTC_CONTROL share same address... */ - CMOS_WRITE(cmos_century, RTC_CONTROL); - - return 0; -} - -void -rtc_ds1742_init(unsigned long base) -{ - u8 cmos_second; - - /* remember the base */ - rtc_base = base; - db_assert((rtc_base & 0xe0000000) == KSEG1); - - /* set the function pointers */ - rtc_get_time = rtc_ds1742_get_time; - rtc_set_time = rtc_ds1742_set_time; - - /* clear oscillator stop bit */ - CMOS_WRITE(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); - CMOS_WRITE(RTC_WRITE, RTC_CONTROL); - CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ - CMOS_WRITE(0, RTC_CONTROL); -} diff -urN linux-2.4.24/arch/mips/jmr3927/rbhma3100/rtc.c linux-2.4.25/arch/mips/jmr3927/rbhma3100/rtc.c --- linux-2.4.24/arch/mips/jmr3927/rbhma3100/rtc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/jmr3927/rbhma3100/rtc.c 2004-02-18 05:36:30.000000000 -0800 @@ -31,17 +31,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include /* bad name... */ -#include +#include static unsigned char jmr3927_rtc_read_data(unsigned long addr) { - return jmr3927_nvram_in(addr); + return readb(addr); } static void jmr3927_rtc_write_data(unsigned char data, unsigned long addr) { - jmr3927_nvram_out(data, addr); + writeb(data, addr); } static int jmr3927_rtc_bcd_mode(void) diff -urN linux-2.4.24/arch/mips/kernel/Makefile linux-2.4.25/arch/mips/kernel/Makefile --- linux-2.4.24/arch/mips/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -12,7 +12,7 @@ O_TARGET := kernel.o -export-objs = irq.o mips_ksyms.o pci-dma.o setup.o smp.o +export-objs = irq.o mips_ksyms.o pci-dma.o setup.o semaphore.o smp.o obj-y += branch.o cpu-probe.o irq.o process.o signal.o entry.o \ traps.o ptrace.o reset.o semaphore.o setup.o syscall.o \ @@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o diff -urN linux-2.4.24/arch/mips/kernel/cpu-probe.c linux-2.4.25/arch/mips/kernel/cpu-probe.c --- linux-2.4.24/arch/mips/kernel/cpu-probe.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/cpu-probe.c 2004-02-18 05:36:30.000000000 -0800 @@ -34,6 +34,12 @@ ".set\tmips0"); } +/* The Au1xxx wait is available only if we run CONFIG_PM and + * the timer setup found we had a 32KHz counter available. + * There are still problems with functions that may call au1k_wait + * directly, but that will be discovered pretty quickly. + */ +extern void (*au1k_wait_ptr)(void); void au1k_wait(void) { #ifdef CONFIG_PM @@ -75,21 +81,31 @@ case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: +/* case CPU_RM9000: */ case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: case CPU_5KC: /* case CPU_20KC:*/ + case CPU_24K: + case CPU_25KF: cpu_wait = r4k_wait; printk(" available.\n"); break; +#ifdef CONFIG_PM case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: - cpu_wait = au1k_wait; - printk(" available.\n"); + if (au1k_wait_ptr != NULL) { + cpu_wait = au1k_wait_ptr; + printk(" available.\n"); + } + else { + printk(" unavailable.\n"); + } break; +#endif default: printk(" unavailable.\n"); break; @@ -146,350 +162,415 @@ } #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ - | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) + | MIPS_CPU_COUNTER) -__init void cpu_probe(void) +static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { - struct cpuinfo_mips *c = ¤t_cpu_data; - unsigned long config0 = read_c0_config(); - unsigned long config1; - - c->processor_id = PRID_IMP_UNKNOWN; - c->fpu_id = FPIR_IMP_NONE; - c->cputype = CPU_UNKNOWN; - - if (config0 & (1 << 31)) { - /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_LLSC; - config1 = read_c0_config1(); - if (config1 & (1 << 3)) - c->options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - c->options |= MIPS_CPU_MIPS16; - if (config1 & (1 << 1)) - c->options |= MIPS_CPU_EJTAG; - if (config1 & 1) { + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) c->options |= MIPS_CPU_FPU; - c->options |= MIPS_CPU_32FPR; - } - c->scache.flags = MIPS_CACHE_NOT_PRESENT; - - c->tlbsize = ((config1 >> 25) & 0x3f) + 1; - } - - c->processor_id = read_c0_prid(); - switch (c->processor_id & 0xff0000) { - case PRID_COMP_LEGACY: - switch (c->processor_id & 0xff00) { - case PRID_IMP_R2000: - c->cputype = CPU_R2000; - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | - MIPS_CPU_LLSC; - if (__cpu_has_fpu()) - c->options |= MIPS_CPU_FPU; - c->tlbsize = 64; + c->tlbsize = 64; + break; + case PRID_IMP_R3000: + if ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else + c->cputype = CPU_R3000A; + else + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R4000: + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_VR41XX: + switch (c->processor_id & 0xf0) { +#ifndef CONFIG_VR4181 + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; break; - case PRID_IMP_R3000: - if ((c->processor_id & 0xff) == PRID_REV_R3000A) - if (cpu_has_confreg()) - c->cputype = CPU_R3081E; - else - c->cputype = CPU_R3000A; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; + break; +#endif + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; + break; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; else - c->cputype = CPU_R3000; - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | - MIPS_CPU_LLSC; - if (__cpu_has_fpu()) - c->options |= MIPS_CPU_FPU; - c->tlbsize = 64; + c->cputype = CPU_VR4181A; break; - case PRID_IMP_R4000: - if ((c->processor_id & 0xff) >= PRID_REV_R4400) - c->cputype = CPU_R4400SC; + case PRID_REV_VR4130: + if ((c->processor_id & 0xf) < 0x4) + c->cputype = CPU_VR4131; else - c->cputype = CPU_R4000SC; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_VCE | - MIPS_CPU_LLSC; - c->tlbsize = 48; + c->cputype = CPU_VR4133; break; - case PRID_IMP_VR41XX: - switch (c->processor_id & 0xf0) { -#ifndef CONFIG_VR4181 - case PRID_REV_VR4111: - c->cputype = CPU_VR4111; - break; -#else - case PRID_REV_VR4181: - c->cputype = CPU_VR4181; - break; -#endif - case PRID_REV_VR4121: - c->cputype = CPU_VR4121; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; break; - case PRID_REV_VR4122: - if ((c->processor_id & 0xf) < 0x3) - c->cputype = CPU_VR4122; - else - c->cputype = CPU_VR4181A; + } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; + break; + case PRID_IMP_R4300: + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R4600: + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #if 0 + case PRID_IMP_R4650: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #endif + case PRID_IMP_TX39: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; - case PRID_REV_VR4131: - c->cputype = CPU_VR4131; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - c->cputype = CPU_VR41XX; + c->cputype = CPU_UNKNOWN; break; } - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS; - c->tlbsize = 32; - break; - case PRID_IMP_R4300: - c->cputype = CPU_R4300; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R4600: - c->cputype = CPU_R4600; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - #if 0 - case PRID_IMP_R4650: - /* - * This processor doesn't have an MMU, so it's not - * "real easy" to run Linux on it. It is left purely - * for documentation. Commented out because it shares - * it's c0_prid id number with the TX3900. - */ - c->cputype = CPU_R4650; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - #endif - case PRID_IMP_TX39: - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB; - - if ((c->processor_id & 0xf0) == - (PRID_REV_TX3927 & 0xf0)) { - c->cputype = CPU_TX3927; - c->tlbsize = 64; - } else { - switch (c->processor_id & 0xff) { - case PRID_REV_TX3912: - c->cputype = CPU_TX3912; - c->tlbsize = 32; - break; - case PRID_REV_TX3922: - c->cputype = CPU_TX3922; - c->tlbsize = 64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } - } - break; - case PRID_IMP_R4700: - c->cputype = CPU_R4700; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_TX49: - c->cputype = CPU_TX49XX; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R5000: - c->cputype = CPU_R5000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R5432: - c->cputype = CPU_R5432; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R5500: - c->cputype = CPU_R5500; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_NEVADA: - c->cputype = CPU_NEVADA; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_DIVEC | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R6000: - c->cputype = CPU_R6000; - c->isa_level = MIPS_CPU_ISA_II; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R6000A: - c->cputype = CPU_R6000A; - c->isa_level = MIPS_CPU_ISA_II; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_RM7000: - c->cputype = CPU_RM7000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - /* - * Undocumented RM7000: Bit 29 in the info register of - * the RM7000 v2.0 indicates if the TLB has 48 or 64 - * entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ - c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; - break; - case PRID_IMP_R8000: - c->cputype = CPU_R8000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ - break; - case PRID_IMP_R10000: - c->cputype = CPU_R10000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; - c->tlbsize = 64; - break; - case PRID_IMP_R12000: - c->cputype = CPU_R12000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; - c->tlbsize = 64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; } break; - case PRID_COMP_MIPS: - switch (c->processor_id & 0xff00) { - case PRID_IMP_4KC: - c->cputype = CPU_4KC; - c->isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KEC: - c->cputype = CPU_4KEC; - c->isa_level = MIPS_CPU_ISA_M32; + case PRID_IMP_R4700: + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_TX49: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_LLSC; + if (!(c->processor_id & 0x08)) + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5432: + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5500: + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_NEVADA: + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R6000: + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R6000A: + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_RM7000: + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Undocumented RM7000: Bit 29 in the info register of + * the RM7000 v2.0 indicates if the TLB has 48 or 64 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_RM9000: + c->cputype = CPU_RM9000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Bit 29 in the info register of the RM9000 + * indicates if the TLB has 48 or 64 entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ + break; + case PRID_IMP_R10000: + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + case PRID_IMP_R12000: + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void decode_config1(struct cpuinfo_mips *c) +{ + unsigned long config0 = read_c0_config(); + unsigned long config1; + + if ((config0 & (1 << 31)) == 0) + return; /* actually wort a panic() */ + + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); + if (config1 & (1 << 3)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; +} + +static inline void cpu_probe_mips(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_24K: + c->cputype = CPU_24K; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_25KF: + c->cputype = CPU_25KF; + c->isa_level = MIPS_CPU_ISA_M64; + /* Probe for L2 cache */ + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; break; - case PRID_IMP_4KSC: - c->cputype = CPU_4KSC; - c->isa_level = MIPS_CPU_ISA_M32; + case 1: + c->cputype = CPU_AU1500; break; - case PRID_IMP_5KC: - c->cputype = CPU_5KC; - c->isa_level = MIPS_CPU_ISA_M64; + case 2: + c->cputype = CPU_AU1100; break; - case PRID_IMP_20KC: - c->cputype = CPU_20KC; - c->isa_level = MIPS_CPU_ISA_M64; + case 3: + c->cputype = CPU_AU1550; break; default: - c->cputype = CPU_UNKNOWN; + panic("Unknown Au Core!"); break; } + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + /* FPU in pass1 is known to have issues. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); + break; + case PRID_COMP_MIPS: + cpu_probe_mips(c); break; case PRID_COMP_ALCHEMY: - switch (c->processor_id & 0xff00) { - case PRID_IMP_AU1_REV1: - case PRID_IMP_AU1_REV2: - switch ((c->processor_id >> 24) & 0xff) { - case 0: - c->cputype = CPU_AU1000; - break; - case 1: - c->cputype = CPU_AU1500; - break; - case 2: - c->cputype = CPU_AU1100; - break; - default: - panic("Unknown Au Core!"); - break; - } - c->isa_level = MIPS_CPU_ISA_M32; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } + cpu_probe_alchemy(c); break; case PRID_COMP_SIBYTE: - switch (c->processor_id & 0xff00) { - case PRID_IMP_SB1: - c->cputype = CPU_SB1; - c->isa_level = MIPS_CPU_ISA_M64; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; -#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - /* FPU in pass1 is known to have issues. */ - c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; -#endif - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } + cpu_probe_sibyte(c); break; case PRID_COMP_SANDCRAFT: - switch (c->processor_id & 0xff00) { - case PRID_IMP_SR71000: - c->cputype = CPU_SR71000; - c->isa_level = MIPS_CPU_ISA_M64; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_FPU | - MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; - c->scache.ways = 8; - c->tlbsize = 64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } + cpu_probe_sandcraft(c); break; default: c->cputype = CPU_UNKNOWN; diff -urN linux-2.4.24/arch/mips/kernel/gdb-stub.c linux-2.4.25/arch/mips/kernel/gdb-stub.c --- linux-2.4.24/arch/mips/kernel/gdb-stub.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/gdb-stub.c 2004-02-18 05:36:30.000000000 -0800 @@ -966,7 +966,7 @@ __asm__ __volatile__( ".globl breakinst\n\t" ".set\tnoreorder\n\t" - "nop\n\t" + "nop\n" "breakinst:\tbreak\n\t" "nop\n\t" ".set\treorder" @@ -979,7 +979,7 @@ __asm__ __volatile__( ".globl async_breakinst\n\t" ".set\tnoreorder\n\t" - "nop\n\t" + "nop\n" "async_breakinst:\tbreak\n\t" "nop\n\t" ".set\treorder" diff -urN linux-2.4.24/arch/mips/kernel/head.S linux-2.4.25/arch/mips/kernel/head.S --- linux-2.4.24/arch/mips/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/head.S 2004-02-18 05:36:30.000000000 -0800 @@ -160,14 +160,7 @@ .set noreorder /* - * Stack for kernel and init, current variable - */ - la $28, init_task_union - addiu t0, $28, KERNEL_STACK_SIZE-32 - subu sp, t0, 4*SZREG - - sw t0, kernelsp - /* The firmware/bootloader passes argc/argp/envp + * The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because * the romvec and other important info is stored there * by prom_init(). @@ -180,6 +173,14 @@ bne t0, t1, 1b sw zero, (t0) + /* + * Stack for kernel and init, current variable + */ + la $28, init_task_union + addiu t0, $28, KERNEL_STACK_SIZE-32 + subu sp, t0, 4*SZREG + sw t0, kernelsp + jal init_arch nop END(kernel_entry) @@ -197,7 +198,7 @@ mtc0 zero, CP0_WIRED CLI mfc0 t0, CP0_STATUS - li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX) + li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_UX) and t0, t1 or t0, (ST0_CU0); jal start_secondary diff -urN linux-2.4.24/arch/mips/kernel/ipc.c linux-2.4.25/arch/mips/kernel/ipc.c --- linux-2.4.24/arch/mips/kernel/ipc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/ipc.c 2004-02-18 05:36:30.000000000 -0800 @@ -32,7 +32,11 @@ switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + return sys_semtimedop (first, (struct sembuf *)ptr, second, + NULL); + case SEMTIMEDOP: + return sys_semtimedop (first, (struct sembuf *)ptr, second, + (const struct timespec *)fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { diff -urN linux-2.4.24/arch/mips/kernel/irixsig.c linux-2.4.25/arch/mips/kernel/irixsig.c --- linux-2.4.24/arch/mips/kernel/irixsig.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/irixsig.c 2004-02-18 05:36:30.000000000 -0800 @@ -676,49 +676,53 @@ continue; flag = 1; switch (p->state) { - case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & (W_TRAPPED|W_STOPPED)) && - !(p->ptrace & PT_PTRACED)) - continue; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(0, &info->code); - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); - p->exit_code = 0; - retval = 0; - goto end_waitsys; - case TASK_ZOMBIE: - current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; - current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(1, &info->code); /* CLD_EXITED */ - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, - &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, - &info->stuff.procinfo.procdata.child.stime); - retval = 0; - if (p->p_opptr != p->p_pptr) { - REMOVE_LINKS(p); - p->p_pptr = p->p_opptr; - SET_LINKS(p); - notify_parent(p, SIGCHLD); - } else - release_task(p); - goto end_waitsys; - default: + case TASK_STOPPED: + if (!p->exit_code) continue; + if (!(options & (W_TRAPPED|W_STOPPED)) && + !(p->ptrace & PT_PTRACED)) + continue; + read_unlock(&tasklist_lock); + if (ru != NULL) + getrusage(p, RUSAGE_BOTH, ru); + __put_user(SIGCHLD, &info->sig); + __put_user(0, &info->code); + __put_user(p->pid, &info->stuff.procinfo.pid); + __put_user((p->exit_code >> 8) & 0xff, + &info->stuff.procinfo.procdata.child.status); + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); + p->exit_code = 0; + retval = 0; + goto end_waitsys; + case TASK_ZOMBIE: + current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; + current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; + read_unlock(&tasklist_lock); + if (ru != NULL) + getrusage(p, RUSAGE_BOTH, ru); + __put_user(SIGCHLD, &info->sig); + __put_user(1, &info->code); /* CLD_EXITED */ + __put_user(p->pid, &info->stuff.procinfo.pid); + __put_user((p->exit_code >> 8) & 0xff, + &info->stuff.procinfo.procdata.child.status); + __put_user(p->times.tms_utime, + &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, + &info->stuff.procinfo.procdata.child.stime); + retval = 0; + if (p->p_opptr != p->p_pptr) { + write_lock_irq(&tasklist_lock); + REMOVE_LINKS(p); + p->p_pptr = p->p_opptr; + SET_LINKS(p); + notify_parent(p, SIGCHLD); + write_unlock_irq(&tasklist_lock); + } else + release_task(p); + goto end_waitsys; + default: + continue; } } read_unlock(&tasklist_lock); diff -urN linux-2.4.24/arch/mips/kernel/irq.c linux-2.4.25/arch/mips/kernel/irq.c --- linux-2.4.24/arch/mips/kernel/irq.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/mips/kernel/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -916,8 +916,8 @@ return -EFAULT; /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + * Parse the first HEX_DIGITS characters as a hex string, any non-hex + * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ value = 0; diff -urN linux-2.4.24/arch/mips/kernel/mips_ksyms.c linux-2.4.25/arch/mips/kernel/mips_ksyms.c --- linux-2.4.24/arch/mips/kernel/mips_ksyms.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/mips_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -62,7 +62,7 @@ EXPORT_SYMBOL_NOVERS(strstr); EXPORT_SYMBOL_NOVERS(strtok); -EXPORT_SYMBOL(_clear_page); +EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(kernel_thread); /* @@ -89,14 +89,6 @@ EXPORT_SYMBOL(invalid_pte_table); /* - * Semaphore stuff - */ -EXPORT_SYMBOL(__down); -EXPORT_SYMBOL(__down_interruptible); -EXPORT_SYMBOL(__down_trylock); -EXPORT_SYMBOL(__up); - -/* * Kernel hacking ... */ #include diff -urN linux-2.4.24/arch/mips/kernel/proc.c linux-2.4.25/arch/mips/kernel/proc.c --- linux-2.4.24/arch/mips/kernel/proc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/proc.c 2004-02-18 05:36:30.000000000 -0800 @@ -39,6 +39,7 @@ [CPU_R6000A] "R6000A", [CPU_R8000] "R8000", [CPU_R10000] "R10000", + [CPU_R12000] "R12000", [CPU_R4300] "R4300", [CPU_R4650] "R4650", [CPU_R4700] "R4700", @@ -47,6 +48,7 @@ [CPU_R4640] "R4640", [CPU_NEVADA] "Nevada", [CPU_RM7000] "RM7000", + [CPU_RM9000] "RM9000", [CPU_R5432] "R5432", [CPU_4KC] "MIPS 4Kc", [CPU_5KC] "MIPS 5Kc", @@ -63,10 +65,13 @@ [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", [CPU_20KC] "MIPS 20Kc", + [CPU_24K] "MIPS 24K", + [CPU_25KF] "MIPS 25Kf", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", + [CPU_VR4133] "NEC VR4133", [CPU_VR4181] "NEC VR4181", [CPU_VR4181A] "NEC VR4181A", [CPU_SR71000] "Sandcraft SR71000" diff -urN linux-2.4.24/arch/mips/kernel/scall_o32.S linux-2.4.25/arch/mips/kernel/scall_o32.S --- linux-2.4.24/arch/mips/kernel/scall_o32.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/kernel/scall_o32.S 2004-02-18 05:36:30.000000000 -0800 @@ -18,7 +18,7 @@ #include /* Highest syscall used of any syscall flavour */ -#define MAX_SYSCALL_NO __NR_Linux + __NR_Linux_syscalls +#define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls .align 5 NESTED(handle_sys, PT_SIZE, sp) @@ -309,7 +309,7 @@ LEAF(sys_syscall) lw t0, PT_R29(sp) # user sp - sltu v0, a0, __NR_Linux + __NR_Linux_syscalls + 1 + sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 beqz v0, enosys sll v0, a0, 2 diff -urN linux-2.4.24/arch/mips/kernel/semaphore.c linux-2.4.25/arch/mips/kernel/semaphore.c --- linux-2.4.24/arch/mips/kernel/semaphore.c 2001-04-17 17:19:25.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/semaphore.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,129 +1,272 @@ /* - * Generic semaphore code. Buyer beware. Do your own - * specific changes in + * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * + * Heavily inspired by the Alpha implementation */ - +#include +#include +#include #include -#include + +#ifdef CONFIG_CPU_HAS_LLDSCD +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(semaphore_lock); +#endif /* - * Semaphores are implemented using a two-way counter: - * The "count" variable is decremented for each process - * that tries to sleep, while the "waking" variable is - * incremented when the "up()" code goes to wake up waiting - * processes. - * - * Notably, the inline "up()" and "down()" functions can - * efficiently test if they need to do any extra work (up - * needs to do something only if count was negative before - * the increment operation. - * - * waking_non_zero() (from asm/semaphore.h) must execute - * atomically. - * - * When __up() is called, the count was negative before - * incrementing it, and we need to wake up somebody. - * - * This routine adds one to the count of processes that need to - * wake up and exit. ALL waiting processes actually wake up but - * only the one that gets to the "waking" field first will gate - * through and acquire the semaphore. The others will go back - * to sleep. - * - * Note that these functions are only called when there is - * contention on the lock, and as such all this is the - * "non-critical" part of the whole semaphore business. The - * critical part is the inline stuff in - * where we want to avoid any extra jumps and calls. + * Semaphores are implemented using a two-way counter: The "count" variable is + * decremented for each process that tries to sleep, while the "waking" variable + * is incremented when the "up()" code goes to wake up waiting processes. + * + * Notably, the inline "up()" and "down()" functions can efficiently test if + * they need to do any extra work (up needs to do something only if count was + * negative before the increment operation. + * + * waking_non_zero() must execute atomically. + * + * When __up() is called, the count was negative before incrementing it, and we + * need to wake up somebody. + * + * This routine adds one to the count of processes that need to wake up and + * exit. ALL waiting processes actually wake up but only the one that gets to + * the "waking" field first will gate through and acquire the semaphore. The + * others will go back to sleep. + * + * Note that these functions are only called when there is contention on the + * lock, and as such all this is the "non-critical" part of the whole semaphore + * business. The critical part is the inline stuff in where + * we want to avoid any extra jumps and calls. */ -void __up(struct semaphore *sem) +void __up_wakeup(struct semaphore *sem) { - wake_one_more(sem); wake_up(&sem->wait); } +EXPORT_SYMBOL(__up_wakeup); + +#ifdef CONFIG_CPU_HAS_LLSC + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + __asm__ __volatile__( + "1: ll %1, %2 # waking_non_zero \n" + " blez %1, 2f \n" + " subu %0, %1, 1 \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + "2: \n" + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); + + return ret; +} + +#else /* !CONFIG_CPU_HAS_LLSC */ + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int waking, ret = 0; + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_lock, flags); + + return ret; +} + +#endif /* !CONFIG_CPU_HAS_LLSC */ + /* - * Perform the "down" function. Return zero for semaphore acquired, - * return negative for signalled out of the function. + * Perform the "down" function. Return zero for semaphore acquired, return + * negative for signalled out of the function. * - * If called from __down, the return is ignored and the wait loop is - * not interruptible. This means that a task waiting on a semaphore - * using "down()" cannot be killed until someone does an "up()" on - * the semaphore. - * - * If called from __down_interruptible, the return value gets checked - * upon return. If the return value is negative then the task continues - * with the negative value in the return register (it can be tested by - * the caller). + * If called from down, the return is ignored and the wait loop is not + * interruptible. This means that a task waiting on a semaphore using "down()" + * cannot be killed until someone does an "up()" on the semaphore. * - * Either form may be used in conjunction with "up()". + * If called from down_interruptible, the return value gets checked upon return. + * If the return value is negative then the task continues with the negative + * value in the return register (it can be tested by the caller). * + * Either form may be used in conjunction with "up()". */ -#define DOWN_VAR \ - struct task_struct *tsk = current; \ - wait_queue_t wait; \ +void __down_failed(struct semaphore * sem) +{ + struct task_struct *tsk = current; + wait_queue_t wait; + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); -#define DOWN_HEAD(task_state) \ - \ - \ - tsk->state = (task_state); \ - add_wait_queue(&sem->wait, &wait); \ - \ - /* \ - * Ok, we're set up. sem->count is known to be less than zero \ - * so we must wait. \ - * \ - * We can let go the lock for purposes of waiting. \ - * We re-acquire it after awaking so as to protect \ - * all semaphore operations. \ - * \ - * If "up()" is called before we call waking_non_zero() then \ - * we will catch it right away. If it is called later then \ - * we will have to go through a wakeup cycle to catch it. \ - * \ - * Multiple waiters contend for the semaphore lock to see \ - * who gets to gate through and who has to wait some more. \ - */ \ + /* + * Ok, we're set up. sem->count is known to be less than zero + * so we must wait. + * + * We can let go the lock for purposes of waiting. + * We re-acquire it after awaking so as to protect + * all semaphore operations. + * + * If "up()" is called before we call waking_non_zero() then + * we will catch it right away. If it is called later then + * we will have to go through a wakeup cycle to catch it. + * + * Multiple waiters contend for the semaphore lock to see + * who gets to gate through and who has to wait some more. + */ for (;;) { - -#define DOWN_TAIL(task_state) \ - tsk->state = (task_state); \ - } \ - tsk->state = TASK_RUNNING; \ + if (waking_non_zero(sem)) + break; + schedule(); + __set_current_state(TASK_UNINTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); +} + +EXPORT_SYMBOL(__down_failed); + +#ifdef CONFIG_CPU_HAS_LLDSCD + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + * + * We must undo the sem->count down_interruptible decrement + * simultaneously and atomically with the sem->waking adjustment, + * otherwise we can race with wake_one_more. + * + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. + * + * This is crazy. Normally it's strictly forbidden to use 64-bit operations + * in the 32-bit MIPS kernel. In this case it's however ok because if an + * interrupt has destroyed the upper half of registers sc will fail. + * Note also that this will not work for MIPS32 CPUs! + * + * Pseudocode: + * + * If(sem->waking > 0) { + * Decrement(sem->waking) + * Return(SUCCESS) + * } else If(signal_pending(tsk)) { + * Increment(sem->count) + * Return(-EINTR) + * } else { + * Return(SLEEP) + * } + */ -void __down(struct semaphore * sem) +static inline int +waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { - DOWN_VAR - DOWN_HEAD(TASK_UNINTERRUPTIBLE) - if (waking_non_zero(sem)) - break; - schedule(); - DOWN_TAIL(TASK_UNINTERRUPTIBLE) + long ret, tmp; + + __asm__ __volatile__( + " .set push # waking_non_zero_interruptible \n" + " .set mips3 \n" + " .set noat \n" + "0: lld %1, %2 \n" + " li %0, 0 \n" + " sll $1, %1, 0 \n" + " blez $1, 1f \n" + " daddiu %1, %1, -1 \n" + " li %0, 1 \n" + " b 2f \n" + "1: beqz %3, 2f \n" + " li %0, %4 \n" + " dli $1, 0x0000000100000000 \n" + " daddu %1, %1, $1 \n" + "2: scd %1, %2 \n" + " beqz %1, 0b \n" + " .set pop \n" + : "=&r" (ret), "=&r" (tmp), "=m" (*sem) + : "r" (signal_pending(tsk)), "i" (-EINTR)); + + return ret; } -int __down_interruptible(struct semaphore * sem) +#else /* !CONFIG_CPU_HAS_LLDSCD */ + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) { - int ret = 0; - DOWN_VAR - DOWN_HEAD(TASK_INTERRUPTIBLE) + int waking, pending, ret = 0; + unsigned long flags; - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) - { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; - break; + pending = signal_pending(tsk); + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } else if (pending) { + atomic_set(&sem->count, atomic_read(&sem->count) + 1); + ret = -EINTR; } - schedule(); - DOWN_TAIL(TASK_INTERRUPTIBLE) + spin_unlock_irqrestore(&semaphore_lock, flags); + return ret; } -int __down_trylock(struct semaphore * sem) +#endif /* !CONFIG_CPU_HAS_LLDSCD */ + +int __down_failed_interruptible(struct semaphore * sem) { - return waking_non_zero_trylock(sem); + struct task_struct *tsk = current; + wait_queue_t wait; + int ret = 0; + + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); + + /* + * Ok, we're set up. sem->count is known to be less than zero + * so we must wait. + * + * We can let go the lock for purposes of waiting. + * We re-acquire it after awaking so as to protect + * all semaphore operations. + * + * If "up()" is called before we call waking_non_zero() then + * we will catch it right away. If it is called later then + * we will have to go through a wakeup cycle to catch it. + * + * Multiple waiters contend for the semaphore lock to see + * who gets to gate through and who has to wait some more. + */ + for (;;) { + ret = waking_non_zero_interruptible(sem, tsk); + if (ret) { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + __set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); + + return ret; } + +EXPORT_SYMBOL(__down_failed_interruptible); diff -urN linux-2.4.24/arch/mips/kernel/setup.c linux-2.4.25/arch/mips/kernel/setup.c --- linux-2.4.24/arch/mips/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -394,7 +394,7 @@ if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - PHYSADDR(initrd_end), + (unsigned long) PHYSADDR(initrd_end), PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; } @@ -479,6 +479,7 @@ void momenco_ocelot_setup(void); void momenco_ocelot_g_setup(void); void momenco_ocelot_c_setup(void); + void momenco_jaguar_atx_setup(void); void nino_setup(void); void nec_osprey_setup(void); void nec_eagle_setup(void); @@ -553,6 +554,11 @@ momenco_ocelot_c_setup(); break; #endif +#ifdef CONFIG_MOMENCO_JAGUAR_ATX + case MACH_GROUP_MOMENCO: + momenco_jaguar_atx_setup(); + break; +#endif #ifdef CONFIG_MIPS_SEAD case MACH_GROUP_UNKNOWN: sead_setup(); @@ -681,6 +687,11 @@ hp_setup(); break; #endif +#ifdef CONFIG_PMC_YOSEMITE + case MACH_GROUP_TITAN: + pmc_yosemite_setup(); + break; +#endif default: panic("Unsupported architecture"); } diff -urN linux-2.4.24/arch/mips/kernel/smp.c linux-2.4.25/arch/mips/kernel/smp.c --- linux-2.4.24/arch/mips/kernel/smp.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/smp.c 2004-02-18 05:36:30.000000000 -0800 @@ -52,35 +52,6 @@ int __cpu_logical_map[NR_CPUS]; cycles_t cacheflush_time; -/* These are defined by the board-specific code. */ - -/* - * Cause the function described by call_data to be executed on the passed - * cpu. When the function has finished, increment the finished field of - * call_data. - */ -void core_send_ipi(int cpu, unsigned int action); - -/* - * Clear all undefined state in the cpu, set up sp and gp to the passed - * values, and kick the cpu into smp_bootstrap(); - */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); - -/* - * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed - */ -void prom_init_secondary(void); - -/* - * Do whatever setup needs to be done for SMP at the board level. Return - * the number of cpus in the system, including this one - */ -int prom_setup_smp(void); - -void prom_smp_finish(void); - void __init smp_callin(void) { #if 0 @@ -89,34 +60,6 @@ #endif } -#ifndef CONFIG_SGI_IP27 -/* - * Hook for doing final board-specific setup after the generic smp setup - * is done - */ -asmlinkage void start_secondary(void) -{ - unsigned int cpu = smp_processor_id(); - - cpu_probe(); - prom_init_secondary(); - per_cpu_trap_init(); - - /* - * XXX parity protection should be folded in here when it's converted - * to an option instead of something based on .cputype - */ - pgd_current[cpu] = init_mm.pgd; - cpu_data[cpu].udelay_val = loops_per_jiffy; - prom_smp_finish(); - printk("Slave cpu booted successfully\n"); - CPUMASK_SETB(cpu_online_map, cpu); - atomic_inc(&cpus_booted); - while (!atomic_read(&smp_commenced)); - cpu_idle(); -} -#endif /* CONFIG_SGI_IP27 */ - void __init smp_commence(void) { wmb(); diff -urN linux-2.4.24/arch/mips/kernel/time.c linux-2.4.25/arch/mips/kernel/time.c --- linux-2.4.24/arch/mips/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -102,9 +102,9 @@ /* - * Timer ack for a R4k-compatible timer of a known frequency. + * Timer ack for an R4k-compatible timer of a known frequency. */ -static void c0_fixed_timer_ack(void) +static void c0_timer_ack(void) { unsigned int count; @@ -129,22 +129,23 @@ return read_c0_count(); } -/* For unknown frequency. */ +/* For use solely as a high precision timer. */ static void c0_hpt_init(unsigned int count) { write_c0_count(read_c0_count() - count); } -/* For a known frequency. Used as an interrupt source. */ -static void c0_fixed_hpt_init(unsigned int count) +/* For use both as a high precision timer and an interrupt source. */ +static void c0_hpt_timer_init(unsigned int count) { - expirelo = cycles_per_jiffy; count = read_c0_count() - count; - write_c0_count(0); - write_c0_compare(cycles_per_jiffy); + expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; + write_c0_count(expirelo - cycles_per_jiffy); + write_c0_compare(expirelo); write_c0_count(count); } +int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); void (*mips_hpt_init)(unsigned int); @@ -328,9 +329,9 @@ "dsll32 %1,%2,0\n\t" "or %1,%1,%0\n\t" "ddivu $0,%1,%4\n\t" + "mflo %1\n\t" "dsll32 %0,%5,0\n\t" "or %0,%0,%6\n\t" - "mflo %1\n\t" "ddivu $0,%0,%1\n\t" "mflo %0\n\t" ".set pop" @@ -410,6 +411,7 @@ */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + unsigned long j; unsigned int count; count = mips_hpt_read(); @@ -447,10 +449,41 @@ * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca - */ - if (!jiffies) { - timerhi = timerlo = 0; - mips_hpt_init(count); + * + * The first timer interrupt comes late as interrupts are + * enabled long after timers are initialized. Therefore the + * high precision timer is fast, leading to wrong gettimeoffset() + * calculations. We deal with it by setting it based on the + * number of its ticks between the second and the third interrupt. + * That is still somewhat imprecise, but it's a good estimate. + * --macro + */ + j = jiffies; + if (j < 4) { + static unsigned int prev_count; + static int hpt_initialized; + + switch (j) { + case 0: + timerhi = timerlo = 0; + mips_hpt_init(count); + break; + case 2: + prev_count = count; + break; + case 3: + if (!hpt_initialized) { + unsigned int c3 = 3 * (count - prev_count); + + timerhi = 0; + timerlo = c3; + mips_hpt_init(count - c3); + hpt_initialized = 1; + } + break; + default: + break; + } } #if !defined(CONFIG_SMP) @@ -500,7 +533,9 @@ int cpu = smp_processor_id(); irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; + + if (cpu != 0) + kstat.irqs[cpu][irq]++; /* we keep interrupt disabled all the time */ local_timer_interrupt(irq, NULL, regs); @@ -516,7 +551,7 @@ * * 1) board_time_init() - * a) (optional) set up RTC routines, - * b) (optional) calibrate and set the mips_counter_frequency + * b) (optional) calibrate and set the mips_hpt_frequency * (only needed if you intended to use fixed_rate_gettimeoffset * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_get_time(). @@ -531,7 +566,7 @@ void (*board_time_init)(void); void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency; +unsigned int mips_hpt_frequency; static struct irqaction timer_irqaction = { .handler = timer_interrupt, @@ -539,6 +574,49 @@ .name = "timer", }; +static unsigned int __init calibrate_hpt(void) +{ + u64 frequency; + u32 hpt_start, hpt_end, hpt_count, hz; + + const int loops = HZ / 10; + int log_2_loops = 0; + int i; + + /* + * We want to calibrate for 0.1s, but to avoid a 64-bit + * division we round the number of loops up to the nearest + * power of 2. + */ + while (loops > 1 << log_2_loops) + log_2_loops++; + i = 1 << log_2_loops; + + /* + * Wait for a rising edge of the timer interrupt. + */ + while (mips_timer_state()); + while (!mips_timer_state()); + + /* + * Now see how many high precision timer ticks happen + * during the calculated number of periods between timer + * interrupts. + */ + hpt_start = mips_hpt_read(); + do { + while (mips_timer_state()); + while (!mips_timer_state()); + } while (--i); + hpt_end = mips_hpt_read(); + + hpt_count = hpt_end - hpt_start; + hz = HZ; + frequency = (u64)hpt_count * (u64)hz; + + return frequency >> log_2_loops; +} + void __init time_init(void) { if (board_time_init) @@ -555,7 +633,7 @@ /* No high precision timer -- sorry. */ mips_hpt_read = null_hpt_read; mips_hpt_init = null_hpt_init; - } else if (!mips_counter_frequency) { + } else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ @@ -578,27 +656,36 @@ */ do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* We know counter frequency! */ + /* We know counter frequency. Or we can get it. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - mips_hpt_init = c0_fixed_hpt_init; - if (!mips_timer_ack) - /* R4k timer interrupt ack. */ - mips_timer_ack = c0_fixed_timer_ack; + if (mips_timer_state) + mips_hpt_init = c0_hpt_init; + else { + /* No external timer interrupt -- use R4k. */ + mips_hpt_init = c0_hpt_timer_init; + mips_timer_ack = c0_timer_ack; + } } + if (!mips_hpt_frequency) + mips_hpt_frequency = calibrate_hpt(); do_gettimeoffset = fixed_rate_gettimeoffset; /* Calculate cache parameters. */ - cycles_per_jiffy = mips_counter_frequency / HZ; + cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* Any better way to do this? */ - sll32_usecs_per_cycle = mips_counter_frequency / 100000; - sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; - sll32_usecs_per_cycle *= 10; + do_div64_32(sll32_usecs_per_cycle, + 1000000, mips_hpt_frequency / 2, + mips_hpt_frequency); + + /* Report the high precision timer rate for a reference. */ + printk("Using %u.%03u MHz high precision timer.\n", + ((mips_hpt_frequency + 500) / 1000) / 1000, + ((mips_hpt_frequency + 500) / 1000) % 1000); } if (!mips_timer_ack) diff -urN linux-2.4.24/arch/mips/kernel/traps.c linux-2.4.25/arch/mips/kernel/traps.c --- linux-2.4.24/arch/mips/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/traps.c 2004-02-18 05:36:30.000000000 -0800 @@ -63,6 +63,7 @@ void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); +void (*board_nmi_handler_setup)(void); int kstack_depth_to_print = 24; @@ -234,9 +235,10 @@ /* * Saved cp0 registers */ - printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, - regs->cp0_cause); + printk("epc : %08lx %s\n", regs->cp0_epc, print_tainted()); + printk("Status: %08lx\n", regs->cp0_status); + printk("Cause : %08lx\n", regs->cp0_cause); + printk("PrId : %08x\n", read_c0_prid()); } void show_registers(struct pt_regs *regs) @@ -523,6 +525,8 @@ simulate_sc(regs, opcode); return 0; } + + return -EFAULT; /* Strange things going on ... */ } asmlinkage void do_ov(struct pt_regs *regs) @@ -584,6 +588,8 @@ unsigned int opcode, bcode; siginfo_t info; + die_if_kernel("Break instruction in kernel code", regs); + if (get_insn_opcode(regs, &opcode)) return; @@ -879,7 +885,7 @@ unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + clear_c0_status(ST0_CU3|ST0_CU2|ST0_CU1|ST0_BEV|ST0_KX|ST0_SX|ST0_UX); if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) set_c0_status(ST0_XX); @@ -896,8 +902,7 @@ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - if (current->mm) - BUG(); + BUG_ON(current->mm); enter_lazy_tlb(&init_mm, current, cpu); } @@ -1007,6 +1012,9 @@ restore_fp_context = fpu_emulator_restore_context; } + if (board_nmi_handler_setup) + board_nmi_handler_setup(); + flush_icache_range(KSEG0, KSEG0 + 0x400); atomic_inc(&init_mm.mm_count); /* XXX UP? */ diff -urN linux-2.4.24/arch/mips/kernel/unaligned.c linux-2.4.25/arch/mips/kernel/unaligned.c --- linux-2.4.24/arch/mips/kernel/unaligned.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/kernel/unaligned.c 2004-02-18 05:36:30.000000000 -0800 @@ -40,7 +40,7 @@ * Below a little program to play around with this feature. * * #include - * #include + * #include * * struct foo { * unsigned char bar[8]; diff -urN linux-2.4.24/arch/mips/lasat/Makefile linux-2.4.25/arch/mips/lasat/Makefile --- linux-2.4.24/arch/mips/lasat/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -5,7 +5,7 @@ O_TARGET := lasatkern.o obj-y := reset.o setup.o prom.o lasat_board.o \ - crc32.o at93c.o interrupt.o lasatIRQ.o + at93c.o interrupt.o lasatIRQ.o obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o diff -urN linux-2.4.24/arch/mips/lasat/lasat_board.c linux-2.4.25/arch/mips/lasat/lasat_board.c --- linux-2.4.24/arch/mips/lasat/lasat_board.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/lasat_board.c 2004-02-18 05:36:30.000000000 -0800 @@ -24,6 +24,7 @@ * Routines specific to the LASAT boards */ #include +#include #include #include #include @@ -33,9 +34,11 @@ #include "at93c.h" /* New model description table */ #include "lasat_models.h" + +#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len)) + struct lasat_info lasat_board_info; -unsigned long crc32(unsigned long, unsigned char *, int); void update_bcastaddr(void); int EEPROMRead(unsigned int pos, unsigned char *data, int len) @@ -68,19 +71,19 @@ ls[LASAT_MTD_NORMAL] = 0x100000; if (mips_machtype == MACH_LASAT_100) { - lasat_board_info.li_flash_base = KSEG1ADDR(0x1e000000); + lasat_board_info.li_flash_base = 0x1e000000; - lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x1e400000); + lb[LASAT_MTD_BOOTLOADER] = 0x1e400000; if (lasat_board_info.li_flash_size > 0x200000) { ls[LASAT_MTD_CONFIG] = 0x100000; ls[LASAT_MTD_FS] = 0x500000; } } else { - lasat_board_info.li_flash_base = KSEG1ADDR(0x10000000); + lasat_board_info.li_flash_base = 0x10000000; if (lasat_board_info.li_flash_size < 0x1000000) { - lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x10000000); + lb[LASAT_MTD_BOOTLOADER] = 0x10000000; ls[LASAT_MTD_CONFIG] = 0x100000; if (lasat_board_info.li_flash_size >= 0x400000) { ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; @@ -109,7 +112,7 @@ sizeof(struct lasat_eeprom_struct)); /* Check the CRC */ - crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), sizeof(struct lasat_eeprom_struct) - 4); if (crc != lasat_board_info.li_eeprom_info.crc32) { @@ -268,7 +271,7 @@ unsigned long crc; /* Generate the CRC */ - crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), sizeof(struct lasat_eeprom_struct) - 4); lasat_board_info.li_eeprom_info.crc32 = crc; diff -urN linux-2.4.24/arch/mips/lasat/prom.c linux-2.4.25/arch/mips/lasat/prom.c --- linux-2.4.24/arch/mips/lasat/prom.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -78,7 +78,7 @@ { u32 version = *(u32 *)(RESET_VECTOR + 0x90); - if (version == 306) { + if (version >= 306) { prom_display = (void *)PROM_DISPLAY_ADDR; prom_putc = (void *)PROM_PUTC_ADDR; prom_printf = real_prom_printf; diff -urN linux-2.4.24/arch/mips/lasat/setup.c linux-2.4.25/arch/mips/lasat/setup.c --- linux-2.4.24/arch/mips/lasat/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -138,7 +138,7 @@ static void lasat_time_init(void) { - mips_counter_frequency = lasat_board_info.li_cpu_hz / 2; + mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; } static void lasat_timer_setup(struct irqaction *irq) @@ -146,7 +146,7 @@ write_c0_compare( read_c0_count() + - mips_counter_frequency / HZ); + mips_hpt_frequency / HZ); change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); } diff -urN linux-2.4.24/arch/mips/lasat/sysctl.c linux-2.4.25/arch/mips/lasat/sysctl.c --- linux-2.4.24/arch/mips/lasat/sysctl.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/sysctl.c 2004-02-18 05:36:30.000000000 -0800 @@ -95,32 +95,6 @@ return 0; } -static int rtctmp; - -#ifdef CONFIG_DS1603 -/* proc function to read/write RealTime Clock */ -int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) -{ - int r; - down(&lasat_info_sem); - if (!write) { - rtctmp = ds1603_read(); - /* check for time < 0 and set to 0 */ - if (rtctmp < 0) - rtctmp = 0; - } - r = proc_dointvec(table, write, filp, buffer, lenp); - if ( (!write) || r) { - up(&lasat_info_sem); - return r; - } - ds1603_set(rtctmp); - up(&lasat_info_sem); - return 0; -} -#endif - /* Sysctl for setting the IP addresses */ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, @@ -140,30 +114,6 @@ return 1; } -#if CONFIG_DS1603 -/* Same for RTC */ -int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) -{ - int r; - down(&lasat_info_sem); - rtctmp = ds1603_read(); - if (rtctmp < 0) - rtctmp = 0; - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); - if (r < 0) { - up(&lasat_info_sem); - return r; - } - if (newval && newlen) { - ds1603_set(rtctmp); - } - up(&lasat_info_sem); - return 1; -} -#endif - #ifdef CONFIG_INET static char lasat_bcastaddr[16]; @@ -328,10 +278,6 @@ 0600, NULL, &proc_dolasatstring, &sysctl_lasatstring}, {LASAT_SBOOT, "boot-service", &lasat_boot_to_service, sizeof(int), 0644, NULL, &proc_dointvec, &sysctl_intvec}, -#if CONFIG_DS1603 - {LASAT_RTC, "rtc", &rtctmp, sizeof(int), - 0644, NULL, &proc_dolasatrtc, &sysctl_lasat_rtc}, -#endif {LASAT_NAMESTR, "namestr", &lasat_board_info.li_namestr, sizeof(lasat_board_info.li_namestr), 0444, NULL, &proc_dostring, &sysctl_string}, {LASAT_TYPESTR, "typestr", &lasat_board_info.li_typestr, sizeof(lasat_board_info.li_typestr), diff -urN linux-2.4.24/arch/mips/lasat/sysctl.h linux-2.4.25/arch/mips/lasat/sysctl.h --- linux-2.4.24/arch/mips/lasat/sysctl.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lasat/sysctl.h 2004-02-18 05:36:30.000000000 -0800 @@ -16,7 +16,6 @@ LASAT_BCAST, LASAT_PASSWORD, LASAT_SBOOT, - LASAT_RTC, LASAT_NAMESTR, LASAT_TYPESTR, }; diff -urN linux-2.4.24/arch/mips/ld.script.in linux-2.4.25/arch/mips/ld.script.in --- linux-2.4.24/arch/mips/ld.script.in 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/ld.script.in 2004-02-18 05:36:30.000000000 -0800 @@ -49,9 +49,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff -urN linux-2.4.24/arch/mips/lib/Makefile linux-2.4.25/arch/mips/lib/Makefile --- linux-2.4.24/arch/mips/lib/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lib/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -11,6 +11,8 @@ memset.o watch.o strlen_user.o \ strncpy_user.o strnlen_user.o +export-objs := rtc-std.o rtc-no.o + ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) obj-y += r3k_dump_tlb.o else diff -urN linux-2.4.24/arch/mips/lib/rtc-no.c linux-2.4.25/arch/mips/lib/rtc-no.c --- linux-2.4.24/arch/mips/lib/rtc-no.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lib/rtc-no.c 2004-02-18 05:36:30.000000000 -0800 @@ -9,6 +9,7 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include +#include #include static unsigned int shouldnt_happen(void) @@ -28,3 +29,5 @@ .rtc_write_data = (void *) &shouldnt_happen, .rtc_bcd_mode = (void *) &shouldnt_happen }; + +EXPORT_SYMBOL(rtc_ops); diff -urN linux-2.4.24/arch/mips/lib/rtc-std.c linux-2.4.25/arch/mips/lib/rtc-std.c --- linux-2.4.24/arch/mips/lib/rtc-std.c 2001-07-02 13:56:40.000000000 -0700 +++ linux-2.4.25/arch/mips/lib/rtc-std.c 2004-02-18 05:36:30.000000000 -0800 @@ -7,6 +7,7 @@ * * Copyright (C) 1998, 2001 by Ralf Baechle */ +#include #include #include @@ -32,3 +33,5 @@ &std_rtc_write_data, &std_rtc_bcd_mode }; + +EXPORT_SYMBOL(rtc_ops); diff -urN linux-2.4.24/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.25/arch/mips/mips-boards/atlas/atlas_setup.c --- linux-2.4.24/arch/mips/mips-boards/atlas/atlas_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mips-boards/atlas/atlas_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -33,11 +34,6 @@ #include #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - #ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void saa9730_kgdb_hook(void); @@ -75,14 +71,20 @@ #ifdef CONFIG_SERIAL_CONSOLE argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { - int i = 0; + struct console_cmdline *c = &console_cmdline[0]; char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') + int i = 0; + static char options[8]; + while (s && s[i] >= '0' && s[i] <= '9') { + options[i] = s[i]; i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); + } + options[i] = 0; + strcpy(c->name, "ttyS"); + c->options = s ? options : NULL; + c->index = 0; + prom_printf("Serial console: %s%d %s\n", + c->name, c->index, options); } #endif diff -urN linux-2.4.24/arch/mips/mips-boards/generic/time.c linux-2.4.25/arch/mips/mips-boards/generic/time.c --- linux-2.4.24/arch/mips/mips-boards/generic/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mips-boards/generic/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -102,12 +102,12 @@ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_c0_count(); + mips_hpt_frequency = read_c0_count(); /* restore interrupts */ local_irq_restore(flags); - return (mips_counter_frequency / HZ); + return (mips_hpt_frequency / HZ); } unsigned long __init mips_rtc_get_time(void) diff -urN linux-2.4.24/arch/mips/mips-boards/malta/malta_int.c linux-2.4.25/arch/mips/mips-boards/malta/malta_int.c --- linux-2.4.24/arch/mips/mips-boards/malta/malta_int.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mips-boards/malta/malta_int.c 2004-02-18 05:36:30.000000000 -0800 @@ -162,7 +162,7 @@ printk("GT_INTRCAUSE = %08x\n", data); data = GT_READ(0x70); datahi = GT_READ(0x78); - printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data); + printk("GT_CPU_ERR_ADDR = %02x%08x\n", datahi, data); break; case MIPS_REVISION_CORID_BONITO64: case MIPS_REVISION_CORID_CORE_20K: diff -urN linux-2.4.24/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.25/arch/mips/mips-boards/malta/malta_setup.c --- linux-2.4.24/arch/mips/mips-boards/malta/malta_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mips-boards/malta/malta_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -45,11 +45,6 @@ #include #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - #ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); int remote_debug = 0; diff -urN linux-2.4.24/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.25/arch/mips/mips-boards/sead/sead_setup.c --- linux-2.4.24/arch/mips/mips-boards/sead/sead_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mips-boards/sead/sead_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,11 +32,6 @@ #include #include -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - extern void mips_reboot_setup(void); extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); @@ -54,14 +50,20 @@ #ifdef CONFIG_SERIAL_CONSOLE argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { - int i = 0; + struct console_cmdline *c = &console_cmdline[0]; char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') + int i = 0; + static char options[8]; + while (s && s[i] >= '0' && s[i] <= '9') { + options[i] = s[i]; i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); + } + options[i] = 0; + strcpy(c->name, "ttyS"); + c->options = s ? options : NULL; + c->index = 0; + prom_printf("Serial console: %s%d %s\n", + c->name, c->index, options); } #endif diff -urN linux-2.4.24/arch/mips/mm/Makefile linux-2.4.25/arch/mips/mm/Makefile --- linux-2.4.24/arch/mips/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -14,8 +14,8 @@ obj-y += cache.o extable.o init.o ioremap.o fault.o \ loadmmu.o -obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o tlb-r3k.o tlbex-r3k.o -obj-$(CONFIG_CPU_TX39XX) += pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += pg-r4k.o c-r3k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += pg-r4k.o c-tx39.o tlb-r3k.o tlbex-r3k.o obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4300) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4X00) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o @@ -24,6 +24,7 @@ obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R5432) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_RM7000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_RM9000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R10000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_MIPS32) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-mips32.o obj-$(CONFIG_CPU_MIPS64) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o @@ -31,7 +32,7 @@ cex-sb1.o cerr-sb1.o obj-$(CONFIG_64BIT_PHYS_ADDR) += remap.o -obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_SGI_IP22) += sc-ip22.o diff -urN linux-2.4.24/arch/mips/mm/c-r3k.c linux-2.4.25/arch/mips/mm/c-r3k.c --- linux-2.4.24/arch/mips/mm/c-r3k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/c-r3k.c 2004-02-18 05:36:30.000000000 -0800 @@ -23,9 +23,6 @@ #include #include -void r3k_clear_page(void * page); -void r3k_copy_page(void * to, void * from); - static unsigned long icache_size, dcache_size; /* Size in bytes */ static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ @@ -320,10 +317,8 @@ void __init ld_mmu_r23000(void) { - unsigned long config; - - _clear_page = r3k_clear_page; - _copy_page = r3k_copy_page; + extern void build_clear_page(void); + extern void build_copy_page(void); r3k_probe_cache(); @@ -344,4 +339,7 @@ icache_size >> 10, icache_lsize); printk("Primary data cache %ldkB, linesize %ld bytes.\n", dcache_size >> 10, dcache_lsize); + + build_clear_page(); + build_copy_page(); } diff -urN linux-2.4.24/arch/mips/mm/c-r4k.c linux-2.4.25/arch/mips/mm/c-r4k.c --- linux-2.4.24/arch/mips/mm/c-r4k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/c-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -28,27 +28,6 @@ static unsigned long icache_size, dcache_size, scache_size; -extern void andes_clear_page(void * page); -extern void r4k_clear_page32_d16(void * page); -extern void r4k_clear_page32_d32(void * page); -extern void r4k_clear_page_d16(void * page); -extern void r4k_clear_page_d32(void * page); -extern void r4k_clear_page_r4600_v1(void * page); -extern void r4k_clear_page_r4600_v2(void * page); -extern void r4k_clear_page_s16(void * page); -extern void r4k_clear_page_s32(void * page); -extern void r4k_clear_page_s64(void * page); -extern void r4k_clear_page_s128(void * page); -extern void andes_copy_page(void * to, void * from); -extern void r4k_copy_page_d16(void * to, void * from); -extern void r4k_copy_page_d32(void * to, void * from); -extern void r4k_copy_page_r4600_v1(void * to, void * from); -extern void r4k_copy_page_r4600_v2(void * to, void * from); -extern void r4k_copy_page_s16(void * to, void * from); -extern void r4k_copy_page_s32(void * to, void * from); -extern void r4k_copy_page_s64(void * to, void * from); -extern void r4k_copy_page_s128(void * to, void * from); - /* * Dummy cache handling routines for machines without boardcaches */ @@ -73,80 +52,46 @@ __asm__ __volatile__("nop;nop;nop;nop"); \ } while (0) -static void r4k_blast_dcache_page(unsigned long addr) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; +static void (* r4k_blast_dcache_page)(unsigned long addr); -dc_16: - blast_dcache16_page(addr); - return; - -dc_32: +static inline void r4k_blast_dcache_page_dc32(unsigned long addr) +{ R4600_HIT_CACHEOP_WAR_IMPL; blast_dcache32_page(addr); - return; +} -init: - dc_lsize = current_cpu_data.dcache.linesz; +static inline void r4k_blast_dcache_page_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache_page = blast_dcache16_page; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; } -static void r4k_blast_dcache_page_indexed(unsigned long addr) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; - -dc_16: - blast_dcache16_page_indexed(addr); - return; - -dc_32: - blast_dcache32_page_indexed(addr); - return; +static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -init: - dc_lsize = current_cpu_data.dcache.linesz; +static void r4k_blast_dcache_page_indexed_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; } -static void r4k_blast_dcache(void) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; - -dc_16: - blast_dcache16(); - return; - -dc_32: - blast_dcache32(); - return; +static void (* r4k_blast_dcache)(void); -init: - dc_lsize = current_cpu_data.dcache.linesz; +static inline void r4k_blast_dcache_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache = blast_dcache16; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache = blast_dcache32; } /* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ @@ -201,175 +146,82 @@ cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_blast_icache_page(unsigned long addr) +static void (* r4k_blast_icache_page)(unsigned long addr); + +static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16_page(addr); - return; - -ic_32: - blast_icache32_page(addr); - return; -ic_64: - blast_icache64_page(addr); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache_page = blast_icache16_page; else if (ic_lsize == 32) - l = &&ic_32; + r4k_blast_icache_page = blast_icache32_page; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache_page = blast_icache64_page; } -static void r4k_blast_icache_page_indexed(unsigned long addr) +static void (* r4k_blast_icache_page_indexed)(unsigned long addr); + +static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16_page_indexed(addr); - return; - -ic_32: - blast_icache32_page_indexed(addr); - return; - -ic_64: - blast_icache64_page_indexed(addr); - return; -ic_32_tx49: - tx49_blast_icache32_page_indexed(addr); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache_page_indexed = blast_icache16_page_indexed; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed; else if (ic_lsize == 32) - if (TX49XX_ICACHE_INDEX_INV_WAR) - l = &&ic_32_tx49; - else - l = &&ic_32; + r4k_blast_icache_page_indexed = blast_icache32_page_indexed; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache_page_indexed = blast_icache64_page_indexed; } -static void r4k_blast_icache(void) +static void (* r4k_blast_icache)(void); + +static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16(); - return; - -ic_32: - blast_icache32(); - return; -ic_64: - blast_icache64(); - return; - -ic_32_tx49: - tx49_blast_icache32(); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache = blast_icache16; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache = tx49_blast_icache32; else if (ic_lsize == 32) - if (TX49XX_ICACHE_INDEX_INV_WAR) - l = &&ic_32_tx49; - else - l = &&ic_32; + r4k_blast_icache = blast_icache32; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache = blast_icache64; } -static void r4k_blast_scache_page(unsigned long addr) +static void (* r4k_blast_scache_page)(unsigned long addr); + +static inline void r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = current_cpu_data.scache.linesz; - static void *l = &&init; - - goto *l; - -sc_16: - blast_scache16_page(addr); - return; -sc_32: - blast_scache32_page(addr); - return; - -sc_64: - blast_scache64_page(addr); - return; - -sc_128: - blast_scache128_page(addr); - return; - -init: if (sc_lsize == 16) - l = &&sc_16; + r4k_blast_scache_page = blast_scache16_page; else if (sc_lsize == 32) - l = &&sc_32; + r4k_blast_scache_page = blast_scache32_page; else if (sc_lsize == 64) - l = &&sc_64; + r4k_blast_scache_page = blast_scache64_page; else if (sc_lsize == 128) - l = &&sc_128; - goto *l; + r4k_blast_scache_page = blast_scache128_page; } -static void r4k_blast_scache(void) +static void (* r4k_blast_scache)(void); + +static inline void r4k_blast_scache_setup(void) { unsigned long sc_lsize = current_cpu_data.scache.linesz; - static void *l = &&init; - - goto *l; -sc_16: - blast_scache16(); - return; - -sc_32: - blast_scache32(); - return; - -sc_64: - blast_scache64(); - return; - -sc_128: - blast_scache128(); - return; - -init: if (sc_lsize == 16) - l = &&sc_16; + r4k_blast_scache = blast_scache16; else if (sc_lsize == 32) - l = &&sc_32; + r4k_blast_scache = blast_scache32; else if (sc_lsize == 64) - l = &&sc_64; + r4k_blast_scache = blast_scache64; else if (sc_lsize == 128) - l = &&sc_128; - goto *l; + r4k_blast_scache = blast_scache128; } static void r4k_flush_cache_all(void) @@ -561,7 +413,9 @@ */ if (cpu_has_subset_pcaches) { unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); return; } @@ -569,6 +423,7 @@ if (!cpu_has_ic_fills_f_dc) { unsigned long addr = (unsigned long) page_address(page); r4k_blast_dcache_page(addr); + ClearPageDcacheDirty(page); } /* @@ -775,6 +630,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit= ffs(dcache_size/2) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R5432: @@ -788,6 +645,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_TX49XX: @@ -800,6 +659,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 4; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R4000PC: @@ -818,6 +679,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 1; c->dcache.waybit = 0; /* does not matter */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R10000: @@ -831,9 +694,20 @@ c->dcache.linesz = 32; c->dcache.ways = 2; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_PREFETCH; break; + case CPU_VR4133: + write_c0_config(config & ~CONF_EB); case CPU_VR4131: + /* Workaround for cache instruction bug of VR4131 */ + if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U || + c->processor_id == 0x0c82U) { + config &= ~0x00000030U; + config |= 0x00410000U; + write_c0_config(config); + } icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 2; @@ -843,6 +717,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit = ffs(dcache_size/2) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_VR41XX: @@ -860,11 +736,14 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 1; c->dcache.waybit = 0; /* does not matter */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_RM7000: rm7k_erratum31(); + case CPU_RM9000: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 4; @@ -874,6 +753,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 4; c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH; break; default: @@ -898,6 +779,9 @@ c->icache.linesz; c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + /* * Now probe the MIPS32 / MIPS64 data cache. */ @@ -914,6 +798,8 @@ c->dcache.ways * c->dcache.linesz; c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + + c->options |= MIPS_CPU_PREFETCH; break; } @@ -947,9 +833,6 @@ if (c->dcache.waysize > PAGE_SIZE) c->dcache.flags |= MIPS_CACHE_ALIASES; - if (config & 0x8) /* VI bit */ - c->icache.flags |= MIPS_CACHE_VTAG; - switch (c->cputype) { case CPU_20KC: /* @@ -1037,71 +920,6 @@ return 1; } -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch (current_cpu_data.dcache.linesz) { - case 16: - if (cpu_has_64bits) - _clear_page = r4k_clear_page_d16; - else - _clear_page = r4k_clear_page32_d16; - _copy_page = r4k_copy_page_d16; - - break; - case 32: - prid = read_c0_prid() & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - } else { - if (cpu_has_64bits) - _clear_page = r4k_clear_page_d32; - else - _clear_page = r4k_clear_page32_d32; - _copy_page = r4k_copy_page_d32; - } - break; - } -} - -static void __init setup_scache_funcs(void) -{ - struct cpuinfo_mips *c = ¤t_cpu_data; - - if (c->dcache.linesz > c->scache.linesz) - panic("Invalid primary cache configuration detected"); - - if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - return; - } - - switch (c->scache.linesz) { - case 16: - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } -} - typedef int (*probe_func_t)(unsigned long); extern int r5k_sc_init(void); extern int rm7k_sc_init(void); @@ -1127,6 +945,8 @@ case CPU_R4400MC: probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); sc_present = probe_scache_kseg1(config); + if (sc_present) + c->options |= MIPS_CPU_CACHE_CDEX_S; break; case CPU_R10000: @@ -1140,14 +960,13 @@ case CPU_R5000: case CPU_NEVADA: - setup_noscache_funcs(); #ifdef CONFIG_R5000_CPU_SCACHE r5k_sc_init(); #endif return; case CPU_RM7000: - setup_noscache_funcs(); + case CPU_RM9000: #ifdef CONFIG_RM7000_CPU_SCACHE rm7k_sc_init(); #endif @@ -1157,10 +976,8 @@ sc_present = 0; } - if (!sc_present) { - setup_noscache_funcs(); + if (!sc_present) return; - } if ((c->isa_level == MIPS_CPU_ISA_M32 || c->isa_level == MIPS_CPU_ISA_M64) && @@ -1176,7 +993,6 @@ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); c->options |= MIPS_CPU_SUBSET_CACHES; - setup_scache_funcs(); } static inline void coherency_setup(void) @@ -1205,6 +1021,8 @@ void __init ld_mmu_r4xx0(void) { + extern void build_clear_page(void); + extern void build_copy_page(void); extern char except_vec2_generic; struct cpuinfo_mips *c = ¤t_cpu_data; @@ -1214,11 +1032,19 @@ probe_pcache(); setup_scache(); - coherency_setup(); if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) c->dcache.flags |= MIPS_CACHE_ALIASES; + r4k_blast_dcache_page_setup(); + r4k_blast_dcache_page_indexed_setup(); + r4k_blast_dcache_setup(); + r4k_blast_icache_page_setup(); + r4k_blast_icache_page_indexed_setup(); + r4k_blast_icache_setup(); + r4k_blast_scache_page_setup(); + r4k_blast_scache_setup(); + /* * Some MIPS32 and MIPS64 processors have physically indexed caches. * This code supports virtually indexed processors and will be @@ -1247,4 +1073,8 @@ #endif __flush_cache_all(); + coherency_setup(); + + build_clear_page(); + build_copy_page(); } diff -urN linux-2.4.24/arch/mips/mm/c-sb1.c linux-2.4.25/arch/mips/mm/c-sb1.c --- linux-2.4.24/arch/mips/mm/c-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/c-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,14 +25,7 @@ #include #include -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS extern void sb1_dma_init(void); -extern void sb1_clear_page_dma(void * page); -extern void sb1_copy_page_dma(void * to, void * from); -#else -extern void sb1_clear_page(void * page); -extern void sb1_copy_page(void * to, void * from); -#endif /* These are probed at ld_mmu time */ static unsigned long icache_size; @@ -53,23 +46,6 @@ static unsigned int icache_range_cutoff; static unsigned int dcache_range_cutoff; -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -248,6 +224,7 @@ if (!(vma->vm_flags & VM_EXEC)) return; + addr &= PAGE_MASK; args.vma = vma; args.addr = addr; smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); @@ -573,21 +550,18 @@ void ld_mmu_sb1(void) { extern char except_vec2_sb1; + extern char handle_vec2_sb1; unsigned long temp; /* Special cache error handler for SB1 */ memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); probe_cache_sizes(); #ifdef CONFIG_SIBYTE_DMA_PAGEOPS - _clear_page = sb1_clear_page_dma; - _copy_page = sb1_copy_page_dma; sb1_dma_init(); -#else - _clear_page = sb1_clear_page; - _copy_page = sb1_copy_page; #endif /* @@ -596,7 +570,6 @@ * occur */ _flush_cache_range = (void *) sb1_nop; - _flush_cache_page = sb1_flush_cache_page; _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; _flush_cache_all = sb1_nop; @@ -605,6 +578,9 @@ _flush_icache_page = sb1_flush_icache_page; _flush_icache_all = __sb1_flush_icache_all; /* local only */ + /* This implies an Icache flush too, so can't be nop'ed */ + _flush_cache_page = sb1_flush_cache_page; + _flush_cache_sigtramp = sb1_flush_cache_sigtramp; _flush_data_cache_page = (void *) sb1_nop; diff -urN linux-2.4.24/arch/mips/mm/c-tx39.c linux-2.4.25/arch/mips/mm/c-tx39.c --- linux-2.4.24/arch/mips/mm/c-tx39.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/c-tx39.c 2004-02-18 05:36:30.000000000 -0800 @@ -28,9 +28,6 @@ #include -extern void r3k_clear_page(void * page); -extern void r3k_copy_page(void * to, void * from); - extern int r3k_have_wired_reg; /* in r3k-tlb.c */ /* This sequence is required to ensure icache is disabled immediately */ @@ -409,11 +406,10 @@ void __init ld_mmu_tx39(void) { + extern void build_clear_page(void); + extern void build_copy_page(void); unsigned long config; - _clear_page = r3k_clear_page; - _copy_page = r3k_copy_page; - config = read_c0_conf(); config &= ~TX39_CONF_WBON; write_c0_conf(config); @@ -488,4 +484,7 @@ icache_size >> 10, current_cpu_data.icache.linesz); printk("Primary data cache %ldkb, linesize %d bytes\n", dcache_size >> 10, current_cpu_data.dcache.linesz); + + build_clear_page(); + build_copy_page(); } diff -urN linux-2.4.24/arch/mips/mm/cerr-sb1.c linux-2.4.25/arch/mips/mm/cerr-sb1.c --- linux-2.4.24/arch/mips/mm/cerr-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/cerr-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -193,7 +193,9 @@ prom_printf(" cp0_cerr_i == %08x", cerr_i); breakout_cerri(cerr_i); if (CP0_CERRI_IDX_VALID(cerr_i)) { - if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + /* Check index of EPC, allowing for delay slot */ + if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) && + ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4))) prom_printf(" cerr_i idx doesn't match eepc\n"); else { res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, diff -urN linux-2.4.24/arch/mips/mm/cex-sb1.S linux-2.4.25/arch/mips/mm/cex-sb1.S --- linux-2.4.24/arch/mips/mm/cex-sb1.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/cex-sb1.S 2004-02-18 05:36:30.000000000 -0800 @@ -22,40 +22,122 @@ #include #include #include +#include +#include #include - .text - .set noat - .set mips4 +#define C0_ERRCTL $26 /* CP0: Error info */ +#define C0_CERR_I $27 /* CP0: Icache error */ +#define C0_CERR_D $27,1 /* CP0: Dcache error */ + + /* + * Based on SiByte sample software cache-err/cerr.S + * CVS revision 1.8. Only the 'unrecoverable' case + * is changed. + */ __INIT - - /* Cache Error handler for SB1 */ - LEAF(except_vec2_sb1) - mfc0 k1, $26 - # check if error was recoverable - bltz k1, leave_cerr -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - # look for signature of spurious CErr - lui k0, 0x4000 - bne k0, k1, 1f - .word 0x401Bd801 # mfc0 k1, $27, 1 - lui k0, 0xffe0 - and k1, k0, k1 - lui k0, 0x0200 - beq k0, k1, leave_cerr -1: -#endif - j handle_vec2_sb1 -leave_cerr: - # clear/unlock the registers - mtc0 zero, $26 - mtc0 zero, $27 - .word 0x4080d801 # mtc0 zero, $27, 1 - .word 0x4080d803 # mtc0 zero, $27, 3 + .set mips64 + .set noreorder + .set noat + + /* + * sb1_cerr_vec: code to be copied to the Cache Error + * Exception vector. The code must be pushed out to memory + * (either by copying to Kseg0 and Kseg1 both, or by flushing + * the L1 and L2) since it is fetched as 0xa0000100. + * + * NOTE: Be sure this handler is at most 28 instructions long + * since the final 16 bytes of the exception vector memory + * (0x170-0x17f) are used to preserve k0, k1, and ra. + */ + +LEAF(except_vec2_sb1) + /* + * If this error is recoverable, we need to exit the handler + * without having dirtied any registers. To do this, + * save/restore k0 and k1 from low memory (Useg is direct + * mapped while ERL=1). Note that we can't save to a + * CPU-specific location without ruining a register in the + * process. This means we are vulnerable to data corruption + * whenever the handler is reentered by a second CPU. + */ + sd k0,0x170($0) + sd k1,0x178($0) + + /* + * M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell + * if we can fast-path out of here for a h/w-recovered error. + */ + mfc0 k1,C0_ERRCTL + bgtz k1,attempt_recovery + sll k0,k1,1 + +recovered_dcache: + /* + * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA). + * Ought to log the occurence of this recovered dcache error. + */ + b recovered + .word 0x4080d801 # mtc0 zero, $27, 1 + +attempt_recovery: + /* + * k0 has C0_ERRCTL << 1, which puts 'DC' at bit 31. Any + * Dcache errors we can recover from will take more extensive + * processing. For now, they are considered "unrecoverable". + * Note that 'DC' becoming set (outside of ERL mode) will + * cause 'IC' to clear; so if there's an Icache error, we'll + * only find out about it if we recover from this error and + * continue executing. + */ + bltz k0,unrecoverable + sll k0,1 + + /* + * k0 has C0_ERRCTL << 2, which puts 'IC' at bit 31. If an + * Icache error isn't indicated, I'm not sure why we got here. + * Consider that case "unrecoverable" for now. + */ + bgez k0,unrecoverable + +attempt_icache_recovery: + /* + * External icache errors are due to uncorrectable ECC errors + * in the L2 cache or Memory Controller and cannot be + * recovered here. + */ + mfc0 k0,C0_CERR_I /* delay slot */ + li k1,1 << 26 /* ICACHE_EXTERNAL */ + and k1,k0 + bnez k1,unrecoverable + andi k0,0x1fe0 + + /* + * Since the error is internal, the 'IDX' field from + * CacheErr-I is valid and we can just invalidate all blocks + * in that set. + */ + cache Index_Invalidate_I,(0<<13)(k0) + cache Index_Invalidate_I,(1<<13)(k0) + cache Index_Invalidate_I,(2<<13)(k0) + cache Index_Invalidate_I,(3<<13)(k0) + + /* Ought to log this recovered icache error */ + +recovered: + /* Restore the saved registers */ + ld k0,0x170($0) + ld k1,0x178($0) eret - END(except_vec2_sb1) + +unrecoverable: + /* Unrecoverable Icache or Dcache error; log it and/or fail */ + j handle_vec2_sb1 + nop + +END(except_vec2_sb1) __FINIT @@ -75,9 +157,16 @@ mfc0 k0, CP0_STATUS sll k0, k0, 3 # check CU0 (kernel?) bltz k0, 2f + nop + + /* Get a valid Kseg0 stack pointer. Any task's stack pointer + * will do, although if we ever want to resume execution we + * better not have corrupted any state. */ GET_SAVED_SP - move sp, k0 # want Kseg SP (so uncached) + move sp, k1 + 2: j sb1_cache_error + nop END(handle_vec2_sb1) diff -urN linux-2.4.24/arch/mips/mm/init.c linux-2.4.25/arch/mips/mm/init.c --- linux-2.4.24/arch/mips/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -43,6 +43,23 @@ static unsigned long totalram_pages; static unsigned long totalhigh_pages; +void pgd_init(unsigned long page) +{ + unsigned long *p = (unsigned long *) page; + int i; + + for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { + p[i + 0] = (unsigned long) invalid_pte_table; + p[i + 1] = (unsigned long) invalid_pte_table; + p[i + 2] = (unsigned long) invalid_pte_table; + p[i + 3] = (unsigned long) invalid_pte_table; + p[i + 4] = (unsigned long) invalid_pte_table; + p[i + 5] = (unsigned long) invalid_pte_table; + p[i + 6] = (unsigned long) invalid_pte_table; + p[i + 7] = (unsigned long) invalid_pte_table; + } +} + /* * We have upto 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -244,7 +261,13 @@ zones_size[ZONE_DMA] = low; #endif #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = high - low; + if (cpu_has_dc_aliases) { + printk(KERN_WARNING "This processor doesn't support highmem."); + if (high - low) + printk(" %dk highmem ignored", high - low); + printk("\n"); + } else + zones_size[ZONE_HIGHMEM] = high - low; #endif free_area_init(zones_size); diff -urN linux-2.4.24/arch/mips/mm/loadmmu.c linux-2.4.25/arch/mips/mm/loadmmu.c --- linux-2.4.24/arch/mips/mm/loadmmu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/loadmmu.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,10 +22,6 @@ #include #include -/* memory functions */ -void (*_clear_page)(void * page); -void (*_copy_page)(void * to, void * from); - /* Cache operations. */ void (*_flush_cache_all)(void); void (*___flush_cache_all)(void); @@ -73,7 +69,7 @@ defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ - defined(CONFIG_CPU_RM7000) + defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000) ld_mmu_r4xx0(); r4k_tlb_init(); #endif diff -urN linux-2.4.24/arch/mips/mm/pg-r3k.c linux-2.4.25/arch/mips/mm/pg-r3k.c --- linux-2.4.24/arch/mips/mm/pg-r3k.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/pg-r3k.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) - */ -#include -#include - -/* page functions */ -void r3k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%2\n" - "1:\tsw\t$0,(%0)\n\t" - "sw\t$0,4(%0)\n\t" - "sw\t$0,8(%0)\n\t" - "sw\t$0,12(%0)\n\t" - "addiu\t%0,32\n\t" - "sw\t$0,-16(%0)\n\t" - "sw\t$0,-12(%0)\n\t" - "sw\t$0,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t$0,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE) - : "memory"); -} - -void r3k_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%8\n" - "1:\tlw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - : "0" (to), "1" (from), - "I" (PAGE_SIZE)); -} - -/* - * Initialize new page directory with pointers to invalid ptes - */ -void pgd_init(unsigned long page) -{ - unsigned long dummy1, dummy2; - - /* - * The plain and boring version for the R3000. No cache flushing - * stuff is implemented since the R3000 has physical caches. - */ - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsw\t%2, (%0)\n\t" - "sw\t%2, 4(%0)\n\t" - "sw\t%2, 8(%0)\n\t" - "sw\t%2, 12(%0)\n\t" - "sw\t%2, 16(%0)\n\t" - "sw\t%2, 20(%0)\n\t" - "sw\t%2, 24(%0)\n\t" - "sw\t%2, 28(%0)\n\t" - "subu\t%1, 1\n\t" - "bnez\t%1, 1b\n\t" - "addiu\t%0, 32\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2) - :"r" ((unsigned long) invalid_pte_table), "0" (page), - "1" (USER_PTRS_PER_PGD / 8)); -} diff -urN linux-2.4.24/arch/mips/mm/pg-r4k.S linux-2.4.25/arch/mips/mm/pg-r4k.S --- linux-2.4.24/arch/mips/mm/pg-r4k.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/pg-r4k.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,803 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PGD_SIZE 0x2000 -#else -#define PGD_SIZE 0x1000 -#endif - - .text - .set noat - -/* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: - * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. - */ - -LEAF(r4k_clear_page32_d16) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sw zero, (a0) - sw zero, 4(a0) - sw zero, 8(a0) - sw zero, 12(a0) - addiu a0, 32 - cache Create_Dirty_Excl_D, -16(a0) - sw zero, -16(a0) - sw zero, -12(a0) - sw zero, -8(a0) - sw zero, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page32_d16) - -LEAF(r4k_clear_page32_d32) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sw zero, (a0) - sw zero, 4(a0) - sw zero, 8(a0) - sw zero, 12(a0) - addiu a0, 32 - sw zero, -16(a0) - sw zero, -12(a0) - sw zero, -8(a0) - sw zero, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page32_d32) - -LEAF(r4k_clear_page_d16) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - cache Create_Dirty_Excl_D, 16(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - cache Create_Dirty_Excl_D, -16(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_d16) - -LEAF(r4k_clear_page_d32) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_d32) - -/* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ - -LEAF(r4k_clear_page_r4600_v1) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - nop - nop - nop - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_r4600_v1) - -LEAF(r4k_clear_page_r4600_v2) - .set mips3 - mfc0 a1, CP0_STATUS - ori AT, a1, 1 - xori AT, 1 - mtc0 AT, CP0_STATUS - nop - nop - nop - - .set volatile - la AT, KSEG1 - lw zero, (AT) - .set novolatile - - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_D, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - - mfc0 AT, CP0_STATUS # __restore_flags - andi a1, 1 - ori AT, 1 - xori AT, 1 - or a1, AT - mtc0 a1, CP0_STATUS - nop - nop - nop - - jr ra - END(r4k_clear_page_r4600_v2) - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ - -LEAF(r4k_clear_page_s16) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - cache Create_Dirty_Excl_SD, 16(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_SD, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - cache Create_Dirty_Excl_SD, -16(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s16) - -LEAF(r4k_clear_page_s32) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - cache Create_Dirty_Excl_SD, -32(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s32) - -LEAF(r4k_clear_page_s64) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - addiu a0, 64 - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s64) - -LEAF(r4k_clear_page_s128) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - sd zero, (a0) - sd zero, 8(a0) - sd zero, 16(a0) - sd zero, 24(a0) - sd zero, 32(a0) - sd zero, 40(a0) - sd zero, 48(a0) - sd zero, 56(a0) - addiu a0, 128 - sd zero, -64(a0) - sd zero, -56(a0) - sd zero, -48(a0) - sd zero, -40(a0) - sd zero, -32(a0) - sd zero, -24(a0) - sd zero, -16(a0) - sd zero, -8(a0) - bne AT, a0, 1b - jr ra - END(r4k_clear_page_s128) - -/* - * This is suboptimal for 32-bit kernels; we assume that R10000 is only used - * with 64-bit kernels. The prefetch offsets have been experimentally tuned - * an Origin 200. - */ -LEAF(andes_clear_page) - .set mips4 - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 7, 512(a0) - sd zero, 0*SZREG(a0) - sd zero, 1*SZREG(a0) - sd zero, 2*SZREG(a0) - sd zero, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - sd zero, -4*SZREG(a0) - sd zero, -3*SZREG(a0) - sd zero, -2*SZREG(a0) - sd zero, -1*SZREG(a0) - bne AT, a0, 1b - j ra - END(andes_clear_page) - .set mips0 - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -LEAF(r4k_copy_page_d16) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - cache Create_Dirty_Excl_D, 16(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - cache Create_Dirty_Excl_D, -16(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_d16) - -LEAF(r4k_copy_page_d32) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_d32) - -/* - * Again a special version for the R4600 V1.x - */ - -LEAF(r4k_copy_page_r4600_v1) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - nop - nop - nop - nop - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_r4600_v1) - -LEAF(r4k_copy_page_r4600_v2) - .set mips3 - mfc0 v1, CP0_STATUS - ori AT, v1, 1 - xori AT, 1 - - mtc0 AT, CP0_STATUS - nop - nop - nop - - addiu AT, a0, _PAGE_SIZE -1: nop - nop - nop - nop - cache Create_Dirty_Excl_D, (a0) - lw t1, (a1) - lw t0, 4(a1) - lw a3, 8(a1) - lw a2, 12(a1) - sw t1, (a0) - sw t0, 4(a0) - sw a3, 8(a0) - sw a2, 12(a0) - lw t1, 16(a1) - lw t0, 20(a1) - lw a3, 24(a1) - lw a2, 28(a1) - sw t1, 16(a0) - sw t0, 20(a0) - sw a3, 24(a0) - sw a2, 28(a0) - nop - nop - nop - nop - cache Create_Dirty_Excl_D, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw t1, -32(a1) - lw t0, -28(a1) - lw a3, -24(a1) - lw a2, -20(a1) - sw t1, -32(a0) - sw t0, -28(a0) - sw a3, -24(a0) - sw a2, -20(a0) - lw t1, -16(a1) - lw t0, -12(a1) - lw a3, -8(a1) - lw a2, -4(a1) - sw t1, -16(a0) - sw t0, -12(a0) - sw a3, -8(a0) - sw a2, -4(a0) - bne AT, a0, 1b - - mfc0 AT, CP0_STATUS # __restore_flags - andi v1, 1 - ori AT, 1 - xori AT, 1 - or v1, AT - mtc0 v1, CP0_STATUS - nop - nop - nop - jr ra - END(r4k_copy_page_r4600_v2) - -/* - * These are for R4000SC / R4400MC - */ - -LEAF(r4k_copy_page_s16) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - cache Create_Dirty_Excl_SD, 16(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_SD, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - cache Create_Dirty_Excl_SD, -16(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s16) - -LEAF(r4k_copy_page_s32) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - cache Create_Dirty_Excl_SD, 32(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s32) - -LEAF(r4k_copy_page_s64) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - addiu a0, 64 - addiu a1, 64 - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s64) - -LEAF(r4k_copy_page_s128) - .set mips3 - addiu AT, a0, _PAGE_SIZE -1: cache Create_Dirty_Excl_SD, (a0) - lw a3, (a1) - lw a2, 4(a1) - lw v1, 8(a1) - lw v0, 12(a1) - sw a3, (a0) - sw a2, 4(a0) - sw v1, 8(a0) - sw v0, 12(a0) - lw a3, 16(a1) - lw a2, 20(a1) - lw v1, 24(a1) - lw v0, 28(a1) - sw a3, 16(a0) - sw a2, 20(a0) - sw v1, 24(a0) - sw v0, 28(a0) - lw a3, 32(a1) - lw a2, 36(a1) - lw v1, 40(a1) - lw v0, 44(a1) - sw a3, 32(a0) - sw a2, 36(a0) - sw v1, 40(a0) - sw v0, 44(a0) - lw a3, 48(a1) - lw a2, 52(a1) - lw v1, 56(a1) - lw v0, 60(a1) - sw a3, 48(a0) - sw a2, 52(a0) - sw v1, 56(a0) - sw v0, 60(a0) - addiu a0, 128 - addiu a1, 128 - lw a3, -64(a1) - lw a2, -60(a1) - lw v1, -56(a1) - lw v0, -52(a1) - sw a3, -64(a0) - sw a2, -60(a0) - sw v1, -56(a0) - sw v0, -52(a0) - lw a3, -48(a1) - lw a2, -44(a1) - lw v1, -40(a1) - lw v0, -36(a1) - sw a3, -48(a0) - sw a2, -44(a0) - sw v1, -40(a0) - sw v0, -36(a0) - lw a3, -32(a1) - lw a2, -28(a1) - lw v1, -24(a1) - lw v0, -20(a1) - sw a3, -32(a0) - sw a2, -28(a0) - sw v1, -24(a0) - sw v0, -20(a0) - lw a3, -16(a1) - lw a2, -12(a1) - lw v1, -8(a1) - lw v0, -4(a1) - sw a3, -16(a0) - sw a2, -12(a0) - sw v1, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(r4k_copy_page_s128) - - - .text - .set mips4 - .set noat - - -/* - * This is suboptimal for 32-bit kernels; we assume that R10000 is only used - * with 64-bit kernels. The prefetch offsets have been experimentally tuned - * an Origin 200. - */ -LEAF(andes_copy_page) - .set mips4 - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 0, 2*128(a1) - pref 1, 2*128(a0) - LONG_L a3, 0*SZREG(a1) - LONG_L a2, 1*SZREG(a1) - LONG_L v1, 2*SZREG(a1) - LONG_L v0, 3*SZREG(a1) - LONG_S a3, 0*SZREG(a0) - LONG_S a2, 1*SZREG(a0) - LONG_S v1, 2*SZREG(a0) - LONG_S v0, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - LONG_ADDIU a1, a1, 8*SZREG - LONG_L a3, -4*SZREG(a1) - LONG_L a2, -3*SZREG(a1) - LONG_L v1, -2*SZREG(a1) - LONG_L v0, -1*SZREG(a1) - LONG_S a3, -4*SZREG(a0) - LONG_S a2, -3*SZREG(a0) - LONG_S v1, -2*SZREG(a0) - LONG_S v0, -1*SZREG(a0) - bne AT, a0,1b - j ra - END(andes_copy_page) - .set mips0 - -/* This one still needs to receive cache optimizations */ -LEAF(pgd_init) - .set mips0 - addiu AT, a0, PGD_SIZE / 2 - la v0, invalid_pte_table -1: sw v0, (a0) - sw v0, 4(a0) - sw v0, 8(a0) - sw v0, 12(a0) - addiu a0, 32 - sw v0, -16(a0) - sw v0, -12(a0) - sw v0, -8(a0) - sw v0, -4(a0) - bne AT, a0, 1b - jr ra - END(pgd_init) diff -urN linux-2.4.24/arch/mips/mm/pg-r4k.c linux-2.4.25/arch/mips/mm/pg-r4k.c --- linux-2.4.24/arch/mips/mm/pg-r4k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/mm/pg-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,471 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Maximum sizes: + * + * R4000 16 bytes D-cache, 128 bytes S-cache: 0x78 bytes + * R4600 v1.7: 0x5c bytes + * R4600 v2.0: 0x60 bytes + * With prefetching, 16 byte strides 0xa0 bytes + */ + +static unsigned int clear_page_array[0xa0 / 4]; + +void clear_page(void * page) __attribute__((alias("clear_page_array"))); + +/* + * Maximum sizes: + * + * R4000 16 bytes D-cache, 128 bytes S-cache: 0xbc bytes + * R4600 v1.7: 0x80 bytes + * R4600 v2.0: 0x84 bytes + * With prefetching, 16 byte strides 0xb8 bytes + */ +static unsigned int copy_page_array[0xb8 / 4]; + +void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); + +/* + * An address fits into a single register so it's safe to use 64-bit registers + * if we have 64-bit adresses. + */ +#define cpu_has_64bit_registers cpu_has_64bit_addresses + +/* + * This is suboptimal for 32-bit kernels; we assume that R10000 is only used + * with 64-bit kernels. The prefetch offsets have been experimentally tuned + * an Origin 200. + */ +static int pref_offset_clear __initdata = 512; +static int pref_offset_copy __initdata = 256; + +static unsigned int pref_src_mode __initdata; +static unsigned int pref_dst_mode __initdata; + +static int has_scache __initdata = 0; +static int load_offset __initdata = 0; +static int store_offset __initdata = 0; + +static unsigned int __initdata *dest, *epc; + +static inline void build_src_pref(int advance) +{ + if (!(load_offset & (cpu_dcache_line_size() - 1))) { + union mips_instruction mi; + + mi.i_format.opcode = pref_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = pref_src_mode; + mi.i_format.simmediate = load_offset + advance; + + *epc++ = mi.word; + } +} + +static inline void __build_load_reg(int reg) +{ + union mips_instruction mi; + + if (cpu_has_64bit_registers) + mi.i_format.opcode = ld_op; + else + mi.i_format.opcode = lw_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = reg; /* $zero */ + mi.i_format.simmediate = load_offset; + + load_offset += (cpu_has_64bit_registers ? 8 : 4); + + *epc++ = mi.word; +} + +static inline void build_load_reg(int reg) +{ + if (cpu_has_prefetch) + build_src_pref(pref_offset_copy); + + __build_load_reg(reg); +} + +static inline void build_dst_pref(int advance) +{ + if (!(store_offset & (cpu_dcache_line_size() - 1))) { + union mips_instruction mi; + + mi.i_format.opcode = pref_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = pref_dst_mode; + mi.i_format.simmediate = store_offset + advance; + + *epc++ = mi.word; + } +} + +static inline void build_cdex(void) +{ + union mips_instruction mi; + + if (cpu_has_cache_cdex_s && + !(store_offset & (cpu_scache_line_size() - 1))) { + + mi.c_format.opcode = cache_op; + mi.c_format.rs = 4; /* $a0 */ + mi.c_format.c_op = 3; /* Create Dirty Exclusive */ + mi.c_format.cache = 3; /* Secondary Data Cache */ + mi.c_format.simmediate = store_offset; + + *epc++ = mi.word; + } + + if (store_offset & (cpu_dcache_line_size() - 1)) + return; + + if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) { + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + } + + mi.c_format.opcode = cache_op; + mi.c_format.rs = 4; /* $a0 */ + mi.c_format.c_op = 3; /* Create Dirty Exclusive */ + mi.c_format.cache = 1; /* Data Cache */ + mi.c_format.simmediate = store_offset; + + *epc++ = mi.word; +} + +static inline void __build_store_zero_reg(void) +{ + union mips_instruction mi; + + if (cpu_has_64bits) + mi.i_format.opcode = sd_op; + else + mi.i_format.opcode = sw_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 0; /* $zero */ + mi.i_format.simmediate = store_offset; + + store_offset += (cpu_has_64bits ? 8 : 4); + + *epc++ = mi.word; +} + +static inline void __build_store_reg(int reg) +{ + union mips_instruction mi; + int reg_size; + +#ifdef CONFIG_MIPS32 + if (cpu_has_64bit_registers && reg == 0) { + mi.i_format.opcode = sd_op; + reg_size = 8; + } else { + mi.i_format.opcode = sw_op; + reg_size = 4; + } +#endif +#ifdef CONFIG_MIPS64 + mi.i_format.opcode = sd_op; + reg_size = 8; +#endif + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = reg; /* $zero */ + mi.i_format.simmediate = store_offset; + + store_offset += reg_size; + + *epc++ = mi.word; +} + +static inline void build_store_reg(int reg) +{ + if (cpu_has_prefetch) + if (reg) + build_dst_pref(pref_offset_copy); + else + build_dst_pref(pref_offset_clear); + else if (cpu_has_cache_cdex_p) + build_cdex(); + + __build_store_reg(reg); +} + +static inline void build_addiu_at_a0(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 1; /* $at */ + mi.i_format.simmediate = offset; + + *epc++ = mi.word; +} + +static inline void build_addiu_a1(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = 5; /* $a1 */ + mi.i_format.simmediate = offset; + + load_offset -= offset; + + *epc++ = mi.word; +} + +static inline void build_addiu_a0(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 4; /* $a0 */ + mi.i_format.simmediate = offset; + + store_offset -= offset; + + *epc++ = mi.word; +} + +static inline void build_bne(unsigned int *dest) +{ + union mips_instruction mi; + + mi.i_format.opcode = bne_op; + mi.i_format.rs = 1; /* $at */ + mi.i_format.rt = 4; /* $a0 */ + mi.i_format.simmediate = dest - epc - 1; + + *epc++ = mi.word; +} + +static inline void build_nop(void) +{ + *epc++ = 0; +} + +static inline void build_jr_ra(void) +{ + union mips_instruction mi; + + mi.r_format.opcode = spec_op; + mi.r_format.rs = 31; + mi.r_format.rt = 0; + mi.r_format.rd = 0; + mi.r_format.re = 0; + mi.r_format.func = jr_op; + + *epc++ = mi.word; +} + +void __init build_clear_page(void) +{ + epc = (unsigned int *) &clear_page_array; + + if (cpu_has_prefetch) { + switch (current_cpu_data.cputype) { + case CPU_R10000: + case CPU_R12000: + pref_src_mode = Pref_LoadStreamed; + pref_dst_mode = Pref_StoreRetained; + break; + default: + pref_src_mode = Pref_LoadStreamed; + pref_dst_mode = Pref_PrepareForStore; + break; + } + } + + build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); + + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) { + *epc++ = 0x40026000; /* mfc0 $v0, $12 */ + *epc++ = 0x34410001; /* ori $at, v0, 0x1 */ + *epc++ = 0x38210001; /* xori $at, at, 0x1 */ + *epc++ = 0x40816000; /* mtc0 $at, $12 */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x3c01a000; /* lui $at, 0xa000 */ + *epc++ = 0x8c200000; /* lw $zero, ($at) */ + } + +dest = epc; + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + } + build_addiu_a0(2 * store_offset); + build_store_reg(0); + build_store_reg(0); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + } + build_store_reg(0); + build_bne(dest); + build_store_reg(0); + + if (cpu_has_prefetch && pref_offset_clear) { + build_addiu_at_a0(pref_offset_clear); + dest = epc; + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + build_addiu_a0(2 * store_offset); + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + build_bne(dest); + __build_store_reg(0); + } + + build_jr_ra(); + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + *epc++ = 0x40826000; /* mtc0 $v0, $12 */ + else + build_nop(); + + flush_icache_range((unsigned long)&clear_page_array, + (unsigned long) epc); + + BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array)); +} + +void __init build_copy_page(void) +{ + epc = (unsigned int *) ©_page_array; + + build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); + + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) { + *epc++ = 0x40026000; /* mfc0 $v0, $12 */ + *epc++ = 0x34410001; /* ori $at, v0, 0x1 */ + *epc++ = 0x38210001; /* xori $at, at, 0x1 */ + *epc++ = 0x40816000; /* mtc0 $at, $12 */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x3c01a000; /* lui $at, 0xa000 */ + *epc++ = 0x8c200000; /* lw $zero, ($at) */ + } + +dest = epc; + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + build_store_reg(11); + if (has_scache && cpu_scache_line_size() == 128) { + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + build_store_reg(11); + } + build_addiu_a0(2 * store_offset); + build_addiu_a1(2 * load_offset); + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(11); + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + } + build_bne(dest); + build_store_reg(11); + + if (cpu_has_prefetch && pref_offset_copy) { + build_addiu_at_a0(pref_offset_copy); + dest = epc; + __build_load_reg( 8); + __build_load_reg( 9); + __build_load_reg(10); + __build_load_reg(11); + __build_store_reg( 8); + __build_store_reg( 9); + __build_store_reg(10); + __build_store_reg(11); + build_addiu_a0(2 * store_offset); + build_addiu_a1(2 * load_offset); + __build_load_reg( 8); + __build_load_reg( 9); + __build_load_reg(10); + __build_load_reg(11); + __build_store_reg( 8); + __build_store_reg( 9); + __build_store_reg(10); + build_bne(dest); + __build_store_reg(11); + } + + build_jr_ra(); + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + *epc++ = 0x40826000; /* mtc0 $v0, $12 */ + else + build_nop(); + + BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array)); +} diff -urN linux-2.4.24/arch/mips/mm/pg-sb1.c linux-2.4.25/arch/mips/mm/pg-sb1.c --- linux-2.4.24/arch/mips/mm/pg-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/pg-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -2,6 +2,7 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 2000 SiByte, Inc. + * Copyright (C) 2002, 2003 Broadcom Corporation * * Written by Justin Carlson of SiByte, Inc. * and Kip Walker of Broadcom Corp. @@ -40,8 +41,11 @@ #define SB1_PREF_STORE_STREAMED_HINT "5" #endif -/* These are the functions hooked by the memory management function pointers */ -void sb1_clear_page(void *page) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void clear_page_cpu(void *page) +#else +void clear_page(void *page) +#endif { /* * JDCXXX - This should be bottlenecked by the write buffer, but these @@ -80,7 +84,11 @@ } -void sb1_copy_page(void *to, void *from) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void copy_page_cpu(void *to, void *from) +#else +void copy_page(void *to, void *from) +#endif { /* * This should be optimized in assembly...can't use ld/sd, though, @@ -168,13 +176,13 @@ IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -void sb1_clear_page_dma(void *page) +void clear_page(void *page) { int cpu = smp_processor_id(); /* if the page is above Kseg0, use old way */ if (KSEGX(page) != K0BASE) - return sb1_clear_page(page); + return clear_page_cpu(page); page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); @@ -189,7 +197,7 @@ in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -void sb1_copy_page_dma(void *to, void *from) +void copy_page(void *to, void *from) { unsigned long from_phys = PHYSADDR(from); unsigned long to_phys = PHYSADDR(to); @@ -197,7 +205,7 @@ /* if either page is above Kseg0, use old way */ if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) - return sb1_copy_page(to, from); + return copy_page_cpu(to, from); page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); @@ -212,4 +220,4 @@ in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -#endif +#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */ diff -urN linux-2.4.24/arch/mips/mm/sc-rm7k.c linux-2.4.25/arch/mips/mm/sc-rm7k.c --- linux-2.4.24/arch/mips/mm/sc-rm7k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/sc-rm7k.c 2004-02-18 05:36:30.000000000 -0800 @@ -131,7 +131,7 @@ static void rm7k_sc_disable(void) { - set_c0_config(1<<3); /* CONF_SE */ + clear_c0_config(1<<3); /* CONF_SE */ } static inline int __init rm7k_sc_probe(void) @@ -142,11 +142,11 @@ if ((config >> 31) & 1) return 0; - printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + printk(KERN_INFO "Secondary cache size %ldK, linesize %ld bytes.\n", (scache_size >> 10), sc_lsize); - if ((config >> 3) & 1) - return; + if ((config >> 3) & 1) /* CONF_SE */ + return 1; printk(KERN_INFO "Enabling secondary cache..."); func(); diff -urN linux-2.4.24/arch/mips/mm/tlb-r4k.c linux-2.4.25/arch/mips/mm/tlb-r4k.c --- linux-2.4.24/arch/mips/mm/tlb-r4k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/tlb-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -170,6 +170,36 @@ } } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + /* We will need multiple versions of update_mmu_cache(), one that just * updates the TLB with the new pte(s), and another which also checks * for the R4k "end of page" hardware bug and does the needy. @@ -339,24 +369,22 @@ static void __init probe_tlb(unsigned long config) { + struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int reg; - reg = read_c0_prid() & 0xff00; - if (reg == PRID_IMP_RM7000 || !(config & (1 << 31))) - /* - * Not a MIPS32 compliant CPU. Config 1 register not - * supported, we assume R4k style. Cpu probing already figured - * out the number of tlb entries. - */ + /* + * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register + * is not supported, we assume R4k style. Cpu probing already figured + * out the number of tlb entries. + */ + if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) return; -#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) reg = read_c0_config1(); if (!((config >> 7) & 3)) - panic("No MMU present"); - else - current_cpu_data.tlbsize = ((reg >> 25) & 0x3f) + 1; -#endif + panic("No TLB present"); + + c->tlbsize = ((reg >> 25) & 0x3f) + 1; } void __init r4k_tlb_init(void) @@ -371,7 +399,7 @@ * be set for 4kb pages. */ probe_tlb(config); - write_c0_pagemask(PM_4K); + write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); diff -urN linux-2.4.24/arch/mips/mm/tlb-sb1.c linux-2.4.25/arch/mips/mm/tlb-sb1.c --- linux-2.4.24/arch/mips/mm/tlb-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/tlb-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,12 +18,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include #include extern char except_vec0_sb1[]; +#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1))) + /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) { @@ -35,6 +38,7 @@ ".set noreorder \n" ".set mips64 \n" ".set noat \n" + " tlbr \n" " dmfc0 $1, $10 \n" " dsrl32 %0, $1, 0 \n" " sll %1, $1, 0 \n" @@ -76,7 +80,6 @@ for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { write_c0_index(entry); printk("\n%02i ", entry); - tlb_read(); dump_cur_tlb_regs(); } printk("\n"); @@ -95,10 +98,13 @@ old_ctx = read_c0_entryhi() & ASID_MASK; write_c0_entrylo0(0); write_c0_entrylo1(0); - for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { - write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + + entry = read_c0_wired(); + while (entry < current_cpu_data.tlbsize) { + write_c0_entryhi(UNIQUE_ENTRYHI(entry)); write_c0_index(entry); tlb_write_indexed(); + entry++; } write_c0_entryhi(old_ctx); local_irq_restore(flags); @@ -110,7 +116,7 @@ * Use increments of the maximum page size (16MB), and check for duplicate * entries before doing a given write. Then, when we're safe from collisions * with the firmware, go back and give all the entries invalid addresses with - * the normal flush routine. + * the normal flush routine. Wired entries will be killed as well! */ void sb1_sanitize_tlb(void) { @@ -164,7 +170,7 @@ idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); - write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); if (idx < 0) continue; tlb_write_indexed(); @@ -196,7 +202,7 @@ if (idx < 0) goto finish; /* Make sure all entries differ. */ - write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); tlb_write_indexed(); finish: write_c0_entryhi(oldpid); @@ -204,13 +210,39 @@ local_irq_restore(flags); } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + tlb_write_indexed(); + } + + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} /* All entries common to a mm share an asid. To effectively flush these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { int cpu = smp_processor_id(); - if (cpu_context(cpu, mm) != 0) { drop_mmu_context(mm, cpu); } @@ -252,6 +284,34 @@ local_irq_restore(flags); } +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + tlb_write_indexed(); + + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); + + local_flush_tlb_all(); + local_irq_restore(flags); +} + /* * This is called from loadmmu.c. We have to set up all the * memory management function pointers, as well as initialize @@ -259,7 +319,8 @@ */ void sb1_tlb_init(void) { - write_c0_pagemask(PM_4K); + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); /* * We don't know what state the firmware left the TLB's in, so this is diff -urN linux-2.4.24/arch/mips/mm/tlbex-mips32.S linux-2.4.25/arch/mips/mm/tlbex-mips32.S --- linux-2.4.24/arch/mips/mm/tlbex-mips32.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/tlbex-mips32.S 2004-02-18 05:36:30.000000000 -0800 @@ -102,7 +102,7 @@ #endif nop mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, PGDIR_SHIFT # get pgd only bits + srl k0, k0, _PGDIR_SHIFT # get pgd only bits sll k0, k0, 2 addu k1, k1, k0 # add in pgd offset @@ -168,7 +168,7 @@ #define LOAD_PTE(pte, ptr) \ GET_PGD(pte, ptr) \ mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, PGDIR_SHIFT; \ + srl pte, pte, _PGDIR_SHIFT; \ sll pte, pte, 2; \ addu ptr, ptr, pte; \ mfc0 pte, CP0_BADVADDR; \ diff -urN linux-2.4.24/arch/mips/mm/tlbex-r4k.S linux-2.4.25/arch/mips/mm/tlbex-r4k.S --- linux-2.4.24/arch/mips/mm/tlbex-r4k.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/mm/tlbex-r4k.S 2004-02-18 05:36:30.000000000 -0800 @@ -32,21 +32,19 @@ #define PTE_S sd #define PTE_SRL dsrl #define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 #else #define PTE_L lw #define PTE_S sw #define PTE_SRL srl #define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 #endif +#define PTE_PAGE_SIZE (_PAGE_SIZE << _PTE_ORDER) +#define PTE_PAGE_SHIFT (_PAGE_SHIFT + _PTE_ORDER) +#define PTEP_INDX_MSK ((PTE_PAGE_SIZE - 1) & ~(_PTE_T_SIZE << 1 - 1)) +#define PTE_INDX_MSK ((PTE_PAGE_SIZE - 1) & ~(_PTE_T_SIZE - 1)) +#define PTE_INDX_SHIFT (PTE_PAGE_SHIFT - _PTE_T_LOG2) + /* * ABUSE of CPP macros 101. * @@ -72,7 +70,7 @@ GET_PGD(pte, ptr) \ mfc0 pte, CP0_BADVADDR; \ srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ + sll pte, pte, _PGD_T_LOG2; \ addu ptr, ptr, pte; \ mfc0 pte, CP0_BADVADDR; \ lw ptr, (ptr); \ @@ -86,9 +84,9 @@ * TMP as a scratch register. */ #define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ + ori ptr, ptr, _PTE_T_SIZE; \ + xori ptr, ptr, _PTE_T_SIZE; \ + PTE_L tmp, _PTE_T_SIZE(ptr); \ PTE_L ptr, 0(ptr); \ PTE_SRL tmp, tmp, 6; \ P_MTC0 tmp, CP0_ENTRYLO1; \ @@ -143,14 +141,22 @@ __INIT -#ifdef CONFIG_64BIT_PHYS_ADDR -#define GET_PTE_OFF(reg) -#elif CONFIG_CPU_VR41XX -#define GET_PTE_OFF(reg) srl reg, reg, 3 +/* + * Different for VR41xx because it supports 1k as smallest page size + */ +#ifdef CONFIG_CPU_VR41XX +#define BASE_VPN_SHIFT 6 +#else +#define BASE_VPN_SHIFT 4 +#endif + +#if (BASE_VPN_SHIFT- PTE_T_LOG2-1) > 0 +#define GET_PTE_OFF(reg) srl reg, reg, BASE_VPN_SHIFT-_PTE_T_LOG2-1 #else -#define GET_PTE_OFF(reg) srl reg, reg, 1 +#define GET_PTE_OFF(reg) #endif + /* * These handlers much be written in a relocatable manner * because based upon the cpu type an arbitrary one of the @@ -165,8 +171,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits - - sll k0, k0, 2 + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 # add in pgd offset mfc0 k0, CP0_CONTEXT # get context reg lw k1, (k1) @@ -174,15 +179,17 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 # add in offset PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_L k1, _PTE_T_SIZE(k1) # get odd pte PTE_SRL k0, k0, 6 # convert to entrylo0 P_MTC0 k0, CP0_ENTRYLO0 # load it PTE_SRL k1, k1, 6 # convert to entrylo1 P_MTC0 k1, CP0_ENTRYLO1 # load it b 1f + rm9000_tlb_hazard tlbwr # write random tlb entry 1: nop + rm9000_tlb_hazard eret # return from trap END(except_vec0_r4000) @@ -192,7 +199,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -200,7 +207,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) PTE_SRL k0, k0, 6 P_MTC0 k0, CP0_ENTRYLO0 PTE_SRL k1, k1, 6 @@ -228,7 +235,7 @@ mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits lw k1, pgd_current # get pgd pointer - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 # add in pgd offset lw k1, (k1) mfc0 k0, CP0_CONTEXT # get context reg @@ -236,7 +243,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 # add in offset PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_L k1, _PTE_T_SIZE(k1) # get odd pte PTE_SRL k0, k0, 6 # convert to entrylo0 P_MTC0 k0, CP0_ENTRYLO0 # load it PTE_SRL k1, k1, 6 # convert to entrylo1 @@ -260,7 +267,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits - sll k0, k0, 2 + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 # add in pgd offset mfc0 k0, CP0_CONTEXT # get context reg lw k1, (k1) @@ -268,7 +275,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 # add in offset PTE_L k0, 0(k1) # get even pte - PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_L k1, _PTE_T_SIZE(k1) # get odd pte PTE_SRL k0, k0, 6 # convert to entrylo0 P_MTC0 k0, CP0_ENTRYLO0 # load it PTE_SRL k1, k1, 6 # convert to entrylo1 @@ -283,7 +290,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -293,7 +300,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -315,7 +322,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -325,7 +332,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -347,7 +354,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -357,7 +364,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) PTE_SRL k0, k0, 6 P_MTC0 zero, CP0_ENTRYLO0 P_MTC0 k0, CP0_ENTRYLO0 @@ -378,7 +385,7 @@ GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - sll k0, k0, 2 # log2(sizeof(pgd_t) + sll k0, k0, _PGD_T_LOG2 addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) @@ -388,7 +395,7 @@ and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) - PTE_L k1, PTE_SIZE(k1) + PTE_L k1, _PTE_T_SIZE(k1) nop /* XXX */ tlbp PTE_SRL k0, k0, 6 @@ -453,6 +460,7 @@ #endif invalid_tlbl: #ifdef TLB_OPTIMIZE + .set mips3 /* Test present bit in entry. */ LOAD_PTE(k0, k1) R5K_HAZARD @@ -460,11 +468,13 @@ PTE_PRESENT(k0, k1, nopage_tlbl) PTE_MAKEVALID(k0, k1) PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: nop + rm9000_tlb_hazard .set mips3 eret .set mips0 @@ -486,11 +496,13 @@ PTE_WRITABLE(k0, k1, nopage_tlbs) PTE_MAKEWRITE(k0, k1) PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: nop + rm9000_tlb_hazard .set mips3 eret .set mips0 @@ -517,10 +529,12 @@ /* Now reload the entry into the tlb. */ PTE_RELOAD(k1, k0) + rm9000_tlb_hazard nop b 1f tlbwi 1: + rm9000_tlb_hazard nop .set mips3 eret @@ -530,4 +544,3 @@ nowrite_mod: DO_FAULT(1) END(handle_mod) - diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/Makefile linux-2.4.25/arch/mips/momentum/jaguar_atx/Makefile --- linux-2.4.24/arch/mips/momentum/jaguar_atx/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,20 @@ +# +# Makefile for Momentum Computer's Jaguar-ATX board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET:= jaguar_atx.o + +obj-y += mv-irq.o int-handler.o irq.o pci-irq.o pci.o prom.o reset.o setup.o + +obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/dbg_io.c linux-2.4.25/arch/mips/momentum/jaguar_atx/dbg_io.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/dbg_io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/dbg_io.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,126 @@ +#include + +#if defined(CONFIG_REMOTE_DEBUG) + +#include /* For the serial port location and base baud */ + +/* --- CONFIG --- */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +/* --- END OF CONFIG --- */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE OCELOT_SERIAL1_BASE +#define MAX_BAUD OCELOT_BASE_BAUD + +/* === END OF CONFIG === */ + +#define REG_OFFSET 4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +#endif diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/int-handler.S linux-2.4.25/arch/mips/momentum/jaguar_atx/int-handler.S --- linux-2.4.24/arch/mips/momentum/jaguar_atx/int-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/int-handler.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,132 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work: + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for Jaguar-ATX board. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#define __ASSEMBLY__ +#include +#include +#include +#include +#include +#include +#include "jaguar_atx_fpga.h" + +/* + * First level interrupt dispatcher for Ocelot-CS board + */ + .align 5 + NESTED(jaguar_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ + bnez t1, ll_sw0_irq + andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ + bnez t1, ll_sw1_irq + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_pcixa_irq + andi t1, t0, STATUSF_IP3 /* int1 hardware line */ + bnez t1, ll_pcixb_irq + andi t1, t0, STATUSF_IP4 /* int2 hardware line */ + bnez t1, ll_pcia_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t1, ll_pcib_irq + andi t1, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_uart_irq + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + + nop + nop + + /* now look at extended interrupts */ + mfc0 t0, CP0_CAUSE + cfc0 t1, CP0_S1_INTCONTROL + + /* shift the mask 8 bits left to line up the bits */ + sll t2, t1, 8 + + and t0, t2 + srl t0, t0, 16 + + andi t1, t0, STATUSF_IP8 /* int6 hardware line */ + bnez t1, ll_mv64340_decode_irq + + nop + nop + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(jaguar_handle_int) + + .align 5 +ll_sw0_irq: + li a0, 1 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_sw1_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_pcixa_irq: + li a0, 3 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_pcixb_irq: + li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_pcia_irq: + li a0, 5 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_pcib_irq: + li a0, 6 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_uart_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cputimer_irq: + li a0, 8 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_mv64340_decode_irq: + move a0, sp + jal ll_mv64340_irq + j ret_from_irq + diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/irq.c linux-2.4.25/arch/mips/momentum/jaguar_atx/irq.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2002 Momentum Computer, Inc. + * Author: Matthew Dharm, mdharm@momenco.com + * + * Based on work by: + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define read_32bit_cp0_set1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc0\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_set1_register(register,value) \ + __asm__ __volatile__( \ + "ctc0\t%0,"STR(register)"\n\t" \ + "nop" \ + : : "r" (value)); + +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_status(status); + + /* do the high 8 bits */ + clr_mask = 0xff & (clr_mask_in >> 8); + set_mask = 0xff & (set_mask_in >> 8); + status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_rm9000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(1 << (irq-1)); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_rm9000_irq(unsigned int irq) +{ + enable_rm9000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_rm9000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(1 << (irq-1)); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define shutdown_rm9000_irq disable_rm9000_irq + +static void mask_and_ack_rm9000_irq(unsigned int irq) +{ + mask_irq(1 << (irq-1)); +} + +static void end_rm9000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << (irq-1)); +} + +static struct hw_interrupt_type rm9000_hpcdma_irq_type = { + "RM9000", + startup_rm9000_irq, + shutdown_rm9000_irq, + enable_rm9000_irq, + disable_rm9000_irq, + mask_and_ack_rm9000_irq, + end_rm9000_irq, + NULL +}; + +extern void wired_reset(void); +extern void PMON_v2_setup(void); +extern asmlinkage void jaguar_handle_int(void); +extern void mv64340_irq_init(void); + +static struct irqaction cascade_mv64340 = + { no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL }; +static struct irqaction unused_irq = + { no_action, SA_INTERRUPT, 0, "unused", NULL, NULL }; + +void __init init_IRQ(void) +{ + int i; + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + __cli(); + + /* Sets the first-level interrupt dispatcher. */ + set_except_vector(0, jaguar_handle_int); + init_generic_irq(); + + /* set up handler for first 12 IRQs as the CPU */ + for (i = 0; i < 13; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &rm9000_hpcdma_irq_type; + } + + /* set up the cascading interrupts */ + setup_irq(9, &cascade_mv64340); + + /* mark unconnected IRQs as unconnected */ + setup_irq(10, &unused_irq); + + /* mark un-used IRQ numbers as unconnected */ + setup_irq(13, &unused_irq); + setup_irq(14, &unused_irq); + setup_irq(15, &unused_irq); + + mv64340_irq_init(); + +#ifdef CONFIG_REMOTE_DEBUG + printk("start kgdb ...\n"); + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif + +} diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h linux-2.4.25/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h --- linux-2.4.24/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,54 @@ +/* + * Jaguar-ATX Board Register Definitions + * + * (C) 2002 Momentum Computer Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __JAGUAR_ATX_FPGA_H__ +#define __JAGUAR_ATX_FPGA_H__ + +#ifdef CONFIG_MIPS64 +#define JAGUAR_ATX_CS0_ADDR (0xfffffffffc000000) +#else +#define JAGUAR_ATX_CS0_ADDR (0xfc000000) +#endif + +#define JAGUAR_ATX_REG_BOARDREV 0x0 +#define JAGUAR_ATX_REG_FPGA_REV 0x1 +#define JAGUAR_ATX_REG_FPGA_TYPE 0x2 +#define JAGUAR_ATX_REG_RESET_STATUS 0x3 +#define JAGUAR_ATX_REG_BOARD_STATUS 0x4 +#define JAGUAR_ATX_REG_RESERVED1 0x5 +#define JAGUAR_ATX_REG_SET 0x6 +#define JAGUAR_ATX_REG_CLR 0x7 +#define JAGUAR_ATX_REG_EEPROM_MODE 0x9 +#define JAGUAR_ATX_REG_RESERVED2 0xa +#define JAGUAR_ATX_REG_RESERVED3 0xb +#define JAGUAR_ATX_REG_RESERVED4 0xc +#define JAGUAR_ATX_REG_PHY_INTSTAT 0xd +#define JAGUAR_ATX_REG_RESERVED5 0xe +#define JAGUAR_ATX_REG_RESERVED6 0xf + +#define JAGUAR_FPGA_WRITE(x,y) writeb(x,JAGUAR_ATX_CS0_ADDR+JAGUAR_ATX_REG_##y) +#define JAGUAR_FPGA_READ(x) readb(JAGUAR_ATX_CS0_ADDR + JAGUAR_ATX_REG_##x) + +#endif diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/mv-irq.c linux-2.4.25/arch/mips/momentum/jaguar_atx/mv-irq.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/mv-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/mv-irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,166 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/jaguar_atx/mv-irq.c + * Interrupt routines for mv64340. Interrupt numbers are assigned from + * MV64340_IRQ_BASE to MV64340_IRQ_BASE+64. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern unsigned int do_IRQ(int irq, struct pt_regs *regs); + +#define MV64340_IRQ_BASE 16 + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 1 is enable, 0 is disable */ +static inline void mask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value &= ~(1 << (irq - MV64340_IRQ_BASE)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value &= ~(1 << (irq - (MV64340_IRQ_BASE - 32))); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* unmask an interrupt -- 1 is enable, 0 is disable */ +static inline void unmask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value |= 1 << (irq - MV64340_IRQ_BASE); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value |= 1 << (irq - (MV64340_IRQ_BASE - 32)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* + * Enables the IRQ on Marvell Chip + */ +static void enable_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); +} + +/* + * Initialize the IRQ on Marvell Chip + */ +static unsigned int startup_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); + return 0; +} + +/* + * Disables the IRQ on Marvell Chip + */ +static void disable_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_mv64340_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_mv64340_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the Marvell chip. + * It could be built in ethernet ports etc... + */ +void ll_mv64340_irq(struct pt_regs *regs) +{ + unsigned int irq_src_low, irq_src_high; + unsigned int irq_mask_low, irq_mask_high; + + /* read the interrupt status registers */ + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &irq_mask_low); + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &irq_mask_high); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW, &irq_src_low); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH, &irq_src_high); + + /* mask for just the interrupts we want */ + irq_src_low &= irq_mask_low; + irq_src_high &= irq_mask_high; + + if (irq_src_low) + do_IRQ(ls1bit32(irq_src_low) + MV64340_IRQ_BASE, regs); + else + do_IRQ(ls1bit32(irq_src_high) + MV64340_IRQ_BASE + 32, regs); +} + +#define shutdown_mv64340_irq disable_mv64340_irq + +struct hw_interrupt_type mv64340_irq_type = { + "MV-64340", + startup_mv64340_irq, + shutdown_mv64340_irq, + enable_mv64340_irq, + disable_mv64340_irq, + mask_and_ack_mv64340_irq, + end_mv64340_irq, + NULL +}; + +void mv64340_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = MV64340_IRQ_BASE; i < (MV64340_IRQ_BASE + 64); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &mv64340_irq_type; + } +} diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/pci-irq.c linux-2.4.25/arch/mips/momentum/jaguar_atx/pci-irq.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/pci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/pci-irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/jaguar/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include + + +void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + /* loop over all known devices on this bus */ + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1)) { + /* PCI-X A */ + devices->irq = 3; + } else if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PCI-X B */ + devices->irq = 4; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 1)) { + /* PCI A */ + devices->irq = 5; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PCI B */ + devices->irq = 6; + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master for everything but the MV-64340 */ + if (((current_bus->number != 0) && (current_bus->number != 1)) + || (PCI_SLOT(devices->devfn) != 0)) { + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } + } +} diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/pci.c linux-2.4.25/arch/mips/momentum/jaguar_atx/pci.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/pci.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,489 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PCI + +#define SELF 0 + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +void mv64340_board_pcibios_fixup_bus(struct pci_bus* c); + +/* Functions to implement "pci ops" */ +static int galileo_pcibios_read_config_word(struct pci_dev *dev, + int offset, u16 * val); +static int galileo_pcibios_read_config_byte(struct pci_dev *dev, + int offset, u8 * val); +static int galileo_pcibios_read_config_dword(struct pci_dev *dev, + int offset, u32 * val); +static int galileo_pcibios_write_config_byte(struct pci_dev *dev, + int offset, u8 val); +static int galileo_pcibios_write_config_word(struct pci_dev *dev, + int offset, u16 val); +static int galileo_pcibios_write_config_dword(struct pci_dev *dev, + int offset, u32 val); +static void galileo_pcibios_set_master(struct pci_dev *dev); + +/* + * General-purpose PCI functions. + */ + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* Accessing device 31 crashes the MV-64340. */ + if (dev < 5) + return 0; + return -1; +} + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int galileo_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_pcibios_read_config_word(struct pci_dev *device, + int offset, u16* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static void galileo_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); +} + +/* Externally-expected functions. Do not change function names */ + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + + galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); + } + + /* + * Let's fix up the latency timer and cache line size here. Cache + * line size = 32 bytes / sizeof dword (4) = 8. + * Latency timer must be > 8. 32 is random but appears to work. + */ + galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); + if (tmp1 != 8) { + printk(KERN_WARNING "PCI setting cache line size to 8 from " + "%d\n", tmp1); + galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + 8); + } + galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); + if (tmp1 < 32) { + printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", + tmp1); + galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, + 32); + } + + return 0; +} + +#if 0 +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + +void pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + return; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4 * resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* + * Somebody might have asked allocation of a non-standard + * resource + */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & + ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : + PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} +#endif + +struct pci_ops galileo_pci_ops = { + galileo_pcibios_read_config_byte, + galileo_pcibios_read_config_word, + galileo_pcibios_read_config_dword, + galileo_pcibios_write_config_byte, + galileo_pcibios_write_config_word, + galileo_pcibios_write_config_dword +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + mv64340_board_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + /* Reset PCI I/O and PCI MEM values */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &galileo_pci_ops, NULL); + pci_scan_bus(1, &galileo_pci_ops, NULL); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +#endif /* CONFIG_PCI */ diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/prom.c linux-2.4.25/arch/mips/momentum/jaguar_atx/prom.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,249 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] + * + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "jaguar_atx_fpga.h" + + +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long mv64340_base; +extern unsigned long cpu_clock; + +#ifdef CONFIG_MV64340_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +const char *get_system_type(void) +{ + return "Momentum Jaguar-ATX"; +} + +#ifdef CONFIG_MV64340_ETH +static void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +static u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + + +#ifdef CONFIG_MIPS64 + +unsigned long signext(unsigned long addr) +{ + addr &= 0xffffffff; + return (unsigned long)((int)addr); +} + +void *get_arg(unsigned long args, int arc) +{ + unsigned long ul; + unsigned char *puc, uc; + + args += (arc * 4); + ul = (unsigned long)signext(args); + puc = (unsigned char *)ul; + if (puc == 0) + return (void *)0; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + uc = *puc++; + ul = (unsigned long)uc; + uc = *puc++; + ul |= (((unsigned long)uc) << 8); + uc = *puc++; + ul |= (((unsigned long)uc) << 16); + uc = *puc++; + ul |= (((unsigned long)uc) << 24); +#else + uc = *puc++; + ul = ((unsigned long)uc) << 24; + uc = *puc++; + ul |= (((unsigned long)uc) << 16); + uc = *puc++; + ul |= (((unsigned long)uc) << 8); + uc = *puc++; + ul |= ((unsigned long)uc); +#endif + ul = signext(ul); + return (void *)ul; +} + +char *arg64(unsigned long addrin, int arg_index) +{ + unsigned long args; + char *p; + args = signext(addrin); + p = (char *)get_arg(args, arg_index); + return p; +} +#endif /* CONFIG_MIPS64 */ + +/* PMON passes arguments in C main() style */ +void __init prom_init(int argc, char **arg, char **env, struct callvectors *cv) +{ + int i; +#ifdef CONFIG_MIPS64 + char *ptr; + + printk("Mips64 Jaguar-ATX\n"); + /* save the PROM vectors for debugging use */ + debug_vectors = (struct callvectors *)signext((unsigned long)cv); + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + + for (i = 1; i < argc; i++) { + ptr = (char *)arg64((unsigned long)arg, i); + if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= + sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ptr); + strcat(arcs_cmdline, " "); + } + + i = 0; + while (1) { + ptr = (char *)arg64((unsigned long)env, i); + if (! ptr) + break; + + if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(ptr + strlen("gtbase="), + NULL, 16); + + if ((mv64340_base & 0xffffffff00000000) == 0) + mv64340_base |= 0xffffffff00000000; + + printk("mv64340_base set to 0x%016lx\n", mv64340_base); + } + if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(ptr + strlen("cpuclock="), + NULL, 10); + printk("cpu_clock set to %d\n", cpu_clock); + } + i++; + } + printk("arcs_cmdline: %s\n", arcs_cmdline); + +#else /* CONFIG_MIPS64 */ + /* save the PROM vectors for debugging use */ + debug_vectors = cv; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + while (*env) { + if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + } + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(*env + strlen("cpuclock="), + NULL, 10); + } + env++; + } +#endif /* CONFIG_MIPS64 */ + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_JAGUAR_ATX; + +#ifdef CONFIG_MV64340_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + +#ifndef CONFIG_MIPS64 + debug_vectors->printf("Booting Linux kernel...\n"); +#endif +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/reset.c linux-2.4.25/arch/mips/momentum/jaguar_atx/reset.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/reset.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void momenco_jaguar_restart(char *command) +{ + /* base address of timekeeper portion of part */ +#ifdef CONFIG_MIPS64 + void *nvram = (void*) 0xfffffffffc807000; +#else + void *nvram = (void*) 0xfc807000; +#endif + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ + writeb(0x84, nvram + 0xff7); + + /* wait for the watchdog to go off */ + mdelay(100+(1000/16)); + + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +void momenco_jaguar_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void momenco_jaguar_power_off(void) +{ + momenco_jaguar_halt(); +} diff -urN linux-2.4.24/arch/mips/momentum/jaguar_atx/setup.c linux-2.4.25/arch/mips/momentum/jaguar_atx/setup.c --- linux-2.4.24/arch/mips/momentum/jaguar_atx/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/jaguar_atx/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,362 @@ +/* + * setup.c + * + * BRIEF MODULE DESCRIPTION + * Momentum Computer Jaguar-ATX board dependent boot routines + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2002 Momentum Computer + * + * Author: Matthew Dharm, Momentum Computer + * mdharm@momenco.com + * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] + * + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "jaguar_atx_fpga.h" + + +unsigned long mv64340_base; +extern unsigned long mv64340_sram_base; +unsigned long cpu_clock; + +/* These functions are used for rebooting or halting the machine*/ +extern void momenco_jaguar_restart(char *command); +extern void momenco_jaguar_halt(void); +extern void momenco_jaguar_power_off(void); + +void momenco_time_init(void); + +static char reset_reason; + +#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) + +void __init bus_error_init(void) { /* nothing */ } + +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup(void) +{ + /* Some wired TLB entries for the MV64340 and perhiperals. The + MV64340 is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) + + Device Physical Virtual + MV64340 Internal Regs 0xf4000000 0xf4000000 + Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000 + NVRAM (CS1) 0xfc800000 0xfc800000 + UARTs (CS2) 0xfd000000 0xfd000000 + Internal SRAM 0xfe000000 0xfe000000 + M-Systems DOC (CS3) 0xff000000 0xff000000 + */ + printk("PMON_v2_setup\n"); + +#ifdef CONFIG_MIPS64 + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); + + mv64340_base = 0xfffffffff4000000; + mv64340_sram_base = 0xfffffffffe000000; +#else + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); + + mv64340_base = 0xf4000000; + mv64340_sram_base = 0xfe000000; +#endif +} + +#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) +#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) + +unsigned long m48t37y_get_time(void) +{ +#ifdef CONFIG_MIPS64 + unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000; +#else + unsigned char *rtc_base = (unsigned char*)0xfc800000; +#endif + unsigned int year, month, day, hour, min, sec; + + /* stop the update */ + rtc_base[0x7ff8] = 0x40; + + year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); + year += CONV_BCD_TO_BIN(rtc_base[0x7ff1]) * 100; + + month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); + + day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); + + hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); + min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); + sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + + /* start the update */ + rtc_base[0x7ff8] = 0x00; + + return mktime(year, month, day, hour, min, sec); +} + +int m48t37y_set_time(unsigned long sec) +{ +#ifdef CONFIG_MIPS64 + unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000; +#else + unsigned char *rtc_base = (unsigned char*)0xfc800000; +#endif + struct rtc_time tm; + + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; + + /* enable writing */ + rtc_base[0x7ff8] = 0x80; + + /* year */ + rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + + /* month */ + rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + + /* day */ + rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + + /* hour/min/sec */ + rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); + rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); + rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + + /* disable writing */ + rtc_base[0x7ff8] = 0x00; + + return 0; +} + +void momenco_timer_setup(struct irqaction *irq) +{ + setup_irq(8, irq); +} + +void momenco_time_init(void) +{ + mips_hpt_frequency = cpu_clock / 2; + board_timer_setup = momenco_timer_setup; + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; +} + +void __init momenco_jaguar_atx_setup(void) +{ + unsigned int tmpword; + + board_time_init = momenco_time_init; + + _machine_restart = momenco_jaguar_restart; + _machine_halt = momenco_jaguar_halt; + _machine_power_off = momenco_jaguar_power_off; + + /* + * initrd_start = (ulong)jaguar_initrd_start; + * initrd_end = (ulong)jaguar_initrd_start + (ulong)jaguar_initrd_size; + * initrd_below_start_ok = 1; + */ + + /* do handoff reconfiguration */ + PMON_v2_setup(); + + /* shut down ethernet ports, just to be sure our memory doesn't get + * corrupted by random ethernet traffic. + */ + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); + + /* Turn off the Bit-Error LED */ + JAGUAR_FPGA_WRITE(0x80, CLR); + + tmpword = JAGUAR_FPGA_READ(BOARDREV); + if (tmpword < 26) + printk("Momentum Jaguar-ATX: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momentum Jaguar-ATX: Board Assembly Revision #0x%x\n", + tmpword); + + tmpword = JAGUAR_FPGA_READ(FPGA_REV); + printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = JAGUAR_FPGA_READ(RESET_STATUS); + printk("Reset reason: 0x%x\n", tmpword); + switch (tmpword) { + case 0x1: + printk(" - Power-up reset\n"); + break; + case 0x2: + printk(" - Push-button reset\n"); + break; + case 0x8: + printk(" - Watchdog reset\n"); + break; + case 0x10: + printk(" - JTAG reset\n"); + break; + default: + printk(" - Unknown reset cause\n"); + } + reset_reason = tmpword; + JAGUAR_FPGA_WRITE(0xff, RESET_STATUS); + + tmpword = JAGUAR_FPGA_READ(BOARD_STATUS); + printk("Board Status register: 0x%02x\n", tmpword); + printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); + printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); + + /* 256MiB of RM9000x2 DDR */ +// add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM); + + /* 128MiB of MV-64340 DDR */ +// add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM); + + /* XXX Memory configuration should be picked up from PMON2k */ +#ifdef CONFIG_JAGUAR_DMALOW + printk("Jaguar ATX DMA-low mode set\n"); + add_memory_region(0x00000000, 0x08000000, BOOT_MEM_RAM); + add_memory_region(0x08000000, 0x10000000, BOOT_MEM_RAM); +#else + /* 128MiB of MV-64340 DDR RAM */ + printk("Jaguar ATX DMA-low mode is not set\n"); + add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM); +#endif + +#ifdef GEMDEBUG_TRACEBUFFER + { + unsigned int tbControl; + tbControl = + 0 << 26 | /* post trigger delay 0 */ + 0x2 << 16 | /* sequential trace mode */ + // 0x0 << 16 | /* non-sequential trace mode */ + // 0xf << 4 | /* watchpoints disabled */ + 2 << 2 | /* armed */ + 2 ; /* interrupt disabled */ + printk ("setting tbControl = %08lx\n", tbControl); + write_32bit_cp0_set1_register($22, tbControl); + __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t"); + + } +#endif +} + + +#ifndef CONFIG_MIPS64 +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ +static int io_base_ioremap(void) +{ + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); + + printk("*** io_base_ioremap\n"); + if (!io_remap_range) { + panic("Could not ioremap I/O port range"); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); + + return 0; +} + +module_init(io_base_ioremap); +#endif diff -urN linux-2.4.24/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h linux-2.4.25/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h --- linux-2.4.24/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 2004-02-18 05:36:30.000000000 -0800 @@ -22,11 +22,19 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] */ + #ifndef __OCELOT_C_FPGA_H__ #define __OCELOT_C_FPGA_H__ -#define OCELOT_C_CS0_ADDR (0xfc000000) +#ifdef CONFIG_MIPS64 +#define OCELOT_C_CS0_ADDR (0xfffffffffc000000) +#else +#define OCELOT_C_CS0_ADDR (0xfc000000) +#endif #define OCELOT_C_REG_BOARDREV 0x0 #define OCELOT_C_REG_FPGA_REV 0x1 diff -urN linux-2.4.24/arch/mips/momentum/ocelot_c/prom.c linux-2.4.25/arch/mips/momentum/ocelot_c/prom.c --- linux-2.4.24/arch/mips/momentum/ocelot_c/prom.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/momentum/ocelot_c/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -2,6 +2,9 @@ * Copyright 2002 Momentum Computer Inc. * Author: Matthew Dharm * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] + * * Based on Ocelot Linux port, which is * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net @@ -101,11 +104,107 @@ } #endif + +#ifdef CONFIG_MIPS64 + +unsigned long signext(unsigned long addr) +{ + addr &= 0xffffffff; + return (unsigned long)((int)addr); +} + +void *get_arg(unsigned long args, int arc) +{ + unsigned long ul; + unsigned char *puc, uc; + + args += (arc * 4); + ul = (unsigned long)signext(args); + puc = (unsigned char *)ul; + if (puc == 0) + return (void *)0; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + uc = *puc++; + ul = (unsigned long)uc; + uc = *puc++; + ul |= (((unsigned long)uc) << 8); + uc = *puc++; + ul |= (((unsigned long)uc) << 16); + uc = *puc++; + ul |= (((unsigned long)uc) << 24); +#else /* CONFIG_CPU_LITTLE_ENDIAN */ + uc = *puc++; + ul = ((unsigned long)uc) << 24; + uc = *puc++; + ul |= (((unsigned long)uc) << 16); + uc = *puc++; + ul |= (((unsigned long)uc) << 8); + uc = *puc++; + ul |= ((unsigned long)uc); +#endif /* CONFIG_CPU_LITTLE_ENDIAN */ + ul = signext(ul); + return (void *)ul; +} + +char *arg64(unsigned long addrin, int arg_index) +{ + unsigned long args; + char *p; + args = signext(addrin); + p = (char *)get_arg(args, arg_index); + return p; +} +#endif /* CONFIG_MIPS64 */ + + /* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) { int i; +#ifdef CONFIG_MIPS64 + char *ptr; + printk("prom_init - MIPS64\n"); + /* save the PROM vectors for debugging use */ + debug_vectors = (struct callvectors *)signext((unsigned long)cv); + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + + for (i = 1; i < argc; i++) { + ptr = (char *)arg64((unsigned long)arg, i); + if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= + sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ptr); + strcat(arcs_cmdline, " "); + } + i = 0; + while (1) { + ptr = (char *)arg64((unsigned long)env, i); + if (! ptr) + break; + + if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(ptr + strlen("gtbase="), + NULL, 16); + + if ((mv64340_base & 0xffffffff00000000) == 0) + mv64340_base |= 0xffffffff00000000; + + printk("mv64340_base set to 0x%016lx\n", mv64340_base); + } + if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(ptr + strlen("cpuclock="), + NULL, 10); + printk("cpu_clock set to %d\n", cpu_clock); + } + i++; + } + printk("arcs_cmdline: %s\n", arcs_cmdline); + +#else /* CONFIG_MIPS64 */ /* save the PROM vectors for debugging use */ debug_vectors = cv; @@ -119,9 +218,6 @@ strcat(arcs_cmdline, " "); } - mips_machgroup = MACH_GROUP_MOMENCO; - mips_machtype = MACH_MOMENCO_OCELOT_C; - while (*env) { if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { mv64340_base = simple_strtol(*env + strlen("gtbase="), @@ -133,13 +229,19 @@ } env++; } +#endif /* CONFIG_MIPS64 */ + + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_OCELOT_C; #ifdef CONFIG_MV64340_ETH /* get the base MAC address for on-board ethernet ports */ get_mac(prom_mac_addr_base); #endif +#ifndef CONFIG_MIPS64 debug_vectors->printf("Booting Linux kernel...\n"); +#endif } void __init prom_free_prom_memory(void) diff -urN linux-2.4.24/arch/mips/momentum/ocelot_c/reset.c linux-2.4.25/arch/mips/momentum/ocelot_c/reset.c --- linux-2.4.24/arch/mips/momentum/ocelot_c/reset.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/momentum/ocelot_c/reset.c 2004-02-18 05:36:30.000000000 -0800 @@ -10,6 +10,9 @@ * * Copyright (C) 2002 Momentum Computer Inc. * Author: Matthew Dharm + * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] */ #include #include @@ -23,7 +26,12 @@ void momenco_ocelot_restart(char *command) { /* base address of timekeeper portion of part */ - void *nvram = (void*) 0xfc807000; + void *nvram = (void *) +#ifdef CONFIG_MIPS64 + 0xfffffffffc807000; +#else + 0xfc807000; +#endif /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ writeb(0x84, nvram + 0xff7); diff -urN linux-2.4.24/arch/mips/momentum/ocelot_c/setup.c linux-2.4.25/arch/mips/momentum/ocelot_c/setup.c --- linux-2.4.24/arch/mips/momentum/ocelot_c/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/momentum/ocelot_c/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,6 +12,9 @@ * Author: Matthew Dharm, Momentum Computer * mdharm@momenco.com * + * Louis Hamilton, Red Hat, Inc. + * hamilton@redhat.com [MIPS64 modifications] + * * Author: RidgeRun, Inc. * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com * @@ -69,6 +72,7 @@ #include "ocelot_c_fpga.h" unsigned long mv64340_base; +extern unsigned long mv64340_sram_base; unsigned long cpu_clock; /* These functions are used for rebooting or halting the machine*/ @@ -80,6 +84,7 @@ static char reset_reason; +void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask); #define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) /* setup code for a handoff from a version 2 PMON 2000 PROM */ @@ -100,7 +105,19 @@ Internal SRAM 0xfe000000 0xfe000000 M-Systems DOC (CS3) 0xff000000 0xff000000 */ + printk("PMON_v2_setup\n"); + +#ifdef CONFIG_MIPS64 + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); + mv64340_base = 0xfffffffff4000000; + mv64340_sram_base = 0xfffffffffe000000; +#else /* marvell and extra space */ add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); /* fpga, rtc, and uart */ @@ -109,6 +126,8 @@ add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); mv64340_base = 0xf4000000; + mv64340_sram_base = 0xfe000000; +#endif } #define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) @@ -116,7 +135,11 @@ unsigned long m48t37y_get_time(void) { +#ifdef CONFIG_MIPS64 + unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000; +#else unsigned char* rtc_base = (unsigned char*)0xfc800000; +#endif unsigned int year, month, day, hour, min, sec; /* stop the update */ @@ -141,7 +164,11 @@ int m48t37y_set_time(unsigned long sec) { +#ifdef CONFIG_MIPS64 + unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000; +#else unsigned char* rtc_base = (unsigned char*)0xfc800000; +#endif struct rtc_time tm; /* convert to a more useful format -- note months count from 0 */ @@ -183,12 +210,13 @@ void momenco_time_init(void) { #ifdef CONFIG_CPU_SR71000 - mips_counter_frequency = cpu_clock; + mips_hpt_frequency = cpu_clock; #elif defined(CONFIG_CPU_RM7000) - mips_counter_frequency = cpu_clock / 2; + mips_hpt_frequency = cpu_clock / 2; #else #error Unknown CPU for this board #endif + printk("momenco_time_init cpu_clock=%d\n", cpu_clock); board_timer_setup = momenco_timer_setup; rtc_get_time = m48t37y_get_time; @@ -311,6 +339,7 @@ } } +#ifndef CONFIG_MIPS64 /* This needs to be one of the first initcalls, because no I/O port access can work before this */ static int io_base_ioremap(void) @@ -328,3 +357,4 @@ } module_init(io_base_ioremap); +#endif diff -urN linux-2.4.24/arch/mips/momentum/ocelot_g/prom.c linux-2.4.25/arch/mips/momentum/ocelot_g/prom.c --- linux-2.4.24/arch/mips/momentum/ocelot_g/prom.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/momentum/ocelot_g/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -40,7 +40,7 @@ extern unsigned long gt64240_base; extern unsigned long bus_clock; -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH extern unsigned char prom_mac_addr_base[6]; #endif @@ -71,7 +71,7 @@ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_G; -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH /* get the base MAC address for on-board ethernet ports */ memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); #endif diff -urN linux-2.4.24/arch/mips/momentum/ocelot_g/setup.c linux-2.4.25/arch/mips/momentum/ocelot_g/setup.c --- linux-2.4.24/arch/mips/momentum/ocelot_g/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/momentum/ocelot_g/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -70,7 +70,7 @@ extern struct rtc_ops no_rtc_ops; -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH extern unsigned char prom_mac_addr_base[6]; #endif @@ -141,7 +141,7 @@ /* do handoff reconfiguration */ PMON_v2_setup(); -#ifdef CONFIG_GALILLEO_GT64240_ETH +#ifdef CONFIG_GALILEO_GT64240_ETH /* get the mac addr */ memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); #endif diff -urN linux-2.4.24/arch/mips/pci/ops-nile4.c linux-2.4.25/arch/mips/pci/ops-nile4.c --- linux-2.4.24/arch/mips/pci/ops-nile4.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/pci/ops-nile4.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,4 +1,3 @@ -#include #include #include #include diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/Makefile linux-2.4.25/arch/mips/pmc-sierra/yosemite/Makefile --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,18 @@ +# +# Makefile for the PMC-Sierra Titan +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET:= titan.o + +obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o setup.o + +obj-$(CONFIG_PCI) += pci-irq.o pci.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_HYPERTRANSPORT) += ht-irq.o ht.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,171 @@ +/* + * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Description: + * + * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL + * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program + * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are + * expected to have a connectivity from the EEPROM to the serial port. This program does + * __not__ communicate using the I2C protocol + */ + +#include "atmel_read_eeprom.h" + +static void delay(int delay) +{ + while (delay--); +} + +static void send_bit(unsigned char bit) +{ + scl_lo; + delay(TXX); + if (bit) + sda_hi; + else + sda_lo; + + delay(TXX); + scl_hi; + delay(TXX); +} + +static void send_ack(void) +{ + send_bit(0); +} + +static void send_byte(unsigned char byte) +{ + int i = 0; + + for (i = 7; i >= 0; i--) + send_bit((byte >> i) & 0x01); +} + +static void send_start(void) +{ + sda_hi; + delay(TXX); + scl_hi; + delay(TXX); + sda_lo; + delay(TXX); +} + +static void send_stop(void) +{ + sda_lo; + delay(TXX); + scl_hi; + delay(TXX); + sda_hi; + delay(TXX); +} + +static void do_idle(void) +{ + sda_hi; + scl_hi; + vcc_off; +} + +static int recv_bit(void) +{ + int status; + + scl_lo; + delay(TXX); + sda_hi; + delay(TXX); + scl_hi; + delay(TXX); + + return 1; +} + +static unsigned char recv_byte(void) { + int i; + unsigned char byte=0; + + for (i=7;i>=0;i--) + byte |= (recv_bit() << i); + + return byte; +} + +static int recv_ack(void) +{ + unsigned int ack; + + ack = (unsigned int)recv_bit(); + scl_lo; + + if (ack) { + do_idle(); + printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n"); + return -1; + } + + return ack; +} + +/* + * This function does the actual read of the EEPROM. It needs the buffer into which the + * read data is copied, the size of the EEPROM being read and the buffer size + */ +int read_eeprom(char *buffer, int eeprom_size, int size) +{ + int i = 0, err; + + send_start(); + send_byte(W_HEADER); + recv_ack(); + + /* EEPROM with size of more then 2K need two byte addressing */ + if (eeprom_size > 2048) { + send_byte(0x00); + recv_ack(); + } + + send_start(); + send_byte(R_HEADER); + err = recv_ack(); + if (err == -1) + return err; + + for (i = 0; i < size; i++) { + *buffer++ = recv_byte(); + send_ack(); + } + + /* Note : We should do some check if the buffer contains correct information */ + + send_stop(); +} diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h linux-2.4.25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,68 @@ +/* + * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Header file for atmel_read_eeprom.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_PORT "/dev/ttyS0" /* Port to open */ +#define TXX 0 /* Dummy loop for spinning */ + +#define BLOCK_SEL 0x00 +#define SLAVE_ADDR 0xa0 +#define READ_BIT 0x01 +#define WRITE_BIT 0x00 +#define R_HEADER SLAVE_ADDR + BLOCK_SEL + READ_BIT +#define W_HEADER SLAVE_ADDR + BLOCK_SEL + WRITE_BIT + +/* + * Clock, Voltages and Data + */ +#define vcc_off (ioctl(fd, TIOCSBRK, 0)) +#define vcc_on (ioctl(fd, TIOCCBRK, 0)) +#define sda_hi (ioctl(fd, TIOCMBIS, &dtr)) +#define sda_lo (ioctl(fd, TIOCMBIC, &dtr)) +#define scl_lo (ioctl(fd, TIOCMBIC, &rts)) +#define scl_hi (ioctl(fd, TIOCMBIS, &rts)) + +const char rts = TIOCM_RTS; +const char dtr = TIOCM_DTR; +int fd; + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/ht-irq.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/ht-irq.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/ht-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/ht-irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,52 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +/* + * HT Bus fixup for the Titan + * XXX IRQ values need to change based on the board layout + */ +void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + } + + /* + * PLX and SPKT related changes go here + */ + +} diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/ht.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/ht.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/ht.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/ht.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,458 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_HYPERTRANSPORT + + +/* + * This function check if the Hypertransport Link Initialization completed. If + * it did, then proceed further with scanning bus #2 + */ +static __inline__ int check_titan_htlink(void) +{ + u32 val; + + val = *(volatile u_int32_t *)(RM9000x2_HTLINK_REG); + if (val & 0x00000020) + /* HT Link Initialization completed */ + return 1; + else + return 0; +} + +static int titan_ht_config_read_dword(struct pci_dev *device, + int offset, u32* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + RM9K_WRITE(address_reg, address); + RM9K_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int titan_ht_config_read_word(struct pci_dev *device, + int offset, u16* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + if ((offset & 0x3) == 0) + offset = 0x2; + else + offset = 0x0; + + RM9K_WRITE(address_reg, address); + RM9K_READ_16(data_reg + offset, val); + + return PCIBIOS_SUCCESSFUL; +} + + +u32 longswap(unsigned long l) +{ + unsigned char b1,b2,b3,b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((b1<<24) + (b2<<16) + (b3<<8) + b4); +} + + +static int titan_ht_config_read_byte(struct pci_dev *device, + int offset, u8* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + int offset1; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + RM9K_WRITE(address_reg, address); + + if ((offset & 0x3) == 0) { + offset1 = 0x3; + } + if ((offset & 0x3) == 1) { + offset1 = 0x2; + } + if ((offset & 0x3) == 2) { + offset1 = 0x1; + } + if ((offset & 0x3) == 3) { + offset1 = 0x0; + } + RM9K_READ_8(data_reg + offset1, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int titan_ht_config_write_dword(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + RM9K_WRITE(address_reg, address); + RM9K_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_write_word(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + if ((offset & 0x3) == 0) + offset = 0x2; + else + offset = 0x0; + + RM9K_WRITE(address_reg, address); + RM9K_WRITE_16(data_reg + offset, val); + + return PCIBIOS_SUCCESSFUL; +} + +static int titan_ht_config_write_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + int offset1; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* XXX Need to change the Bus # */ + if (bus > 2) + address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | + 0x80000000 | 0x1; + else + address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; + + address_reg = RM9000x2_OCD_HTCFGA; + data_reg = RM9000x2_OCD_HTCFGD; + + RM9K_WRITE(address_reg, address); + + if ((offset & 0x3) == 0) { + offset1 = 0x3; + } + if ((offset & 0x3) == 1) { + offset1 = 0x2; + } + if ((offset & 0x3) == 2) { + offset1 = 0x1; + } + if ((offset & 0x3) == 3) { + offset1 = 0x0; + } + + RM9K_WRITE_8(data_reg + offset1, val); + return PCIBIOS_SUCCESSFUL; +} + + +static void titan_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + int bus = dev->bus->number; + + if (check_titan_htlink()) + titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); + + cmd |= PCI_COMMAND_MASTER; + + if (check_titan_htlink()) + titan_ht_config_write_word(dev, PCI_COMMAND, cmd); +} + + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + int bus = dev->bus->number; + + if (check_titan_htlink()) + titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); + + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + if (check_titan_htlink()) + titan_ht_config_write_word(dev, PCI_COMMAND, cmd); + } + + if (check_titan_htlink()) + titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); + + if (tmp1 != 8) { + printk(KERN_WARNING "PCI setting cache line size to 8 from " + "%d\n", tmp1); + } + + if (check_titan_htlink()) + titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8); + + if (check_titan_htlink()) + titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1); + + if (tmp1 < 32 || tmp1 == 0xff) { + printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", + tmp1); + } + + if (check_titan_htlink()) + titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32); + + return 0; +} + + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + + + +void pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + return; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4 * resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* + * Somebody might have asked allocation of a non-standard + * resource + */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & + ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : + PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +struct pci_ops titan_pci_ops = { + titan_ht_config_read_byte, + titan_ht_config_read_word, + titan_ht_config_read_dword, + titan_ht_config_write_byte, + titan_ht_config_write_word, + titan_ht_config_write_dword +}; + + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + titan_ht_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + + /* Reset PCI I/O and PCI MEM values */ + /* XXX Need to add the proper values here */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + /* XXX Need to add bus values */ + pci_scan_bus(2, &titan_pci_ops, NULL); + pci_scan_bus(3, &titan_pci_ops, NULL); +} + +/* + * for parsing "pci=" kernel boot arguments. + */ +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + /* We want to use the PCI bus detection done by PMON */ + return 0; +} + +#endif /* CONFIG_HYPERTRANSPORT */ diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,186 @@ +/* + * arch/mips/pmc-sierra/yosemite/i2c-yosemite.c + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Detailed Description: + * + * This block implements the I2C interface to the slave devices like the Atmel 24C32 + * EEPROM and the MAX 1619 Sensors device. The I2C Master interface can be controlled + * by the SCMB block. And the SCMB block kicks in only when using the Ethernet Mode of + * operation and __not__ the SysAD mode + * + * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to communicate + * with the Quad-PHY from Marvel. The I2C is used to communicate with the I2C slave devices. + * It seems that the driver does not explicitly deal with the control of SDA and SCL serial + * lines. So, the driver will set the slave address, drive the command and then the data. + * The SCMB will then control the two serial lines as required. + * + * It seems the documents are very unclear abt this. Hence, I took some time out to write + * the desciption to have an idea of how the I2C can actually work. Currently, this Linux + * driver wont be integrated into the generic Linux I2C framework. And finally, the I2C + * interface is also known as the 2BI interface. 2BI means 2-bit interface referring to + * SDA and SCL serial lines respectively. + * + * - Manish Lachwani (12/09/2003) + */ + +#include "i2c-yosemite.h" + +/* + * Poll the I2C interface for the BUSY bit. + */ +static int titan_i2c_poll(void) +{ + int i = 0; + unsigned long val = 0; + + for (i = 0; i < TITAN_I2C_MAX_POLL; i++) { + val = TITAN_I2C_READ(TITAN_I2C_COMMAND); + + if ( !(val & 0x8000)) + return 0; + } + + return TITAN_I2C_ERR_TIMEOUT; +} + +/* + * Execute the I2C command + */ +int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command *cmd, + int size, unsigned int *addr) +{ + int loop = 0, bytes, i; + unsigned int *write_data, data, *read_data; + unsigned long reg_val, val; + + write_data = cmd->data; + read_data = addr; + + TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr); + + if (cmd->type == TITAN_I2C_CMD_WRITE) + loop = cmd->write_size; + else + loop = size; + + while (loop > 0) { + if ( (cmd->type == TITAN_I2C_CMD_WRITE) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE) ) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; ++i,write_data += 2, + reg_val += 4) { + if (bytes < cmd->write_size) { + data = write_data[0]; + ++data; + } + + if (bytes < cmd->write_size) { + data = write_data[1]; + ++data; + } + + TITAN_I2C_WRITE(reg_val, data); + } + } + + TITAN_I2C_WRITE(TITAN_I2C_COMMAND, (unsigned int)(cmd->type << 13)); + if (titan_i2c_poll() != TITAN_I2C_ERR_OK) + return TITAN_I2C_ERR_TIMEOUT; + + if ( (cmd->type == TITAN_I2C_CMD_READ) || + (cmd->type == TITAN_I2C_CMD_READ_WRITE) ) { + + reg_val = TITAN_I2C_DATA; + for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; ++i,read_data += 2, + reg_val += 4) { + data = TITAN_I2C_READ(reg_val); + + if (bytes < size) { + read_data[0] = data & 0xff; + ++bytes; + } + + if (bytes < size) { + read_data[1] = ((data >> 8) & 0xff); + ++bytes; + } + } + } + + loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2); + } + + /* + * Read the Interrupt status and then return the appropriate error code + */ + + val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS); + if (val & 0x0020) + return TITAN_I2C_ERR_ARB_LOST; + + if (val & 0x0040) + return TITAN_I2C_ERR_NO_RESP; + + if (val & 0x0080) + return TITAN_I2C_ERR_DATA_COLLISION; + + return TITAN_I2C_ERR_OK; +} + +/* + * Init the I2C subsystem of the PMC-Sierra Yosemite board + */ +int titan_i2c_init(titan_i2c_config *config) +{ + unsigned int val; + + /* + * Reset the SCMB and program into the I2C mode + */ + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000); + + /* + * Configure the filtera and clka values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A); + val |= ( (val & ~(0xF000)) | ( (config->filtera << 12) & 0xF000)); + val |= ( (val & ~(0x03FF)) | ( config->clka & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val); + + /* + * Configure the filterb and clkb values + */ + val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B); + val |= ( (val & ~(0xF000)) | ( (config->filterb << 12) & 0xF000)); + val |= ( (val & ~(0x03FF)) | ( config->clkb & 0x03FF)); + TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val); + + return TITAN_I2C_ERR_OK; +} diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h linux-2.4.25/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,96 @@ +/* + * arch/mips/pmc-sierra/yosemite/i2c-yosemite.h + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __I2C_YOSEMITE_H +#define __I2C_YOSEMITE_H + +/* Read and Write operations to the chip */ + +#define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */ + +#define TITAN_I2C_WRITE(offset, data) \ + *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data + +#define TITAN_I2C_READ(offset) *(volatile unsigned long *)(TITAN_I2C_BASE + offset) + + +/* Local constansts*/ +#define TITAN_I2C_MAX_FILTER 15 +#define TITAN_I2C_MAX_CLK 1023 +#define TITAN_I2C_MAX_ARBF 15 +#define TITAN_I2C_MAX_NAK 15 +#define TITAN_I2C_MAX_MASTERCODE 7 +#define TITAN_I2C_MAX_WORDS_PER_RW 4 +#define TITAN_I2C_MAX_POLL 100 + +/* Registers used for I2C work */ +#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */ +#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */ +#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */ +#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */ +#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */ +#define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */ +#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */ +#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */ + +/* Error */ +#define TITAN_I2C_ERR_ARB_LOST (-9220) +#define TITAN_I2C_ERR_NO_RESP (-9221) +#define TITAN_I2C_ERR_DATA_COLLISION (-9222) +#define TITAN_I2C_ERR_TIMEOUT (-9223) +#define TITAN_I2C_ERR_OK 0 + +/* I2C Command Type */ +typedef enum { + TITAN_I2C_CMD_WRITE = 0, + TITAN_I2C_CMD_READ = 1, + TITAN_I2C_CMD_READ_WRITE = 2 +} titan_i2c_cmd_type; + +/* I2C structures */ +typedef struct { + int filtera; /* Register 0x0184, bits 15 - 12*/ + int clka; /* Register 0x0184, bits 9 - 0 */ + int filterb; /* Register 0x0188, bits 15 - 12 */ + int clkb; /* Register 0x0188, bits 9 - 0 */ +} titan_i2c_config; + +/* I2C command type */ +typedef struct { + titan_i2c_cmd_type type; /* Type of command */ + int num_arb; /* Register 0x01a0, bits 15 - 12 */ + int num_nak; /* Register 0x01a0, bits 11 - 8 */ + int addr_size; /* Register 0x01a0, bit 7 */ + int mst_code; /* Register 0x01a0, bits 6 - 4 */ + int arb_en; /* Register 0x01a0, bit 1 */ + int speed; /* Register 0x01a0, bit 0 */ + int slave_addr; /* Register 0x01a8 */ + int write_size; /* Register 0x01a4, bits 10 - 8 */ + unsigned int *data; /* Register 0x01ac */ +} titan_i2c_command; + +#endif /* __I2C_YOSEMITE_H */ diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/irq-handler.S linux-2.4.25/arch/mips/pmc-sierra/yosemite/irq-handler.S --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/irq-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/irq-handler.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,128 @@ +/* + * Copyright 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com + * + * First-level interrupt router for the PMC-Sierra Titan board + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define __ASSEMBLY__ +#include +#include +#include +#include +#include +#include + +/* + * IRQ router for the Titan board + */ + + .align 5 + NESTED(titan_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP0 /* INTB0 hardware line */ + bnez t1, ll_pcia_irq /* 64-bit PCI */ + andi t1, t0, STATUSF_IP1 /* INTB1 hardware line */ + bnez t1, ll_pcib_irq /* second 64-bit PCI slot */ + andi t1, t0, STATUSF_IP2 /* INTB2 hardware line */ + bnez t1, ll_duart_irq /* UART */ + andi t1, t0, STATUSF_IP3 /* INTB3 hardware line*/ + bnez t1, ll_ht_smp_irq /* Hypertransport */ + andi t1, t0, STATUSF_IP5 /* INTB5 hardware line */ + bnez t1, ll_timer_irq /* Timer */ + + nop + nop + + /* Extended interrupts */ + mfc0 t0, CPU_CAUSE + cfc0 t1, CP0_S1_INTCONTROL + + sll t2, t1, 8 + + and t0, t2 + srl t0, t0, 16 + + + andi t1, t0, STATUSF_IP6 /* INTB6 hardware line */ + bnez t1, ll_phy0_irq /* Ethernet port 0 */ + andi t1, t0, STATUSF_IP7 /* INTB7 hardware line */ + bnez t1, ll_phy1_irq /* Ethernet port 1 */ + andi t1, t0, STATUSF_IP8 /* INTB8 hardware line */ + bnez t1, ll_phy2_irq /* Ethernet Port 2 */ + + nop + nop + + .set reorder + + /* No handler */ + j spurious_interrupt + nop + END(titan_handle_int) + + .align 5 + +/* Individual Handlers */ + +ll_pcia_irq: + li a0, 1 + move a2, sp + jal do_IRQ + j ret_from_irq + +ll_pcib_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_duart_irq: + li a0, 3 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ht_irq: + li a0, 4 + move a1, sp + jal ll_ht_smp_irq_handler /* Detailed HT & SMP IRQ handling */ + j ret_from_irq + +ll_timer_irq: + li a0, 5 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_phy0_irq: + li a0, 6 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_phy1_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_phy2_irq: + li a0, 8 + move a1, sp + jal do_IRQ + j ret_from_irq + + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/irq.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/irq.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Hypertransport specific */ +#define IRQ_STATUS_REG_CPU0 0xbb001b30 /* INT# 3 status register on CPU 0*/ +#define IRQ_STATUS_REG_CPU1 0xbb002b30 /* INT# 3 status register on CPU 1*/ +#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ +#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 0*/ +#define IRQ_CLEAR_REG_CPU0 0xbb002b3c /* IRQ clear register on CPU 1*/ + +#define HYPERTRANSPORT_EOI 0xbb0006E0 /* End of Interrupt */ +#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ +#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ +#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ +#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ + +#define read_32bit_cp0_set1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc0\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_set1_register(register,value) \ + __asm__ __volatile__( \ + "ctc0\t%0,"STR(register)"\n\t" \ + "nop" \ + : : "r" (value)); + +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8 | 0x0000FF00; + write_c0_status(status); + + /* do the high 8 bits */ + clr_mask = 0xff & (clr_mask_in >> 8); + set_mask = 0xff & (set_mask_in >> 8); + status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_rm9000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(1 << (irq-1)); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_rm9000_irq(unsigned int irq) +{ + enable_rm9000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_rm9000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(1 << (irq-1)); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define shutdown_rm9000_irq disable_rm9000_irq + +static void mask_and_ack_rm9000_irq(unsigned int irq) +{ + mask_irq(1 << (irq-1)); +} + +static void end_rm9000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << (irq-1)); +} + +static struct hw_interrupt_type rm9000_hpcdma_irq_type = { + "RM9000", + startup_rm9000_irq, + shutdown_rm9000_irq, + enable_rm9000_irq, + disable_rm9000_irq, + mask_and_ack_rm9000_irq, + end_rm9000_irq, + NULL +}; + +extern asmlinkage void titan_handle_int(void); +extern void jaguar_mailbox_irq(struct pt_regs *); + +/* + * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. For interprocessor + * interrupts, the best thing to do is to use the INTMSG register. We use the same external + * interrupt line, i.e. INTB3 and monitor another status bit + */ +asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) +{ + u32 status; + status = *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU0); + + /* Ack all the bits that correspond to the interrupt sources */ + if (status != 0) + *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU0) = IRQ_ACK_BITS; + + status = *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU1); + if (status != 0) + *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU1) = IRQ_ACK_BITS; + +#ifdef CONFIG_SMP + if (status == 0x2) { + /* This is an SMP IPI sent from one core to another */ + jaguar_mailbox_irq(regs); + goto done; + } +#endif + +#ifdef CONFIG_HT_LEVEL_TRIGGER + /* + * Level Trigger Mode only. Send the HT EOI message back to the source. + */ + switch (status) { + case 0x1000000: + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; + break; + case 0x2000000: + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; + break; + case 0x4000000: + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; + break; + case 0x8000000: + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; + break; + case 0x0000001: + /* PLX */ + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = 0x20; + *(volatile u_int32_t *)(IRQ_CLEAR_REG) = IRQ_ACK_BITS; + break; + case 0xf000000: + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA; + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB; + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC; + *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD; + break; + } +#endif /* CONFIG_HT_LEVEL_TRIGGER */ + +done: + if (status != 0x2) + /* Not for SMP */ + do_IRQ(irq, regs); +} + +/* + * Initialize the next level interrupt handler + */ +void __init init_IRQ(void) +{ + int i; + + clear_c0_status(ST0_IM | ST0_BEV); + __cli(); + + set_except_vector(0, titan_handle_int); + init_generic_irq(); + + for (i = 0; i < 13; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &rm9000_hpcdma_irq_type; + } +} + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/pci-irq.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/pci-irq.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/pci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/pci-irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,65 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +/* + * PCI Bus fixup for the Titan + * XXX IRQ values need to change based on the board layout + */ +void __init titan_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1)) { + /* PCI-X A */ + devices->irq = 3; + } else if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PCI-X B */ + devices->irq = 4; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 1)) { + /* PCI A */ + devices->irq = 5; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PCI B */ + devices->irq = 6; + } + } +} diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/pci.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/pci.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/pci.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,387 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +void titan_pcibios_fixup_bus(struct pci_bus* c); + +/* + * Titan PCI Config Dword Read + */ +static int titan_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* read the data */ + TITAN_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Config Word Read + */ +static int titan_pcibios_read_config_word(struct pci_dev *device, + int offset, u16* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* read the data */ + TITAN_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Config Read Byte + */ +static int titan_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* write the data */ + TITAN_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Config Write Dword + */ +static int titan_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* write the data */ + TITAN_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Config Write Word + */ +static int titan_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* write the data */ + TITAN_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Config Byte Write + */ +static int titan_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + address_reg = TITAN_PCI_0_CONFIG_ADDRESS; + data_reg = TITAN_PCI_0_CONFIG_DATA; + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + TITAN_WRITE(address_reg, address); + + /* write the data */ + TITAN_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Titan PCI Set Bus Master + */ +static void titan_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + titan_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + titan_pcibios_write_config_word(dev, PCI_COMMAND, cmd); +} + +/* + * Global export to pcibios_enable_resources + */ +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + + titan_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + titan_pcibios_write_config_word(dev, PCI_COMMAND, cmd); + } + + titan_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); + if (tmp1 != 8) { + printk(KERN_WARNING "PCI setting cache line size to 8 from " + "%d\n", tmp1); + + titan_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); + } + + titan_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); + if (tmp1 < 32 || tmp1 == 0xff) { + printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", + tmp1); + titan_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, 32); + } + + return 0; +} + +/* + * Export for pcibios_enable_device + */ +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + +/* + * Export for pcibios_update_resource + */ +void pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4 * resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* + * Somebody might have asked allocation of a non-standard + * resource + */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & + ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : + PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +/* + * Export to pcibios_align_resource + */ +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +/* + * Titan PCI structure + */ +struct pci_ops titan_pci_ops = { + titan_pcibios_read_config_byte, + titan_pcibios_read_config_word, + titan_pcibios_read_config_dword, + titan_pcibios_write_config_byte, + titan_pcibios_write_config_word, + titan_pcibios_write_config_dword +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + titan_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + /* + * XXX These values below need to change + */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &titan_pci_ops, NULL); +} + +/* + * for parsing "pci=" kernel boot arguments. + */ +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/prom.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/prom.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,188 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "setup.h" + +/* Call Vectors */ +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long yosemite_base; +extern unsigned long cpu_clock; +unsigned char titan_ge_mac_addr_base[6]; + +const char *get_system_type(void) +{ + return "PMC-Sierra Yosemite"; +} + +static void prom_cpu0_exit(void) +{ + void *nvram = YOSEMITE_NVRAM_BASE_ADDR; + + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ + writeb(0x84, nvram + 0xff7); + + /* wait for the watchdog to go off */ + mdelay(100+(1000/16)); + + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +/* + * Reset the NVRAM over the local bus + */ +static void prom_exit(void) +{ +#ifdef CONFIG_SMP + if (smp_processor_id()) + /* CPU 1 */ + smp_call_function(prom_cpu0_exit, NULL, 1, 1); +#endif + prom_cpu0_exit; +} + +/* + * Get the MAC address from the EEPROM using the I2C protocol + */ +void get_mac_address(char dest[6]) +{ + /* Use the I2C command code in the i2c-yosemite */ +} + +/* + * Halt the system + */ +static void prom_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +/* + * Init routine which accepts the variables from PMON + */ +__init prom_init(int argc, char **arg, char **env, struct callvectors *cv) +{ + int i = 0; + + /* Callbacks for halt, restart */ + _machine_restart = (void (*)(char *))prom_exit; + _machine_halt = prom_halt; + _machine_power_off = prom_halt; + +#ifdef CONFIG_MIPS64 + + /* Do nothing for the 64-bit for now. Just implement for the 32-bit */ + +#else /* CONFIG_MIPS64 */ + + debug_vectors = cv; + arcs_cmdline[0] = '\0'; + + /* Get the boot parameters */ + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) + break; + + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + while (*env) { + if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) + yosemite_base = simple_strtol(*env + strlen("ocd_base="), + NULL, 16); + + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) + cpu_clock = simple_strtol(*env + strlen("cpuclock="), + NULL, 10); + + env++; + } +#endif /* CONFIG_MIPS64 */ + + mips_machgroup = MACH_GROUP_TITAN; + mips_machtype = MACH_TITAN_YOSEMITE; + + get_mac_address(titan_ge_mac_addr_base); + + debug_vectors->printf("Booting Linux kernel...\n"); +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} + +/* + * SMP support + */ +int prom_setup_smp(void) +{ + int num_cpus = 2; + + /* + * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this + * can be hardcoded for now. + */ + return num_cpus; +} + +int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) +{ + /* Clear the semaphore */ + *(volatile u_int32_t *)(0xbb000a68) = 0x80000000; + + return 1; +} + +void prom_init_secondary(void) +{ + clear_c0_config(CONF_CM_CMASK); + set_c0_config(0x2); + + clear_c0_status(ST0_IM); + set_c0_status(0x1ffff); +} + +void prom_smp_finish(void) +{ +} + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/setup.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/setup.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,158 @@ +/* + * arch/mips/pmc-sierra/yosemite/setup.c + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "setup.h" + +unsigned long cpu_clock; +unsigned long yosemite_base; + +void __init bus_error_init(void) +{ + /* Do nothing */ +} + +unsigned long m48t37y_get_time(void) +{ + unsigned char *rtc_base = YOSEMITE_RTC_BASE; + unsigned int year, month, day, hour, min, sec; + + /* Stop the update to the time */ + rtc_base[0x7ff8] = 0x40; + + year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); + year += CONV_BCD_TO_BIN(rtc_base[0x7fff1]) * 100; + + month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); + day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); + hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); + min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); + sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + + /* Start the update to the time again */ + rtc_base[0x7ff8] = 0x00; + + return mktime(year, month, day, hour, min, sec); +} + +int m48t37y_set_time(unsigned long sec) +{ + unsigned char *rtc_base = YOSEMITE_RTC_BASE; + unsigned int year, month, day, hour, min, sec; + + struct rtc_time tm; + + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; + + /* enable writing */ + rtc_base[0x7ff8] = 0x80; + + /* year */ + rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + + /* month */ + rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + + /* day */ + rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + + /* hour/min/sec */ + rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); + rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); + rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + + /* disable writing */ + rtc_base[0x7ff8] = 0x00; + + return 0; +} + +void yosemite_timer_setup(struct irqaction *irq) +{ + setup_irq(6, irq); +} + +void yosemite_time_init(void) +{ + mips_counter_frequency = cpu_clock / 2; + board_timer_setup = yosemite_timer_setup; + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; +} + +void __init pmc_yosemite_setup(void) +{ + unsigned long val = 0; + + printk("PMC-Sierra Yosemite Board Setup \n"); + board_time_init = yosemite_time_init; + + /* Add memory regions */ + add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); + add_memory_region(0x10000000, 0x10000000, BOOT_MEM_RAM); + + /* Setup the HT controller */ + val = *(volatile u_int32_t *)(HYPERTRANSPORT_CONFIG_REG); + val |= HYPERTRANSPORT_ENABLE; + *(volatile u_int32_t *)(HYPERTRANSPORT_CONFIG_REG) = val; + + /* Set the BAR. Shifted mode */ + *(volatile u_int32_t *)(HYPERTRANSPORT_BAR0_REG) = HYPERTRANSPORT_BAR0_ADDR; + *(volatile u_int32_t *)(HYPERTRANSPORT_SIZE0_REG) = HYPERTRANSPORT_SIZE0; +} + + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/setup.h linux-2.4.25/arch/mips/pmc-sierra/yosemite/setup.h --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/setup.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/setup.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * Board specific definititions for the PMC-Sierra Yosemite + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __SETUP_H__ +#define __SETUP_H__ + +/* Real Time Clock base */ +#define YOSEMITE_RTC_BASE +#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) +#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) + +/* NVRAM Base */ +#define YOSEMITE_NVRAM_BASE_ADDR 0xbb000678 /* XXX Need change */ +#define YOSEMITE_RTC_BASE 0xbb000679 /* XXX Need change */ + +/* + * Hypertransport Specific + */ +#define HYPERTRANSPORT_CONFIG_REG 0xbb000604 +#define HYPERTRANSPORT_BAR0_REG 0xbb000610 +#define HYPERTRANSPORT_SIZE0_REG 0xbb000688 +#define HYPERTRANSPORT_BAR0_ATTR_REG 0xbb000680 + +#define HYPERTRANSPORT_BAR0_ADDR 0x00000006 +#define HYPERTRANSPORT_SIZE0 0x0fffffff +#define HYPERTRANSPORT_BAR0_ATTR 0x00002000 + +#define HYPERTRANSPORT_ENABLE 0x6 + +/* + * EEPROM Size + */ +#define TITAN_ATMEL_24C32_SIZE 32768 +#define TITAN_ATMEL_24C64_SIZE 65536 + + +#endif /* __SETUP_H__ */ + diff -urN linux-2.4.24/arch/mips/pmc-sierra/yosemite/smp.c linux-2.4.25/arch/mips/pmc-sierra/yosemite/smp.c --- linux-2.4.24/arch/mips/pmc-sierra/yosemite/smp.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/pmc-sierra/yosemite/smp.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,178 @@ +/* + * Copyright 2003 PMC-Sierra + * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include +#include + +extern void smp_call_function_interrupt(void); + +/* + * Send inter-processor interrupt + */ +void core_send_ipi(int cpu, unsigned int action) +{ + /* + * Generate and INTMSG so that it can be sent over to the destination CPU + * The INTMSG will put the STATUS bits based on the action desired + */ + switch(action) { + case SMP_RESCHEDULE_YOURSELF: + /* Do nothing */ + break; + case SMP_CALL_FUNCTION: + if (cpu == 1) + *(volatile u_int32_t *)(0xbb000a00) = 0x00610002; + else + *(volatile u_int32_t *)(0xbb000a00) = 0x00610001; + break; + + default: + panic("core_send_ipi \n"); + } +} + +/* + * Mailbox interrupt to handle IPI + */ +void jaguar_mailbox_irq(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + /* SMP_CALL_FUNCTION */ + smp_call_function_interrupt(); +} + +extern atomic_t cpus_booted; + +void __init start_secondary(void) +{ + unsigned int cpu = smp_processor_id(); + extern atomic_t smp_commenced; + + if (current->processor != 1) { + printk("Impossible CPU %d \n", cpu); + current->processor = 1; + current->cpus_runnable = 1 << 1; + cpu = current->processor; + } + + if (current->mm) + current->mm = NULL; + + prom_init_secondary(); + per_cpu_trap_init(); + + /* + * XXX parity protection should be folded in here when it's converted + * to an option instead of something based on .cputype + */ + pgd_current[cpu] = init_mm.pgd; + cpu_data[cpu].udelay_val = loops_per_jiffy; + prom_smp_finish(); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + __flush_cache_all(); + + printk("Slave cpu booted successfully \n"); + *(volatile u_int32_t *)(0xbb000a68) = 0x00000000; + *(volatile u_int32_t *)(0xbb000a68) = 0x80000000; + + while (*(volatile u_int32_t *)(0xbb000a68) != 0x00000000); + + return cpu_idle(); +} + +void __init smp_boot_cpus(void) +{ + int i; + int cur_cpu = 0; + + smp_num_cpus = prom_setup_smp(); + printk("Detected %d available CPUs \n", smp_num_cpus); + + init_new_context(current, &init_mm); + current->processor = 0; + cpu_data[0].udelay_val = loops_per_jiffy; + cpu_data[0].asid_cache = ASID_FIRST_VERSION; + CPUMASK_CLRALL(cpu_online_map); + CPUMASK_SETB(cpu_online_map, 0); + atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ + init_idle(); + + __cpu_number_map[0] = 0; + __cpu_logical_map[0] = 0; + + /* + * This loop attempts to compensate for "holes" in the CPU + * numbering. It's overkill, but general. + */ + for (i = 1; i < smp_num_cpus; ) { + struct task_struct *p; + struct pt_regs regs; + int retval; + printk("Starting CPU %d... \n", i); + + /* Spawn a new process normally. Grab a pointer to + its task struct so we can mess with it */ + do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); + + p = init_task.prev_task; + if (!p) + panic("failed fork for CPU %d", i); + + /* This is current for the second processor */ + p->processor = i; + p->cpus_runnable = 1 << i; /* we schedule the first task manually */ + p->thread.reg31 = (unsigned long) start_secondary; + + del_from_runqueue(p); + unhash_process(p); + init_tasks[i] = p; + + __flush_cache_all(); + + do { + /* Iterate until we find a CPU that comes up */ + cur_cpu++; + retval = prom_boot_secondary(cur_cpu, + (unsigned long)p + KERNEL_STACK_SIZE - 32, + (unsigned long)p); + + } while (!retval && (cur_cpu < NR_CPUS)); + if (retval) { + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; + i++; + } else { + panic("CPU discovery disaster"); + } + } + + /* Local semaphore to both the CPUs */ + + *(volatile u_int32_t *)(0xbb000a68) = 0x80000000; + while (*(volatile u_int32_t *)(0xbb000a68) != 0x00000000); + + smp_threads_ready = 1; +} diff -urN linux-2.4.24/arch/mips/sgi-ip22/Makefile linux-2.4.25/arch/mips/sgi-ip22/Makefile --- linux-2.4.24/arch/mips/sgi-ip22/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -16,7 +16,7 @@ ip22-time.o ip22-rtc.o ip22-nvram.o ip22-reset.o \ ip22-setup.o ip22-ksyms.o -obj-$(CONFIG_IP22_EISA) += ip22-eisa.o +obj-$(CONFIG_EISA) += ip22-eisa.o export-objs := ip22-ksyms.o diff -urN linux-2.4.24/arch/mips/sgi-ip22/ip22-hpc.c linux-2.4.25/arch/mips/sgi-ip22/ip22-hpc.c --- linux-2.4.24/arch/mips/sgi-ip22/ip22-hpc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/ip22-hpc.c 2004-02-18 05:36:30.000000000 -0800 @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -23,8 +23,11 @@ void __init sgihpc_init(void) { - hpc3c0 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP0_BASE); - hpc3c1 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP1_BASE); + /* ioremap can't fail */ + hpc3c0 = (struct hpc3_regs *) + ioremap(HPC3_CHIP0_BASE, sizeof(struct hpc3_regs)); + hpc3c1 = (struct hpc3_regs *) + ioremap(HPC3_CHIP1_BASE, sizeof(struct hpc3_regs)); /* IOC lives in PBUS PIO channel 6 */ sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6]; diff -urN linux-2.4.24/arch/mips/sgi-ip22/ip22-int.c linux-2.4.25/arch/mips/sgi-ip22/ip22-int.c --- linux-2.4.24/arch/mips/sgi-ip22/ip22-int.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/ip22-int.c 2004-02-18 05:36:30.000000000 -0800 @@ -405,7 +405,7 @@ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif -#ifdef CONFIG_IP22_EISA +#ifdef CONFIG_EISA if (ip22_is_fullhouse()) /* Only Indigo-2 have EISA stuff */ ip22_eisa_init (); #endif diff -urN linux-2.4.24/arch/mips/sgi-ip22/ip22-mc.c linux-2.4.25/arch/mips/sgi-ip22/ip22-mc.c --- linux-2.4.24/arch/mips/sgi-ip22/ip22-mc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/ip22-mc.c 2004-02-18 05:36:30.000000000 -0800 @@ -9,9 +9,8 @@ #include #include -#include +#include #include -#include #include #include #include @@ -106,7 +105,9 @@ { u32 tmp; - sgimc = (struct sgimc_regs *)(KSEG1 + SGIMC_BASE); + /* ioremap can't fail */ + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); printk(KERN_INFO "MC: SGI memory controller Revision %d\n", (int) sgimc->systemid & SGIMC_SYSID_MASKREV); diff -urN linux-2.4.24/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.25/arch/mips/sgi-ip22/ip22-setup.c --- linux-2.4.24/arch/mips/sgi-ip22/ip22-setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/ip22-setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,9 @@ static int remote_debug = 0; #endif +#ifdef CONFIG_EISA +extern struct fd_ops std_fd_ops; +#endif extern struct rtc_ops ip22_rtc_ops; unsigned long sgi_gfxaddr; @@ -110,11 +114,10 @@ extern void ip22_be_init(void) __init; extern void ip22_time_init(void) __init; -extern int console_setup(char *) __init; - void __init ip22_setup(void) { - char *ctype; + struct console_cmdline *c; + char *con; #ifdef CONFIG_KGDB char *kgdb_ttyd; #endif @@ -136,23 +139,29 @@ indy_sc_init(); #endif - /* Set the IO space to some sane value */ - set_io_port_base (KSEG1ADDR (0x00080000)); + /* Set EISA IO port base for Indigo2 */ + set_io_port_base(KSEG1ADDR(0x00080000)); + /* Nothing registered console before us, so simply use first entry */ + c = &console_cmdline[0]; /* ARCS console environment variable is set to "g?" for * graphics console, it is set to "d" for the first serial * line and "d2" for the second serial line. */ - ctype = ArcGetEnvironmentVariable("console"); - if (ctype && *ctype == 'd') { - if (*(ctype + 1) == '2') - console_setup("ttyS1"); - else - console_setup("ttyS0"); - } else if (!ctype || *ctype != 'g') { + con = ArcGetEnvironmentVariable("console"); + if (con && *con == 'd') { + static char options[8]; + char *baud = ArcGetEnvironmentVariable("dbaud"); + strcpy(c->name, "ttyS"); + c->index = *(con + 1) == '2' ? 1 : 0; + if (baud) { + strcpy(options, baud); + c->options = options; + } + } else if (!con || *con != 'g') { /* Use ARC if we don't want serial ('d') or Newport ('g'). */ prom_flags |= PROM_FLAG_USE_AS_CONSOLE; - console_setup("arc"); + strcpy(c->name, "arc"); } #ifdef CONFIG_KGDB @@ -179,12 +188,12 @@ #ifdef CONFIG_VT conswitchp = &dummy_con; #ifdef CONFIG_SGI_NEWPORT_CONSOLE - if (ctype && *ctype == 'g'){ - unsigned long *gfxinfo; - long (*__vec)(void) = - (void *) *(long *)((PROMBLOCK)->pvector + 0x20); + if (con && *con == 'g'){ + ULONG *gfxinfo; + ULONG * (*__vec)(void) = (void *) (long) + *((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20)); - gfxinfo = (unsigned long *)__vec(); + gfxinfo = __vec(); sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000 && gfxinfo[1] <= 0xc0000000) ? gfxinfo[1] - 0xa0000000 : 0); @@ -208,6 +217,14 @@ } #endif #endif + +/* + * Warning: this is broken, means it has to be known at kernel compile time + * if a floppy module might ever be loaded + */ +#if defined(CONFIG_EISA) && defined(CONFIG_BLK_DEV_FD) + fd_ops = &std_fd_ops; +#endif rtc_ops = &ip22_rtc_ops; kbd_ops = &ip22_kbd_ops; #ifdef CONFIG_PSMOUSE diff -urN linux-2.4.24/arch/mips/sgi-ip22/ip22-time.c linux-2.4.25/arch/mips/sgi-ip22/ip22-time.c --- linux-2.4.24/arch/mips/sgi-ip22/ip22-time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip22/ip22-time.c 2004-02-18 05:36:30.000000000 -0800 @@ -40,7 +40,7 @@ sec = hpc3c0->rtcregs[RTC_SECONDS] & 0xff; min = hpc3c0->rtcregs[RTC_MINUTES] & 0xff; - hrs = hpc3c0->rtcregs[RTC_HOURS] & 0x1f; + hrs = hpc3c0->rtcregs[RTC_HOURS] & 0x3f; day = hpc3c0->rtcregs[RTC_DATE] & 0xff; mon = hpc3c0->rtcregs[RTC_MONTH] & 0x1f; yrs = hpc3c0->rtcregs[RTC_YEAR] & 0xff; @@ -127,7 +127,7 @@ * for every 1/HZ seconds. We round off the nearest 1 MHz of master * clock (= 1000000 / HZ / 2). */ - //return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ); + /*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/ return (ct1 - ct0) / (500000/HZ) * (500000/HZ); } @@ -177,7 +177,7 @@ (int) (r4k_tick / (500000 / HZ)), (int) (r4k_tick % (500000 / HZ))); - mips_counter_frequency = r4k_tick * HZ; + mips_hpt_frequency = r4k_tick * HZ; } /* Generic SGI handler for (spurious) 8254 interrupts */ diff -urN linux-2.4.24/arch/mips/sgi-ip27/ip27-init.c linux-2.4.25/arch/mips/sgi-ip27/ip27-init.c --- linux-2.4.24/arch/mips/sgi-ip27/ip27-init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sgi-ip27/ip27-init.c 2004-02-18 05:36:30.000000000 -0800 @@ -466,7 +466,6 @@ int num_cpus = 0; cpuid_t cpu, mycpuid = getcpuid(); cnodeid_t cnode; - extern void smp_bootstrap(void); sn_mp_setup(); /* Master has already done per_cpu_init() */ diff -urN linux-2.4.24/arch/mips/sgi-ip27/ip27-nmi.c linux-2.4.25/arch/mips/sgi-ip27/ip27-nmi.c --- linux-2.4.24/arch/mips/sgi-ip27/ip27-nmi.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/sgi-ip27/ip27-nmi.c 2004-02-18 05:36:30.000000000 -0800 @@ -52,23 +52,77 @@ */ void -nmi_cpu_eframe_save(nasid_t nasid, - int slice) +nmi_cpu_eframe_save(nasid_t nasid, int slice) { - int i, numberof_nmi_cpu_regs; - machreg_t *prom_format; - - /* Get the total number of registers being saved by the prom */ - numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t); + struct reg_struct *nr; + int i; /* Get the pointer to the current cpu's register set. */ - prom_format = - (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + - slice * IP27_NMI_KREGS_CPU_SIZE); + nr = (struct reg_struct *) + (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + + slice * IP27_NMI_KREGS_CPU_SIZE); printk("NMI nasid %d: slice %d\n", nasid, slice); - for (i = 0; i < numberof_nmi_cpu_regs; i++) - printk("0x%lx ", prom_format[i]); + + /* + * Saved main processor registers + */ + for (i = 0; i < 32; ) { + if ((i % 4) == 0) + printk("$%2d :", i); + printk(" %016lx", nr->gpr[i]); + + i++; + if ((i % 4) == 0) + printk("\n"); + } + + printk("Hi : (value lost)\n"); + printk("Lo : (value lost)\n"); + + /* + * Saved cp0 registers + */ + printk("epc : %016lx %s\n", nr->epc, print_tainted()); + printk("Status: %08lx ", nr->sr); + + if (nr->sr & ST0_KX) + printk("KX "); + if (nr->sr & ST0_SX) + printk("SX "); + if (nr->sr & ST0_UX) + printk("UX "); + + switch (nr->sr & ST0_KSU) { + case KSU_USER: + printk("USER "); + break; + case KSU_SUPERVISOR: + printk("SUPERVISOR "); + break; + case KSU_KERNEL: + printk("KERNEL "); + break; + default: + printk("BAD_MODE "); + break; + } + + if (nr->sr & ST0_ERL) + printk("ERL "); + if (nr->sr & ST0_EXL) + printk("EXL "); + if (nr->sr & ST0_IE) + printk("IE "); + printk("\n"); + + printk("Cause : %08lx\n", nr->cause); + printk("PrId : %08x\n", read_c0_prid()); + printk("BadVA : %016lx\n", nr->badva); + printk("ErrEPC: %016lx\n", nr->error_epc); + printk("CErr : %016lx\n", nr->cache_err); + printk("NMI_SR: %016lx\n", nr->nmi_sr); + printk("\n\n"); } diff -urN linux-2.4.24/arch/mips/sibyte/cfe/smp.c linux-2.4.25/arch/mips/sibyte/cfe/smp.c --- linux-2.4.24/arch/mips/sibyte/cfe/smp.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sibyte/cfe/smp.c 2004-02-18 05:36:30.000000000 -0800 @@ -24,20 +24,15 @@ #include "cfe_api.h" #include "cfe_error.h" -extern void asmlinkage smp_bootstrap(void); - /* Boot all other cpus in the system, initialize them, and bring them into the boot fn */ -int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) +void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) { int retval; - retval = cfe_cpu_start(cpu, &smp_bootstrap, sp, gp, 0); + retval = cfe_cpu_start(cpu, smp_bootstrap, sp, gp, 0); if (retval != 0) { printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); - return 0; - } else { - return 1; } } @@ -47,12 +42,12 @@ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | STATUSF_IP1 | STATUSF_IP0; + /* cache and TLB setup */ + load_mmu(); + /* Enable basic interrupts */ change_c0_status(ST0_IM, imask); set_c0_status(ST0_IE); - - /* cache and TLB setup */ - load_mmu(); } /* diff -urN linux-2.4.24/arch/mips/sibyte/sb1250/bus_watcher.c linux-2.4.25/arch/mips/sibyte/sb1250/bus_watcher.c --- linux-2.4.24/arch/mips/sibyte/sb1250/bus_watcher.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sibyte/sb1250/bus_watcher.c 2004-02-18 05:36:30.000000000 -0800 @@ -174,10 +174,24 @@ { struct bw_stats_struct *stats = data; unsigned long cntr; +#ifdef CONFIG_SIBYTE_BW_TRACE + int i; +#endif #ifndef CONFIG_PROC_FS char bw_buf[1024]; #endif +#ifdef CONFIG_SIBYTE_BW_TRACE + csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG); + csr_out32(M_SCD_TRACE_CFG_START_READ, IO_SPACE_BASE | A_SCD_TRACE_CFG); + + for (i=0; i<256*6; i++) + printk("%016llx\n", in64(IO_SPACE_BASE | A_SCD_TRACE_READ)); + + csr_out32(M_SCD_TRACE_CFG_RESET, IO_SPACE_BASE | A_SCD_TRACE_CFG); + csr_out32(M_SCD_TRACE_CFG_START, IO_SPACE_BASE | A_SCD_TRACE_CFG); +#endif + /* Destructive read, clears register and interrupt */ stats->status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); stats->status_printed = 0; @@ -226,6 +240,14 @@ create_proc_decoder(&bw_stats); #endif +#ifdef CONFIG_SIBYTE_BW_TRACE + csr_out32((M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE | + K_SCD_TRSEQ_TRIGGER_ALL), + IO_SPACE_BASE | A_SCD_TRACE_SEQUENCE_0); + csr_out32(M_SCD_TRACE_CFG_RESET, IO_SPACE_BASE | A_SCD_TRACE_CFG); + csr_out32(M_SCD_TRACE_CFG_START, IO_SPACE_BASE | A_SCD_TRACE_CFG); +#endif + return 0; } diff -urN linux-2.4.24/arch/mips/sibyte/sb1250/smp.c linux-2.4.25/arch/mips/sibyte/sb1250/smp.c --- linux-2.4.24/arch/mips/sibyte/sb1250/smp.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sibyte/sb1250/smp.c 2004-02-18 05:36:30.000000000 -0800 @@ -62,9 +62,6 @@ void sb1250_smp_finish(void) { - extern void sb1_sanitize_tlb(void); - - sb1_sanitize_tlb(); sb1250_time_init(); } @@ -91,8 +88,33 @@ } extern atomic_t cpus_booted; -extern int prom_setup_smp(void); -extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); +extern atomic_t smp_commenced; + +/* + * Hook for doing final board-specific setup after the generic smp setup + * is done + */ +asmlinkage void start_secondary(void) +{ + unsigned int cpu = smp_processor_id(); + + cpu_probe(); + prom_init_secondary(); + per_cpu_trap_init(); + + /* + * XXX parity protection should be folded in here when it's converted + * to an option instead of something based on .cputype + */ + pgd_current[cpu] = init_mm.pgd; + cpu_data[cpu].udelay_val = loops_per_jiffy; + prom_smp_finish(); + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + while (!atomic_read(&smp_commenced)); + cpu_idle(); +} void __init smp_boot_cpus(void) { @@ -119,7 +141,6 @@ for (i = 1; i < smp_num_cpus; ) { struct task_struct *p; struct pt_regs regs; - int retval; printk("Starting CPU %d... ", i); /* Spawn a new process normally. Grab a pointer to @@ -139,17 +160,13 @@ do { /* Iterate until we find a CPU that comes up */ cur_cpu++; - retval = prom_boot_secondary(cur_cpu, + prom_boot_secondary(cur_cpu, (unsigned long)p + KERNEL_STACK_SIZE - 32, (unsigned long)p); - } while (!retval && (cur_cpu < NR_CPUS)); - if (retval) { - __cpu_number_map[cur_cpu] = i; - __cpu_logical_map[i] = cur_cpu; - i++; - } else { - panic("CPU discovery disaster"); - } + } while (cur_cpu < NR_CPUS); + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; + i++; } /* Wait for everyone to come up */ diff -urN linux-2.4.24/arch/mips/sibyte/sb1250/time.c linux-2.4.25/arch/mips/sibyte/sb1250/time.c --- linux-2.4.24/arch/mips/sibyte/sb1250/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/sibyte/sb1250/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -102,7 +102,6 @@ int cpu = smp_processor_id(); int irq = K_INT_TIMER_0+cpu; - kstat.irqs[cpu][irq]++; /* Reset the timer */ out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); diff -urN linux-2.4.24/arch/mips/tools/offset.c linux-2.4.25/arch/mips/tools/offset.c --- linux-2.4.24/arch/mips/tools/offset.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/tools/offset.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,7 +22,7 @@ #define offset(string, ptr, member) \ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) #define constant(string, member) \ - __asm__("\n@@@" string "%x0" : : "i" (member)) + __asm__("\n@@@" string "%x0" : : "ri" (member)) #define size(string, size) \ __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) #define linefeed text("") @@ -94,6 +94,12 @@ offset("#define TASK_PID ", struct task_struct, pid); size( "#define TASK_STRUCT_SIZE ", struct task_struct); linefeed; + + text("/* MIPS task_struct allocation info. */"); + constant("#define _THREAD_ORDER ", THREAD_ORDER); + constant("#define _THREAD_SIZE ", THREAD_SIZE); + constant("#define _THREAD_MASK ", THREAD_MASK); + linefeed; } void output_thread_defines(void) @@ -138,9 +144,29 @@ offset("#define MM_CONTEXT ", struct mm_struct, context); linefeed; constant("#define _PAGE_SIZE ", PAGE_SIZE); - constant("#define _PGD_ORDER ", PGD_ORDER); + constant("#define _PAGE_SHIFT ", PAGE_SHIFT); + linefeed; + constant("#define _PGD_T_SIZE ", sizeof(pgd_t)); + constant("#define _PMD_T_SIZE ", sizeof(pmd_t)); + constant("#define _PTE_T_SIZE ", sizeof(pte_t)); + linefeed; + constant("#define _PGD_T_LOG2 ", PGD_T_LOG2); + constant("#define _PMD_T_LOG2 ", PMD_T_LOG2); + constant("#define _PTE_T_LOG2 ", PTE_T_LOG2); + linefeed; + constant("#define _PMD_SHIFT ", PMD_SHIFT); constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT); linefeed; + constant("#define _PGD_ORDER ", PGD_ORDER); +#ifdef PMD_ORDER + constant("#define _PMD_ORDER ", PMD_ORDER); +#endif + constant("#define _PTE_ORDER ", PTE_ORDER); + linefeed; + constant("#define _PTRS_PER_PGD ", PTRS_PER_PGD); + constant("#define _PTRS_PER_PMD ", PTRS_PER_PMD); + constant("#define _PTRS_PER_PTE ", PTRS_PER_PTE); + linefeed; } void output_sc_defines(void) diff -urN linux-2.4.24/arch/mips/tx4927/common/tx4927_setup.c linux-2.4.25/arch/mips/tx4927/common/tx4927_setup.c --- linux-2.4.24/arch/mips/tx4927/common/tx4927_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/tx4927/common/tx4927_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -120,7 +120,7 @@ /* to generate the first timer interrupt */ c1 = read_c0_count(); - count = c1 + (mips_counter_frequency / HZ); + count = c1 + (mips_hpt_frequency / HZ); write_c0_compare(count); c2 = read_c0_count(); diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/Makefile linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/Makefile --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -13,8 +13,11 @@ obj-y += toshiba_rbtx4927_prom.o obj-y += toshiba_rbtx4927_setup.o obj-y += toshiba_rbtx4927_irq.o +obj-y += toshiba_rbtx4927_led.o +obj-y += toshiba_rbtx4927_nmi.o obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_fixup.o obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_ops.o +obj-$(CONFIG_DS1742) += toshiba_rbtx4927_rtc.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -122,9 +122,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -132,12 +130,10 @@ #include #include #include +#include #include #include #include -#ifdef CONFIG_RTC_DS1742 -#include -#endif #ifdef CONFIG_TOSHIBA_FPCIB0 #include #endif diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_led.c linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_led.c --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_led.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_led.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,73 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_led.c + * + * RBTX4927 Status LED toggle + * + * Copyright (C) 2003 TimeSys Corp. + * S. James Hill (James.Hill@timesys.com) + * (sjhill@realitydiluted.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +static struct led_state { + struct timer_list timer; + unsigned char val123; + unsigned long val45; +} led_state; + +void led_toggle (unsigned long v) +{ + struct led_state *l = (struct led_state *) v; + + writeb(l->val123, RBTX4927_STATUS_LED_123); + writel(l->val45, RBTX4927_STATUS_LED_45); + + l->val123 = ~l->val123; + l->val45 = ~l->val45; + + l->timer.expires = jiffies + HZ; + add_timer(&l->timer); +} + +int __init led_setup (void) +{ + led_state.val123 = 0xfd; +#ifdef __MIPSEB__ + led_state.val45 = 0x5a000000; +#else + led_state.val45 = 0x0000005a; +#endif + + led_state.timer.data = (unsigned long) &led_state; + led_state.timer.expires = jiffies + HZ; + init_timer(&led_state.timer); + led_state.timer.function = led_toggle; + add_timer(&led_state.timer); + + return 0; +} + +__initcall (led_setup); diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_nmi.S linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_nmi.S --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_nmi.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_nmi.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,46 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_nmi.S + * + * NMI handler for Toshiba RBTX4927 board + * + * Copyright (C) 2003 TimeSys Corp. + * S. James Hill (James.Hill@timesys.com) + * (sjhill@realitydiluted.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include + + .align 5 + .set noat + NESTED(tx4927_nmi_handler, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 k0, CP0_STATUS + lui k1, 0x50 /* Clear BEV and NMI */ + nor k1, zero, k1 + and k0, k1 + mtc0 k0, CP0_STATUS + move a0, sp + jal toshiba_rbtx4927_nmi + END(tx4927_nmi_handler) diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_rtc.c linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_rtc.c --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_rtc.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,51 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_rtc.c + * + * RTC routines for Dallas chip. + * + * Copyright (C) 2003 TimeSys Corp. + * S. James Hill (James.Hill@timesys.com) + * (sjhill@realitydiluted.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +static unsigned char ds1742_rtc_read_data(unsigned long addr) +{ + return readb(addr); +} + +static void ds1742_rtc_write_data(unsigned char data, unsigned long addr) +{ + writeb(data, addr); +} + +static int ds1742_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops ds1742_rtc_ops = { + &ds1742_rtc_read_data, + &ds1742_rtc_write_data, + &ds1742_rtc_bcd_mode +}; diff -urN linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c --- linux-2.4.24/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -64,8 +64,8 @@ #include #include #include -#ifdef CONFIG_RTC_DS1742 -#include +#ifdef CONFIG_DS1742 +#include #endif #ifdef CONFIG_TOSHIBA_FPCIB0 #include @@ -907,8 +907,44 @@ /* no return */ } +void toshiba_rbtx4927_nmi (struct pt_regs *regs) +{ + extern void show_code(unsigned int *pc); + extern void show_runqueue(void); + extern void show_stack(unsigned int *sp); + extern void show_state_nolock(void); + extern void show_trace(long *sp); + + bust_spinlocks(1); + printk("\ncurrent = %d:%s\n",current->pid,current->comm); + show_regs(regs); + printk("Process %s (pid: %d, stackpage=%08lx)\n", + current->comm, current->pid, (unsigned long) current); + show_stack((unsigned int *)regs->regs[29]); + show_trace((long *)regs->regs[29]); + show_code((unsigned int *)regs->cp0_epc); + bust_spinlocks(0); +} + +void __init toshiba_rbtx4927_nmi_handler_setup (void) +{ + extern void tx4927_nmi_handler (void); + unsigned long vec[2]; + + vec[0] = 0x08000000 | + (0x03ffffff & ((unsigned long)tx4927_nmi_handler >> 2)); + vec[1] = 0; + + /* + * Our firmware (PMON in this case) has a NMI hook that + * jumps to 0x80000220. We locate our NMI handler there. + */ + memcpy((void *)(KSEG0 + 0x220), &vec, 0x8); +} + void __init toshiba_rbtx4927_setup(void) { + extern void (*board_nmi_handler_setup)(void); vu32 cp0_config; printk("CPU is %s\n", toshiba_name); @@ -928,6 +964,9 @@ cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); write_c0_config(cp0_config); + /* set up the NMI handler */ + board_nmi_handler_setup = toshiba_rbtx4927_nmi_handler_setup; + #ifdef TOSHIBA_RBTX4927_SETUP_DEBUG { extern void dump_cp0(char *); @@ -1149,26 +1188,28 @@ void __init toshiba_rbtx4927_time_init(void) { -#ifdef CONFIG_RTC_DS1742 +#ifdef CONFIG_DS1742 + extern void rtc_ds1742_init(unsigned long base); + extern void rtc_ds1742_wait(void); + extern struct rtc_ops ds1742_rtc_ops; u32 c1; u32 c2; #endif TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); -#ifdef CONFIG_RTC_DS1742 - - rtc_get_time = rtc_ds1742_get_time; - rtc_set_time = rtc_ds1742_set_time; +#ifdef CONFIG_DS1742 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, ":rtc_ds1742_init()-\n"); - rtc_ds1742_init(0xbc010000); + rtc_ds1742_init(RBTX4927_IOC_NVRAMB_ADDR); + rtc_ops = &ds1742_rtc_ops; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, ":rtc_ds1742_init()+\n"); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":Calibrate mips_counter_frequency-\n"); + ":Calibrate mips_hpt_frequency-\n"); rtc_ds1742_wait(); /* get the count */ @@ -1181,29 +1222,29 @@ c2 = read_c0_count(); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":Calibrate mips_counter_frequency+\n"); + ":Calibrate mips_hpt_frequency+\n"); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, ":c1=%12u\n", c1); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, ":c2=%12u\n", c2); /* this diff is as close as we are going to get to counter ticks per sec */ - mips_counter_frequency = abs(c2 - c1); + mips_hpt_frequency = abs(c2 - c1); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":f1=%12u\n", mips_counter_frequency); + ":f1=%12u\n", mips_hpt_frequency); /* round to 1/10th of a MHz */ - mips_counter_frequency /= (100 * 1000); - mips_counter_frequency *= (100 * 1000); + mips_hpt_frequency /= (100 * 1000); + mips_hpt_frequency *= (100 * 1000); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":f2=%12u\n", mips_counter_frequency); + ":f2=%12u\n", mips_hpt_frequency); TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, - ":mips_counter_frequency=%uHz (%uMHz)\n", - mips_counter_frequency, - mips_counter_frequency / 1000000); + ":mips_hpt_frequency=%uHz (%uMHz)\n", + mips_hpt_frequency, + mips_hpt_frequency / 1000000); #else - mips_counter_frequency = 100000000; + mips_hpt_frequency = 100000000; #endif TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); diff -urN linux-2.4.24/arch/mips/vr41xx/casio-e55/setup.c linux-2.4.25/arch/mips/vr41xx/casio-e55/setup.c --- linux-2.4.24/arch/mips/vr41xx/casio-e55/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/casio-e55/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -59,7 +59,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); } diff -urN linux-2.4.24/arch/mips/vr41xx/common/Makefile linux-2.4.25/arch/mips/vr41xx/common/Makefile --- linux-2.4.24/arch/mips/vr41xx/common/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -12,13 +12,13 @@ O_TARGET := vr41xx.o -obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o +obj-y := bcu.o cmu.o giu.o icu.o int-handler.o ksyms.o reset.o rtc.o -export-objs := vrc4173.o +export-objs := ksyms.o vrc4171.o vrc4173.o obj-$(CONFIG_PCI) += pciu.o obj-$(CONFIG_SERIAL) += serial.o -obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_VRC4171) += vrc4171.o obj-$(CONFIG_VRC4173) += vrc4173.o obj-$(subst m,y,$(CONFIG_IDE)) += ide.o diff -urN linux-2.4.24/arch/mips/vr41xx/common/bcu.c linux-2.4.25/arch/mips/vr41xx/common/bcu.c --- linux-2.4.24/arch/mips/vr41xx/common/bcu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/bcu.c 2004-02-18 05:36:30.000000000 -0800 @@ -33,27 +33,22 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Paul Mundt - * - Calculate mips_counter_frequency properly on VR4131. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include -#include #include #include -#include -#include -#define VR4111_CLKSPEEDREG KSEG1ADDR(0x0b000014) -#define VR4122_CLKSPEEDREG KSEG1ADDR(0x0f000014) -#define VR4131_CLKSPEEDREG VR4122_CLKSPEEDREG +#define CLKSPEEDREG_TYPE1 KSEG1ADDR(0x0b000014) +#define CLKSPEEDREG_TYPE2 KSEG1ADDR(0x0f000014) #define CLKSP(x) ((x) & 0x001f) + #define CLKSP_VR4133(x) ((x) & 0x0007) #define DIV2B 0x8000 #define DIV3B 0x4000 @@ -65,15 +60,27 @@ #define TDIVMODE(x) (2 << (((x) & 0x1000) >> 12)) #define VTDIVMODE(x) (((x) & 0x0700) >> 8) -unsigned long vr41xx_vtclock = 0; +static unsigned long vr41xx_vtclock; +static unsigned long vr41xx_tclock; + +unsigned long vr41xx_get_vtclock_frequency(void) +{ + return vr41xx_vtclock; +} + +unsigned long vr41xx_get_tclock_frequency(void) +{ + return vr41xx_tclock; +} -static inline u16 read_clkspeed(void) +static inline uint16_t read_clkspeed(void) { switch (current_cpu_data.cputype) { case CPU_VR4111: - case CPU_VR4121: return readw(VR4111_CLKSPEEDREG); - case CPU_VR4122: return readw(VR4122_CLKSPEEDREG); - case CPU_VR4131: return readw(VR4131_CLKSPEEDREG); + case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1); + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2); default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; @@ -82,7 +89,7 @@ return 0; } -static inline unsigned long calculate_pclock(u16 clkspeed) +static inline unsigned long calculate_pclock(uint16_t clkspeed) { unsigned long pclock = 0; @@ -90,63 +97,90 @@ case CPU_VR4111: case CPU_VR4121: pclock = 18432000 * 64; + pclock /= CLKSP(clkspeed); break; case CPU_VR4122: pclock = 18432000 * 98; + pclock /= CLKSP(clkspeed); break; case CPU_VR4131: pclock = 18432000 * 108; + pclock /= CLKSP(clkspeed); + break; + case CPU_VR4133: + switch (CLKSP_VR4133(clkspeed)) { + case 0: + pclock = 133000000; + break; + case 1: + pclock = 149000000; + break; + case 2: + pclock = 165900000; + break; + case 3: + pclock = 199100000; + break; + case 4: + pclock = 265900000; + break; + default: + printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n"); + break; + } break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; } - pclock /= CLKSP(clkspeed); printk(KERN_INFO "PClock: %ldHz\n", pclock); return pclock; } -static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock) +static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock) { + unsigned long vtclock = 0; + switch (current_cpu_data.cputype) { case CPU_VR4111: /* The NEC VR4111 doesn't have the VTClock. */ break; case CPU_VR4121: - vr41xx_vtclock = pclock; + vtclock = pclock; /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */ if (DIVVT(clkspeed) == 9) - vr41xx_vtclock = pclock * 6; + vtclock = pclock * 6; /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */ else if (DIVVT(clkspeed) == 10) - vr41xx_vtclock = pclock * 4; - vr41xx_vtclock /= DIVVT(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + vtclock = pclock * 4; + vtclock /= DIVVT(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; case CPU_VR4122: if(VTDIVMODE(clkspeed) == 7) - vr41xx_vtclock = pclock / 1; + vtclock = pclock / 1; else if(VTDIVMODE(clkspeed) == 1) - vr41xx_vtclock = pclock / 2; + vtclock = pclock / 2; else - vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; case CPU_VR4131: - vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); - printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + case CPU_VR4133: + vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vtclock); break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); break; } - return vr41xx_vtclock; + return vtclock; } -static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock, +static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock, unsigned long vtclock) { unsigned long tclock = 0; @@ -165,6 +199,7 @@ break; case CPU_VR4122: case CPU_VR4131: + case CPU_VR4133: tclock = vtclock / TDIVMODE(clkspeed); break; default: @@ -177,30 +212,14 @@ return tclock; } -static inline unsigned long calculate_mips_counter_frequency(unsigned long tclock) -{ - /* - * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2). - */ - if ((current_cpu_data.processor_id == PRID_VR4131_REV2_0) || - (current_cpu_data.processor_id == PRID_VR4131_REV2_1)) - tclock /= 2; - else - tclock /= 4; - - return tclock; -} - void __init vr41xx_bcu_init(void) { - unsigned long pclock, vtclock, tclock; - u16 clkspeed; + unsigned long pclock; + uint16_t clkspeed; clkspeed = read_clkspeed(); pclock = calculate_pclock(clkspeed); - vtclock = calculate_vtclock(clkspeed, pclock); - tclock = calculate_tclock(clkspeed, pclock, vtclock); - - mips_counter_frequency = calculate_mips_counter_frequency(tclock); + vr41xx_vtclock = calculate_vtclock(clkspeed, pclock); + vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock); } diff -urN linux-2.4.24/arch/mips/vr41xx/common/cmu.c linux-2.4.25/arch/mips/vr41xx/common/cmu.c --- linux-2.4.24/arch/mips/vr41xx/common/cmu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/cmu.c 2004-02-18 05:36:30.000000000 -0800 @@ -33,52 +33,192 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include #include #include +#include -#define VR4111_CMUCLKMSK KSEG1ADDR(0x0b000060) -#define VR4122_CMUCLKMSK KSEG1ADDR(0x0f000060) +#define CMUCLKMSK_TYPE1 KSEG1ADDR(0x0b000060) +#define CMUCLKMSK_TYPE2 KSEG1ADDR(0x0f000060) + #define MSKPIU 0x0001 + #define MSKSIU 0x0002 + #define MSKAIU 0x0004 + #define MSKKIU 0x0008 + #define MSKFIR 0x0010 + #define MSKDSIU 0x0820 + #define MSKCSI 0x0040 + #define MSKPCIU 0x0080 + #define MSKSSIU 0x0100 + #define MSKSHSP 0x0200 + #define MSKFFIR 0x0400 + #define MSKSCSI 0x1000 + #define MSKPPCIU 0x2000 +#define CMUCLKMSK2 KSEG1ADDR(0x0f000064) + #define MSKCEU 0x0001 + #define MSKMAC0 0x0002 + #define MSKMAC1 0x0004 static u32 vr41xx_cmu_base; -static u16 cmuclkmsk; +static u16 cmuclkmsk, cmuclkmsk2; -#define write_cmu(mask) writew((mask), vr41xx_cmu_base) +#define read_cmuclkmsk() readw(vr41xx_cmu_base) +#define read_cmuclkmsk2() readw(CMUCLKMSK2) +#define write_cmuclkmsk() writew(cmuclkmsk, vr41xx_cmu_base) +#define write_cmuclkmsk2() writew(cmuclkmsk2, CMUCLKMSK2) -void vr41xx_clock_supply(u16 mask) +void vr41xx_clock_supply(unsigned int clock) { - cmuclkmsk |= mask; - write_cmu(cmuclkmsk); + switch (clock) { + case PIU_CLOCK: + cmuclkmsk |= MSKPIU; + break; + case SIU_CLOCK: + cmuclkmsk |= MSKSIU | MSKSSIU; + break; + case AIU_CLOCK: + cmuclkmsk |= MSKAIU; + break; + case KIU_CLOCK: + cmuclkmsk |= MSKKIU; + break; + case FIR_CLOCK: + cmuclkmsk |= MSKFIR | MSKFFIR; + break; + case DSIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) + cmuclkmsk |= MSKDSIU; + else + cmuclkmsk |= MSKSIU | MSKDSIU; + break; + case CSI_CLOCK: + cmuclkmsk |= MSKCSI | MSKSCSI; + break; + case PCIU_CLOCK: + cmuclkmsk |= MSKPCIU; + break; + case HSP_CLOCK: + cmuclkmsk |= MSKSHSP; + break; + case PCI_CLOCK: + cmuclkmsk |= MSKPPCIU; + break; + case CEU_CLOCK: + cmuclkmsk2 |= MSKCEU; + break; + case ETHER0_CLOCK: + cmuclkmsk2 |= MSKMAC0; + break; + case ETHER1_CLOCK: + cmuclkmsk2 |= MSKMAC1; + break; + default: + break; + } + + if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || + clock == ETHER1_CLOCK) + write_cmuclkmsk2(); + else + write_cmuclkmsk(); } -void vr41xx_clock_mask(u16 mask) +void vr41xx_clock_mask(unsigned int clock) { - cmuclkmsk &= ~mask; - write_cmu(cmuclkmsk); + switch (clock) { + case PIU_CLOCK: + cmuclkmsk &= ~MSKPIU; + break; + case SIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) { + cmuclkmsk &= ~(MSKSIU | MSKSSIU); + } else { + if (cmuclkmsk & MSKDSIU) + cmuclkmsk &= ~MSKSSIU; + else + cmuclkmsk &= ~(MSKSIU | MSKSSIU); + } + break; + case AIU_CLOCK: + cmuclkmsk &= ~MSKAIU; + break; + case KIU_CLOCK: + cmuclkmsk &= ~MSKKIU; + break; + case FIR_CLOCK: + cmuclkmsk &= ~(MSKFIR | MSKFFIR); + break; + case DSIU_CLOCK: + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) { + cmuclkmsk &= ~MSKDSIU; + } else { + if (cmuclkmsk & MSKSIU) + cmuclkmsk &= ~MSKDSIU; + else + cmuclkmsk &= ~(MSKSIU | MSKDSIU); + } + break; + case CSI_CLOCK: + cmuclkmsk &= ~(MSKCSI | MSKSCSI); + break; + case PCIU_CLOCK: + cmuclkmsk &= ~MSKPCIU; + break; + case HSP_CLOCK: + cmuclkmsk &= ~MSKSHSP; + break; + case PCI_CLOCK: + cmuclkmsk &= ~MSKPPCIU; + break; + case CEU_CLOCK: + cmuclkmsk2 &= ~MSKCEU; + break; + case ETHER0_CLOCK: + cmuclkmsk2 &= ~MSKMAC0; + break; + case ETHER1_CLOCK: + cmuclkmsk2 &= ~MSKMAC1; + break; + default: + break; + } + + if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || + clock == ETHER1_CLOCK) + write_cmuclkmsk2(); + else + write_cmuclkmsk(); } -void __init vr41xx_cmu_init(u16 mask) +void __init vr41xx_cmu_init(void) { switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_cmu_base = VR4111_CMUCLKMSK; + vr41xx_cmu_base = CMUCLKMSK_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_cmu_base = VR4122_CMUCLKMSK; + vr41xx_cmu_base = CMUCLKMSK_TYPE2; + break; + case CPU_VR4133: + vr41xx_cmu_base = CMUCLKMSK_TYPE2; + cmuclkmsk2 = read_cmuclkmsk2(); break; default: panic("Unexpected CPU of NEC VR4100 series"); break; } - cmuclkmsk = mask; + cmuclkmsk = read_cmuclkmsk(); } diff -urN linux-2.4.24/arch/mips/vr41xx/common/giu.c linux-2.4.25/arch/mips/vr41xx/common/giu.c --- linux-2.4.24/arch/mips/vr41xx/common/giu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/giu.c 2004-02-18 05:36:30.000000000 -0800 @@ -34,6 +34,9 @@ * Changes: * MontaVista Software Inc. or * - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported. + * + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include @@ -41,13 +44,12 @@ #include #include -#include #include #include #include -#define VR4111_GIUIOSELL KSEG1ADDR(0x0b000100) -#define VR4122_GIUIOSELL KSEG1ADDR(0x0f000140) +#define GIUIOSELL_TYPE1 KSEG1ADDR(0x0b000100) +#define GIUIOSELL_TYPE2 KSEG1ADDR(0x0f000140) #define GIUIOSELL 0x00 #define GIUIOSELH 0x02 @@ -61,15 +63,19 @@ #define GIUINTALSELH 0x16 #define GIUINTHTSELL 0x18 #define GIUINTHTSELH 0x1a +#define GIUFEDGEINHL 0x20 +#define GIUFEDGEINHH 0x22 +#define GIUREDGEINHL 0x24 +#define GIUREDGEINHH 0x26 -u32 vr41xx_giu_base = 0; +static uint32_t giu_base; -#define read_giuint(offset) readw(vr41xx_giu_base + (offset)) -#define write_giuint(val, offset) writew((val), vr41xx_giu_base + (offset)) +#define read_giuint(offset) readw(giu_base + (offset)) +#define write_giuint(val, offset) writew((val), giu_base + (offset)) -static inline u16 set_giuint(u16 offset, u16 set) +static inline uint16_t set_giuint(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_giuint(offset); res |= set; @@ -78,9 +84,9 @@ return res; } -static inline u16 clear_giuint(u16 offset, u16 clear) +static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_giuint(offset); res &= ~clear; @@ -92,51 +98,83 @@ void vr41xx_enable_giuint(int pin) { if (pin < 16) - set_giuint(GIUINTENL, (u16)1 << pin); + set_giuint(GIUINTENL, (uint16_t)1 << pin); else - set_giuint(GIUINTENH, (u16)1 << (pin - 16)); + set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); } void vr41xx_disable_giuint(int pin) { if (pin < 16) - clear_giuint(GIUINTENL, (u16)1 << pin); + clear_giuint(GIUINTENL, (uint16_t)1 << pin); else - clear_giuint(GIUINTENH, (u16)1 << (pin - 16)); + clear_giuint(GIUINTENH, (uint16_t)1 << (pin - 16)); } void vr41xx_clear_giuint(int pin) { if (pin < 16) - write_giuint((u16)1 << pin, GIUINTSTATL); + write_giuint((uint16_t)1 << pin, GIUINTSTATL); else - write_giuint((u16)1 << (pin - 16), GIUINTSTATH); + write_giuint((uint16_t)1 << (pin - 16), GIUINTSTATH); } void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { - u16 mask; + uint16_t mask; if (pin < 16) { - mask = (u16)1 << pin; - if (trigger == TRIGGER_EDGE) { + mask = (uint16_t)1 << pin; + if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPL, mask); if (hold == SIGNAL_HOLD) set_giuint(GIUINTHTSELL, mask); else clear_giuint(GIUINTHTSELL, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case TRIGGER_EDGE_FALLING: + set_giuint(GIUFEDGEINHL, mask); + clear_giuint(GIUREDGEINHL, mask); + break; + case TRIGGER_EDGE_RISING: + clear_giuint(GIUFEDGEINHL, mask); + set_giuint(GIUREDGEINHL, mask); + break; + default: + set_giuint(GIUFEDGEINHL, mask); + set_giuint(GIUREDGEINHL, mask); + break; + } + } } else { clear_giuint(GIUINTTYPL, mask); clear_giuint(GIUINTHTSELL, mask); } } else { - mask = (u16)1 << (pin - 16); - if (trigger == TRIGGER_EDGE) { + mask = (uint16_t)1 << (pin - 16); + if (trigger != TRIGGER_LEVEL) { set_giuint(GIUINTTYPH, mask); if (hold == SIGNAL_HOLD) set_giuint(GIUINTHTSELH, mask); else clear_giuint(GIUINTHTSELH, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case TRIGGER_EDGE_FALLING: + set_giuint(GIUFEDGEINHH, mask); + clear_giuint(GIUREDGEINHH, mask); + break; + case TRIGGER_EDGE_RISING: + clear_giuint(GIUFEDGEINHH, mask); + set_giuint(GIUREDGEINHH, mask); + break; + default: + set_giuint(GIUFEDGEINHH, mask); + set_giuint(GIUREDGEINHH, mask); + break; + } + } } else { clear_giuint(GIUINTTYPH, mask); clear_giuint(GIUINTHTSELH, mask); @@ -148,16 +186,16 @@ void vr41xx_set_irq_level(int pin, int level) { - u16 mask; + uint16_t mask; if (pin < 16) { - mask = (u16)1 << pin; + mask = (uint16_t)1 << pin; if (level == LEVEL_HIGH) set_giuint(GIUINTALSELL, mask); else clear_giuint(GIUINTALSELL, mask); } else { - mask = (u16)1 << (pin - 16); + mask = (uint16_t)1 << (pin - 16); if (level == LEVEL_HIGH) set_giuint(GIUINTALSELH, mask); else @@ -198,7 +236,7 @@ if(!get_irq_number) return -EINVAL; - pin = irq - GIU_IRQ(0); + pin = GIU_IRQ_TO_PIN(irq); giuint_cascade[pin].flag = GIUINT_CASCADE; giuint_cascade[pin].get_irq_number = get_irq_number; @@ -219,7 +257,7 @@ disable_irq(GIUINT_CASCADE_IRQ); cascade = &giuint_cascade[pin]; - giuint_irq = pin + GIU_IRQ(0); + giuint_irq = GIU_IRQ(pin); if (cascade->flag == GIUINT_CASCADE) { cascade_irq = cascade->get_irq_number(giuint_irq); disable_irq(giuint_irq); @@ -242,11 +280,12 @@ switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_giu_base = VR4111_GIUIOSELL; + giu_base = GIUIOSELL_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_giu_base = VR4122_GIUIOSELL; + case CPU_VR4133: + giu_base = GIUIOSELL_TYPE2; break; default: panic("GIU: Unexpected CPU of NEC VR4100 series"); diff -urN linux-2.4.24/arch/mips/vr41xx/common/icu.c linux-2.4.25/arch/mips/vr41xx/common/icu.c --- linux-2.4.24/arch/mips/vr41xx/common/icu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/icu.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,9 +1,9 @@ /* * FILE NAME - * arch/mips/vr41xx/vr4122/common/icu.c + * arch/mips/vr41xx/common/icu.c * * BRIEF MODULE DESCRIPTION - * Interrupt Control Unit routines for the NEC VR4122 and VR4131. + * Interrupt Control Unit routines for the NEC VR4100 series. * * Author: Yoichi Yuasa * yyuasa@mvista.com or source@mvista.com @@ -33,13 +33,11 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Paul Mundt - * - kgdb support. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Coped with INTASSIGN of NEC VR4133. */ #include #include @@ -47,51 +45,65 @@ #include #include -#include #include -#include #include -#include +#include +#include #include extern asmlinkage void vr41xx_handle_interrupt(void); -extern void __init init_generic_irq(void); -extern void mips_cpu_irq_init(u32 irq_base); - extern void vr41xx_giuint_init(void); +extern void vr41xx_enable_giuint(int pin); +extern void vr41xx_disable_giuint(int pin); +extern void vr41xx_clear_giuint(int pin); extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); -static u32 vr41xx_icu1_base = 0; -static u32 vr41xx_icu2_base = 0; +static uint32_t icu1_base; +static uint32_t icu2_base; -#define VR4111_SYSINT1REG KSEG1ADDR(0x0b000080) -#define VR4111_SYSINT2REG KSEG1ADDR(0x0b000200) +static unsigned char sysint1_assign[16] = { + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static unsigned char sysint2_assign[16] = { + 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#define VR4122_SYSINT1REG KSEG1ADDR(0x0f000080) -#define VR4122_SYSINT2REG KSEG1ADDR(0x0f0000a0) +#define SYSINT1REG_TYPE1 KSEG1ADDR(0x0b000080) +#define SYSINT2REG_TYPE1 KSEG1ADDR(0x0b000200) + +#define SYSINT1REG_TYPE2 KSEG1ADDR(0x0f000080) +#define SYSINT2REG_TYPE2 KSEG1ADDR(0x0f0000a0) #define SYSINT1REG 0x00 +#define INTASSIGN0 0x04 +#define INTASSIGN1 0x06 #define GIUINTLREG 0x08 #define MSYSINT1REG 0x0c #define MGIUINTLREG 0x14 #define NMIREG 0x18 #define SOFTREG 0x1a +#define INTASSIGN2 0x1c +#define INTASSIGN3 0x1e #define SYSINT2REG 0x00 #define GIUINTHREG 0x02 #define MSYSINT2REG 0x06 #define MGIUINTHREG 0x08 -#define read_icu1(offset) readw(vr41xx_icu1_base + (offset)) -#define write_icu1(val, offset) writew((val), vr41xx_icu1_base + (offset)) +#define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */ +#define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */ + +#define read_icu1(offset) readw(icu1_base + (offset)) +#define write_icu1(val, offset) writew((val), icu1_base + (offset)) -#define read_icu2(offset) readw(vr41xx_icu2_base + (offset)) -#define write_icu2(val, offset) writew((val), vr41xx_icu2_base + (offset)) +#define read_icu2(offset) readw(icu2_base + (offset)) +#define write_icu2(val, offset) writew((val), icu2_base + (offset)) -static inline u16 set_icu1(u16 offset, u16 set) +#define INTASSIGN_MAX 4 +#define INTASSIGN_MASK 0x0007 + +static inline uint16_t set_icu1(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_icu1(offset); res |= set; @@ -100,9 +112,9 @@ return res; } -static inline u16 clear_icu1(u16 offset, u16 clear) +static inline uint16_t clear_icu1(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_icu1(offset); res &= ~clear; @@ -111,9 +123,9 @@ return res; } -static inline u16 set_icu2(u16 offset, u16 set) +static inline uint16_t set_icu2(uint8_t offset, uint16_t set) { - u16 res; + uint16_t res; res = read_icu2(offset); res |= set; @@ -122,9 +134,9 @@ return res; } -static inline u16 clear_icu2(u16 offset, u16 clear) +static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear) { - u16 res; + uint16_t res; res = read_icu2(offset); res &= ~clear; @@ -137,17 +149,17 @@ static void enable_sysint1_irq(unsigned int irq) { - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static void disable_sysint1_irq(unsigned int irq) { - clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static unsigned int startup_sysint1_irq(unsigned int irq) { - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } @@ -158,35 +170,34 @@ static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq)); } static struct hw_interrupt_type sysint1_irq_type = { - "SYSINT1", - startup_sysint1_irq, - shutdown_sysint1_irq, - enable_sysint1_irq, - disable_sysint1_irq, - ack_sysint1_irq, - end_sysint1_irq, - NULL + .typename = "SYSINT1", + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, + .end = end_sysint1_irq, }; /*=======================================================================*/ static void enable_sysint2_irq(unsigned int irq) { - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static void disable_sysint2_irq(unsigned int irq) { - clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static unsigned int startup_sysint2_irq(unsigned int irq) { - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); return 0; /* never anything pending */ } @@ -197,18 +208,17 @@ static void end_sysint2_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq)); } static struct hw_interrupt_type sysint2_irq_type = { - "SYSINT2", - startup_sysint2_irq, - shutdown_sysint2_irq, - enable_sysint2_irq, - disable_sysint2_irq, - ack_sysint2_irq, - end_sysint2_irq, - NULL + .typename = "SYSINT2", + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, + .end = end_sysint2_irq, }; /*=======================================================================*/ @@ -217,12 +227,11 @@ { int pin; - pin = irq - GIU_IRQ_BASE; + pin = GIU_IRQ_TO_PIN(irq); if (pin < 16) - set_icu1(MGIUINTLREG, (u16)1 << pin); + set_icu1(MGIUINTLREG, (uint16_t)1 << pin); else - set_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); - + set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); vr41xx_enable_giuint(pin); } @@ -230,18 +239,17 @@ { int pin; - pin = irq - GIU_IRQ_BASE; + pin = GIU_IRQ_TO_PIN(irq); vr41xx_disable_giuint(pin); - if (pin < 16) - clear_icu1(MGIUINTLREG, (u16)1 << pin); + clear_icu1(MGIUINTLREG, (uint16_t)1 << pin); else - clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); + clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16)); } static unsigned int startup_giuint_irq(unsigned int irq) { - vr41xx_clear_giuint(irq - GIU_IRQ_BASE); + vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); enable_giuint_irq(irq); @@ -254,7 +262,7 @@ { disable_giuint_irq(irq); - vr41xx_clear_giuint(irq - GIU_IRQ_BASE); + vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq)); } static void end_giuint_irq(unsigned int irq) @@ -264,14 +272,13 @@ } static struct hw_interrupt_type giuint_irq_type = { - "GIUINT", - startup_giuint_irq, - shutdown_giuint_irq, - enable_giuint_irq, - disable_giuint_irq, - ack_giuint_irq, - end_giuint_irq, - NULL + .typename = "GIUINT", + .startup = startup_giuint_irq, + .shutdown = shutdown_giuint_irq, + .enable = enable_giuint_irq, + .disable = disable_giuint_irq, + .ack = ack_giuint_irq, + .end = end_giuint_irq, }; /*=======================================================================*/ @@ -285,13 +292,14 @@ switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - vr41xx_icu1_base = VR4111_SYSINT1REG; - vr41xx_icu2_base = VR4111_SYSINT2REG; + icu1_base = SYSINT1REG_TYPE1; + icu2_base = SYSINT2REG_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - vr41xx_icu1_base = VR4122_SYSINT1REG; - vr41xx_icu2_base = VR4122_SYSINT2REG; + case CPU_VR4133: + icu1_base = SYSINT1REG_TYPE2; + icu2_base = SYSINT2REG_TYPE2; break; default: panic("Unexpected CPU of NEC VR4100 series"); @@ -313,7 +321,11 @@ irq_desc[i].handler = &giuint_irq_type; } - setup_irq(ICU_CASCADE_IRQ, &icu_cascade); + setup_irq(INT0_CASCADE_IRQ, &icu_cascade); + setup_irq(INT1_CASCADE_IRQ, &icu_cascade); + setup_irq(INT2_CASCADE_IRQ, &icu_cascade); + setup_irq(INT3_CASCADE_IRQ, &icu_cascade); + setup_irq(INT4_CASCADE_IRQ, &icu_cascade); } void __init init_IRQ(void) @@ -327,31 +339,171 @@ vr41xx_giuint_init(); set_except_vector(0, vr41xx_handle_interrupt); +} + +/*=======================================================================*/ + +static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) +{ + irq_desc_t *desc = irq_desc + irq; + uint16_t intassign0, intassign1; + unsigned int pin; + + pin = SYSINT1_IRQ_TO_PIN(irq); + + spin_lock_irq(&desc->lock); -#ifdef CONFIG_KGDB - printk("Setting debug traps - please connect the remote debugger.\n"); - set_debug_traps(); - breakpoint(); -#endif + intassign0 = read_icu1(INTASSIGN0); + intassign1 = read_icu1(INTASSIGN1); + + switch (pin) { + case 0: + intassign0 &= ~INTASSIGN_MASK; + intassign0 |= (uint16_t)assign; + break; + case 1: + intassign0 &= ~(INTASSIGN_MASK << 3); + intassign0 |= (uint16_t)assign << 3; + break; + case 2: + intassign0 &= ~(INTASSIGN_MASK << 6); + intassign0 |= (uint16_t)assign << 6; + break; + case 3: + intassign0 &= ~(INTASSIGN_MASK << 9); + intassign0 |= (uint16_t)assign << 9; + break; + case 8: + intassign0 &= ~(INTASSIGN_MASK << 12); + intassign0 |= (uint16_t)assign << 12; + break; + case 9: + intassign1 &= ~INTASSIGN_MASK; + intassign1 |= (uint16_t)assign; + break; + case 11: + intassign1 &= ~(INTASSIGN_MASK << 6); + intassign1 |= (uint16_t)assign << 6; + break; + case 12: + intassign1 &= ~(INTASSIGN_MASK << 9); + intassign1 |= (uint16_t)assign << 9; + break; + default: + return -EINVAL; + } + + sysint1_assign[pin] = assign; + write_icu1(intassign0, INTASSIGN0); + write_icu1(intassign1, INTASSIGN1); + + spin_unlock_irq(&desc->lock); + + return 0; +} + +static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) +{ + irq_desc_t *desc = irq_desc + irq; + uint16_t intassign2, intassign3; + unsigned int pin; + + pin = SYSINT2_IRQ_TO_PIN(irq); + + spin_lock_irq(&desc->lock); + + intassign2 = read_icu1(INTASSIGN2); + intassign3 = read_icu1(INTASSIGN3); + + switch (pin) { + case 0: + intassign2 &= ~INTASSIGN_MASK; + intassign2 |= (uint16_t)assign; + break; + case 1: + intassign2 &= ~(INTASSIGN_MASK << 3); + intassign2 |= (uint16_t)assign << 3; + break; + case 3: + intassign2 &= ~(INTASSIGN_MASK << 6); + intassign2 |= (uint16_t)assign << 6; + break; + case 4: + intassign2 &= ~(INTASSIGN_MASK << 9); + intassign2 |= (uint16_t)assign << 9; + break; + case 5: + intassign2 &= ~(INTASSIGN_MASK << 12); + intassign2 |= (uint16_t)assign << 12; + break; + case 6: + intassign3 &= ~INTASSIGN_MASK; + intassign3 |= (uint16_t)assign; + break; + case 7: + intassign3 &= ~(INTASSIGN_MASK << 3); + intassign3 |= (uint16_t)assign << 3; + break; + case 8: + intassign3 &= ~(INTASSIGN_MASK << 6); + intassign3 |= (uint16_t)assign << 6; + break; + case 9: + intassign3 &= ~(INTASSIGN_MASK << 9); + intassign3 |= (uint16_t)assign << 9; + break; + case 10: + intassign3 &= ~(INTASSIGN_MASK << 12); + intassign3 |= (uint16_t)assign << 12; + break; + default: + return -EINVAL; + } + + sysint2_assign[pin] = assign; + write_icu1(intassign2, INTASSIGN2); + write_icu1(intassign3, INTASSIGN3); + + spin_unlock_irq(&desc->lock); + + return 0; +} + +int vr41xx_set_intassign(unsigned int irq, unsigned char intassign) +{ + int retval = -EINVAL; + + if (current_cpu_data.cputype != CPU_VR4133) + return -EINVAL; + + if (intassign > INTASSIGN_MAX) + return -EINVAL; + + if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST) + retval = set_sysint1_assign(irq, intassign); + else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST) + retval = set_sysint2_assign(irq, intassign); + + return retval; } /*=======================================================================*/ -static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs) +static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh, + struct pt_regs *regs) { int i; if (pendl) { for (i = 0; i < 16; i++) { - if (pendl & (0x0001 << i)) { + if (pendl & ((uint16_t)1 << i)) { giuint_do_IRQ(i, regs); return; } } - } - else if (pendh) { + } else { for (i = 0; i < 16; i++) { - if (pendh & (0x0001 << i)) { + if (pendh & ((uint16_t)1 << i)) { giuint_do_IRQ(i + 16, regs); return; } @@ -359,10 +511,10 @@ } } -asmlinkage void icu_irqdispatch(struct pt_regs *regs) +asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs) { - u16 pend1, pend2, pendl, pendh; - u16 mask1, mask2, maskl, maskh; + uint16_t pend1, pend2, pendl, pendh; + uint16_t mask1, mask2, maskl, maskh; int i; pend1 = read_icu1(SYSINT1REG); @@ -377,31 +529,36 @@ pendh = read_icu2(GIUINTHREG); maskh = read_icu2(MGIUINTHREG); - pend1 &= mask1; - pend2 &= mask2; - pendl &= maskl; - pendh &= maskh; - - if (pend1) { - if ((pend1 & 0x01ff) == 0x0100) { - giuint_irqdispatch(pendl, pendh, regs); - } - else { - for (i = 0; i < 16; i++) { - if (pend1 & (0x0001 << i)) { - do_IRQ(SYSINT1_IRQ_BASE + i, regs); - break; + mask1 &= pend1; + mask2 &= pend2; + maskl &= pendl; + maskh &= pendh; + + if (mask1) { + for (i = 0; i < 16; i++) { + if (intnum == sysint1_assign[i] && + (mask1 & ((uint16_t)1 << i))) { + if (i == 8 && (maskl | maskh)) { + giuint_irq_dispatch(maskl, maskh, regs); + return; + } else { + do_IRQ(SYSINT1_IRQ(i), regs); + return; } } } - return; } - else if (pend2) { + + if (mask2) { for (i = 0; i < 16; i++) { - if (pend2 & (0x0001 << i)) { - do_IRQ(SYSINT2_IRQ_BASE + i, regs); - break; + if (intnum == sysint2_assign[i] && + (mask2 & ((uint16_t)1 << i))) { + do_IRQ(SYSINT2_IRQ(i), regs); + return; } } } + + printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh); + atomic_inc(&irq_err_count); } diff -urN linux-2.4.24/arch/mips/vr41xx/common/int-handler.S linux-2.4.25/arch/mips/vr41xx/common/int-handler.S --- linux-2.4.24/arch/mips/vr41xx/common/int-handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/vr41xx/common/int-handler.S 2004-02-18 05:36:30.000000000 -0800 @@ -34,6 +34,9 @@ * Changes: * MontaVista Software Inc. or * - New creation, NEC VR4100 series are supported. + * + * Yoichi Yuasa + * - Coped with INTASSIGN of NEC VR4133. */ #include #include @@ -59,55 +62,52 @@ andi t0, 0xff00 and t0, t0, t1 - andi t1, t0, CAUSEF_IP7 # timer interrupt - beqz t1, 1f + andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt + bnez t1, handle_irq li a0, 7 - jal ll_timer_interrupt - move a1, sp - j ret_from_irq -1: - andi t1, t0, 0x7800 # check for IP3-6 - beqz t1, 2f + andi t1, t0, 0x7800 # check for Int1-4 + beqz t1, 1f - andi t1, t0, CAUSEF_IP3 # check for IP3 - bnez t1, handle_it + andi t1, t0, CAUSEF_IP3 # check for Int1 + bnez t1, handle_int + li a0, 1 + + andi t1, t0, CAUSEF_IP4 # check for Int2 + bnez t1, handle_int + li a0, 2 + + andi t1, t0, CAUSEF_IP5 # check for Int3 + bnez t1, handle_int li a0, 3 - andi t1, t0, CAUSEF_IP4 # check for IP4 - bnez t1, handle_it + andi t1, t0, CAUSEF_IP6 # check for Int4 + bnez t1, handle_int li a0, 4 - andi t1, t0, CAUSEF_IP5 # check for IP5 - bnez t1, handle_it - li a0, 5 - - andi t1, t0, CAUSEF_IP6 # check for IP6 - bnez t1, handle_it - li a0, 6 - -2: - andi t1, t0, CAUSEF_IP2 # check for IP2 - beqz t1, 3f - move a0, sp - jal icu_irqdispatch - nop - j ret_from_irq - nop +1: + andi t1, t0, CAUSEF_IP2 # check for Int0 + bnez t1, handle_int + li a0, 0 -3: andi t1, t0, CAUSEF_IP0 # check for IP0 - bnez t1, handle_it + bnez t1, handle_irq li a0, 0 andi t1, t0, CAUSEF_IP1 # check for IP1 - bnez t1, handle_it + bnez t1, handle_irq li a0, 1 j spurious_interrupt nop -handle_it: +handle_int: + jal irq_dispatch + move a1, sp + j ret_from_irq + nop + +handle_irq: jal do_IRQ move a1, sp j ret_from_irq diff -urN linux-2.4.24/arch/mips/vr41xx/common/ksyms.c linux-2.4.25/arch/mips/vr41xx/common/ksyms.c --- linux-2.4.24/arch/mips/vr41xx/common/ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/vr41xx/common/ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,35 @@ +/* + * ksyms.c, Export NEC VR4100 series specific functions needed for loadable modules. + * + * Copyright (C) 2003 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include + +#include + +EXPORT_SYMBOL(vr41xx_get_vtclock_frequency); +EXPORT_SYMBOL(vr41xx_get_tclock_frequency); + +EXPORT_SYMBOL(vr41xx_set_intassign); + +EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle); +EXPORT_SYMBOL(vr41xx_read_rtclong1_counter); +EXPORT_SYMBOL(vr41xx_set_rtclong2_cycle); +EXPORT_SYMBOL(vr41xx_read_rtclong2_counter); +EXPORT_SYMBOL(vr41xx_set_tclock_cycle); +EXPORT_SYMBOL(vr41xx_read_tclock_counter); diff -urN linux-2.4.24/arch/mips/vr41xx/common/pciu.c linux-2.4.25/arch/mips/vr41xx/common/pciu.c --- linux-2.4.24/arch/mips/vr41xx/common/pciu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/pciu.c 2004-02-18 05:36:30.000000000 -0800 @@ -51,8 +51,6 @@ #include "pciu.h" -extern unsigned long vr41xx_vtclock; - static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where) { unsigned char bus = dev->bus->number; @@ -74,7 +72,7 @@ /* * Type 1 configuration */ - if (bus > 255 || PCI_SLOT(dev_fn) > 31 || where > 255) + if (PCI_SLOT(dev_fn) > 31 || where > 255) return -1; writel((bus << 16) | @@ -196,6 +194,7 @@ void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) { struct vr41xx_pci_address_space *s; + unsigned long vtclock; u32 config; int n; @@ -215,11 +214,12 @@ udelay(1); /* Select PCI clock */ - if (vr41xx_vtclock < MAX_PCI_CLOCK) + vtclock = vr41xx_get_vtclock_frequency(); + if (vtclock < MAX_PCI_CLOCK) writel(EQUAL_VTCLOCK, PCICLKSELREG); - else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK) + else if ((vtclock / 2) < MAX_PCI_CLOCK) writel(HALF_VTCLOCK, PCICLKSELREG); - else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK) + else if ((vtclock / 4) < MAX_PCI_CLOCK) writel(QUARTER_VTCLOCK, PCICLKSELREG); else printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); diff -urN linux-2.4.24/arch/mips/vr41xx/common/pciu.h linux-2.4.25/arch/mips/vr41xx/common/pciu.h --- linux-2.4.24/arch/mips/vr41xx/common/pciu.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.25/arch/mips/vr41xx/common/pciu.h 2004-02-18 05:36:30.000000000 -0800 @@ -107,9 +107,6 @@ #define MAX_PCI_CLOCK 33333333 -#define PCIU_CLOCK 0x0080 -#define PCI_CLOCK 0x2000 - static inline int pciu_read_config_byte(int where, u8 *val) { u32 data; diff -urN linux-2.4.24/arch/mips/vr41xx/common/rtc.c linux-2.4.25/arch/mips/vr41xx/common/rtc.c --- linux-2.4.24/arch/mips/vr41xx/common/rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/vr41xx/common/rtc.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,312 @@ +/* + * rtc.c, RTC(has only timer function) routines for NEC VR4100 series. + * + * Copyright (C) 2003 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include + +static uint32_t rtc1_base; +static uint32_t rtc2_base; + +static uint64_t previous_elapsedtime; +static unsigned int remainder_per_sec; +static unsigned int cycles_per_sec; +static unsigned int cycles_per_jiffy; +static unsigned long epoch_time; + +#define CLOCK_TICK_RATE 32768 /* 32.768kHz */ + +#define CYCLES_PER_JIFFY (CLOCK_TICK_RATE / HZ) +#define REMAINDER_PER_SEC (CLOCK_TICK_RATE - (CYCLES_PER_JIFFY * HZ)) +#define CYCLES_PER_100USEC ((CLOCK_TICK_RATE + (10000 / 2)) / 10000) + +#define ETIMELREG_TYPE1 KSEG1ADDR(0x0b0000c0) +#define TCLKLREG_TYPE1 KSEG1ADDR(0x0b0001c0) + +#define ETIMELREG_TYPE2 KSEG1ADDR(0x0f000100) +#define TCLKLREG_TYPE2 KSEG1ADDR(0x0f000120) + +/* RTC 1 registers */ +#define ETIMELREG 0x00 +#define ETIMEMREG 0x02 +#define ETIMEHREG 0x04 +/* RFU */ +#define ECMPLREG 0x08 +#define ECMPMREG 0x0a +#define ECMPHREG 0x0c +/* RFU */ +#define RTCL1LREG 0x10 +#define RTCL1HREG 0x12 +#define RTCL1CNTLREG 0x14 +#define RTCL1CNTHREG 0x16 +#define RTCL2LREG 0x18 +#define RTCL2HREG 0x1a +#define RTCL2CNTLREG 0x1c +#define RTCL2CNTHREG 0x1e + +/* RTC 2 registers */ +#define TCLKLREG 0x00 +#define TCLKHREG 0x02 +#define TCLKCNTLREG 0x04 +#define TCLKCNTHREG 0x06 +/* RFU */ +#define RTCINTREG 0x1e + #define TCLOCK_INT 0x08 + #define RTCLONG2_INT 0x04 + #define RTCLONG1_INT 0x02 + #define ELAPSEDTIME_INT 0x01 + +#define read_rtc1(offset) readw(rtc1_base + (offset)) +#define write_rtc1(val, offset) writew((val), rtc1_base + (offset)) + +#define read_rtc2(offset) readw(rtc2_base + (offset)) +#define write_rtc2(val, offset) writew((val), rtc2_base + (offset)) + +static inline uint64_t read_elapsedtime_counter(void) +{ + uint64_t first, second; + uint32_t first_mid, first_low; + uint32_t second_mid, second_low; + + do { + first_low = (uint32_t)read_rtc1(ETIMELREG); + first_mid = (uint32_t)read_rtc1(ETIMEMREG); + first = (uint64_t)read_rtc1(ETIMEHREG); + second_low = (uint32_t)read_rtc1(ETIMELREG); + second_mid = (uint32_t)read_rtc1(ETIMEMREG); + second = (uint64_t)read_rtc1(ETIMEHREG); + } while (first_low != second_low || first_mid != second_mid || + first != second); + + return (first << 32) | (uint64_t)((first_mid << 16) | first_low); +} + +static inline void write_elapsedtime_counter(uint64_t time) +{ + write_rtc1((uint16_t)time, ETIMELREG); + write_rtc1((uint16_t)(time >> 16), ETIMEMREG); + write_rtc1((uint16_t)(time >> 32), ETIMEHREG); +} + +static inline void write_elapsedtime_compare(uint64_t time) +{ + write_rtc1((uint16_t)time, ECMPLREG); + write_rtc1((uint16_t)(time >> 16), ECMPMREG); + write_rtc1((uint16_t)(time >> 32), ECMPHREG); +} + +void vr41xx_set_rtclong1_cycle(uint32_t cycles) +{ + write_rtc1((uint16_t)cycles, RTCL1LREG); + write_rtc1((uint16_t)(cycles >> 16), RTCL1HREG); +} + +uint32_t vr41xx_read_rtclong1_counter(void) +{ + uint32_t first_high, first_low; + uint32_t second_high, second_low; + + do { + first_low = (uint32_t)read_rtc1(RTCL1CNTLREG); + first_high = (uint32_t)read_rtc1(RTCL1CNTHREG); + second_low = (uint32_t)read_rtc1(RTCL1CNTLREG); + second_high = (uint32_t)read_rtc1(RTCL1CNTHREG); + } while (first_low != second_low || first_high != second_high); + + return (first_high << 16) | first_low; +} + +void vr41xx_set_rtclong2_cycle(uint32_t cycles) +{ + write_rtc1((uint16_t)cycles, RTCL2LREG); + write_rtc1((uint16_t)(cycles >> 16), RTCL2HREG); +} + +uint32_t vr41xx_read_rtclong2_counter(void) +{ + uint32_t first_high, first_low; + uint32_t second_high, second_low; + + do { + first_low = (uint32_t)read_rtc1(RTCL2CNTLREG); + first_high = (uint32_t)read_rtc1(RTCL2CNTHREG); + second_low = (uint32_t)read_rtc1(RTCL2CNTLREG); + second_high = (uint32_t)read_rtc1(RTCL2CNTHREG); + } while (first_low != second_low || first_high != second_high); + + return (first_high << 16) | first_low; +} + +void vr41xx_set_tclock_cycle(uint32_t cycles) +{ + write_rtc2((uint16_t)cycles, TCLKLREG); + write_rtc2((uint16_t)(cycles >> 16), TCLKHREG); +} + +uint32_t vr41xx_read_tclock_counter(void) +{ + uint32_t first_high, first_low; + uint32_t second_high, second_low; + + do { + first_low = (uint32_t)read_rtc2(TCLKCNTLREG); + first_high = (uint32_t)read_rtc2(TCLKCNTHREG); + second_low = (uint32_t)read_rtc2(TCLKCNTLREG); + second_high = (uint32_t)read_rtc2(TCLKCNTHREG); + } while (first_low != second_low || first_high != second_high); + + return (first_high << 16) | first_low; +} + +static void vr41xx_timer_ack(void) +{ + uint64_t cur; + + write_rtc2(ELAPSEDTIME_INT, RTCINTREG); + + previous_elapsedtime += (uint64_t)cycles_per_jiffy; + cycles_per_sec += cycles_per_jiffy; + + if (cycles_per_sec >= CLOCK_TICK_RATE) { + cycles_per_sec = 0; + remainder_per_sec = REMAINDER_PER_SEC; + } + + cycles_per_jiffy = 0; + + do { + cycles_per_jiffy += CYCLES_PER_JIFFY; + if (remainder_per_sec > 0) { + cycles_per_jiffy++; + remainder_per_sec--; + } + + cur = read_elapsedtime_counter(); + } while (cur >= previous_elapsedtime + (uint64_t)cycles_per_jiffy); + + write_elapsedtime_compare(previous_elapsedtime + (uint64_t)cycles_per_jiffy); +} + +static void vr41xx_hpt_init(unsigned int count) +{ +} + +static unsigned int vr41xx_hpt_read(void) +{ + uint64_t cur; + + cur = read_elapsedtime_counter(); + + return (unsigned int)cur; +} + +static unsigned long vr41xx_gettimeoffset(void) +{ + uint64_t cur; + unsigned long gap; + + cur = read_elapsedtime_counter(); + gap = (unsigned long)(cur - previous_elapsedtime); + gap = gap / CYCLES_PER_100USEC * 100; /* usec */ + + return gap; +} + +static unsigned long vr41xx_get_time(void) +{ + uint64_t counts; + + counts = read_elapsedtime_counter(); + counts >>= 15; + + return epoch_time + (unsigned long)counts; + +} + +static int vr41xx_set_time(unsigned long sec) +{ + if (sec < epoch_time) + return -EINVAL; + + sec -= epoch_time; + + write_elapsedtime_counter((uint64_t)sec << 15); + + return 0; +} + +void vr41xx_set_epoch_time(unsigned long time) +{ + epoch_time = time; +} + +void __init vr41xx_time_init(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + rtc1_base = ETIMELREG_TYPE1; + rtc2_base = TCLKLREG_TYPE1; + break; + case CPU_VR4122: + case CPU_VR4131: + case CPU_VR4133: + rtc1_base = ETIMELREG_TYPE2; + rtc2_base = TCLKLREG_TYPE2; + break; + default: + panic("Unexpected CPU of NEC VR4100 series"); + break; + } + + mips_timer_ack = vr41xx_timer_ack; + + mips_hpt_init = vr41xx_hpt_init; + mips_hpt_read = vr41xx_hpt_read; + mips_hpt_frequency = CLOCK_TICK_RATE; + + if (epoch_time == 0) + epoch_time = mktime(1970, 1, 1, 0, 0, 0); + + rtc_get_time = vr41xx_get_time; + rtc_set_time = vr41xx_set_time; +} + +void __init vr41xx_timer_setup(struct irqaction *irq) +{ + do_gettimeoffset = vr41xx_gettimeoffset; + + remainder_per_sec = REMAINDER_PER_SEC; + cycles_per_jiffy = CYCLES_PER_JIFFY; + + if (remainder_per_sec > 0) { + cycles_per_jiffy++; + remainder_per_sec--; + } + + previous_elapsedtime = read_elapsedtime_counter(); + write_elapsedtime_compare(previous_elapsedtime + (uint64_t)cycles_per_jiffy); + write_rtc2(ELAPSEDTIME_INT, RTCINTREG); + + setup_irq(ELAPSEDTIME_IRQ, irq); +} diff -urN linux-2.4.24/arch/mips/vr41xx/common/serial.c linux-2.4.25/arch/mips/vr41xx/common/serial.c --- linux-2.4.24/arch/mips/vr41xx/common/serial.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/serial.c 2004-02-18 05:36:30.000000000 -0800 @@ -33,10 +33,11 @@ /* * Changes: * MontaVista Software Inc. or + * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * MontaVista Software Inc. or - * - New creation, NEC VR4122 and VR4131 are supported. + * Yoichi Yuasa + * - Added support for NEC VR4133. */ #include #include @@ -48,12 +49,12 @@ #include /* VR4111 and VR4121 SIU Registers */ -#define VR4111_SIURB KSEG1ADDR(0x0c000000) -#define VR4111_SIUIRSEL KSEG1ADDR(0x0c000008) +#define SIURB_TYPE1 KSEG1ADDR(0x0c000000) +#define SIUIRSEL_TYPE1 KSEG1ADDR(0x0c000008) -/* VR4122 and VR4131 SIU Registers */ -#define VR4122_SIURB KSEG1ADDR(0x0f000800) -#define VR4122_SIUIRSEL KSEG1ADDR(0x0f000808) +/* VR4122, VR4131 and VR4133 SIU Registers */ +#define SIURB_TYPE2 KSEG1ADDR(0x0f000800) +#define SIUIRSEL_TYPE2 KSEG1ADDR(0x0f000808) #define USE_RS232C 0x00 #define USE_IRDA 0x01 @@ -66,7 +67,6 @@ #define TMICMODE 0x20 #define SIU_BASE_BAUD 1152000 -#define SIU_CLOCK 0x0102 /* VR4122 and VR4131 DSIU Registers */ #define DSIURB KSEG1ADDR(0x0f000820) @@ -75,7 +75,6 @@ #define INTDSIU 0x0800 #define DSIU_BASE_BAUD 1152000 -#define DSIU_CLOCK 0x0802 int vr41xx_serial_ports = 0; @@ -102,11 +101,12 @@ switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - writew(val, VR4111_SIUIRSEL); + writew(val, SIUIRSEL_TYPE1); break; case CPU_VR4122: case CPU_VR4131: - writew(val, VR4122_SIUIRSEL); + case CPU_VR4133: + writew(val, SIUIRSEL_TYPE2); break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); @@ -129,11 +129,12 @@ switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: - s.iomem_base = (unsigned char *)VR4111_SIURB; + s.iomem_base = (unsigned char *)SIURB_TYPE1; break; case CPU_VR4122: case CPU_VR4131: - s.iomem_base = (unsigned char *)VR4122_SIURB; + case CPU_VR4133: + s.iomem_base = (unsigned char *)SIURB_TYPE2; break; default: panic("Unexpected CPU of NEC VR4100 series"); @@ -154,7 +155,8 @@ struct serial_struct s; if (current_cpu_data.cputype != CPU_VR4122 && - current_cpu_data.cputype != CPU_VR4131) + current_cpu_data.cputype != CPU_VR4131 && + current_cpu_data.cputype != CPU_VR4133) return; memset(&s, 0, sizeof(s)); diff -urN linux-2.4.24/arch/mips/vr41xx/common/time.c linux-2.4.25/arch/mips/vr41xx/common/time.c --- linux-2.4.24/arch/mips/vr41xx/common/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/time.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,93 +0,0 @@ -/* - * FILE NAME - * arch/mips/vr41xx/common/time.c - * - * BRIEF MODULE DESCRIPTION - * Timer routines for the NEC VR4100 series. - * - * Author: Yoichi Yuasa - * yyuasa@mvista.com or source@mvista.com - * - * Copyright 2001,2002 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* - * Changes: - * MontaVista Software Inc. or - * - Added support for NEC VR4100 series RTC Unit. - * - * MontaVista Software Inc. or - * - New creation, NEC VR4100 series are supported. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define VR4111_ETIMELREG KSEG1ADDR(0x0b0000c0) -#define VR4122_ETIMELREG KSEG1ADDR(0x0f000100) - -u32 vr41xx_rtc_base = 0; - -#ifdef CONFIG_VR41XX_RTC -extern unsigned long vr41xx_rtc_get_time(void); -extern int vr41xx_rtc_set_time(unsigned long sec); -#endif - -void vr41xx_time_init(void) -{ - switch (current_cpu_data.cputype) { - case CPU_VR4111: - case CPU_VR4121: - vr41xx_rtc_base = VR4111_ETIMELREG; - break; - case CPU_VR4122: - case CPU_VR4131: - vr41xx_rtc_base = VR4122_ETIMELREG; - break; - default: - panic("Unexpected CPU of NEC VR4100 series"); - break; - } - -#ifdef CONFIG_VR41XX_RTC - rtc_get_time = vr41xx_rtc_get_time; - rtc_set_time = vr41xx_rtc_set_time; -#endif -} - -void vr41xx_timer_setup(struct irqaction *irq) -{ - u32 count; - - setup_irq(MIPS_COUNTER_IRQ, irq); - - count = read_c0_count(); - write_c0_compare(count + (mips_counter_frequency / HZ)); -} diff -urN linux-2.4.24/arch/mips/vr41xx/common/vrc4171.c linux-2.4.25/arch/mips/vr41xx/common/vrc4171.c --- linux-2.4.24/arch/mips/vr41xx/common/vrc4171.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips/vr41xx/common/vrc4171.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,106 @@ +/* + * vrc4171.c, NEC VRC4171 base driver. + * + * Copyright (C) 2003 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include +#include + +MODULE_DESCRIPTION("NEC VRC4171 base driver"); +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL_GPL(vrc4171_get_irq_status); +EXPORT_SYMBOL_GPL(vrc4171_set_multifunction_pin); + +#define CONFIGURATION1 0x05fe + #define SLOTB_CONFIG 0xc000 + #define SLOTB_NONE 0x0000 + #define SLOTB_PCCARD 0x4000 + #define SLOTB_CF 0x8000 + #define SLOTB_FLASHROM 0xc000 + +#define CONFIGURATION2 0x05fc +#define INTERRUPT_STATUS 0x05fa +#define PCS_CONTROL 0x05ee +#define GPIO_DATA PCS_CONTROL +#define PCS0_UPPER_START 0x05ec +#define PCS0_LOWER_START 0x05ea +#define PCS0_UPPER_STOP 0x05e8 +#define PCS0_LOWER_STOP 0x05e6 +#define PCS1_UPPER_START 0x05e4 +#define PCS1_LOWER_START 0x05e2 +#define PCS1_UPPER_STOP 0x05de +#define PCS1_LOWER_STOP 0x05dc + +#define VRC4171_REGS_BASE PCS1_LOWER_STOP +#define VRC4171_REGS_SIZE 0x24 + +uint16_t vrc4171_get_irq_status(void) +{ + return inw(INTERRUPT_STATUS); +} + +void vrc4171_set_multifunction_pin(int config) +{ + uint16_t config1; + + config1 = inw(CONFIGURATION1); + config1 &= ~SLOTB_CONFIG; + + switch (config) { + case SLOTB_IS_NONE: + config1 |= SLOTB_NONE; + break; + case SLOTB_IS_PCCARD: + config1 |= SLOTB_PCCARD; + break; + case SLOTB_IS_CF: + config1 |= SLOTB_CF; + break; + case SLOTB_IS_FLASHROM: + config1 |= SLOTB_FLASHROM; + break; + default: + break; + } + + outw(config1, CONFIGURATION1); +} + +static int __devinit vrc4171_init(void) +{ + if (request_region(VRC4171_REGS_BASE, VRC4171_REGS_SIZE, "NEC VRC4171") == NULL) + return -EBUSY; + + printk(KERN_INFO "NEC VRC4171 base driver\n"); + + return 0; +} + +static void __devexit vrc4171_exit(void) +{ + release_region(VRC4171_REGS_BASE, VRC4171_REGS_SIZE); +} + +module_init(vrc4171_init); +module_exit(vrc4171_exit); diff -urN linux-2.4.24/arch/mips/vr41xx/common/vrc4173.c linux-2.4.25/arch/mips/vr41xx/common/vrc4173.c --- linux-2.4.24/arch/mips/vr41xx/common/vrc4173.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/common/vrc4173.c 2004-02-18 05:36:30.000000000 -0800 @@ -195,8 +195,8 @@ vrc4173_outw(0, VRC4173_MSYSINT1REG); - vr41xx_set_irq_trigger(cascade_irq - GIU_IRQ(0), TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(cascade_irq - GIU_IRQ(0), LEVEL_LOW); + vr41xx_set_irq_trigger(GIU_IRQ_TO_PIN(cascade_irq), TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) irq_desc[i].handler = &vrc4173_irq_type; diff -urN linux-2.4.24/arch/mips/vr41xx/ibm-workpad/setup.c linux-2.4.25/arch/mips/vr41xx/ibm-workpad/setup.c --- linux-2.4.24/arch/mips/vr41xx/ibm-workpad/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/ibm-workpad/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -59,7 +59,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); } diff -urN linux-2.4.24/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.25/arch/mips/vr41xx/nec-eagle/setup.c --- linux-2.4.24/arch/mips/vr41xx/nec-eagle/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/nec-eagle/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -140,7 +140,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); #ifdef CONFIG_SERIAL vr41xx_dsiu_init(); diff -urN linux-2.4.24/arch/mips/vr41xx/tanbac-tb0226/init.c linux-2.4.25/arch/mips/vr41xx/tanbac-tb0226/init.c --- linux-2.4.24/arch/mips/vr41xx/tanbac-tb0226/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/tanbac-tb0226/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -32,7 +32,6 @@ void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { - u32 config; int i; /* @@ -46,17 +45,6 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_TANBAC_TB0226; - - switch (current_cpu_data.processor_id) { - case PRID_VR4131_REV1_2: - config = read_c0_config(); - config &= ~0x00000030UL; - config |= 0x00410000UL; - write_c0_config(config); - break; - default: - break; - } } void __init prom_free_prom_memory (void) diff -urN linux-2.4.24/arch/mips/vr41xx/tanbac-tb0226/setup.c linux-2.4.25/arch/mips/vr41xx/tanbac-tb0226/setup.c --- linux-2.4.24/arch/mips/vr41xx/tanbac-tb0226/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/tanbac-tb0226/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -102,7 +102,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); diff -urN linux-2.4.24/arch/mips/vr41xx/tanbac-tb0229/init.c linux-2.4.25/arch/mips/vr41xx/tanbac-tb0229/init.c --- linux-2.4.24/arch/mips/vr41xx/tanbac-tb0229/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/tanbac-tb0229/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -37,7 +37,6 @@ void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { - u32 config; int i; /* @@ -51,17 +50,6 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_TANBAC_TB0229; - - switch (current_cpu_data.processor_id) { - case PRID_VR4131_REV1_2: - config = read_c0_config(); - config &= ~0x00000030UL; - config |= 0x00410000UL; - write_c0_config(config); - break; - default: - break; - } } void __init prom_free_prom_memory (void) diff -urN linux-2.4.24/arch/mips/vr41xx/tanbac-tb0229/setup.c linux-2.4.25/arch/mips/vr41xx/tanbac-tb0229/setup.c --- linux-2.4.24/arch/mips/vr41xx/tanbac-tb0229/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/tanbac-tb0229/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -114,7 +114,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); vr41xx_dsiu_init(); diff -urN linux-2.4.24/arch/mips/vr41xx/victor-mpc30x/setup.c linux-2.4.25/arch/mips/vr41xx/victor-mpc30x/setup.c --- linux-2.4.24/arch/mips/vr41xx/victor-mpc30x/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/victor-mpc30x/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -107,7 +107,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); diff -urN linux-2.4.24/arch/mips/vr41xx/zao-capcella/init.c linux-2.4.25/arch/mips/vr41xx/zao-capcella/init.c --- linux-2.4.24/arch/mips/vr41xx/zao-capcella/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/zao-capcella/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -32,7 +32,6 @@ void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { - u32 config; int i; /* @@ -46,17 +45,6 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_ZAO_CAPCELLA; - - switch (current_cpu_data.processor_id) { - case PRID_VR4131_REV1_2: - config = read_c0_config(); - config &= ~0x00000030UL; - config |= 0x00410000UL; - write_c0_config(config); - break; - default: - break; - } } void __init prom_free_prom_memory (void) diff -urN linux-2.4.24/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.25/arch/mips/vr41xx/zao-capcella/setup.c --- linux-2.4.24/arch/mips/vr41xx/zao-capcella/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips/vr41xx/zao-capcella/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -107,7 +107,7 @@ vr41xx_bcu_init(); - vr41xx_cmu_init(0x0102); + vr41xx_cmu_init(); vr41xx_siu_init(SIU_RS232C, 0); vr41xx_dsiu_init(); diff -urN linux-2.4.24/arch/mips64/Makefile linux-2.4.25/arch/mips64/Makefile --- linux-2.4.24/arch/mips64/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -3,7 +3,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 2002 Maciej W. Rozycki +# Copyright (C) 2002, 2003 Maciej W. Rozycki # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -11,6 +11,8 @@ # this architecture # +comma := , + # # Select the object file format to substitute into the linker script. # @@ -36,10 +38,11 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe +GCCFLAGS += $(call check_gcc, -finline-limit=100000,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_KGDB +ifdef CONFIG_DEBUG_INFO GCCFLAGS += -g ifdef CONFIG_SB1XXX_CORELIS GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer @@ -47,41 +50,81 @@ endif check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) +check_gas = $(shell if $(CC) $(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +# +# Use: $(call set_gccflags,,,,) +# +# , -- preferred CPU and ISA designations (may require +# recent tools) +# , -- fallback CPU and ISA designations (have to work +# with up to the oldest supported tools) +# +set_gccflags = $(shell \ +while :; do \ + cpu=$(1); isa=-$(2); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + cpu=$(3); isa=-$(4); \ + for gcc_opt in -march= -mcpu=; do \ + $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \ + -xc /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + break; \ +done; \ +gcc_cpu=$$cpu; gcc_isa=$$isa; \ +gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \ +while :; do \ + for gas_opt in -Wa,-march= -Wa,-mcpu=; do \ + $(CC) $$gas_opt$$cpu $$gas_isa -Wa,-Z -c -o /dev/null \ + -xassembler /dev/null > /dev/null 2>&1 && \ + break 2; \ + done; \ + gas_opt=; gas_cpu=; gas_isa=; \ + break; \ +done; \ +echo $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_opt$$gas_cpu $$gas_isa) # # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R4300 -GCCFLAGS += -mcpu=r4300 -mips3 +GCCFLAGS += $(call set_gccflags,r4300,mips3,r4300,mips3) endif ifdef CONFIG_CPU_R4X00 -GCCFLAGS += -mcpu=r4600 -mips3 +GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3) endif ifdef CONFIG_CPU_R5000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r5000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_NEVADA -GCCFLAGS += -mcpu=r8000 -mips3 -mmad +GCCFLAGS += $(call set_gccflags,rm5200,mips4,r8000,mips4) +#GCCFLAGS += $(call check_gcc,-mmad,) endif ifdef CONFIG_CPU_RM7000 -GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ - -mips2 -Wa,--trap +GCCFLAGS += $(call set_gccflags,rm7000,mips4,r5000,mips4) +endif +ifdef CONFIG_CPU_RM9000 +GCCFLAGS += $(call set_gccflags,rm9000,mips4,r5000,mips4) endif ifdef CONFIG_CPU_R8000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r8000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_R10000 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,r10000,mips4,r8000,mips4) endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) -mips4 +GCCFLAGS += $(call set_gccflags,sb1,mips64,r5000,mips4) ifdef CONFIG_SB1_PASS_1_WORKAROUNDS MODFLAGS += -msb1-pass1-workarounds endif endif ifdef CONFIG_CPU_MIPS64 -#CFLAGS += -mips64 # Should be used then we get a MIPS64 compiler -CFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call set_gccflags,mips64,mips64,r8000,mips4) endif # @@ -106,6 +149,15 @@ # # +# Cobalt Server +# +ifdef CONFIG_MIPS_COBALT +SUBDIRS += arch/mips/cobalt +CORE_FILES += arch/mips/cobalt/cobalt.o +LOADADDR := 0x80080000 +endif + +# # DECstation family # ifdef CONFIG_DECSTATION @@ -182,13 +234,21 @@ # Momentum Ocelot-C and -CS boards # ifdef CONFIG_MOMENCO_OCELOT_C -# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the -# mips_io_port_base. CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o SUBDIRS += arch/mips/momentum/ocelot_c LOADADDR := 0x80100000 endif +ifdef CONFIG_MOMENCO_JAGUAR_ATX +LIBS += arch/mips/momentum/jaguar_atx/jaguar_atx.o +SUBDIRS += arch/mips/momentum/jaguar_atx +ifdef CONFIG_JAGUAR_DMALOW +LOADADDR := 0x88000000 +else +LOADADDR := 0x80100000 +endif +endif + ifdef CONFIG_PCI CORE_FILES += arch/mips/pci/pci-core.o SUBDIRS += arch/mips/pci @@ -274,7 +334,7 @@ # convert to ECOFF using elf2ecoff. # ifdef CONFIG_BOOT_ELF32 -GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) +GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,) LINKFLAGS += -T arch/mips64/ld.script.elf32 endif # @@ -282,7 +342,7 @@ # ELF files from 32-bit files by conversion. # ifdef CONFIG_BOOT_ELF64 -GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) +GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,) LINKFLAGS += -T arch/mips64/ld.script.elf32 #AS += -64 #LD += -m elf64bmip @@ -320,7 +380,7 @@ ifdef CONFIG_MAPPED_KERNEL vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xbfffffff40000000 $< $@ + $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xc000000080000000 $< $@ else vmlinux.64: vmlinux $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xa800000080000000 $< $@ diff -urN linux-2.4.24/arch/mips64/Makefile.lib linux-2.4.25/arch/mips64/Makefile.lib --- linux-2.4.24/arch/mips64/Makefile.lib 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips64/Makefile.lib 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1 @@ +obj-$(CONFIG_LASAT) += crc32.o diff -urN linux-2.4.24/arch/mips64/defconfig linux-2.4.25/arch/mips64/defconfig --- linux-2.4.24/arch/mips64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/mips64/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,9 +104,10 @@ # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y CONFIG_SMP=y -CONFIG_NR_CPUS=32 # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -119,7 +124,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -138,7 +142,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -165,6 +169,7 @@ # 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 is not set @@ -242,7 +247,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -285,6 +289,7 @@ # 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 @@ -318,6 +323,15 @@ # CONFIG_SCSI_NSP32 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -407,6 +421,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -453,6 +468,7 @@ # 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 @@ -468,12 +484,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -483,6 +504,7 @@ # 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 @@ -524,6 +546,11 @@ # 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 @@ -532,6 +559,7 @@ # 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 @@ -589,6 +617,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -600,10 +633,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-atlas linux-2.4.25/arch/mips64/defconfig-atlas --- linux-2.4.24/arch/mips64/defconfig-atlas 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-atlas 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -97,7 +101,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -113,7 +121,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -132,7 +139,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -159,6 +166,7 @@ # 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 is not set @@ -203,6 +211,12 @@ # CONFIG_SYN_COOKIES 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 @@ -248,7 +262,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -292,6 +305,7 @@ # 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 @@ -326,6 +340,20 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -418,6 +446,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -464,6 +493,7 @@ # 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 @@ -478,12 +508,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -493,6 +528,7 @@ # 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 @@ -534,6 +570,11 @@ # 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 @@ -542,6 +583,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -584,6 +626,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -595,11 +642,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-decstation linux-2.4.25/arch/mips64/defconfig-decstation --- linux-2.4.24/arch/mips64/defconfig-decstation 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-decstation 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -70,6 +74,7 @@ CONFIG_BOOT_ELF32=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=4 +CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_MIPS_AU1000 is not set @@ -91,7 +96,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -106,7 +115,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set CONFIG_TC=y # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -125,7 +133,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -152,6 +160,7 @@ # 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 is not set @@ -195,6 +204,12 @@ # CONFIG_SYN_COOKIES 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 @@ -240,7 +255,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -285,6 +299,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -311,6 +326,15 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -402,6 +426,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -472,10 +497,12 @@ # 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_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -485,12 +512,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM 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 @@ -500,6 +532,7 @@ # 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 @@ -541,6 +574,11 @@ # 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 @@ -549,6 +587,7 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -605,6 +644,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -616,11 +660,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-ip22 linux-2.4.25/arch/mips64/defconfig-ip22 --- linux-2.4.24/arch/mips64/defconfig-ip22 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-ip22 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,7 +104,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -114,11 +122,10 @@ # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set CONFIG_ARC_CONSOLE=y -# CONFIG_IP22_EISA is not set CONFIG_NET=y +# CONFIG_EISA is not set # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -137,6 +144,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -163,6 +171,7 @@ # 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 is not set @@ -207,6 +216,12 @@ # CONFIG_SYN_COOKIES 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 @@ -252,7 +267,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -298,6 +312,7 @@ # 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_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set @@ -324,6 +339,15 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -415,6 +439,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -459,7 +484,11 @@ # Mice # # CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set # # Joysticks @@ -504,14 +533,15 @@ # CONFIG_WDT is not set # CONFIG_WDTPCI is not set # CONFIG_MACHZ_WDT is not set -CONFIG_INDYDOG=y +# CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO 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_MIPS_RTC is not set -CONFIG_SGI_DS1286=y +CONFIG_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -521,12 +551,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -536,6 +571,7 @@ # 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 @@ -577,6 +613,11 @@ # 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 @@ -585,6 +626,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -672,6 +714,8 @@ # CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set # # USB support @@ -679,6 +723,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -690,11 +739,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-ip27 linux-2.4.25/arch/mips64/defconfig-ip27 --- linux-2.4.24/arch/mips64/defconfig-ip27 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-ip27 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -100,7 +104,9 @@ # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set @@ -118,7 +124,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -137,7 +142,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -164,6 +169,7 @@ # 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 is not set @@ -241,7 +247,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -284,6 +289,7 @@ # 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 @@ -317,6 +323,15 @@ # CONFIG_SCSI_NSP32 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -406,6 +421,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -452,6 +468,7 @@ # 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 @@ -467,12 +484,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -482,6 +504,7 @@ # 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 @@ -523,6 +546,11 @@ # 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 @@ -531,6 +559,7 @@ # 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 @@ -588,6 +617,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -599,10 +633,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-jaguar linux-2.4.25/arch/mips64/defconfig-jaguar --- linux-2.4.24/arch/mips64/defconfig-jaguar 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips64/defconfig-jaguar 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,599 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +CONFIG_CPU_RM9000=y +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_BINFMT_IRIX is not set +CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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 is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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=y +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER 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_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI 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 + +# +# 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_SUNLANCE 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_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_FDDI 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 + +# +# 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 + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +# CONFIG_EXT2_FS is not set +# 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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-malta linux-2.4.25/arch/mips64/defconfig-malta --- linux-2.4.24/arch/mips64/defconfig-malta 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-malta 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -102,7 +106,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -117,7 +125,6 @@ CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -136,7 +143,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -163,6 +170,7 @@ # 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 is not set @@ -206,6 +214,12 @@ # CONFIG_SYN_COOKIES 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 @@ -251,7 +265,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -295,6 +308,7 @@ # 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 @@ -329,6 +343,20 @@ # 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -421,6 +449,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -467,6 +496,7 @@ # 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 @@ -481,12 +511,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -496,6 +531,7 @@ # 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 @@ -537,6 +573,11 @@ # 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 @@ -545,6 +586,7 @@ # 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=y CONFIG_NFSD_V3=y @@ -588,6 +630,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -599,11 +646,19 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-ocelotc linux-2.4.25/arch/mips64/defconfig-ocelotc --- linux-2.4.24/arch/mips64/defconfig-ocelotc 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/mips64/defconfig-ocelotc 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,650 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +CONFIG_MOMENCO_OCELOT_C=y +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_PCI=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_NONCOHERENT_IO=y +CONFIG_NEW_TIME_C=y +CONFIG_BOOT_ELF32=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_RM7000_CPU_SCACHE=y +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_BINFMT_IRIX is not set +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT 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=y +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# 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=y +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER 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_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES 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 + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI 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 + +# +# 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_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=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 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_MV64340_ETH=y +CONFIG_MV64340_ETH_0=y +# CONFIG_MV64340_ETH_1 is not set +# CONFIG_MV64340_ETH_2 is not set +# CONFIG_FDDI 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 + +# +# 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 + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# 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_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_MIPS_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +# CONFIG_EXT2_FS is not set +# 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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-sb1250-swarm linux-2.4.25/arch/mips64/defconfig-sb1250-swarm --- linux-2.4.24/arch/mips64/defconfig-sb1250-swarm 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-sb1250-swarm 2004-02-18 05:36:30.000000000 -0800 @@ -29,8 +29,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -49,6 +51,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -77,6 +81,7 @@ CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set # CONFIG_SIBYTE_BUS_WATCHER is not set +# CONFIG_SIBYTE_BW_TRACE is not set # CONFIG_SIBYTE_SB1250_PROF is not set # CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set @@ -117,7 +122,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SMP=y # CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y @@ -138,7 +147,6 @@ CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -157,7 +165,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -184,6 +192,7 @@ # 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 is not set @@ -224,6 +233,12 @@ # CONFIG_SYN_COOKIES 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 @@ -269,7 +284,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -278,6 +292,15 @@ # CONFIG_SCSI 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 + +# # Network device support # CONFIG_NETDEVICES=y @@ -369,6 +392,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -439,6 +463,7 @@ # 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 @@ -453,12 +478,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM 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 @@ -468,6 +498,7 @@ # 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 @@ -509,6 +540,11 @@ # 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 @@ -517,6 +553,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -560,6 +597,11 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Bluetooth support # # CONFIG_BLUEZ is not set @@ -571,11 +613,20 @@ # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set +CONFIG_NR_CPUS=64 +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/defconfig-sead linux-2.4.25/arch/mips64/defconfig-sead --- linux-2.4.24/arch/mips64/defconfig-sead 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/defconfig-sead 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,10 @@ # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_MIPS_MTX1 is not set +# CONFIG_COGENT_CSB250 is not set # CONFIG_BAGET_MIPS is not set # CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set @@ -47,6 +49,8 @@ # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_YOSEMITE is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -92,7 +96,11 @@ # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -107,7 +115,6 @@ # CONFIG_NET is not set # CONFIG_PCI is not set # CONFIG_ISA is not set -# CONFIG_EISA is not set # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set @@ -126,7 +133,7 @@ # CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set +# CONFIG_OOM_KILLER is not set # # Memory Technology Devices (MTD) @@ -153,6 +160,7 @@ # 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 @@ -190,7 +198,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -199,6 +206,15 @@ # CONFIG_SCSI 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 + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -211,6 +227,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -256,6 +273,7 @@ # 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 @@ -270,12 +288,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM 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 @@ -285,6 +308,7 @@ # 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 @@ -326,6 +350,11 @@ # 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 # CONFIG_NCPFS_NLS is not set # CONFIG_SMB_FS is not set # CONFIG_ZISOFS_FS is not set @@ -368,17 +397,30 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Kernel hacking # CONFIG_CROSSCOMPILE=y # CONFIG_RUNTIME_DEBUG is not set # CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.24/arch/mips64/kernel/Makefile linux-2.4.25/arch/mips64/kernel/Makefile --- linux-2.4.24/arch/mips64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -12,7 +12,7 @@ O_TARGET := kernel.o -export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o time.o +export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o semaphore.o smp.o time.o obj-y := branch.o cpu-probe.o entry.o irq.o proc.o process.o \ ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \ diff -urN linux-2.4.24/arch/mips64/kernel/cpu-probe.c linux-2.4.25/arch/mips64/kernel/cpu-probe.c --- linux-2.4.24/arch/mips64/kernel/cpu-probe.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/cpu-probe.c 2004-02-18 05:36:30.000000000 -0800 @@ -98,6 +98,8 @@ case CPU_4KSC: case CPU_5KC: /* case CPU_20KC:*/ + case CPU_24K: + case CPU_25KF: cpu_wait = r4k_wait; printk(" available.\n"); break; @@ -113,18 +115,40 @@ } } -static inline void check_mult_sh(void) +static inline void align_mod(const int align, const int mod) +{ + asm volatile( + ".set push\n\t" + ".set noreorder\n\t" + ".balign %0\n\t" + ".rept %1\n\t" + "nop\n\t" + ".endr\n\t" + ".set pop" + : + : "n" (align), "n" (mod)); +} + +static inline void mult_sh_align_mod(long *v1, long *v2, long *w, + const int align, const int mod) { unsigned long flags; int m1, m2; - long p, s, v; + long p, s, lv1, lv2, lw; - printk("Checking for the multiply/shift bug... "); + /* + * We want the multiply and the shift to be isolated from the + * rest of the code to disable gcc optimizations. Hence the + * asm statements that execute nothing, but make gcc not know + * what the values of m1, m2 and s are and what lv2 and p are + * used for. + */ local_irq_save(flags); /* - * The following code leads to a wrong result of dsll32 when - * executed on R4000 rev. 2.2 or 3.0. + * The following code leads to a wrong result of the first + * dsll32 when executed on R4000 rev. 2.2 or 3.0 (PRId + * 00000422 or 00000430, respectively). * * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for @@ -132,52 +156,97 @@ * sigh... --macro */ asm volatile( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (5), "1" (8), "2" (5)); + align_mod(align, mod); + /* + * The trailing nop is needed to fullfill the two-instruction + * requirement between reading hi/lo and staring a mult/div. + * Leaving it out may cause gas insert a nop itself breaking + * the desired alignment of the next chunk. + */ + asm volatile( ".set push\n\t" ".set noat\n\t" ".set noreorder\n\t" ".set nomacro\n\t" - "mult %1, %2\n\t" - "dsll32 %0, %3, %4\n\t" + "mult %2, %3\n\t" + "dsll32 %0, %4, %5\n\t" "mflo $0\n\t" + "dsll32 %1, %4, %5\n\t" + "nop\n\t" ".set pop" - : "=r" (v) - : "r" (5), "r" (8), "r" (5), "I" (0) + : "=&r" (lv1), "=r" (lw) + : "r" (m1), "r" (m2), "r" (s), "I" (0) : "hi", "lo", "accum"); - local_irq_restore(flags); - - if (v == 5L << 32) { - printk("no.\n"); - return; - } - - printk("yes, workaround... "); - local_irq_save(flags); - /* - * We want the multiply and the shift to be isolated from the - * rest of the code to disable gcc optimizations. Hence the - * asm statements that execute nothing, but make gcc not know - * what the values of m1, m2 and s are and what v and p are - * used for. - * - * We have to use single integers for m1 and m2 and a double + /* We have to use single integers for m1 and m2 and a double * one for p to be sure the mulsidi3 gcc's RTL multiplication * instruction has the workaround applied. Older versions of - * gcc have correct mulsi3, but other multiplication variants - * lack the workaround. + * gcc have correct umulsi3 and mulsi3, but other + * multiplication variants lack the workaround. */ asm volatile( "" : "=r" (m1), "=r" (m2), "=r" (s) - : "0" (5), "1" (8), "2" (5)); + : "0" (m1), "1" (m2), "2" (s)); + align_mod(align, mod); p = m1 * m2; - v = s << 32; + lv2 = s << 32; asm volatile( "" - : "=r" (v) - : "0" (v), "r" (p)); + : "=r" (lv2) + : "0" (lv2), "r" (p)); local_irq_restore(flags); - if (v == 5L << 32) { + *v1 = lv1; + *v2 = lv2; + *w = lw; +} + +static inline void check_mult_sh(void) +{ + long v1[8], v2[8], w[8]; + int bug, fix, i; + + printk("Checking for the multiply/shift bug... "); + + /* + * Testing discovered false negatives for certain code offsets + * into cache lines. Hence we test all possible offsets for + * the worst assumption of an R4000 I-cache line width of 32 + * bytes. + * + * We can't use a loop as alignment directives need to be + * immediates. + */ + mult_sh_align_mod(&v1[0], &v2[0], &w[0], 32, 0); + mult_sh_align_mod(&v1[1], &v2[1], &w[1], 32, 1); + mult_sh_align_mod(&v1[2], &v2[2], &w[2], 32, 2); + mult_sh_align_mod(&v1[3], &v2[3], &w[3], 32, 3); + mult_sh_align_mod(&v1[4], &v2[4], &w[4], 32, 4); + mult_sh_align_mod(&v1[5], &v2[5], &w[5], 32, 5); + mult_sh_align_mod(&v1[6], &v2[6], &w[6], 32, 6); + mult_sh_align_mod(&v1[7], &v2[7], &w[7], 32, 7); + + bug = 0; + for (i = 0; i < 8; i++) + if (v1[i] != w[i]) + bug = 1; + + if (bug == 0) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + fix = 1; + for (i = 0; i < 8; i++) + if (v2[i] != w[i]) + fix = 0; + + if (fix == 1) { printk("yes.\n"); return; } @@ -213,7 +282,8 @@ handler = set_except_vector(12, handle_daddi_ov); /* * The following code fails to trigger an overflow exception - * when executed on R4000 rev. 2.2 or 3.0. + * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or + * 00000430, respectively). * * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and * 3.0" by MIPS Technologies, Inc., erratum #23 for details. @@ -273,15 +343,16 @@ /* * The following code leads to a wrong result of daddiu when - * executed on R4400 rev. 1.0. + * executed on R4400 rev. 1.0 (PRId 00000440). * * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by * MIPS Technologies, Inc., erratum #7 for details. * * According to "MIPS R4000PC/SC Errata, Processor Revision * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this - * problem affects R4000 rev. 2.2 and 3.0, too. Testing - * failed to trigger it so far. + * problem affects R4000 rev. 2.2 and 3.0 (PRId 00000422 and + * 00000430, respectively), too. Testing failed to trigger it + * so far. * * I got no permission to duplicate the errata here, sigh... * --macro @@ -383,350 +454,408 @@ } #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ - | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) + | MIPS_CPU_COUNTER) -__init void cpu_probe(void) +static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { - struct cpuinfo_mips *c = ¤t_cpu_data; - unsigned long config0 = read_c0_config(); - unsigned long config1; - - c->processor_id = PRID_IMP_UNKNOWN; - c->fpu_id = FPIR_IMP_NONE; - c->cputype = CPU_UNKNOWN; - - if (config0 & (1 << 31)) { - /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_LLSC; - config1 = read_c0_config1(); - if (config1 & (1 << 3)) - c->options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - c->options |= MIPS_CPU_MIPS16; - if (config1 & (1 << 1)) - c->options |= MIPS_CPU_EJTAG; - if (config1 & 1) { + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) c->options |= MIPS_CPU_FPU; - c->options |= MIPS_CPU_32FPR; - } - c->scache.flags = MIPS_CACHE_NOT_PRESENT; - - c->tlbsize = ((config1 >> 25) & 0x3f) + 1; - } - - c->processor_id = read_c0_prid(); - switch (c->processor_id & 0xff0000) { - case PRID_COMP_LEGACY: - switch (c->processor_id & 0xff00) { - case PRID_IMP_R2000: - c->cputype = CPU_R2000; - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | - MIPS_CPU_LLSC; - if (__cpu_has_fpu()) - c->options |= MIPS_CPU_FPU; - c->tlbsize = 64; - break; - case PRID_IMP_R3000: - if ((c->processor_id & 0xff) == PRID_REV_R3000A) - if (cpu_has_confreg()) - c->cputype = CPU_R3081E; - else - c->cputype = CPU_R3000A; - else - c->cputype = CPU_R3000; - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | - MIPS_CPU_LLSC; - if (__cpu_has_fpu()) - c->options |= MIPS_CPU_FPU; - c->tlbsize = 64; - break; - case PRID_IMP_R4000: - if ((c->processor_id & 0xff) >= PRID_REV_R4400) - c->cputype = CPU_R4400SC; + c->tlbsize = 64; + break; + case PRID_IMP_R3000: + if ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; else - c->cputype = CPU_R4000SC; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_VCE | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_VR41XX: - switch (c->processor_id & 0xf0) { + c->cputype = CPU_R3000A; + else + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R4000: + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_VR41XX: + switch (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 - case PRID_REV_VR4111: - c->cputype = CPU_VR4111; - break; -#else - case PRID_REV_VR4181: - c->cputype = CPU_VR4181; - break; -#endif - case PRID_REV_VR4121: - c->cputype = CPU_VR4121; - break; - case PRID_REV_VR4122: - if ((c->processor_id & 0xf) < 0x3) - c->cputype = CPU_VR4122; - else - c->cputype = CPU_VR4181A; - break; - case PRID_REV_VR4131: - c->cputype = CPU_VR4131; - break; - default: - printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - c->cputype = CPU_VR41XX; - break; - } - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS; - c->tlbsize = 32; - break; - case PRID_IMP_R4300: - c->cputype = CPU_R4300; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R4600: - c->cputype = CPU_R4600; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - #if 0 - case PRID_IMP_R4650: - /* - * This processor doesn't have an MMU, so it's not - * "real easy" to run Linux on it. It is left purely - * for documentation. Commented out because it shares - * it's c0_prid id number with the TX3900. - */ - c->cputype = CPU_R4650; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - #endif - case PRID_IMP_TX39: - c->isa_level = MIPS_CPU_ISA_I; - c->options = MIPS_CPU_TLB; - - if ((c->processor_id & 0xf0) == - (PRID_REV_TX3927 & 0xf0)) { - c->cputype = CPU_TX3927; - c->tlbsize = 64; - } else { - switch (c->processor_id & 0xff) { - case PRID_REV_TX3912: - c->cputype = CPU_TX3912; - c->tlbsize = 32; - break; - case PRID_REV_TX3922: - c->cputype = CPU_TX3922; - c->tlbsize = 64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } - } - break; - case PRID_IMP_R4700: - c->cputype = CPU_R4700; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_TX49: - c->cputype = CPU_TX49XX; - c->isa_level = MIPS_CPU_ISA_III; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R5000: - c->cputype = CPU_R5000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 48; + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; break; - case PRID_IMP_R5432: - c->cputype = CPU_R5432; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R5500: - c->cputype = CPU_R5500; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_NEVADA: - c->cputype = CPU_NEVADA; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_DIVEC | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; - case PRID_IMP_R6000: - c->cputype = CPU_R6000; - c->isa_level = MIPS_CPU_ISA_II; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R6000A: - c->cputype = CPU_R6000A; - c->isa_level = MIPS_CPU_ISA_II; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_RM7000: - c->cputype = CPU_RM7000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - /* - * Undocumented RM7000: Bit 29 in the info register of - * the RM7000 v2.0 indicates if the TLB has 48 or 64 - * entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ - c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; break; - case PRID_IMP_R8000: - c->cputype = CPU_R8000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ +#endif + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; break; - case PRID_IMP_R10000: - c->cputype = CPU_R10000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; - c->tlbsize = 64; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; + else + c->cputype = CPU_VR4181A; break; - case PRID_IMP_R12000: - c->cputype = CPU_R12000; - c->isa_level = MIPS_CPU_ISA_IV; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; - c->tlbsize = 64; + case PRID_REV_VR4130: + if ((c->processor_id & 0xf) < 0x4) + c->cputype = CPU_VR4131; + else + c->cputype = CPU_VR4133; break; default: - c->cputype = CPU_UNKNOWN; + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; break; } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; - case PRID_COMP_MIPS: - switch (c->processor_id & 0xff00) { - case PRID_IMP_4KC: - c->cputype = CPU_4KC; - c->isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KEC: - c->cputype = CPU_4KEC; - c->isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_4KSC: - c->cputype = CPU_4KSC; - c->isa_level = MIPS_CPU_ISA_M32; - break; - case PRID_IMP_5KC: - c->cputype = CPU_5KC; - c->isa_level = MIPS_CPU_ISA_M64; - break; - case PRID_IMP_20KC: - c->cputype = CPU_20KC; - c->isa_level = MIPS_CPU_ISA_M64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } + case PRID_IMP_R4300: + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; - case PRID_COMP_ALCHEMY: - switch (c->processor_id & 0xff00) { - case PRID_IMP_AU1_REV1: - case PRID_IMP_AU1_REV2: - switch ((c->processor_id >> 24) & 0xff) { - case 0: - c->cputype = CPU_AU1000; - break; - case 1: - c->cputype = CPU_AU1500; + case PRID_IMP_R4600: + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #if 0 + case PRID_IMP_R4650: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #endif + case PRID_IMP_TX39: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; - case 2: - c->cputype = CPU_AU1100; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - panic("Unknown Au Core!"); + c->cputype = CPU_UNKNOWN; break; } - c->isa_level = MIPS_CPU_ISA_M32; - break; - default: - c->cputype = CPU_UNKNOWN; - break; } break; - case PRID_COMP_SIBYTE: - switch (c->processor_id & 0xff00) { - case PRID_IMP_SB1: - c->cputype = CPU_SB1; - c->isa_level = MIPS_CPU_ISA_M64; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; -#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - /* FPU in pass1 is known to have issues. */ + case PRID_IMP_R4700: + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_TX49: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_LLSC; + if (!(c->processor_id & 0x08)) c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; -#endif + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5432: + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5500: + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_NEVADA: + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R6000: + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R6000A: + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_RM7000: + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Undocumented RM7000: Bit 29 in the info register of + * the RM7000 v2.0 indicates if the TLB has 48 or 64 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_RM9000: + c->cputype = CPU_RM9000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Bit 29 in the info register of the RM9000 + * indicates if the TLB has 48 or 64 entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ + break; + case PRID_IMP_R10000: + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + case PRID_IMP_R12000: + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void decode_config1(struct cpuinfo_mips *c) +{ + unsigned long config0 = read_c0_config(); + unsigned long config1; + + if ((config0 & (1 << 31)) == 0) + return; /* actually wort a panic() */ + + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); + if (config1 & (1 << 3)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; +} + +static inline void cpu_probe_mips(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_24K: + c->cputype = CPU_24K; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_25KF: + c->cputype = CPU_25KF; + c->isa_level = MIPS_CPU_ISA_M64; + /* Probe for L2 cache */ + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; + break; + case 1: + c->cputype = CPU_AU1500; + break; + case 2: + c->cputype = CPU_AU1100; break; default: - c->cputype = CPU_UNKNOWN; + panic("Unknown Au Core!"); break; } + c->isa_level = MIPS_CPU_ISA_M32; + break; + } +} + +static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + /* FPU in pass1 is known to have issues. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) +{ + decode_config1(c); + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } +} + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); + break; + case PRID_COMP_MIPS: + cpu_probe_mips(c); + break; + case PRID_COMP_ALCHEMY: + cpu_probe_alchemy(c); + break; + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); break; case PRID_COMP_SANDCRAFT: - switch (c->processor_id & 0xff00) { - case PRID_IMP_SR71000: - c->cputype = CPU_SR71000; - c->isa_level = MIPS_CPU_ISA_M64; - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_FPU | - MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; - c->scache.ways = 8; - c->tlbsize = 64; - break; - default: - c->cputype = CPU_UNKNOWN; - break; - } + cpu_probe_sandcraft(c); break; default: c->cputype = CPU_UNKNOWN; diff -urN linux-2.4.24/arch/mips64/kernel/gdb-stub.c linux-2.4.25/arch/mips64/kernel/gdb-stub.c --- linux-2.4.24/arch/mips64/kernel/gdb-stub.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/gdb-stub.c 2004-02-18 05:36:30.000000000 -0800 @@ -992,7 +992,7 @@ __asm__ __volatile__( ".globl breakinst\n\t" ".set\tnoreorder\n\t" - "nop\n\t" + "nop\n" "breakinst:\tbreak\n\t" "nop\n\t" ".set\treorder" @@ -1005,7 +1005,7 @@ __asm__ __volatile__( ".globl async_breakinst\n\t" ".set\tnoreorder\n\t" - "nop\n\t" + "nop\n" "async_breakinst:\tbreak\n\t" "nop\n\t" ".set\treorder" diff -urN linux-2.4.24/arch/mips64/kernel/head.S linux-2.4.25/arch/mips64/kernel/head.S --- linux-2.4.24/arch/mips64/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/head.S 2004-02-18 05:36:30.000000000 -0800 @@ -105,11 +105,8 @@ CLI # disable interrupts - PTR_LA $28, init_task_union # init current pointer - daddiu sp, $28, KERNEL_STACK_SIZE-32 - set_saved_sp sp, t0, t1 - - /* The firmware/bootloader passes argc/argp/envp + /* + * The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because * the romvec and other important info is stored there * by prom_init(). @@ -122,6 +119,9 @@ sd zero, (t0) bne t0, t1, 1b + PTR_LA $28, init_task_union # init current pointer + daddiu sp, $28, KERNEL_STACK_SIZE-32 + set_saved_sp sp, t0, t1 dsubu sp, 4*SZREG # init stack pointer j init_arch @@ -135,7 +135,7 @@ NESTED(smp_bootstrap, 16, sp) #ifdef CONFIG_SGI_IP27 GET_NASID_ASM t1 - li t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ + dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ KLDIR_OFF_POINTER + K0BASE dsll t1, NASID_SHFT or t0, t0, t1 @@ -176,9 +176,9 @@ .data .align 12 - page swapper_pg_dir, 1 - page invalid_pte_table, 0 - page invalid_pmd_table, 1 + page swapper_pg_dir, _PGD_ORDER + page invalid_pmd_table, _PMD_ORDER + page invalid_pte_table, _PTE_ORDER page kptbl, _PGD_ORDER .globl ekptbl page kpmdtbl, 0 diff -urN linux-2.4.24/arch/mips64/kernel/ioctl32.c linux-2.4.25/arch/mips64/kernel/ioctl32.c --- linux-2.4.24/arch/mips64/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/ioctl32.c 2004-02-18 05:36:30.000000000 -0800 @@ -4,7 +4,7 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2000 Ralf Baechle - * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2002, 2003 Maciej W. Rozycki * * Mostly stolen from the sparc64 ioctl32 implementation. */ @@ -12,31 +12,43 @@ #include #include #include +#include +#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include #include -#include -#include +#include #include -#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +#include +#endif /* LVM */ #include #undef __KERNEL__ /* This file was born to be ugly ... */ @@ -46,11 +58,10 @@ #include #include +#include -#include -#ifdef CONFIG_MTD_CHAR #include -#endif +#include #ifdef CONFIG_SIBYTE_TBPROF #include @@ -350,7 +361,7 @@ struct ifreq32 *ifr32; struct ifreq *ifr; mm_segment_t old_fs; - int len; + unsigned int i, j; int err; if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32))) @@ -369,16 +380,14 @@ } ifr = ifc.ifc_req; ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); - len = ifc32.ifc_len / sizeof (struct ifreq32); - while (len--) { + for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) { if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) { - err = -EFAULT; - goto out; + kfree (ifc.ifc_buf); + return -EFAULT; } } - old_fs = get_fs(); - set_fs (KERNEL_DS); + old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); set_fs (old_fs); if (err) @@ -386,16 +395,26 @@ ifr = ifc.ifc_req; ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); - len = ifc.ifc_len / sizeof (struct ifreq); - ifc32.ifc_len = len * sizeof (struct ifreq32); - - while (len--) { + for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len; + i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) { err = -EFAULT; goto out; } } - + if (ifc32.ifcbuf == 0) { + /* Translate from 64-bit structure multiple to + * a 32-bit one. + */ + i = ifc.ifc_len; + i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); + ifc32.ifc_len = i; + } else { + if (i <= ifc32.ifc_len) + ifc32.ifc_len = i; + else + ifc32.ifc_len = i - sizeof (struct ifreq32); + } if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) { err = -EFAULT; goto out; @@ -528,6 +547,246 @@ return sys_ioctl(fd, cmd, arg); } +struct video_tuner32 { + s32 tuner; + u8 name[32]; + u32 rangelow, rangehigh; + u32 flags; + u16 mode, signal; +}; + +static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up) +{ + int i; + + if(get_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __get_user(kp->name[i], &up->name[i]); + __get_user(kp->rangelow, &up->rangelow); + __get_user(kp->rangehigh, &up->rangehigh); + __get_user(kp->flags, &up->flags); + __get_user(kp->mode, &up->mode); + __get_user(kp->signal, &up->signal); + return 0; +} + +static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up) +{ + int i; + + if(put_user(kp->tuner, &up->tuner)) + return -EFAULT; + for(i = 0; i < 32; i++) + __put_user(kp->name[i], &up->name[i]); + __put_user(kp->rangelow, &up->rangelow); + __put_user(kp->rangehigh, &up->rangehigh); + __put_user(kp->flags, &up->flags); + __put_user(kp->mode, &up->mode); + __put_user(kp->signal, &up->signal); + return 0; +} + +struct video_buffer32 { + /* void * */ u32 base; + s32 height, width, depth, bytesperline; +}; + +static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up) +{ + u32 tmp; + + if(get_user(tmp, &up->base)) + return -EFAULT; + kp->base = (void *) ((unsigned long)tmp); + __get_user(kp->height, &up->height); + __get_user(kp->width, &up->width); + __get_user(kp->depth, &up->depth); + __get_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up) +{ + u32 tmp = (u32)((unsigned long)kp->base); + + if(put_user(tmp, &up->base)) + return -EFAULT; + __put_user(kp->height, &up->height); + __put_user(kp->width, &up->width); + __put_user(kp->depth, &up->depth); + __put_user(kp->bytesperline, &up->bytesperline); + return 0; +} + +struct video_clip32 { + s32 x, y, width, height; + /* struct video_clip32 * */ u32 next; +}; + +struct video_window32 { + u32 x, y, width, height, chromakey, flags; + /* struct video_clip32 * */ u32 clips; + s32 clipcount; +}; + +static void free_kvideo_clips(struct video_window *kp) +{ + struct video_clip *cp; + + cp = kp->clips; + if(cp != NULL) + kfree(cp); +} + +static int get_video_window32(struct video_window *kp, struct video_window32 *up) +{ + struct video_clip32 *ucp; + struct video_clip *kcp; + int nclips, err, i; + u32 tmp; + + if(get_user(kp->x, &up->x)) + return -EFAULT; + __get_user(kp->y, &up->y); + __get_user(kp->width, &up->width); + __get_user(kp->height, &up->height); + __get_user(kp->chromakey, &up->chromakey); + __get_user(kp->flags, &up->flags); + __get_user(kp->clipcount, &up->clipcount); + __get_user(tmp, &up->clips); + ucp = (struct video_clip32 *)A(tmp); + kp->clips = NULL; + + nclips = kp->clipcount; + if(nclips == 0) + return 0; + + if(ucp == 0) + return -EINVAL; + + /* Peculiar interface... */ + if(nclips < 0) + nclips = VIDEO_CLIPMAP_SIZE; + + kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL); + err = -ENOMEM; + if(kcp == NULL) + goto cleanup_and_err; + + kp->clips = kcp; + for(i = 0; i < nclips; i++) { + __get_user(kcp[i].x, &ucp[i].x); + __get_user(kcp[i].y, &ucp[i].y); + __get_user(kcp[i].width, &ucp[i].width); + __get_user(kcp[i].height, &ucp[i].height); + kcp[nclips].next = NULL; + } + + return 0; + +cleanup_and_err: + free_kvideo_clips(kp); + return err; +} + +/* You get back everything except the clips... */ +static int put_video_window32(struct video_window *kp, struct video_window32 *up) +{ + if(put_user(kp->x, &up->x)) + return -EFAULT; + __put_user(kp->y, &up->y); + __put_user(kp->width, &up->width); + __put_user(kp->height, &up->height); + __put_user(kp->chromakey, &up->chromakey); + __put_user(kp->flags, &up->flags); + __put_user(kp->clipcount, &up->clipcount); + return 0; +} + +#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) +#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) +#define VIDIOCGWIN32 _IOR('v',9, struct video_window32) +#define VIDIOCSWIN32 _IOW('v',10, struct video_window32) +#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) +#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) +#define VIDIOCGFREQ32 _IOR('v',14, u32) +#define VIDIOCSFREQ32 _IOW('v',15, u32) + +static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + union { + struct video_tuner vt; + struct video_buffer vb; + struct video_window vw; + unsigned long vx; + } karg; + mm_segment_t old_fs = get_fs(); + void *up = (void *)arg; + int err = 0; + + /* First, convert the command. */ + switch(cmd) { + case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; + case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; + case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; + case VIDIOCSWIN32: cmd = VIDIOCSWIN; break; + case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; + case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; + case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; + case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + }; + + switch(cmd) { + case VIDIOCSTUNER: + case VIDIOCGTUNER: + err = get_video_tuner32(&karg.vt, up); + break; + + case VIDIOCSWIN: + err = get_video_window32(&karg.vw, up); + break; + + case VIDIOCSFBUF: + err = get_video_buffer32(&karg.vb, up); + break; + + case VIDIOCSFREQ: + err = get_user(karg.vx, (u32 *)up); + break; + }; + if(err) + goto out; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&karg); + set_fs(old_fs); + + if(cmd == VIDIOCSWIN) + free_kvideo_clips(&karg.vw); + + if(err == 0) { + switch(cmd) { + case VIDIOCGTUNER: + err = put_video_tuner32(&karg.vt, up); + break; + + case VIDIOCGWIN: + err = put_video_window32(&karg.vw, up); + break; + + case VIDIOCGFBUF: + err = put_video_buffer32(&karg.vb, up); + break; + + case VIDIOCGFREQ: + err = put_user(((u32)karg.vx), (u32 *)up); + break; + }; + } +out: + return err; +} struct hd_geometry32 { unsigned char heads; unsigned char sectors; @@ -577,6 +836,12 @@ return -EINVAL; } +static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + /* The mkswap binary hard codes it to Intel value :-((( */ + return w_long(fd, BLKGETSIZE, arg); +} + struct blkpg_ioctl_arg32 { int op; int flags; @@ -614,6 +879,39 @@ return err; } +/* Fix sizeof(sizeof()) breakage */ +#define BLKELVGET_32 _IOR(0x12,106,int) +#define BLKELVSET_32 _IOW(0x12,107,int) +#define BLKBSZGET_32 _IOR(0x12,112,int) +#define BLKBSZSET_32 _IOW(0x12,113,int) +#define BLKGETSIZE64_32 _IOR(0x12,114,int) + +static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVGET, arg); +} + +static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVSET, arg); +} + +static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZGET, arg); +} + +static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZSET, arg); +} + +static int do_blkgetsize64(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + return sys_ioctl(fd, BLKGETSIZE64, arg); +} + struct mtget32 { __u32 mt_type; __u32 mt_resid; @@ -865,6 +1163,558 @@ return err; } +#ifdef CONFIG_VT + +extern int tty_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg); + +static int vt_check(struct file *file) +{ + struct tty_struct *tty; + struct inode *inode = file->f_dentry->d_inode; + + if (file->f_op->ioctl != tty_ioctl) + return -EINVAL; + + tty = (struct tty_struct *)file->private_data; + if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) + return -EINVAL; + + if (tty->driver.ioctl != vt_ioctl) + return -EINVAL; + + /* + * To have permissions to do most of the vt ioctls, we either have + * to be the owner of the tty, or super-user. + */ + if (current->tty == tty || suser()) + return 1; + return 0; +} + +struct consolefontdesc32 { + unsigned short charcount; /* characters in font (256 or 512) */ + unsigned short charheight; /* scan lines per character (1-32) */ + u32 chardata; /* font data in expanded form */ +}; + +static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file) +{ + struct consolefontdesc cfdarg; + struct console_font_op op; + int i, perm; + + perm = vt_check(file); + if (perm < 0) return perm; + + if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32))) + return -EFAULT; + + cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata); + + switch (cmd) { + case PIO_FONTX: + if (!perm) + return -EPERM; + op.op = KD_FONT_OP_SET; + op.flags = 0; + op.width = 8; + op.height = cfdarg.charheight; + op.charcount = cfdarg.charcount; + op.data = cfdarg.chardata; + return con_font_op(fg_console, &op); + case GIO_FONTX: + if (!cfdarg.chardata) + return 0; + op.op = KD_FONT_OP_GET; + op.flags = 0; + op.width = 8; + op.height = cfdarg.charheight; + op.charcount = cfdarg.charcount; + op.data = cfdarg.chardata; + i = con_font_op(fg_console, &op); + if (i) + return i; + cfdarg.charheight = op.height; + cfdarg.charcount = op.charcount; + ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata; + if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32))) + return -EFAULT; + return 0; + } + return -EINVAL; +} + +struct console_font_op32 { + unsigned int op; /* operation code KD_FONT_OP_* */ + unsigned int flags; /* KD_FONT_FLAG_* */ + unsigned int width, height; /* font size */ + unsigned int charcount; + u32 data; /* font data with height fixed to 32 */ +}; + +static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file) +{ + struct console_font_op op; + int perm = vt_check(file), i; + struct vt_struct *vt; + + if (perm < 0) return perm; + + if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32))) + return -EFAULT; + if (!perm && op.op != KD_FONT_OP_GET) + return -EPERM; + op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data); + op.flags |= KD_FONT_FLAG_OLD; + vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data; + i = con_font_op(vt->vc_num, &op); + if (i) return i; + ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; + if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32))) + return -EFAULT; + return 0; +} + +#endif /* CONFIG_VT */ + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */ +typedef struct { + uint8_t vg_name[NAME_LEN]; + uint32_t vg_number; + uint32_t vg_access; + uint32_t vg_status; + uint32_t lv_max; + uint32_t lv_cur; + uint32_t lv_open; + uint32_t pv_max; + uint32_t pv_cur; + uint32_t pv_act; + uint32_t dummy; + uint32_t vgda; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pvg_total; + u32 proc; + u32 pv[ABS_MAX_PV + 1]; + u32 lv[ABS_MAX_LV + 1]; + uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */ + uint8_t dummy1[200]; +} vg32_t; + +typedef struct { + uint8_t id[2]; + uint16_t version; + lvm_disk_data_t pv_on_disk; + lvm_disk_data_t vg_on_disk; + lvm_disk_data_t pv_namelist_on_disk; + lvm_disk_data_t lv_on_disk; + lvm_disk_data_t pe_on_disk; + uint8_t pv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint8_t system_id[NAME_LEN]; + kdev_t pv_dev; + uint32_t pv_number; + uint32_t pv_status; + uint32_t pv_allocatable; + uint32_t pv_size; + uint32_t lv_cur; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pe_stale; + u32 pe; + u32 inode; + uint8_t pv_uuid[UUID_LEN+1]; +} pv32_t; + +typedef struct { + char lv_name[NAME_LEN]; + u32 lv; +} lv_req32_t; + +typedef struct { + u32 lv_index; + u32 lv; + /* Transfer size because user space and kernel space differ */ + uint16_t size; +} lv_status_byindex_req32_t; + +typedef struct { + __kernel_dev_t32 dev; + u32 lv; +} lv_status_bydev_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + kdev_t old_dev; + kdev_t new_dev; + u32 old_pe; + u32 new_pe; +} le_remap_req32_t; + +typedef struct { + char pv_name[NAME_LEN]; + u32 pv; +} pv_status_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint32_t lv_access; + uint32_t lv_status; + uint32_t lv_open; + kdev_t lv_dev; + uint32_t lv_number; + uint32_t lv_mirror_copies; + uint32_t lv_recovery; + uint32_t lv_schedule; + uint32_t lv_size; + u32 lv_current_pe; + uint32_t lv_current_le; + uint32_t lv_allocated_le; + uint32_t lv_stripes; + uint32_t lv_stripesize; + uint32_t lv_badblock; + uint32_t lv_allocation; + uint32_t lv_io_timeout; + uint32_t lv_read_ahead; + /* delta to version 1 starts here */ + u32 lv_snapshot_org; + u32 lv_snapshot_prev; + u32 lv_snapshot_next; + u32 lv_block_exception; + uint32_t lv_remap_ptr; + uint32_t lv_remap_end; + uint32_t lv_chunk_size; + uint32_t lv_snapshot_minor; + char dummy[200]; +} lv32_t; + +typedef struct { + u32 hash[2]; + u32 rsector_org; + kdev_t rdev_org; + u32 rsector_new; + kdev_t rdev_new; +} lv_block_exception32_t; + +static void put_lv_t(lv_t *l) +{ + if (l->lv_current_pe) vfree(l->lv_current_pe); + if (l->lv_block_exception) vfree(l->lv_block_exception); + kfree(l); +} + +static lv_t *get_lv_t(u32 p, int *errp) +{ + int err, i; + u32 ptr1, ptr2; + size_t size; + lv_block_exception32_t *lbe32; + lv_block_exception_t *lbe; + lv32_t *ul = (lv32_t *)A(p); + lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL); + + if (!l) { + *errp = -ENOMEM; + return NULL; + } + memset(l, 0, sizeof(lv_t)); + err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + err |= __get_user(ptr1, &ul->lv_current_pe); + err |= __get_user(ptr2, &ul->lv_block_exception); + if (err) { + kfree(l); + *errp = -EFAULT; + return NULL; + } + if (ptr1) { + size = l->lv_allocated_le * sizeof(pe_t); + l->lv_current_pe = vmalloc(size); + if (l->lv_current_pe) + err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size); + } + if (!err && ptr2) { + size = l->lv_remap_end * sizeof(lv_block_exception_t); + l->lv_block_exception = lbe = vmalloc(size); + if (l->lv_block_exception) { + lbe32 = (lv_block_exception32_t *)A(ptr2); + memset(lbe, 0, size); + for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) { + err |= get_user(lbe->rsector_org, &lbe32->rsector_org); + err |= __get_user(lbe->rdev_org, &lbe32->rdev_org); + err |= __get_user(lbe->rsector_new, &lbe32->rsector_new); + err |= __get_user(lbe->rdev_new, &lbe32->rdev_new); + } + } + } + if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) { + if (!err) + *errp = -ENOMEM; + else + *errp = -EFAULT; + put_lv_t(l); + return NULL; + } + return l; +} + +static int copy_lv_t(u32 ptr, lv_t *l) +{ + int err; + lv32_t *ul = (lv32_t *)A(ptr); + u32 ptr1; + size_t size; + + err = get_user(ptr1, &ul->lv_current_pe); + if (err) + return -EFAULT; + err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + size = l->lv_allocated_le * sizeof(pe_t); + if (ptr1) + err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size); + return err ? -EFAULT : 0; +} + +static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + vg_t *v = NULL; + union { + lv_req_t lv_req; + le_remap_req_t le_remap; + lv_status_byindex_req_t lv_byindex; + lv_status_bydev_req_t lv_bydev; + pv_status_req_t pv_status; + } u; + pv_t p; + int err; + u32 ptr = 0; + int i; + mm_segment_t old_fs; + void *karg = &u; + + switch (cmd) { + case VG_STATUS: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) + return -ENOMEM; + karg = v; + break; + + case VG_CREATE_OLD: + case VG_CREATE: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) + return -ENOMEM; + if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) { + kfree(v); + return -EFAULT; + } + /* 'proc' field is unused, just NULL it out. */ + v->proc = NULL; + if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) { + kfree(v); + return -EFAULT; + } + + karg = v; + memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv)); + if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV) + return -EPERM; + for (i = 0; i < v->pv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->pv[i]); + if (err) + break; + if (ptr) { + v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL); + if (!v->pv[i]) { + err = -ENOMEM; + break; + } + err = copy_from_user(v->pv[i], (void *)A(ptr), + sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) { + err = -EFAULT; + break; + } + err = copy_from_user(v->pv[i]->pv_uuid, + ((pv32_t *)A(ptr))->pv_uuid, + UUID_LEN+1); + if (err) { + err = -EFAULT; + break; + } + + v->pv[i]->pe = NULL; + v->pv[i]->bd = NULL; + } + } + if (!err) { + for (i = 0; i < v->lv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->lv[i]); + if (err) + break; + if (ptr) { + v->lv[i] = get_lv_t(ptr, &err); + if (err) + break; + } + } + } + break; + + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + case LV_REMOVE: + case LV_RENAME: + case LV_STATUS_BYNAME: + err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name)); + if (err) + return -EFAULT; + if (cmd != LV_REMOVE) { + err = __get_user(ptr, &((lv_req32_t *)arg)->lv); + if (err) + return err; + u.lv_req.lv = get_lv_t(ptr, &err); + } else + u.lv_req.lv = NULL; + break; + + case LV_STATUS_BYINDEX: + err = get_user(u.lv_byindex.lv_index, + &((lv_status_byindex_req32_t *)arg)->lv_index); + err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv); + if (err) + return err; + u.lv_byindex.lv = get_lv_t(ptr, &err); + break; + + case LV_STATUS_BYDEV: + err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev); + err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv); + if (err) + return err; + u.lv_bydev.lv = get_lv_t(ptr, &err); + break; + + case VG_EXTEND: + err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1); + if (err) + return -EFAULT; + p.pe = NULL; + p.bd = NULL; + karg = &p; + break; + + case PV_CHANGE: + case PV_STATUS: + err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name)); + if (err) + return -EFAULT; + err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv); + if (err) + return err; + u.pv_status.pv = &p; + if (cmd == PV_CHANGE) { + err = copy_from_user(&p, (void *)A(ptr), + sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + p.pe = NULL; + p.bd = NULL; + } + break; + }; + + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)karg); + set_fs (old_fs); + + switch (cmd) { + case VG_STATUS: + if (!err) { + if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) || + clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc)) + err = -EFAULT; + } + if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) { + err = -EFAULT; + } + kfree(v); + break; + + case VG_CREATE_OLD: + case VG_CREATE: + for (i = 0; i < v->pv_max; i++) { + if (v->pv[i]) + kfree(v->pv[i]); + } + for (i = 0; i < v->lv_max; i++) { + if (v->lv[i]) + put_lv_t(v->lv[i]); + } + kfree(v); + break; + + case LV_STATUS_BYNAME: + if (!err && u.lv_req.lv) + err = copy_lv_t(ptr, u.lv_req.lv); + /* Fall through */ + + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + if (u.lv_req.lv) + put_lv_t(u.lv_req.lv); + break; + + case LV_STATUS_BYINDEX: + if (u.lv_byindex.lv) { + if (!err) + err = copy_lv_t(ptr, u.lv_byindex.lv); + put_lv_t(u.lv_byindex.lv); + } + break; + + case LV_STATUS_BYDEV: + if (u.lv_bydev.lv) { + if (!err) + err = copy_lv_t(ptr, u.lv_bydev.lv); + put_lv_t(u.lv_byindex.lv); + } + break; + + case PV_STATUS: + if (!err) { + err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1); + if (err) + return -EFAULT; + err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1); + if (err) + return -EFAULT; + } + break; + }; + + return err; +} +#endif /* CONFIG_BLK_DEV_LVM */ + struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long); @@ -884,6 +1734,7 @@ IOCTL32_DEFAULT(TCSETAW), IOCTL32_DEFAULT(TCSETAF), IOCTL32_DEFAULT(TCSBRK), + IOCTL32_DEFAULT(TCSBRKP), IOCTL32_DEFAULT(TCXONC), IOCTL32_DEFAULT(TCFLSH), IOCTL32_DEFAULT(TCGETS), @@ -934,62 +1785,37 @@ IOCTL32_DEFAULT(FBIOPAN_DISPLAY), #endif /* CONFIG_FB */ - /* Big K */ - IOCTL32_DEFAULT(PIO_FONT), - IOCTL32_DEFAULT(GIO_FONT), - IOCTL32_DEFAULT(KDSIGACCEPT), - IOCTL32_DEFAULT(KDGETKEYCODE), - IOCTL32_DEFAULT(KDSETKEYCODE), - IOCTL32_DEFAULT(KIOCSOUND), - IOCTL32_DEFAULT(KDMKTONE), - IOCTL32_DEFAULT(KDGKBTYPE), - IOCTL32_DEFAULT(KDSETMODE), - IOCTL32_DEFAULT(KDGETMODE), - IOCTL32_DEFAULT(KDSKBMODE), - IOCTL32_DEFAULT(KDGKBMODE), - IOCTL32_DEFAULT(KDSKBMETA), - IOCTL32_DEFAULT(KDGKBMETA), - IOCTL32_DEFAULT(KDGKBENT), - IOCTL32_DEFAULT(KDSKBENT), - IOCTL32_DEFAULT(KDGKBSENT), - IOCTL32_DEFAULT(KDSKBSENT), - IOCTL32_DEFAULT(KDGKBDIACR), - IOCTL32_DEFAULT(KDSKBDIACR), - IOCTL32_DEFAULT(KDKBDREP), - IOCTL32_DEFAULT(KDGKBLED), - IOCTL32_DEFAULT(KDSKBLED), - IOCTL32_DEFAULT(KDGETLED), - IOCTL32_DEFAULT(KDSETLED), - IOCTL32_DEFAULT(GIO_SCRNMAP), - IOCTL32_DEFAULT(PIO_SCRNMAP), - IOCTL32_DEFAULT(GIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_FONTRESET), - IOCTL32_DEFAULT(PIO_UNIMAPCLR), - - /* Big S */ - IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN), - IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK), - IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK), - IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY), - IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE), - IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE), - IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER), - IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND), - - /* Big V */ - IOCTL32_DEFAULT(VT_SETMODE), - IOCTL32_DEFAULT(VT_GETMODE), - IOCTL32_DEFAULT(VT_GETSTATE), - IOCTL32_DEFAULT(VT_OPENQRY), - IOCTL32_DEFAULT(VT_ACTIVATE), - IOCTL32_DEFAULT(VT_WAITACTIVE), - IOCTL32_DEFAULT(VT_RELDISP), - IOCTL32_DEFAULT(VT_DISALLOCATE), - IOCTL32_DEFAULT(VT_RESIZE), - IOCTL32_DEFAULT(VT_RESIZEX), - IOCTL32_DEFAULT(VT_LOCKSWITCH), - IOCTL32_DEFAULT(VT_UNLOCKSWITCH), + /* Little v, the video4linux ioctls */ + IOCTL32_DEFAULT(VIDIOCGCAP), + IOCTL32_DEFAULT(VIDIOCGCHAN), + IOCTL32_DEFAULT(VIDIOCSCHAN), + IOCTL32_DEFAULT(VIDIOCGPICT), + IOCTL32_DEFAULT(VIDIOCSPICT), + IOCTL32_DEFAULT(VIDIOCCAPTURE), + + IOCTL32_DEFAULT(VIDIOCGWIN), + IOCTL32_DEFAULT(VIDIOCSWIN), + IOCTL32_DEFAULT(VIDIOCGFBUF), + IOCTL32_DEFAULT(VIDIOCSFBUF), + + IOCTL32_DEFAULT(VIDIOCKEY), + IOCTL32_DEFAULT(VIDIOCGAUDIO), + IOCTL32_DEFAULT(VIDIOCSAUDIO), + IOCTL32_DEFAULT(VIDIOCSYNC), + IOCTL32_DEFAULT(VIDIOCMCAPTURE), + IOCTL32_DEFAULT(VIDIOCGMBUF), + IOCTL32_DEFAULT(VIDIOCGUNIT), + IOCTL32_DEFAULT(VIDIOCGCAPTURE), + IOCTL32_DEFAULT(VIDIOCSCAPTURE), + /* BTTV specific... */ + IOCTL32_DEFAULT(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256])), + IOCTL32_DEFAULT(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256])), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)), + IOCTL32_DEFAULT(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])), /* struct bttv_pll_info */ + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)), + IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)), #ifdef CONFIG_NET /* Socket level stuff */ @@ -1100,6 +1926,158 @@ IOCTL32_DEFAULT(LOOP_CLR_FD), IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status), IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status), + /* Big Q for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_SEQ_RESET), + IOCTL32_DEFAULT(SNDCTL_SEQ_SYNC), + IOCTL32_DEFAULT(SNDCTL_SYNTH_INFO), + IOCTL32_DEFAULT(SNDCTL_SEQ_CTRLRATE), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETOUTCOUNT), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETINCOUNT), + IOCTL32_DEFAULT(SNDCTL_SEQ_PERCMODE), + IOCTL32_DEFAULT(SNDCTL_FM_LOAD_INSTR), + IOCTL32_DEFAULT(SNDCTL_SEQ_TESTMIDI), + IOCTL32_DEFAULT(SNDCTL_SEQ_RESETSAMPLES), + IOCTL32_DEFAULT(SNDCTL_SEQ_NRSYNTHS), + IOCTL32_DEFAULT(SNDCTL_SEQ_NRMIDIS), + IOCTL32_DEFAULT(SNDCTL_MIDI_INFO), + IOCTL32_DEFAULT(SNDCTL_SEQ_THRESHOLD), + IOCTL32_DEFAULT(SNDCTL_SYNTH_MEMAVL), + IOCTL32_DEFAULT(SNDCTL_FM_4OP_ENABLE), + IOCTL32_DEFAULT(SNDCTL_SEQ_PANIC), + IOCTL32_DEFAULT(SNDCTL_SEQ_OUTOFBAND), + IOCTL32_DEFAULT(SNDCTL_SEQ_GETTIME), + IOCTL32_DEFAULT(SNDCTL_SYNTH_ID), + IOCTL32_DEFAULT(SNDCTL_SYNTH_CONTROL), + IOCTL32_DEFAULT(SNDCTL_SYNTH_REMOVESAMPLE), + /* Big T for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_TMR_TIMEBASE), + IOCTL32_DEFAULT(SNDCTL_TMR_START), + IOCTL32_DEFAULT(SNDCTL_TMR_STOP), + IOCTL32_DEFAULT(SNDCTL_TMR_CONTINUE), + IOCTL32_DEFAULT(SNDCTL_TMR_TEMPO), + IOCTL32_DEFAULT(SNDCTL_TMR_SOURCE), + IOCTL32_DEFAULT(SNDCTL_TMR_METRONOME), + IOCTL32_DEFAULT(SNDCTL_TMR_SELECT), + /* Little m for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_MIDI_PRETIME), + IOCTL32_DEFAULT(SNDCTL_MIDI_MPUMODE), + IOCTL32_DEFAULT(SNDCTL_MIDI_MPUCMD), + /* Big P for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_DSP_RESET), + IOCTL32_DEFAULT(SNDCTL_DSP_SYNC), + IOCTL32_DEFAULT(SNDCTL_DSP_SPEED), + IOCTL32_DEFAULT(SNDCTL_DSP_STEREO), + IOCTL32_DEFAULT(SNDCTL_DSP_GETBLKSIZE), + IOCTL32_DEFAULT(SNDCTL_DSP_CHANNELS), + IOCTL32_DEFAULT(SOUND_PCM_WRITE_FILTER), + IOCTL32_DEFAULT(SNDCTL_DSP_POST), + IOCTL32_DEFAULT(SNDCTL_DSP_SUBDIVIDE), + IOCTL32_DEFAULT(SNDCTL_DSP_SETFRAGMENT), + IOCTL32_DEFAULT(SNDCTL_DSP_GETFMTS), + IOCTL32_DEFAULT(SNDCTL_DSP_SETFMT), + IOCTL32_DEFAULT(SNDCTL_DSP_GETOSPACE), + IOCTL32_DEFAULT(SNDCTL_DSP_GETISPACE), + IOCTL32_DEFAULT(SNDCTL_DSP_NONBLOCK), + IOCTL32_DEFAULT(SNDCTL_DSP_GETCAPS), + IOCTL32_DEFAULT(SNDCTL_DSP_GETTRIGGER), + IOCTL32_DEFAULT(SNDCTL_DSP_SETTRIGGER), + IOCTL32_DEFAULT(SNDCTL_DSP_GETIPTR), + IOCTL32_DEFAULT(SNDCTL_DSP_GETOPTR), + /* SNDCTL_DSP_MAPINBUF, XXX needs translation */ + /* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */ + IOCTL32_DEFAULT(SNDCTL_DSP_SETSYNCRO), + IOCTL32_DEFAULT(SNDCTL_DSP_SETDUPLEX), + IOCTL32_DEFAULT(SNDCTL_DSP_GETODELAY), + IOCTL32_DEFAULT(SNDCTL_DSP_PROFILE), + IOCTL32_DEFAULT(SOUND_PCM_READ_RATE), + IOCTL32_DEFAULT(SOUND_PCM_READ_CHANNELS), + IOCTL32_DEFAULT(SOUND_PCM_READ_BITS), + IOCTL32_DEFAULT(SOUND_PCM_READ_FILTER), + /* Big C for sound/OSS */ + IOCTL32_DEFAULT(SNDCTL_COPR_RESET), + IOCTL32_DEFAULT(SNDCTL_COPR_LOAD), + IOCTL32_DEFAULT(SNDCTL_COPR_RDATA), + IOCTL32_DEFAULT(SNDCTL_COPR_RCODE), + IOCTL32_DEFAULT(SNDCTL_COPR_WDATA), + IOCTL32_DEFAULT(SNDCTL_COPR_WCODE), + IOCTL32_DEFAULT(SNDCTL_COPR_RUN), + IOCTL32_DEFAULT(SNDCTL_COPR_HALT), + IOCTL32_DEFAULT(SNDCTL_COPR_SENDMSG), + IOCTL32_DEFAULT(SNDCTL_COPR_RCVMSG), + /* Big M for sound/OSS */ + IOCTL32_DEFAULT(SOUND_MIXER_READ_VOLUME), + IOCTL32_DEFAULT(SOUND_MIXER_READ_BASS), + IOCTL32_DEFAULT(SOUND_MIXER_READ_TREBLE), + IOCTL32_DEFAULT(SOUND_MIXER_READ_SYNTH), + IOCTL32_DEFAULT(SOUND_MIXER_READ_PCM), + IOCTL32_DEFAULT(SOUND_MIXER_READ_SPEAKER), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE), + IOCTL32_DEFAULT(SOUND_MIXER_READ_MIC), + IOCTL32_DEFAULT(SOUND_MIXER_READ_CD), + IOCTL32_DEFAULT(SOUND_MIXER_READ_IMIX), + IOCTL32_DEFAULT(SOUND_MIXER_READ_ALTPCM), + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECLEV), + IOCTL32_DEFAULT(SOUND_MIXER_READ_IGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_READ_OGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE1), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE2), + IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE3), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL1)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL2)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL3)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEIN)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEOUT)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_VIDEO)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_RADIO)), + IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_MONITOR)), + IOCTL32_DEFAULT(SOUND_MIXER_READ_MUTE), + /* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */ + /* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */ + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECSRC), + IOCTL32_DEFAULT(SOUND_MIXER_READ_DEVMASK), + IOCTL32_DEFAULT(SOUND_MIXER_READ_RECMASK), + IOCTL32_DEFAULT(SOUND_MIXER_READ_STEREODEVS), + IOCTL32_DEFAULT(SOUND_MIXER_READ_CAPS), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_VOLUME), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_BASS), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_TREBLE), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SYNTH), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_PCM), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SPEAKER), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MIC), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_CD), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IMIX), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_ALTPCM), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECLEV), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_OGAIN), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE1), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE2), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE3), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL1)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL2)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL3)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEIN)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEOUT)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_VIDEO)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_RADIO)), + IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_MONITOR)), + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MUTE), + /* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */ + /* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */ + IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECSRC), + IOCTL32_DEFAULT(SOUND_MIXER_INFO), + IOCTL32_DEFAULT(SOUND_OLD_MIXER_INFO), + IOCTL32_DEFAULT(SOUND_MIXER_ACCESS), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE1), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE2), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE3), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE4), + IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE5), + IOCTL32_DEFAULT(SOUND_MIXER_GETLEVELS), + IOCTL32_DEFAULT(SOUND_MIXER_SETLEVELS), + IOCTL32_DEFAULT(OSS_GETVERSION), /* And these ioctls need translation */ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), @@ -1145,11 +2123,53 @@ #endif /* CONFIG_NET */ + IOCTL32_HANDLER(BLKRAGET, w_long), + IOCTL32_HANDLER(BLKGETSIZE, w_long), + // IOCTL32_HANDLER(0x1260, broken_blkgetsize), + IOCTL32_HANDLER(BLKFRAGET, w_long), + IOCTL32_HANDLER(BLKSECTGET, w_long), + IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), + IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), + IOCTL32_HANDLER(VIDIOCGTUNER32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSTUNER32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGWIN32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSWIN32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGFBUF32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSFBUF32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCGFREQ32, do_video_ioctl), + IOCTL32_HANDLER(VIDIOCSFREQ32, do_video_ioctl), + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) + IOCTL32_HANDLER(VG_STATUS, do_lvm_ioctl), + IOCTL32_HANDLER(VG_CREATE_OLD, do_lvm_ioctl), + IOCTL32_HANDLER(VG_CREATE, do_lvm_ioctl), + IOCTL32_HANDLER(VG_EXTEND, do_lvm_ioctl), + IOCTL32_HANDLER(LV_CREATE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_REMOVE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_EXTEND, do_lvm_ioctl), + IOCTL32_HANDLER(LV_REDUCE, do_lvm_ioctl), + IOCTL32_HANDLER(LV_RENAME, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYNAME, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYINDEX, do_lvm_ioctl), + IOCTL32_HANDLER(LV_STATUS_BYDEV, do_lvm_ioctl), + IOCTL32_HANDLER(PV_CHANGE, do_lvm_ioctl), + IOCTL32_HANDLER(PV_STATUS, do_lvm_ioctl), +#endif /* LVM */ + + /* take care of sizeof(sizeof()) breakage */ + /* elevator */ + IOCTL32_HANDLER(BLKELVGET_32, do_blkelvget), + IOCTL32_HANDLER(BLKELVSET_32, do_blkelvset), + /* block stuff */ + IOCTL32_HANDLER(BLKBSZGET_32, do_blkbszget), + IOCTL32_HANDLER(BLKBSZSET_32, do_blkbszset), + IOCTL32_HANDLER(BLKGETSIZE64_32, do_blkgetsize64), + IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), @@ -1178,21 +2198,106 @@ IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls */ IOCTL32_DEFAULT(BLKROGET), IOCTL32_DEFAULT(BLKRRPART), - IOCTL32_HANDLER(BLKGETSIZE, w_long), - IOCTL32_DEFAULT(BLKFLSBUF), IOCTL32_DEFAULT(BLKRASET), - IOCTL32_HANDLER(BLKRAGET, w_long), IOCTL32_DEFAULT(BLKFRASET), - IOCTL32_HANDLER(BLKFRAGET, w_long), IOCTL32_DEFAULT(BLKSECTSET), - IOCTL32_HANDLER(BLKSECTGET, w_long), IOCTL32_DEFAULT(BLKSSZGET), - IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), - IOCTL32_DEFAULT(BLKELVGET), - IOCTL32_DEFAULT(BLKELVSET), - IOCTL32_DEFAULT(BLKBSZGET), - IOCTL32_DEFAULT(BLKBSZSET), + + /* RAID */ + IOCTL32_DEFAULT(RAID_VERSION), + IOCTL32_DEFAULT(GET_ARRAY_INFO), + IOCTL32_DEFAULT(GET_DISK_INFO), + IOCTL32_DEFAULT(PRINT_RAID_DEBUG), + IOCTL32_DEFAULT(CLEAR_ARRAY), + IOCTL32_DEFAULT(ADD_NEW_DISK), + IOCTL32_DEFAULT(HOT_REMOVE_DISK), + IOCTL32_DEFAULT(SET_ARRAY_INFO), + IOCTL32_DEFAULT(SET_DISK_INFO), + IOCTL32_DEFAULT(WRITE_RAID_INFO), + IOCTL32_DEFAULT(UNPROTECT_ARRAY), + IOCTL32_DEFAULT(PROTECT_ARRAY), + IOCTL32_DEFAULT(HOT_ADD_DISK), + IOCTL32_DEFAULT(SET_DISK_FAULTY), + IOCTL32_DEFAULT(RUN_ARRAY), + IOCTL32_DEFAULT(START_ARRAY), + IOCTL32_DEFAULT(STOP_ARRAY), + IOCTL32_DEFAULT(STOP_ARRAY_RO), + IOCTL32_DEFAULT(RESTART_ARRAY_RW), + IOCTL32_DEFAULT(RAID_AUTORUN), + + /* Big K */ + IOCTL32_DEFAULT(PIO_FONT), + IOCTL32_DEFAULT(GIO_FONT), +#ifdef CONFIG_VT + IOCTL32_HANDLER(GIO_FONTX, do_fontx_ioctl), + IOCTL32_HANDLER(PIO_FONTX, do_fontx_ioctl), +#endif + IOCTL32_DEFAULT(KDSIGACCEPT), + IOCTL32_DEFAULT(KDGETKEYCODE), + IOCTL32_DEFAULT(KDSETKEYCODE), + IOCTL32_DEFAULT(KIOCSOUND), + IOCTL32_DEFAULT(KDMKTONE), + IOCTL32_DEFAULT(KDGKBTYPE), + IOCTL32_DEFAULT(KDSETMODE), + IOCTL32_DEFAULT(KDGETMODE), + IOCTL32_DEFAULT(KDSKBMODE), + IOCTL32_DEFAULT(KDGKBMODE), + IOCTL32_DEFAULT(KDSKBMETA), + IOCTL32_DEFAULT(KDGKBMETA), + IOCTL32_DEFAULT(KDGKBENT), + IOCTL32_DEFAULT(KDSKBENT), + IOCTL32_DEFAULT(KDGKBSENT), + IOCTL32_DEFAULT(KDSKBSENT), + IOCTL32_DEFAULT(KDGKBDIACR), + IOCTL32_DEFAULT(KDKBDREP), +#ifdef CONFIG_VT + IOCTL32_HANDLER(KDFONTOP, do_kdfontop_ioctl), +#endif + IOCTL32_DEFAULT(KDSKBDIACR), + IOCTL32_DEFAULT(KDGKBLED), + IOCTL32_DEFAULT(KDSKBLED), + IOCTL32_DEFAULT(KDGETLED), + IOCTL32_DEFAULT(KDSETLED), + IOCTL32_DEFAULT(GIO_SCRNMAP), + IOCTL32_DEFAULT(PIO_SCRNMAP), + IOCTL32_DEFAULT(GIO_UNISCRNMAP), + IOCTL32_DEFAULT(PIO_UNISCRNMAP), + IOCTL32_DEFAULT(PIO_FONTRESET), + IOCTL32_DEFAULT(PIO_UNIMAPCLR), + + /* Big S */ + IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN), + IOCTL32_DEFAULT(SCSI_IOCTL_PROBE_HOST), + IOCTL32_DEFAULT(SCSI_IOCTL_GET_PCI), + IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK), + IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK), + IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY), + IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE), + IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE), + IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER), + IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND), + + /* Big T */ + IOCTL32_DEFAULT(TUNSETNOCSUM), + IOCTL32_DEFAULT(TUNSETDEBUG), + IOCTL32_DEFAULT(TUNSETIFF), + IOCTL32_DEFAULT(TUNSETPERSIST), + IOCTL32_DEFAULT(TUNSETOWNER), + + /* Big V */ + IOCTL32_DEFAULT(VT_SETMODE), + IOCTL32_DEFAULT(VT_GETMODE), + IOCTL32_DEFAULT(VT_GETSTATE), + IOCTL32_DEFAULT(VT_OPENQRY), + IOCTL32_DEFAULT(VT_ACTIVATE), + IOCTL32_DEFAULT(VT_WAITACTIVE), + IOCTL32_DEFAULT(VT_RELDISP), + IOCTL32_DEFAULT(VT_DISALLOCATE), + IOCTL32_DEFAULT(VT_RESIZE), + IOCTL32_DEFAULT(VT_RESIZEX), + IOCTL32_DEFAULT(VT_LOCKSWITCH), + IOCTL32_DEFAULT(VT_UNLOCKSWITCH), #ifdef CONFIG_MD /* status */ @@ -1248,6 +2353,39 @@ IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), + /* DEVFS */ + IOCTL32_DEFAULT(DEVFSDIOC_GET_PROTO_REV), + IOCTL32_DEFAULT(DEVFSDIOC_SET_EVENT_MASK), + IOCTL32_DEFAULT(DEVFSDIOC_RELEASE_EVENT_QUEUE), + IOCTL32_DEFAULT(DEVFSDIOC_SET_DEBUG_MASK), + + /* Raw devices */ + IOCTL32_DEFAULT(RAW_SETBIND), + IOCTL32_DEFAULT(RAW_GETBIND), + +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) + /* 0xfe - lvm */ + IOCTL32_DEFAULT(VG_SET_EXTENDABLE), + IOCTL32_DEFAULT(VG_STATUS_GET_COUNT), + IOCTL32_DEFAULT(VG_STATUS_GET_NAMELIST), + IOCTL32_DEFAULT(VG_REMOVE), + IOCTL32_DEFAULT(VG_RENAME), + IOCTL32_DEFAULT(VG_REDUCE), + IOCTL32_DEFAULT(PE_LOCK_UNLOCK), + IOCTL32_DEFAULT(PV_FLUSH), + IOCTL32_DEFAULT(LVM_LOCK_LVM), + IOCTL32_DEFAULT(LVM_GET_IOP_VERSION), +#ifdef LVM_TOTAL_RESET + IOCTL32_DEFAULT(LVM_RESET), +#endif + IOCTL32_DEFAULT(LV_SET_ACCESS), + IOCTL32_DEFAULT(LV_SET_STATUS), + IOCTL32_DEFAULT(LV_SET_ALLOCATION), + IOCTL32_DEFAULT(LE_REMAP), + IOCTL32_DEFAULT(LV_BMAP), + IOCTL32_DEFAULT(LV_SNAPSHOT_USE_RATE), +#endif /* LVM */ + /* Little p (/dev/rtc, /dev/envctrl, etc.) */ IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */ IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */ @@ -1265,6 +2403,7 @@ IOCTL32_DEFAULT(RTC_SET_TIME), IOCTL32_DEFAULT(RTC_WKALM_SET), IOCTL32_DEFAULT(RTC_WKALM_RD), + #ifdef CONFIG_MTD_CHAR /* Big M */ IOCTL32_DEFAULT(MEMGETINFO), diff -urN linux-2.4.24/arch/mips64/kernel/irq.c linux-2.4.25/arch/mips64/kernel/irq.c --- linux-2.4.24/arch/mips64/kernel/irq.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/mips64/kernel/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -916,8 +916,8 @@ return -EFAULT; /* - * Parse the first 8 characters as a hex string, any non-hex char - * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + * Parse the first HEX_DIGITS characters as a hex string, any non-hex + * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. */ value = 0; diff -urN linux-2.4.24/arch/mips64/kernel/linux32.c linux-2.4.25/arch/mips64/kernel/linux32.c --- linux-2.4.24/arch/mips64/kernel/linux32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/linux32.c 2004-02-18 05:36:30.000000000 -0800 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,37 @@ #include #include +extern asmlinkage long sys_socket(int family, int type, int protocol); +extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen); +extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, + int addrlen); +extern asmlinkage long sys_listen(int fd, int backlog); +extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, + int *upeer_addrlen); +extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr, + int *usockaddr_len); +extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr, + int *usockaddr_len); +extern asmlinkage long sys_socketpair(int family, int type, int protocol, + int *usockvec); +extern asmlinkage long sys_send(int fd, void * buff, size_t len, + unsigned flags); +extern asmlinkage long sys_sendto(int fd, void * buff, size_t len, + unsigned flags, struct sockaddr *addr, int addr_len); +extern asmlinkage long sys_recv(int fd, void * ubuf, size_t size, + unsigned flags); +extern asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, + unsigned flags, struct sockaddr *addr, int *addr_len); +extern asmlinkage long sys_shutdown(int fd, int how); +extern asmlinkage long sys_setsockopt(int fd, int level, int optname, + char *optval, int optlen); +extern asmlinkage long sys_getsockopt(int fd, int level, int optname, + char *optval, int *optlen); +extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags); +extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, + unsigned int flags); + + /* Use this to get at 32-bit user passed pointers. */ /* A() macro should be used for places where you e.g. have some internal variable u32 and just want to get @@ -1463,9 +1495,6 @@ return ret; } -extern asmlinkage int sys_setsockopt(int fd, int level, int optname, - char *optval, int optlen); - static int do_set_attach_filter(int fd, int level, int optname, char *optval, int optlen) { @@ -1771,10 +1800,10 @@ case IPC_STAT: case SEM_STAT: fourth.__pad = &s; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_semctl (first, second, third, fourth); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_semctl(first, second, third | IPC_64, fourth); + set_fs(old_fs); if (third & IPC_64) { struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad); @@ -1936,18 +1965,18 @@ } if (err) break; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds *)&m); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); + set_fs(old_fs); break; case IPC_STAT: case MSG_STAT: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds *)&m); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m); + set_fs(old_fs); if (second & IPC_64) { if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { err = -EFAULT; @@ -2008,8 +2037,6 @@ if (version == 1) return err; - if (version == 1) - return err; err = sys_shmat (first, uptr, second, &raddr); if (err) return err; @@ -2017,21 +2044,23 @@ return err; } +struct shm_info32 { + int used_ids; + u32 shm_tot, shm_rss, shm_swp; + u32 swap_attempts, swap_successes; +}; + static int do_sys32_shmctl (int first, int second, void *uptr) { + struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; + struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; + struct shm_info32 *uip = (struct shm_info32 *)uptr; int err = -EFAULT, err2; - struct shmid_ds s; struct shmid64_ds s64; - struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; - struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; mm_segment_t old_fs; - struct shm_info32 { - int used_ids; - u32 shm_tot, shm_rss, shm_swp; - u32 swap_attempts, swap_successes; - } *uip = (struct shm_info32 *)uptr; struct shm_info si; + struct shmid_ds s; switch (second & ~IPC_64) { case IPC_INFO: @@ -2039,7 +2068,7 @@ case IPC_RMID: case SHM_LOCK: case SHM_UNLOCK: - err = sys_shmctl (first, second, (struct shmid_ds *)uptr); + err = sys_shmctl(first, second, (struct shmid_ds *)uptr); break; case IPC_SET: if (second & IPC_64) { @@ -2053,18 +2082,18 @@ } if (err) break; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, &s); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second & ~IPC_64, &s); + set_fs(old_fs); break; case IPC_STAT: case SHM_STAT: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (void *) &s64); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second | IPC_64, (void *) &s64); + set_fs(old_fs); if (err < 0) break; if (second & IPC_64) { @@ -2111,32 +2140,53 @@ break; case SHM_INFO: - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (void *)&si); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second, (void *)&si); + set_fs(old_fs); if (err < 0) break; - err2 = put_user (si.used_ids, &uip->used_ids); - err2 |= __put_user (si.shm_tot, &uip->shm_tot); - err2 |= __put_user (si.shm_rss, &uip->shm_rss); - err2 |= __put_user (si.shm_swp, &uip->shm_swp); - err2 |= __put_user (si.swap_attempts, - &uip->swap_attempts); - err2 |= __put_user (si.swap_successes, - &uip->swap_successes); + err2 = put_user(si.used_ids, &uip->used_ids); + err2 |= __put_user(si.shm_tot, &uip->shm_tot); + err2 |= __put_user(si.shm_rss, &uip->shm_rss); + err2 |= __put_user(si.shm_swp, &uip->shm_swp); + err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); + err2 |= __put_user (si.swap_successes, &uip->swap_successes); if (err2) err = -EFAULT; break; default: - err = -ENOSYS; + err = -EINVAL; break; } return err; } +static inline void *alloc_user_space(long len) +{ + unsigned long sp = (unsigned long) current + THREAD_SIZE - 32; + + return (void *) (sp - len); +} + +static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems, + const struct timespec32 *timeout32) +{ + struct timespec32 t32; + struct timespec *t64 = alloc_user_space(sizeof(*t64)); + + if (copy_from_user(&t32, timeout32, sizeof(t32))) + return -EFAULT; + + if (put_user(t32.tv_sec, &t64->tv_sec) || + put_user(t32.tv_nsec, &t64->tv_nsec)) + return -EFAULT; + + return sys_semtimedop(semid, tsems, nsems, t64); +} + asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -2149,8 +2199,12 @@ case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semop (first, (struct sembuf *)AA(ptr), - second); + err = sys_semtimedop (first, (struct sembuf *)AA(ptr), + second, NULL); + break; + case SEMTIMEDOP: + err = sys32_semtimedop(first, (struct sembuf *)AA(ptr), second, + (const struct timespec32 *) AA(fifth)); break; case SEMGET: err = sys_semget (first, second, third); @@ -2285,6 +2339,40 @@ return ret; } +/* ustat compatibility */ +struct ustat32 { + __kernel_daddr_t32 f_tfree; + __kernel_ino_t32 f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf); + +asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32) +{ + int err; + struct ustat tmp; + struct ustat32 tmp32; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + err = sys_ustat(dev, &tmp); + set_fs (old_fs); + + if (err) + goto out; + + memset(&tmp32,0,sizeof(struct ustat32)); + tmp32.f_tfree = tmp.f_tfree; + tmp32.f_tinode = tmp.f_tinode; + + err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0; + +out: + return err; +} + /* Handle adjtimex compatability. */ struct timex32 { @@ -2498,7 +2586,7 @@ return tot_len; } -extern __inline__ void +static __inline__ void sockfd_put(struct socket *sock) { fput(sock->file); @@ -2915,6 +3003,98 @@ return sys_readahead(fd, merge_64(a2, a3), count); } +/* Argument list sizes for sys_socketcall */ +#define AL(x) ((x) * sizeof(unsigned int)) +static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), + AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), + AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; +#undef AL + +/* + * System call vectors. + * + * Argument checking cleaned up. Saved 20% in size. + * This function doesn't need to set the kernel lock because + * it is set by the callees. + */ + +asmlinkage long sys32_socketcall(int call, unsigned int *args32) +{ + unsigned int a[6]; + unsigned int a0,a1; + int err; + + if(call<1||call>SYS_RECVMSG) + return -EINVAL; + + /* copy_from_user should be SMP safe. */ + if (copy_from_user(a, args32, socketcall_nargs[call])) + return -EFAULT; + + a0=a[0]; + a1=a[1]; + + switch (call) { + case SYS_SOCKET: + err = sys_socket(a0,a1,a[2]); + break; + case SYS_BIND: + err = sys_bind(a0,(struct sockaddr *)A(a1), a[2]); + break; + case SYS_CONNECT: + err = sys_connect(a0, (struct sockaddr *)A(a1), a[2]); + break; + case SYS_LISTEN: + err = sys_listen(a0,a1); + break; + case SYS_ACCEPT: + err = sys_accept(a0,(struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_GETSOCKNAME: + err = sys_getsockname(a0,(struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_GETPEERNAME: + err = sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2])); + break; + case SYS_SOCKETPAIR: + err = sys_socketpair(a0,a1, a[2], (int *)A(a[3])); + break; + case SYS_SEND: + err = sys_send(a0, (void *)A(a1), a[2], a[3]); + break; + case SYS_SENDTO: + err = sys_sendto(a0,(void *)A(a1), a[2], a[3], + (struct sockaddr *)A(a[4]), a[5]); + break; + case SYS_RECV: + err = sys_recv(a0, (void *)A(a1), a[2], a[3]); + break; + case SYS_RECVFROM: + err = sys_recvfrom(a0, (void *)A(a1), a[2], a[3], + (struct sockaddr *)A(a[4]), (int *)A(a[5])); + break; + case SYS_SHUTDOWN: + err = sys_shutdown(a0,a1); + break; + case SYS_SETSOCKOPT: + err = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]), a[4]); + break; + case SYS_GETSOCKOPT: + err = sys_getsockopt(a0, a1, a[2], (char *)A(a[3]), (int *)A(a[4])); + break; + case SYS_SENDMSG: + err = sys_sendmsg(a0, (struct msghdr *) A(a1), a[2]); + break; + case SYS_RECVMSG: + err = sys_recvmsg(a0, (struct msghdr *) A(a1), a[2]); + break; + default: + err = -EINVAL; + break; + } + return err; +} + #ifdef CONFIG_MODULES /* From sparc64 */ diff -urN linux-2.4.24/arch/mips64/kernel/mips64_ksyms.c linux-2.4.25/arch/mips64/kernel/mips64_ksyms.c --- linux-2.4.24/arch/mips64/kernel/mips64_ksyms.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/mips64_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -62,7 +62,7 @@ EXPORT_SYMBOL_NOVERS(strtok); EXPORT_SYMBOL_NOVERS(strpbrk); -EXPORT_SYMBOL(_clear_page); +EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(kernel_thread); /* diff -urN linux-2.4.24/arch/mips64/kernel/proc.c linux-2.4.25/arch/mips64/kernel/proc.c --- linux-2.4.24/arch/mips64/kernel/proc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/proc.c 2004-02-18 05:36:30.000000000 -0800 @@ -39,6 +39,7 @@ [CPU_R6000A] "R6000A", [CPU_R8000] "R8000", [CPU_R10000] "R10000", + [CPU_R12000] "R12000", [CPU_R4300] "R4300", [CPU_R4650] "R4650", [CPU_R4700] "R4700", @@ -47,6 +48,7 @@ [CPU_R4640] "R4640", [CPU_NEVADA] "Nevada", [CPU_RM7000] "RM7000", + [CPU_RM9000] "RM9000", [CPU_R5432] "R5432", [CPU_4KC] "MIPS 4Kc", [CPU_5KC] "MIPS 5Kc", @@ -63,10 +65,13 @@ [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", [CPU_20KC] "MIPS 20Kc", + [CPU_24K] "MIPS 24K", + [CPU_25KF] "MIPS 25Kf", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", + [CPU_VR4133] "NEC VR4133", [CPU_VR4181] "NEC VR4181", [CPU_VR4181A] "NEC VR4181A", [CPU_SR71000] "Sandcraft SR71000" diff -urN linux-2.4.24/arch/mips64/kernel/r4k_genex.S linux-2.4.25/arch/mips64/kernel/r4k_genex.S --- linux-2.4.24/arch/mips64/kernel/r4k_genex.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/r4k_genex.S 2004-02-18 05:36:30.000000000 -0800 @@ -17,6 +17,7 @@ #include #include #include +#include BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ diff -urN linux-2.4.24/arch/mips64/kernel/scall_64.S linux-2.4.25/arch/mips64/kernel/scall_64.S --- linux-2.4.24/arch/mips64/kernel/scall_64.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/scall_64.S 2004-02-18 05:36:30.000000000 -0800 @@ -33,14 +33,14 @@ #endif ld t1, PT_EPC(sp) # skip syscall on return - subu t0, v0, __NR_Linux # check syscall number - sltiu t0, t0, __NR_Linux_syscalls + 1 + subu t0, v0, __NR_64_Linux # check syscall number + sltiu t0, t0, __NR_64_Linux_syscalls + 1 daddiu t1, 4 # skip to next instruction beqz t0, illegal_syscall sd t1, PT_EPC(sp) dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux * 8))(t0) # syscall routine + ld t2, (sys_call_table - (__NR_64_Linux * 8))(t0) # syscall routine sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -326,7 +326,7 @@ PTR sys_lremovexattr /* 5190 */ PTR sys_fremovexattr PTR sys_tkill - PTR sys_time + PTR sys_ni_syscall PTR sys_ni_syscall /* res. for futex */ PTR sys_ni_syscall /* 5195 rs. sched_setaffinity */ PTR sys_ni_syscall /* res. f. sched_getaffinity */ @@ -345,3 +345,6 @@ PTR sys_ni_syscall PTR sys_ni_syscall /* 5210 */ PTR sys_rt_sigreturn + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_semtimedop diff -urN linux-2.4.24/arch/mips64/kernel/scall_n32.S linux-2.4.25/arch/mips64/kernel/scall_n32.S --- linux-2.4.24/arch/mips64/kernel/scall_n32.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/scall_n32.S 2004-02-18 05:36:30.000000000 -0800 @@ -326,7 +326,7 @@ PTR sys_lremovexattr /* 6190 */ PTR sys_fremovexattr PTR sys_tkill - PTR sys_time + PTR sys_ni_syscall PTR sys_ni_syscall /* res. for futex */ PTR sys_ni_syscall /* 6195 rs. sched_setaffinity */ PTR sys_ni_syscall /* res. f. sched_getaffinity */ @@ -348,7 +348,7 @@ PTR sys_fcntl PTR sys_ni_syscall PTR sys_ni_syscall - PTR sys_ni_syscall /* 6215 */ + PTR sys_semtimedop /* 6215 */ PTR sys_ni_syscall PTR sys_ni_syscall PTR sys_ni_syscall diff -urN linux-2.4.24/arch/mips64/kernel/scall_o32.S linux-2.4.25/arch/mips64/kernel/scall_o32.S --- linux-2.4.24/arch/mips64/kernel/scall_o32.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/scall_o32.S 2004-02-18 05:36:30.000000000 -0800 @@ -386,7 +386,7 @@ sys sys_ni_syscall 0 /* was sys_olduname */ sys sys_umask 1 /* 4060 */ sys sys_chroot 1 - sys sys_ustat 2 + sys sys32_ustat 2 sys sys_dup2 2 sys sys_getppid 0 sys sys_getpgrp 0 /* 4065 */ @@ -426,7 +426,7 @@ sys sys32_statfs 2 sys sys32_fstatfs 2 /* 4100 */ sys sys_ni_syscall 0 /* sys_ioperm */ - sys sys_socketcall 2 + sys sys32_socketcall 2 sys sys_syslog 3 sys sys32_setitimer 3 sys sys32_getitimer 2 /* 4105 */ diff -urN linux-2.4.24/arch/mips64/kernel/semaphore.c linux-2.4.25/arch/mips64/kernel/semaphore.c --- linux-2.4.24/arch/mips64/kernel/semaphore.c 2001-04-17 17:19:25.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/semaphore.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,129 +1,272 @@ /* - * Generic semaphore code. Buyer beware. Do your own - * specific changes in + * Copyright (C) 1999, 2001, 02, 03 Ralf Baechle + * + * Heavily inspired by the Alpha implementation */ - +#include +#include +#include #include -#include + +#ifdef CONFIG_CPU_HAS_LLDSCD +/* + * On machines without lld/scd we need a spinlock to make the manipulation of + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL(semaphore_lock); +#endif /* - * Semaphores are implemented using a two-way counter: - * The "count" variable is decremented for each process - * that tries to sleep, while the "waking" variable is - * incremented when the "up()" code goes to wake up waiting - * processes. - * - * Notably, the inline "up()" and "down()" functions can - * efficiently test if they need to do any extra work (up - * needs to do something only if count was negative before - * the increment operation. - * - * waking_non_zero() (from asm/semaphore.h) must execute - * atomically. - * - * When __up() is called, the count was negative before - * incrementing it, and we need to wake up somebody. - * - * This routine adds one to the count of processes that need to - * wake up and exit. ALL waiting processes actually wake up but - * only the one that gets to the "waking" field first will gate - * through and acquire the semaphore. The others will go back - * to sleep. - * - * Note that these functions are only called when there is - * contention on the lock, and as such all this is the - * "non-critical" part of the whole semaphore business. The - * critical part is the inline stuff in - * where we want to avoid any extra jumps and calls. + * Semaphores are implemented using a two-way counter: The "count" variable is + * decremented for each process that tries to sleep, while the "waking" variable + * is incremented when the "up()" code goes to wake up waiting processes. + * + * Notably, the inline "up()" and "down()" functions can efficiently test if + * they need to do any extra work (up needs to do something only if count was + * negative before the increment operation. + * + * waking_non_zero() must execute atomically. + * + * When __up() is called, the count was negative before incrementing it, and we + * need to wake up somebody. + * + * This routine adds one to the count of processes that need to wake up and + * exit. ALL waiting processes actually wake up but only the one that gets to + * the "waking" field first will gate through and acquire the semaphore. The + * others will go back to sleep. + * + * Note that these functions are only called when there is contention on the + * lock, and as such all this is the "non-critical" part of the whole semaphore + * business. The critical part is the inline stuff in where + * we want to avoid any extra jumps and calls. */ -void __up(struct semaphore *sem) +void __up_wakeup(struct semaphore *sem) { - wake_one_more(sem); wake_up(&sem->wait); } +EXPORT_SYMBOL(__up_wakeup); + +#ifdef CONFIG_CPU_HAS_LLSC + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + __asm__ __volatile__( + "1: ll %1, %2 # waking_non_zero \n" + " blez %1, 2f \n" + " subu %0, %1, 1 \n" + " sc %0, %2 \n" + " beqz %0, 1b \n" + "2: \n" + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); + + return ret; +} + +#else /* !CONFIG_CPU_HAS_LLSC */ + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int waking, ret = 0; + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_lock, flags); + + return ret; +} + +#endif /* !CONFIG_CPU_HAS_LLSC */ + /* - * Perform the "down" function. Return zero for semaphore acquired, - * return negative for signalled out of the function. + * Perform the "down" function. Return zero for semaphore acquired, return + * negative for signalled out of the function. * - * If called from __down, the return is ignored and the wait loop is - * not interruptible. This means that a task waiting on a semaphore - * using "down()" cannot be killed until someone does an "up()" on - * the semaphore. - * - * If called from __down_interruptible, the return value gets checked - * upon return. If the return value is negative then the task continues - * with the negative value in the return register (it can be tested by - * the caller). + * If called from down, the return is ignored and the wait loop is not + * interruptible. This means that a task waiting on a semaphore using "down()" + * cannot be killed until someone does an "up()" on the semaphore. * - * Either form may be used in conjunction with "up()". + * If called from down_interruptible, the return value gets checked upon return. + * If the return value is negative then the task continues with the negative + * value in the return register (it can be tested by the caller). * + * Either form may be used in conjunction with "up()". */ -#define DOWN_VAR \ - struct task_struct *tsk = current; \ - wait_queue_t wait; \ +void __down_failed(struct semaphore * sem) +{ + struct task_struct *tsk = current; + wait_queue_t wait; + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); -#define DOWN_HEAD(task_state) \ - \ - \ - tsk->state = (task_state); \ - add_wait_queue(&sem->wait, &wait); \ - \ - /* \ - * Ok, we're set up. sem->count is known to be less than zero \ - * so we must wait. \ - * \ - * We can let go the lock for purposes of waiting. \ - * We re-acquire it after awaking so as to protect \ - * all semaphore operations. \ - * \ - * If "up()" is called before we call waking_non_zero() then \ - * we will catch it right away. If it is called later then \ - * we will have to go through a wakeup cycle to catch it. \ - * \ - * Multiple waiters contend for the semaphore lock to see \ - * who gets to gate through and who has to wait some more. \ - */ \ + /* + * Ok, we're set up. sem->count is known to be less than zero + * so we must wait. + * + * We can let go the lock for purposes of waiting. + * We re-acquire it after awaking so as to protect + * all semaphore operations. + * + * If "up()" is called before we call waking_non_zero() then + * we will catch it right away. If it is called later then + * we will have to go through a wakeup cycle to catch it. + * + * Multiple waiters contend for the semaphore lock to see + * who gets to gate through and who has to wait some more. + */ for (;;) { - -#define DOWN_TAIL(task_state) \ - tsk->state = (task_state); \ - } \ - tsk->state = TASK_RUNNING; \ + if (waking_non_zero(sem)) + break; + schedule(); + __set_current_state(TASK_UNINTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); remove_wait_queue(&sem->wait, &wait); +} + +EXPORT_SYMBOL(__down_failed); + +#ifdef CONFIG_CPU_HAS_LLDSCD + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + * + * We must undo the sem->count down_interruptible decrement + * simultaneously and atomically with the sem->waking adjustment, + * otherwise we can race with wake_one_more. + * + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. + * + * This is crazy. Normally it's strictly forbidden to use 64-bit operations + * in the 32-bit MIPS kernel. In this case it's however ok because if an + * interrupt has destroyed the upper half of registers sc will fail. + * Note also that this will not work for MIPS32 CPUs! + * + * Pseudocode: + * + * If(sem->waking > 0) { + * Decrement(sem->waking) + * Return(SUCCESS) + * } else If(signal_pending(tsk)) { + * Increment(sem->count) + * Return(-EINTR) + * } else { + * Return(SLEEP) + * } + */ -void __down(struct semaphore * sem) +static inline int +waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk) { - DOWN_VAR - DOWN_HEAD(TASK_UNINTERRUPTIBLE) - if (waking_non_zero(sem)) - break; - schedule(); - DOWN_TAIL(TASK_UNINTERRUPTIBLE) + long ret, tmp; + + __asm__ __volatile__( + " .set push # waking_non_zero_interruptible \n" + " .set mips3 \n" + " .set noat \n" + "0: lld %1, %2 \n" + " li %0, 0 \n" + " sll $1, %1, 0 \n" + " blez $1, 1f \n" + " daddiu %1, %1, -1 \n" + " li %0, 1 \n" + " b 2f \n" + "1: beqz %3, 2f \n" + " li %0, %4 \n" + " dli $1, 0x0000000100000000 \n" + " daddu %1, %1, $1 \n" + "2: scd %1, %2 \n" + " beqz %1, 0b \n" + " .set pop \n" + : "=&r" (ret), "=&r" (tmp), "=m" (*sem) + : "r" (signal_pending(tsk)), "i" (-EINTR)); + + return ret; } -int __down_interruptible(struct semaphore * sem) +#else /* !CONFIG_CPU_HAS_LLDSCD */ + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) { - int ret = 0; - DOWN_VAR - DOWN_HEAD(TASK_INTERRUPTIBLE) + int waking, pending, ret = 0; + unsigned long flags; - ret = waking_non_zero_interruptible(sem, tsk); - if (ret) - { - if (ret == 1) - /* ret != 0 only if we get interrupted -arca */ - ret = 0; - break; + pending = signal_pending(tsk); + + spin_lock_irqsave(&semaphore_lock, flags); + waking = atomic_read(&sem->waking); + if (waking > 0) { + atomic_set(&sem->waking, waking - 1); + ret = 1; + } else if (pending) { + atomic_set(&sem->count, atomic_read(&sem->count) + 1); + ret = -EINTR; } - schedule(); - DOWN_TAIL(TASK_INTERRUPTIBLE) + spin_unlock_irqrestore(&semaphore_lock, flags); + return ret; } -int __down_trylock(struct semaphore * sem) +#endif /* !CONFIG_CPU_HAS_LLDSCD */ + +int __down_failed_interruptible(struct semaphore * sem) { - return waking_non_zero_trylock(sem); + struct task_struct *tsk = current; + wait_queue_t wait; + int ret = 0; + + init_waitqueue_entry(&wait, tsk); + __set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue_exclusive(&sem->wait, &wait); + + /* + * Ok, we're set up. sem->count is known to be less than zero + * so we must wait. + * + * We can let go the lock for purposes of waiting. + * We re-acquire it after awaking so as to protect + * all semaphore operations. + * + * If "up()" is called before we call waking_non_zero() then + * we will catch it right away. If it is called later then + * we will have to go through a wakeup cycle to catch it. + * + * Multiple waiters contend for the semaphore lock to see + * who gets to gate through and who has to wait some more. + */ + for (;;) { + ret = waking_non_zero_interruptible(sem, tsk); + if (ret) { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + __set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); + + return ret; } + +EXPORT_SYMBOL(__down_failed_interruptible); diff -urN linux-2.4.24/arch/mips64/kernel/setup.c linux-2.4.25/arch/mips64/kernel/setup.c --- linux-2.4.24/arch/mips64/kernel/setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -416,6 +416,7 @@ extern void momenco_ocelot_setup(void); extern void momenco_ocelot_g_setup(void); extern void momenco_ocelot_c_setup(void); + extern void momenco_jaguar_atx_setup(void); extern void sead_setup(void); extern void swarm_setup(void); extern void frame_info_init(void); @@ -427,6 +428,9 @@ #ifdef CONFIG_DECSTATION decstation_setup(); #endif +#ifdef CONFIG_PMC_YOSEMITE + pmc_yosemite_setup(); +#endif #ifdef CONFIG_SGI_IP22 ip22_setup(); #endif @@ -451,6 +455,9 @@ #ifdef CONFIG_MOMENCO_OCELOT_C momenco_ocelot_c_setup(); #endif +#ifdef CONFIG_MOMENCO_JAGUAR_ATX + momenco_jaguar_atx_setup(); +#endif strncpy(command_line, arcs_cmdline, CL_SIZE); memcpy(saved_command_line, command_line, CL_SIZE); diff -urN linux-2.4.24/arch/mips64/kernel/signal.c linux-2.4.25/arch/mips64/kernel/signal.c --- linux-2.4.24/arch/mips64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/signal.c 2004-02-18 05:36:30.000000000 -0800 @@ -74,13 +74,12 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys_rt_sigsuspend); +static_unused int _sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; - save_static(®s); - /* XXX Don't preclude handling different sized sigset_t's. */ sigsetsize = regs.regs[5]; if (sigsetsize != sizeof(sigset_t)) diff -urN linux-2.4.24/arch/mips64/kernel/signal32.c linux-2.4.25/arch/mips64/kernel/signal32.c --- linux-2.4.24/arch/mips64/kernel/signal32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/signal32.c 2004-02-18 05:36:30.000000000 -0800 @@ -27,6 +27,13 @@ #include #include +/* + * Including would give use the 64-bit syscall numbers ... + */ +#define __NR_O32_sigreturn 4119 +#define __NR_O32_rt_sigreturn 4193 +#define __NR_O32_restart_syscall 4253 + #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -119,12 +126,12 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys32_sigsuspend); +static_unused int _sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset32_t *uset; sigset_t newset, saveset; - save_static(®s); uset = (sigset32_t *) regs.regs[4]; if (get_sigset(&newset, uset)) return -EFAULT; @@ -146,13 +153,13 @@ } } -asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys32_rt_sigsuspend); +static_unused int _sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset32_t *uset; sigset_t newset, saveset; size_t sigsetsize; - save_static(®s); /* XXX Don't preclude handling different sized sigset_t's. */ sigsetsize = regs.regs[5]; if (sigsetsize != sizeof(sigset32_t)) @@ -234,7 +241,7 @@ if (!access_ok(VERIFY_READ, uss, sizeof(*uss))) return -EFAULT; err |= __get_user(sp, &uss->ss_sp); - kss.ss_size = (long) sp; + kss.ss_sp = (void *) (long) sp; err |= __get_user(kss.ss_size, &uss->ss_size); err |= __get_user(kss.ss_flags, &uss->ss_flags); if (err) diff -urN linux-2.4.24/arch/mips64/kernel/signal_n32.c linux-2.4.25/arch/mips64/kernel/signal_n32.c --- linux-2.4.24/arch/mips64/kernel/signal_n32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/signal_n32.c 2004-02-18 05:36:30.000000000 -0800 @@ -37,6 +37,12 @@ #include #include +/* + * Including TASK_SIZE - len) + return -ENOMEM; + if (addr & ~PAGE_MASK) + return -EINVAL; + if (flags & MAP_SHARED && pages_do_alias((pgoff << PAGE_SHIFT), addr)) + return -EINVAL; + + return addr; +} + asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset) @@ -134,22 +147,22 @@ return error; } -asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys_fork); +static_unused int _sys_fork(abi64_no_regargs, struct pt_regs regs) { int res; - save_static(®s); res = do_fork(SIGCHLD, regs.regs[29], ®s, 0); return res; } -asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs) +save_static_function(sys_clone); +static_unused int _sys_clone(abi64_no_regargs, struct pt_regs regs) { unsigned long clone_flags; unsigned long newsp; int res; - save_static(®s); clone_flags = regs.regs[4]; newsp = regs.regs[5]; if (!newsp) diff -urN linux-2.4.24/arch/mips64/kernel/time.c linux-2.4.25/arch/mips64/kernel/time.c --- linux-2.4.24/arch/mips64/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -102,9 +102,9 @@ /* - * Timer ack for a R4k-compatible timer of a known frequency. + * Timer ack for an R4k-compatible timer of a known frequency. */ -static void c0_fixed_timer_ack(void) +static void c0_timer_ack(void) { unsigned int count; @@ -129,22 +129,23 @@ return read_c0_count(); } -/* For unknown frequency. */ +/* For use solely as a high precision timer. */ static void c0_hpt_init(unsigned int count) { write_c0_count(read_c0_count() - count); } -/* For a known frequency. Used as an interrupt source. */ -static void c0_fixed_hpt_init(unsigned int count) +/* For use both as a high precision timer and an interrupt source. */ +static void c0_hpt_timer_init(unsigned int count) { - expirelo = cycles_per_jiffy; count = read_c0_count() - count; - write_c0_count(0); - write_c0_compare(cycles_per_jiffy); + expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; + write_c0_count(expirelo - cycles_per_jiffy); + write_c0_compare(expirelo); write_c0_count(count); } +int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); void (*mips_hpt_init)(unsigned int); @@ -185,7 +186,7 @@ * This is revolting. We need to set "xtime" correctly. However, * the value in this location is the value at the most recent update * of wall time. Discover what correction gettimeofday() would have - * done, and then undo it! + * made, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY; @@ -328,9 +329,9 @@ "dsll32 %1,%2,0\n\t" "or %1,%1,%0\n\t" "ddivu $0,%1,%4\n\t" + "mflo %1\n\t" "dsll32 %0,%5,0\n\t" "or %0,%0,%6\n\t" - "mflo %1\n\t" "ddivu $0,%0,%1\n\t" "mflo %0\n\t" ".set pop" @@ -410,6 +411,7 @@ */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + unsigned long j; unsigned int count; count = mips_hpt_read(); @@ -447,10 +449,41 @@ * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca - */ - if (!jiffies) { - timerhi = timerlo = 0; - mips_hpt_init(count); + * + * The first timer interrupt comes late as interrupts are + * enabled long after timers are initialized. Therefore the + * high precision timer is fast, leading to wrong gettimeoffset() + * calculations. We deal with it by setting it based on the + * number of its ticks between the second and the third interrupt. + * That is still somewhat imprecise, but it's a good estimate. + * --macro + */ + j = jiffies; + if (j < 4) { + static unsigned int prev_count; + static int hpt_initialized; + + switch (j) { + case 0: + timerhi = timerlo = 0; + mips_hpt_init(count); + break; + case 2: + prev_count = count; + break; + case 3: + if (!hpt_initialized) { + unsigned int c3 = 3 * (count - prev_count); + + timerhi = 0; + timerlo = c3; + mips_hpt_init(count - c3); + hpt_initialized = 1; + } + break; + default: + break; + } } #if !defined(CONFIG_SMP) @@ -500,7 +533,9 @@ int cpu = smp_processor_id(); irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; + + if (cpu != 0) + kstat.irqs[cpu][irq]++; /* we keep interrupt disabled all the time */ local_timer_interrupt(irq, NULL, regs); @@ -516,7 +551,7 @@ * * 1) board_time_init() - * a) (optional) set up RTC routines, - * b) (optional) calibrate and set the mips_counter_frequency + * b) (optional) calibrate and set the mips_hpt_frequency * (only needed if you intended to use fixed_rate_gettimeoffset * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_get_time(). @@ -531,7 +566,7 @@ void (*board_time_init)(void); void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency; +unsigned int mips_hpt_frequency; static struct irqaction timer_irqaction = { .handler = timer_interrupt, @@ -539,6 +574,49 @@ .name = "timer", }; +static unsigned int __init calibrate_hpt(void) +{ + u64 frequency; + u32 hpt_start, hpt_end, hpt_count, hz; + + const int loops = HZ / 10; + int log_2_loops = 0; + int i; + + /* + * We want to calibrate for 0.1s, but to avoid a 64-bit + * division we round the number of loops up to the nearest + * power of 2. + */ + while (loops > 1 << log_2_loops) + log_2_loops++; + i = 1 << log_2_loops; + + /* + * Wait for a rising edge of the timer interrupt. + */ + while (mips_timer_state()); + while (!mips_timer_state()); + + /* + * Now see how many high precision timer ticks happen + * during the calculated number of periods between timer + * interrupts. + */ + hpt_start = mips_hpt_read(); + do { + while (mips_timer_state()); + while (!mips_timer_state()); + } while (--i); + hpt_end = mips_hpt_read(); + + hpt_count = hpt_end - hpt_start; + hz = HZ; + frequency = (u64)hpt_count * (u64)hz; + + return frequency >> log_2_loops; +} + void __init time_init(void) { if (board_time_init) @@ -555,7 +633,7 @@ /* No high precision timer -- sorry. */ mips_hpt_read = null_hpt_read; mips_hpt_init = null_hpt_init; - } else if (!mips_counter_frequency) { + } else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ @@ -578,27 +656,36 @@ */ do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* We know counter frequency! */ + /* We know counter frequency. Or we can get it. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - mips_hpt_init = c0_fixed_hpt_init; - if (!mips_timer_ack) - /* R4k timer interrupt ack. */ - mips_timer_ack = c0_fixed_timer_ack; + if (mips_timer_state) + mips_hpt_init = c0_hpt_init; + else { + /* No external timer interrupt -- use R4k. */ + mips_hpt_init = c0_hpt_timer_init; + mips_timer_ack = c0_timer_ack; + } } + if (!mips_hpt_frequency) + mips_hpt_frequency = calibrate_hpt(); do_gettimeoffset = fixed_rate_gettimeoffset; /* Calculate cache parameters. */ - cycles_per_jiffy = mips_counter_frequency / HZ; + cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* Any better way to do this? */ - sll32_usecs_per_cycle = mips_counter_frequency / 100000; - sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; - sll32_usecs_per_cycle *= 10; + do_div64_32(sll32_usecs_per_cycle, + 1000000, mips_hpt_frequency / 2, + mips_hpt_frequency); + + /* Report the high precision timer rate for a reference. */ + printk("Using %u.%03u MHz high precision timer.\n", + ((mips_hpt_frequency + 500) / 1000) / 1000, + ((mips_hpt_frequency + 500) / 1000) % 1000); } if (!mips_timer_ack) diff -urN linux-2.4.24/arch/mips64/kernel/traps.c linux-2.4.25/arch/mips64/kernel/traps.c --- linux-2.4.24/arch/mips64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/traps.c 2004-02-18 05:36:30.000000000 -0800 @@ -232,6 +232,7 @@ printk("epc : %016lx %s\nbadvaddr: %016lx\n", regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); printk("Status : %08x [ ", (unsigned int) regs->cp0_status); + if (regs->cp0_status & ST0_KX) printk("KX "); if (regs->cp0_status & ST0_SX) printk("SX "); if (regs->cp0_status & ST0_UX) printk("UX "); @@ -247,6 +248,7 @@ printk("]\n"); printk("Cause : %08x\n", (unsigned int) regs->cp0_cause); + printk("PrId : %08x\n", read_c0_prid()); } void show_registers(struct pt_regs *regs) @@ -533,6 +535,8 @@ simulate_sc(regs, opcode); return 0; } + + return -EFAULT; /* Strange things going on ... */ } asmlinkage void do_ov(struct pt_regs *regs) @@ -594,6 +598,8 @@ unsigned int opcode, bcode; siginfo_t info; + die_if_kernel("Break instruction in kernel code", regs); + if (get_insn_opcode(regs, &opcode)) return; diff -urN linux-2.4.24/arch/mips64/kernel/unaligned.c linux-2.4.25/arch/mips64/kernel/unaligned.c --- linux-2.4.24/arch/mips64/kernel/unaligned.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/kernel/unaligned.c 2004-02-18 05:36:30.000000000 -0800 @@ -40,7 +40,7 @@ * Below a little program to play around with this feature. * * #include - * #include + * #include * * struct foo { * unsigned char bar[8]; diff -urN linux-2.4.24/arch/mips64/ld.script.elf32.S linux-2.4.25/arch/mips64/ld.script.elf32.S --- linux-2.4.24/arch/mips64/ld.script.elf32.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/ld.script.elf32.S 2004-02-18 05:36:30.000000000 -0800 @@ -50,9 +50,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff -urN linux-2.4.24/arch/mips64/ld.script.elf64 linux-2.4.25/arch/mips64/ld.script.elf64 --- linux-2.4.24/arch/mips64/ld.script.elf64 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/ld.script.elf64 2004-02-18 05:36:30.000000000 -0800 @@ -59,9 +59,6 @@ . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff -urN linux-2.4.24/arch/mips64/lib/Makefile linux-2.4.25/arch/mips64/lib/Makefile --- linux-2.4.24/arch/mips64/lib/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/lib/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -6,9 +6,12 @@ L_TARGET = lib.a -obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o promlib.o rtc-std.o \ - rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \ - strnlen_user.o watch.o +obj-y += csum_partial.o csum_partial_copy.o \ + promlib.o rtc-std.o rtc-no.o memcpy.o \ + memset.o watch.o strlen_user.o \ + strncpy_user.o dump_tlb.o strnlen_user.o + +export-objs := rtc-std.o rtc-no.o obj-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o obj-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module diff -urN linux-2.4.24/arch/mips64/lib/rtc-no.c linux-2.4.25/arch/mips64/lib/rtc-no.c --- linux-2.4.24/arch/mips64/lib/rtc-no.c 2001-07-04 11:50:39.000000000 -0700 +++ linux-2.4.25/arch/mips64/lib/rtc-no.c 2004-02-18 05:36:30.000000000 -0800 @@ -9,25 +9,25 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include +#include #include -static unsigned char no_rtc_read_data(unsigned long addr) +static unsigned int shouldnt_happen(void) { - panic("no_rtc_read_data called - shouldn't happen."); -} + static int called; -static void no_rtc_write_data(unsigned char data, unsigned long addr) -{ - panic("no_rtc_write_data called - shouldn't happen."); -} + if (!called) { + called = 1; + printk(KERN_DEBUG "RTC functions called - shouldn't happen\n"); + } -static int no_rtc_bcd_mode(void) -{ - panic("no_rtc_bcd_mode called - shouldn't happen."); + return 0; } struct rtc_ops no_rtc_ops = { - &no_rtc_read_data, - &no_rtc_write_data, - &no_rtc_bcd_mode + .rtc_read_data = (void *) &shouldnt_happen, + .rtc_write_data = (void *) &shouldnt_happen, + .rtc_bcd_mode = (void *) &shouldnt_happen }; + +EXPORT_SYMBOL(rtc_ops); diff -urN linux-2.4.24/arch/mips64/lib/rtc-std.c linux-2.4.25/arch/mips64/lib/rtc-std.c --- linux-2.4.24/arch/mips64/lib/rtc-std.c 2001-07-04 11:50:39.000000000 -0700 +++ linux-2.4.25/arch/mips64/lib/rtc-std.c 2004-02-18 05:36:30.000000000 -0800 @@ -5,8 +5,9 @@ * * RTC routines for PC style attached Dallas chip. * - * Copyright (C) 1998 by Ralf Baechle + * Copyright (C) 1998, 2001 by Ralf Baechle */ +#include #include #include @@ -32,3 +33,5 @@ &std_rtc_write_data, &std_rtc_bcd_mode }; + +EXPORT_SYMBOL(rtc_ops); diff -urN linux-2.4.24/arch/mips64/mm/Makefile linux-2.4.25/arch/mips64/mm/Makefile --- linux-2.4.24/arch/mips64/mm/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -16,12 +16,13 @@ obj-$(CONFIG_CPU_NEVADA) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o obj-$(CONFIG_CPU_R5432) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o obj-$(CONFIG_CPU_RM7000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_RM9000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o obj-$(CONFIG_CPU_R10000) += c-r4k.o pg-r4k.o tlb-andes.o tlb-glue-r4k.o obj-$(CONFIG_CPU_SB1) += c-sb1.o pg-sb1.o tlb-sb1.o tlb-glue-sb1.o \ cex-sb1.o cerr-sb1.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_SGI_IP22) += sc-ip22.o diff -urN linux-2.4.24/arch/mips64/mm/c-r4k.c linux-2.4.25/arch/mips64/mm/c-r4k.c --- linux-2.4.24/arch/mips64/mm/c-r4k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/c-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -28,27 +28,6 @@ static unsigned long icache_size, dcache_size, scache_size; -extern void andes_clear_page(void * page); -extern void r4k_clear_page32_d16(void * page); -extern void r4k_clear_page32_d32(void * page); -extern void r4k_clear_page_d16(void * page); -extern void r4k_clear_page_d32(void * page); -extern void r4k_clear_page_r4600_v1(void * page); -extern void r4k_clear_page_r4600_v2(void * page); -extern void r4k_clear_page_s16(void * page); -extern void r4k_clear_page_s32(void * page); -extern void r4k_clear_page_s64(void * page); -extern void r4k_clear_page_s128(void * page); -extern void andes_copy_page(void * to, void * from); -extern void r4k_copy_page_d16(void * to, void * from); -extern void r4k_copy_page_d32(void * to, void * from); -extern void r4k_copy_page_r4600_v1(void * to, void * from); -extern void r4k_copy_page_r4600_v2(void * to, void * from); -extern void r4k_copy_page_s16(void * to, void * from); -extern void r4k_copy_page_s32(void * to, void * from); -extern void r4k_copy_page_s64(void * to, void * from); -extern void r4k_copy_page_s128(void * to, void * from); - /* * Dummy cache handling routines for machines without boardcaches */ @@ -73,80 +52,46 @@ __asm__ __volatile__("nop;nop;nop;nop"); \ } while (0) -static void r4k_blast_dcache_page(unsigned long addr) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; +static void (* r4k_blast_dcache_page)(unsigned long addr); -dc_16: - blast_dcache16_page(addr); - return; - -dc_32: +static inline void r4k_blast_dcache_page_dc32(unsigned long addr) +{ R4600_HIT_CACHEOP_WAR_IMPL; blast_dcache32_page(addr); - return; +} -init: - dc_lsize = current_cpu_data.dcache.linesz; +static inline void r4k_blast_dcache_page_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache_page = blast_dcache16_page; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; } -static void r4k_blast_dcache_page_indexed(unsigned long addr) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; - -dc_16: - blast_dcache16_page_indexed(addr); - return; - -dc_32: - blast_dcache32_page_indexed(addr); - return; +static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -init: - dc_lsize = current_cpu_data.dcache.linesz; +static void r4k_blast_dcache_page_indexed_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; } -static void r4k_blast_dcache(void) -{ - static void *l = &&init; - unsigned long dc_lsize; - - goto *l; - -dc_16: - blast_dcache16(); - return; - -dc_32: - blast_dcache32(); - return; +static void (* r4k_blast_dcache)(void); -init: - dc_lsize = current_cpu_data.dcache.linesz; +static inline void r4k_blast_dcache_setup(void) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; if (dc_lsize == 16) - l = &&dc_16; + r4k_blast_dcache = blast_dcache16; else if (dc_lsize == 32) - l = &&dc_32; - goto *l; + r4k_blast_dcache = blast_dcache32; } /* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ @@ -201,175 +146,82 @@ cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_blast_icache_page(unsigned long addr) +static void (* r4k_blast_icache_page)(unsigned long addr); + +static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16_page(addr); - return; -ic_32: - blast_icache32_page(addr); - return; - -ic_64: - blast_icache64_page(addr); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache_page = blast_icache16_page; else if (ic_lsize == 32) - l = &&ic_32; + r4k_blast_icache_page = blast_icache32_page; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache_page = blast_icache64_page; } -static void r4k_blast_icache_page_indexed(unsigned long addr) +static void (* r4k_blast_icache_page_indexed)(unsigned long addr); + +static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16_page_indexed(addr); - return; - -ic_32: - blast_icache32_page_indexed(addr); - return; -ic_64: - blast_icache64_page_indexed(addr); - return; - -ic_32_tx49: - tx49_blast_icache32_page_indexed(addr); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache_page_indexed = blast_icache16_page_indexed; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed; else if (ic_lsize == 32) - if (TX49XX_ICACHE_INDEX_INV_WAR) - l = &&ic_32_tx49; - else - l = &&ic_32; + r4k_blast_icache_page_indexed = blast_icache32_page_indexed; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache_page_indexed = blast_icache64_page_indexed; } -static void r4k_blast_icache(void) +static void (* r4k_blast_icache)(void); + +static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = current_cpu_data.icache.linesz; - static void *l = &&init; - - goto *l; - -ic_16: - blast_icache16(); - return; -ic_32: - blast_icache32(); - return; - -ic_64: - blast_icache64(); - return; - -ic_32_tx49: - tx49_blast_icache32(); - return; - -init: if (ic_lsize == 16) - l = &&ic_16; + r4k_blast_icache = blast_icache16; + else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR) + r4k_blast_icache = tx49_blast_icache32; else if (ic_lsize == 32) - if (TX49XX_ICACHE_INDEX_INV_WAR) - l = &&ic_32_tx49; - else - l = &&ic_32; + r4k_blast_icache = blast_icache32; else if (ic_lsize == 64) - l = &&ic_64; - goto *l; + r4k_blast_icache = blast_icache64; } -static void r4k_blast_scache_page(unsigned long addr) +static void (* r4k_blast_scache_page)(unsigned long addr); + +static inline void r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = current_cpu_data.scache.linesz; - static void *l = &&init; - - goto *l; -sc_16: - blast_scache16_page(addr); - return; - -sc_32: - blast_scache32_page(addr); - return; - -sc_64: - blast_scache64_page(addr); - return; - -sc_128: - blast_scache128_page(addr); - return; - -init: if (sc_lsize == 16) - l = &&sc_16; + r4k_blast_scache_page = blast_scache16_page; else if (sc_lsize == 32) - l = &&sc_32; + r4k_blast_scache_page = blast_scache32_page; else if (sc_lsize == 64) - l = &&sc_64; + r4k_blast_scache_page = blast_scache64_page; else if (sc_lsize == 128) - l = &&sc_128; - goto *l; + r4k_blast_scache_page = blast_scache128_page; } -static void r4k_blast_scache(void) +static void (* r4k_blast_scache)(void); + +static inline void r4k_blast_scache_setup(void) { unsigned long sc_lsize = current_cpu_data.scache.linesz; - static void *l = &&init; - goto *l; - -sc_16: - blast_scache16(); - return; - -sc_32: - blast_scache32(); - return; - -sc_64: - blast_scache64(); - return; - -sc_128: - blast_scache128(); - return; - -init: if (sc_lsize == 16) - l = &&sc_16; + r4k_blast_scache = blast_scache16; else if (sc_lsize == 32) - l = &&sc_32; + r4k_blast_scache = blast_scache32; else if (sc_lsize == 64) - l = &&sc_64; + r4k_blast_scache = blast_scache64; else if (sc_lsize == 128) - l = &&sc_128; - goto *l; + r4k_blast_scache = blast_scache128; } static void r4k_flush_cache_all(void) @@ -561,7 +413,9 @@ */ if (cpu_has_subset_pcaches) { unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); return; } @@ -569,6 +423,7 @@ if (!cpu_has_ic_fills_f_dc) { unsigned long addr = (unsigned long) page_address(page); r4k_blast_dcache_page(addr); + ClearPageDcacheDirty(page); } /* @@ -775,6 +630,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit= ffs(dcache_size/2) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R5432: @@ -788,6 +645,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_TX49XX: @@ -800,6 +659,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 4; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R4000PC: @@ -818,6 +679,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 1; c->dcache.waybit = 0; /* does not matter */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_R10000: @@ -831,9 +694,20 @@ c->dcache.linesz = 32; c->dcache.ways = 2; c->dcache.waybit = 0; + + c->options |= MIPS_CPU_PREFETCH; break; + case CPU_VR4133: + write_c0_config(config & ~CONF_EB); case CPU_VR4131: + /* Workaround for cache instruction bug of VR4131 */ + if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U || + c->processor_id == 0x0c82U) { + config &= ~0x00000030U; + config |= 0x00410000U; + write_c0_config(config); + } icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 2; @@ -843,6 +717,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 2; c->dcache.waybit = ffs(dcache_size/2) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_VR41XX: @@ -860,11 +736,14 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 1; c->dcache.waybit = 0; /* does not matter */ + + c->options |= MIPS_CPU_CACHE_CDEX_P; break; case CPU_RM7000: rm7k_erratum31(); + case CPU_RM9000: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 4; @@ -874,6 +753,8 @@ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); c->dcache.ways = 4; c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + + c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH; break; default: @@ -898,6 +779,9 @@ c->icache.linesz; c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + /* * Now probe the MIPS32 / MIPS64 data cache. */ @@ -914,6 +798,8 @@ c->dcache.ways * c->dcache.linesz; c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + + c->options |= MIPS_CPU_PREFETCH; break; } @@ -947,9 +833,6 @@ if (c->dcache.waysize > PAGE_SIZE) c->dcache.flags |= MIPS_CACHE_ALIASES; - if (config & 0x8) /* VI bit */ - c->icache.flags |= MIPS_CACHE_VTAG; - switch (c->cputype) { case CPU_20KC: /* @@ -1037,71 +920,6 @@ return 1; } -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch (current_cpu_data.dcache.linesz) { - case 16: - if (cpu_has_64bits) - _clear_page = r4k_clear_page_d16; - else - _clear_page = r4k_clear_page32_d16; - _copy_page = r4k_copy_page_d16; - - break; - case 32: - prid = read_c0_prid() & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - } else { - if (cpu_has_64bits) - _clear_page = r4k_clear_page_d32; - else - _clear_page = r4k_clear_page32_d32; - _copy_page = r4k_copy_page_d32; - } - break; - } -} - -static void __init setup_scache_funcs(void) -{ - struct cpuinfo_mips *c = ¤t_cpu_data; - - if (c->dcache.linesz > c->scache.linesz) - panic("Invalid primary cache configuration detected"); - - if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - return; - } - - switch (c->scache.linesz) { - case 16: - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } -} - typedef int (*probe_func_t)(unsigned long); extern int r5k_sc_init(void); extern int rm7k_sc_init(void); @@ -1127,6 +945,8 @@ case CPU_R4400MC: probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); sc_present = probe_scache_kseg1(config); + if (sc_present) + c->options |= MIPS_CPU_CACHE_CDEX_S; break; case CPU_R10000: @@ -1140,14 +960,13 @@ case CPU_R5000: case CPU_NEVADA: - setup_noscache_funcs(); #ifdef CONFIG_R5000_CPU_SCACHE r5k_sc_init(); #endif return; case CPU_RM7000: - setup_noscache_funcs(); + case CPU_RM9000: #ifdef CONFIG_RM7000_CPU_SCACHE rm7k_sc_init(); #endif @@ -1157,10 +976,8 @@ sc_present = 0; } - if (!sc_present) { - setup_noscache_funcs(); + if (!sc_present) return; - } if ((c->isa_level == MIPS_CPU_ISA_M32 || c->isa_level == MIPS_CPU_ISA_M64) && @@ -1176,7 +993,6 @@ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); c->options |= MIPS_CPU_SUBSET_CACHES; - setup_scache_funcs(); } static inline void coherency_setup(void) @@ -1205,6 +1021,8 @@ void __init ld_mmu_r4xx0(void) { + extern void build_clear_page(void); + extern void build_copy_page(void); extern char except_vec2_generic; struct cpuinfo_mips *c = ¤t_cpu_data; @@ -1219,6 +1037,15 @@ if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) c->dcache.flags |= MIPS_CACHE_ALIASES; + r4k_blast_dcache_page_setup(); + r4k_blast_dcache_page_indexed_setup(); + r4k_blast_dcache_setup(); + r4k_blast_icache_page_setup(); + r4k_blast_icache_page_indexed_setup(); + r4k_blast_icache_setup(); + r4k_blast_scache_page_setup(); + r4k_blast_scache_setup(); + /* * Some MIPS32 and MIPS64 processors have physically indexed caches. * This code supports virtually indexed processors and will be @@ -1247,4 +1074,7 @@ #endif __flush_cache_all(); + + build_clear_page(); + build_copy_page(); } diff -urN linux-2.4.24/arch/mips64/mm/c-sb1.c linux-2.4.25/arch/mips64/mm/c-sb1.c --- linux-2.4.24/arch/mips64/mm/c-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/c-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,14 +25,7 @@ #include #include -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS extern void sb1_dma_init(void); -extern void sb1_clear_page_dma(void * page); -extern void sb1_copy_page_dma(void * to, void * from); -#else -extern void sb1_clear_page(void * page); -extern void sb1_copy_page(void * to, void * from); -#endif /* These are probed at ld_mmu time */ static unsigned long icache_size; @@ -231,6 +224,7 @@ if (!(vma->vm_flags & VM_EXEC)) return; + addr &= PAGE_MASK; args.vma = vma; args.addr = addr; smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); @@ -556,21 +550,18 @@ void ld_mmu_sb1(void) { extern char except_vec2_sb1; + extern char handle_vec2_sb1; unsigned long temp; /* Special cache error handler for SB1 */ memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); probe_cache_sizes(); #ifdef CONFIG_SIBYTE_DMA_PAGEOPS - _clear_page = sb1_clear_page_dma; - _copy_page = sb1_copy_page_dma; sb1_dma_init(); -#else - _clear_page = sb1_clear_page; - _copy_page = sb1_copy_page; #endif /* @@ -579,7 +570,6 @@ * occur */ _flush_cache_range = (void *) sb1_nop; - _flush_cache_page = sb1_flush_cache_page; _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; _flush_cache_all = sb1_nop; @@ -590,6 +580,9 @@ _flush_cache_sigtramp = sb1_flush_cache_sigtramp; _flush_data_cache_page = (void *) sb1_nop; + /* This implies an Icache flush too, so can't be nop'ed */ + _flush_cache_page = sb1_flush_cache_page; + /* Full flushes */ ___flush_cache_all = sb1___flush_cache_all; diff -urN linux-2.4.24/arch/mips64/mm/cerr-sb1.c linux-2.4.25/arch/mips64/mm/cerr-sb1.c --- linux-2.4.24/arch/mips64/mm/cerr-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/cerr-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -193,7 +193,9 @@ prom_printf(" c0_cerr_i == %08x", cerr_i); breakout_cerri(cerr_i); if (CP0_CERRI_IDX_VALID(cerr_i)) { - if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + /* Check index of EPC, allowing for delay slot */ + if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) && + ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4))) prom_printf(" cerr_i idx doesn't match eepc\n"); else { res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, diff -urN linux-2.4.24/arch/mips64/mm/cex-sb1.S linux-2.4.25/arch/mips64/mm/cex-sb1.S --- linux-2.4.24/arch/mips64/mm/cex-sb1.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/cex-sb1.S 2004-02-18 05:36:30.000000000 -0800 @@ -22,40 +22,122 @@ #include #include #include +#include +#include #include - .text - .set noat - .set mips4 +#define C0_ERRCTL $26 /* CP0: Error info */ +#define C0_CERR_I $27 /* CP0: Icache error */ +#define C0_CERR_D $27,1 /* CP0: Dcache error */ + + /* + * Based on SiByte sample software cache-err/cerr.S + * CVS revision 1.8. Only the 'unrecoverable' case + * is changed. + */ __INIT - - /* Cache Error handler for SB1 */ - LEAF(except_vec2_sb1) - mfc0 k1, $26 - # check if error was recoverable - bltz k1, leave_cerr -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - # look for signature of spurious CErr - lui k0, 0x4000 - bne k0, k1, 1f - .word 0x401Bd801 # mfc0 k1, $27, 1 - lui k0, 0xffe0 - and k1, k0, k1 - lui k0, 0x0200 - beq k0, k1, leave_cerr -1: -#endif - j handle_vec2_sb1 -leave_cerr: - # clear/unlock the registers - mtc0 zero, $26 - mtc0 zero, $27 - .word 0x4080d801 # mtc0 zero, $27, 1 - .word 0x4080d803 # mtc0 zero, $27, 3 + .set mips64 + .set noreorder + .set noat + + /* + * sb1_cerr_vec: code to be copied to the Cache Error + * Exception vector. The code must be pushed out to memory + * (either by copying to Kseg0 and Kseg1 both, or by flushing + * the L1 and L2) since it is fetched as 0xa0000100. + * + * NOTE: Be sure this handler is at most 28 instructions long + * since the final 16 bytes of the exception vector memory + * (0x170-0x17f) are used to preserve k0, k1, and ra. + */ + +LEAF(except_vec2_sb1) + /* + * If this error is recoverable, we need to exit the handler + * without having dirtied any registers. To do this, + * save/restore k0 and k1 from low memory (Useg is direct + * mapped while ERL=1). Note that we can't save to a + * CPU-specific location without ruining a register in the + * process. This means we are vulnerable to data corruption + * whenever the handler is reentered by a second CPU. + */ + sd k0,0x170($0) + sd k1,0x178($0) + + /* + * M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell + * if we can fast-path out of here for a h/w-recovered error. + */ + mfc0 k1,C0_ERRCTL + bgtz k1,attempt_recovery + sll k0,k1,1 + +recovered_dcache: + /* + * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA). + * Ought to log the occurence of this recovered dcache error. + */ + b recovered + .word 0x4080d801 # mtc0 zero, $27, 1 + +attempt_recovery: + /* + * k0 has C0_ERRCTL << 1, which puts 'DC' at bit 31. Any + * Dcache errors we can recover from will take more extensive + * processing. For now, they are considered "unrecoverable". + * Note that 'DC' becoming set (outside of ERL mode) will + * cause 'IC' to clear; so if there's an Icache error, we'll + * only find out about it if we recover from this error and + * continue executing. + */ + bltz k0,unrecoverable + sll k0,1 + + /* + * k0 has C0_ERRCTL << 2, which puts 'IC' at bit 31. If an + * Icache error isn't indicated, I'm not sure why we got here. + * Consider that case "unrecoverable" for now. + */ + bgez k0,unrecoverable + +attempt_icache_recovery: + /* + * External icache errors are due to uncorrectable ECC errors + * in the L2 cache or Memory Controller and cannot be + * recovered here. + */ + mfc0 k0,C0_CERR_I /* delay slot */ + li k1,1 << 26 /* ICACHE_EXTERNAL */ + and k1,k0 + bnez k1,unrecoverable + andi k0,0x1fe0 + + /* + * Since the error is internal, the 'IDX' field from + * CacheErr-I is valid and we can just invalidate all blocks + * in that set. + */ + cache Index_Invalidate_I,(0<<13)(k0) + cache Index_Invalidate_I,(1<<13)(k0) + cache Index_Invalidate_I,(2<<13)(k0) + cache Index_Invalidate_I,(3<<13)(k0) + + /* Ought to log this recovered icache error */ + +recovered: + /* Restore the saved registers */ + ld k0,0x170($0) + ld k1,0x178($0) eret - END(except_vec2_sb1) + +unrecoverable: + /* Unrecoverable Icache or Dcache error; log it and/or fail */ + j handle_vec2_sb1 + nop + +END(except_vec2_sb1) __FINIT @@ -75,9 +157,16 @@ mfc0 k0, CP0_STATUS sll k0, k0, 3 # check CU0 (kernel?) bltz k0, 2f + nop + + /* Get a valid Kseg0 stack pointer. Any task's stack pointer + * will do, although if we ever want to resume execution we + * better not have corrupted any state. */ get_saved_sp - move sp, k1 # want Kseg SP (so uncached) + move sp, k1 + 2: j sb1_cache_error + nop END(handle_vec2_sb1) diff -urN linux-2.4.24/arch/mips64/mm/fault.c linux-2.4.25/arch/mips64/mm/fault.c --- linux-2.4.24/arch/mips64/mm/fault.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/fault.c 2004-02-18 05:36:30.000000000 -0800 @@ -266,5 +266,5 @@ return; vmalloc_fault: - panic("Pagefault for kernel virtual memory"); + die("Pagefault for kernel virtual memory", regs); } diff -urN linux-2.4.24/arch/mips64/mm/init.c linux-2.4.25/arch/mips64/mm/init.c --- linux-2.4.24/arch/mips64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -63,7 +63,7 @@ { pgd_t *ret, *init; - ret = (pgd_t *) __get_free_pages(GFP_KERNEL, 1); + ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); if (ret) { init = pgd_offset(&init_mm, 0); pgd_init((unsigned long)ret); diff -urN linux-2.4.24/arch/mips64/mm/loadmmu.c linux-2.4.25/arch/mips64/mm/loadmmu.c --- linux-2.4.24/arch/mips64/mm/loadmmu.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/loadmmu.c 2004-02-18 05:36:30.000000000 -0800 @@ -22,10 +22,6 @@ #include #include -/* memory functions */ -void (*_clear_page)(void * page); -void (*_copy_page)(void * to, void * from); - /* Cache operations. */ void (*_flush_cache_all)(void); void (*___flush_cache_all)(void); @@ -73,7 +69,7 @@ defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ - defined(CONFIG_CPU_RM7000) + defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000) ld_mmu_r4xx0(); r4k_tlb_init(); #endif diff -urN linux-2.4.24/arch/mips64/mm/pg-r4k.c linux-2.4.25/arch/mips64/mm/pg-r4k.c --- linux-2.4.24/arch/mips64/mm/pg-r4k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/pg-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -3,706 +3,469 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 98, 99, 2000, 01, 02, 03 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) */ +#include #include #include #include #include +#include #include +#include #include #include #include +#include #include #include +#include #include #include +#include /* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: + * Maximum sizes: * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. + * R4000 16 bytes D-cache, 128 bytes S-cache: 0x78 bytes + * R4600 v1.7: 0x5c bytes + * R4600 v2.0: 0x60 bytes + * With prefetching, 16 byte strides 0xa0 bytes */ -void r4k_clear_page_d16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -void r4k_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} +static unsigned int clear_page_array[0xa0 / 4]; +void clear_page(void * page) __attribute__((alias("clear_page_array"))); /* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. + * Maximum sizes: * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -void r4k_clear_page_r4600_v1(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * And this one is for the R4600 V2.0 - */ -void r4k_clear_page_r4600_v2(void * page) -{ - unsigned long flags; - - local_irq_save(flags); - *(volatile unsigned int *)KSEG1; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); - local_irq_restore(flags); -} - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ -void r4k_clear_page_s16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -void r4k_clear_page_s32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -void r4k_clear_page_s64(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -void r4k_clear_page_s128(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "sd\t$0,32(%0)\n\t" - "sd\t$0,40(%0)\n\t" - "sd\t$0,48(%0)\n\t" - "sd\t$0,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "sd\t$0,-64(%0)\n\t" - "sd\t$0,-56(%0)\n\t" - "sd\t$0,-48(%0)\n\t" - "sd\t$0,-40(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -/* - * This version has been tuned on an Origin. For other machines the arguments - * of the pref instructin may have to be tuned differently. + * R4000 16 bytes D-cache, 128 bytes S-cache: 0xbc bytes + * R4600 v1.7: 0x80 bytes + * R4600 v2.0: 0x84 bytes + * With prefetching, 16 byte strides 0xb8 bytes */ -void andes_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tmips4\n\t" - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tpref 7,512(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tpop" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE) - : "memory"); -} +static unsigned int copy_page_array[0xb8 / 4]; +void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); /* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. + * An address fits into a single register so it's safe to use 64-bit registers + * if we have 64-bit adresses. */ - -void r4k_copy_page_d16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void r4k_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} +#define cpu_has_64bit_registers cpu_has_64bit_addresses /* - * Again a special version for the R4600 V1.x + * This is suboptimal for 32-bit kernels; we assume that R10000 is only used + * with 64-bit kernels. The prefetch offsets have been experimentally tuned + * an Origin 200. */ -void r4k_copy_page_r4600_v1(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; +static int pref_offset_clear __initdata = 512; +static int pref_offset_copy __initdata = 256; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void r4k_copy_page_r4600_v2(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - unsigned long flags; - - local_irq_save(flags); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); - local_irq_restore(flags); -} +static unsigned int pref_src_mode __initdata; +static unsigned int pref_dst_mode __initdata; -/* - * These are for R4000SC / R4400MC - */ -void r4k_copy_page_s16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -void r4k_copy_page_s32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -void r4k_copy_page_s64(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -void r4k_copy_page_s128(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "ld\t%2,32(%1)\n\t" - "ld\t%3,40(%1)\n\t" - "ld\t%4,48(%1)\n\t" - "ld\t%5,56(%1)\n\t" - "sd\t%2,32(%0)\n\t" - "sd\t%3,40(%0)\n\t" - "sd\t%4,48(%0)\n\t" - "sd\t%5,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "daddiu\t%1,128\n\t" - "ld\t%2,-64(%1)\n\t" - "ld\t%3,-56(%1)\n\t" - "ld\t%4,-48(%1)\n\t" - "ld\t%5,-40(%1)\n\t" - "sd\t%2,-64(%0)\n\t" - "sd\t%3,-56(%0)\n\t" - "sd\t%4,-48(%0)\n\t" - "sd\t%5,-40(%0)\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -/* - * This version has been tuned on an Origin. For other machines the arguments - * of the pref instructin may have to be tuned differently. - */ -void andes_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; +static int has_scache __initdata = 0; +static int load_offset __initdata = 0; +static int store_offset __initdata = 0; + +static unsigned int __initdata *dest, *epc; + +static inline void build_src_pref(int advance) +{ + if (!(load_offset & (cpu_dcache_line_size() - 1))) { + union mips_instruction mi; + + mi.i_format.opcode = pref_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = pref_src_mode; + mi.i_format.simmediate = load_offset + advance; + + *epc++ = mi.word; + } +} + +static inline void __build_load_reg(int reg) +{ + union mips_instruction mi; + + if (cpu_has_64bit_registers) + mi.i_format.opcode = ld_op; + else + mi.i_format.opcode = lw_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = reg; /* $zero */ + mi.i_format.simmediate = load_offset; + + load_offset += (cpu_has_64bit_registers ? 8 : 4); + + *epc++ = mi.word; +} + +static inline void build_load_reg(int reg) +{ + if (cpu_has_prefetch) + build_src_pref(pref_offset_copy); + + __build_load_reg(reg); +} + +static inline void build_dst_pref(int advance) +{ + if (!(store_offset & (cpu_dcache_line_size() - 1))) { + union mips_instruction mi; + + mi.i_format.opcode = pref_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = pref_dst_mode; + mi.i_format.simmediate = store_offset + advance; + + *epc++ = mi.word; + } +} + +static inline void build_cdex(void) +{ + union mips_instruction mi; + + if (cpu_has_cache_cdex_s && + !(store_offset & (cpu_scache_line_size() - 1))) { + + mi.c_format.opcode = cache_op; + mi.c_format.rs = 4; /* $a0 */ + mi.c_format.c_op = 3; /* Create Dirty Exclusive */ + mi.c_format.cache = 3; /* Secondary Data Cache */ + mi.c_format.simmediate = store_offset; + + *epc++ = mi.word; + } + + if (store_offset & (cpu_dcache_line_size() - 1)) + return; + + if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) { + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + *epc++ = 0; /* nop */ + } + + mi.c_format.opcode = cache_op; + mi.c_format.rs = 4; /* $a0 */ + mi.c_format.c_op = 3; /* Create Dirty Exclusive */ + mi.c_format.cache = 1; /* Data Cache */ + mi.c_format.simmediate = store_offset; + + *epc++ = mi.word; +} + +static inline void __build_store_zero_reg(void) +{ + union mips_instruction mi; + + if (cpu_has_64bits) + mi.i_format.opcode = sd_op; + else + mi.i_format.opcode = sw_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 0; /* $zero */ + mi.i_format.simmediate = store_offset; + + store_offset += (cpu_has_64bits ? 8 : 4); + + *epc++ = mi.word; +} + +static inline void __build_store_reg(int reg) +{ + union mips_instruction mi; + int reg_size; + +#ifdef CONFIG_MIPS32 + if (cpu_has_64bit_registers && reg == 0) { + mi.i_format.opcode = sd_op; + reg_size = 8; + } else { + mi.i_format.opcode = sw_op; + reg_size = 4; + } +#endif +#ifdef CONFIG_MIPS64 + mi.i_format.opcode = sd_op; + reg_size = 8; +#endif + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = reg; /* $zero */ + mi.i_format.simmediate = store_offset; + + store_offset += reg_size; + + *epc++ = mi.word; +} + +static inline void build_store_reg(int reg) +{ + if (cpu_has_prefetch) + if (reg) + build_dst_pref(pref_offset_copy); + else + build_dst_pref(pref_offset_clear); + else if (cpu_has_cache_cdex_p) + build_cdex(); + + __build_store_reg(reg); +} + +static inline void build_addiu_at_a0(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 1; /* $at */ + mi.i_format.simmediate = offset; + + *epc++ = mi.word; +} + +static inline void build_addiu_a1(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 5; /* $a1 */ + mi.i_format.rt = 5; /* $a1 */ + mi.i_format.simmediate = offset; + + load_offset -= offset; + + *epc++ = mi.word; +} + +static inline void build_addiu_a0(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.rs = 4; /* $a0 */ + mi.i_format.rt = 4; /* $a0 */ + mi.i_format.simmediate = offset; + + store_offset -= offset; + + *epc++ = mi.word; +} + +static inline void build_bne(unsigned int *dest) +{ + union mips_instruction mi; + + mi.i_format.opcode = bne_op; + mi.i_format.rs = 1; /* $at */ + mi.i_format.rt = 4; /* $a0 */ + mi.i_format.simmediate = dest - epc - 1; + + *epc++ = mi.word; +} + +static inline void build_nop(void) +{ + *epc++ = 0; +} + +static inline void build_jr_ra(void) +{ + union mips_instruction mi; + + mi.r_format.opcode = spec_op; + mi.r_format.rs = 31; + mi.r_format.rt = 0; + mi.r_format.rd = 0; + mi.r_format.re = 0; + mi.r_format.func = jr_op; + + *epc++ = mi.word; +} + +void __init build_clear_page(void) +{ + epc = (unsigned int *) &clear_page_array; + + if (cpu_has_prefetch) { + switch (current_cpu_data.cputype) { + case CPU_R10000: + case CPU_R12000: + pref_src_mode = Pref_LoadStreamed; + pref_dst_mode = Pref_StoreRetained; + break; + default: + pref_src_mode = Pref_LoadStreamed; + pref_dst_mode = Pref_PrepareForStore; + break; + } + } + + build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); + + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) { + *epc++ = 0x40026000; /* mfc0 $v0, $12 */ + *epc++ = 0x34410001; /* ori $at, v0, 0x1 */ + *epc++ = 0x38210001; /* xori $at, at, 0x1 */ + *epc++ = 0x40816000; /* mtc0 $at, $12 */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x3c01a000; /* lui $at, 0xa000 */ + *epc++ = 0x8c200000; /* lw $zero, ($at) */ + } + +dest = epc; + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + } + build_addiu_a0(2 * store_offset); + build_store_reg(0); + build_store_reg(0); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + build_store_reg(0); + } + build_store_reg(0); + build_bne(dest); + build_store_reg(0); + + if (cpu_has_prefetch && pref_offset_clear) { + build_addiu_at_a0(pref_offset_clear); + dest = epc; + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + build_addiu_a0(2 * store_offset); + __build_store_reg(0); + __build_store_reg(0); + __build_store_reg(0); + build_bne(dest); + __build_store_reg(0); + } + + build_jr_ra(); + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + *epc++ = 0x40826000; /* mtc0 $v0, $12 */ + else + build_nop(); + + flush_icache_range((unsigned long)&clear_page_array, + (unsigned long) epc); + + BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array)); +} + +void __init build_copy_page(void) +{ + epc = (unsigned int *) ©_page_array; + + build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); + + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) { + *epc++ = 0x40026000; /* mfc0 $v0, $12 */ + *epc++ = 0x34410001; /* ori $at, v0, 0x1 */ + *epc++ = 0x38210001; /* xori $at, at, 0x1 */ + *epc++ = 0x40816000; /* mtc0 $at, $12 */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x00000000; /* nop */ + *epc++ = 0x3c01a000; /* lui $at, 0xa000 */ + *epc++ = 0x8c200000; /* lw $zero, ($at) */ + } + +dest = epc; + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + build_store_reg(11); + if (has_scache && cpu_scache_line_size() == 128) { + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + build_store_reg(11); + } + build_addiu_a0(2 * store_offset); + build_addiu_a1(2 * load_offset); + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + if (has_scache && cpu_scache_line_size() == 128) { + build_store_reg(11); + build_load_reg( 8); + build_load_reg( 9); + build_load_reg(10); + build_load_reg(11); + build_store_reg( 8); + build_store_reg( 9); + build_store_reg(10); + } + build_bne(dest); + build_store_reg(11); + + if (cpu_has_prefetch && pref_offset_copy) { + build_addiu_at_a0(pref_offset_copy); + dest = epc; + __build_load_reg( 8); + __build_load_reg( 9); + __build_load_reg(10); + __build_load_reg(11); + __build_store_reg( 8); + __build_store_reg( 9); + __build_store_reg(10); + __build_store_reg(11); + build_addiu_a0(2 * store_offset); + build_addiu_a1(2 * load_offset); + __build_load_reg( 8); + __build_load_reg( 9); + __build_load_reg(10); + __build_load_reg(11); + __build_store_reg( 8); + __build_store_reg( 9); + __build_store_reg(10); + build_bne(dest); + __build_store_reg(11); + } + + build_jr_ra(); + if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + *epc++ = 0x40826000; /* mtc0 $v0, $12 */ + else + build_nop(); - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tmips4\n\t" - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tpref\t0,2*128(%1)\n\t" - "pref\t1,2*128(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tpop\n\t" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), - "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), "I" (PAGE_SIZE)); + BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array)); } diff -urN linux-2.4.24/arch/mips64/mm/pg-sb1.c linux-2.4.25/arch/mips64/mm/pg-sb1.c --- linux-2.4.24/arch/mips64/mm/pg-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/pg-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -2,6 +2,7 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 2000 SiByte, Inc. + * Copyright (C) 2002, 2003 Broadcom Corporation * * Written by Justin Carlson of SiByte, Inc. * and Kip Walker of Broadcom Corp. @@ -40,8 +41,11 @@ #define SB1_PREF_STORE_STREAMED_HINT "5" #endif -/* These are the functions hooked by the memory management function pointers */ -void sb1_clear_page(void *page) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void clear_page_cpu(void *page) +#else +void clear_page(void *page) +#endif { /* * JDCXXX - This should be bottlenecked by the write buffer, but these @@ -80,7 +84,11 @@ } -void sb1_copy_page(void *to, void *from) +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +static inline void copy_page_cpu(void *to, void *from) +#else +void copy_page(void *to, void *from) +#endif { /* * This should be optimized in assembly...can't use ld/sd, though, @@ -168,13 +176,13 @@ IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -void sb1_clear_page_dma(void *page) +void clear_page(void *page) { int cpu = smp_processor_id(); /* if the page is above Kseg0, use old way */ if (KSEGX(page) != K0BASE) - return sb1_clear_page(page); + return clear_page_cpu(page); page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); @@ -189,7 +197,7 @@ in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -void sb1_copy_page_dma(void *to, void *from) +void copy_page(void *to, void *from) { unsigned long from_phys = PHYSADDR(from); unsigned long to_phys = PHYSADDR(to); @@ -197,7 +205,7 @@ /* if either page is above Kseg0, use old way */ if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) - return sb1_copy_page(to, from); + return copy_page_cpu(to, from); page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); @@ -212,4 +220,4 @@ in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } -#endif +#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */ diff -urN linux-2.4.24/arch/mips64/mm/sc-rm7k.c linux-2.4.25/arch/mips64/mm/sc-rm7k.c --- linux-2.4.24/arch/mips64/mm/sc-rm7k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/sc-rm7k.c 2004-02-18 05:36:30.000000000 -0800 @@ -129,7 +129,7 @@ static void rm7k_sc_disable(void) { - set_c0_config(1<<3); /* CONF_SE */ + clear_c0_config(1<<3); /* CONF_SE */ } static inline int __init rm7k_sc_probe(void) @@ -140,11 +140,11 @@ if ((config >> 31) & 1) return 0; - printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + printk(KERN_INFO "Secondary cache size %ldK, linesize %ld bytes.\n", (scache_size >> 10), sc_lsize); - if ((config >> 3) & 1) - return; + if ((config >> 3) & 1) /* CONF_SE */ + return 1; printk(KERN_INFO "Enabling secondary cache..."); func(); diff -urN linux-2.4.24/arch/mips64/mm/tlb-andes.c linux-2.4.25/arch/mips64/mm/tlb-andes.c --- linux-2.4.24/arch/mips64/mm/tlb-andes.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/tlb-andes.c 2004-02-18 05:36:30.000000000 -0800 @@ -192,7 +192,7 @@ * - The entire mm handling assumes the c0_pagemask register to * be set for 4kb pages. */ - write_c0_pagemask(PM_4K); + write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); write_c0_framemask(0); diff -urN linux-2.4.24/arch/mips64/mm/tlb-r4k.c linux-2.4.25/arch/mips64/mm/tlb-r4k.c --- linux-2.4.24/arch/mips64/mm/tlb-r4k.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/tlb-r4k.c 2004-02-18 05:36:30.000000000 -0800 @@ -173,6 +173,36 @@ } /* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} + +/* * Updates the TLB with the new pte(s). */ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) @@ -305,31 +335,29 @@ static void __init probe_tlb(unsigned long config) { - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - current_cpu_data.tlbsize = 48; - } else { - unsigned long config1; + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config1; - config1 = read_c0_config1(); - if (!((config >> 7) & 3)) - panic("No MMU present"); - else - current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; - } + /* + * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register + * is not supported, we assume R4k style. Cpu probing already figured + * out the number of tlb entries. + */ + if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) + return; + + config1 = read_c0_config1(); + if (!((config1 >> 7) & 3)) + panic("No MMU present"); - printk("Number of TLB entries %d.\n", current_cpu_data.tlbsize); + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } void __init r4k_tlb_init(void) { unsigned long config = read_c0_config(); - probe_tlb(config); - write_c0_pagemask(PM_4K); + write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); diff -urN linux-2.4.24/arch/mips64/mm/tlb-sb1.c linux-2.4.25/arch/mips64/mm/tlb-sb1.c --- linux-2.4.24/arch/mips64/mm/tlb-sb1.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/tlb-sb1.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,7 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,12 +18,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include #include extern void except_vec1_sb1(void); +#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1))) + /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) { @@ -33,8 +36,7 @@ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - "#.set mips64 \n" - ".set mips4 \n" + ".set mips64 \n" ".set noat \n" " tlbr \n" " dmfc0 $1, $10 \n" @@ -48,13 +50,11 @@ " sll %5, $1, 0 \n" " mfc0 %6, $5 \n" ".set pop \n" - : "=r" (entryhihi), - "=r" (entryhilo), - "=r" (entrylo0hi), - "=r" (entrylo0lo), - "=r" (entrylo1hi), - "=r" (entrylo1lo), - "=r" (pagemask)); + : "=r" (entryhihi), "=r" (entryhilo), + "=r" (entrylo0hi), "=r" (entrylo0lo), + "=r" (entrylo1hi), "=r" (entrylo1lo), + "=r" (pagemask)); + printk("%08X%08X %08X%08X %08X%08X %08X", entryhihi, entryhilo, entrylo0hi, entrylo0lo, @@ -98,10 +98,13 @@ old_ctx = read_c0_entryhi() & ASID_MASK; write_c0_entrylo0(0); write_c0_entrylo1(0); - for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { - write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + + entry = read_c0_wired(); + while (entry < current_cpu_data.tlbsize) { + write_c0_entryhi(UNIQUE_ENTRYHI(entry)); write_c0_index(entry); tlb_write_indexed(); + entry++; } write_c0_entryhi(old_ctx); local_irq_restore(flags); @@ -113,7 +116,7 @@ * Use increments of the maximum page size (16MB), and check for duplicate * entries before doing a given write. Then, when we're safe from collisions * with the firmware, go back and give all the entries invalid addresses with - * the normal flush routine. + * the normal flush routine. Wired entries will be killed as well! */ void sb1_sanitize_tlb(void) { @@ -151,14 +154,14 @@ int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= (current_cpu_data.tlbsize/2)) { + if (size <= (current_cpu_data.tlbsize/2)) { int oldpid = read_c0_entryhi() & ASID_MASK; int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); end &= (PAGE_MASK << 1); - while(start < end) { + while (start < end) { int idx; write_c0_entryhi(start | newpid); @@ -167,8 +170,8 @@ idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); - write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); - if(idx < 0) + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); + if (idx < 0) continue; tlb_write_indexed(); } @@ -196,10 +199,10 @@ idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); - if(idx < 0) + if (idx < 0) goto finish; /* Make sure all entries differ. */ - write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); tlb_write_indexed(); finish: write_c0_entryhi(oldpid); @@ -207,6 +210,33 @@ local_irq_restore(flags); } +/* + * Remove one kernel space TLB entry. This entry is assumed to be marked + * global so we don't do the ASID thing. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + + local_irq_save(flags); + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(UNIQUE_ENTRYHI(idx)); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + tlb_write_indexed(); + } + + write_c0_entryhi(oldpid); + local_irq_restore(flags); +} /* All entries common to a mm share an asid. To effectively flush these entries, we just bump the asid. */ @@ -254,6 +284,34 @@ local_irq_restore(flags); } +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + tlb_write_indexed(); + + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); + + local_flush_tlb_all(); + local_irq_restore(flags); +} + /* * This is called from loadmmu.c. We have to set up all the * memory management function pointers, as well as initialize @@ -261,7 +319,8 @@ */ void sb1_tlb_init(void) { - write_c0_pagemask(PM_4K); + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); /* * We don't know what state the firmware left the TLB's in, so this is diff -urN linux-2.4.24/arch/mips64/mm/tlbex-r4k.S linux-2.4.25/arch/mips64/mm/tlbex-r4k.S --- linux-2.4.24/arch/mips64/mm/tlbex-r4k.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/mips64/mm/tlbex-r4k.S 2004-02-18 05:36:30.000000000 -0800 @@ -10,13 +10,20 @@ #include #include #include + #include +#include #include #include #include #include #include +#define PGD_INDX_MASK ((_PTRS_PER_PGD - 1) << _PGD_T_LOG2) +#define PMD_INDX_MASK ((_PTRS_PER_PMD - 1) << _PMD_T_LOG2) +#define PTE_INDX_MASK ((_PTRS_PER_PTE - 1) << _PTE_T_LOG2) +#define PTEP_INDX_MASK ((_PTRS_PER_PTE >> 1 - 1) << (_PTE_T_LOG2 + 1)) + .data .comm pgd_current, NR_CPUS * 8, 8 @@ -35,17 +42,17 @@ #endif bltz \tmp, \kaddr ld \ptr, (\ptr) - dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((PTRS_PER_PGD - 1)<<3) + dsrl \tmp, PGDIR_SHIFT - 3 # get pgd offset in bytes + andi \tmp, PGD_INDX_MASK daddu \ptr, \tmp # add in pgd offset dmfc0 \tmp, CP0_BADVADDR ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((PTRS_PER_PMD - 1)<<3) + dsrl \tmp, PMD_SHIFT - 3 # get pmd offset in bytes + andi \tmp, PMD_INDX_MASK daddu \ptr, \tmp # add in pmd offset dmfc0 \tmp, CP0_XCONTEXT ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset + andi \tmp, PTEP_INDX_MASK # get pte offset daddu \ptr, \tmp .endm @@ -65,7 +72,7 @@ */ dsubu \tmp, \tmp, \ptr dla \ptr, kptbl - dsrl \tmp, (PAGE_SHIFT+1) # get vpn2 + dsrl \tmp, _PAGE_SHIFT + 1 # get vpn2 dsll \tmp, 4 # byte offset of pte daddu \ptr, \ptr, \tmp @@ -123,7 +130,7 @@ dmfc0 k0, CP0_BADVADDR dmfc0 k1, CP0_ENTRYHI xor k0, k1 - dsrl k0, k0, PAGE_SHIFT+1 + dsrl k0, k0, _PAGE_SHIFT + 1 bnez k0, 1f #endif .set noat @@ -144,9 +151,11 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard b 1f tlbwr 1: nop + rm9000_tlb_hazard eret 9: # handle the vmalloc range @@ -154,9 +163,11 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard b 1f tlbwr 1: nop + rm9000_tlb_hazard eret END(handle_vec1_r4k) @@ -184,8 +195,10 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard nop tlbwr + rm9000_tlb_hazard eret 9: # handle the vmalloc range @@ -193,8 +206,10 @@ ld k0, 0(k1) # get even pte ld k1, 8(k1) # get odd pte PTE_RELOAD k0 k1 + rm9000_tlb_hazard nop tlbwr + rm9000_tlb_hazard eret END(handle_vec1_r10k) diff -urN linux-2.4.24/arch/parisc/config.in linux-2.4.25/arch/parisc/config.in --- linux-2.4.24/arch/parisc/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/parisc/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -116,7 +116,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/parisc/defconfig linux-2.4.25/arch/parisc/defconfig --- linux-2.4.24/arch/parisc/defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/parisc/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -245,7 +245,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/8260_io/fcc_enet.c linux-2.4.25/arch/ppc/8260_io/fcc_enet.c --- linux-2.4.24/arch/ppc/8260_io/fcc_enet.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/8260_io/fcc_enet.c 2004-02-18 05:36:30.000000000 -0800 @@ -1327,6 +1327,12 @@ */ eap = (unsigned char *)&(ep->fen_paddrh); for (i=5; i>=0; i--) { + +/* + * The EP8260 only uses FCC3, so we can safely give it the real + * MAC address. + */ +#ifndef CONFIG_RPX6 if (i == 3) { dev->dev_addr[i] = bd->bi_enetaddr[i]; dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum)); @@ -1335,6 +1341,9 @@ else { *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; } +#else + *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; +#endif } ep->fen_taddrh = 0; diff -urN linux-2.4.24/arch/ppc/8xx_io/Config.in linux-2.4.25/arch/ppc/8xx_io/Config.in --- linux-2.4.24/arch/ppc/8xx_io/Config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/8xx_io/Config.in 2004-02-18 05:36:30.000000000 -0800 @@ -27,8 +27,8 @@ if [ "$CONFIG_SCC3_ENET" != "y" ]; then bool 'Use SMC1 for UART' CONFIG_8xx_SMC1 fi -bool 'Use SMC2 for UART' CONFIG_SMC2_UART -if [ "$CONFIG_SMC2_UART" = "y" ]; then +bool 'Use SMC2 for UART' CONFIG_8xx_SMC2 +if [ "$CONFIG_8xx_SMC2" = "y" ]; then bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2 bool 'Use SMC2 for Console' CONFIG_CONS_SMC2 fi diff -urN linux-2.4.24/arch/ppc/boot/Makefile linux-2.4.25/arch/ppc/boot/Makefile --- linux-2.4.24/arch/ppc/boot/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -33,6 +33,7 @@ tools-$(CONFIG_4xx) := mktree tools-$(CONFIG_LOPEC) := mkbugboot mkprep tools-$(CONFIG_PPLUS) := mkbugboot mkprep +tools-$(CONFIG_PRPMC750) := mkbugboot mkprep tools-$(CONFIG_SPRUCE) := mktree # These are dirs we don't want to go into on BOOT_TARGETS. We have them for @@ -42,6 +43,9 @@ # These are the subdirs we want to use BOOTDIRS = $(filter-out $(NONBOOT), $(subdir-y)) +makeof1275: + $(MAKE) -C of1275 + # This will make the tools we need. We do it like this to ensure that we use # HOSTCC. -- Tom maketools: @@ -50,7 +54,7 @@ # The targets all boards support for boot images. BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd -$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz maketools +$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz makeof1275 maketools ifneq ($(BOOTDIRS),) for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done endif diff -urN linux-2.4.24/arch/ppc/boot/chrp/Makefile linux-2.4.25/arch/ppc/boot/chrp/Makefile --- linux-2.4.24/arch/ppc/boot/chrp/Makefile 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/chrp/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -12,7 +12,7 @@ OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \ ../common/ofcommon.o -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a ADDNOTE = ../utils/addnote PIGGYBACK = ../utils/piggyback @@ -50,13 +50,13 @@ --set-section-flags=.sysmap=contents,alloc,load,readonly,data endif -zImage: $(OBJS) $(LIBS) $(ADDNOTE) +zImage: $(OBJS) $(LIBS) $(ADDNOTE) ../ld.script $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk cp ../images/$@.chrp ../images/$@.chrp-rs6k $(ADDNOTE) ../images/$@.chrp-rs6k -zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz +zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz ../ld.script $(OBJCOPY) image.o image.o \ --add-section=.ramdisk=../images/ramdisk.image.gz \ --set-section-flags=.ramdisk=contents,alloc,load,readonly,data diff -urN linux-2.4.24/arch/ppc/boot/chrp/main.c linux-2.4.25/arch/ppc/boot/chrp/main.c --- linux-2.4.24/arch/ppc/boot/chrp/main.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/chrp/main.c 2004-02-18 05:36:30.000000000 -0800 @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include #include @@ -15,15 +16,11 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *, unsigned long); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); char *avail_ram; char *begin_avail, *end_avail; diff -urN linux-2.4.24/arch/ppc/boot/chrp/start.c linux-2.4.25/arch/ppc/boot/chrp/start.c --- linux-2.4.24/arch/ppc/boot/chrp/start.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/chrp/start.c 2004-02-18 05:36:30.000000000 -0800 @@ -7,17 +7,13 @@ * 2 of the License, or (at your option) any later version. */ #include +#include "of1275.h" int (*prom)(void *args); -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); +phandle stdin; +phandle stdout; +phandle stderr; void printk(char *fmt, ...); @@ -27,163 +23,15 @@ void start(int a1, int a2, void *promptr) { - prom = promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - chrpboot(a1, a2, promptr); for (;;) exit(); } int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - prom(&args); - return args.actual; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int putc(int c, void *f) { char ch = c; diff -urN linux-2.4.24/arch/ppc/boot/common/misc-simple.c linux-2.4.25/arch/ppc/boot/common/misc-simple.c --- linux-2.4.24/arch/ppc/boot/common/misc-simple.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/common/misc-simple.c 2004-02-18 05:36:30.000000000 -0800 @@ -75,16 +75,9 @@ extern void gunzip(void *, int, unsigned char *, int *); extern void serial_fixups(void); -/* Allow decompress_kernel to be hooked into. This is the default. */ -void * __attribute__ ((weak)) -load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, - void *bp) -{ - return decompress_kernel(load_addr, num_words, cksum, bp); -} - -struct bi_record * -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +static struct bi_record * +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + void *ignored) { #ifdef INTERACTIVE_CONSOLE int timer = 0; @@ -271,3 +264,11 @@ return (struct bi_record *)rec_loc; } + +/* Allow decompress_kernel to be hooked into. This is the default. */ +void * __attribute__ ((weak)) +load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + void *bp) +{ + return decompress_kernel(load_addr, num_words, cksum, bp); +} diff -urN linux-2.4.24/arch/ppc/boot/common/ofcommon.c linux-2.4.25/arch/ppc/boot/common/ofcommon.c --- linux-2.4.24/arch/ppc/boot/common/ofcommon.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/common/ofcommon.c 2004-02-18 05:36:30.000000000 -0800 @@ -8,6 +8,7 @@ */ #include "zlib.h" +#include "of1275.h" #include "nonstdio.h" #include #include @@ -18,8 +19,6 @@ extern int strcmp(const char *s1, const char *s2); extern char *avail_ram, *avail_high; extern char *end_avail; -extern void claim(unsigned int virt, unsigned int size, unsigned int align); -extern void pause(void); unsigned int heap_use, heap_max; diff -urN linux-2.4.24/arch/ppc/boot/common/util.S linux-2.4.25/arch/ppc/boot/common/util.S --- linux-2.4.24/arch/ppc/boot/common/util.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/common/util.S 2004-02-18 05:36:30.000000000 -0800 @@ -217,11 +217,6 @@ blt 2b 3: blr -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - .section ".relocate_code","xa" /* * Flush and enable instruction cache diff -urN linux-2.4.24/arch/ppc/boot/include/mpc10x.h linux-2.4.25/arch/ppc/boot/include/mpc10x.h --- linux-2.4.24/arch/ppc/boot/include/mpc10x.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/include/mpc10x.h 2004-02-18 05:36:30.000000000 -0800 @@ -58,7 +58,7 @@ #define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ #define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ -#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */ +#define MPC10X_MCTLR_MEM_END_2 0x94 /* Banks 4-7 */ #define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ #define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ diff -urN linux-2.4.24/arch/ppc/boot/include/of1275.h linux-2.4.25/arch/ppc/boot/include/of1275.h --- linux-2.4.24/arch/ppc/boot/include/of1275.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/include/of1275.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +typedef void *prom_handle; +typedef void *ihandle; +typedef void *phandle; +typedef int (*prom_entry)(void *); + +#define OF_INVALID_HANDLE ((prom_handle)-1UL) + +extern prom_entry of_prom_entry; + +/* function declarations */ + +void * claim(unsigned int virt, unsigned int size, unsigned int align); +void enter(void); +void exit(void); +phandle finddevice(const char *name); +int getprop(phandle node, const char *name, void *buf, int buflen); +void ofinit(prom_entry entry); +int ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr); +int read(ihandle instance, void *buf, int buflen); +void release(void *virt, unsigned int size); +int write(ihandle instance, void *buf, int buflen); +ihandle open(const char *name); +void close(ihandle instance); +int setcolor(ihandle instance, int color, int red, int green, int blue); +phandle instancetopackage(const ihandle instance); + +/* inlines */ + +extern inline void pause(void) +{ + enter(); +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/Makefile linux-2.4.25/arch/ppc/boot/of1275/Makefile --- linux-2.4.24/arch/ppc/boot/of1275/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,11 @@ +# +# Makefile of1275 stuff +# + +L_TARGET := of1275.a + +obj-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ + ofstdio.o read.o release.o write.o open.o close.o setcolor.o \ + instancetopackage.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/arch/ppc/boot/of1275/claim.c linux-2.4.25/arch/ppc/boot/of1275/claim.c --- linux-2.4.24/arch/ppc/boot/of1275/claim.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/claim.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +void * +claim(unsigned int virt, unsigned int size, unsigned int align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*of_prom_entry)(&args); + return args.ret; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/close.c linux-2.4.25/arch/ppc/boot/of1275/close.c --- linux-2.4.24/arch/ppc/boot/of1275/close.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/close.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +void +close(ihandle instance) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + } args; + + args.service = "close"; + args.nargs = 1; + args.nret = 0; + args.instance = instance; + (*of_prom_entry)(&args); +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/enter.c linux-2.4.25/arch/ppc/boot/of1275/enter.c --- linux-2.4.24/arch/ppc/boot/of1275/enter.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/enter.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,22 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +void +enter(void) +{ + struct prom_args { + char *service; + } args; + + args.service = "enter"; + (*of_prom_entry)(&args); +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/exit.c linux-2.4.25/arch/ppc/boot/of1275/exit.c --- linux-2.4.24/arch/ppc/boot/of1275/exit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/exit.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,24 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +void +exit(void) +{ + struct prom_args { + char *service; + } args; + + for (;;) { + args.service = "exit"; + (*of_prom_entry)(&args); + } +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/finddevice.c linux-2.4.25/arch/ppc/boot/of1275/finddevice.c --- linux-2.4.24/arch/ppc/boot/of1275/finddevice.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/finddevice.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +phandle +finddevice(const char *name) +{ + struct prom_args { + char *service; + int nargs; + int nret; + const char *devspec; + phandle device; + } args; + + args.service = "finddevice"; + args.nargs = 1; + args.nret = 1; + args.devspec = name; + args.device = OF_INVALID_HANDLE; + (*of_prom_entry)(&args); + return args.device; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/getprop.c linux-2.4.25/arch/ppc/boot/of1275/getprop.c --- linux-2.4.24/arch/ppc/boot/of1275/getprop.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/getprop.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +int +getprop(phandle node, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + phandle node; + const char *name; + void *buf; + int buflen; + int size; + } args; + + args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.node = node; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*of_prom_entry)(&args); + return args.size; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/instancetopackage.c linux-2.4.25/arch/ppc/boot/of1275/instancetopackage.c --- linux-2.4.24/arch/ppc/boot/of1275/instancetopackage.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/instancetopackage.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,29 @@ +/* + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +phandle +instancetopackage(const ihandle instance) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + phandle package; + } args; + + args.service = "instance-to-package"; + args.nargs = 1; + args.nret = 1; + args.instance = instance; + (*of_prom_entry)(&args); + return args.package; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/ofinit.c linux-2.4.25/arch/ppc/boot/of1275/ofinit.c --- linux-2.4.24/arch/ppc/boot/of1275/ofinit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/ofinit.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +prom_entry of_prom_entry; +ihandle of_prom_mmu; + +void +ofinit(prom_entry prom_ptr) +{ + phandle chosen; + + of_prom_entry = prom_ptr; + + if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) + return; + if (getprop(chosen, "mmu", &of_prom_mmu, sizeof(ihandle)) != 4) + return; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/ofstdio.c linux-2.4.25/arch/ppc/boot/of1275/ofstdio.c --- linux-2.4.24/arch/ppc/boot/of1275/ofstdio.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/ofstdio.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +int +ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr) +{ + ihandle in, out; + phandle chosen; + + if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) + goto err; + if (getprop(chosen, "stdout", &out, sizeof(out)) != 4) + goto err; + if (getprop(chosen, "stdin", &in, sizeof(in)) != 4) + goto err; + + *stdin = in; + *stdout = out; + *stderr = out; + return 0; +err: + return -1; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/open.c linux-2.4.25/arch/ppc/boot/of1275/open.c --- linux-2.4.24/arch/ppc/boot/of1275/open.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/open.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +ihandle +open(const char *name) +{ + struct prom_args { + char *service; + int nargs; + int nret; + const char *name; + ihandle instance; + } args; + + args.service = "open"; + args.nargs = 1; + args.nret = 1; + args.name = name; + args.instance = OF_INVALID_HANDLE; + (*of_prom_entry)(&args); + return args.instance; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/read.c linux-2.4.25/arch/ppc/boot/of1275/read.c --- linux-2.4.24/arch/ppc/boot/of1275/read.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/read.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +int +read(ihandle instance, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + void *buf; + int buflen; + int actual; + } args; + + args.service = "read"; + args.nargs = 3; + args.nret = 1; + args.instance = instance; + args.buf = buf; + args.buflen = buflen; + args.actual = -1; + (*of_prom_entry)(&args); + return args.actual; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/release.c linux-2.4.25/arch/ppc/boot/of1275/release.c --- linux-2.4.24/arch/ppc/boot/of1275/release.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/release.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +void +release(void *virt, unsigned int size) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *virt; + unsigned int size; + } args; + + args.service = "release"; + args.nargs = 2; + args.nret = 0; + args.virt = virt; + args.size = size; + (*of_prom_entry)(&args); +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/setcolor.c linux-2.4.25/arch/ppc/boot/of1275/setcolor.c --- linux-2.4.24/arch/ppc/boot/of1275/setcolor.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/setcolor.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,42 @@ +/* + * arch/ppc/boot/of1275/setcolor.c + * + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +int +setcolor(ihandle instance, int color, int red, int green, int blue) +{ + struct prom_args { + char *service; + int nargs; + int nret; + char *method; + ihandle instance; + int color; + int blue; + int green; + int red; + int result; + } args; + + args.service = "call-method"; + args.nargs = 6; + args.nret = 1; + args.method = "color!"; + args.instance = instance; + args.color = color; + args.blue = blue; + args.green = green; + args.red = red; + args.result = 0; + (*of_prom_entry)(&args); + return args.result; +} diff -urN linux-2.4.24/arch/ppc/boot/of1275/write.c linux-2.4.25/arch/ppc/boot/of1275/write.c --- linux-2.4.24/arch/ppc/boot/of1275/write.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/of1275/write.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "of1275.h" + +int +write(ihandle instance, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + void *buf; + int buflen; + int actual; + } args; + + args.service = "write"; + args.nargs = 3; + args.nret = 1; + args.instance = instance; + args.buf = buf; + args.buflen = buflen; + args.actual = -1; + (*of_prom_entry)(&args); + return args.actual; +} diff -urN linux-2.4.24/arch/ppc/boot/pmac/Makefile linux-2.4.25/arch/ppc/boot/pmac/Makefile --- linux-2.4.24/arch/ppc/boot/pmac/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/pmac/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -14,7 +14,7 @@ COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a MKNOTE := ../utils/mknote SIZE := ../utils/size @@ -84,7 +84,7 @@ rm -f coffboot.initrd ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac -vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o +vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o ../ld.script $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o $(MKNOTE) > note $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ @@ -92,7 +92,7 @@ rm -f note vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \ - ../images/ramdisk.image.gz + ../images/ramdisk.image.gz ../ld.script $(OBJCOPY) image.o image-elf.o \ --add-section=.ramdisk=../images/ramdisk.image.gz \ --set-section-flags=.ramdisk=contents,alloc,load,readonly,data diff -urN linux-2.4.24/arch/ppc/boot/pmac/chrpmain.c linux-2.4.25/arch/ppc/boot/pmac/chrpmain.c --- linux-2.4.24/arch/ppc/boot/pmac/chrpmain.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/pmac/chrpmain.c 2004-02-18 05:36:30.000000000 -0800 @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include #include @@ -15,16 +16,11 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); -extern void release(void *ptr, unsigned int len); char *avail_ram; char *begin_avail, *end_avail; diff -urN linux-2.4.24/arch/ppc/boot/pmac/coffmain.c linux-2.4.25/arch/ppc/boot/pmac/coffmain.c --- linux-2.4.24/arch/ppc/boot/pmac/coffmain.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/pmac/coffmain.c 2004-02-18 05:36:30.000000000 -0800 @@ -10,6 +10,7 @@ #include #include "nonstdio.h" +#include "of1275.h" #include "zlib.h" /* Passed from the linker */ @@ -17,17 +18,13 @@ extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern char *claim(unsigned, unsigned, unsigned); extern char image_data[], initrd_data[]; extern int initrd_len, image_len; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); extern void setup_bats(unsigned long start); char *avail_ram; diff -urN linux-2.4.24/arch/ppc/boot/pmac/start.c linux-2.4.25/arch/ppc/boot/pmac/start.c --- linux-2.4.24/arch/ppc/boot/pmac/start.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/pmac/start.c 2004-02-18 05:36:30.000000000 -0800 @@ -7,33 +7,22 @@ * 2 of the License, or (at your option) any later version. */ #include +#include "of1275.h" extern int strlen(const char *s); extern void boot(int a1, int a2, void *prom); -int (*prom)(void *args); +phandle stdin; +phandle stdout; +phandle stderr; -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); void printk(char *fmt, ...); void start(int a1, int a2, void *promptr) { - prom = (int (*)(void *)) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) exit(); boot(a1, a2, promptr); @@ -41,30 +30,6 @@ exit(); } -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - int writestring(void *f, char *ptr, int nb) { int w = 0, i; @@ -85,142 +50,6 @@ } int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -void -release(void *virt, unsigned int size) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *virt; - unsigned int size; - } args; - - args.service = "release"; - args.nargs = 2; - args.nret = 0; - args.virt = virt; - args.size = size; - (*prom)(&args); -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int putc(int c, void *f) { char ch = c; diff -urN linux-2.4.24/arch/ppc/boot/prep/Makefile linux-2.4.25/arch/ppc/boot/prep/Makefile --- linux-2.4.24/arch/ppc/boot/prep/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -22,12 +22,12 @@ endif LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic -obj-y := head.o ../simple/legacy.o misc.o of1275.o \ +obj-y := head.o ../simple/legacy.o misc.o \ ../common/util.o ../common/string.o \ ../common/misc-common.o \ ../common/serial_stub.o OBJCOPY_ARGS = -O elf32-powerpc -LIBS = ../lib/zlib.a +LIBS = ../lib/zlib.a ../of1275/of1275.a obj-$(CONFIG_SERIAL_CONSOLE) += ../common/ns16550.o obj-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o diff -urN linux-2.4.24/arch/ppc/boot/prep/head.S linux-2.4.25/arch/ppc/boot/prep/head.S --- linux-2.4.24/arch/ppc/boot/prep/head.S 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/head.S 2004-02-18 05:36:30.000000000 -0800 @@ -34,14 +34,29 @@ isync mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - /* Save the original MSR value */ - mfmsr r26 +/* + * Save the OF pointer to r25, but only if the entry point is in a sane + * location; if not we store 0. If there is no entry point, or it is + * invalid, we establish the default MSR value immediately. Otherwise, + * we defer doing that, to allow OF functions to be called, until we + * begin uncompressing the kernel. + */ + lis r3,0x0fff /* r3 = 0x0fffffff */ + ori r3,r3,0xffff - /* Establish default MSR value */ - li r3,MSR_IP|MSR_FP - mtmsr r3 + subc r3,r3,r5 /* r3 = (r5 <= r3) ? ~0 : 0 */ + subfe r3,r3,r3 + nand r3,r3,r3 + + and. r5,r5,r3 /* r5 will be cleared if (r5 > r3) */ + bne+ haveOF + + li r3,MSR_IP|MSR_FP /* Not OF: set MSR immediately */ + mtmsr r3 + isync +haveOF: + mr r25,r5 /* compute the size of the whole image in words. */ lis r4,start@h @@ -110,17 +125,12 @@ li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 - /* Store the original MSR into 'orig_MSR' */ - lis r3,orig_MSR@h - ori r3,r3,orig_MSR@l - stw r26,0(r3) - /* Run loader */ mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ mr r5,r6 /* Checksum */ mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ + mr r7,r25 /* Validated OFW interface */ bl decompress_kernel /* diff -urN linux-2.4.24/arch/ppc/boot/prep/misc.c linux-2.4.25/arch/ppc/boot/prep/misc.c --- linux-2.4.24/arch/ppc/boot/prep/misc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/misc.c 2004-02-18 05:36:30.000000000 -0800 @@ -18,6 +18,7 @@ #include #include #include +#include "of1275.h" #include "nonstdio.h" #include "zlib.h" @@ -54,7 +55,6 @@ RESIDUAL hold_resid_buf; RESIDUAL *hold_residual = &hold_resid_buf; unsigned long initrd_size = 0; -unsigned long orig_MSR; char *zimage_start; int zimage_size; @@ -67,14 +67,9 @@ #endif /* CONFIG_VGA_CONSOLE */ extern int CRT_tstc(void); -extern void of_init(void *handler); -extern int of_finddevice(const char *device_specifier, int *phandle); -extern int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); extern int vga_init(unsigned char *ISA_mem); extern void gunzip(void *, int, unsigned char *, int *); -extern void _put_MSR(unsigned int val); extern unsigned long serial_init(int chan, void *ignored); extern void serial_fixups(void); @@ -119,6 +114,27 @@ } #endif /* CONFIG_VGA_CONSOLE */ +static void +get_of_args(void) +{ + int size; + phandle chosen; + char buf[256]; + + /* Get bootargs property of /chosen node */ + if (!(chosen = finddevice("/chosen"))) + return; + + if (getprop(chosen, "bootargs", buf, sizeof(buf)) != 4) + return; + + if (size > sizeof(cmd_buf)) + size = sizeof(cmd_buf); + + if (size > 1) /* includes null-terminator */ + memcpy(cmd_buf, buf, size); +} + unsigned long decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual, void *OFW_interface) @@ -131,14 +147,13 @@ char *cp; /* Default to 32MiB memory. */ unsigned long TotalMemory = 0x02000000; - int dev_handle; - int mem_info[2]; - int res, size; - unsigned char board_type; - unsigned char base_mod; int start_multi = 0; unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; + /* If we have Open Firmware, initialise it immediately */ + if (OFW_interface) + ofinit(OFW_interface); + serial_fixups(); com_port = serial_init(0, NULL); #if defined(CONFIG_VGA_CONSOLE) @@ -175,7 +190,8 @@ /* Is this Motorola PPCBug? */ if ((1 & residual->VitalProductData.FirmwareSupports) && (1 == residual->VitalProductData.FirmwareSupplier)) { - board_type = inb(0x800) & 0xF0; + unsigned char base_mod; + unsigned char board_type = inb(0x800) & 0xF0; /* * Reset the onboard 21x4x Ethernet @@ -231,35 +247,23 @@ * we don't try this on a PReP box without OF * -- Cort */ - while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) + while (OFW_interface) { - /* We need to restore the slightly inaccurate - * MSR so that OpenFirmware will behave. -- Tom - */ - _put_MSR(orig_MSR); - of_init(OFW_interface); + phandle dev_handle; + int mem_info[2]; /* get handle to memory description */ - res = of_finddevice("/memory@0", - &dev_handle); - if (res) + if (!(dev_handle = finddevice("/memory@0"))) break; /* get the info */ - res = of_getprop(dev_handle, - "reg", - mem_info, - sizeof(mem_info), - &size); - if (res) + if (getprop(dev_handle, "reg", mem_info, + sizeof(mem_info)) !=8) break; TotalMemory = mem_info[1]; break; } - - /* Enforce a sane MSR for booting. */ - _put_MSR(MSR_IP); } /* assume the chunk below 8M is free */ @@ -300,6 +304,10 @@ if (keyb_present) CRT_tstc(); /* Forces keyboard to be initialized */ + /* If we have OF then try to get args from there */ + if (OFW_interface) + get_of_args(); + puts("\nLinux/PPC load: "); cp = cmd_line; memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); @@ -338,6 +346,18 @@ *cp = 0; puts("\nUncompressing Linux..."); + /* + * If we have OF, then we have deferred setting the MSR. + * We must set it now because we are about to overwrite + * the exception table. The new MSR value will disable + * machine check exceptions and point the exception table + * to the ROM. + */ + if (OFW_interface) { + mtmsr(MSR_IP | MSR_FP); + asm volatile("isync"); + } + gunzip(0, 0x400000, zimage_start, &zimage_size); puts("done.\n"); diff -urN linux-2.4.24/arch/ppc/boot/prep/of1275.c linux-2.4.25/arch/ppc/boot/prep/of1275.c --- linux-2.4.24/arch/ppc/boot/prep/of1275.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/of1275.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,427 +0,0 @@ -/* Open Firmware Client Interface */ - - -#include "of1275.h" - - -static int (*of_server)(void *) = (int(*)(void*))-1; - -void -of_init(void *handler) -{ - of_server = (int(*)(void*))handler; -} - - -/* 6.3.2.1 Client interface */ - - -int -of_test(const char *name, int *missing) -{ - int result; - static of_test_service s; - s.service = "test"; - s.n_args = 1; - s.n_returns = 1; - s.name = name; - result = of_server(&s); - *missing = s.missing; - return result; -} - - -/* 6.3.2.2 Device tree */ - - -int -of_peer(int phandle, int *sibling_phandle) -{ - int result; - static of_peer_service s; - s.service = "peer"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *sibling_phandle = s.sibling_phandle; - return result; -} - -int -of_child(int phandle, int *child_phandle) -{ - int result; - static of_child_service s; - s.service = "child"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *child_phandle = s.child_phandle; - return result; -} - -int -of_parent(int phandle, int *parent_phandle) -{ - int result; - static of_parent_service s; - s.service = "parent"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *parent_phandle = s.parent_phandle; - return result; -} - -int -of_instance_to_package(int ihandle, int *phandle) -{ - int result; - static of_instance_to_package_service s; - s.service = "instance-to-package"; - s.n_args = 1; - s.n_returns = 1; - s.ihandle = ihandle; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_getproplen(int phandle, const char *name, int *proplen) -{ - int result; - static of_getproplen_service s; - s.service = "getproplen"; - s.n_args = 2; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - result = of_server(&s); - *proplen = s.proplen; - return result; -} - -int -of_getprop(int phandle, const char *name, void *buf, int buflen, int *size) -{ - int result; - static of_getprop_service s; - s.service = "getprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_nextprop(int phandle, const char *previous, void *buf, int *flag) -{ - int result; - static of_nextprop_service s; - s.service = "nextprop"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.previous = previous; - s.buf = buf; - result = of_server(&s); - *flag = s.flag; - return result; -} - -int -of_setprop(int phandle, const char *name, void *buf, int len, int *size) -{ - int result; - static of_setprop_service s; - s.service = "setprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.len = len; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_canon(const char *device_specifier, void *buf, int buflen, int *length) -{ - int result; - static of_canon_service s; - s.service = "canon"; - s.n_args = 3; - s.n_returns = 1; - s.device_specifier = device_specifier; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_finddevice(const char *device_specifier, int *phandle) -{ - int result; - static of_finddevice_service s; - s.service = "finddevice"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_instance_to_path(int ihandle, void *buf, int buflen, int *length) -{ - int result; - static of_instance_to_path_service s; - s.service = "instance-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_package_to_path(int phandle, void *buf, int buflen, int *length) -{ - int result; - static of_package_to_path_service s; - s.service = "package-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -/* int of_call_method(const char *method, int ihandle, ...); */ - - -/* 6.3.2.3 Device I/O */ - - -int -of_open(const char *device_specifier, int *ihandle) -{ - int result; - static of_open_service s; - s.service = "open"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *ihandle = s.ihandle; - return result; -} - -int -of_close(int ihandle) -{ - int result; - static of_close_service s; - s.service = "close"; - s.n_args = 1; - s.n_returns = 0; - s.ihandle = ihandle; - result = of_server(&s); - return result; -} - -int -of_read(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_read_service s; - s.service = "read"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_write(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_write_service s; - s.service = "write"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_seek(int ihandle, int pos_hi, int pos_lo, int *status) -{ - int result; - static of_seek_service s; - s.service = "seek"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.pos_hi = pos_hi; - s.pos_lo = pos_lo; - result = of_server(&s); - *status = s.status; - return result; -} - - -/* 6.3.2.4 Memory */ - - -int -of_claim(void *virt, int size, int align, void **baseaddr) -{ - int result; - static of_claim_service s; - s.service = "claim"; - s.n_args = 3; - s.n_returns = 1; - s.virt = virt; - s.size = size; - s.align = align; - result = of_server(&s); - *baseaddr = s.baseaddr; - return result; -} - -int -of_release(void *virt, int size) -{ - int result; - static of_release_service s; - s.service = "release"; - s.n_args = 2; - s.n_returns = 0; - s.virt = virt; - s.size = size; - result = of_server(&s); - return result; -} - - -/* 6.3.2.5 Control transfer */ - - -int -of_boot(const char *bootspec) -{ - int result; - static of_boot_service s; - s.service = "boot"; - s.n_args = 1; - s.n_returns = 0; - s.bootspec = bootspec; - result = of_server(&s); - return result; -} - -int -of_enter(void) -{ - int result; - static of_enter_service s; - s.service = "enter"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -int -of_exit(void) -{ - int result; - static of_exit_service s; - s.service = "exit"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -/* int of_chain(void *virt, int size, void *entry, void *args, int len); */ - - -/* 6.3.2.6 User interface */ - - -/* int of_interpret(const char *arg, ...); */ - -int -of_set_callback(void *newfunc, void **oldfunc) -{ - int result; - static of_set_callback_service s; - s.service = "set-callback"; - s.n_args = 1; - s.n_returns = 1; - s.newfunc = newfunc; - result = of_server(&s); - *oldfunc = s.oldfunc; - return result; -} - -int -of_set_symbol_lookup(void *sym_to_value, void *value_to_sym) -{ - int result; - static of_set_symbol_lookup_service s; - s.service = "set-symbol-lookup"; - s.n_args = 2; - s.n_returns = 0; - s.sym_to_value = sym_to_value; - s.value_to_sym = s.value_to_sym; - result = of_server(&s); - return result; -} - - -/* 6.3.2.7 Time */ - - -int -of_milliseconds(int *ms) -{ - int result; - static of_milliseconds_service s; - s.service = "milliseconds"; - s.n_args = 0; - s.n_returns = 1; - result = of_server(&s); - *ms = s.ms; - return result; -} diff -urN linux-2.4.24/arch/ppc/boot/prep/of1275.h linux-2.4.25/arch/ppc/boot/prep/of1275.h --- linux-2.4.24/arch/ppc/boot/prep/of1275.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/of1275.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,421 +0,0 @@ -/* 6.3.2.1 Client interface */ - - -typedef struct _of_test_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *name; - /*out*/ - int missing; -} of_test_service; - -int of_test(const char *name, int *missing); - - -/* 6.3.2.2 Device tree */ - - -typedef struct _of_peer_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int sibling_phandle; -} of_peer_service; - -int of_peer(int phandle, int *sibling_phandle); - - -typedef struct _of_child_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int child_phandle; -} of_child_service; - -int of_child(int phandle, int *child_phandle); - - -typedef struct _of_parent_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int parent_phandle; -} of_parent_service; - -int of_child(int phandle, int *parent_phandle); - - -typedef struct _of_instance_to_package_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ - int phandle; -} of_instance_to_package_service; - -int of_instance_to_package(int ihandle, int *phandle); - - -typedef struct _of_getproplen_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - /*out*/ - int proplen; -} of_getproplen_service; - -int of_getproplen(int phandle, const char *name, int *proplen); - - -typedef struct _of_getprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int buflen; - /*out*/ - int size; -} of_getprop_service; - -int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); - - -typedef struct _of_nextprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *previous; - void *buf; - /*out*/ - int flag; -} of_nextprop_service; - -int of_nextprop(int phandle, const char *previous, void *buf, int *flag); - - -typedef struct _of_setprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int len; - /*out*/ - int size; -} of_setprop_service; - -int of_setprop(int phandle, const char *name, void *buf, int len, int *size); - - -typedef struct _of_canon_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - void *buf; - int buflen; - /*out*/ - int length; -} of_canon_service; - -int of_canon(const char *device_specifier, void *buf, int buflen, int *length); - - -typedef struct _of_finddevice_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int phandle; -} of_finddevice_service; - -int of_finddevice(const char *device_specifier, int *phandle); - - -typedef struct _of_instance_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_instance_to_path_service; - -int of_instance_to_path(int ihandle, void *buf, int buflen, int *length); - - -typedef struct _of_package_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_package_to_path_service; - -int of_package_to_path(int phandle, void *buf, int buflen, int *length); - - -typedef struct _of_call_method_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *method; - int ihandle; - /*...*/ - int args[0]; -} of_call_method_service; - -int of_call_method(const char *method, int ihandle, ...); - - -/* 6.3.2.3 Device I/O */ - - -typedef struct _of_open_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int ihandle; -} of_open_service; - -int of_open(const char *device_specifier, - int *ihandle); - - -typedef struct _of_close_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ -} of_close_service; - -int of_close(int ihandle); - - -typedef struct _of_read_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_read_service; - -int of_read(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_write_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_write_service; - -int of_write(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_seek_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - int pos_hi; - int pos_lo; - /*out*/ - int status; -} of_seek_service; - -int of_seek(int ihandle, int pos_hi, int pos_lo, int *status); - - -/* 6.3.2.4 Memory */ - - -typedef struct _of_claim_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ - void *baseaddr; -} of_claim_service; - -int of_claim(void *virt, int size, int align, void **baseaddr); - - -typedef struct _of_release_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ -} of_release_service; - -int of_release(void *virt, int size); - - -/* 6.3.2.5 Control transfer */ - - -typedef struct _of_boot_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *bootspec; - /*out*/ -} of_boot_service; - -int of_boot(const char *bootspec); - - -typedef struct _of_enter_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_enter_service; - -int of_enter(void); - - -typedef struct _of_exit_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_exit_service; - -int of_exit(void); - - -typedef struct _of_chain_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - void *entry; - void *args; - int len; - /*out*/ -} of_chain_service; - -int of_chain(void *virt, int size, void *entry, void *args, int len); - - -/* 6.3.2.6 User interface */ - - -typedef struct _of_interpret_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *cmd; - int args[0]; - /*...*/ - /*out*/ - /*...*/ -} of_interpret_service; - -int of_interpret(const char *arg, ...); - - -typedef struct _of_set_callback_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *newfunc; - /*out*/ - void *oldfunc; -} of_set_callback_service; - -int of_set_callback(void *newfunc, void **oldfunc); - - -typedef struct _of_set_symbol_lookup_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *sym_to_value; - void *value_to_sym; - /*out*/ -} of_set_symbol_lookup_service; - -int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym); - - -/* 6.3.2.7 Time */ - - -typedef struct _of_milliseconds_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ - int ms; -} of_milliseconds_service; - -int of_milliseconds(int *ms); diff -urN linux-2.4.24/arch/ppc/boot/prep/vreset.c linux-2.4.25/arch/ppc/boot/prep/vreset.c --- linux-2.4.24/arch/ppc/boot/prep/vreset.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/prep/vreset.c 2004-02-18 05:36:30.000000000 -0800 @@ -389,7 +389,7 @@ extern void puts(const char *); static void unlockS3(void); -static void inline +static inline void outw(int port, unsigned short val) { outb(port, val >> 8); @@ -691,14 +691,14 @@ unsigned long regs[NPCIREGS]; } PCI_slots [NSLOTS] = { - { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */ - { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */ - { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */ + { (unsigned long *)0x80808000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80800800, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80801000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80802000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80804000, {0xDEADBEEF,} }, /* onboard */ + { (unsigned long *)0x80810000, {0xDEADBEEF,} }, /* slot A/1 */ + { (unsigned long *)0x80820000, {0xDEADBEEF,} }, /* slot B/2 */ + { (unsigned long *)0x80840000, {0xDEADBEEF,} } /* slot C/3 */ }; diff -urN linux-2.4.24/arch/ppc/boot/simple/Makefile linux-2.4.25/arch/ppc/boot/simple/Makefile --- linux-2.4.24/arch/ppc/boot/simple/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/simple/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -9,12 +9,10 @@ # or implied. # # Notes: -# (1) For machine targets which produce more than one image, define -# ZNETBOOT and ZNETBOOTRD to the image which should be available for -# 'znetboot' and 'znetboot.initrd` -# (2) For machine targets which use the mktree program, define END to be -# the machine name you want in the image, and you can optionally set -# ENTRYPOINT which the image should be loaded at. The optimal setting +# (1) All machines must set the END variable to the suffix of the preferred +# final image (i.e. would be copied in 'make znetboot'. +# (2) For machine targets which use the mktree program you can optionally +# set ENTRYPOINT which the image should be loaded at. The optimal setting # for ENTRYPOINT is the link address. USE_STANDARD_AS_RULE := true @@ -25,15 +23,13 @@ ifeq ($(CONFIG_EMBEDDEDBOOT),y) ZIMAGE := zImage-EMBEDDED ZIMAGEINITRD := zImage.initrd-EMBEDDED -TFTPIMAGE := /tftpboot/zImage.embedded MISC := misc-embedded.o +END := embedded endif ifeq ($(CONFIG_IBM_OPENBIOS),y) ZIMAGE := zImage-TREE ZIMAGEINITRD := zImage.initrd-TREE END := treeboot -ZNETBOOT := zImage.treeboot -ZNETBOOTRD := zImage.initrd.treeboot TFTPIMAGE := /tftpboot/zImage.embedded MISC := misc-embedded.o endif @@ -42,9 +38,6 @@ ZIMAGEINITRD := zImage.initrd-TREE END := ebony ENTRYPOINT := 0x00800000 -ZNETBOOT := zImage.treeboot -ZNETBOOTRD := zImage.initrd.treeboot -TFTPIMAGE := /tftpboot/zImage.$(END) EXTRA := misc-44x.o endif ifeq ($(CONFIG_OCOTEA),y) @@ -52,25 +45,21 @@ ZIMAGEINITRD := zImage.initrd-TREE END := ocotea ENTRYPOINT := 0x00800000 -ZNETBOOT := zImage.treeboot -ZNETBOOTRD := zImage.initrd.treeboot -TFTPIMAGE := /tftpboot/zImage.$(END) EXTRA := misc-44x.o endif ifeq ($(CONFIG_GEMINI),y) ZIMAGE := zImage-SMON ZIMAGEINITRD := zImage.initrd-SMON -TFTPIMAGE := /tftpboot/zImage.gemini +END := gemini endif # kbuild-2.4 'feature', only one of these will ever by 'y' at a time. # The rest will be unset. -ifeq ($(CONFIG_LOPEC)$(CONFIG_PPLUS),y) +ifeq ($(CONFIG_LOPEC)$(CONFIG_PPLUS)$(CONFIG_PRPMC750),y) ZIMAGE := zImage-PPLUS ZIMAGEINITRD := zImage.initrd-PPLUS EXTRA := ../common/mpc10x_memory.o TFTPIMAGE := /tftpboot/zImage.pplus -ZNETBOOT := zImage.pplus -ZNETBOOTRD := zImage.initrd.pplus +END := pplus endif ifeq ($(CONFIG_PPLUS),y) EXTRA := legacy.o @@ -78,7 +67,14 @@ ifeq ($(CONFIG_PAL4),y) ZIMAGE := zImage-PAL4 ZIMAGEINITRD := zImage.initrd-PAL4 -TFTPIMAGE := /tftpboot/zImage.pal4 +END := pal4 +endif +ifeq ($(CONFIG_SANDPOINT),y) +ZIMAGE := zImage-SP +ZIMAGEINITRD := zImage.initrd-SP +CACHEFLAG := -include clear.S +TFTPIMAGE := /tftpboot/zImage.sandpoint +END := sandpoint endif ifeq ($(CONFIG_SPRUCE),y) ZIMAGE := zImage-TREE @@ -86,12 +82,14 @@ ENTRYPOINT := 0x00800000 MISC := misc-spruce.o END := spruce -TFTPIMAGE := /tftpboot/zImage.$(END) endif + +TFTPIMAGE ?= /tftpboot/zImage.$(END) ifeq ($(CONFIG_SMP),y) TFTPIMAGE += .smp endif + # Setup a default address to put ourselves, change it as needed. LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic ifdef CONFIG_8xx @@ -156,30 +154,22 @@ rm -f zvmlinux.initrd znetboot: zImage -ifneq ($(ZNETBOOT),) - cp ../images/$(ZNETBOOT) $(TFTPIMAGE) -else - cp ../images/zImage.* $(TFTPIMAGE) -endif + cp ../images/zImage.$(END) $(TFTPIMAGE) znetboot.initrd: zImage.initrd -ifneq ($(ZNETBOOTRD),) - cp ../images/$(ZNETBOOTRD) $(TFTPIMAGE) -else - cp ../images/zImage.* $(TFTPIMAGE) -endif + cp ../images/zImage.initrd.$(END) $(TFTPIMAGE) zImage-EMBEDDED: zvmlinux - mv zvmlinux ../images/zImage.embedded + mv zvmlinux ../images/zImage.$(END) zImage.initrd-EMBEDDED: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.embedded + mv zvmlinux.initrd ../images/zImage.initrd.$(END) zImage-PAL4: zvmlinux - mv zvmlinux ../images/zImage.pal4 + mv zvmlinux ../images/zImage.$(END) zImage.initrd-PAL4: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.pal4 + mv zvmlinux.initrd ../images/zImage.initrd.$(END) zImage-PPLUS: zvmlinux $(MKPREP) $(MKBUGBOOT) $(MKPREP) -pbp zvmlinux ../images/zImage.pplus @@ -189,11 +179,17 @@ $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.pplus $(MKBUGBOOT) zvmlinux.initrd ../images/zImage.initrd.bugboot +zImage-SP: zvmlinux + mv zvmlinux ../images/zImage.sandpoint + +zImage.initrd-SP: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.sandpoint + zImage-SMON: zvmlinux - dd if=zvmlinux of=../images/zImage.gemini skip=64 bs=1k + dd if=zvmlinux of=../images/zImage.$(END) skip=64 bs=1k zImage.initrd-SMON: zvmlinux.initrd - dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k + dd if=zvmlinux.initrd of=../images/zImage.initrd.$(END) skip=64 bs=1k zImage-TREE: zvmlinux $(MKTREE) zvmlinux ../images/zImage.$(END) $(ENTRYPOINT) diff -urN linux-2.4.24/arch/ppc/boot/simple/clear.S linux-2.4.25/arch/ppc/boot/simple/clear.S --- linux-2.4.24/arch/ppc/boot/simple/clear.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/simple/clear.S 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,19 @@ +/* + * Code to call _setup_L2CR to flus, invalidate and disable the L2, + * and if present, do the same to the L3. + */ + +#define CLEAR_CACHES \ + bl _setup_L2CR; \ + \ + /* If 745x, turn off L3CR as well */ \ + mfspr r8,PVR; \ + srwi r8,r8,16; \ + \ + cmpli cr0,r8,0x8000; /* 7450 */ \ + cmpli cr1,r8,0x8001; /* 7455 */ \ + cmpli cr2,r8,0x8002; /* 7457 */ \ + /* Now test if any are true. */ \ + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq; \ + cror 4*cr0+eq,4*cr0+eq,4*cr2+eq; \ + beql _setup_L3CR diff -urN linux-2.4.24/arch/ppc/boot/simple/embed_config.c linux-2.4.25/arch/ppc/boot/simple/embed_config.c --- linux-2.4.24/arch/ppc/boot/simple/embed_config.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/boot/simple/embed_config.c 2004-02-18 05:36:30.000000000 -0800 @@ -52,7 +52,7 @@ { u_char *mp; u_char eebuf[128]; - int i; + int i = 8; bd_t *bd; bd = *bdp; @@ -64,11 +64,21 @@ /* All we are looking for is the Ethernet MAC address. The * first 8 bytes are 'MOTOROLA', so check for part of that. + * Next, the VPD describes a MAC 'packet' as being of type 08 + * and size 06. So we look for that and the MAC must follow. + * If there are more than one, we still only care about the first. * If it's there, assume we have a valid MAC address. If not, * grab our default one. */ - if ((*(uint *)eebuf) == 0x4d4f544f) - mp = &eebuf[0x4c]; + if ((*(uint *)eebuf) == 0x4d4f544f) { + while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) + i += eebuf[i + 1] + 2; /* skip this packet */ + + if (i == 127) /* Couldn't find. */ + mp = (u_char *)def_enet_addr; + else + mp = &eebuf[i + 2]; + } else mp = (u_char *)def_enet_addr; diff -urN linux-2.4.24/arch/ppc/boot/utils/mkbugboot.c linux-2.4.25/arch/ppc/boot/utils/mkbugboot.c --- linux-2.4.24/arch/ppc/boot/utils/mkbugboot.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/utils/mkbugboot.c 2004-02-18 05:36:30.000000000 -0800 @@ -51,29 +51,22 @@ /* size of read buffer */ #define SIZE 0x1000 -#ifndef __sun__ -/* typedef long int32_t; */ -typedef unsigned long uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -#endif - /* PPCBUG ROM boot header */ typedef struct bug_boot_header { - uint8_t magic_word[4]; /* "BOOT" */ - uint32_t entry_offset; /* Offset from top of header to code */ - uint32_t routine_length; /* Length of code */ - uint8_t routine_name[8]; /* Name of the boot code */ + unsigned char magic_word[4]; /* "BOOT" */ + unsigned long entry_offset; /* Offset from top of header to code */ + unsigned long routine_length; /* Length of code */ + unsigned char routine_name[8]; /* Name of the boot code */ } bug_boot_header_t; #define HEADER_SIZE sizeof(bug_boot_header_t) -uint32_t copy_image(int32_t in_fd, int32_t out_fd) +unsigned long copy_image(int32_t in_fd, int32_t out_fd) { - uint8_t buf[SIZE]; + unsigned char buf[SIZE]; int n; - uint32_t image_size = 0; - uint8_t zero = 0; + unsigned long image_size = 0; + unsigned char zero = 0; lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); @@ -95,9 +88,9 @@ return image_size; } -void write_bugboot_header(int32_t out_fd, uint32_t boot_size) +void write_bugboot_header(int32_t out_fd, unsigned long boot_size) { - uint8_t header_block[HEADER_SIZE]; + unsigned char header_block[HEADER_SIZE]; bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; memset(header_block, 0, HEADER_SIZE); @@ -112,16 +105,16 @@ write(out_fd, header_block, HEADER_SIZE); } -uint16_t calc_checksum(int32_t bug_fd) +unsigned short calc_checksum(int32_t bug_fd) { - uint32_t checksum_var = 0; - uint8_t buf[2]; + unsigned long checksum_var = 0; + unsigned char buf[2]; int n; /* Checksum loop */ while ( (n = read(bug_fd, buf, 2) ) ) { - checksum_var = checksum_var + *(uint16_t *)buf; + checksum_var = checksum_var + *(unsigned short *)buf; /* If we carry out, mask it and add one to the checksum */ if (checksum_var >> 16) @@ -135,9 +128,9 @@ { int32_t image_fd, bugboot_fd; int argptr = 1; - uint32_t kernel_size = 0; - uint16_t checksum = 0; - uint8_t bugbootname[256]; + unsigned long kernel_size = 0; + unsigned short checksum = 0; + unsigned char bugbootname[256]; if ( (argc != 3) ) { diff -urN linux-2.4.24/arch/ppc/boot/utils/mkprep.c linux-2.4.25/arch/ppc/boot/utils/mkprep.c --- linux-2.4.24/arch/ppc/boot/utils/mkprep.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/boot/utils/mkprep.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,12 +12,14 @@ * -- Cort * * Modified for x86 hosted builds by Matt Porter + * Modified for Sparc hosted builds by Peter Wahl */ #include #include #include #include +#include #include #include @@ -147,7 +149,7 @@ void write_prep_partition(int in, int out) { unsigned char block[512]; - partition_entry_t *pe = (partition_entry_t *)&block[0x1BE]; + partition_entry_t pe; dword_t *entry = (dword_t *)&block[0]; dword_t *length = (dword_t *)&block[sizeof(long)]; struct stat info; @@ -177,8 +179,8 @@ * Build a "PReP" partition table entry in the boot record * - "PReP" may only look at the system_indicator */ - pe->boot_indicator = BootActive; - pe->system_indicator = SystemPrep; + pe.boot_indicator = BootActive; + pe.system_indicator = SystemPrep; /* * The first block of the diskette is used by this "boot record" which * actually contains the partition table. (The first block of the @@ -186,12 +188,12 @@ * one partition on the diskette and it shall contain the rest of the * diskette. */ - pe->starting_head = 0; /* zero-based */ - pe->starting_sector = 2; /* one-based */ - pe->starting_cylinder = 0; /* zero-based */ - pe->ending_head = 1; /* assumes two heads */ - pe->ending_sector = 18; /* assumes 18 sectors/track */ - pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */ + pe.starting_head = 0; /* zero-based */ + pe.starting_sector = 2; /* one-based */ + pe.starting_cylinder = 0; /* zero-based */ + pe.ending_head = 1; /* assumes two heads */ + pe.ending_sector = 18; /* assumes 18 sectors/track */ + pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ /* * The "PReP" software ignores the above fields and just looks at @@ -201,22 +203,24 @@ * - unlike the above sector numbers, the beginning sector is zero-based! */ #if 0 - pe->beginning_sector = cpu_to_le32(1); + pe.beginning_sector = cpu_to_le32(1); #else /* This has to be 0 on the PowerStack? */ #ifdef __i386__ - pe->beginning_sector = 0; + pe.beginning_sector = 0; #else - pe->beginning_sector = cpu_to_le32(0); + pe.beginning_sector = cpu_to_le32(0); #endif /* __i386__ */ #endif #ifdef __i386__ - pe->number_of_sectors = 2*18*80-1; + pe.number_of_sectors = 2*18*80-1; #else - pe->number_of_sectors = cpu_to_le32(2*18*80-1); + pe.number_of_sectors = cpu_to_le32(2*18*80-1); #endif /* __i386__ */ + memcpy(&block[0x1BE],&pe,sizeof(pe)); + write( out, block, sizeof(block) ); write( out, entry, sizeof(*entry) ); write( out, length, sizeof(*length) ); diff -urN linux-2.4.24/arch/ppc/config.in linux-2.4.25/arch/ppc/config.in --- linux-2.4.24/arch/ppc/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -62,7 +62,8 @@ if [ "$CONFIG_40x" = "y" ]; then choice 'Machine Type' \ - "Oak CONFIG_OAK \ + "CPCI405 CONFIG_CPCI405 \ + Oak CONFIG_OAK \ Walnut CONFIG_WALNUT" Walnut fi @@ -111,13 +112,15 @@ Amiga-APUS CONFIG_APUS \ IBM-Spruce CONFIG_SPRUCE \ Motorola-LoPEC CONFIG_LOPEC \ + Motorola-Sandpoint CONFIG_SANDPOINT \ Motorola-PowerPlus CONFIG_PPLUS \ + Motorola-PrPMC750 CONFIG_PRPMC750 \ SBS-Palomar4 CONFIG_PAL4 \ Synergy-Gemini CONFIG_GEMINI" CHRP/PowerMac/PReP fi -if [ "$CONFIG_SPRUCE" = "y" ]; then - define_bool CONFIG_GEN550 y +if [ "$CONFIG_SANDPOINT" = "y" ]; then + bool 'Enable MPC10x store gathering' CONFIG_MPC10X_STORE_GATHERING fi if [ "$CONFIG_LOPEC" = "y" ]; then @@ -129,6 +132,19 @@ define_bool CONFIG_GEN550 y fi +if [ "$CONFIG_PRPMC750" = "y" ]; then + define_bool CONFIG_GEN550 y +fi + +if [ "$CONFIG_SANDPOINT" = "y" ]; then + define_bool CONFIG_EPIC_SERIAL_MODE y + define_bool CONFIG_GEN550 y +fi + +if [ "$CONFIG_SPRUCE" = "y" ]; then + define_bool CONFIG_GEN550 y +fi + bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS @@ -173,6 +189,11 @@ # # Set processor implementation based on board # + + if [ "$CONFIG_CPCI405" = "y" ]; then + define_bool CONFIG_405GP y + fi + if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then define_bool CONFIG_403GCX y fi @@ -270,6 +291,9 @@ if [ "$CONFIG_TASK_SIZE_BOOL" = "y" ]; then hex " Size of user task space" CONFIG_TASK_SIZE 0x80000000 fi + if [ "$CONFIG_8xx" = "y" ]; then + bool "Pinned Kernel TLBs (86x ONLY)" CONFIG_PIN_TLB + fi fi if [ "$CONFIG_HIGHMEM_START_BOOL" != "y" ]; then @@ -328,6 +352,7 @@ define_bool CONFIG_BINFMT_ELF y define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/pci/Config.in @@ -420,7 +445,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/ppc/configs/IVMS8_defconfig linux-2.4.25/arch/ppc/configs/IVMS8_defconfig --- linux-2.4.24/arch/ppc/configs/IVMS8_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/IVMS8_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -69,6 +69,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -214,7 +215,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -531,7 +531,7 @@ # CONFIG_FEC_DP83846A is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -# CONFIG_SMC2_UART is not set +# CONFIG_8xx_SMC2 is not set # CONFIG_8xx_SCC1 is not set # CONFIG_8xx_SCC2 is not set # CONFIG_8xx_SCC3 is not set diff -urN linux-2.4.24/arch/ppc/configs/SM850_defconfig linux-2.4.25/arch/ppc/configs/SM850_defconfig --- linux-2.4.24/arch/ppc/configs/SM850_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/SM850_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -70,6 +70,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -181,7 +182,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -489,7 +489,7 @@ CONFIG_SCC3_ENET=y # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y CONFIG_ALTSMC2=y CONFIG_CONS_SMC2=y # CONFIG_8xx_SCC1 is not set diff -urN linux-2.4.24/arch/ppc/configs/SPD823TS_defconfig linux-2.4.25/arch/ppc/configs/SPD823TS_defconfig --- linux-2.4.24/arch/ppc/configs/SPD823TS_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/SPD823TS_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -69,6 +69,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -180,7 +181,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -489,7 +489,7 @@ # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y CONFIG_ALTSMC2=y # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC1 is not set diff -urN linux-2.4.24/arch/ppc/configs/TQM823L_defconfig linux-2.4.25/arch/ppc/configs/TQM823L_defconfig --- linux-2.4.24/arch/ppc/configs/TQM823L_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/TQM823L_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -70,6 +70,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -181,7 +182,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -490,7 +490,7 @@ # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y CONFIG_ALTSMC2=y # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC1 is not set diff -urN linux-2.4.24/arch/ppc/configs/TQM850L_defconfig linux-2.4.25/arch/ppc/configs/TQM850L_defconfig --- linux-2.4.24/arch/ppc/configs/TQM850L_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/TQM850L_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -70,6 +70,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -181,7 +182,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -489,7 +489,7 @@ # CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y CONFIG_ALTSMC2=y # CONFIG_CONS_SMC2 is not set # CONFIG_USE_SCC_IO is not set diff -urN linux-2.4.24/arch/ppc/configs/TQM860L_defconfig linux-2.4.25/arch/ppc/configs/TQM860L_defconfig --- linux-2.4.24/arch/ppc/configs/TQM860L_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/TQM860L_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -70,6 +70,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -215,7 +216,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -531,7 +531,7 @@ # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y # CONFIG_ALTSMC2 is not set # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC2 is not set diff -urN linux-2.4.24/arch/ppc/configs/apus_defconfig linux-2.4.25/arch/ppc/configs/apus_defconfig --- linux-2.4.24/arch/ppc/configs/apus_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/apus_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -59,6 +59,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -290,7 +291,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/configs/briq_defconfig linux-2.4.25/arch/ppc/configs/briq_defconfig --- linux-2.4.24/arch/ppc/configs/briq_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/briq_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -300,7 +301,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/configs/bseip_defconfig linux-2.4.25/arch/ppc/configs/bseip_defconfig --- linux-2.4.24/arch/ppc/configs/bseip_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/bseip_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -67,6 +67,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -180,7 +181,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -489,7 +489,7 @@ # CONFIG_FEC_ENET is not set # CONFIG_ENET_BIG_BUFFERS is not set CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y # CONFIG_ALTSMC2 is not set # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC1 is not set diff -urN linux-2.4.24/arch/ppc/configs/common_defconfig linux-2.4.25/arch/ppc/configs/common_defconfig --- linux-2.4.24/arch/ppc/configs/common_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/common_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y CONFIG_HOTPLUG=y @@ -308,7 +309,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/configs/cpci405_defconfig linux-2.4.25/arch/ppc/configs/cpci405_defconfig --- linux-2.4.24/arch/ppc/configs/cpci405_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/cpci405_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,638 @@ +# +# Automatically generated make config: 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 is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_40x=y +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +CONFIG_4xx=y +CONFIG_CPCI405=y +# CONFIG_OAK is not set +# CONFIG_WALNUT is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_PPC4xx_DMA is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_405GP=y +CONFIG_IBM_OCP=y +CONFIG_405=y +CONFIG_IBM405_ERR51=y +CONFIG_IBM405_ERR77=y + +# +# General setup +# +# CONFIG_HIGHMEM 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_PC_KEYBOARD is not set +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=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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 is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +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 is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# 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 +# 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=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_CPCI405_IDE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 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 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 + +# +# On-chip net devices +# +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 +CONFIG_IBM_OCP_ENET_SKB_RES=0 +CONFIG_OCP_NET=y +# CONFIG_FDDI 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 +# + +# +# 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=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_PPC405_ALGO is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PROC=y + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_JBD is not set +# 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 is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# 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 is not set +# 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 + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc/configs/ebony_defconfig linux-2.4.25/arch/ppc/configs/ebony_defconfig --- linux-2.4.24/arch/ppc/configs/ebony_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/ebony_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -62,6 +62,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -182,7 +183,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/est8260_defconfig linux-2.4.25/arch/ppc/configs/est8260_defconfig --- linux-2.4.24/arch/ppc/configs/est8260_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/est8260_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -50,6 +50,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -163,7 +164,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/gemini_defconfig linux-2.4.25/arch/ppc/configs/gemini_defconfig --- linux-2.4.24/arch/ppc/configs/gemini_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/gemini_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -182,7 +183,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/ibmchrp_defconfig linux-2.4.25/arch/ppc/configs/ibmchrp_defconfig --- linux-2.4.24/arch/ppc/configs/ibmchrp_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/ibmchrp_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -58,6 +58,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=y +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -226,7 +227,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/mbx_defconfig linux-2.4.25/arch/ppc/configs/mbx_defconfig --- linux-2.4.24/arch/ppc/configs/mbx_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/mbx_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -67,6 +67,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -177,7 +178,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -485,7 +485,7 @@ # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y # CONFIG_ALTSMC2 is not set # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC2 is not set diff -urN linux-2.4.24/arch/ppc/configs/oak_defconfig linux-2.4.25/arch/ppc/configs/oak_defconfig --- linux-2.4.24/arch/ppc/configs/oak_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/oak_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -52,6 +52,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -164,7 +165,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/ocotea_defconfig linux-2.4.25/arch/ppc/configs/ocotea_defconfig --- linux-2.4.24/arch/ppc/configs/ocotea_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/ocotea_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -63,6 +63,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -183,7 +184,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/pal4_defconfig linux-2.4.25/arch/ppc/configs/pal4_defconfig --- linux-2.4.24/arch/ppc/configs/pal4_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/pal4_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -58,6 +58,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -225,7 +226,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/pmac_defconfig linux-2.4.25/arch/ppc/configs/pmac_defconfig --- linux-2.4.24/arch/ppc/configs/pmac_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/pmac_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y CONFIG_HOTPLUG=y @@ -312,7 +313,6 @@ # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/configs/power3_defconfig linux-2.4.25/arch/ppc/configs/power3_defconfig --- linux-2.4.24/arch/ppc/configs/power3_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/power3_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -52,6 +52,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=y +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -180,7 +181,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/pplus_defconfig linux-2.4.25/arch/ppc/configs/pplus_defconfig --- linux-2.4.24/arch/ppc/configs/pplus_defconfig 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/pplus_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ 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 @@ -299,7 +300,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/configs/prpmc750_defconfig linux-2.4.25/arch/ppc/configs/prpmc750_defconfig --- linux-2.4.24/arch/ppc/configs/prpmc750_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/prpmc750_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,621 @@ +# +# Automatically generated make config: 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 is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_SANDPOINT is not set +# CONFIG_PPLUS is not set +CONFIG_PRPMC750=y +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +CONFIG_GEN550=y +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +CONFIG_PPC_ISATIMER=y + +# +# General setup +# +# CONFIG_HIGHMEM 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 is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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=4096 +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 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 is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_MATCH_TCPMSS=m +# CONFIG_IP_NF_MATCH_HELPER is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# 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 is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 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=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 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_FDDI 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 + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +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 is not set +# 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_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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc/configs/rpxcllf_defconfig linux-2.4.25/arch/ppc/configs/rpxcllf_defconfig --- linux-2.4.24/arch/ppc/configs/rpxcllf_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/rpxcllf_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -69,6 +69,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set CONFIG_HOTPLUG=y # @@ -190,7 +191,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -525,7 +525,7 @@ # CONFIG_USE_MDIO is not set CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xx_SMC1=y -CONFIG_SMC2_UART=y +CONFIG_8xx_SMC2=y # CONFIG_ALTSMC2 is not set # CONFIG_CONS_SMC2 is not set # CONFIG_8xx_SCC2 is not set diff -urN linux-2.4.24/arch/ppc/configs/rpxlite_defconfig linux-2.4.25/arch/ppc/configs/rpxlite_defconfig --- linux-2.4.24/arch/ppc/configs/rpxlite_defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/rpxlite_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -69,6 +69,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set CONFIG_HOTPLUG=y # @@ -190,7 +191,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -524,7 +524,7 @@ # CONFIG_FEC_ENET is not set # CONFIG_ENET_BIG_BUFFERS is not set CONFIG_8xx_SMC1=y -# CONFIG_SMC2_UART is not set +# CONFIG_8xx_SMC2 is not set # CONFIG_8xx_SCC1 is not set # CONFIG_8xx_SCC3 is not set # CONFIG_8xx_SCC4 is not set diff -urN linux-2.4.24/arch/ppc/configs/sandpoint_defconfig linux-2.4.25/arch/ppc/configs/sandpoint_defconfig --- linux-2.4.24/arch/ppc/configs/sandpoint_defconfig 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/configs/sandpoint_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,719 @@ +# +# Automatically generated make config: 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 is not set + +# +# 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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +CONFIG_SANDPOINT=y +# CONFIG_PPLUS is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_MPC10X_STORE_GATHERING is not set +CONFIG_EPIC_SERIAL_MODE=y +CONFIG_GEN550=y +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set +CONFIG_PPC_ISATIMER=y + +# +# General setup +# +# CONFIG_HIGHMEM 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=y +# 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=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# 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=4096 +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 is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES 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=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_SL82C105=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +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=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# 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=y +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_AIC79XX 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=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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 + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 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=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +CONFIG_DE4X5=y +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 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_FDDI 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 + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# 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_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM 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 + +# +# 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 is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# 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 is not set +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 is not set +# 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_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 is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc/configs/spruce_defconfig linux-2.4.25/arch/ppc/configs/spruce_defconfig --- linux-2.4.24/arch/ppc/configs/spruce_defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/spruce_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -59,6 +59,7 @@ 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 @@ -172,7 +173,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/configs/walnut_defconfig linux-2.4.25/arch/ppc/configs/walnut_defconfig --- linux-2.4.24/arch/ppc/configs/walnut_defconfig 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/configs/walnut_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -172,7 +173,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/ppc/defconfig linux-2.4.25/arch/ppc/defconfig --- linux-2.4.24/arch/ppc/defconfig 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -60,6 +60,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set CONFIG_PCI_NAMES=y CONFIG_HOTPLUG=y @@ -308,7 +309,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set diff -urN linux-2.4.24/arch/ppc/kernel/Makefile linux-2.4.25/arch/ppc/kernel/Makefile --- linux-2.4.24/arch/ppc/kernel/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -64,6 +64,7 @@ obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o +obj-$(CONFIG_8xx_WDT) += m8xx_wdt.o ifeq ($(CONFIG_8xx),y) obj-$(CONFIG_PCI) += qspan_pci.o ifndef CONFIG_MATH_EMULATION @@ -79,6 +80,10 @@ obj-$(CONFIG_PAL4) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_PPLUS) += pplus_common.o open_pic.o i8259.o \ indirect_pci.o todc_time.o pci_auto.o +obj-$(CONFIG_PRPMC750) += open_pic.o indirect_pci.o pci_auto.o \ + pplus_common.o +obj-$(CONFIG_SANDPOINT) += i8259.o open_pic.o mpc10x_common.o \ + pci_auto.o indirect_pci.o todc_time.o obj-$(CONFIG_SPRUCE) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o obj-$(CONFIG_BOOTX_TEXT) += btext.o diff -urN linux-2.4.24/arch/ppc/kernel/cpu_setup_6xx.S linux-2.4.25/arch/ppc/kernel/cpu_setup_6xx.S --- linux-2.4.24/arch/ppc/kernel/cpu_setup_6xx.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/kernel/cpu_setup_6xx.S 2004-02-18 05:36:30.000000000 -0800 @@ -104,8 +104,8 @@ /* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some * erratas we work around here. - * Moto MPC710CE.pdf describes them, those are errata - * #3, #4 and #5 + * Moto MPC7410CE.pdf describes them, those are errata + * #3, #4 and #5 (7400 erratas #13, #14 and #15). * Note that we assume the firmware didn't choose to * apply other workarounds (there are other ones documented * in the .pdf). It appear that Apple firmware only works @@ -155,7 +155,20 @@ BEGIN_FTR_SECTION oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) - li r3,HID0_SPD + + /* 7400 Errata #7, don't enable SGE on < Rev 2.1 */ + mfpvr r10 + rlwinm r3,r10,16,16,31 + cmplwi r3,0x000c + bne 1f /* Not a 7400. */ + andi. r3,r10,0x0f0f + cmpwi 0,r3,0x0200 + bgt 1f /* Rev >= 2.1 */ + li r3,HID0_SGE /* 7400 rev < 2.1, clear SGE. */ + b 2f + +1: li r3,0 /* Don't clear SGE. */ +2: ori r3,r3,HID0_SPD andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 mtspr ICTC,r3 /* Instruction Cache Throttling off */ @@ -223,9 +236,17 @@ oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + /* We only want to disable BTIC on 7457's */ + mfpvr r3 + rlwinm r3,r3,16,16,31 + cmplwi r3,0x8002 + li r3,0 /* Assume we don't want to clear BTIC. */ + bne 2f /* Not a 7457. */ + li r3,HID0_BTIC /* 7457, clear BTIC. */ + /* All of the bits we have to clear.... */ - li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI +2: ori r3,r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 diff -urN linux-2.4.24/arch/ppc/kernel/cputable.c linux-2.4.25/arch/ppc/kernel/cputable.c --- linux-2.4.24/arch/ppc/kernel/cputable.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/cputable.c 2004-02-18 05:36:30.000000000 -0800 @@ -144,7 +144,7 @@ 0xffffff00, 0x70000100, "750FX", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, + CPU_FTR_750FX | CPU_FTR_NO_DPM, COMMON_PPC, 32, 32, __setup_cpu_750 @@ -153,7 +153,7 @@ 0xffffffff, 0x70000200, "750FX", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NO_DPM, + CPU_FTR_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NO_DPM, COMMON_PPC, 32, 32, __setup_cpu_750 @@ -162,7 +162,7 @@ 0xffff0000, 0x70000000, "750FX", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP | - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTR_750FX | CPU_FTR_HAS_HIGH_BATS, COMMON_PPC, 32, 32, __setup_cpu_750fx @@ -202,6 +202,15 @@ 32, 32, __setup_cpu_7410 }, + { /* 7450 1.x - no doze/nap */ + 0xffffff00, 0x80000100, "7450", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_745x + }, { /* 7450 2.0 - no doze/nap */ 0xffffffff, 0x80000200, "7450", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | @@ -276,6 +285,14 @@ 32, 32, __setup_cpu_603 }, + { /* 8280 is a G2_LE (603e core, plus some) */ + 0x7fff0000, 0x00820000, "8280", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, { /* default match, we assume split I/D cache & TB (non-601)... */ 0x00000000, 0x00000000, "(generic PPC)", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, diff -urN linux-2.4.24/arch/ppc/kernel/head_8xx.S linux-2.4.25/arch/ppc/kernel/head_8xx.S --- linux-2.4.24/arch/ppc/kernel/head_8xx.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/head_8xx.S 2004-02-18 05:36:30.000000000 -0800 @@ -341,7 +341,7 @@ beq 2f /* If zero, don't try to find a pte */ /* We have a pte table, so load the MI_TWC with the attributes - * for this page, which has only bit 31 set. + * for this "segment." */ tophys(r21,r21) ori r21,r21,1 /* Set valid bit */ @@ -350,7 +350,7 @@ stw r3, 12(r0) lwz r3, 12(r0) #endif - mtspr MI_TWC, r21 /* Set page attributes */ + mtspr MI_TWC, r21 /* Set segment attributes */ #ifdef CONFIG_8xx_CPU6 li r3, 0x3b80 stw r3, 12(r0) @@ -369,8 +369,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -463,8 +461,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -608,8 +604,6 @@ * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ diff -urN linux-2.4.24/arch/ppc/kernel/idle_6xx.S linux-2.4.25/arch/ppc/kernel/idle_6xx.S --- linux-2.4.24/arch/ppc/kernel/idle_6xx.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/kernel/idle_6xx.S 2004-02-18 05:36:30.000000000 -0800 @@ -52,7 +52,7 @@ mfspr r4,SPRN_HID1 addis r6,r5,nap_save_hid1@ha stw r4,nap_save_hid1@l(r6) -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +END_FTR_SECTION_IFSET(CPU_FTR_750FX) blr /* @@ -139,7 +139,7 @@ oris r4,r4,0x0001 mtspr SPRN_HID1,r4 1: -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +END_FTR_SECTION_IFSET(CPU_FTR_750FX) /* Go to NAP or DOZE now */ mfspr r4,SPRN_HID0 @@ -210,7 +210,7 @@ addis r22,r24,(nap_save_hid1-KERNELBASE)@ha lwz r22,nap_save_hid1@l(r22) mtspr SPRN_HID1, r22 -END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) +END_FTR_SECTION_IFSET(CPU_FTR_750FX) b transfer_to_handler_cont .data diff -urN linux-2.4.24/arch/ppc/kernel/m8xx_setup.c linux-2.4.25/arch/ppc/kernel/m8xx_setup.c --- linux-2.4.24/arch/ppc/kernel/m8xx_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/kernel/m8xx_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -58,6 +58,7 @@ extern unsigned long find_available_memory(void); extern void m8xx_cpm_reset(uint); +extern void m8xx_wdt_handler_install(bd_t *bp); void __init m8xx_setup_arch(void) @@ -184,6 +185,13 @@ if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0) panic("Could not allocate timer IRQ!"); + +#ifdef CONFIG_8xx_WDT + /* Install watchdog timer handler early because it might be + * already enabled by the bootloader + */ + m8xx_wdt_handler_install(binfo); +#endif } /* The RTC on the MPC8xx is an internal register. diff -urN linux-2.4.24/arch/ppc/kernel/m8xx_wdt.c linux-2.4.25/arch/ppc/kernel/m8xx_wdt.c --- linux-2.4.24/arch/ppc/kernel/m8xx_wdt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/m8xx_wdt.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,110 @@ +/* + * m8xx_wdt.c - MPC8xx watchdog driver + * + * Copyright (C) 2002 Florian Schirmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include + +static int wdt_timeout; + +void +m8xx_wdt_reset(void) +{ + volatile immap_t *imap = (volatile immap_t *) IMAP_ADDR; + + imap->im_siu_conf.sc_swsr = 0x556c; /* write magic1 */ + imap->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */ +} + +static void +m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + volatile immap_t *imap = (volatile immap_t *) IMAP_ADDR; + + m8xx_wdt_reset(); + + imap->im_sit.sit_piscr |= PISCR_PS; /* clear irq */ +} + +void __init +m8xx_wdt_handler_install(bd_t * binfo) +{ + volatile immap_t *imap = (volatile immap_t *) IMAP_ADDR; + u32 pitc; + u32 sypcr; + u32 pitrtclk; + + sypcr = imap->im_siu_conf.sc_sypcr; + + if (!(sypcr & 0x04)) { + printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", + sypcr); + return; + } + + m8xx_wdt_reset(); + + printk(KERN_NOTICE + "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n", + (sypcr >> 16), sypcr & 0x01); + + wdt_timeout = (sypcr >> 16) & 0xFFFF; + + if (!wdt_timeout) + wdt_timeout = 0xFFFF; + + if (sypcr & 0x01) + wdt_timeout *= 2048; + + /* + * Fire trigger if half of the wdt ticked down + */ + + if (imap->im_sit.sit_rtcsc & RTCSC_38K) + pitrtclk = 9600; + else + pitrtclk = 8192; + + if ((wdt_timeout) > (UINT_MAX / pitrtclk)) + pitc = wdt_timeout / binfo->bi_intfreq * pitrtclk / 2; + else + pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2; + + imap->im_sit.sit_pitc = pitc << 16; + imap->im_sit.sit_piscr = + (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE; + + if (request_irq(PIT_INTERRUPT, m8xx_wdt_interrupt, 0, "watchdog", NULL)) + panic("m8xx_wdt: could not allocate watchdog irq!"); + + printk(KERN_NOTICE + "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc); + + wdt_timeout /= binfo->bi_intfreq; +} + +int +m8xx_wdt_get_timeout(void) +{ + return wdt_timeout; +} diff -urN linux-2.4.24/arch/ppc/kernel/open_pic.c linux-2.4.25/arch/ppc/kernel/open_pic.c --- linux-2.4.24/arch/ppc/kernel/open_pic.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/kernel/open_pic.c 2004-02-18 05:36:30.000000000 -0800 @@ -69,7 +69,6 @@ * These functions are not used but the code is kept here * for completeness and future reference. */ -static void openpic_reset(void); #ifdef notused static void openpic_enable_8259_pass_through(void); static u_int openpic_get_priority(void); @@ -167,13 +166,21 @@ { u_int val; +#ifdef CONFIG_PPC_OPENPIC_BE + val = in_be32(addr); +#else val = in_le32(addr); +#endif return val; } static inline void openpic_write(volatile u_int *addr, u_int val) { +#ifdef CONFIG_PPC_OPENPIC_BE + out_be32(addr, val); +#else out_le32(addr, val); +#endif } static inline u_int openpic_readfield(volatile u_int *addr, u_int mask) @@ -212,7 +219,7 @@ u_int openpic_read_IPI(volatile u_int* addr) { u_int val = 0; -#ifdef CONFIG_POWER3 +#if defined(CONFIG_PPC_OPENPIC_BE) || defined(CONFIG_POWER3) val = in_be32(addr); #else val = in_le32(addr); diff -urN linux-2.4.24/arch/ppc/kernel/ppc_htab.c linux-2.4.25/arch/ppc/kernel/ppc_htab.c --- linux-2.4.24/arch/ppc/kernel/ppc_htab.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/ppc_htab.c 2004-02-18 05:36:30.000000000 -0800 @@ -509,40 +509,59 @@ left -= len; _set_L2CR(val); } else { + int is750fx = cur_cpu_spec[0]->cpu_features & CPU_FTR_750FX; p = buf; if (!first) *p++ = '\t'; val = _get_L2CR(); p += sprintf(p, "0x%08x: ", val); - p += sprintf(p, " L2 %s", (val >> 31) & 1 ? "enabled" : + p += sprintf(p, " L2 %s, ", (val >> 31) & 1 ? "enabled" : "disabled"); - p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no "); + if (!(val>>30&1)) + p += sprintf(p, "no "); + if (is750fx) + p += sprintf(p, "ECC checkstop"); + else + p += sprintf(p, "parity"); /* 75x & 74x0 have different L2CR than 745x */ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450)) { - p += sprintf(p, ", %s", - sizestrings[(val >> 28) & 3]); - p += sprintf(p, ", %s", - clockstrings[(val >> 25) & 7]); - p += sprintf(p, ", %s", - typestrings[(val >> 23) & 3]); + if (!is750fx) { + p += sprintf(p, ", %s", + sizestrings[(val >> 28) & 3]); + p += sprintf(p, ", %s", + clockstrings[(val >> 25) & 7]); + p += sprintf(p, ", %s", + typestrings[(val >> 23) & 3]); + } p += sprintf(p, "%s", (val>>22)&1 ? - ", data only" : ""); - p += sprintf(p, "%s", (val>>20)&1 ? - ", ZZ enabled": ""); + ", data only" : ""); + if (!is750fx) { + p += sprintf(p, "%s", (val>>20)&1 ? + ", ZZ enabled": ""); + } p += sprintf(p, ", %s", (val>>19)&1 ? "write-through" : "copy-back"); p += sprintf(p, "%s", (val>>18)&1 ? ", testing" : ""); - p += sprintf(p, ", %sns hold", - holdstrings[(val>>16)&3]); - p += sprintf(p, "%s", (val>>15)&1 ? - ", DLL slow" : ""); - p += sprintf(p, "%s", (val>>14)&1 ? - ", diff clock" :""); - p += sprintf(p, "%s", (val>>13)&1 ? - ", DLL bypass" :""); + if (!is750fx) { + p += sprintf(p, ", %sns hold", + holdstrings[(val>>16)&3]); + p += sprintf(p, "%s", (val>>15)&1 ? + ", DLL slow" : ""); + p += sprintf(p, "%s", (val>>14)&1 ? + ", diff clock" :""); + p += sprintf(p, "%s", (val>>13)&1 ? + ", DLL bypass" :""); + } else { + if ((val>>11)&1) + p += sprintf(p, ", lock way 0"); + if ((val>>10)&1) + p += sprintf(p, ", lock way 1"); + if ((val>>9)&1) + p += sprintf(p, ", Snoop Hit in Locked Line Error Enabled"); + } } else { /* 745x */ p += sprintf(p, ", %sinstn only", (val>>20)&1 ? "" : "no "); diff -urN linux-2.4.24/arch/ppc/kernel/ppc_ksyms.c linux-2.4.25/arch/ppc/kernel/ppc_ksyms.c --- linux-2.4.24/arch/ppc/kernel/ppc_ksyms.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/ppc_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -357,6 +357,12 @@ EXPORT_SYMBOL(cpm_free_handler); EXPORT_SYMBOL(m8xx_cpm_hostalloc); EXPORT_SYMBOL(m8xx_cpm_dpalloc); +#ifdef CONFIG_8xx_WDT +extern int m8xx_wdt_get_timeout(void); +extern void m8xx_wdt_reset(void); +EXPORT_SYMBOL(m8xx_wdt_get_timeout); +EXPORT_SYMBOL(m8xx_wdt_reset); +#endif #endif /* CONFIG_8xx */ /* Those should really be inline */ diff -urN linux-2.4.24/arch/ppc/kernel/setup.c linux-2.4.25/arch/ppc/kernel/setup.c --- linux-2.4.24/arch/ppc/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -157,7 +157,7 @@ lpj = loops_per_jiffy; #endif - seq_printf(m, "processor\t: %lu\n", i); + seq_printf(m, "processor\t: %u\n", i); seq_printf(m, "cpu\t\t: "); if (cur_cpu_spec[i]->pvr_mask) @@ -258,7 +258,7 @@ unsigned long early_init(int r3, int r4, int r5) { - extern char __bss_start, _end; + extern char __bss_start[], _end[]; unsigned long phys; unsigned long offset = reloc_offset(); @@ -267,7 +267,7 @@ /* First zero the BSS -- use memset, some arches don't have * caches on yet */ - memset_io(PTRRELOC(&__bss_start), 0, &_end - &__bss_start); + memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); /* * Identify the CPU type and fix up code sections diff -urN linux-2.4.24/arch/ppc/mm/pgtable.c linux-2.4.25/arch/ppc/mm/pgtable.c --- linux-2.4.24/arch/ppc/mm/pgtable.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/mm/pgtable.c 2004-02-18 05:36:30.000000000 -0800 @@ -258,7 +258,7 @@ printk(KERN_INFO "Memory BAT mapping: BAT2=%ldMb, BAT3=%ldMb," " residual: %ldMb\n", __bat2 >> 20, __bat3 >> 20, - (total_lowmem - (__bat2 - __bat3)) >> 20); + (total_lowmem - (__bat2 + __bat3)) >> 20); /* On SMP, we limit the lowmem to the area mapped with BATs. * We also assume nobody will do SMP with 601s diff -urN linux-2.4.24/arch/ppc/platforms/Makefile linux-2.4.25/arch/ppc/platforms/Makefile --- linux-2.4.24/arch/ppc/platforms/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -32,6 +32,7 @@ obj-$(CONFIG_440GP) += ibm440gp.o obj-$(CONFIG_440GX) += ibm440gx.o +obj-$(CONFIG_CPCI405) += cpci405.o obj-$(CONFIG_EBONY) += ebony.o obj-$(CONFIG_OCOTEA) += ocotea.o obj-$(CONFIG_WALNUT) += walnut.o @@ -53,6 +54,8 @@ obj-$(CONFIG_LOPEC) += lopec_setup.o lopec_pci.o obj-$(CONFIG_PAL4) += pal4_setup.o pal4_pci.o cpc700_pic.o obj-$(CONFIG_PPLUS) += pplus_pci.o pplus_setup.o +obj-$(CONFIG_PRPMC750) += prpmc750.o +obj-$(CONFIG_SANDPOINT) += sandpoint.o obj-$(CONFIG_SPRUCE) += spruce_setup.o spruce_pci.o cpc700_pic.o ifeq ($(CONFIG_SMP),y) diff -urN linux-2.4.24/arch/ppc/platforms/cpci405.c linux-2.4.25/arch/ppc/platforms/cpci405.c --- linux-2.4.24/arch/ppc/platforms/cpci405.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/cpci405.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,141 @@ +/* + * arch/ppc/platforms/cpci405.c + * + * Board setup routines for the esd CPCI-405 cPCI Board. + * + * Author: Stefan Roese + * stefan.roese@esd-electronics.com + * + * Copyright 2001-2003 esd electronic system design - hannover germany + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * History: 11/09/2001 - armin + * added board_init to add in additional instuctions needed during platfrom_init + * + * : 03/26/03 - stefan + * Added cpci405_early_serial_map (cloned from evb405ep) to generate + * BASE_BAUD dynamically from the UDIV settings (configured by U-Boot). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void *cpci405_nvram; + +/* + * Some IRQs unique to CPCI-405. + */ +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 15 - cPCI slot 8 */ + {29, 29, 29, 29}, /* IDSEL 16 - cPCI slot 7 */ + {30, 30, 30, 30}, /* IDSEL 17 - cPCI slot 6 */ + {27, 27, 27, 27}, /* IDSEL 18 - cPCI slot 5 */ + {28, 28, 28, 28}, /* IDSEL 19 - cPCI slot 4 */ + {29, 29, 29, 29}, /* IDSEL 20 - cPCI slot 3 */ + {30, 30, 30, 30}, /* IDSEL 21 - cPCI slot 2 */ + }; + const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +/* The serial clock for the chip is an internal clock determined by + * different clock speeds/dividers. + * Calculate the proper input baud rate and setup the serial driver. + */ +static void __init +cpci405_early_serial_map(void) +{ + u32 uart_div; + int serial_baud_405; + bd_t *bip = (bd_t *) __res; + struct serial_struct serialreq = {0}; + + /* Calculate the serial clock input frequency + * + * The base baud is the PLL OUTA (provided in the board info + * structure) divided by the external UART Divisor, divided + * by 16. + */ + uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1; + serial_baud_405 = bip->bi_procfreq / uart_div / 16; + + /* Update the serial port attributes */ + serialreq.baud_base = serial_baud_405; + serialreq.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST); + serialreq.io_type = SERIAL_IO_MEM; + + serialreq.line = 0; + serialreq.port = 0; + serialreq.irq = ACTING_UART0_INT; + serialreq.iomem_base = (void*)ACTING_UART0_IO_BASE; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + /* Configure debug serial access */ + gen550_init(0, &serialreq); +#endif + + if (early_serial_setup(&serialreq) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + serialreq.line = 1; + serialreq.port = 1; + serialreq.irq = ACTING_UART1_INT; + serialreq.iomem_base = (void*)ACTING_UART1_IO_BASE; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + /* Configure debug serial access */ + gen550_init(1, &serialreq); +#endif + + if (early_serial_setup(&serialreq) != 0) { + printk("Early serial init of port 1 failed\n"); + } +} + +void __init +board_setup_arch(void) +{ + cpci405_early_serial_map(); + TODC_INIT(TODC_TYPE_MK48T35, cpci405_nvram, cpci405_nvram, cpci405_nvram, 8); +} + +void __init +board_io_mapping(void) +{ + cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE); +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +} diff -urN linux-2.4.24/arch/ppc/platforms/cpci405.h linux-2.4.25/arch/ppc/platforms/cpci405.h --- linux-2.4.24/arch/ppc/platforms/cpci405.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/cpci405.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,52 @@ +/* + * CPCI-405 board specific definitions + * + * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com) + */ + +#ifdef __KERNEL__ +#ifndef __ASM_CPCI405_H__ +#define __ASM_CPCI405_H__ + +#include + +/* We have a 405GP core */ +#include + +#include + +#ifndef __ASSEMBLY__ +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +/* Map for the NVRAM space */ +#define CPCI405_NVRAM_PADDR ((uint)0xf0200000) +#define CPCI405_NVRAM_SIZE ((uint)32*1024) + +#if defined(CONFIG_UART0_TTYS0) +#define ACTING_UART0_IO_BASE UART0_IO_BASE +#define ACTING_UART1_IO_BASE UART1_IO_BASE +#define ACTING_UART0_INT UART0_INT +#define ACTING_UART1_INT UART1_INT +#else +#define ACTING_UART0_IO_BASE UART1_IO_BASE +#define ACTING_UART1_IO_BASE UART0_IO_BASE +#define ACTING_UART0_INT UART1_INT +#define ACTING_UART1_INT UART0_INT +#endif + +/* The UART clock is based off an internal clock - + * define BASE_BAUD based on the internal clock and divider(s). + * Since BASE_BAUD must be a constant, we will initialize it + * using clock/divider values which U-Boot initializes + * for typical configurations at various CPU speeds. + * The base baud is calculated as (FWDA / EXT UART DIV / 16) + */ +#define BASE_BAUD 0 + +#define PPC4xx_MACHINE_NAME "esd CPCI-405" + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_CPCI405_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.24/arch/ppc/platforms/ebony.c linux-2.4.25/arch/ppc/platforms/ebony.c --- linux-2.4.24/arch/ppc/platforms/ebony.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/ebony.c 2004-02-18 05:36:30.000000000 -0800 @@ -301,7 +301,7 @@ serial_req.baud_base = BASE_BAUD; serial_req.port = 0; serial_req.irq = 0; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = ioremap64(PPC440GP_UART0_ADDR, 8); serial_req.iomem_reg_shift = 0; diff -urN linux-2.4.24/arch/ppc/platforms/ebony.h linux-2.4.25/arch/ppc/platforms/ebony.h --- linux-2.4.24/arch/ppc/platforms/ebony.h 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/ebony.h 2004-02-18 05:36:30.000000000 -0800 @@ -68,7 +68,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, 0, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM}, diff -urN linux-2.4.24/arch/ppc/platforms/gemini_serial.h linux-2.4.25/arch/ppc/platforms/gemini_serial.h --- linux-2.4.24/arch/ppc/platforms/gemini_serial.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/gemini_serial.h 2004-02-18 05:36:30.000000000 -0800 @@ -15,11 +15,11 @@ #define BASE_BAUD (24576000 / 16) #ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) #else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif #define STD_SERIAL_PORT_DEFNS \ diff -urN linux-2.4.24/arch/ppc/platforms/ibm405gp.h linux-2.4.25/arch/ppc/platforms/ibm405gp.h --- linux-2.4.24/arch/ppc/platforms/ibm405gp.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/ibm405gp.h 2004-02-18 05:36:30.000000000 -0800 @@ -108,7 +108,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, 0, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: (u8 *)UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM}, diff -urN linux-2.4.24/arch/ppc/platforms/lopec_serial.h linux-2.4.25/arch/ppc/platforms/lopec_serial.h --- linux-2.4.24/arch/ppc/platforms/lopec_serial.h 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/lopec_serial.h 2004-02-18 05:36:30.000000000 -0800 @@ -33,7 +33,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, UART##num##_PORT, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM }, diff -urN linux-2.4.24/arch/ppc/platforms/lopec_setup.c linux-2.4.25/arch/ppc/platforms/lopec_setup.c --- linux-2.4.24/arch/ppc/platforms/lopec_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/lopec_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -299,7 +299,7 @@ serial_req.line = 0; serial_req.baud_base = BASE_BAUD; serial_req.irq = UART0_INT; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = ioremap(UART0_PORT, 8); diff -urN linux-2.4.24/arch/ppc/platforms/ocotea.c linux-2.4.25/arch/ppc/platforms/ocotea.c --- linux-2.4.24/arch/ppc/platforms/ocotea.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/ocotea.c 2004-02-18 05:36:30.000000000 -0800 @@ -215,7 +215,7 @@ serial_req.baud_base = BASE_BAUD; serial_req.port = 0; serial_req.irq = 0; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = ioremap64(PPC440GX_UART0_ADDR, 8); serial_req.iomem_reg_shift = 0; diff -urN linux-2.4.24/arch/ppc/platforms/ocotea.h linux-2.4.25/arch/ppc/platforms/ocotea.h --- linux-2.4.24/arch/ppc/platforms/ocotea.h 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/ocotea.h 2004-02-18 05:36:30.000000000 -0800 @@ -58,7 +58,7 @@ #define BASE_BAUD 11059200/16 #define STD_UART_OP(num) \ { 0, BASE_BAUD, 0, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM}, diff -urN linux-2.4.24/arch/ppc/platforms/pal4_serial.h linux-2.4.25/arch/ppc/platforms/pal4_serial.h --- linux-2.4.24/arch/ppc/platforms/pal4_serial.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/pal4_serial.h 2004-02-18 05:36:30.000000000 -0800 @@ -20,19 +20,11 @@ #define RS_TABLE_SIZE 2 #define BASE_BAUD (33333333 / 4 / 16) -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) -#endif - #define SERIAL_PORT_DFNS \ - {0, BASE_BAUD, CPC700_SERIAL_1, 3, STD_COM_FLAGS, \ + {0, BASE_BAUD, CPC700_SERIAL_1, 3, ASYNC_BOOT_AUTOCONF, \ iomem_base: (unsigned char *) CPC700_SERIAL_1, \ io_type: SERIAL_IO_MEM}, /* ttyS0 */ \ - {0, BASE_BAUD, CPC700_SERIAL_2, 4, STD_COM_FLAGS, \ + {0, BASE_BAUD, CPC700_SERIAL_2, 4, ASYNC_BOOT_AUTOCONF, \ iomem_base: (unsigned char *) CPC700_SERIAL_2, \ io_type: SERIAL_IO_MEM} diff -urN linux-2.4.24/arch/ppc/platforms/prep_pci.c linux-2.4.25/arch/ppc/platforms/prep_pci.c --- linux-2.4.24/arch/ppc/platforms/prep_pci.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/prep_pci.c 2004-02-18 05:36:30.000000000 -0800 @@ -1141,8 +1141,6 @@ prep_pcibios_fixup(void) { struct pci_dev *dev; - extern unsigned char *Motherboard_map; - extern unsigned char *Motherboard_routes; prep_route_pci_interrupts(); diff -urN linux-2.4.24/arch/ppc/platforms/prpmc750.c linux-2.4.25/arch/ppc/platforms/prpmc750.c --- linux-2.4.24/arch/ppc/platforms/prpmc750.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/prpmc750.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,392 @@ +/* + * arch/ppc/platforms/prpmc750_setup.c + * + * Board setup routines for Motorola PrPMC750 + * + * Author: Matt Porter + * + * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prpmc750_serial.h" + +extern int mpic_init(void); +extern unsigned long loops_per_jiffy; +extern void gen550_progress(char *, unsigned short); + +static u_char prpmc750_openpic_initsenses[] __initdata = +{ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UART */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_DEBUGINT */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HAWK_WDT */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_ABORT */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTC */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTD */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */ +}; + +/* + * Motorola PrPMC750/PrPMC800 in PrPMCBASE or PrPMC-Carrier + * Combined irq tables. Only Base has IDSEL 14, only Carrier has 21 and 22. + */ +static inline int +prpmc_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {12, 0, 0, 0}, /* IDSEL 14 - Ethernet, base */ + {0, 0, 0, 0}, /* IDSEL 15 - unused */ + {10, 11, 12, 9}, /* IDSEL 16 - PMC A1, PMC1 */ + {10, 11, 12, 9}, /* IDSEL 17 - PrPMC-A-B, PMC2-B */ + {11, 12, 9, 10}, /* IDSEL 18 - PMC A1-B, PMC1-B */ + {0, 0, 0, 0}, /* IDSEL 19 - unused */ + {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */ + {11, 12, 9, 10}, /* IDSEL 21 - PMC A2, carrier */ + {12, 9, 10, 11}, /* IDSEL 22 - PMC A2-B, carrier */ + }; + const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static void __init +prpmc750_pcibios_fixup(void) +{ + struct pci_dev *dev; + unsigned short wtmp; + + /* + * Kludge to clean up after PPC6BUG which doesn't + * configure the CL5446 VGA card. Also the + * resource subsystem doesn't fixup the + * PCI mem resources on the CL5446. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_CIRRUS, + PCI_DEVICE_ID_CIRRUS_5446, 0))) + { + dev->resource[0].start += PRPMC750_PCI_PHY_MEM_BASE; + dev->resource[0].end += PRPMC750_PCI_PHY_MEM_BASE; + pci_read_config_word(dev, + PCI_COMMAND, + &wtmp); + pci_write_config_word(dev, + PCI_COMMAND, + wtmp|3); + /* Enable Color mode in MISC reg */ + outb(0x03, 0x3c2); + /* Select DRAM config reg */ + outb(0x0f, 0x3c4); + /* Set proper DRAM config */ + outb(0xdf, 0x3c5); + } +} + +static void __init +prpmc750_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PRPMC750_PCI_PHY_MEM_BASE; + + pci_init_resource(&hose->io_resource, + PRPMC750_PCI_LOWER_IO, + PRPMC750_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + PRPMC750_PCI_LOWER_MEM + PRPMC750_PCI_PHY_MEM_BASE, + PRPMC750_PCI_UPPER_MEM + PRPMC750_PCI_PHY_MEM_BASE, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = PRPMC750_PCI_LOWER_IO; + hose->io_space.end = PRPMC750_PCI_UPPER_IO; + hose->mem_space.start = PRPMC750_PCI_LOWER_MEM; + hose->mem_space.end = PRPMC750_PCI_UPPER_MEM_AUTO; + + hose->io_base_virt = (void *)PRPMC750_ISA_IO_BASE; + + setup_indirect_pci(hose, + PRPMC750_PCI_CONFIG_ADDR, + PRPMC750_PCI_CONFIG_DATA); + + /* + * Disable MPIC response to PCI I/O space (BAR 0). + * Make MPIC respond to PCI Mem space at specified address. + * (BAR 1). + */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_0, + 0x00000000 | 0x1); + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_1, + (PRPMC750_HAWK_MPIC_BASE - + PRPMC750_PCI_MEM_OFFSET) | 0x0); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = prpmc750_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = prpmc_map_irq; +} + +static int +prpmc750_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: PrPMC750\n"); + + return 0; +} + +static void __init +prpmc750_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + prpmc750_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + /* Find and map our OpenPIC */ + pplus_mpic_init(PRPMC750_PCI_MEM_OFFSET); + OpenPIC_InitSenses = prpmc750_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(prpmc750_openpic_initsenses); +} + +/* + * Compute the PrPMC750's bus speed using the baud clock as a + * reference. + */ +static unsigned long __init +prpmc750_get_bus_speed(void) +{ + unsigned long tbl_start, tbl_end; + unsigned long current_state, old_state, bus_speed; + unsigned char lcr, dll, dlm; + int baud_divisor, count; + + /* Read the UART's baud clock divisor */ + lcr = readb(PRPMC750_SERIAL_0_LCR); + writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + dll = readb(PRPMC750_SERIAL_0_DLL); + dlm = readb(PRPMC750_SERIAL_0_DLM); + writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + baud_divisor = (dlm << 8) | dll; + + /* + * Use the baud clock divisor and base baud clock + * to determine the baud rate and use that as + * the number of baud clock edges we use for + * the time base sample. Make it half the baud + * rate. + */ + count = PRPMC750_BASE_BAUD / (baud_divisor * 16); + + /* Find the first edge of the baud clock */ + old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK; + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + + old_state = current_state; + + /* Get the starting time base value */ + tbl_start = get_tbl(); + + /* + * Loop until we have found a number of edges equal + * to half the count (half the baud rate) + */ + do { + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + old_state = current_state; + } while (--count); + + /* Get the ending time base value */ + tbl_end = get_tbl(); + + /* Compute bus speed */ + bus_speed = (tbl_end-tbl_start)*128; + + return bus_speed; +} + +static void __init +prpmc750_calibrate_decr(void) +{ + unsigned long freq; + int divisor = 4; + + freq = prpmc750_get_bus_speed(); + + tb_ticks_per_jiffy = freq / (HZ * divisor); + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static void +prpmc750_restart(char *cmd) +{ + __cli(); + writeb(PRPMC750_MODRST_MASK, PRPMC750_MODRST_REG); + while(1); +} + +static void +prpmc750_halt(void) +{ + __cli(); + while (1); +} + +static void +prpmc750_power_off(void) +{ + prpmc750_halt(); +} + +static void __init +prpmc750_init_IRQ(void) +{ + openpic_init(0); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +prpmc750_set_bat(void) +{ + mb(); + mtspr(DBAT1U, 0xf0001ffe); + mtspr(DBAT1L, 0xf000002a); + mb(); +} + +/* + * We need to read the Falcon/Hawk memory controller + * to properly determine this value + */ +static unsigned long __init +prpmc750_find_end_of_memory(void) +{ + /* Read the memory size from the Hawk SMC */ + return pplus_get_mem_size(PRPMC750_HAWK_SMC_BASE); +} + +static void __init +prpmc750_map_io(void) +{ + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO); + io_block_mapping(0xf8000000, 0xf8000000, 0x08000000, _PAGE_IO); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = PRPMC750_ISA_IO_BASE; + isa_mem_base = PRPMC750_ISA_MEM_BASE; + pci_dram_offset = PRPMC750_SYS_MEM_BASE; + + prpmc750_set_bat(); + + ppc_md.setup_arch = prpmc750_setup_arch; + ppc_md.show_cpuinfo = prpmc750_show_cpuinfo; + ppc_md.init_IRQ = prpmc750_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.find_end_of_memory = prpmc750_find_end_of_memory; + ppc_md.setup_io_mappings = prpmc750_map_io; + + ppc_md.restart = prpmc750_restart; + ppc_md.power_off = prpmc750_power_off; + ppc_md.halt = prpmc750_halt; + + /* PrPMC750 has no timekeeper part */ + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.calibrate_decr = prpmc750_calibrate_decr; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = gen550_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +} diff -urN linux-2.4.24/arch/ppc/platforms/prpmc750.h linux-2.4.25/arch/ppc/platforms/prpmc750.h --- linux-2.4.24/arch/ppc/platforms/prpmc750.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/prpmc750.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,65 @@ +/* + * include/asm-ppc/platforms/prpmc750.h + * + * Definitions for Motorola PrPMC750 board support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_PRPMC750_H__ +#define __ASM_PRPMC750_H__ + +#include + +#define PRPMC750_PCI_CONFIG_ADDR 0x80000cf8 +#define PRPMC750_PCI_CONFIG_DATA 0x80000cfc + +#define PRPMC750_PCI_PHY_MEM_BASE 0xc0000000 +#define PRPMC750_PCI_MEM_BASE 0xf0000000 +#define PRPMC750_PCI_IO_BASE 0x80000000 + +#define PRPMC750_ISA_IO_BASE PRPMC750_PCI_IO_BASE +#define PRPMC750_ISA_MEM_BASE PRPMC750_PCI_MEM_BASE +#define PRPMC750_PCI_MEM_OFFSET PRPMC750_PCI_PHY_MEM_BASE + +#define PRPMC750_SYS_MEM_BASE 0x80000000 + +#define PRPMC750_PCI_LOWER_MEM 0x00000000 +#define PRPMC750_PCI_UPPER_MEM_AUTO 0x3bf7ffff +#define PRPMC750_PCI_UPPER_MEM 0x3bffffff +#define PRPMC750_PCI_LOWER_IO 0x00000000 +#define PRPMC750_PCI_UPPER_IO 0x0ff7ffff + +#define PRPMC750_HAWK_MPIC_BASE 0xfbf80000 +#define PRPMC750_HAWK_SMC_BASE 0xfef80000 + +#define PRPMC750_BASE_BAUD 1843200 +#define PRPMC750_SERIAL_0 0xfef88000 +#define PRPMC750_SERIAL_0_DLL (PRPMC750_SERIAL_0 + (UART_DLL << 4)) +#define PRPMC750_SERIAL_0_DLM (PRPMC750_SERIAL_0 + (UART_DLM << 4)) +#define PRPMC750_SERIAL_0_LCR (PRPMC750_SERIAL_0 + (UART_LCR << 4)) + +#define PRPMC750_STATUS_REG 0xfef88080 +#define PRPMC750_BAUDOUT_MASK 0x02 +#define PRPMC750_MONARCH_MASK 0x01 + +#define PRPMC750_MODRST_REG 0xfef880a0 +#define PRPMC750_MODRST_MASK 0x01 + +#define PRPMC750_PIRQ_REG 0xfef880b0 +#define PRPMC750_SEL1_MASK 0x02 +#define PRPMC750_SEL0_MASK 0x01 + +#define PRPMC750_TBEN_REG 0xfef880c0 +#define PRPMC750_TBEN_MASK 0x01 + +#endif /* __ASM_PRPMC750_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.24/arch/ppc/platforms/prpmc750_serial.h linux-2.4.25/arch/ppc/platforms/prpmc750_serial.h --- linux-2.4.24/arch/ppc/platforms/prpmc750_serial.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/prpmc750_serial.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,39 @@ +/* + * include/asm-ppc/platforms/prpmc750_serial.h + * + * Motorola PrPMC750 serial support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_PRPMC750_SERIAL_H__ +#define __ASM_PRPMC750_SERIAL_H__ + +#include +#include + +#define RS_TABLE_SIZE 4 + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (PRPMC750_BASE_BAUD / 16) + +#ifndef SERIAL_MAGIC_KEY +#define kernel_debugger ppc_kernel_debug +#endif + +#define SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, PRPMC750_SERIAL_0, 1, ASYNC_SKIP_TEST, \ + iomem_base: (unsigned char *)PRPMC750_SERIAL_0, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM } /* ttyS0 */ + +#endif /* __ASM_PRPMC750_SERIAL_H__ */ +#endif /* __KERNEL__ */ diff -urN linux-2.4.24/arch/ppc/platforms/sandpoint.c linux-2.4.25/arch/ppc/platforms/sandpoint.c --- linux-2.4.24/arch/ppc/platforms/sandpoint.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/sandpoint.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,742 @@ +/* + * arch/ppc/platforms/sandpoint.c + * + * Board setup routines for the Motorola SPS Sandpoint Test Platform. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * 2000-2003 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +/* + * This file adds support for the Motorola SPS Sandpoint Test Platform. + * These boards have a PPMC slot for the processor so any combination + * of cpu and host bridge can be attached. This port is for an 8240 PPMC + * module from Motorola SPS and other closely related cpu/host bridge + * combinations (e.g., 750/755/7400 with MPC107 host bridge). + * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2 + * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a + * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr), + * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V + * but are really 5V). + * + * The firmware on the sandpoint is called DINK (not my acronym :). This port + * depends on DINK to do some basic initialization (e.g., initialize the memory + * ctlr) and to ensure that the processor is using MAP B (CHRP map). + * + * The switch settings for the Sandpoint board MUST be as follows: + * S3: down + * S4: up + * S5: up + * S6: down + * + * 'down' is in the direction from the PCI slots towards the PPMC slot; + * 'up' is in the direction from the PPMC slot towards the PCI slots. + * Be careful, the way the sandpoint board is installed in XT chasses will + * make the directions reversed. + * + * Since Motorola listened to our suggestions for improvement, we now have + * the Sandpoint X3 board. All of the PCI slots are available, it uses + * the serial interrupt interface (just a hardware thing we need to + * configure properly). + * + * Use the default X3 switch settings. The interrupts are then: + * EPIC Source + * 0 SIOINT (8259, active low) + * 1 PCI #1 + * 2 PCI #2 + * 3 PCI #3 + * 4 PCI #4 + * 7 Winbond INTC (IDE interrupt) + * 8 Winbond INTD (IDE interrupt) + * + * It is important to note that this code only supports the Sandpoint X3 + * (all flavors) platform, and it does not support the X2 anymore. Code + * that at one time worked on the X2 can be found at: + * ftp://source.mvista.com/pub/linuxppc/obsolete/sandpoint/ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sandpoint_serial.h" + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +extern void gen550_progress(char *, unsigned short); +extern void gen550_init(int, struct serial_struct *); + +unsigned char __res[sizeof (bd_t)]; + +static void sandpoint_halt(void); + +/* + * Define all of the IRQ senses and polarities. Taken from the + * Sandpoint X3 User's manual. + */ +static u_char sandpoint_openpic_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 0: SIOINT */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 2: PCI Slot 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 3: PCI Slot 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 4: PCI Slot 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 5: PCI Slot 4 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 8: IDE (INT C) */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE) /* 9: IDE (INT D) */ +}; + +/* + * Motorola SPS Sandpoint interrupt routing. + */ +static inline int +sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {16, 0, 0, 0}, /* IDSEL 11 - i8259 on Windbond */ + { 0, 0, 0, 0}, /* IDSEL 12 - unused */ + {17, 18, 19, 20}, /* IDSEL 13 - PCI slot 1 */ + {18, 19, 20, 17}, /* IDSEL 14 - PCI slot 2 */ + {19, 20, 17, 18}, /* IDSEL 15 - PCI slot 3 */ + {20, 17, 18, 19}, /* IDSEL 16 - PCI slot 4 */ + }; + + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static void __init +sandpoint_setup_winbond_83553(struct pci_controller *hose) +{ + int devfn; + + /* + * Route IDE interrupts directly to the 8259's IRQ 14 & 15. + * We can't route the IDE interrupt to PCI INTC# or INTD# because those + * woule interfere with the PMC's INTC# and INTD# lines. + */ + /* + * Winbond Fcn 0 + */ + devfn = PCI_DEVFN(11, 0); + + /* IDE Interrupt Routing Control */ + early_write_config_byte(hose, 0, devfn, 0x43, 0xef); + + /* PCI Interrupt Routing Control */ + early_write_config_word(hose, 0, devfn, 0x44, 0x0000); + + /* Want ISA memory cycles to be forwarded to PCI bus. + * ISA-to-PCI Addr Decoder Control. + */ + early_write_config_byte(hose, 0, devfn, 0x48, 0xf0); + + /* Enable RTC and Keyboard address locations. */ + early_write_config_byte(hose, 0, devfn, 0x4d, 0x00); + + /* Enable Port 92. */ + early_write_config_byte(hose, 0, devfn, 0x4e, 0x06); + + /* + * Winbond Fcn 1 + */ + devfn = PCI_DEVFN(11, 1); + + /* Put IDE controller into native mode (via PIR). */ + early_write_config_byte(hose, 0, devfn, 0x09, 0x8f); + + /* Init IRQ routing, enable both ports, disable fast 16, via + * IDE Control/Status Register. + */ + early_write_config_dword(hose, 0, devfn, 0x40, 0x00ff0011); +} + +static void __init +sandpoint_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, MPC10X_MAPB_EUMB_BASE) == 0) { + + /* Do early winbond init, then scan PCI bus */ + sandpoint_setup_winbond_83553(hose); + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = sandpoint_map_irq; + } else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + + return; +} + +#ifdef CONFIG_SERIAL +static void __init +sandpoint_early_serial_map(void) +{ + struct serial_struct serial_req; + + /* Setup serial port access */ + memset(&serial_req, 0, sizeof (serial_req)); + serial_req.baud_base = BASE_BAUD; + serial_req.line = 0; + serial_req.port = 0; + serial_req.irq = 4; + serial_req.flags = ASYNC_BOOT_AUTOCONF; + serial_req.io_type = SERIAL_IO_MEM; + serial_req.iomem_base = (u_char *) SANDPOINT_SERIAL_0; + serial_req.iomem_reg_shift = 0; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(0, &serial_req); +#endif + + if (early_serial_setup(&serial_req) != 0) + printk("Early serial init of port 0 failed\n"); + + /* Assume early_serial_setup() doesn't modify serial_req */ + serial_req.line = 1; + serial_req.port = 1; + serial_req.irq = 3; /* XXXX */ + serial_req.iomem_base = (u_char *) SANDPOINT_SERIAL_1; + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) + gen550_init(1, &serial_req); +#endif + + if (early_serial_setup(&serial_req) != 0) + printk("Early serial init of port 1 failed\n"); +} +#endif + +static void __init +sandpoint_setup_arch(void) +{ + loops_per_jiffy = 100000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0301); /* /dev/hda1 IDE disk */ +#endif + + /* Lookup PCI host bridges */ + sandpoint_find_bridges(); + +#ifdef CONFIG_SERIAL + sandpoint_early_serial_map(); +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n"); + + /* DINK32 12.3 and below do not correctly enable any caches. + * We will do this now with good known values. Future versions + * of DINK32 are supposed to get this correct. + */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) + /* 745x is different. We only want to pass along enable. */ + _set_L2CR(L2CR_L2E); + else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) + /* All modules have 1MB of L2. We also assume that an + * L2 divisor of 3 will work. + */ + _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3 + | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); +#if 0 + /* Untested right now. */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) { + /* Magic value. */ + _set_L3CR(0x8f032000); + } +#endif +} + +#define SANDPOINT_87308_CFG_ADDR 0x15c +#define SANDPOINT_87308_CFG_DATA 0x15d + +#define SANDPOINT_87308_CFG_INB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + (byte) = inb(SANDPOINT_87308_CFG_DATA); \ +} + +#define SANDPOINT_87308_CFG_OUTB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + outb((byte), SANDPOINT_87308_CFG_DATA); \ +} + +#define SANDPOINT_87308_SELECT_DEV(dev_num) { \ + SANDPOINT_87308_CFG_OUTB(0x07, (dev_num)); \ +} + +#define SANDPOINT_87308_DEV_ENABLE(dev_num) { \ + SANDPOINT_87308_SELECT_DEV(dev_num); \ + SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \ +} + +/* + * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip. + */ +static void __init +sandpoint_setup_natl_87308(void) +{ + u_char reg; + + /* + * Enable all the devices on the Super I/O chip. + */ + SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */ + SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */ + SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */ + SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */ + SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */ + SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */ + SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + + /* Set up floppy in PS/2 mode */ + outb(0x09, SIO_CONFIG_RA); + reg = inb(SIO_CONFIG_RD); + reg = (reg & 0x3F) | 0x40; + outb(reg, SIO_CONFIG_RD); + outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ + + return; +} + +/* + * Fix IDE interrupts. + */ +static void __init +sandpoint_fix_winbond_83553(void) +{ + /* Make all 8259 interrupt level sensitive */ + outb(0xf8, 0x4d0); + outb(0xde, 0x4d1); + + return; +} + +static void __init +sandpoint_init2(void) +{ + /* Do Sandpoint board specific initialization. */ + sandpoint_fix_winbond_83553(); + sandpoint_setup_natl_87308(); + + request_region(0x00, 0x20, "dma1"); + request_region(0x20, 0x20, "pic1"); + request_region(0x40, 0x20, "timer"); + request_region(0x80, 0x10, "dma page reg"); + request_region(0xa0, 0x20, "pic2"); + request_region(0xc0, 0x20, "dma2"); + + return; +} + +/* + * Interrupt setup and service. The i8259 is cascaded from EPIC IRQ0, + * IRQ1-4 map to PCI slots 1-4, IDE is on EPIC 7 and 8. + */ +static void __init +sandpoint_init_IRQ(void) +{ + int i; + + OpenPIC_InitSenses = sandpoint_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof (sandpoint_openpic_initsenses); + + /* + * We need to tell openpic_set_sources where things actually are. + * mpc10x_common will setup OpenPIC_Addr at ioremap(EUMB phys base + + * EPIC offset (0x40000)); The EPIC IRQ Register Address Map - + * Interrupt Source Configuration Registers gives these numbers + * as offsets starting at 0x50200, we need to adjust occordinly. + */ + + /* Map serial interrupt 0 */ + openpic_set_sources(0, 1, OpenPIC_Addr + 0x10200); + /* Map serial interrupts 2-5 */ + openpic_set_sources(1, 4, OpenPIC_Addr + 0x10240); + /* Map serial interrupts 8-9 */ + openpic_set_sources(5, 2, OpenPIC_Addr + 0x10300); + /* Skip reserved space and map i2c and DMA Ch[01] */ + openpic_set_sources(7, 3, OpenPIC_Addr + 0x11020); + /* Skip reserved space and map Message Unit Interrupt (I2O) */ + openpic_set_sources(10, 1, OpenPIC_Addr + 0x110C0); + + openpic_init(NUM_8259_INTERRUPTS); + /* The cascade is on EPIC IRQ 0 (Linux IRQ 16). */ + openpic_hookup_cascade(16, "8259 cascade to EPIC", &i8259_irq); + + /* + * openpic_init() has set up irq_desc[0-23] to be openpic + * interrupts. We need to set irq_desc[0-15] to be 8259 interrupts. + * We then need to request and enable the 8259 irq. + */ + for (i = 0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + /* + * The EPIC allows for a read in the range of 0xFEF00000 -> + * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. + */ + i8259_init(0xfef00000); +} + +static u32 +sandpoint_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + return 9; + else + return irq; +} + +static unsigned long __init +sandpoint_find_end_of_memory(void) +{ + bd_t *bp = (bd_t *) __res; + + if (bp->bi_memsize) + return bp->bi_memsize; + + /* This might be fixed in DINK32 12.4, or we'll have another + * way to determine the correct memory size anyhow. */ + /* return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); */ + return 32 * 1024 * 1024; +} + +static void __init +sandpoint_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +static void +sandpoint_restart(char *cmd) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + /* Reset system via Port 92 */ + outb(0x00, 0x92); + outb(0x01, 0x92); + for (;;) ; /* Spin until reset happens */ +} + +static void +sandpoint_power_off(void) +{ + __cli(); + for (;;) ; /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +sandpoint_halt(void) +{ + sandpoint_power_off(); + /* NOTREACHED */ +} + +static int +sandpoint_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Motorola SPS\n"); + seq_printf(m, "machine\t\t: Sandpoint\n"); + + return 0; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int sandpoint_ide_ports_known = 0; +static ide_ioreg_t sandpoint_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_idedma_regbase; + +static void +sandpoint_ide_probe(void) +{ + struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, + NULL); + + if (pdev) { + sandpoint_ide_regbase[0] = pdev->resource[0].start; + sandpoint_ide_regbase[1] = pdev->resource[2].start; + sandpoint_ide_ctl_regbase[0] = pdev->resource[1].start; + sandpoint_ide_ctl_regbase[1] = pdev->resource[3].start; + sandpoint_idedma_regbase = pdev->resource[4].start; + } + + sandpoint_ide_ports_known = 1; + return; +} + +/* The Sandpoint X3 allows the IDE interrupt to be directly connected + * from the Windbond (PCI INTC or INTD) to the serial EPIC. Someday + * we should try this, but it was easier to use the existing 83c553 + * initialization than change it to route the different interrupts :-). + * -- Dan + */ +#if 0 +#define SANDPOINT_IDE_INT0 23 /* EPIC 7 */ +#define SANDPOINT_IDE_INT1 24 /* EPIC 8 */ +#else +#define SANDPOINT_IDE_INT0 14 /* 8259 Test */ +#define SANDPOINT_IDE_INT1 15 /* 8259 Test */ +#endif +static int +sandpoint_ide_default_irq(ide_ioreg_t base) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + if (base == sandpoint_ide_regbase[0]) + return SANDPOINT_IDE_INT0; + else if (base == sandpoint_ide_regbase[1]) + return SANDPOINT_IDE_INT1; + else + return 0; +} + +static ide_ioreg_t +sandpoint_ide_default_io_base(int index) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + return sandpoint_ide_regbase[index]; +} + +static void __init +sandpoint_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + unsigned int alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) + hw->io_ports[i] = reg++; + + if (data_port == sandpoint_ide_regbase[0]) { + alt_status_base = sandpoint_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } else if (data_port == sandpoint_ide_regbase[1]) { + alt_status_base = sandpoint_ide_ctl_regbase[1] + 2; + hw->irq = 15; + } else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + + if (irq != NULL) + *irq = hw->irq; + + return; +} +#endif + +/* + * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. + */ +static __inline__ void +sandpoint_set_bat(void) +{ +#if 1 + mb(); + mtspr(DBAT1U, 0xf8000ffe); + mtspr(DBAT1L, 0xf800002a); + mb(); +#else + unsigned long bat3u, bat3l; + + __asm__ __volatile__(" lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync ":"=r"(bat3u), "=r"(bat3l)); +#endif +} + +TODC_ALLOC(); + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) + * are non-zero, then we should use the board info from the bd_t + * structure and the cmdline pointed to by r6 instead of the + * information from birecs, if any. Otherwise, use the information + * from birecs as discovered by the preceeding call to + * parse_bootinfo(). This rule should work with both PPCBoot, which + * uses a bd_t board info structure, and the kernel boot wrapper, + * which uses birecs. + */ + if (r3 && r6) { + /* copy board info structure */ + memcpy((void *) __res, (void *) (r3 + KERNELBASE), + sizeof (bd_t)); + /* copy command line */ + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } +#ifdef CONFIG_BLK_DEV_INITRD + /* take care of initrd if we have one */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Map in board regs, etc. */ + sandpoint_set_bat(); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = sandpoint_setup_arch; + ppc_md.show_cpuinfo = sandpoint_show_cpuinfo; + ppc_md.irq_cannonicalize = sandpoint_irq_cannonicalize; + ppc_md.init_IRQ = sandpoint_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = sandpoint_init2; + + ppc_md.restart = sandpoint_restart; + ppc_md.power_off = sandpoint_power_off; + ppc_md.halt = sandpoint_halt; + + ppc_md.find_end_of_memory = sandpoint_find_end_of_memory; + ppc_md.setup_io_mappings = sandpoint_map_io; + + TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8); + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_mc146818_read_val; + ppc_md.nvram_write_val = todc_mc146818_write_val; + +#ifdef CONFIG_SERIAL +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = gen550_progress; +#endif + ppc_md.early_serial_map = sandpoint_early_serial_map; +#endif + +#ifdef CONFIG_VT + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = sandpoint_ide_default_irq; + ppc_ide_md.default_io_base = sandpoint_ide_default_io_base; + ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports; +#endif + + return; +} diff -urN linux-2.4.24/arch/ppc/platforms/sandpoint_serial.h linux-2.4.25/arch/ppc/platforms/sandpoint_serial.h --- linux-2.4.24/arch/ppc/platforms/sandpoint_serial.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc/platforms/sandpoint_serial.h 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,47 @@ +/* + * include/asm-ppc/sandpoint_serial.h + * + * Definitions for Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_SANDPOINT_SERIAL_H +#define __ASMPPC_SANDPOINT_SERIAL_H + +#include + +#define SANDPOINT_SERIAL_0 0xfe0003f8 +#define SANDPOINT_SERIAL_1 0xfe0002f8 + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 2 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 1843200 / 16 ) + +#define STD_SERIAL_PORT_DFNS \ + /* ttyS0 */ \ + { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, ASYNC_BOOT_AUTOCONF, \ + iomem_base: (u8 *)SANDPOINT_SERIAL_0, \ + io_type: SERIAL_IO_MEM }, \ + /* ttyS1 */ \ + { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, ASYNC_BOOT_AUTOCONF, \ + iomem_base: (u8 *)SANDPOINT_SERIAL_1, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_SANDPOINT_SERIAL_H */ diff -urN linux-2.4.24/arch/ppc/platforms/spruce.h linux-2.4.25/arch/ppc/platforms/spruce.h --- linux-2.4.24/arch/ppc/platforms/spruce.h 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/spruce.h 2004-02-18 05:36:30.000000000 -0800 @@ -70,7 +70,7 @@ #define STD_UART_OP(num) \ { 0, BASE_BAUD, 0, UART##num##_INT, \ - (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + ASYNC_BOOT_AUTOCONF, \ iomem_base: UART##num##_IO_BASE, \ io_type: SERIAL_IO_MEM}, diff -urN linux-2.4.24/arch/ppc/platforms/spruce_setup.c linux-2.4.25/arch/ppc/platforms/spruce_setup.c --- linux-2.4.24/arch/ppc/platforms/spruce_setup.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc/platforms/spruce_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -132,7 +132,7 @@ serial_req.line = 0; serial_req.port = 0; serial_req.irq = 3; - serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_BOOT_AUTOCONF; serial_req.io_type = SERIAL_IO_MEM; serial_req.iomem_base = (u_char *)UART0_IO_BASE; serial_req.iomem_reg_shift = 0; diff -urN linux-2.4.24/arch/ppc64/Makefile linux-2.4.25/arch/ppc64/Makefile --- linux-2.4.24/arch/ppc64/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -19,11 +19,11 @@ CHECKS = checks endif -HAS_BIARCH := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;) +HAS_BIARCH := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;) ifeq ($(HAS_BIARCH),y) AS := $(AS) -64 LD := $(LD) -m elf64ppc -CC := gcc -m64 +CC := $(CC) -m64 endif LINKFLAGS = -T arch/ppc64/vmlinux.lds -Bstatic \ @@ -33,6 +33,11 @@ -mtraceback=full CPP = $(CC) -E $(CFLAGS) +HAVE_ZERO_BSS := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi) + +ifeq ($(HAVE_ZERO_BSS),y) +CFLAGS += -fno-zero-initialized-in-bss +endif HEAD := arch/ppc64/kernel/head.o @@ -45,10 +50,6 @@ SUBDIRS += arch/ppc64/xmon CORE_FILES += arch/ppc64/xmon/x.o endif -ifdef CONFIG_KDB -SUBDIRS += arch/ppc64/kdb -CORE_FILES += arch/ppc64/kdb/kdba.o -endif MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot diff -urN linux-2.4.24/arch/ppc64/boot/Makefile linux-2.4.25/arch/ppc64/boot/Makefile --- linux-2.4.24/arch/ppc64/boot/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/boot/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -31,6 +31,10 @@ OBJCOPYFLAGS = contents,alloc,load,readonly,data +LDVARS= \ + --defsym _vmlinux_memsize=0x`$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | sed '$$s/^........\([^ ]*\).*/\1/p;d'` \ + --defsym _vmlinux_filesize=0x`ls -l $(TOPDIR)/vmlinux | awk '{ printf "%x\n", $$5 }'` + .c.o: $(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $< .S.o: @@ -39,7 +43,7 @@ CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS LD_ARGS = -Ttext 0x00400000 -e _start -OBJS = crt0.o string.o prom.o zImage.o zlib.o imagesize.o +OBJS = crt0.o string.o prom.o zImage.o zlib.o LIBS = ifeq ($(CONFIG_SMP),y) @@ -88,12 +92,13 @@ $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c -imagesize.c: $(TOPDIR)/vmlinux - ls -l $(TOPDIR)/vmlinux | awk '{printf "/* generated -- do not edit! */\nunsigned long vmlinux_filesize = %d;\n", $$5}' > imagesize.c - $(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | awk '{i=$$1}END{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr(i,8)}' >> imagesize.c - zImage.o: $(TOPDIR)/vmlinux +uts_string: uts_string.txt + $(OBJCOPY) zImage.o \ + --add-section=.kernel:$@=$@.txt \ + --set-section-flags=.kernel:$@=$(OBJCOPYFLAGS) + vmlinux .config System.map: % : $(TOPDIR)/% zImage.o gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz $(OBJCOPY) zImage.o \ @@ -105,17 +110,23 @@ --add-section=.kernel:$@=ramdisk.image.gz \ --set-section-flags=.kernel:$@=$(OBJCOPYFLAGS) -zImage: $(OBJS) addnote vmlinux .config System.map - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) +uts_string.txt: $(TOPDIR)/vmlinux + strings $(TOPDIR)/vmlinux | \ + grep -E 'Linux version .* .gcc version' > $@ + +zImage: $(OBJS) addnote uts_string vmlinux .config System.map + $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \ + $(LDVARS) ./addnote $@ -zImage.initrd: $(OBJS) addnote vmlinux .config System.map initrd - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) +zImage.initrd: $(OBJS) addnote uts_string vmlinux .config System.map initrd + $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \ + $(LDVARS) ./addnote $@ clean: rm -f add{note,RamDisk,SystemMap} $(OBJS) initrd.o \ - vmlinux.{sm,initrd} zImage{,.initrd} imagesize.c \ + vmlinux.{sm,initrd} zImage{,.initrd} uts_string.txt \ kernel-{vmlinux,.config,System.map}.gz fastdep: diff -urN linux-2.4.24/arch/ppc64/boot/ppc32-types.h linux-2.4.25/arch/ppc64/boot/ppc32-types.h --- linux-2.4.24/arch/ppc64/boot/ppc32-types.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/boot/ppc32-types.h 2004-02-18 05:36:30.000000000 -0800 @@ -27,4 +27,10 @@ #define BITS_PER_LONG 32 +typedef struct { + __u32 u[4]; +} __attribute((aligned(16))) __vector128; + +typedef __vector128 vector128; + #endif /* _PPC64_TYPES_H */ diff -urN linux-2.4.24/arch/ppc64/boot/zImage.c linux-2.4.25/arch/ppc64/boot/zImage.c --- linux-2.4.24/arch/ppc64/boot/zImage.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc64/boot/zImage.c 2004-02-18 05:36:30.000000000 -0800 @@ -12,7 +12,6 @@ #include "ppc32-types.h" #include "zlib.h" #include -#include #include #include #include @@ -53,8 +52,9 @@ extern char _sysmap_end[]; extern char _initrd_start[]; extern char _initrd_end[]; -extern unsigned long vmlinux_filesize; -extern unsigned long vmlinux_memsize; + +extern void *_vmlinux_filesize; +extern void *_vmlinux_memsize; struct addr_range { unsigned long addr; @@ -69,8 +69,8 @@ static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ typedef void (*kernel_entry_t)( unsigned long, - unsigned long, - void *, + unsigned long, + void *, struct bi_record *); @@ -86,13 +86,12 @@ start(unsigned long a1, unsigned long a2, void *promptr) { unsigned long i, claim_addr, claim_size; + unsigned long vmlinux_filesize; extern char _start; struct bi_record *bi_recs; kernel_entry_t kernel_entry; Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; - /* tell userland tools about uname -r */ - unsigned char this_uts[] = "Linux version " UTS_RELEASE; prom = (int (*)(void *)) promptr; chosen_handle = finddevice("/chosen"); @@ -104,20 +103,7 @@ if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); - printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start); - printf("%s\n\r", this_uts); - -#if 0 - sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start); - sysmap.memsize = sysmap.size; - if ( sysmap.size > 0 ) { - sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF; - claim(sysmap.addr, RAM_END - sysmap.addr, 0); - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", - sysmap.addr, (unsigned long)_sysmap_start, sysmap.size); - memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size); - } -#endif + printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)&_start); initrd.size = (unsigned long)(_initrd_end - _initrd_start); initrd.memsize = initrd.size; @@ -133,12 +119,13 @@ vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); vmlinux.addr = (unsigned long)(void *)-1; + vmlinux_filesize = (unsigned long)&_vmlinux_filesize; vmlinux.size = PAGE_ALIGN(vmlinux_filesize); - vmlinux.memsize = vmlinux_memsize; + vmlinux.memsize = (unsigned long)&_vmlinux_memsize; claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */; - for(claim_addr = PROG_START; - claim_addr <= PROG_START * 8; + for(claim_addr = PROG_START; + claim_addr <= PROG_START * 8; claim_addr += 0x100000) { printf(" trying: 0x%08lx\n\r", claim_addr); vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0); diff -urN linux-2.4.24/arch/ppc64/boot/zImage.lds linux-2.4.25/arch/ppc64/boot/zImage.lds --- linux-2.4.24/arch/ppc64/boot/zImage.lds 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/boot/zImage.lds 2004-02-18 05:36:30.000000000 -0800 @@ -58,6 +58,8 @@ CONSTRUCTORS } + .kernel:uts_string : { *(.kernel:uts_string) } + . = ALIGN(4096); _vmlinux_start = .; .kernel:vmlinux : { *(.kernel:vmlinux) } diff -urN linux-2.4.24/arch/ppc64/config.in linux-2.4.25/arch/ppc64/config.in --- linux-2.4.24/arch/ppc64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -25,7 +25,7 @@ choice 'Machine Type' \ "pSeries CONFIG_PPC_PSERIES \ iSeries CONFIG_PPC_ISERIES" CONFIG_PPC_PSERIES - +bool 'VMX ( AltiVec ) Support' CONFIG_ALTIVEC bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS @@ -48,6 +48,8 @@ bool 'Shared kernel/user space addressing' CONFIG_SHARED_MEMORY_ADDRESSING +bool 'LPAR Configuration Data' CONFIG_LPARCFG + endmenu mainmenu_option next_comment @@ -120,7 +122,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -245,15 +246,8 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ bool 'Include kgdb kernel debugger' CONFIG_KGDB bool 'Include xmon kernel debugger' CONFIG_XMON -bool 'Include kdb kernel debugger' CONFIG_KDB bool 'Debug memory allocations' CONFIG_DEBUG_SLAB -if [ "$CONFIG_KDB" = "y" ]; then - bool ' KDB off by default' CONFIG_KDB_OFF - define_bool CONFIG_KALLSYMS y - define_bool CONFIG_XMON n -fi if [ "$CONFIG_XMON" = "y" ]; then - define_bool CONFIG_KDB n define_bool CONFIG_KALLSYMS n fi bool 'Include PPCDBG realtime debugging' CONFIG_PPCDBG diff -urN linux-2.4.24/arch/ppc64/configs/iSeries_devfs_defconfig linux-2.4.25/arch/ppc64/configs/iSeries_devfs_defconfig --- linux-2.4.24/arch/ppc64/configs/iSeries_devfs_defconfig 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/configs/iSeries_devfs_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -21,9 +21,13 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_PPC_PSERIES is not set CONFIG_PPC_ISERIES=y +# CONFIG_ALTIVEC is not set CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 CONFIG_MSCHUNKS=y +# CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -40,6 +44,7 @@ # CONFIG_MCA is not set # CONFIG_EISA is not set CONFIG_PCI=y +# CONFIG_PCMCIA is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -50,7 +55,6 @@ CONFIG_BINFMT_MISC=y CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set # # Parallel port support @@ -58,18 +62,6 @@ # CONFIG_PARPORT is not set # -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set - -# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -77,12 +69,16 @@ # 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=8192 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -101,8 +97,6 @@ # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -117,17 +111,30 @@ # 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 # 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 @@ -143,7 +150,16 @@ # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -# CONFIG_BLK_DEV_IDE_MODES 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 # @@ -180,13 +196,16 @@ # 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 @@ -201,6 +220,7 @@ # 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 @@ -216,9 +236,8 @@ # 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 -# CONFIG_SCSI_MESH is not set -# CONFIG_SCSI_MAC53C94 is not set # # IEEE 1394 (FireWire) support (EXPERIMENTAL) @@ -247,12 +266,10 @@ # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_OAKNET is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -262,14 +279,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -281,11 +302,14 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -295,11 +319,15 @@ CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I 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_VETH=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -317,7 +345,12 @@ CONFIG_TR=y CONFIG_IBMOL=m # CONFIG_IBMLS is not set +# CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -333,11 +366,6 @@ # CONFIG_HAMRADIO is not set # -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # ISDN subsystem # # CONFIG_ISDN is not set @@ -348,15 +376,6 @@ # CONFIG_CD_NO_IDESCSI is not set # -# Console drivers -# - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# # iSeries device drivers # CONFIG_VIOCONS=y @@ -386,6 +405,7 @@ # 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 @@ -442,12 +462,19 @@ # CONFIG_INPUT_GAMECON is not set # CONFIG_INPUT_TURBOGRAFX 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_INTEL_RNG 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_DTLK is not set @@ -459,22 +486,33 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set -# CONFIG_MWAVE 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=y # CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y # 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 is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -484,11 +522,14 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y -# CONFIG_MINIX_FS is not set +# CONFIG_ZISOFS is not set # 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 @@ -507,16 +548,24 @@ # 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 is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -530,6 +579,7 @@ # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set # # Partition Types @@ -564,6 +614,7 @@ # 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 @@ -581,114 +632,16 @@ # CONFIG_NLS_UTF8 is not set # -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# 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_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_WACOM is not set - -# -# USB Imaging devices -# -# 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 - -# -# USB Multimedia devices -# -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_PWC is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS 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 - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Library routines # -# CONFIG_USB_SERIAL 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_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set # -# USB Miscellaneous drivers +# Cryptographic options # -# CONFIG_USB_RIO500 is not set +# CONFIG_CRYPTO is not set # # Kernel hacking @@ -696,10 +649,7 @@ # CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set -# CONFIG_KDB_OFF is not set -# CONFIG_KALLSYMS is not set +# CONFIG_DEBUG_SLAB is not set # CONFIG_PPCDBG is not set # CONFIG_DUMP is not set -# CONFIG_DUMP_COMPRESS_RLE is not set -# CONFIG_DUMP_COMPRESS_GZIP is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linux-2.4.25/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig --- linux-2.4.24/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -21,9 +21,13 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_PPC_PSERIES is not set CONFIG_PPC_ISERIES=y +# CONFIG_ALTIVEC is not set CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 CONFIG_MSCHUNKS=y +# CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -40,6 +44,7 @@ # CONFIG_MCA is not set # CONFIG_EISA is not set CONFIG_PCI=y +# CONFIG_PCMCIA is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -50,7 +55,6 @@ CONFIG_BINFMT_MISC=y CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set # # Parallel port support @@ -58,17 +62,6 @@ # CONFIG_PARPORT is not set # -# Memory Technology Devices (MTD) -# -# CONFIG_MTD 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 @@ -77,12 +70,15 @@ # 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=64000 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -113,7 +109,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_TOS=y CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_DHCP is not set # CONFIG_IP_PNP_BOOTP is not set @@ -129,6 +124,12 @@ CONFIG_SYN_COOKIES=y # 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 @@ -167,7 +168,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -206,12 +206,14 @@ # 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 @@ -242,6 +244,7 @@ # 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 # @@ -284,15 +287,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set -# CONFIG_TC35815 is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -304,10 +310,11 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -320,12 +327,15 @@ CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I 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_VETH=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -345,6 +355,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -360,11 +374,6 @@ # CONFIG_HAMRADIO is not set # -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # ISDN subsystem # # CONFIG_ISDN is not set @@ -386,24 +395,6 @@ # CONFIG_CDU535 is not set # -# Console drivers -# - -# -# 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 - -# # iSeries device drivers # CONFIG_VIOCONS=y @@ -432,8 +423,8 @@ # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set -CONFIG_ICOM=m # 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 @@ -468,11 +459,19 @@ # Input core support is needed for joysticks # # 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_DTLK is not set @@ -484,12 +483,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # CONFIG_QUOTA=y +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_REISERFS_FS=y @@ -499,6 +503,9 @@ # 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 @@ -516,9 +523,10 @@ CONFIG_ISO9660_FS=y CONFIG_JOLIET=y # CONFIG_ZISOFS is not set -# CONFIG_MINIX_FS is not set # 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 @@ -537,6 +545,11 @@ # 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 @@ -545,9 +558,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -563,7 +578,6 @@ CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -616,14 +630,16 @@ CONFIG_NLS_UTF8=y # -# Sound +# Library routines # -# CONFIG_SOUND is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set # -# USB support +# Cryptographic options # -# CONFIG_USB is not set +# CONFIG_CRYPTO is not set # # Kernel hacking @@ -631,10 +647,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set -# CONFIG_KDB_OFF is not set -# CONFIG_KALLSYMS is not set +# CONFIG_DEBUG_SLAB is not set # CONFIG_PPCDBG is not set # CONFIG_DUMP is not set -# CONFIG_DUMP_COMPRESS_RLE is not set -# CONFIG_DUMP_COMPRESS_GZIP is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc64/configs/pSeries_defconfig linux-2.4.25/arch/ppc64/configs/pSeries_defconfig --- linux-2.4.24/arch/ppc64/configs/pSeries_defconfig 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/configs/pSeries_defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -21,8 +21,10 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_PPC_PSERIES=y # CONFIG_PPC_ISERIES is not set +CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 # CONFIG_HMT is not set # CONFIG_MSCHUNKS is not set CONFIG_RTAS_FLASH=m @@ -30,6 +32,7 @@ CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERRINJCT is not set # CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -76,6 +79,7 @@ # 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 @@ -118,6 +122,12 @@ CONFIG_SYN_COOKIES=y # 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 @@ -176,7 +186,6 @@ # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes @@ -194,7 +203,7 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set @@ -208,13 +217,11 @@ # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_PDC202XX_FORCE is not set # CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set @@ -228,7 +235,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -270,12 +276,14 @@ # 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 @@ -359,12 +367,14 @@ # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set CONFIG_E100=y # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -383,7 +393,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -396,6 +405,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y +CONFIG_E1000_NAPI=y # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -422,6 +432,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -471,12 +485,15 @@ CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y # CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_PROC=y # CONFIG_FB_MATROX_MULTIHEAD is not set # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set @@ -504,6 +521,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set CONFIG_VIOPATH=y # @@ -557,6 +575,7 @@ # 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 @@ -570,12 +589,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set CONFIG_REISERFS_FS=y @@ -585,6 +609,7 @@ # 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 @@ -626,6 +651,11 @@ # 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 @@ -634,6 +664,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y @@ -720,22 +751,29 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Kernel hacking # CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_KDB_OFF is not set -CONFIG_KALLSYMS=y CONFIG_PPCDBG=y # CONFIG_DUMP is not set -# CONFIG_DUMP_COMPRESS_RLE is not set -# CONFIG_DUMP_COMPRESS_GZIP is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc64/defconfig linux-2.4.25/arch/ppc64/defconfig --- linux-2.4.24/arch/ppc64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -21,9 +21,10 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_PPC_PSERIES=y # CONFIG_PPC_ISERIES is not set +CONFIG_ALTIVEC=y CONFIG_SMP=y -CONFIG_NR_CPUS=32 CONFIG_IRQ_ALL_CPUS=y +CONFIG_NR_CPUS=32 # CONFIG_HMT is not set # CONFIG_MSCHUNKS is not set CONFIG_RTAS_FLASH=m @@ -31,6 +32,7 @@ CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERRINJCT is not set # CONFIG_SHARED_MEMORY_ADDRESSING is not set +CONFIG_LPARCFG=y # # Loadable module support @@ -77,6 +79,7 @@ # 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 @@ -119,6 +122,12 @@ CONFIG_SYN_COOKIES=y # 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 @@ -226,7 +235,6 @@ # CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -275,6 +283,7 @@ # 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 @@ -358,6 +367,7 @@ # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set @@ -383,7 +393,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set -# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -396,6 +405,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y # CONFIG_DL2K is not set CONFIG_E1000=y +CONFIG_E1000_NAPI=y # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -422,6 +432,10 @@ # CONFIG_IBMLS is not set # CONFIG_3C359 is not set # CONFIG_TMS380TR is not set +# CONFIG_TMSPCI is not set +# CONFIG_TMSISA is not set +# CONFIG_ABYSS is not set +# CONFIG_MADGEMC is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -472,8 +486,9 @@ CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_FB_MATROX_G450 is not set -# CONFIG_FB_MATROX_G100A is not set -# CONFIG_FB_MATROX_PROC is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_PROC=y # CONFIG_FB_MATROX_MULTIHEAD is not set # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set @@ -506,6 +521,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set CONFIG_VIOPATH=y # @@ -559,6 +575,7 @@ # 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 @@ -572,12 +589,17 @@ # # CONFIG_FTAPE is not set # CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# # CONFIG_DRM is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set CONFIG_REISERFS_FS=y @@ -587,6 +609,7 @@ # 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 @@ -628,6 +651,11 @@ # 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 @@ -636,6 +664,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y @@ -722,18 +751,29 @@ # CONFIG_USB is not set # +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Kernel hacking # CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set # CONFIG_XMON is not set -# CONFIG_KDB is not set # CONFIG_DEBUG_SLAB is not set CONFIG_PPCDBG=y # CONFIG_DUMP is not set +CONFIG_LOG_BUF_SHIFT=0 diff -urN linux-2.4.24/arch/ppc64/kernel/HvCall.c linux-2.4.25/arch/ppc64/kernel/HvCall.c --- linux-2.4.24/arch/ppc64/kernel/HvCall.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/HvCall.c 2004-02-18 05:36:30.000000000 -0800 @@ -1,7 +1,7 @@ /* * HvCall.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -60,7 +60,7 @@ curPtr = virt_to_absolute( (unsigned long) buffer ); for(i=0; i bytesLeft) { @@ -90,11 +90,11 @@ struct HvLpBufferList bufList; u64 bytesLeft = bufLen; u64 leftThisPage; - u64 curPtr = virt_to_absolute( (unsigned long) buffer ); + u64 curPtr = virt_to_absolute((unsigned long) buffer); while (bytesLeft) { bufList.addr = curPtr; - + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; if (leftThisPage > bytesLeft) { @@ -105,11 +105,11 @@ bytesLeft -= leftThisPage; } - curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; - } - - HvCall2(HvCallBaseWriteLogBuffer, - virt_to_absolute((unsigned long)&bufList), bufLen); + HvCall2(HvCallBaseWriteLogBuffer, + virt_to_absolute((unsigned long) &bufList), + bufList.len); + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } } diff -urN linux-2.4.24/arch/ppc64/kernel/Makefile linux-2.4.25/arch/ppc64/kernel/Makefile --- linux-2.4.24/arch/ppc64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -17,7 +17,7 @@ O_TARGET := kernel.o -export-objs := ppc_ksyms.o setup.o +export-objs := ppc_ksyms.o setup.o vio.o viopath.o obj-y := ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ @@ -27,23 +27,26 @@ pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \ ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \ iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \ - rtc.o perfmon.o cputable.o + rtc.o perfmon.o cputable.o vio.o obj-$(CONFIG_PCI) += pci.o pci_dn.o pci_dma.o pSeries_lpar.o pSeries_hvCall.o ifeq ($(CONFIG_PPC_ISERIES),y) obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o +obj-$(CONFIG_VIOPATH) += viopath.o endif ifeq ($(CONFIG_PPC_PSERIES),y) obj-$(CONFIG_PCI) += pSeries_pci.o eeh.o -obj-y += rtasd.o nvram.o +obj-y += nvram.o rtasd.o endif obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_SCANLOG) += scanlog.o +obj-$(CONFIG_LPARCFG) += lparcfg.o + obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o diff -urN linux-2.4.24/arch/ppc64/kernel/chrp_setup.c linux-2.4.25/arch/ppc64/kernel/chrp_setup.c --- linux-2.4.24/arch/ppc64/kernel/chrp_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/chrp_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -82,18 +82,21 @@ extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; extern void openpic_init_IRQ(void); +extern void openpic_init_irq_desc(irq_desc_t *); extern void init_ras_IRQ(void); extern void find_and_init_phbs(void); extern void pSeries_pcibios_fixup(void); extern void iSeries_pcibios_fixup(void); +extern void pSeries_get_boot_time(struct rtc_time *rtc_time); extern void pSeries_get_rtc_time(struct rtc_time *rtc_time); extern int pSeries_set_rtc_time(struct rtc_time *rtc_time); void pSeries_calibrate_decr(void); -static void fwnmi_init(void); +static void machine_check_init(void); extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void); /* from head.S */ -int fwnmi_active; /* TRUE if an FWNMI handler is present */ +int fwnmi_active = 0; /* TRUE if an FWNMI handler is present */ +int check_exception_flag = 0; /* TRUE if a check-exception handler present */ kdev_t boot_dev; unsigned long virtPython0Facilities = 0; // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address. @@ -137,7 +140,6 @@ void __init chrp_setup_arch(void) { - extern char cmd_line[]; struct device_node *root; unsigned int *opprop; @@ -156,11 +158,9 @@ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); else #endif - ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ + ROOT_DEV = to_kdev_t(0x0803); /* sda3 (sda1 is for the kernel or the bootloader) */ - printk("Boot arguments: %s\n", cmd_line); - - fwnmi_init(); + machine_check_init(); #ifndef CONFIG_PPC_ISERIES /* Find and initialize PCI host bridges */ @@ -202,20 +202,26 @@ } /* Initialize firmware assisted non-maskable interrupts if - * the firmware supports this feature. - * + * the firmware supports this feature. If it does not, + * look for the check-exception property. */ -static void __init fwnmi_init(void) +static void __init machine_check_init(void) { long ret; + int check_ex_token; int ibm_nmi_register = rtas_token("ibm,nmi-register"); - if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) - return; - ret = rtas_call(ibm_nmi_register, 2, 1, NULL, - __pa((unsigned long)SystemReset_FWNMI), - __pa((unsigned long)MachineCheck_FWNMI)); - if (ret == 0) - fwnmi_active = 1; + + if (ibm_nmi_register != RTAS_UNKNOWN_SERVICE) { + ret = rtas_call(ibm_nmi_register, 2, 1, NULL, + __pa((unsigned long)SystemReset_FWNMI), + __pa((unsigned long)MachineCheck_FWNMI)); + if (ret == 0) + fwnmi_active = 1; + } else { + check_ex_token = rtas_token("check-exception"); + if (check_ex_token != RTAS_UNKNOWN_SERVICE) + check_exception_flag = 1; + } } @@ -264,19 +270,23 @@ ppc_md.setup_residual = NULL; ppc_md.get_cpuinfo = chrp_get_cpuinfo; if(naca->interrupt_controller == IC_OPEN_PIC) { - ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_irq_desc = openpic_init_irq_desc; ppc_md.get_irq = openpic_get_irq; } else { ppc_md.init_IRQ = xics_init_IRQ; + ppc_md.init_irq_desc = xics_init_irq_desc; ppc_md.get_irq = xics_get_irq; } ppc_md.init_ras_IRQ = init_ras_IRQ; #ifndef CONFIG_PPC_ISERIES ppc_md.pcibios_fixup = pSeries_pcibios_fixup; + ppc_md.log_error = pSeries_log_error; #else ppc_md.pcibios_fixup = NULL; // ppc_md.pcibios_fixup = iSeries_pcibios_fixup; + ppc_md.log_error = NULL; #endif @@ -287,7 +297,7 @@ ppc_md.halt = rtas_halt; ppc_md.time_init = NULL; - ppc_md.get_boot_time = pSeries_get_rtc_time; + ppc_md.get_boot_time = pSeries_get_boot_time; ppc_md.get_rtc_time = pSeries_get_rtc_time; ppc_md.set_rtc_time = pSeries_set_rtc_time; ppc_md.calibrate_decr = pSeries_calibrate_decr; @@ -306,10 +316,10 @@ SYSRQ_KEY = 0x63; /* Print Screen */ #endif #endif - /* Build up the firmware_features bitmask field - * using contents of device-tree/ibm,hypertas-functions. - * Ultimately this functionality may be moved into prom.c prom_init(). - */ + /* Build up the firmware_features bitmask field + * using contents of device-tree/ibm,hypertas-functions. + * Ultimately this functionality may be moved into prom.c prom_init(). + */ struct device_node * dn; char * hypertas; unsigned int len; @@ -317,21 +327,26 @@ cur_cpu_spec->firmware_features=0; hypertas = get_property(dn, "ibm,hypertas-functions", &len); if (hypertas) { - while (len > 0){ - int i; - /* check value against table of strings */ - for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) { - if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) { - /* we have a match */ - cur_cpu_spec->firmware_features |= (1UL << firmware_features_table[i].val ); - break; - } + while (len > 0) { + int i, hypertas_len; + /* check value against table of strings */ + for(i=0; i < FIRMWARE_MAX_FEATURES; i++) { + if ((firmware_features_table[i].name) && + (strcmp(firmware_features_table[i].name,hypertas))==0) { + /* we have a match */ + cur_cpu_spec->firmware_features |= + (firmware_features_table[i].val); + break; + } + } + hypertas_len = strlen(hypertas); + len -= hypertas_len +1; + hypertas+= hypertas_len +1; } - int hypertas_len = strlen(hypertas); - len -= hypertas_len +1; - hypertas+= hypertas_len +1; - } } + + printk(KERN_INFO "firmware_features = 0x%lx\n", + cur_cpu_spec->firmware_features); } void __chrp diff -urN linux-2.4.24/arch/ppc64/kernel/cputable.c linux-2.4.25/arch/ppc64/kernel/cputable.c --- linux-2.4.24/arch/ppc64/kernel/cputable.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/cputable.c 2004-02-18 05:36:30.000000000 -0800 @@ -5,7 +5,7 @@ * * Modifications for ppc64: * Copyright (C) 2003 Dave Engebretsen - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -30,14 +30,17 @@ */ #ifdef CONFIG_ALTIVEC #define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC +#define PPC_FEATURE_HAS_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC #else #define CPU_FTR_ALTIVEC_COMP 0 +#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 #endif struct cpu_spec cpu_specs[] = { { /* Power3 */ 0xffff0000, 0x00400000, "Power3 (630)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -45,7 +48,8 @@ }, { /* Power3+ */ 0xffff0000, 0x00410000, "Power3 (630+)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -53,7 +57,8 @@ }, { /* Northstar */ 0xffff0000, 0x00330000, "Northstar", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -61,7 +66,8 @@ }, { /* Pulsar */ 0xffff0000, 0x00340000, "Pulsar", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -69,7 +75,8 @@ }, { /* I-star */ 0xffff0000, 0x00360000, "I-star", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -77,7 +84,8 @@ }, { /* S-star */ 0xffff0000, 0x00370000, "S-star", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_DABR | CPU_FTR_IABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power3, @@ -86,7 +94,7 @@ { /* Power4 */ 0xffff0000, 0x00350000, "Power4", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2, + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_DABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, @@ -95,6 +103,24 @@ { /* Power4+ */ 0xffff0000, 0x00380000, "Power4+", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_DABR, + COMMON_USER_PPC64, + 128, 128, + __setup_cpu_power4, + COMMON_PPC64_FW + }, + { /* PPC970 */ + 0xffff0000, 0x00390000, "PPC970", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP, + COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, + 128, 128, + __setup_cpu_power4, + COMMON_PPC64_FW + }, + { /* Power5 */ + 0xffff0000, 0x003a0000, "Power5", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, COMMON_USER_PPC64, 128, 128, @@ -103,8 +129,8 @@ }, { /* default match */ 0x00000000, 0x00000000, "(Power4-Compatible)", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | - CPU_FTR_PPCAS_ARCH_V2, + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_DABR, COMMON_USER_PPC64, 128, 128, __setup_cpu_power4, @@ -124,4 +150,13 @@ {FW_FEATURE_DUMP, "hcall-dump"}, {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, {FW_FEATURE_MIGRATE, "hcall-migrate"}, + {FW_FEATURE_PERFMON, "hcall-perfmon"}, + {FW_FEATURE_CRQ, "hcall-crq"}, + {FW_FEATURE_VIO, "hcall-vio"}, + {FW_FEATURE_RDMA, "hcall-rdma"}, + {FW_FEATURE_LLAN, "hcall-lLAN"}, + {FW_FEATURE_BULK, "hcall-bulk"}, + {FW_FEATURE_XDABR, "hcall-xdabr"}, + {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, + {FW_FEATURE_SPLPAR, "hcall-splpar"}, }; diff -urN linux-2.4.24/arch/ppc64/kernel/eeh.c linux-2.4.25/arch/ppc64/kernel/eeh.c --- linux-2.4.24/arch/ppc64/kernel/eeh.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/eeh.c 2004-02-18 05:36:30.000000000 -0800 @@ -30,6 +30,7 @@ #include #include #include +#include #include "pci.h" #define BUID_HI(buid) ((buid) >> 32) @@ -114,6 +115,18 @@ ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); if (ret == 0 && rets[1] == 1 && rets[0] >= 2) { + unsigned char slot_err_buf[RTAS_ERROR_LOG_MAX]; + unsigned long slot_err_ret; + + memset(slot_err_buf, 0, RTAS_ERROR_LOG_MAX); + slot_err_ret = rtas_call(rtas_token("ibm,slot-error-detail"), + 8, 1, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid), + NULL, 0, __pa(slot_err_buf), RTAS_ERROR_LOG_MAX, + 2 /* Permanent Error */); + if (slot_err_ret == 0) + log_error(slot_err_buf, ERR_TYPE_RTAS_LOG, 1 /* Fatal */); + panic("EEH: MMIO failure (%ld) on device:\n %s %s\n", rets[0], dev->slot_name, dev->name); } diff -urN linux-2.4.24/arch/ppc64/kernel/entry.S linux-2.4.25/arch/ppc64/kernel/entry.S --- linux-2.4.24/arch/ppc64/kernel/entry.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/entry.S 2004-02-18 05:36:30.000000000 -0800 @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -46,16 +47,17 @@ */ .text _GLOBAL(DoSyscall) - std r0,THREAD+LAST_SYSCALL(r13) ld r11,_CCR(r1) /* Clear SO bit in CR */ lis r10,0x1000 andc r11,r11,r10 std r11,_CCR(r1) + ld r10,PACACURRENT(r13) + std r0,THREAD+LAST_SYSCALL(r10) #ifdef SHOW_SYSCALLS # ifdef SHOW_SYSCALLS_TASK LOADBASE(r31,show_syscalls_task) ld r31,show_syscalls_task@l(r31) - cmp 0,r13,r31 + cmp 0,r10,r31 bne 1f # endif /* SHOW_SYSCALLS_TASK */ LOADADDR(r3,7f) @@ -69,7 +71,7 @@ LOADADDR(r3,77f) ld r4,GPR8(r1) ld r5,GPR9(r1) - mr r6,r13 + ld r6, PACACURRENT(r13) bl .printk ld r0,GPR0(r1) ld r3,GPR3(r1) @@ -80,8 +82,8 @@ ld r8,GPR8(r1) 1: #endif /* SHOW_SYSCALLS */ - ld r10,TASK_PTRACE(r13) - andi. r10,r10,PT_TRACESYS + ld r11,TASK_PTRACE(r10) + andi. r11,r11,PT_TRACESYS bne- 50f cmpli 0,r0,NR_syscalls bge- 66f @@ -90,10 +92,10 @@ * */ #ifdef CONFIG_BINFMT_ELF32 - ld r10,THREAD+THREAD_FLAGS(r13) - andi. r10,r10,PPC_FLAG_32BIT + ld r11,THREAD+THREAD_FLAGS(r10) + andi. r11,r11,PPC_FLAG_32BIT beq- 15f - LOADADDR(r10,.sys_call_table32) + LOADADDR(r11,.sys_call_table32) /* Now mung the first 4 parameters into shape, by making certain that * the high bits (most significant 32 bits in 64 bit reg) are 0 * for the first 4 parameter regs(3-6). @@ -105,10 +107,10 @@ b 17f 15: #endif - LOADADDR(r10,.sys_call_table) + LOADADDR(r11,.sys_call_table) 17: slwi r0,r0,3 - ldx r10,r10,r0 /* Fetch system call handler [ptr] */ + ldx r10,r11,r0 /* Fetch system call handler [ptr] */ mtlr r10 addi r9,r1,STACK_FRAME_OVERHEAD blrl /* Call handler */ @@ -153,7 +155,8 @@ cmpli 0,r0,NR_syscalls bge- 66f #ifdef CONFIG_BINFMT_ELF32 - ld r10,THREAD+THREAD_FLAGS(r13) + ld r10,PACACURRENT(r13) + ld r10,THREAD+THREAD_FLAGS(r10) andi. r10,r10,PPC_FLAG_32BIT beq- 55f LOADADDR(r10,.sys_call_table32) @@ -214,7 +217,8 @@ _GLOBAL(ppc64_rt_sigreturn) bl .sys_rt_sigreturn -80: ld r10,TASK_PTRACE(r13) +80: ld r10,PACACURRENT(r13) + ld r10,TASK_PTRACE(r10) andi. r10,r10,PT_TRACESYS bne- 81f cmpi 0,r3,0 @@ -254,6 +258,11 @@ mflr r20 /* Return to switch caller */ mfmsr r22 li r6,MSR_FP /* Disable floating-point */ +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + oris r6,r6,MSR_VEC@h /* Disable altivec */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ andc r22,r22,r6 mtmsrd r22 isync @@ -266,10 +275,9 @@ std r6,TRAP(r1) std r1,KSP(r3) /* Set old stack pointer */ - mfspr r5,SPRG3 /* Get Paca */ addi r3,r3,-THREAD /* old 'current' for return value */ - addi r13,r4,-THREAD /* Convert THREAD to 'current' */ - std r13,PACACURRENT(r5) /* Set new 'current' */ + addi r7,r4,-THREAD /* Convert THREAD to 'current' */ + std r7,PACACURRENT(r13) /* Set new 'current' */ #ifdef CONFIG_PPC_ISERIES ld r7,THREAD_FLAGS(r4) /* Get run light flag */ @@ -292,7 +300,8 @@ _GLOBAL(ret_from_fork) bl .schedule_tail - ld r0,TASK_PTRACE(r13) + ld r4,PACACURRENT(r13) + ld r0,TASK_PTRACE(r4) andi. r0,r0,PT_TRACESYS beq+ .ret_from_except bl .syscall_trace @@ -308,9 +317,8 @@ CHECKANYINT(r3,r4) beq+ 4f /* skip do_IRQ if no interrupts */ - mfspr r5,SPRG3 li r3,0 - stb r3,PACAPROCENABLED(r5) /* ensure we are disabled */ + stb r3,PACAPROCENABLED(r13) /* ensure we are disabled */ addi r3,r1,STACK_FRAME_OVERHEAD bl .do_IRQ b irq_recheck /* loop back and handle more */ @@ -322,14 +330,16 @@ beq+ restore /* if so, check need_resched and signals */ _GLOBAL(ret_to_user_hook) nop - /* NEED_RESCHED is a volatile long (64-bits) */ - ld r3,NEED_RESCHED(r13) + /* NEED_RESCHED is a volatile long (64-bits) */ + ld r3,PACACURRENT(r13) + ld r3,NEED_RESCHED(r3) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl .schedule /* SIGPENDING is an int (32-bits) */ -7: - lwz r5,SIGPENDING(r13) /* Check for pending unblocked signals */ +7: + ld r5,PACACURRENT(r13) + lwz r5,SIGPENDING(r5) /* Check for pending unblocked signals */ cmpwi 0,r5,0 beq+ restore li r3,0 @@ -372,26 +382,37 @@ #endif stdcx. r0,0,r1 /* to clear the reservation */ - mfspr r4,SPRG3 /* current task's PACA */ #ifdef DO_SOFT_DISABLE ld r0,SOFTE(r1) - stb r0,PACAPROCENABLED(r4) + stb r0,PACAPROCENABLED(r13) #endif /* if returning to user mode, save kernel SP */ ld r0,_MSR(r1) andi. r0,r0,MSR_PR beq+ 1f + ld r4,PACACURRENT(r13) +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + ld r0,THREAD+THREAD_VRSAVE(r4) + mtspr SPRN_VRSAVE,r0 /* if GPUL, restore VRSAVE reg */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ addi r0,r1,INT_FRAME_SIZE /* size of frame */ - std r0,THREAD+KSP(r13) /* save kernel stack pointer */ - std r1,PACAKSAVE(r4) /* save exception stack pointer */ + std r0,THREAD+KSP(r4) /* save kernel stack pointer */ + std r1,PACAKSAVE(r13) /* save exception stack pointer */ + REST_GPR(13,r1) 1: + mfmsr r0 + li r2, MSR_RI + andc r0,r0,r2 + mtmsrd r0,1 + ld r0,_MSR(r1) mtspr SRR1,r0 ld r2,_CCR(r1) mtcrf 0xFF,r2 ld r2,_NIP(r1) mtspr SRR0,r2 - REST_GPR(13,r1) ld r0,GPR0(r1) ld r2,GPR2(r1) ld r3,GPR3(r1) @@ -440,11 +461,10 @@ /* Unfortunately, the stack pointer and the MSR are also clobbered, * so they are saved in the PACA (SPRG3) which allows us to restore * our original state after RTAS returns. - */ - mfspr r4,SPRG3 /* Get PACA */ - std r1,PACAR1(r4) + */ + std r1,PACAR1(r13) mfmsr r6 - std r6,PACASAVEDMSR(r4) + std r6,PACASAVEDMSR(r13) /* Setup our real return addr */ SET_REG_TO_LABEL(r4,.rtas_return_loc) @@ -473,13 +493,19 @@ _STATIC(rtas_return_loc) /* relocation is off at this point */ - mfspr r4,SPRG3 /* Get PACA */ + mfspr r13,SPRG3 /* Get PACA */ SET_REG_TO_CONST(r5, KERNELBASE) - sub r4,r4,r5 /* RELOC the PACA base pointer */ - - ld r1,PACAR1(r4) /* Restore our SP */ + sub r13,r13,r5 /* RELOC the PACA base pointer */ + + mfmsr r6 /* Clear RI while SRR0/1 are live */ + li r0,MSR_RI + andc r6,r6,r0 + sync + mtmsrd r6 + + ld r1,PACAR1(r13) /* Restore our SP */ LOADADDR(r3,.rtas_restore_regs) - ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ + ld r4,PACASAVEDMSR(r13) /* Restore our MSR */ mtspr SRR0,r3 mtspr SRR1,r4 @@ -492,9 +518,8 @@ REST_8GPRS(14, r1) /* Restore the non-volatiles */ REST_10GPRS(22, r1) /* ditto */ - /* put back current in r13 */ - mfspr r4,SPRG3 - ld r13,PACACURRENT(r4) + /* put back paca in r13 */ + mfspr r13,SPRG3 ld r4,_CCR(r1) mtcr r4 diff -urN linux-2.4.24/arch/ppc64/kernel/head.S linux-2.4.25/arch/ppc64/kernel/head.S --- linux-2.4.24/arch/ppc64/kernel/head.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/head.S 2004-02-18 05:36:30.000000000 -0800 @@ -14,6 +14,10 @@ * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com * + * VMX/Altivec port from ppc32 (C) IBM 2003 + * Denis Joseph Barrow (dj@de.ibm.com,barrow_dj@yahoo.com) + * additional debugging & 2.4-2.5 VMX port + * Ben Herrenschmidt (benh@kernel.crashing.org) * This file contains the low-level support and setup for the * PowerPC-64 platform, including trap and interrupt dispatch. * @@ -38,6 +42,15 @@ #define DO_SOFT_DISABLE #endif +/* copy saved SOFTE bit or EE bit from saved MSR depending + * if we are doing soft-disable or not + */ +#ifdef DO_SOFT_DISABLE +#define DO_COPY_EE() ld r20,SOFTE(r1) +#else +#define DO_COPY_EE() rldicl r20,r23,49,63 +#endif + /* * hcall interface to pSeries LPAR */ @@ -130,6 +143,10 @@ * All of it must fit below the first exception vector at 0x100. */ _GLOBAL(__secondary_hold) + mfmsr r24 + ori r24,r24,MSR_RI + mtmsrd r24 /* RI on */ + /* Grab our linux cpu number */ mr r24,r3 @@ -201,7 +218,7 @@ /* assumes *_common < 16b */ \ mfmsr r23; \ rotldi r23,r23,4; \ - ori r23,r23,0x30B; /* Set IR, DR, SF, ISF, HV */ \ + ori r23,r23,0x32B; /* Set IR, DR, RI, SF, ISF, HV*/ \ rotldi r23,r23,60; /* for generic handlers */ \ mtspr SRR0,r22; \ mtspr SRR1,r23; \ @@ -285,7 +302,7 @@ SAVE_8GPRS(2, r1); /* save r2 - r13 in stackframe */ \ SAVE_4GPRS(10, r1); \ ld r2,PACATOC(r20); \ - ld r13,PACACURRENT(r20) + mr r13,r20 /* * Note: code which follows this uses cr0.eq (set if from kernel), @@ -363,8 +380,17 @@ STD_EXCEPTION_PSERIES( 0xc00, SystemCall ) STD_EXCEPTION_PSERIES( 0xd00, SingleStep ) STD_EXCEPTION_PSERIES( 0xe00, Trap_0e ) - STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor ) + . = 0xf00 + b PerformanceMonitor_Pseries + STD_EXCEPTION_PSERIES( 0xf20, AltiVecUnavailable ) + . = 0xf90 + .globl PerformanceMonitor_Pseries +PerformanceMonitor_Pseries: + EXCEPTION_PROLOG_PSERIES( 0xf00, PerformanceMonitor_common ) STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint ) + STD_EXCEPTION_PSERIES( 0x1700, AltiVecAssist ) + STD_EXCEPTION_PSERIES( 0x1800, ThermalInterrupt) + /* Space for the naca. Architected to be located at real address * 0x4000. Various tools rely on this location being fixed. @@ -436,8 +462,8 @@ .globl SystemReset_Iseries SystemReset_Iseries: - mfspr 25,SPRG3 /* Get paca address */ - lhz r24,PACAPACAINDEX(r25) /* Get processor # */ + mfspr 13,SPRG3 /* Get paca address */ + lhz r24,PACAPACAINDEX(r13) /* Get processor # */ cmpi 0,r24,0 /* Are we processor 0? */ beq .__start_initialization_iSeries /* Start up the first processor */ mfspr r4,CTRLF @@ -448,7 +474,7 @@ 1: HMT_LOW #ifdef CONFIG_SMP - lbz r23,PACAPROCSTART(r25) /* Test if this processor + lbz r23,PACAPROCSTART(r13) /* Test if this processor * should start */ sync LOADADDR(r3,current_set) @@ -478,7 +504,7 @@ #endif /* CONFIG_SMP */ li r0,-1 /* r0=-1 indicates a Hypervisor call */ sc /* Invoke the hypervisor via a system call */ - mfspr r25,SPRG3 /* Put r25 back ???? */ + mfspr r13,SPRG3 /* Put r13 back - why???? */ b 1b /* If SMP not configured, secondaries * loop forever */ @@ -551,6 +577,47 @@ STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException ) STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException ) STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException ) + + .globl AltiVecUnavailable_common +AltiVecUnavailable_common: + EXCEPTION_PROLOG_COMMON +#ifdef CONFIG_ALTIVEC + bne .load_up_altivec /* if from user, just load it up */ +#endif + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0xf20 + bl .save_remaining_regs +#ifndef CONFIG_ALTIVEC + beq 1f + bl .IllegalAltiVecInstruction + b .ret_from_except +1: +#endif + bl .KernelAltiVecUnavailableException + BUG_OPCODE + + .global AltiVecAssist_common +AltiVecAssist_common: + EXCEPTION_PROLOG_COMMON + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0x1700 + bl .save_remaining_regs + bl .AltiVecAssistException + b .ret_from_except + + .global ThermalInterrupt_common +ThermalInterrupt_common: + EXCEPTION_PROLOG_COMMON + addi r3,r1,STACK_FRAME_OVERHEAD + DO_COPY_EE() + li r6,0x1800 + bl .save_remaining_regs + bl .ThermalInterrupt + BUG_OPCODE + + STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException ) /* @@ -570,6 +637,12 @@ REST_GPR(0, r1) REST_8GPRS(2, r1) REST_4GPRS(10, r1) + + mfmsr r20 + li r21, MSR_RI + andc r20,r20,r21 + mtmsrd r20,1 + mtspr SRR1,r23 mtspr SRR0,r22 REST_4GPRS(20, r1) @@ -613,11 +686,7 @@ ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) /* Copy saved SOFTE bit */ -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x300 bl .save_remaining_regs bl .do_page_fault @@ -639,11 +708,7 @@ or. r3,r3,r3 /* Check return code */ beq fast_exception_return /* Return if we succeeded */ addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x380 li r5,0 bl .save_remaining_regs @@ -669,11 +734,7 @@ mr r4,r22 rlwinm r5,r23,0,4,4 /* We only care about PR in error_code */ addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x400 bl .save_remaining_regs bl .do_page_fault @@ -689,11 +750,7 @@ beq fast_exception_return /* Return if we succeeded */ addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x480 li r5,0 bl .save_remaining_regs @@ -766,11 +823,7 @@ Alignment_common: EXCEPTION_PROLOG_COMMON addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x600 bl .save_remaining_regs bl .AlignmentException @@ -780,11 +833,7 @@ ProgramCheck_common: EXCEPTION_PROLOG_COMMON addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x700 bl .save_remaining_regs bl .ProgramCheckException @@ -795,11 +844,7 @@ EXCEPTION_PROLOG_COMMON bne .load_up_fpu /* if from user, just load it up */ addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0x800 bl .save_remaining_regs bl .KernelFPUnavailableException @@ -816,11 +861,7 @@ 1: #endif std r3,ORIG_GPR3(r1) -#ifdef DO_SOFT_DISABLE - ld r20,SOFTE(r1) -#else - rldicl r20,r23,49,63 /* copy EE bit from saved MSR */ -#endif + DO_COPY_EE() li r6,0xC00 bl .save_remaining_regs bl .DoSyscall @@ -1143,6 +1184,12 @@ lwz r23,EX_CCR(r21) /* get saved CR */ /* note that this is almost identical to maskable_exception_exit */ mtcr r23 /* restore CR */ + + mfmsr r22 + li r23, MSR_RI + andc r22,r22,r23 + mtmsrd r22,1 + ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ mtspr SRR0,r22 @@ -1184,7 +1231,7 @@ slbmfee r23,r22 rldicl r23,r23,37,63 cmpwi r23,0 - beq 3f /* Found an invalid entry */ + beq 4f /* Found an invalid entry */ addi r22,r22,1 cmpldi r22,64 @@ -1193,16 +1240,36 @@ /* No free entry - just take the next entry, round-robin */ /* XXX we should get the number of SLB entries from the naca */ SLB_NUM_ENTRIES = 64 - mfspr r21,SPRG3 +2: mfspr r21,SPRG3 ld r22,PACASTABRR(r21) addi r23,r22,1 cmpdi r23,SLB_NUM_ENTRIES - blt 2f + blt 3f li r23,1 -2: std r23,PACASTABRR(r21) +3: std r23,PACASTABRR(r21) /* r20 = vsid, r22 = entry */ -3: + + /* + * Never cast out the segment for our kernel stack. Since we + * dont invalidate the ERAT we could have a valid translation + * for the kernel stack during the first part of exception exit + * which gets invalidated due to a tlbie from another cpu at a + * non recoverable point (after setting srr0/1) - Anton + */ + slbmfee r23,r22 + srdi r23,r23,28 + /* + * This is incorrect (r1 is not the kernel stack) if we entered + * from userspace but there is no critical window from userspace + * so this should be OK. Also if we cast out the userspace stack + * segment while in userspace we will fault it straight back in. + */ + srdi r21,r1,28 + cmpd r21,r23 + beq- 2b + +4: /* Put together the vsid portion of the entry. */ li r21,0 rldimi r21,r20,12,0 @@ -1237,6 +1304,12 @@ lwz r23,EX_CCR(r21) /* get saved CR */ /* note that this is almost identical to maskable_exception_exit */ mtcr r23 /* restore CR */ + + mfmsr r22 + li r23, MSR_RI + andc r22,r22,r23 + mtmsrd r22,1 + ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */ ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */ mtspr SRR0,r22 @@ -1295,21 +1368,27 @@ * Indicate that r1 contains the kernel stack and * get the Kernel TOC and CURRENT pointers from the paca */ - mfspr r23,SPRG3 /* Get PACA */ - std r22,PACAKSAVE(r23) /* r1 is now kernel sp */ - ld r2,PACATOC(r23) /* Get Kernel TOC pointer */ + std r22,PACAKSAVE(r13) /* r1 is now kernel sp */ + ld r2,PACATOC(r13) /* Get Kernel TOC pointer */ /* * If from user state, update THREAD.regs */ beq 2f /* Modify THREAD.regs if from user */ addi r24,r1,STACK_FRAME_OVERHEAD - std r24,THREAD+PT_REGS(r13) + ld r22,PACACURRENT(r13) + std r24,THREAD+PT_REGS(r22) +#ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION + mfspr r24,SPRN_VRSAVE /* if save vrsave register value */ + std r24,THREAD+THREAD_VRSAVE(r22) +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) +#endif /* CONFIG_ALTIVEC */ 2: SET_REG_TO_CONST(r22, MSR_KERNEL) #ifdef DO_SOFT_DISABLE - stb r20,PACAPROCENABLED(r23) /* possibly soft enable */ + stb r20,PACAPROCENABLED(r13) /* possibly soft enable */ ori r22,r22,MSR_EE /* always hard enable */ #else rldimi r22,r20,15,48 /* Insert desired EE value */ @@ -1356,20 +1435,20 @@ /* Set up a paca value for this processor. */ LOADADDR(r24, paca) /* Get base vaddr of Paca array */ - mulli r25,r3,PACA_SIZE /* Calculate vaddr of right Paca */ - add r25,r25,r24 /* for this processor. */ + mulli r13,r3,PACA_SIZE /* Calculate vaddr of right Paca */ + add r13,r13,r24 /* for this processor. */ - mtspr SPRG3,r25 /* Save vaddr of Paca in SPRG3 */ + mtspr SPRG3,r13 /* Save vaddr of Paca in SPRG3 */ mr r24,r3 /* __secondary_start needs cpu# */ 1: HMT_LOW - lbz r23,PACAPROCSTART(r25) /* Test if this processor should */ + lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ /* start. */ sync /* Create a temp kernel stack for use before relocation is on. */ - mr r1,r25 + mr r1,r13 addi r1,r1,PACAGUARD addi r1,r1,0x1000 subi r1,r1,STACK_FRAME_OVERHEAD @@ -1609,16 +1688,17 @@ 1: #endif /* CONFIG_SMP */ /* enable use of FP after return */ - addi r5,r13,THREAD - ld r4,THREAD_FPEXC_MODE(r5) + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r20,THREAD_FPEXC_MODE(r5) ori r23,r23,MSR_FP - or r23,r23,r4 + or r23,r23,r20 lfd fr0,THREAD_FPSCR(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP /* Update last_task_used_math to 'current' */ - std r13,last_task_used_math@l(r3) + std r4,last_task_used_math@l(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ b fast_exception_return @@ -1674,6 +1754,100 @@ #endif /* CONFIG_SMP */ blr +#ifdef CONFIG_ALTIVEC +/* + * load_up_altivec(unused, unused, tsk) + * Disable Altivec for the task which used altivec upreviously, + * and save its altivec registers in its thread_struct. + * Enables Altivec for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch (ie, no lazy save of the altivec registers). + * On entry: r13 == 'current' && last_task_used_altivec != 'current' + */ +_STATIC(load_up_altivec) +/* + * Disable AltiVec for the task which had AltiVec previously, + * and save its AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + * On SMP we know the AltiVec units are free, since we give it up every + * switch. -- Kumar + */ + mfmsr r5 + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of AltiVec now */ + isync +/* + * For SMP, we don't do lazy AltiVec switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altivec in switch_to. + */ +#ifndef CONFIG_SMP + LOADBASE(r3,last_task_used_altivec) + ld r4,last_task_used_altivec@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */ + SAVE_32VR(0,r20,r4) + MFVSCR(vr0) + li r20,THREAD_VSCR + STVX(vr0,r20,r4) + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r20,MSR_VEC@h + andc r4,r4,r20 /* disable altivec for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of AltiVec after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD + oris r23,r23,MSR_VEC@h + li r20,THREAD_VSCR + LVX(vr0,r20,r5) + MTVSCR(vr0) + REST_32VR(0,r20,r5) +#ifndef CONFIG_SMP + /* Update last_task_used_altivec to 'current' */ + std r4,last_task_used_altivec@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return +/* + * giveup_altivec(tsk) + * Disable AltiVec for the task given as the argument, + * and save the AltiVec registers in its thread_struct. + * Enables AltiVec for use in the kernel on return. + */ +_GLOBAL(giveup_altivec) + mfmsr r5 + oris r5,r5,MSR_VEC@h + mtmsrd r5 /* enable use of AltiVec now */ + isync + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32VR(0, r4, r3) + MFVSCR(vr0) + li r4,THREAD_VSCR + STVX(vr0, r4, r3) + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC@h + andc r4,r4,r3 /* disable AltiVec for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + LOADBASE(r4,last_task_used_altivec) + std r5,last_task_used_altivec@l(r4) +#endif /* CONFIG_SMP */ + blr +#endif /* CONFIG_ALTIVEC */ + + + #ifdef CONFIG_SMP /* * This function is called after the master CPU has released the @@ -1685,7 +1859,7 @@ * On entry the following are set: * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries * r24 = cpu# (in Linux terms) - * r25 = paca virtual address + * r13 = paca virtual address * SPRG3 = paca virtual address */ _GLOBAL(__secondary_start) @@ -1697,10 +1871,10 @@ addi r2,r2,0x4000 addi r2,r2,0x4000 - std r2,PACATOC(r25) + std r2,PACATOC(r13) li r6,0 - std r6,PACAKSAVE(r25) - stb r6,PACAPROCENABLED(r25) + std r6,PACAKSAVE(r13) + stb r6,PACAPROCENABLED(r13) #ifndef CONFIG_PPC_ISERIES /* Initialize the page table pointer register. */ @@ -1709,18 +1883,18 @@ mtspr SDR1,r6 /* set the htab location */ #endif /* Initialize the first segment table (or SLB) entry */ - ld r3,PACASTABVIRT(r25) /* get addr of segment table */ + ld r3,PACASTABVIRT(r13) /* get addr of segment table */ bl .stab_initialize /* Initialize the kernel stack. Just a repeat for iSeries. */ LOADADDR(r3,current_set) sldi r28,r24,4 /* get current_set[cpu#] */ - ldx r13,r3,r28 - std r13,PACACURRENT(r25) - addi r1,r13,TASK_UNION_SIZE + ldx r28,r3,r28 + std r28,PACACURRENT(r13) + addi r1,r28,TASK_UNION_SIZE subi r1,r1,STACK_FRAME_OVERHEAD - ld r3,PACASTABREAL(r25) /* get raddr of segment table */ + ld r3,PACASTABREAL(r13) /* get raddr of segment table */ ori r4,r3,1 /* turn on valid bit */ #ifdef CONFIG_PPC_ISERIES @@ -1737,9 +1911,13 @@ bne 98f mfspr r3,PVR srwi r3,r3,16 - cmpwi r3,0x37 /* SStar */ + cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ bne 98f - li r3,H_SET_ASR /* hcall = H_SET_ASR */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ HSC /* Invoking hcall */ b 99f 98: /* !(rpa hypervisor) || !(sstar) */ @@ -1758,7 +1936,6 @@ mtspr SRR0,r3 mtspr SRR1,r4 rfid -#endif /* CONFIG_SMP */ /* * Running with relocation on at this point. All we want to do is @@ -1768,6 +1945,7 @@ li r3,0 std r3,0(r1) /* Zero the stack frame pointer */ bl .start_secondary +#endif /* CONFIG_SMP */ /* * This subroutine clobbers r11, r12 and the LR @@ -1807,6 +1985,10 @@ bl .reloc_offset mr r26,r3 + mfmsr r6 + ori r6,r6,MSR_RI + mtmsrd r6 /* RI on */ + /* setup the systemcfg pointer which is needed by *tab_initialize */ LOADADDR(r6,systemcfg) sub r6,r6,r26 /* addr of the variable systemcfg */ @@ -1880,9 +2062,9 @@ /* stab_initialize */ li r27,0x4000 ld r6,PACA(r27) /* Get the base paca pointer */ - sub r6,r6,r26 /* convert to physical addr */ - mtspr SPRG3,r6 /* PPPBBB: Temp... -Peter */ - ld r3,PACASTABREAL(r6) + sub r13,r6,r26 /* convert to physical addr */ + mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ + ld r3,PACASTABREAL(r13) ori r4,r3,1 /* turn on valid bit */ /* set the ASR */ @@ -1893,8 +2075,12 @@ mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ + beq 97f + cmpwi r3,0x36 /* IStar */ + beq 97f + cmpwi r3,0x34 /* Pulsar */ bne 98f - li r3,H_SET_ASR /* hcall = H_SET_ASR */ +97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ HSC /* Invoking hcall */ b 99f 98: /* This is not a hypervisor machine */ @@ -1973,16 +2159,16 @@ LOADADDR(r4,naca) /* Get naca ptr address */ ld r4,0(r4) /* Get the location of the naca */ - ld r4,PACA(r4) /* Get the base paca pointer */ - mtspr SPRG3,r4 + ld r13,PACA(r4) /* Get the base paca pointer */ + mtspr SPRG3,r13 /* ptr to current */ - LOADADDR(r13,init_task_union) - std r13,PACACURRENT(r4) + LOADADDR(r4,init_task_union) + std r4,PACACURRENT(r13) - std r2,PACATOC(r4) + std r2,PACATOC(r13) li r5,0 - std r0,PACAKSAVE(r4) + std r0,PACAKSAVE(r13) /* ptr to hardware interrupt stack for processor 0 */ LOADADDR(r3, hardware_int_paca0) @@ -1991,10 +2177,10 @@ subi r5,r5,STACK_FRAME_OVERHEAD add r3,r3,r5 - std r3,PACAHRDWINTSTACK(r4) + std r3,PACAHRDWINTSTACK(r13) li r3,0 - stb r3,PACAHRDWINTCOUNT(r4) + stb r3,PACAHRDWINTCOUNT(r13) /* Restore the parms passed in from the bootloader. */ mr r3,r31 diff -urN linux-2.4.24/arch/ppc64/kernel/htab.c linux-2.4.25/arch/ppc64/kernel/htab.c --- linux-2.4.24/arch/ppc64/kernel/htab.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/htab.c 2004-02-18 05:36:30.000000000 -0800 @@ -1179,7 +1179,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) @@ -1200,7 +1200,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) diff -urN linux-2.4.24/arch/ppc64/kernel/i8259.c linux-2.4.25/arch/ppc64/kernel/i8259.c --- linux-2.4.24/arch/ppc64/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/i8259.c 2004-02-18 05:36:30.000000000 -0800 @@ -123,7 +123,8 @@ static void i8259_end_irq(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irqdesc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irqdesc(irq)->action) i8259_unmask_irq(irq); } diff -urN linux-2.4.24/arch/ppc64/kernel/iSeries_irq.c linux-2.4.25/arch/ppc64/kernel/iSeries_irq.c --- linux-2.4.24/arch/ppc64/kernel/iSeries_irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/iSeries_irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -70,15 +70,24 @@ void iSeries_init_irqMap(int irq); +void iSeries_init_irq_desc(irq_desc_t *desc) +{ + if (!desc->handler) + desc->handler = &iSeries_IRQ_handler; +} + /* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ void __init iSeries_init_IRQ(void) { int i; + irq_desc_t *desc; + for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = &iSeries_IRQ_handler; - irq_desc[i].status = 0; - irq_desc[i].status |= IRQ_DISABLED; - irq_desc[i].depth = 1; + desc = real_irqdesc(i); + desc->handler = &iSeries_IRQ_handler; + desc->status = 0; + desc->status |= IRQ_DISABLED; + desc->depth = 1; iSeries_init_irqMap(i); } /* Register PCI event handler and open an event path */ @@ -117,6 +126,7 @@ u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId; struct iSeries_irqEntry* newEntry; unsigned long flags; + irq_desc_t *desc = irqdesc(irq); if (irq < 0 || irq >= NR_IRQS) { return -1; @@ -132,7 +142,7 @@ * done during buswalk, but it should not hurt anything except a * little performance to be smp safe. *******************************************************************/ - spin_lock_irqsave(&irq_desc[irq].lock, flags); + spin_lock_irqsave(&desc->lock, flags); if (iSeries_irqMap[irq].valid) { /* Push the new element onto the irq stack */ @@ -147,7 +157,7 @@ kfree(newEntry); rc = -1; } - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); return rc; } @@ -179,10 +189,11 @@ int irq; unsigned long flags; for (irq=0; irq < NR_IRQS; irq++) { - spin_lock_irqsave(&irq_desc[irq].lock, flags); - irq_desc[irq].handler->startup(irq); - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); - } + irq_desc_t *desc = irqdesc(irq); + spin_lock_irqsave(&desc->lock, flags); + desc->handler->startup(irq); + spin_unlock_irqrestore(&desc->lock, flags); + } } /* this is not called anywhere currently */ diff -urN linux-2.4.24/arch/ppc64/kernel/iSeries_setup.c linux-2.4.25/arch/ppc64/kernel/iSeries_setup.c --- linux-2.4.24/arch/ppc64/kernel/iSeries_setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/iSeries_setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -63,6 +63,7 @@ extern void iSeries_pcibios_init(void); extern void iSeries_pcibios_fixup(void); extern void iSeries_pcibios_fixup_bus(int); +extern void iSeries_init_irq_desc(irq_desc_t *desc); /* Global Variables */ @@ -307,6 +308,7 @@ ppc_md.get_cpuinfo = iSeries_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = iSeries_init_IRQ; + ppc_md.init_irq_desc = iSeries_init_irq_desc; ppc_md.init_ras_IRQ = NULL; ppc_md.get_irq = iSeries_get_irq; ppc_md.init = NULL; @@ -702,6 +704,9 @@ systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; printk("Processor version = %x\n", systemcfg->processor); +#if defined(CONFIG_IRQ_ALL_CPUS) + do_spread_lpevents(MAX_PACAS); +#endif } /* diff -urN linux-2.4.24/arch/ppc64/kernel/idle.c linux-2.4.25/arch/ppc64/kernel/idle.c --- linux-2.4.24/arch/ppc64/kernel/idle.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/idle.c 2004-02-18 05:36:30.000000000 -0800 @@ -2,7 +2,12 @@ * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. * - * Written by Cort Dougan (cort@cs.nmt.edu) + * Originally Written by Cort Dougan (cort@cs.nmt.edu) + * + * iSeries supported added by Mike Corrigan + * + * Additional shared processor, SMT, and firmware support + * Copyright (c) 2003 Dave Engebretsen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -10,6 +15,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -28,17 +34,19 @@ #include #include #include +#include #include #include #include #include +int (*idle_loop)(void); + #ifdef CONFIG_PPC_ISERIES static void yield_shared_processor(void) { struct paca_struct *lpaca = get_paca(); - unsigned long tb; HvCall_setEnabledInterrupts( HvCall_MaskIPI | HvCall_MaskLpEvent | @@ -46,68 +54,180 @@ HvCall_MaskTimeout ); if ( ! ItLpQueue_isLpIntPending( paca->lpQueuePtr ) ) { - tb = get_tb(); - /* Compute future tb value when yield should expire */ - HvCall_yieldProcessor( HvCall_YieldTimed, tb+tb_ticks_per_jiffy ); + /* + * Compute future tb value when yield should expire. + * We want to be woken up when the next decrementer is + * to fire. + */ - /* The decrementer stops during the yield. Force a fake decrementer - * here and let the timer_interrupt code sort out the actual time. + __cli(); + lpaca->yielded = 1; /* Indicate a prod is desired */ + lpaca->xLpPaca.xIdle = 1; /* Inform the HV we are idle */ + + HvCall_yieldProcessor(HvCall_YieldTimed, + lpaca->next_jiffy_update_tb); + + lpaca->yielded = 0; /* Back to IPI's */ + __sti(); + + /* + * The decrementer stops during the yield. Force a fake + * decrementer here and let the timer_interrupt code sort + * out the actual time. */ lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 1; } process_iSeries_events(); } -#endif /* CONFIG_PPC_ISERIES */ -int idled(void) +int idle_iSeries(void) { struct paca_struct *lpaca; long oldval; -#ifdef CONFIG_PPC_ISERIES unsigned long CTRL; -#endif /* endless loop with no priority at all */ current->nice = 20; current->counter = -100; -#ifdef CONFIG_PPC_ISERIES + /* ensure iSeries run light will be out when idle */ current->thread.flags &= ~PPC_FLAG_RUN_LIGHT; CTRL = mfspr(CTRLF); CTRL &= ~RUNLATCH; mtspr(CTRLT, CTRL); -#endif init_idle(); lpaca = get_paca(); for (;;) { -#ifdef CONFIG_PPC_ISERIES if ( lpaca->xLpPaca.xSharedProc ) { if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) ) process_iSeries_events(); if ( !current->need_resched ) yield_shared_processor(); - } - else -#endif - { + } else { /* Avoid an IPI by setting need_resched */ oldval = xchg(¤t->need_resched, -1); if (!oldval) { while(current->need_resched == -1) { -#ifdef CONFIG_PPC_ISERIES HMT_medium(); if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) ) process_iSeries_events(); + HMT_low(); + } + } + } + HMT_medium(); + if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; + schedule(); + check_pgt_cache(); + } + } + return 0; +} #endif + +int idle_default(void) +{ + long oldval; + + current->nice = 20; + current->counter = -100; + init_idle(); + + for (;;) { + /* Avoid an IPI by setting need_resched */ + oldval = xchg(¤t->need_resched, -1); + if (!oldval) { + while(current->need_resched == -1) { HMT_low(); + } + } + HMT_medium(); + if (current->need_resched) { + schedule(); + check_pgt_cache(); + } + } + return 0; +} + +int idle_dedicated(void) +{ + long oldval; + struct paca_struct *lpaca = get_paca(), *ppaca;; + unsigned long start_snooze; + + ppaca = &paca[(lpaca->xPacaIndex) ^ 1]; + current->nice = 20; + current->counter = -100; + init_idle(); + + for (;;) { + /* Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. */ + lpaca->xLpPaca.xIdle = 1; + + /* Avoid an IPI by setting need_resched */ + oldval = xchg(¤t->need_resched, -1); + if (!oldval) { + start_snooze = __get_tb(); + while(current->need_resched == -1) { + if (__get_tb() < + (start_snooze + + naca->smt_snooze_delay*tb_ticks_per_usec)) { + HMT_low(); /* Low thread priority */ + continue; + } + + HMT_very_low(); /* Low power mode */ + + /* If the SMT mode is system controlled & the + * partner thread is doing work, switch into + * ST mode. + */ + if((naca->smt_state == SMT_DYNAMIC) && + (!(ppaca->xLpPaca.xIdle))) { + /* need_resched could be 1 or -1 at this + * point. If it is -1, set it to 0, so + * an IPI/Prod is sent. If it is 1, keep + * it that way & schedule work. + */ + oldval = xchg(¤t->need_resched, 0); + if(oldval == 1) { + current->need_resched = oldval; + break; + } + + /* DRENG: Go HMT_medium here ? */ + __cli(); + lpaca->yielded = 1; + + /* SMT dynamic mode. Cede will result + * in this thread going dormant, if the + * partner thread is still doing work. + * Thread wakes up if partner goes idle, + * an interrupt is presented, or a prod + * occurs. Returning from the cede + * enables external interrupts. + */ + cede_processor(); + + lpaca->yielded = 0; + } else { + /* Give the HV an opportunity at the + * processor, since we are not doing + * any work. + */ + poll_pending(); } } } HMT_medium(); if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; schedule(); check_pgt_cache(); } @@ -115,12 +235,78 @@ return 0; } +int idle_shared(void) +{ + struct paca_struct *lpaca = get_paca(); + + /* endless loop with no priority at all */ + current->nice = 20; + current->counter = -100; + + init_idle(); + + for (;;) { + /* Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. */ + lpaca->xLpPaca.xIdle = 1; + + if (!current->need_resched) { + __cli(); + lpaca->yielded = 1; + /* - * SMP entry into the idle task - calls the same thing as the - * non-smp versions. -- Cort + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. */ + cede_processor(); + + lpaca->yielded = 0; + } + + HMT_medium(); + if (current->need_resched) { + lpaca->xLpPaca.xIdle = 0; + schedule(); + check_pgt_cache(); + } + } + + return 0; +} + int cpu_idle(void) { - idled(); + idle_loop(); return 0; } + +int idle_setup(void) +{ +#ifdef CONFIG_PPC_ISERIES + idle_loop = idle_iSeries; +#else + if (systemcfg->platform & PLATFORM_PSERIES) { + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if(get_paca()->xLpPaca.xSharedProc) { + printk("idle = idle_shared\n"); + idle_loop = idle_shared; + } else { + printk("idle = idle_dedicated\n"); + idle_loop = idle_dedicated; + } + } else { + printk("idle = idle_default\n"); + idle_loop = idle_default; + } + } else { + printk("idle_setup: unknown platform, use idle_default\n"); + idle_loop = idle_default; + } +#endif + + return 1; +} + diff -urN linux-2.4.24/arch/ppc64/kernel/ioctl32.c linux-2.4.25/arch/ppc64/kernel/ioctl32.c --- linux-2.4.24/arch/ppc64/kernel/ioctl32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ioctl32.c 2004-02-18 05:36:30.000000000 -0800 @@ -566,11 +566,52 @@ goto out; } switch (ethcmd) { - case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break; + case ETHTOOL_GSTRINGS: { + struct ethtool_gstrings *stringsaddr = (struct ethtool_gstrings *)A(data); + if (get_user(len, (u32 *)&stringsaddr->len)) { + err = -EFAULT; + goto out; + } + if (len > (PAGE_SIZE - sizeof(struct ethtool_gstrings))/ETH_GSTRING_LEN ) { + err = -EINVAL; + goto out; + } + len = (len*ETH_GSTRING_LEN) + sizeof(struct ethtool_gstrings); + break; + } + case ETHTOOL_GSTATS: { + struct ethtool_stats *statsaddr = (struct ethtool_stats *)A(data); + if (get_user(len, (u32 *)&statsaddr->n_stats)) { + err = -EFAULT; + goto out; + } + if (len > (PAGE_SIZE - sizeof(struct ethtool_stats))/sizeof(u64) ) { + err = -EINVAL; + goto out; + } + len = (len*sizeof(u64)) + sizeof(struct ethtool_stats); + break; + } + case ETHTOOL_SWOL: + case ETHTOOL_GWOL: + len = sizeof(struct ethtool_wolinfo); + break; + case ETHTOOL_GDRVINFO: + len = sizeof(struct ethtool_drvinfo); + break; case ETHTOOL_GMSGLVL: case ETHTOOL_SMSGLVL: case ETHTOOL_GLINK: - case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break; + case ETHTOOL_NWAY_RST: + case ETHTOOL_SSG: + case ETHTOOL_GSG: + case ETHTOOL_GTXCSUM: + case ETHTOOL_STXCSUM: + case ETHTOOL_GRXCSUM: + case ETHTOOL_SRXCSUM: + case ETHTOOL_PHYS_ID: + len = sizeof(struct ethtool_value); + break; case ETHTOOL_GREGS: { struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data); /* darned variable size arguments */ @@ -578,22 +619,44 @@ err = -EFAULT; goto out; } + if (len > PAGE_SIZE - sizeof(struct ethtool_regs)) { + err = -EINVAL; + goto out; + } len += sizeof(struct ethtool_regs); break; } - case ETHTOOL_GEEPROM: - case ETHTOOL_SEEPROM: { - struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); - /* darned variable size arguments */ - if (get_user(len, (u32 *)&promaddr->len)) { - err = -EFAULT; - goto out; - } - len += sizeof(struct ethtool_eeprom); - break; - } + case ETHTOOL_GEEPROM: + case ETHTOOL_SEEPROM: { + struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); + /* darned variable size arguments */ + if (get_user(len, (u32 *)&promaddr->len)) { + err = -EFAULT; + goto out; + } + if (len > PAGE_SIZE - sizeof(struct ethtool_eeprom)) { + err = -EINVAL; + goto out; + } + len += sizeof(struct ethtool_eeprom); + break; + } + case ETHTOOL_GRINGPARAM: + case ETHTOOL_SRINGPARAM: + len = sizeof(struct ethtool_ringparam); + break; + case ETHTOOL_GPAUSEPARAM: + case ETHTOOL_SPAUSEPARAM: + len = sizeof(struct ethtool_pauseparam); + break; + case ETHTOOL_GCOALESCE: + case ETHTOOL_SCOALESCE: + len = sizeof(struct ethtool_coalesce); + break; case ETHTOOL_GSET: - case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break; + case ETHTOOL_SSET: + len = sizeof(struct ethtool_cmd); + break; default: err = -EOPNOTSUPP; goto out; @@ -1238,12 +1301,16 @@ u32 iov_len; } sg_iovec32_t; +#define EMU_SG_MAX 128 + static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32) { sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32); sg_iovec_t *kiov; int i; + if (sgp->iovec_count > EMU_SG_MAX) + return -EINVAL; sgp->dxferp = kmalloc(sgp->iovec_count * sizeof(sg_iovec_t), GFP_KERNEL); if (!sgp->dxferp) @@ -1257,39 +1324,9 @@ if (__get_user(iov_base32, &uiov->iov_base) || __get_user(kiov->iov_len, &uiov->iov_len)) return -EFAULT; - - kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL); - if (!kiov->iov_base) - return -ENOMEM; - if (copy_from_user(kiov->iov_base, - (void *) A(iov_base32), - kiov->iov_len)) + if (verify_area(VERIFY_WRITE, (void *)A(iov_base32), kiov->iov_len)) return -EFAULT; - - uiov++; - kiov++; - } - - return 0; -} - -static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32) -{ - sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32); - sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp; - int i; - - for (i = 0; i < sgp->iovec_count; i++) { - u32 iov_base32; - - if (__get_user(iov_base32, &uiov->iov_base)) - return -EFAULT; - - if (copy_to_user((void *) A(iov_base32), - kiov->iov_base, - kiov->iov_len)) - return -EFAULT; - + kiov->iov_base = (void *)A(iov_base32); uiov++; kiov++; } @@ -1299,16 +1336,6 @@ static void free_sg_iovec(sg_io_hdr_t *sgp) { - sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp; - int i; - - for (i = 0; i < sgp->iovec_count; i++) { - if (kiov->iov_base) { - kfree(kiov->iov_base); - kiov->iov_base = NULL; - } - kiov++; - } kfree(sgp->dxferp); sgp->dxferp = NULL; } @@ -1337,6 +1364,10 @@ sg_io64.sbp = NULL; err |= __get_user(cmdp32, &sg_io32->cmdp); + if (sg_io64.cmd_len > 4*PAGE_SIZE || sg_io64.mx_sb_len > 4*PAGE_SIZE) { + err = -EINVAL; + goto out; + } sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL); if (!sg_io64.cmdp) { err = -ENOMEM; @@ -1371,6 +1402,10 @@ goto out; } } else { + if (sg_io64.dxfer_len > 4*PAGE_SIZE) { + err = -EINVAL; + goto out; + } sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL); if (!sg_io64.dxferp) { err = -ENOMEM; @@ -1411,7 +1446,7 @@ err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len); if (sg_io64.dxferp) { if (sg_io64.iovec_count) - err |= copy_back_sg_iovec(&sg_io64, dxferp32); + ; else err |= copy_to_user((void *)A(dxferp32), sg_io64.dxferp, @@ -1467,6 +1502,8 @@ case PPPIOCSCOMPRESS32: if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32))) return -EFAULT; + if (data32.length > PAGE_SIZE) + return -EINVAL; data.ptr = kmalloc (data32.length, GFP_KERNEL); if (!data.ptr) return -ENOMEM; @@ -1669,10 +1706,9 @@ err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf); if (err) return -EFAULT; - data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL); - if (!data) - return -ENOMEM; - cdreadaudio.buf = data; + if (verify_area(VERIFY_WRITE, (void *)A(addr), cdreadaudio.nframes*2352)) + return -EFAULT; + cdreadaudio.buf = (void *)A(addr); break; case CDROM_SEND_PACKET: karg = &cgc; @@ -1681,9 +1717,9 @@ err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen); if (err) return -EFAULT; - if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL) - return -ENOMEM; - cgc.buffer = data; + if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen)) + return -EFAULT; + cgc.buffer = (void *)A(addr); break; default: do { @@ -1698,18 +1734,6 @@ set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)karg); set_fs (old_fs); - if (err) - goto out; - switch (cmd) { - case CDROMREADAUDIO: - err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352); - break; - case CDROM_SEND_PACKET: - err = copy_to_user((char *)A(addr), data, cgc.buflen); - break; - default: - break; - } out: if (data) kfree(data); return err ? -EFAULT : 0; @@ -2126,37 +2150,16 @@ if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) { iobuf.buffer = (void*)(unsigned long)iobuf32.buffer; } else { - iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL); - if (iobuf.buffer == NULL) { - err = -ENOMEM; - goto out; - } - - err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length); - if (err) { - err = -EFAULT; - goto out; - } + iobuf.buffer = A(iobuf32.buffer); + if (verify_area(VERIFY_WRITE, iobuf.buffer, iobuf.length)) + return -EINVAL; } old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); + err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); set_fs (old_fs); - if (err) - goto out; - - if (iobuf.buffer && iobuf.length > 0) { - err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length); - if (err) { - err = -EFAULT; - goto out; - } - } - err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); - - out: - if (iobuf32.buffer && iobuf32.length > 0) - kfree(iobuf.buffer); + if (!err) + err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); return err; } @@ -2179,40 +2182,19 @@ if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) { sioc.arg = (void*)(unsigned long)sioc32.arg; - } else { - sioc.arg = kmalloc(sioc.length, GFP_KERNEL); - if (sioc.arg == NULL) { - err = -ENOMEM; - goto out; - } - - err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length); - if (err) { - err = -EFAULT; - goto out; - } - } - - old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&sioc); - set_fs (old_fs); - if (err) { - goto out; + } else { + sioc.arg = A(sioc32.arg); + if (verify_area(VERIFY_WRITE, sioc.arg, sioc32.length)) + return -EFAULT; } - - if (sioc.arg && sioc.length > 0) { - err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length); - if (err) { - err = -EFAULT; - goto out; - } - } - err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); - - out: - if (sioc32.arg && sioc32.length > 0) - kfree(sioc.arg); - + + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&sioc); + set_fs (old_fs); + + if (!err) + err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); + return err; } @@ -2428,12 +2410,24 @@ return NULL; } if (ptr1) { + if (l->lv_allocated_le > 2*PAGE_SIZE/sizeof(pe_t)) { + kfree(l); + *errp = -EINVAL; + return NULL; + } size = l->lv_allocated_le * sizeof(pe_t); l->lv_current_pe = vmalloc(size); if (l->lv_current_pe) err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size); } if (!err && ptr2) { + /* small limit */ + /* just verify area it? */ + if (l->lv_remap_end > 256*PAGE_SIZE/sizeof(lv_block_exception_t)) { + put_lv_t(l); + *errp = -EINVAL; + return NULL; + } size = l->lv_remap_end * sizeof(lv_block_exception_t); l->lv_block_exception = lbe = vmalloc(size); if (l->lv_block_exception) { @@ -3597,17 +3591,11 @@ goto out; uptr = (void *) A(udata); - err = -ENOMEM; buflen = kurb->buffer_length; - kptr = kmalloc(buflen, GFP_KERNEL); - if (!kptr) - goto out; - - kurb->buffer = kptr; - err = -EFAULT; - if (copy_from_user(kptr, uptr, buflen)) - goto out_kptr; + err = verify_area(VERIFY_WRITE, uptr, buflen); + if (err) + goto out; old_fs = get_fs(); set_fs(KERNEL_DS); @@ -3618,15 +3606,9 @@ /* XXX Shit, this doesn't work for async URBs :-( XXX */ if (put_urb32(kurb, uurb)) { err = -EFAULT; - } else if ((kurb->endpoint & USB_DIR_IN) != 0) { - if (copy_to_user(uptr, kptr, buflen)) - err = -EFAULT; } } -out_kptr: - kfree(kptr); - out: kfree(kurb); return err; @@ -3698,14 +3680,13 @@ #define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32) #define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32) -static inline int +static inline int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg; struct mtd_oob_buf karg; u32 tmp; - char *ptr; int ret; if (get_user(karg.start, &uarg->start) || @@ -3713,21 +3694,12 @@ get_user(tmp, &uarg->ptr)) return -EFAULT; - ptr = (char *)A(tmp); - if (0 >= karg.length) - return -EINVAL; - - karg.ptr = kmalloc(karg.length, GFP_KERNEL); - if (NULL == karg.ptr) - return -ENOMEM; - - if (copy_from_user(karg.ptr, ptr, karg.length)) { - kfree(karg.ptr); + karg.ptr = A(tmp); + if (verify_area(VERIFY_WRITE, karg.ptr, karg.length)) return -EFAULT; - } set_fs(KERNEL_DS); - if (MEMREADOOB32 == cmd) + if (MEMREADOOB32 == cmd) ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg); else if (MEMWRITEOOB32 == cmd) ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg); @@ -3736,14 +3708,12 @@ set_fs(old_fs); if (0 == ret && cmd == MEMREADOOB32) { - ret = copy_to_user(ptr, karg.ptr, karg.length); - ret |= put_user(karg.start, &uarg->start); + ret = put_user(karg.start, &uarg->start); ret |= put_user(karg.length, &uarg->length); } - kfree(karg.ptr); - return ((0 == ret) ? 0 : -EFAULT); -} + return ret; +} /* Fix sizeof(sizeof()) breakage */ #define BLKELVGET_32 _IOR(0x12,106,int) @@ -3801,6 +3771,7 @@ COMPATIBLE_IOCTL(TCSETAW), COMPATIBLE_IOCTL(TCSETAF), COMPATIBLE_IOCTL(TCSBRK), +COMPATIBLE_IOCTL(TCSBRKP), COMPATIBLE_IOCTL(TCXONC), COMPATIBLE_IOCTL(TCFLSH), COMPATIBLE_IOCTL(TCGETS), @@ -3836,6 +3807,8 @@ COMPATIBLE_IOCTL(TIOCSSERIAL), COMPATIBLE_IOCTL(TIOCSERGETLSR), COMPATIBLE_IOCTL(TIOCSLTC), +COMPATIBLE_IOCTL(TIOCMIWAIT), +COMPATIBLE_IOCTL(TIOCGICOUNT), /* Big F */ COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO), COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO), diff -urN linux-2.4.24/arch/ppc64/kernel/irq.c linux-2.4.25/arch/ppc64/kernel/irq.c --- linux-2.4.24/arch/ppc64/kernel/irq.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/irq.c 2004-02-18 05:36:30.000000000 -0800 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -56,8 +57,47 @@ #include #include -#include "local_irq.h" +/* + * Because the name space for interrupts is so large on ppc64 systems we + * avoid declaring a single array of "NR_IRQ" interrupts and instead build + * a three level tree leading to the irq_desc_t (similar to page tables). + * + * Currently we cover 24-bit irq values: + * 10-bits: the "base" dir (2-pages) + * 9-bits: the "middle" dir (1-page) + * 5-bits: the "bottom" page (1-page) holding 128byte irq_desc's. + * + * We pack a hw_irq_stat struct directly after the irq_desc in the otherwise + * wasted space of the cacheline. + * + * MAX_IRQS is the max this implementation will support. + * It is much larger than NR_IRQS which is bogus on this arch and often used + * to declare arrays. + * + * Note that all "undefined" mid table and bottom table pointers will point + * to dummy tables. Therefore, we don't need to check for NULL on spurious + * interrupts. + */ + +#define IRQ_BASE_INDEX_SIZE 10 +#define IRQ_MID_INDEX_SIZE 9 +#define IRQ_BOT_DESC_SIZE 5 + +#define IRQ_BASE_PTRS (1 << IRQ_BASE_INDEX_SIZE) +#define IRQ_MID_PTRS (1 << IRQ_MID_INDEX_SIZE) +#define IRQ_BOT_DESCS (1 << IRQ_BOT_DESC_SIZE) + +#define IRQ_BASE_IDX_SHIFT (IRQ_MID_INDEX_SIZE + IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_SHIFT (IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_MASK ((1 << IRQ_MID_INDEX_SIZE) - 1) +#define IRQ_BOT_IDX_MASK ((1 << IRQ_BOT_DESC_SIZE) - 1) + +irq_desc_t **irq_desc_base_dir[IRQ_BASE_PTRS] __page_aligned = {0}; +irq_desc_t **irq_desc_mid_null; +irq_desc_t *irq_desc_bot_null; + +unsigned int _next_irq(unsigned int irq); atomic_t ipi_recv; atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); @@ -72,9 +112,10 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; - + +static irq_desc_t *add_irq_desc(unsigned int irq); + int ppc_spurious_interrupts = 0; -struct irqaction *ppc_irq_action[NR_IRQS]; unsigned long lpEvent_count = 0; #ifdef CONFIG_XMON extern void xmon(struct pt_regs *regs); @@ -93,16 +134,200 @@ extern void (*debugger_fault_handler)(struct pt_regs *regs); #endif -/* nasty hack for shared irq's since we need to do kmalloc calls but - * can't very early in the boot when we need to do a request irq. - * this needs to be removed. - * -- Cort - */ #define IRQ_KMALLOC_ENTRIES 16 static int cache_bitmask = 0; static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES]; extern int mem_init_done; +/* The hw_irq_stat struct is stored directly after the irq_desc_t + * in the same cacheline. We need to use care to make sure we don't + * overrun the size of the cacheline. + * + * Currently sizeof(irq_desc_t) is 40 bytes or less and this hw_irq_stat + * fills the rest of the cache line. + */ +struct hw_irq_stat { + unsigned long irqs; /* statistic per irq */ + unsigned long *per_cpu_stats; + struct proc_dir_entry *irq_dir, *smp_affinity; + unsigned long irq_affinity; /* ToDo: cpu bitmask */ +}; + +static inline struct hw_irq_stat *get_irq_stat(irq_desc_t *desc) +{ + /* WARNING: this assumes lock is the last field! */ + return (struct hw_irq_stat *)(&desc->lock+1); +} + +static inline unsigned long *get_irq_per_cpu(struct hw_irq_stat *hw) +{ + return hw->per_cpu_stats; +} + +static inline irq_desc_t **get_irq_mid_table(unsigned int irq) +{ + /* Assume irq < MAX_IRQS so we won't index off the end. */ + return irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT]; +} + +static inline irq_desc_t *get_irq_bot_table(unsigned int irq, + irq_desc_t **mid_ptr) +{ + return mid_ptr[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK]; +} + +/* This should be inline. */ +void *_irqdesc(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table, *desc; + + mid_table = get_irq_mid_table(irq); + bot_table = get_irq_bot_table(irq, mid_table); + + desc = bot_table + (irq & IRQ_BOT_IDX_MASK); + return desc; +} + +/* + * This is used by the for_each_irq(i) macro to iterate quickly over + * all interrupts. It optimizes by skipping over ptrs to the null tables + * when possible, but it may produce false positives. + */ +unsigned int _next_irq(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table; + + irq++; + /* Easy case first...staying on the current bot_table. */ + if (irq & IRQ_BOT_IDX_MASK) + return irq; + + /* Now skip empty mid tables */ + while (irq < MAX_IRQS && + (mid_table = get_irq_mid_table(irq)) == irq_desc_mid_null) { + /* index to the next base index (i.e. the next mid table) */ + irq = (irq & ~(IRQ_BASE_IDX_SHIFT-1)) + IRQ_BASE_IDX_SHIFT; + } + /* And skip empty bot tables */ + while (irq < MAX_IRQS && + (bot_table = get_irq_bot_table(irq, mid_table)) == irq_desc_bot_null) { + /* index to the next mid index (i.e. the next bot table) */ + irq = (irq & ~(IRQ_MID_IDX_SHIFT-1)) + IRQ_MID_IDX_SHIFT; + } + return irq; +} + + +/* Same as irqdesc(irq) except it will "fault in" a real desc as needed + * rather than return the null entry. + * This is used by code that is actually defining the irq. + * + * NULL may be returned on memory allocation failure. In general, init code + * doesn't look for this, but setup_irq does. In this failure case the desc + * is left pointing at the null pages so callers of irqdesc() should + * always return something. + */ +void *_real_irqdesc(unsigned int irq) +{ + irq_desc_t *desc = irqdesc(irq); + if (((unsigned long)desc & PAGE_MASK) == + (unsigned long)irq_desc_bot_null) { + desc = add_irq_desc(irq); + } + return desc; +} + +/* Allocate an irq middle page and init entries to null page. */ +static irq_desc_t **alloc_irq_mid_page(void) +{ + irq_desc_t **m, **ent; + + if (mem_init_done) + m = (irq_desc_t **)__get_free_page(GFP_KERNEL); + else + m = (irq_desc_t **)alloc_bootmem_pages(PAGE_SIZE); + if (m) { + for (ent = m; ent < m + IRQ_MID_PTRS; ent++) { + *ent = irq_desc_bot_null; + } + } + return m; +} + +/* Allocate an irq bottom page and init the entries. */ +static irq_desc_t *alloc_irq_bot_page(void) +{ + irq_desc_t *b, *ent; + if (mem_init_done) + b = (irq_desc_t *)get_zeroed_page(GFP_KERNEL); + else + b = (irq_desc_t *)alloc_bootmem_pages(PAGE_SIZE); + if (b) { + for (ent = b; ent < b + IRQ_BOT_DESCS; ent++) { + ent->lock = SPIN_LOCK_UNLOCKED; + } + } + return b; +} + +/* + * The universe of interrupt numbers ranges from 0 to 2^24. + * Use a sparsely populated tree to map from the irq to the handler. + * Top level is 2 contiguous pages, covering the 10 most significant + * bits. Mid level is 1 page, covering 9 bits. Last page covering + * 5 bits is the irq_desc, each of which is 128B. + */ +static void irq_desc_init(void) { + irq_desc_t ***entry_p; + + /* + * Now initialize the tables to point though the NULL tables for + * the default case of no interrupt handler (spurious). + */ + irq_desc_bot_null = alloc_irq_bot_page(); + irq_desc_mid_null = alloc_irq_mid_page(); + if (!irq_desc_bot_null || !irq_desc_mid_null) + panic("irq_desc_init: could not allocate pages\n"); + for(entry_p = irq_desc_base_dir; + entry_p < irq_desc_base_dir + IRQ_BASE_PTRS; + entry_p++) { + *entry_p = irq_desc_mid_null; + } +} + +/* + * Add a new irq desc for the given irq if needed. + * This breaks any ptr to the "null" middle or "bottom" irq desc page. + * Note that we don't ever coalesce pages as the interrupts are released. + * This isn't worth the effort. We add the cpu stats info when the + * interrupt is actually requested. + * + * May return NULL if memory could not be allocated. + */ +static irq_desc_t *add_irq_desc(unsigned int irq) +{ + irq_desc_t **mid_table_p, *bot_table_p; + + mid_table_p = get_irq_mid_table(irq); + if(mid_table_p == irq_desc_mid_null) { + /* No mid table for this IRQ - create it */ + mid_table_p = alloc_irq_mid_page(); + if (!mid_table_p) return NULL; + irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT] = mid_table_p; + } + + bot_table_p = (irq_desc_t *)(*(mid_table_p + ((irq >> 5) & 0x1ff))); + + if(bot_table_p == irq_desc_bot_null) { + /* No bot table for this IRQ - create it */ + bot_table_p = alloc_irq_bot_page(); + if (!bot_table_p) return NULL; + mid_table_p[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK] = bot_table_p; + } + + return bot_table_p + (irq & IRQ_BOT_IDX_MASK); +} + void *irq_kmalloc(size_t size, int pri) { unsigned int i; @@ -127,13 +352,44 @@ kfree(ptr); } +void allocate_per_cpu_stats(struct hw_irq_stat *hwstat) +{ + unsigned long *p; + + if (mem_init_done) { + p = (unsigned long *)kmalloc(sizeof(long)*NR_CPUS, GFP_KERNEL); + if (p) memset(p, 0, sizeof(long)*NR_CPUS); + } else + p = (unsigned long *)alloc_bootmem(sizeof(long)*NR_CPUS); + hwstat->per_cpu_stats = p; +} + int setup_irq(unsigned int irq, struct irqaction * new) { int shared = 0; unsigned long flags; struct irqaction *old, **p; - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = real_irqdesc(irq); + struct hw_irq_stat *hwstat; + + if (!desc) + return -ENOMEM; + + ppc_md.init_irq_desc(desc); + + hwstat = get_irq_stat(desc); + +#ifdef CONFIG_IRQ_ALL_CPUS + hwstat->irq_affinity = ~0; +#else + hwstat->irq_affinity = 0; +#endif + + /* Now is the time to add per-cpu kstat data to the desc + * since it appears we are actually going to use the irq. + */ + allocate_per_cpu_stats(hwstat); /* * Some drivers like serial.c use request_irq() heavily, @@ -189,11 +445,10 @@ static int do_free_irq(int irq, void* dev_id) { - irq_desc_t *desc; + irq_desc_t *desc = irqdesc(irq); struct irqaction **p; unsigned long flags; - desc = irq_desc + irq; spin_lock_irqsave(&desc->lock,flags); p = &desc->action; for (;;) { @@ -233,8 +488,9 @@ struct irqaction *action; int retval; - if (irq >= NR_IRQS) + if (irq >= MAX_IRQS) return -EINVAL; + if (!handler) /* We could implement really free_irq() instead of that... */ return do_free_irq(irq, dev_id); @@ -285,7 +541,7 @@ void disable_irq_nosync(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -317,7 +573,7 @@ if (!local_irq_count(smp_processor_id())) { do { barrier(); - } while (irq_desc[irq].status & IRQ_INPROGRESS); + } while (irqdesc(irq)->status & IRQ_INPROGRESS); } } @@ -333,7 +589,7 @@ void enable_irq(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -357,82 +613,57 @@ spin_unlock_irqrestore(&desc->lock, flags); } -/* one would think this function has one foot in the grave */ +/* This function as implemented was a potential source of data + * corruption. I pulled it for now, until it can be properly + * implemented. DRENG + */ int get_irq_list(char *buf) { - int i, len = 0, j; - struct irqaction * action; - - len += sprintf(buf+len, " "); - for (j=0; jhandler ) - continue; - len += sprintf(buf+len, "%3d: ", i); -#ifdef CONFIG_SMP - for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf+len, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); -#else - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ -if ( irq_desc[i].handler ) -len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); -else -len += sprintf(buf+len, " None "); -len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); -len += sprintf(buf+len, " %s",action->name); -for (action=action->next; action; action = action->next) { -len += sprintf(buf+len, ", %s", action->name); -} -len += sprintf(buf+len, "\n"); + return(0); } -#ifdef CONFIG_SMP -/* should this be per processor send/receive? */ -len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", -atomic_read(&ipi_recv), atomic_read(&ipi_sent)); -#endif -len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); -return len; -} - - int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + unsigned long flags; seq_printf(p, " "); for (j=0; jlock, flags); + action = desc->action; + if (!action || !action->handler) - continue; - seq_printf(p, "%3d: ", i); -#ifdef CONFIG_SMP + goto skip; + seq_printf(p, "%3d: ", i); + hwstat = get_irq_stat(desc); + per_cpus = get_irq_per_cpu(hwstat); + if (per_cpus) { for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); -#else - seq_printf(p, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ - if (irq_desc[i].handler) - seq_printf(p, " %s ", irq_desc[i].handler->typename ); + seq_printf(p, "%10lu ", per_cpus[j]); + } else { + seq_printf(p, "%10lu ", hwstat->irqs); + } + + if (irqdesc(i)->handler) + seq_printf(p, " %s ", irqdesc(i)->handler->typename ); else seq_printf(p, " None "); - seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); + seq_printf(p, "%s", (irqdesc(i)->status & IRQ_LEVEL) ? "Level " : "Edge "); seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&desc->lock, flags); } #ifdef CONFIG_SMP /* should this be per processor send/receive? */ @@ -470,9 +701,24 @@ int status; struct irqaction *action; int cpu = smp_processor_id(); - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + + /* Statistics. */ + hwstat = get_irq_stat(desc); /* same cache line as desc */ + hwstat->irqs++; + per_cpus = get_irq_per_cpu(hwstat); /* same cache line for < 8 cpus */ + if (per_cpus) + per_cpus[cpu]++; + if(irq < NR_IRQS) { kstat.irqs[cpu][irq]++; + } else { + kstat.irqs[cpu][NR_IRQS-1]++; + } + + spin_lock(&desc->lock); ack_irq(irq); /* @@ -544,11 +790,11 @@ * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); + if (desc->handler) { + if (desc->handler->end) + desc->handler->end(irq); + else if (desc->handler->enable) + desc->handler->enable(irq); } spin_unlock(&desc->lock); } @@ -638,7 +884,10 @@ return; else once++; - + + /* Initialize the irq tree */ + irq_desc_init(); + ppc_md.init_IRQ(); if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); } @@ -794,6 +1043,7 @@ #endif /* CONFIG_SMP */ static struct proc_dir_entry * root_irq_dir; +#if 0 static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; @@ -802,15 +1052,19 @@ #else /* CONFIG_IRQ_ALL_CPUS */ unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; #endif /* CONFIG_IRQ_ALL_CPUS */ +#endif #define HEX_DIGITS 8 static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + irq_desc_t *desc = irqdesc((long)data); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]); + return sprintf(page, "%16lx\n", hwstat->irq_affinity); } static unsigned int parse_hex_value (const char *buffer, @@ -853,10 +1107,13 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (int)(long) data, full_count = count, err; + unsigned int irq = (long)data; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + int full_count = count, err; unsigned long new_value; - if (!irq_desc[irq].handler->set_affinity) + if (!desc->handler->set_affinity) return -EIO; err = parse_hex_value(buffer, count, &new_value); @@ -871,10 +1128,8 @@ if (!(new_value & cpu_online_map)) return -EINVAL; #endif - - irq_affinity[irq] = new_value; - irq_desc[irq].handler->set_affinity(irq, new_value); - + hwstat->irq_affinity = new_value; + desc->handler->set_affinity(irq, new_value); return full_count; } @@ -923,25 +1178,39 @@ { struct proc_dir_entry *entry; char name [MAX_NAMELEN]; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; - if (!root_irq_dir || (irq_desc[irq].handler == NULL)) + desc = real_irqdesc(irq); + if (!root_irq_dir || !desc || !desc->handler) + return; + hwstat = get_irq_stat(desc); + if (hwstat->irq_dir) return; memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ - irq_dir[irq] = proc_mkdir(name, root_irq_dir); + hwstat->irq_dir = proc_mkdir(name, root_irq_dir); + if(hwstat->irq_dir == NULL) { + printk(KERN_ERR "register_irq_proc: proc_mkdir failed.\n"); + return; + } /* create /proc/irq/1234/smp_affinity */ - entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); + entry = create_proc_entry("smp_affinity", 0600, hwstat->irq_dir); - entry->nlink = 1; - entry->data = (void *)(long)irq; - entry->read_proc = irq_affinity_read_proc; - entry->write_proc = irq_affinity_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } else { + printk(KERN_ERR "register_irq_proc: create_proc_entry failed.\n"); + } - smp_affinity_entry[irq] = entry; + hwstat->smp_affinity = entry; } unsigned long prof_cpu_mask = -1; @@ -953,20 +1222,27 @@ /* create /proc/irq */ root_irq_dir = proc_mkdir("irq", 0); + if(root_irq_dir == NULL) { + printk(KERN_ERR "init_irq_proc: proc_mkdir failed.\n"); + } /* create /proc/irq/prof_cpu_mask */ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); - entry->nlink = 1; - entry->data = (void *)&prof_cpu_mask; - entry->read_proc = prof_cpu_mask_read_proc; - entry->write_proc = prof_cpu_mask_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + } else { + printk(KERN_ERR "init_irq_proc: create_proc_entry failed.\n"); + } /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == NULL) + for_each_irq(i) { + if (irqdesc(i)->handler == NULL) continue; register_irq_proc(i); } diff -urN linux-2.4.24/arch/ppc64/kernel/lparcfg.c linux-2.4.25/arch/ppc64/kernel/lparcfg.c --- linux-2.4.24/arch/ppc64/kernel/lparcfg.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/lparcfg.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,477 @@ +/* + * PowerPC64 LPAR Configuration Information Driver + * + * Dave Engebretsen engebret@us.ibm.com + * Copyright (c) 2003 Dave Engebretsen + * Will Schmidt willschm@us.ibm.com + * SPLPAR updates, Copyright (c) 2003 Will Schmidt IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This driver creates a proc file at /proc/ppc64/lparcfg which contains + * keyword - value pairs that specify the configuration of the partition. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_VERSION "1.0" +#define MODULE_NAME "lparcfg" + +static struct proc_dir_entry *proc_ppc64_lparcfg; +#define LPARCFG_BUFF_SIZE 4096 + +#ifdef CONFIG_PPC_ISERIES +static unsigned char e2a(unsigned char x) +{ + switch (x) { + case 0xF0: + return '0'; + case 0xF1: + return '1'; + case 0xF2: + return '2'; + case 0xF3: + return '3'; + case 0xF4: + return '4'; + case 0xF5: + return '5'; + case 0xF6: + return '6'; + case 0xF7: + return '7'; + case 0xF8: + return '8'; + case 0xF9: + return '9'; + case 0xC1: + return 'A'; + case 0xC2: + return 'B'; + case 0xC3: + return 'C'; + case 0xC4: + return 'D'; + case 0xC5: + return 'E'; + case 0xC6: + return 'F'; + case 0xC7: + return 'G'; + case 0xC8: + return 'H'; + case 0xC9: + return 'I'; + case 0xD1: + return 'J'; + case 0xD2: + return 'K'; + case 0xD3: + return 'L'; + case 0xD4: + return 'M'; + case 0xD5: + return 'N'; + case 0xD6: + return 'O'; + case 0xD7: + return 'P'; + case 0xD8: + return 'Q'; + case 0xD9: + return 'R'; + case 0xE2: + return 'S'; + case 0xE3: + return 'T'; + case 0xE4: + return 'U'; + case 0xE5: + return 'V'; + case 0xE6: + return 'W'; + case 0xE7: + return 'X'; + case 0xE8: + return 'Y'; + case 0xE9: + return 'Z'; + } + return ' '; +} + +/* + * Methods used to fetch LPAR data when running on an iSeries platform. + */ +static int lparcfg_data(unsigned char *buf, unsigned long size) +{ + unsigned long n = 0, pool_id, lp_index; + int shared, entitled_capacity, max_entitled_capacity; + int processors, max_processors; + struct paca_struct *lpaca = get_paca(); + + if((buf == NULL) || (size > LPARCFG_BUFF_SIZE)) { + return -EFAULT; + } + memset(buf, 0, size); + + shared = (int)(lpaca->xLpPacaPtr->xSharedProc); + n += snprintf(buf, LPARCFG_BUFF_SIZE - n, + "serial_number=%c%c%c%c%c%c%c\n", + e2a(xItExtVpdPanel.mfgID[2]), + e2a(xItExtVpdPanel.mfgID[3]), + e2a(xItExtVpdPanel.systemSerial[1]), + e2a(xItExtVpdPanel.systemSerial[2]), + e2a(xItExtVpdPanel.systemSerial[3]), + e2a(xItExtVpdPanel.systemSerial[4]), + e2a(xItExtVpdPanel.systemSerial[5])); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_type=%c%c%c%c\n", + e2a(xItExtVpdPanel.machineType[0]), + e2a(xItExtVpdPanel.machineType[1]), + e2a(xItExtVpdPanel.machineType[2]), + e2a(xItExtVpdPanel.machineType[3])); + + lp_index = HvLpConfig_getLpIndex(); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_id=%d\n", (int)lp_index); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_active_processors=%d\n", + (int)HvLpConfig_getSystemPhysicalProcessors()); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_potential_processors=%d\n", + (int)HvLpConfig_getSystemPhysicalProcessors()); + + processors = (int)HvLpConfig_getPhysicalProcessors(); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_active_processors=%d\n", processors); + + max_processors = (int)HvLpConfig_getMaxPhysicalProcessors(); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_potential_processors=%d\n", max_processors); + + if(shared) { + entitled_capacity = HvLpConfig_getSharedProcUnits(); + max_entitled_capacity = HvLpConfig_getMaxSharedProcUnits(); + } else { + entitled_capacity = processors * 100; + max_entitled_capacity = max_processors * 100; + } + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_entitled_capacity=%d\n", entitled_capacity); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_max_entitled_capacity=%d\n", + max_entitled_capacity); + + if(shared) { + pool_id = HvLpConfig_getSharedPoolIndex(); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, "pool=%d\n", + (int)pool_id); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "pool_capacity=%d\n", (int)(HvLpConfig_getNumProcsInSharedPool(pool_id)*100)); + } + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "shared_processor_mode=%d\n", shared); + + return 0; +} +#endif /* CONFIG_PPC_ISERIES */ + +#ifdef CONFIG_PPC_PSERIES +/* + * Methods used to fetch LPAR data when running on a pSeries platform. + */ + +/* + * H_GET_PPP hcall returns info in 4 parms. + * entitled_capacity,unallocated_capacity, + * aggregation, resource_capability). + * + * R4 = Entitled Processor Capacity Percentage. + * R5 = Unallocated Processor Capacity Percentage. + * R6 (AABBCCDDEEFFGGHH). + * XXXX - reserved (0) + * XXXX - reserved (0) + * XXXX - Group Number + * XXXX - Pool Number. + * R7 (PPOONNMMLLKKJJII) + * XX - reserved. (0) + * XX - bit 0-6 reserved (0). bit 7 is Capped indicator. + * XX - variable processor Capacity Weight + * XX - Unallocated Variable Processor Capacity Weight. + * XXXX - Active processors in Physical Processor Pool. + * XXXX - Processors active on platform. + */ +unsigned int h_get_ppp(unsigned long *entitled,unsigned long *unallocated,unsigned long *aggregation,unsigned long *resource) +{ + unsigned long rc; + rc = plpar_hcall_4out(H_GET_PPP,0,0,0,0,entitled,unallocated,aggregation,resource); + return 0; +} + +/* + * get_splpar_potential_characteristics(). + * Retrieve the potential_processors and max_entitled_capacity values + * through the get-system-parameter rtas call. + */ +#define SPLPAR_CHARACTERISTICS_TOKEN 20 +#define SPLPAR_MAXLENGTH 1026*(sizeof(char)) +unsigned int get_splpar_potential_characteristics() +{ + /* return 0 for now. Underlying rtas functionality is not yet complete. 12/01/2003*/ + return 0; +#if 0 + long call_status; + unsigned long ret[2]; + + char * buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); + + printk("token for ibm,get-system-parameter (0x%x)\n",rtas_token("ibm,get-system-parameter")); + + call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, + NULL, + SPLPAR_CHARACTERISTICS_TOKEN, + &buffer, + SPLPAR_MAXLENGTH, + (void *)&ret); + + if (call_status!=0) { + printk("Error calling get-system-parameter (0x%lx)\n",call_status); + kfree(buffer); + return -1; + } else { + printk("get-system-parameter (%s)\n",buffer); + kfree(buffer); + /* TODO: Add code here to parse out value for system_potential_processors and partition_max_entitled_capacity */ + return 1; + } +#endif +} + +static int lparcfg_data(unsigned char *buf, unsigned long size) +{ + unsigned long n = 0; + int shared, max_entitled_capacity; + int processors, system_active_processors, system_potential_processors; + struct device_node *root; + const char *model = ""; + const char *system_id = ""; + unsigned int *lp_index_ptr, lp_index = 0; + struct device_node *rtas_node; + int *ip; + unsigned long h_entitled,h_unallocated,h_aggregation,h_resource; + + if((buf == NULL) || (size > LPARCFG_BUFF_SIZE)) { + return -EFAULT; + } + memset(buf, 0, size); + + root = find_path_device("/"); + if (root) { + model = get_property(root, "model", NULL); + system_id = get_property(root, "system-id", NULL); + lp_index_ptr = (unsigned int *)get_property(root, "ibm,partition-no", NULL); + if(lp_index_ptr) lp_index = *lp_index_ptr; + } + + n = snprintf(buf, LPARCFG_BUFF_SIZE - n, + "serial_number=%s\n", system_id); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_type=%s\n", model); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_id=%d\n", (int)lp_index); + + rtas_node = find_path_device("/rtas"); + ip = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL); + if (ip == NULL) { + system_active_processors = systemcfg->processorCount; + } else { + system_active_processors = *(ip + 4); + } + + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + h_get_ppp(&h_entitled,&h_unallocated,&h_aggregation,&h_resource); +#ifdef DEBUG + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "R4=0x%lx\n", h_entitled); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "R5=0x%lx\n", h_unallocated); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "R6=0x%lx\n", h_aggregation); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "R7=0x%lx\n", h_resource); +#endif /* DEBUG */ + } + + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + system_potential_processors = get_splpar_potential_characteristics(); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_active_processors=%d\n", + (h_resource >> 2*8) && 0xffff); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_potential_processors=%d\n", + system_potential_processors); + } else { + system_potential_processors = system_active_processors; + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_active_processors=%d\n", + system_active_processors); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "system_potential_processors=%d\n", + system_potential_processors); + } + + processors = systemcfg->processorCount; + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_active_processors=%d\n", processors); + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_potential_processors=%d\n", + system_active_processors); + + max_entitled_capacity = system_active_processors * 100; + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_entitled_capacity=%ld\n", h_entitled); + } else { + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_entitled_capacity=%d\n", system_active_processors*100); + } + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "partition_max_entitled_capacity=%d\n", + max_entitled_capacity); + + shared = 0; + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "shared_processor_mode=%d\n", shared); + + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "pool=%d\n", (h_aggregation >> 0*8)&&0xffff); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "pool_capacity=%d\n", (h_resource >> 3*8) &&0xffff); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "group=%d\n", (h_aggregation >> 2*8)&&0xffff); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "capped=%d\n", (h_resource >> 6*8)&&0x40); + + n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, + "capacity_weight=%d\n", (int)(h_resource>>5*8)&0xFF); + } + return 0; +} +#endif /* CONFIG_PPC_PSERIES */ + + +static ssize_t lparcfg_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + unsigned long *data = (unsigned long *)dp->data; + unsigned long p; + ssize_t read; + char * pnt; + + if (!data) { + printk(KERN_ERR "lparcfg: read failed no data\n"); + return -EIO; + } + + if(ppos) { + p = *ppos; + } else { + return -EFAULT; + } + + if (p >= LPARCFG_BUFF_SIZE) return 0; + + lparcfg_data((unsigned char *)data, LPARCFG_BUFF_SIZE); + if (count > (strlen((char *)data) - p)) + count = (strlen((char *)data)) - p; + read = 0; + + pnt = (char *)(data) + p; + copy_to_user(buf, (void *)pnt, count); + read += count; + *ppos += read; + return read; +} + +static int lparcfg_open(struct inode * inode, struct file * file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + unsigned int *data = (unsigned int *)dp->data; + + if (!data) { + printk(KERN_ERR "lparcfg: open failed no data\n"); + return -EIO; + } + + return 0; +} + +struct file_operations lparcfg_fops = { + owner: THIS_MODULE, + read: lparcfg_read, + open: lparcfg_open, +}; + +int __init lparcfg_init(void) +{ + struct proc_dir_entry *ent; + + ent = create_proc_entry("ppc64/lparcfg", S_IRUSR, NULL); + if (ent) { + ent->proc_fops = &lparcfg_fops; + ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL); + if (!ent->data) { + printk(KERN_ERR "Failed to allocate buffer for lparcfg\n"); + remove_proc_entry("lparcfg", ent->parent); + return -ENOMEM; + } + } else { + printk(KERN_ERR "Failed to create ppc64/lparcfg\n"); + return -EIO; + } + + proc_ppc64_lparcfg = ent; + return 0; +} + +void __exit lparcfg_cleanup(void) +{ + if (proc_ppc64_lparcfg) { + if (proc_ppc64_lparcfg->data) { + kfree(proc_ppc64_lparcfg->data); + } + remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); + } +} + +module_init(lparcfg_init); +module_exit(lparcfg_cleanup); +MODULE_DESCRIPTION("Interface for LPAR configuration data"); +MODULE_AUTHOR("Dave Engebretsen"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/arch/ppc64/kernel/mf_proc.c linux-2.4.25/arch/ppc64/kernel/mf_proc.c --- linux-2.4.24/arch/ppc64/kernel/mf_proc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/mf_proc.c 2004-02-18 05:36:30.000000000 -0800 @@ -220,19 +220,22 @@ int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data) { + char side; + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (count == 0) + return 0; + if (get_user(side, buffer)) + return -EFAULT; - if ((*buffer != 'A') && - (*buffer != 'B') && - (*buffer != 'C') && - (*buffer != 'D')) + if ((side != 'A') && (side != 'B') && (side != 'C') && (side != 'D')) { printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n"); return -EINVAL; } - mf_setSide(*buffer); + mf_setSide(side); return count; } @@ -256,20 +259,24 @@ int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data) { + char stkbuf[10]; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if ((count < 4) && (count != 1)) - { + if ((count < 4) && (count != 1)) { printk(KERN_ERR "mf_proc: invalid src\n"); return -EINVAL; } - if ((count == 1) && ((*buffer) == '\0')) - { + if (count > 9) + count = 9; + if (copy_from_user (stkbuf, buffer, count)) + return -EFAULT; + + if ((count == 1) && ((*stkbuf) == '\0')) { mf_clearSrc(); } else { - mf_displaySrc(*(u32 *)buffer); + mf_displaySrc(*(u32 *)stkbuf); } return count; diff -urN linux-2.4.24/arch/ppc64/kernel/misc.S linux-2.4.25/arch/ppc64/kernel/misc.S --- linux-2.4.24/arch/ppc64/kernel/misc.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/misc.S 2004-02-18 05:36:30.000000000 -0800 @@ -69,16 +69,14 @@ _GLOBAL(__no_use_save_flags) mfspr r4,SPRG3 lbz r3,PACAPROCENABLED(r4) + /* shift into position of MSR.EE */ + sldi r3,r3,15 blr -/* void __no_use_restore_flags(unsigned long flags) */ +/* void __no_use_restore_flags(unsigned long flags) */ _GLOBAL(__no_use_restore_flags) -/* - * Just set/clear the MSR_EE bit through restore/flags but do not - * change anything else. This is needed by the RT system and makes - * sense anyway. - * -- Cort - */ + /* shift from position of MSR.EE */ + srdi r3,r3,15 mfspr r6,SPRG3 lbz r5,PACAPROCENABLED(r6) /* Check if things are setup the way we want _already_. */ @@ -104,6 +102,8 @@ lbz r3,PACAPROCENABLED(r5) li r4,0 stb r4,PACAPROCENABLED(r5) + /* shift into position of MSR.EE */ + sldi r3,r3,15 blr /* Done */ _GLOBAL(__no_use_sti) @@ -505,6 +505,9 @@ * r3 = data offset (not changed) */ _GLOBAL(do_cpu_ftr_fixups) +/* Dummy feature section to make sure section exists */ +BEGIN_FTR_SECTION +END_FTR_SECTION(0,0) /* Get CPU 0 features */ LOADADDR(r6,cur_cpu_spec) sub r6,r6,r3 @@ -578,9 +581,10 @@ bnelr /* return if parent */ li r0,0 /* clear out p->thread.regs */ - std r0,THREAD+PT_REGS(r13) /* since we don't have user ctx */ + ld r7,PACACURRENT(r13) + std r0,THREAD+PT_REGS(r7) /* since we don't have user ctx */ li r0,RUN_FLAG /* Run light on */ - std r0,THREAD+THREAD_FLAGS(r13) + std r0,THREAD+THREAD_FLAGS(r7) ld r2,8(r6) ld r6,0(r6) diff -urN linux-2.4.24/arch/ppc64/kernel/mk_defs.c linux-2.4.25/arch/ppc64/kernel/mk_defs.c --- linux-2.4.24/arch/ppc64/kernel/mk_defs.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/mk_defs.c 2004-02-18 05:36:30.000000000 -0800 @@ -133,6 +133,11 @@ DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); +#ifdef CONFIG_ALTIVEC + DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0])); + DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); + DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr)); +#endif /* CONFIG_ALTIVEC */ DEFINE(THREAD_FLAGS, offsetof(struct thread_struct, flags)); DEFINE(PPC_FLAG_32BIT, PPC_FLAG_32BIT); /* @@ -196,5 +201,12 @@ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + /* About the CPU features table */ + DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); + DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask)); + DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); + DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); + DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + return 0; } diff -urN linux-2.4.24/arch/ppc64/kernel/nvram.c linux-2.4.25/arch/ppc64/kernel/nvram.c --- linux-2.4.24/arch/ppc64/kernel/nvram.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/nvram.c 2004-02-18 05:36:30.000000000 -0800 @@ -20,16 +20,44 @@ #include #include #include +#include +#include #include #include #include #include -static unsigned int rtas_nvram_size; +#include + +/*#define DEBUG_NVRAM*/ + +static int scan_nvram_partitions(void); +static int setup_nvram_partition(void); +static int create_os_nvram_partition(void); +static int remove_os_nvram_partition(void); +static unsigned char nvram_checksum(struct nvram_header *p); +static int write_nvram_header(struct nvram_partition * part); +static ssize_t __read_nvram(char *buf, size_t count, loff_t *index); +static ssize_t __write_nvram(char *buf, size_t count, loff_t *index); + +static unsigned int rtas_nvram_size = 0; static unsigned int nvram_fetch, nvram_store; -static char nvram_buf[4]; /* assume this is in the first 4GB */ +static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ +static struct nvram_partition * nvram_part; +static long error_log_nvram_index = -1; +static long error_log_nvram_size = 0; +static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; + +volatile int no_more_logging = 1; + +extern volatile int error_log_cnt; + +struct err_log_info { + int error_type; + unsigned int seq_num; +}; -static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) +static loff_t dev_ppc64_nvram_llseek(struct file *file, loff_t offset, int origin) { switch (origin) { case 1: @@ -46,53 +74,72 @@ } -static ssize_t read_nvram(struct file *file, char *buf, +static ssize_t dev_ppc64_read_nvram(struct file *file, char *buf, size_t count, loff_t *ppos) { - unsigned int i; unsigned long len; - char *p = buf; + char *tmp_buffer; if (verify_area(VERIFY_WRITE, buf, count)) return -EFAULT; if (*ppos >= rtas_nvram_size) return 0; - for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) { - if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) || - len != 1) - return -EIO; - if (__put_user(nvram_buf[0], p)) - return -EFAULT; + if (count > rtas_nvram_size) + count = rtas_nvram_size; + + tmp_buffer = kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_ppc64_read_nvram: kmalloc failed\n"); + return 0; } - *ppos = i; - return p - buf; + + len = read_nvram(tmp_buffer, count, ppos); + if ((long)len <= 0) { + kfree(tmp_buffer); + return len; + } + + if (copy_to_user(buf, tmp_buffer, len)) { + kfree(tmp_buffer); + return -EFAULT; + } + + kfree(tmp_buffer); + return len; + } -static ssize_t write_nvram(struct file *file, const char *buf, +static ssize_t dev_ppc64_write_nvram(struct file *file, const char *buf, size_t count, loff_t *ppos) { - unsigned int i; unsigned long len; - const char *p = buf; - char c; + char * tmp_buffer; if (verify_area(VERIFY_READ, buf, count)) return -EFAULT; if (*ppos >= rtas_nvram_size) return 0; - for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) { - if (__get_user(c, p)) - return -EFAULT; - nvram_buf[0] = c; - if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) || - len != 1) - return -EIO; + if (count > rtas_nvram_size) + count = rtas_nvram_size; + + tmp_buffer = kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_ppc64_write_nvram: kmalloc failed\n"); + return 0; } - *ppos = i; - return p - buf; + + if (copy_from_user(tmp_buffer, buf, count)) { + kfree(tmp_buffer); + return -EFAULT; + } + + len = write_nvram(tmp_buffer, count, ppos); + + kfree(tmp_buffer); + return len; } -static int nvram_ioctl(struct inode *inode, struct file *file, +static int dev_ppc64_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return -EINVAL; @@ -100,10 +147,10 @@ struct file_operations nvram_fops = { .owner = THIS_MODULE, - .llseek = nvram_llseek, - .read = read_nvram, - .write = write_nvram, - .ioctl = nvram_ioctl, + .llseek = dev_ppc64_nvram_llseek, + .read = dev_ppc64_read_nvram, + .write = dev_ppc64_write_nvram, + .ioctl = dev_ppc64_nvram_ioctl }; static struct miscdevice nvram_dev = { @@ -112,26 +159,613 @@ &nvram_fops }; +ssize_t read_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned long s; + ssize_t rc; + + spin_lock_irqsave(&nvram_lock, s); + rc = __read_nvram(buf, count, index); + spin_unlock_irqrestore(&nvram_lock, s); + + return rc; +} +static ssize_t __read_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned int i; + unsigned long len; + unsigned long remainder; + char *p = buf; + + if (((*index + count) > rtas_nvram_size) || (count < 0)) + return 0; + + if (count <= NVRW_CNT) { + remainder = count; + } else { + remainder = count % NVRW_CNT; + } + + if (remainder) { + if((rtas_call(nvram_fetch, 3, 2, &len, *index, __pa(nvram_buf), + remainder) != 0) || len != remainder) { + return -EIO; + } + + count -= remainder; + memcpy(p, nvram_buf, remainder); + p += remainder; + } + + for (i = *index + remainder; count > 0 && i < rtas_nvram_size; + count -= NVRW_CNT) { + if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), + NVRW_CNT) != 0) || len != NVRW_CNT) { + return -EIO; + } + + memcpy(p, nvram_buf, NVRW_CNT); + + p += NVRW_CNT; + i += NVRW_CNT; + } + + *index = i; + return p - buf; +} + +ssize_t write_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned long s; + ssize_t rc; + + spin_lock_irqsave(&nvram_lock, s); + rc = __write_nvram(buf, count, index); + spin_unlock_irqrestore(&nvram_lock, s); + + return rc; +} +static ssize_t __write_nvram(char *buf, size_t count, loff_t *index) +{ + unsigned int i; + unsigned long len; + const char *p = buf; + unsigned long remainder; + + if (((*index + count) > rtas_nvram_size) || (count < 0)) + return 0; + + if (count <= NVRW_CNT) { + remainder = count; + } else { + remainder = count % NVRW_CNT; + } + + if (remainder) { + memcpy(nvram_buf, p, remainder); + + if((rtas_call(nvram_store, 3, 2, &len, *index, __pa(nvram_buf), + remainder) != 0) || len != remainder) { + return -EIO; + } + + count -= remainder; + p += remainder; + } + + for (i = *index + remainder; count > 0 && i < rtas_nvram_size; + count -= NVRW_CNT) { + + memcpy(nvram_buf, p, NVRW_CNT); + + if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), + NVRW_CNT) != 0) || len != NVRW_CNT) { + return -EIO; + } + + p += NVRW_CNT; + i += NVRW_CNT; + } + + *index = i; + return p - buf; +} + int __init nvram_init(void) { struct device_node *nvram; unsigned int *nbytes_p, proplen; + int error; + int rc; + if ((nvram = find_type_devices("nvram")) != NULL) { nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); if (nbytes_p && proplen == sizeof(unsigned int)) { rtas_nvram_size = *nbytes_p; + } else { + return -EIO; } + } else { + /* If we don't know how big NVRAM is then we shouldn't touch + the nvram partitions */ + return -EIO; } + nvram_fetch = rtas_token("nvram-fetch"); + if (nvram_fetch == RTAS_UNKNOWN_SERVICE) { + printk("nvram_init: Does not support nvram-fetch\n"); + return -EIO; + } + nvram_store = rtas_token("nvram-store"); + if (nvram_store == RTAS_UNKNOWN_SERVICE) { + printk("nvram_init: Does not support nvram-store\n"); + return -EIO; + } printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size); - return misc_register(&nvram_dev); + rc = misc_register(&nvram_dev); + if (rc) { + printk(KERN_ERR "nvram_init: Failed misc_register (%d)\n", rc); + /* Going to continue to setup nvram for internal + * kernel services */ + } + + + /* initialize our anchor for the nvram partition list */ + nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!nvram_part) { + printk(KERN_ERR "nvram_init: Failed kmalloc\n"); + return -ENOMEM; + } + INIT_LIST_HEAD(&nvram_part->partition); + + /* Get all the NVRAM partitions */ + error = scan_nvram_partitions(); + if (error) { + printk(KERN_ERR "nvram_init: Failed scan_nvram_partitions\n"); + return error; + } + + error = setup_nvram_partition(); + if (error) { + printk(KERN_WARNING "nvram_init: Could not find nvram partition" + " for nvram buffered error logging.\n"); + return error; + } + +#ifdef DEBUG_NVRAM + print_nvram_partitions("NVRAM Partitions"); +#endif + + return rc; } void __exit nvram_cleanup(void) { - misc_deregister( &nvram_dev ); + misc_deregister( &nvram_dev ); +} + +static int scan_nvram_partitions(void) +{ + loff_t cur_index = 0; + struct nvram_header phead; + struct nvram_partition * tmp_part; + unsigned char c_sum; + long size; + + while (cur_index < rtas_nvram_size) { + + size = read_nvram((char *)&phead, NVRAM_HEADER_LEN, &cur_index); + if (size != NVRAM_HEADER_LEN) { + printk(KERN_ERR "scan_nvram_partitions: Error parsing " + "nvram partitions\n"); + return size; + } + + cur_index -= NVRAM_HEADER_LEN; /* read_nvram will advance us */ + + c_sum = nvram_checksum(&phead); + if (c_sum != phead.checksum) + printk(KERN_WARNING "WARNING: nvram partition checksum " + "was %02x, should be %02x!\n", phead.checksum, c_sum); + + tmp_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!tmp_part) { + printk(KERN_ERR "scan_nvram_partitions: kmalloc failed\n"); + return -ENOMEM; + } + + memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN); + tmp_part->index = cur_index; + list_add_tail(&tmp_part->partition, &nvram_part->partition); + + cur_index += phead.length * NVRAM_BLOCK_LEN; + } + + return 0; +} + +/* setup_nvram_partition + * + * This will setup the partition we need for buffering the + * error logs and cleanup partitions if needed. + * + * The general strategy is the following: + * 1.) If there is ppc64,linux partition large enough then use it. + * 2.) If there is not a ppc64,linux partition large enough, search + * for a free partition that is large enough. + * 3.) If there is not a free partition large enough remove + * _all_ OS partitions and consolidate the space. + * 4.) Will first try getting a chunk that will satisfy the maximum + * error log size (NVRAM_MAX_REQ). + * 5.) If the max chunk cannot be allocated then try finding a chunk + * that will satisfy the minum needed (NVRAM_MIN_REQ). + */ +static int setup_nvram_partition(void) +{ + struct list_head * p; + struct nvram_partition * part; + int rc; + + /* see if we have an OS partition that meets our needs. + will try getting the max we need. If not we'll delete + partitions and try again. */ + list_for_each(p, &nvram_part->partition) { + part = list_entry(p, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_OS) + continue; + + if (strcmp(part->header.name, "ppc64,linux")) + continue; + + if (part->header.length >= NVRAM_MIN_REQ) { + /* found our partition */ + error_log_nvram_index = part->index + NVRAM_HEADER_LEN; + error_log_nvram_size = (part->header.length * NVRAM_BLOCK_LEN) - + NVRAM_HEADER_LEN - sizeof(struct err_log_info); + return 0; + } + } + + /* try creating a partition with the free space we have */ + rc = create_os_nvram_partition(); + if (!rc) { + return 0; + } + + /* need to free up some space */ + rc = remove_os_nvram_partition(); + if (rc) { + return rc; + } + + /* create a partition in this new space */ + rc = create_os_nvram_partition(); + if (rc) { + printk(KERN_ERR "create_os_nvram_partition: Could not find a " + "NVRAM partition large enough (%d)\n", rc); + return rc; + } + + return 0; +} + +static int remove_os_nvram_partition(void) +{ + struct list_head *i; + struct list_head *j; + struct nvram_partition * part; + struct nvram_partition * cur_part; + int rc; + + list_for_each(i, &nvram_part->partition) { + part = list_entry(i, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_OS) + continue; + + /* Make os partition a free partition */ + part->header.signature = NVRAM_SIG_FREE; + sprintf(part->header.name, "wwwwwwwwwwww"); + part->header.checksum = nvram_checksum(&part->header); + + /* Merge contiguous free partitions backwards */ + list_for_each_prev(j, &part->partition) { + cur_part = list_entry(j, struct nvram_partition, partition); + if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { + break; + } + + part->header.length += cur_part->header.length; + part->header.checksum = nvram_checksum(&part->header); + part->index = cur_part->index; + + list_del(&cur_part->partition); + kfree(cur_part); + j = &part->partition; /* fixup our loop */ + } + + /* Merge contiguous free partitions forwards */ + list_for_each(j, &part->partition) { + cur_part = list_entry(j, struct nvram_partition, partition); + if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { + break; + } + + part->header.length += cur_part->header.length; + part->header.checksum = nvram_checksum(&part->header); + + list_del(&cur_part->partition); + kfree(cur_part); + j = &part->partition; /* fixup our loop */ + } + + rc = write_nvram_header(part); + if (rc <= 0) { + printk(KERN_ERR "remove_os_nvram_partition: write_nvram failed (%d)\n", rc); + return rc; + } + + } + + return 0; +} + +/* create_os_nvram_partition + * + * Create a OS linux partition to buffer error logs. + * Will create a partition starting at the first free + * space found if space has enough room. + */ +static int create_os_nvram_partition(void) +{ + struct list_head * p; + struct nvram_partition * part; + struct nvram_partition * new_part = NULL; + struct nvram_partition * free_part; + struct err_log_info seq_init = { 0, 0 }; + loff_t tmp_index; + long size = 0; + int rc; + + /* Find a free partition that will give us the maximum needed size + If can't find one that will give us the minimum size needed */ + list_for_each(p, &nvram_part->partition) { + part = list_entry(p, struct nvram_partition, partition); + if (part->header.signature != NVRAM_SIG_FREE) + continue; + + if (part->header.length >= NVRAM_MAX_REQ) { + size = NVRAM_MAX_REQ; + free_part = part; + break; + } + if (!size && part->header.length >= NVRAM_MIN_REQ) { + size = NVRAM_MIN_REQ; + free_part = part; + } + } + if (!size) { + return -ENOSPC; + } + + /* Create our OS partition */ + new_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!new_part) { + printk(KERN_ERR "create_os_nvram_partition: kmalloc failed\n"); + return -ENOMEM; + } + + new_part->index = free_part->index; + new_part->header.signature = NVRAM_SIG_OS; + new_part->header.length = size; + sprintf(new_part->header.name, "ppc64,linux"); + new_part->header.checksum = nvram_checksum(&new_part->header); + + rc = write_nvram_header(new_part); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram_header \ + failed (%d)\n", rc); + kfree(new_part); + return rc; + } + + /* make sure and initialize to zero the sequence number and the error + type logged */ + tmp_index = new_part->index + NVRAM_HEADER_LEN; + rc = write_nvram((char *)&seq_init, sizeof(seq_init), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram failed (%d)\n", rc); + kfree(new_part); + return rc; + } + + error_log_nvram_index = new_part->index + NVRAM_HEADER_LEN; + error_log_nvram_size = (new_part->header.length * NVRAM_BLOCK_LEN) - + NVRAM_HEADER_LEN - sizeof(struct err_log_info); + + list_add_tail(&new_part->partition, &free_part->partition); + + if (free_part->header.length <= size) { + list_del(&free_part->partition); + kfree(free_part); + return 0; + } + + /* Adjust the partition we stole the space from */ + free_part->index += size * NVRAM_BLOCK_LEN; + free_part->header.length -= size; + free_part->header.checksum = nvram_checksum(&free_part->header); + + rc = write_nvram_header(free_part); + if (rc <= 0) { + printk(KERN_ERR "create_os_nvram_partition: write_nvram_header " + "failed (%d)\n", rc); + error_log_nvram_index = -1; + error_log_nvram_size = 0; + return rc; + } + + return 0; +} + + +void print_nvram_partitions(char * label) +{ + struct list_head * p; + struct nvram_partition * tmp_part; + + printk(KERN_WARNING "--------%s---------\n", label); + printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); + list_for_each(p, &nvram_part->partition) { + tmp_part = list_entry(p, struct nvram_partition, partition); + printk(KERN_WARNING "%d \t%02x\t%02x\t%d\t%s\n", + tmp_part->index, tmp_part->header.signature, + tmp_part->header.checksum, tmp_part->header.length, + tmp_part->header.name); + } +} + +/* write_error_log_nvram + * In NVRAM the partition containing the error log buffer will looks like: + * Header (in bytes): + * +-----------+----------+--------+------------+------------------+ + * | signature | checksum | length | name | data | + * |0 |1 |2 3|4 15|16 length-1| + * +-----------+----------+--------+------------+------------------+ + * NOTE: length is in NVRAM_BLOCK_LEN + * + * The 'data' section would look like (in bytes): + * +--------------+------------+-----------------------------------+ + * | event_logged | sequence # | error log | + * |0 3|4 7|8 error_log_nvram_size-1| + * +--------------+------------+-----------------------------------+ + * + * event_logged: 0 if event has not been logged to syslog, 1 if it has + * sequence #: The unique sequence # for each event. (until it wraps) + * error log: The error log from event_scan + */ +int write_error_log_nvram(char * buff, int num_bytes, unsigned int err_type) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (no_more_logging) { + return -EPERM; + } + + if (error_log_nvram_index == -1) { + return -ESPIPE; + } + + if (num_bytes > error_log_nvram_size) { + num_bytes = error_log_nvram_size; + } + + info.error_type = err_type; + info.seq_num = error_log_cnt; + + tmp_index = error_log_nvram_index; + + rc = write_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + rc = write_nvram(buff, num_bytes, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "write_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + return 0; +} + +/* read_error_log_nvram + * + * Reads nvram for error log for at most 'num_bytes' + */ +int read_error_log_nvram(char * buff, int num_bytes, unsigned int * err_type) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (error_log_nvram_index == -1) + return -1; + + if (num_bytes > error_log_nvram_size) + num_bytes = error_log_nvram_size; + + tmp_index = error_log_nvram_index; + + rc = read_nvram((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc); + return rc; + } + + rc = read_nvram(buff, num_bytes, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "read_error_log_nvram: Failed read_nvram (%d)\n", rc); + return rc; + } + + error_log_cnt = info.seq_num; + *err_type = info.error_type; + + return 0; +} + +/* This doesn't actually zero anything, but it sets the event_logged + * word to tell that this event is safely in syslog. + */ +int clear_error_log_nvram() +{ + loff_t tmp_index; + int clear_word = ERR_FLAG_ALREADY_LOGGED; + int rc; + + if (error_log_nvram_index == -1) { + return -ESPIPE; + } + + tmp_index = error_log_nvram_index; + + rc = write_nvram((char *)&clear_word, sizeof(int), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "clear_error_log_nvram: Failed write_nvram (%d)\n", rc); + return rc; + } + + return 0; +} + +static int write_nvram_header(struct nvram_partition * part) +{ + loff_t tmp_index; + int rc; + + tmp_index = part->index; + rc = write_nvram((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index); + + return rc; +} + +static unsigned char nvram_checksum(struct nvram_header *p) +{ + unsigned int c_sum, c_sum2; + unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */ + c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5]; + + /* The sum may have spilled into the 3rd byte. Fold it back. */ + c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff; + /* The sum cannot exceed 2 bytes. Fold it into a checksum */ + c_sum2 = (c_sum >> 8) + (c_sum << 8); + c_sum = ((c_sum + c_sum2) >> 8) & 0xff; + return c_sum; } module_init(nvram_init); diff -urN linux-2.4.24/arch/ppc64/kernel/open_pic.c linux-2.4.25/arch/ppc64/kernel/open_pic.c --- linux-2.4.24/arch/ppc64/kernel/open_pic.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/open_pic.c 2004-02-18 05:36:30.000000000 -0800 @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include "local_irq.h" @@ -131,13 +131,23 @@ #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +void +openpic_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa/ipi handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &open_pic; +} + void __init openpic_init_IRQ(void) { struct device_node *np; int i; unsigned int *addrp; unsigned char* chrp_int_ack_special = 0; - unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + unsigned char init_senses[NR_IRQS - NUM_ISA_INTERRUPTS]; int nmi_irq = -1; #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) struct device_node *kbd; @@ -152,13 +162,13 @@ __ioremap(addrp[prom_n_addr_cells(np)-1], 1, _PAGE_NO_CACHE); /* hydra still sets OpenPIC_InitSenses to a static set of values */ if (OpenPIC_InitSenses == NULL) { - prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); - OpenPIC_InitSenses = init_senses; - OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; - } - openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) - irq_desc[i].handler = &i8259_pic; + prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_ISA_INTERRUPTS; + } + openpic_init(1, NUM_ISA_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_ISA_INTERRUPTS ; i++ ) + real_irqdesc(i)->handler = &i8259_pic; i8259_init(); } @@ -343,8 +353,8 @@ /* Disabled, Priority 10..13 */ openpic_initipi(i, 10+i, openpic_vec_ipi+i); /* IPIs are per-CPU */ - irq_desc[openpic_vec_ipi+i].status |= IRQ_PER_CPU; - irq_desc[openpic_vec_ipi+i].handler = &open_pic_ipi; + real_irqdesc(openpic_vec_ipi+i)->status |= IRQ_PER_CPU; + real_irqdesc(openpic_vec_ipi+i)->handler = &open_pic_ipi; } #endif @@ -369,7 +379,7 @@ pri = (i == programmer_switch_irq)? 9: 8; sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; if (sense) - irq_desc[i+offset].status = IRQ_LEVEL; + real_irqdesc(i+offset)->status = IRQ_LEVEL; /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); @@ -377,10 +387,6 @@ openpic_mapirq(i, 1<status & IRQ_LEVEL) != 0) openpic_eoi(); } diff -urN linux-2.4.24/arch/ppc64/kernel/open_pic.h linux-2.4.25/arch/ppc64/kernel/open_pic.h --- linux-2.4.24/arch/ppc64/kernel/open_pic.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/open_pic.h 2004-02-18 05:36:30.000000000 -0800 @@ -37,9 +37,4 @@ extern void openpic_setup_ISU(int isu_num, unsigned long addr); extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern inline int openpic_to_irq(int irq) -{ - return irq += NUM_8259_INTERRUPTS; -} -/*extern int open_pic_irq_offset;*/ #endif /* _PPC64_KERNEL_OPEN_PIC_H */ diff -urN linux-2.4.24/arch/ppc64/kernel/pSeries_hvCall.S linux-2.4.25/arch/ppc64/kernel/pSeries_hvCall.S --- linux-2.4.24/arch/ppc64/kernel/pSeries_hvCall.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/pSeries_hvCall.S 2004-02-18 05:36:30.000000000 -0800 @@ -23,7 +23,7 @@ /* * hcall interface to pSeries LPAR */ -#define HSC .long 0x44000022 +#define HVSC .long 0x44000022 /* long plpar_hcall(unsigned long opcode, R3 unsigned long arg1, R4 @@ -45,7 +45,7 @@ std r9,-16(r1) std r10,-24(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r10,-8(r1) /* Fetch r4-r7 ret args. */ std r4,0(r10) @@ -60,11 +60,85 @@ blr /* return r3 = status */ +/* long plpar_hcall_4out(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long *out1, (r4) R8 + unsigned long *out2, (r5) R9 + unsigned long *out3, (r6) R10 + unsigned long *out4); (r7) 112(R1). From Parameter save area. + */ +_GLOBAL(plpar_hcall_4out) + mfcr r0 + std r0,-8(r1) + ld r14,112(r1) + stdu r1,-48(r1) + + std r8,32(r1) /* Save out ptrs. */ + std r9,24(r1) + std r10,16(r1) + std r14,8(r1) + + HVSC /* invoke the hypervisor */ + + ld r14,32(r1) /* Fetch r4-r7 ret args. */ + std r4,0(r14) + ld r14,24(r1) + std r5,0(r14) + ld r14,16(r1) + std r6,0(r14) + ld r14,8(r1) + std r7,0(r14) + + ld r1,0(r1) + ld r0,-8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ + + /* Simple interface with no output values (other than status) */ _GLOBAL(plpar_hcall_norets) mfcr r0 std r0,-8(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ + ld r0,-8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ + + +/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long arg5, R8 + unsigned long arg6, R9 + unsigned long arg7, R10 + unsigned long arg8, 112(R1) + unsigned long *out1); 120(R1) + + */ + + .text +_GLOBAL(plpar_hcall_8arg_2ret) + mfcr r0 + + ld r11, 112(r1) /* put arg8 and out1 in R11 and R12 */ + ld r12, 120(r1) + + std r0,-8(r1) + stdu r1,-32(r1) + + std r12,-8(r1) /* Save out ptr */ + + HVSC /* invoke the hypervisor */ + + ld r10,-8(r1) /* Fetch r4 ret arg */ + std r4,0(r10) + + ld r1,0(r1) ld r0,-8(r1) mtcrf 0xff,r0 blr /* return r3 = status */ diff -urN linux-2.4.24/arch/ppc64/kernel/pSeries_lpar.c linux-2.4.25/arch/ppc64/kernel/pSeries_lpar.c --- linux-2.4.24/arch/ppc64/kernel/pSeries_lpar.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/pSeries_lpar.c 2004-02-18 05:36:30.000000000 -0800 @@ -35,6 +35,41 @@ #include #include #include +long poll_pending(void) +{ + unsigned long dummy; + return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, + &dummy, &dummy, &dummy); +} + +long prod_processor(void) +{ + plpar_hcall_norets(H_PROD); + return(0); +} + +long cede_processor(void) +{ + plpar_hcall_norets(H_CEDE); + return(0); +} + +long register_vpa(unsigned long flags, unsigned long proc, unsigned long vpa) +{ + plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa); + return(0); +} + +void vpa_init(int cpu) +{ + unsigned long flags; + + /* Register the Virtual Processor Area (VPA) */ + printk(KERN_INFO "register_vpa: cpu 0x%x\n", cpu); + flags = 1UL << (63 - 18); + paca[cpu].xLpPaca.xSLBCount = 64; /* SLB restore highwater mark */ + register_vpa(flags, cpu, __pa((unsigned long)&(paca[cpu].xLpPaca))); +} long plpar_tce_get(unsigned long liobn, unsigned long ioba, @@ -318,24 +353,114 @@ return -1; } +/* return the number of client vterms present */ +/* XXX this requires an interface change to handle multiple discontiguous + * vterms */ int hvc_count(int *start_termno) { u32 *termno; - struct device_node *dn; + struct device_node *rtas; + struct device_node *vtys; - if ((dn = find_path_device("/rtas")) != NULL) { - if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) { + /* consider only the first vty node. + * we should _always_ be able to find one. however, it may not be compatible + * with hvterm1, in which case hvc_console can't use it. */ + vtys = find_devices("vty"); + if (vtys && device_is_compatible(vtys, "hvterm1")) { + termno = (u32 *)get_property(vtys, "reg", 0); + if (start_termno && termno) + *start_termno = *termno; + return 1; /* we can't support >1 with this interface */ + } + + /* no vty nodes; use the /rtas/ibm,termno property */ + printk(KERN_ERR "%s: couldn't find a 'vty' node\n", __FUNCTION__); + if ((rtas = find_path_device("/rtas")) != NULL) { + if ((termno = (u32 *)get_property(rtas, "ibm,termno", 0)) != NULL) { if (start_termno) *start_termno = termno[0]; return termno[1]; } } + + /* couldn't find any vterms */ return 0; } #ifndef CONFIG_PPC_ISERIES void pSeries_lpar_mm_init(void); +/* returns 0 if couldn't find or use /chosen/stdout as console */ +static int find_udbg_vterm(void) +{ + struct device_node *stdout_node; + u32 *termno; + char *name; + int found = 0; + + /* find the boot console from /chosen/stdout */ + if (!of_stdout_device) { + printk(KERN_WARNING "couldn't get path from /chosen/stdout!\n"); + return found; + } + stdout_node = find_path_device(of_stdout_device); + if (!stdout_node) { + printk(KERN_WARNING "couldn't find node from /chosen/stdout\n"); + return found; + } + + /* now we have the stdout node; figure out what type of device it is. */ + name = (char *)get_property(stdout_node, "name", 0); + if (!name) { + printk(KERN_WARNING "stdout node missing 'name' property!\n"); + return found; + } + + if (strncmp(name, "vty", 3) == 0) { + char *compatible; + compatible = (char *)get_property(stdout_node, "compatible", 0); + if (compatible && (strncmp(compatible, "hvterm1", 7) == 0)) { + termno = (u32 *)get_property(stdout_node, "reg", 0); + if (termno) { + vtermno = termno[0]; + ppc_md.udbg_putc = udbg_putcLP; + ppc_md.udbg_getc = udbg_getcLP; + ppc_md.udbg_getc_poll = udbg_getc_pollLP; + found = 1; + } + } else { + /* XXX implement udbg_putcLP_vtty for hvterm-protocol1 case */ + printk(KERN_WARNING "%s doesn't speak hvterm1; " + "can't print udbg messages\n", of_stdout_device); + } + } else if (strncmp(name, "rtas", 4)) { + /* according to firmware, this should never happen. to be removed */ + printk(KERN_ERR "ATTENTION: /chosen/stdout should be /vdevice/vty@0!\n" + "Please report this to linuxppc64-dev@lists.linuxppc.org\n"); + + /* "ibm,termno" property is a pair of numbers. The first is the + * starting termno (the one we use) and the second is the number + * of terminals. */ + termno = (u32 *)get_property(stdout_node, "ibm,termno", 0); + if (termno) { + vtermno = termno[0]; + ppc_md.udbg_putc = udbg_putcLP; + ppc_md.udbg_getc = udbg_getcLP; + ppc_md.udbg_getc_poll = udbg_getc_pollLP; + found = 1; + } + } else if (strncmp(name, "serial", 6)) { + /* XXX fix ISA serial console */ + printk(KERN_WARNING "serial stdout on LPAR ('%s')! " + "can't print udbg messages\n", of_stdout_device); + } else { + printk(KERN_WARNING "don't know how to print to stdout '%s'\n", + of_stdout_device); + } + + return found; +} + /* This is called early in setup.c. * Use it to setup page table ppc_md stuff as well as udbg. */ @@ -352,23 +477,12 @@ pSeries_pcibios_init_early(); /* The keyboard is not useful in the LPAR environment. - * Leave all the interfaces NULL. + * Leave all ppc_md keyboard interfaces NULL. */ - /* lookup the first virtual terminal number in case we don't have a com port. - * Zero is probably correct in case someone calls udbg before the init. - * The property is a pair of numbers. The first is the starting termno (the - * one we use) and the second is the number of terminals. - */ - u32 *termno; - struct device_node *np = find_path_device("/rtas"); - if (np) { - termno = (u32 *)get_property(np, "ibm,termno", 0); - if (termno) - vtermno = termno[0]; + if (0 == find_udbg_vterm()) { + printk(KERN_WARNING + "can't use stdout; can't print early debug messages.\n"); } - ppc_md.udbg_putc = udbg_putcLP; - ppc_md.udbg_getc = udbg_getcLP; - ppc_md.udbg_getc_poll = udbg_getc_pollLP; } #endif diff -urN linux-2.4.24/arch/ppc64/kernel/pSeries_pci.c linux-2.4.25/arch/ppc64/kernel/pSeries_pci.c --- linux-2.4.24/arch/ppc64/kernel/pSeries_pci.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/pSeries_pci.c 2004-02-18 05:36:30.000000000 -0800 @@ -208,6 +208,7 @@ PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name); return 0; } + Node = pci_device_to_OF_node(Pci_Dev); if ( Node == NULL) { PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name); @@ -524,13 +525,22 @@ } phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8; - /*************************************************************** - * Trying to build a known just gets the code in trouble. - ***************************************************************/ - } else { + } else { PPCDBG(PPCDBG_PHBINIT, "\tUnknown PHB Type!\n"); - printk("PCI: Unknown Phb Type!\n"); - return NULL; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { + + phb=pci_alloc_pci_controller("PHB UK",phb_type_unknown); + if (phb == NULL) return NULL; + + phb->cfg_addr = NULL; + phb->cfg_data = NULL; + phb->phb_regs = NULL; + phb->chip_regs = NULL; + } else { + printk("PCI: Unknown Phb Type!\n"); + return NULL; + } } /* Add a linux,phbnum property to the device tree so user code @@ -703,10 +713,6 @@ pci_read_irq_line(dev); PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) ); } - - if (naca->interrupt_controller == IC_PPC_XIC) { - xics_isa_init(); - } } /*********************************************************************** diff -urN linux-2.4.24/arch/ppc64/kernel/pci_dma.c linux-2.4.25/arch/ppc64/kernel/pci_dma.c --- linux-2.4.24/arch/ppc64/kernel/pci_dma.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/pci_dma.c 2004-02-18 05:36:30.000000000 -0800 @@ -97,11 +97,8 @@ unsigned order ); /* allocates a range of tces and sets them to the pages */ -static inline dma_addr_t get_tces( struct TceTable *, - unsigned order, - void *page, - unsigned numPages, - int direction ); +dma_addr_t get_tces(struct TceTable *, unsigned order, void *page, + unsigned numPages, int direction); static long test_tce_range( struct TceTable *, long tcenum, @@ -219,7 +216,7 @@ * Build a TceTable structure. This contains a multi-level bit map which * is used to manage allocation of the tce space. */ -static struct TceTable *build_tce_table( struct TceTable * tbl ) +struct TceTable *build_tce_table(struct TceTable * tbl) { unsigned long bits, bytes, totalBytes; unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS]; @@ -527,7 +524,8 @@ return retval; } -static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int direction ) +inline dma_addr_t get_tces(struct TceTable *tbl, unsigned order, + void *page, unsigned numPages, int direction) { long tcenum; unsigned long uaddr; @@ -537,8 +535,8 @@ uaddr = (unsigned long)page & PAGE_MASK; /* Allocate a range of tces */ - tcenum = alloc_tce_range( tbl, order ); - if ( tcenum != -1 ) { + tcenum = alloc_tce_range(tbl, order); + if (tcenum != -1) { /* We got the tces we wanted */ tcenum += tbl->startOffset; /* Offset into real TCE table */ retTce = tcenum << PAGE_SHIFT; /* Set the return dma address */ @@ -553,9 +551,9 @@ the TCE table with the MMIO that will send the bus address to the IOA */ __asm__ __volatile__ ("sync" : : : "memory"); - } - else { - panic("PCI_DMA: Tce Allocation failure in get_tces. 0x%p\n",tbl); + } else { + panic("get_tces: TCE allocation failed. 0x%p 0x%x\n", + tbl, order); } return retTce; @@ -586,8 +584,8 @@ } -static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, - unsigned order, unsigned num_pages) +void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, + unsigned order, unsigned num_pages) { long tcenum, total_tces, free_tce; unsigned i; @@ -1009,34 +1007,34 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ - if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_alloc_consistent size to large: 0x%lx \n",size); - return (void *)NO_TCE; + if (order >= NUM_TCE_LEVELS) { + printk("PCI_DMA: pci_alloc_consistent size too large: 0x%lx\n", + size); + return (void *)NULL; } tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { /* Alloc enough pages (and possibly more) */ ret = (void *)__get_free_pages( GFP_ATOMIC, order ); - if ( ret ) { + if (ret) { /* Page allocation succeeded */ memset(ret, 0, nPages << PAGE_SHIFT); /* Set up tces to cover the allocated range */ tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL ); - if ( tce == NO_TCE ) { - PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tces failed\n" ); + if (tce == NO_TCE) { free_pages( (unsigned long)ret, order ); ret = NULL; - } - else - { + } else { *dma_handle = tce; } + } else { + printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); } - else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); + } else { + panic("pci_alloc_consistent: unable to find TCE table\n"); } - else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tce_table failed for 0x%016lx\n", hwdev); PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle); PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: return = 0x%16.16lx\n", ret); @@ -1059,7 +1057,7 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size); + printk("PCI_DMA: pci_free_consistent size too large: 0x%lx \n",size); return; } @@ -1087,7 +1085,7 @@ PPCDBG(PPCDBG_TCE, "pci_map_single:\n"); PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, direction = 0x%16.16lx, vaddr = 0x%16.16lx\n", hwdev, size, direction, vaddr); - if ( direction == PCI_DMA_NONE ) + if (direction == PCI_DMA_NONE) BUG(); uaddr = (unsigned long)vaddr; @@ -1098,15 +1096,18 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_map_single size to large: 0x%lx \n",size); - return NO_TCE; + panic("PCI_DMA: pci_map_single size too large: 0x%lx \n", size); + return dma_handle; } tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { + /* get_tces panics if there are no entries available */ dma_handle = get_tces( tbl, order, vaddr, nPages, direction ); dma_handle |= ( uaddr & ~PAGE_MASK ); + } else { + panic("PCI_DMA: Unable to find TCE table.\n"); } return dma_handle; @@ -1129,7 +1130,7 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: pci_unmap_single size to large: 0x%lx \n",size); + printk("PCI_DMA: pci_unmap_single size too large: 0x%lx \n",size); return; } @@ -1151,6 +1152,7 @@ { unsigned long nTces, numPages, startPage, endPage, prevEndPage; unsigned i; + void *address; prevEndPage = 0; nTces = 0; @@ -1159,8 +1161,10 @@ /* Compute the starting page number and * the ending page number for this entry */ - startPage = (unsigned long)sg->address >> PAGE_SHIFT; - endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + startPage = (unsigned long)address >> PAGE_SHIFT; + endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT; numPages = endPage - startPage + 1; /* Simple optimization: if the previous entry ended * in the same page in which this entry starts @@ -1187,17 +1191,20 @@ u32 cur_start_dma; unsigned long cur_len_dma, cur_end_virt, uaddr; unsigned num_dma_ents; + void *address; dma_sg = sg; num_dma_ents = 1; /* Process the first sg entry */ - cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK)); + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + cur_start_dma = dma_addr + ((unsigned long)address & (~PAGE_MASK)); cur_len_dma = sg->length; /* cur_end_virt holds the address of the byte immediately after the * end of the current buffer. */ - cur_end_virt = (unsigned long)sg->address + cur_len_dma; + cur_end_virt = (unsigned long)address + cur_len_dma; /* Later code assumes that unused sg->dma_address and sg->dma_length * fields will be zero. Other archs seem to assume that the user * (device driver) guarantees that...I don't want to depend on that @@ -1222,7 +1229,9 @@ * or if the previous entry ends at a page boundary * and the current entry starts at a page boundary. */ - uaddr = (unsigned long)sg->address; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + uaddr = (unsigned long)address; if ( ( uaddr != cur_end_virt ) && ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) || ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) { @@ -1273,13 +1282,14 @@ /* Call the hypervisor to create the TCE entries. * return the number of TCEs created */ -static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, - int nents, unsigned numTces, int direction ) +static dma_addr_t create_tces_sg(struct TceTable *tbl, struct scatterlist *sg, + int nents, unsigned numTces, int direction) { unsigned order, i, j; unsigned long startPage, endPage, prevEndPage, numPages, uaddr; long tcenum, starttcenum; dma_addr_t dmaAddr; + void *address; dmaAddr = NO_TCE; @@ -1287,23 +1297,26 @@ /* Client asked for way to much space. This is checked later anyway */ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { - printk("PCI_DMA: create_tces_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT)); + printk("PCI_DMA: create_tces_sg size too large: 0x%llx \n",(numTces << PAGE_SHIFT)); + panic("numTces is off"); return NO_TCE; } /* allocate a block of tces */ - tcenum = alloc_tce_range( tbl, order ); - if ( tcenum != -1 ) { + tcenum = alloc_tce_range(tbl, order); + if (tcenum != -1) { tcenum += tbl->startOffset; starttcenum = tcenum; dmaAddr = tcenum << PAGE_SHIFT; prevEndPage = 0; for (j=0; jaddress >> PAGE_SHIFT; - endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + startPage = (unsigned long)address >> PAGE_SHIFT; + endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT; numPages = endPage - startPage + 1; - uaddr = (unsigned long)sg->address; + uaddr = (unsigned long)address; /* If the previous entry ended in the same page that * the current page starts then they share that @@ -1335,6 +1348,9 @@ PPCDBG(PPCDBG_TCE, "create_tces_sg: numTces %d, tces used %d\n", numTces, (unsigned)(tcenum - starttcenum)); + } else { + panic("PCI_DMA: TCE allocation failure in create_tces_sg. 0x%p 0x%x\n", + tbl, order); } return dmaAddr; @@ -1346,25 +1362,26 @@ unsigned numTces; int num_dma = 0; dma_addr_t dma_handle; + void *address; - PPCDBG(PPCDBG_TCE, "pci_map_sg:\n"); - PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, sg = 0x%16.16lx, direction = 0x%16.16lx, nents = 0x%16.16lx\n", hwdev, sg, direction, nents); /* Fast path for a single entry scatterlist */ if ( nents == 1 ) { - sg->dma_address = pci_map_single( hwdev, sg->address, - sg->length, direction ); + address = sg->address ? sg->address : + (page_address(sg->page) + sg->offset); + sg->dma_address = pci_map_single( hwdev, address, + sg->length, direction ); sg->dma_length = sg->length; return 1; } - if ( direction == PCI_DMA_NONE ) + if (direction == PCI_DMA_NONE) BUG(); tbl = get_tce_table(hwdev); - if ( tbl ) { + if (tbl) { /* Compute the number of tces required */ - numTces = num_tces_sg( sg, nents ); + numTces = num_tces_sg(sg, nents); /* Create the tces and get the dma address */ dma_handle = create_tces_sg( tbl, sg, nents, numTces, direction ); @@ -1372,6 +1389,8 @@ /* Fill in the dma scatterlist */ num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces ); + } else { + panic("pci_map_sg: unable to find TCE table\n"); } return num_dma; @@ -1407,7 +1426,7 @@ /* It is easier to debug here for the drivers than in the tce tables.*/ if(order >= NUM_TCE_LEVELS) { printk("PCI_DMA: dma_start_page:0x%lx dma_end_page:0x%lx\n",dma_start_page,dma_end_page); - printk("PCI_DMA: pci_unmap_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT)); + printk("PCI_DMA: pci_unmap_sg size too large: 0x%x \n",(numTces << PAGE_SHIFT)); return; } diff -urN linux-2.4.24/arch/ppc64/kernel/perfmon.c linux-2.4.25/arch/ppc64/kernel/perfmon.c --- linux-2.4.24/arch/ppc64/kernel/perfmon.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/perfmon.c 2004-02-18 05:36:30.000000000 -0800 @@ -420,6 +420,33 @@ return(0); } + +static long plpar_perfmon(int mode) +{ + return plpar_hcall_norets(H_PERFMON, mode, 0); +} + +static void pmc_configure_hardware() { + /* + * Debug bus enabled is required on GP for timeslice mode. + * Flood enabled is required on GP for PMC cycle profile mode + * iSeries SP sets this by default. pSeries requires the OS to enable. + */ + if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { + /* Set up the debug bus to pmc mode - a feature of GP */ + switch(systemcfg->platform) { + case PLATFORM_ISERIES_LPAR: + HvCall_setDebugBus(1); + break; + case PLATFORM_PSERIES_LPAR: + plpar_perfmon(1); + break; + case PLATFORM_PSERIES: + mtspr(HID0, mfspr(HID0) | 0x0000080000000000); + } + } +} + /* * pmc_profile * @@ -783,29 +810,3 @@ } spin_unlock(&pmc_lock); } - -long plpar_perfmon(int mode) -{ - return plpar_hcall_norets(H_PERFMON, mode, 0); -} - -void pmc_configure_hardware() { - /* - * Debug bus enabled is required on GP for timeslice mode. - * Flood enabled is required on GP for PMC cycle profile mode - * iSeries SP sets this by default. pSeries requires the OS to enable. - */ - if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) { - /* Set up the debug bus to pmc mode - a feature of GP */ - switch(systemcfg->platform) { - case PLATFORM_ISERIES_LPAR: - HvCall_setDebugBus(1); - break; - case PLATFORM_PSERIES_LPAR: - plpar_perfmon(1); - break; - case PLATFORM_PSERIES: - mtspr(HID0, mfspr(HID0) | 0x0000080000000000); - } - } -} diff -urN linux-2.4.24/arch/ppc64/kernel/pmc.c linux-2.4.25/arch/ppc64/kernel/pmc.c --- linux-2.4.24/arch/ppc64/kernel/pmc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/pmc.c 2004-02-18 05:36:30.000000000 -0800 @@ -74,7 +74,6 @@ page_table_lock : SPIN_LOCK_UNLOCKED}; extern spinlock_t hash_table_lock[]; -extern inline unsigned long get_lock_slot(unsigned long vpn); char * ppc64_pmc_stab(int file) @@ -241,7 +240,7 @@ lock_slot = get_lock_slot(vpn); rpn = pa >> PAGE_SHIFT; - spin_lock(&hash_table_lock[lock_slot].lock); + spin_lock(&hash_table_lock[lock_slot]); /* Get a pointer to the linux page table entry for this page * allocating pmd or pte pages along the way as needed. Note * that the pmd & pte pages are not themselfs bolted. @@ -266,7 +265,7 @@ *ptep = pte; - spin_unlock(&hash_table_lock[lock_slot].lock); + spin_unlock(&hash_table_lock[lock_slot]); } spin_unlock(&btmalloc_mm.page_table_lock); diff -urN linux-2.4.24/arch/ppc64/kernel/ppc_asm.h linux-2.4.25/arch/ppc64/kernel/ppc_asm.h --- linux-2.4.24/arch/ppc64/kernel/ppc_asm.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ppc_asm.h 2004-02-18 05:36:30.000000000 -0800 @@ -44,6 +44,31 @@ #define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) #define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) +/* + * Once a version of gas that understands the AltiVec instructions + * is freely available, we can do this the normal way... - paulus + */ +#define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1) +#define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1) +#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1) +#define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1) +#define DSSALL .long (0x1f<<26)+(0x10<<21)+(0x336<<1) + + +#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base) +#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) +#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base) +#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base) +#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base) +#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base) +#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); LVX(n,b,base) +#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) +#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base) +#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base) +#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) +#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) + + #define CHECKANYINT(ra,rb) \ mfspr rb,SPRG3; /* Get Paca address */\ ld ra,PACALPPACA+LPPACAANYINT(rb); /* Get pending interrupt flags */\ diff -urN linux-2.4.24/arch/ppc64/kernel/ppc_ksyms.c linux-2.4.25/arch/ppc64/kernel/ppc_ksyms.c --- linux-2.4.24/arch/ppc64/kernel/ppc_ksyms.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ppc_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -81,8 +81,8 @@ #ifdef CONFIG_SHARED_MEMORY_ADDRESSING extern void shared_malloc(unsigned long); extern void shared_free(void *); -extern int shared_task_mark(); -extern int shared_task_unmark(); +extern int shared_task_mark(void); +extern int shared_task_unmark(void); #endif EXPORT_SYMBOL(do_signal); @@ -232,6 +232,12 @@ EXPORT_SYMBOL(flush_icache_user_range); EXPORT_SYMBOL(flush_icache_page); EXPORT_SYMBOL(flush_dcache_page); +#ifdef CONFIG_ALTIVEC +#ifndef CONFIG_SMP +EXPORT_SYMBOL(last_task_used_altivec); +#endif /* CONFIG_SMP */ +EXPORT_SYMBOL(giveup_altivec); +#endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SMP EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); @@ -263,6 +269,7 @@ EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_data_buf); EXPORT_SYMBOL(rtas_data_buf_lock); +EXPORT_SYMBOL(rtas_extended_busy_delay_time); #endif #ifndef CONFIG_PPC_ISERIES diff -urN linux-2.4.24/arch/ppc64/kernel/proc_pmc.c linux-2.4.25/arch/ppc64/kernel/proc_pmc.c --- linux-2.4.24/arch/ppc64/kernel/proc_pmc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/proc_pmc.c 2004-02-18 05:36:30.000000000 -0800 @@ -58,6 +58,8 @@ static int proc_ppc64_page_read(char *page, char **start, off_t off, int count, int *eof, void *data); static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir); +void proc_ppc64_create_smt(void); + int proc_ppc64_pmc_find_file(void *data); int proc_ppc64_pmc_read(char *page, char **start, off_t off, int count, int *eof, char *buffer); @@ -182,6 +184,8 @@ rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); } + proc_ppc64_create_smt(); + /* Create the /proc/ppc64/pcifr for the Pci Flight Recorder. */ proc_pciFr_init(proc_ppc64_root); @@ -202,7 +206,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = (void *)proc_ppc64_pmc_stab_read; + ent->write_proc = NULL; } ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, @@ -211,7 +215,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = (void *)proc_ppc64_pmc_htab_read; + ent->write_proc = NULL; } } @@ -221,7 +225,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = (void *)proc_ppc64_pmc_stab_read; + ent->write_proc = NULL; } ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, @@ -230,7 +234,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = (void *)proc_ppc64_pmc_htab_read; + ent->write_proc = NULL; } ent = create_proc_entry("profile", S_IWUSR | S_IRUGO, proc_ppc64_pmc_system_root); @@ -261,7 +265,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = (void *)proc_ppc64_pmc_hw_read; + ent->write_proc = NULL; } } @@ -271,7 +275,7 @@ ent->nlink = 1; ent->data = (void *)proc_ppc64_pmc_system_root; ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = (void *)proc_ppc64_pmc_hw_read; + ent->write_proc = NULL; } } @@ -449,6 +453,7 @@ static ssize_t write_profile(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } static ssize_t read_trace(struct file *file, char *buf, @@ -473,6 +478,7 @@ static ssize_t write_trace(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } static ssize_t read_timeslice(struct file *file, char *buf, @@ -481,7 +487,6 @@ unsigned long p = *ppos; ssize_t read; char * pnt; - unsigned int sample_step = 4; if (p >= (perfmon_base.timeslice_length)) return 0; if (count > (perfmon_base.timeslice_length) - p) @@ -498,6 +503,7 @@ static ssize_t write_timeslice(struct file * file, const char * buf, size_t count, loff_t *ppos) { + return(0); } int @@ -882,15 +888,24 @@ int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ) { - if ( ! strncmp( buffer, "stop", 4 ) ) + char stkbuf[10]; + + if (count > 9) + count = 9; + if (copy_from_user (stkbuf, buffer, count)) + return -EFAULT; + + stkbuf[count] = 0; + + if ( ! strncmp( stkbuf, "stop", 4 ) ) proc_pmc_stop(); - else if ( ! strncmp( buffer, "start", 5 ) ) + else if ( ! strncmp( stkbuf, "start", 5 ) ) proc_pmc_start(); - else if ( ! strncmp( buffer, "reset", 5 ) ) + else if ( ! strncmp( stkbuf, "reset", 5 ) ) proc_pmc_reset(); - else if ( ! strncmp( buffer, "cpi", 3 ) ) + else if ( ! strncmp( stkbuf, "cpi", 3 ) ) proc_pmc_cpi(); - else if ( ! strncmp( buffer, "tlb", 3 ) ) + else if ( ! strncmp( stkbuf, "tlb", 3 ) ) proc_pmc_tlb(); /* IMPLEMENT ME */ @@ -1061,3 +1076,85 @@ remap_page_range( vma->vm_start, __pa(dp->data), dp->size, vma->vm_page_prot ); return 0; } + +static int proc_ppc64_smt_snooze_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + if (naca->smt_snooze_delay) + return sprintf(page, "%lu\n", naca->smt_snooze_delay); + else + return sprintf(page, "disabled\n"); +} + +static int proc_ppc64_smt_snooze_write(struct file* file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long val; + char val_string[22]; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (count > sizeof(val_string) - 1) + return -EINVAL; + + if (copy_from_user(val_string, buffer, count)) + return -EFAULT; + + val_string[count] = '\0'; + + if (val_string[0] == '0' && (val_string[1] == '\n' || val_string[1] == '\0')) { + naca->smt_snooze_delay = 0; + return count; + } + + val = simple_strtoul(val_string, NULL, 10); + if (val != 0) + naca->smt_snooze_delay = val; + else + return -EINVAL; + + return count; +} + +static int proc_ppc64_smt_state_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + switch(naca->smt_state) { + case SMT_OFF: + return sprintf(page, "off\n"); + break; + case SMT_ON: + return sprintf(page, "on\n"); + break; + case SMT_DYNAMIC: + return sprintf(page, "dynamic\n"); + break; + default: + return sprintf(page, "unknown\n"); + break; + } +} + +void proc_ppc64_create_smt(void) +{ + struct proc_dir_entry *ent_snooze = + create_proc_entry("smt-snooze-delay", S_IRUGO | S_IWUSR, + proc_ppc64_root); + struct proc_dir_entry *ent_enabled = + create_proc_entry("smt-enabled", S_IRUGO | S_IWUSR, + proc_ppc64_root); + if (ent_snooze) { + ent_snooze->nlink = 1; + ent_snooze->data = NULL; + ent_snooze->read_proc = (void *)proc_ppc64_smt_snooze_read; + ent_snooze->write_proc = (void *)proc_ppc64_smt_snooze_write; + } + + if (ent_enabled) { + ent_enabled->nlink = 1; + ent_enabled->data = NULL; + ent_enabled->read_proc = (void *)proc_ppc64_smt_state_read; + ent_enabled->write_proc = NULL; + } +} diff -urN linux-2.4.24/arch/ppc64/kernel/process.c linux-2.4.25/arch/ppc64/kernel/process.c --- linux-2.4.24/arch/ppc64/kernel/process.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/process.c 2004-02-18 05:36:30.000000000 -0800 @@ -10,6 +10,9 @@ * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * + * VMX/Altivec port from ppc32 (c) IBM 2003 + * Denis Joseph Barrow (dj@de.ibm.com,barrow_dj@yahoo.com) + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -46,7 +49,10 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs); +#ifndef CONFIG_SMP struct task_struct *last_task_used_math = NULL; +struct task_struct *last_task_used_altivec = NULL; +#endif /* CONFIG_SMP */ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; @@ -93,6 +99,32 @@ return 1; } +#ifdef CONFIG_ALTIVEC +int +dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) +{ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs)); + return 1; +} + + +void +enable_kernel_altivec(void) +{ +#ifdef CONFIG_SMP + if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) + giveup_altivec(current); + else + giveup_altivec(NULL); /* just enable AltiVec for kernel - force */ +#else + giveup_altivec(last_task_used_altivec); +#endif /* __SMP __ */ +} +#endif /* CONFIG_ALTIVEC */ + + void _switch_to(struct task_struct *prev, struct task_struct *new, struct task_struct **last) @@ -121,7 +153,21 @@ */ if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) ) giveup_fpu(prev); - +#ifdef CONFIG_ALTIVEC + /* + * If the previous thread used altivec in the last quantum + * (thus changing altivec regs) then save them. + * We used to check the VRSAVE register but not all apps + * set it, so we don't rely on it now (and in fact we need + * to save & restore VSCR even if VRSAVE == 0). -- paulus + * + * On SMP we always save/restore altivec regs just to avoid the + * complexity of changing processors. + * -- Cort + */ + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) + giveup_altivec(prev); +#endif /* CONFIG_ALTIVEC */ /* prev->last_processor = prev->processor; */ current_set[smp_processor_id()].task = new; #endif /* CONFIG_SMP */ @@ -145,8 +191,11 @@ printk("TASK = %p[%d] '%s' ", current, current->pid, current->comm); printk("Last syscall: %ld ", current->thread.last_syscall); - printk("\nlast math %p ", last_task_used_math); - +#ifndef CONFIG_SMP + printk("\nlast math %p last altivec %p", last_task_used_math, + last_task_used_altivec); +#endif + #ifdef CONFIG_SMP /* printk(" CPU: %d last CPU: %d", current->processor,current->last_processor); */ #endif /* CONFIG_SMP */ @@ -173,14 +222,22 @@ void exit_thread(void) { +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif } void flush_thread(void) { +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif } void @@ -225,7 +282,6 @@ /* Stack is in kernel space - must adjust */ childregs->gpr[1] = (unsigned long)(childregs + 1); *((unsigned long *) childregs->gpr[1]) = 0; - childregs->gpr[13] = (unsigned long) p; } else { /* Provided stack is in user space */ childregs->gpr[1] = usp; @@ -244,6 +300,18 @@ p->thread.fpscr = current->thread.fpscr; p->thread.fpexc_mode = current->thread.fpexc_mode; +#ifdef CONFIG_ALTIVEC + /* + * copy altiVec info - assume lazy altiVec switch + * - kumar + */ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + memcpy(&p->thread.vr, ¤t->thread.vr, sizeof(p->thread.vr)); + p->thread.vscr = current->thread.vscr; + childregs->msr &= ~MSR_VEC; +#endif /* CONFIG_ALTIVEC */ + return 0; } @@ -275,9 +343,19 @@ regs->gpr[1] = sp; regs->gpr[2] = toc; regs->msr = MSR_USER64; +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = 0; + if (last_task_used_altivec == current) + last_task_used_altivec = 0; +#endif /* CONFIG_SMP */ + memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr = 0; +#ifdef CONFIG_ALTIVEC + memset(¤t->thread.vr[0], 0,offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])); + current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */ +#endif /* CONFIG_ALTIVEC */ } # define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */ @@ -337,7 +415,10 @@ goto out; if (regs->msr & MSR_FP) giveup_fpu(current); - +#ifdef CONFIG_ALTIVEC + if (regs->msr & MSR_VEC) + giveup_altivec(current); +#endif /* CONFIG_ALTIVEC */ error = do_execve(filename, (char **) a1, (char **) a2, regs); if (error == 0) diff -urN linux-2.4.24/arch/ppc64/kernel/prom.c linux-2.4.25/arch/ppc64/kernel/prom.c --- linux-2.4.24/arch/ppc64/kernel/prom.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/prom.c 2004-02-18 05:36:30.000000000 -0800 @@ -168,7 +168,6 @@ extern struct rtas_t rtas; extern unsigned long klimit; -extern unsigned long embedded_sysmap_end; extern struct lmb lmb; #ifdef CONFIG_MSCHUNKS extern struct msChunks msChunks; @@ -180,12 +179,9 @@ char *bootpath = 0; char *bootdevice = 0; -struct device_node *allnodes = 0; +#define MAX_CPU_THREADS 2 -#define UNDEFINED_IRQ 0xffff -unsigned short real_irq_to_virt_map[NR_HW_IRQS]; -unsigned short virt_irq_to_real_map[NR_IRQS]; -int last_virt_irq = 2; /* index of last virt_irq. Skip through IPI */ +struct device_node *allnodes = 0; static unsigned long call_prom(const char *service, int nargs, int nret, ...); static void prom_exit(void); @@ -941,7 +937,7 @@ * By doing this, we avoid the pitfalls of trying to DMA to * MMIO space and the DMA alias hole. */ - minsize = 4UL << 20; + minsize = 8UL << 20; /* Align to the greater of the align or size */ align = (minalign < minsize) ? minsize : minalign; @@ -1054,6 +1050,9 @@ unsigned long offset = reloc_offset(); char type[64], *path; int cpuid = 0; + unsigned int interrupt_server[MAX_CPU_THREADS]; + unsigned int cpu_threads, hw_cpu_num; + int propsize; extern void __secondary_hold(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; @@ -1117,18 +1116,12 @@ call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), ®, sizeof(reg)); - /* Only need to start secondary procs, not ourself. */ - if ( reg == _prom->cpu ) - continue; - path = (char *) mem; memset(path, 0, 256); if ((long) call_prom(RELOC("package-to-path"), 3, 1, node, path, 255) < 0) continue; - cpuid++; - #ifdef DEBUG_PROM prom_print_nl(); prom_print(RELOC("cpuid = 0x")); @@ -1140,56 +1133,80 @@ #endif _xPaca[cpuid].xHwProcNum = reg; - prom_print(RELOC("starting cpu ")); - prom_print(path); - /* Init the acknowledge var which will be reset by * the secondary cpu when it awakens from its OF * spinloop. */ *acknowledge = (unsigned long)-1; -#ifdef DEBUG_PROM - prom_print(RELOC(" 3) spinloop = 0x")); - prom_print_hex(spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) *spinloop = 0x")); - prom_print_hex(*spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) acknowledge = 0x")); - prom_print_hex(acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) *acknowledge = 0x")); - prom_print_hex(*acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) secondary_hold = 0x")); - prom_print_hex(secondary_hold); - prom_print_nl(); - prom_print(RELOC(" 3) cpuid = 0x")); - prom_print_hex(cpuid); - prom_print_nl(); -#endif - call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid); - prom_print(RELOC("...")); - for ( i = 0 ; (i < 100000000) && - (*acknowledge == ((unsigned long)-1)); i++ ) ; -#ifdef DEBUG_PROM - { - unsigned long *p = 0x0; - prom_print(RELOC(" 4) 0x0 = 0x")); - prom_print_hex(*p); - prom_print_nl(); + propsize = call_prom(RELOC("getprop"), 4, 1, node, + RELOC("ibm,ppc-interrupt-server#s"), + &interrupt_server, + sizeof(interrupt_server)); + if (propsize < 0) { + /* no property. old hardware has no SMT */ + cpu_threads = 1; + interrupt_server[0] = reg; /* fake it with phys id */ + } else { + /* We have a threaded processor */ + cpu_threads = propsize / sizeof(u32); + if (cpu_threads > MAX_CPU_THREADS) { + prom_print(RELOC("SMT: too many threads!\nSMT: found ")); + prom_print_hex(cpu_threads); + prom_print(RELOC(", max is ")); + prom_print_hex(MAX_CPU_THREADS); + prom_print_nl(); + cpu_threads = 1; /* ToDo: panic? */ + } } -#endif - if (*acknowledge == cpuid) { - prom_print(RELOC("ok\n")); - /* Set the number of active processors. */ - _systemcfg->processorCount++; + + hw_cpu_num = interrupt_server[0]; + if (hw_cpu_num != _prom->cpu) { + /* Primary Thread of non-boot cpu */ + prom_print_hex(cpuid); + prom_print(RELOC(" : starting cpu ")); + prom_print(path); + prom_print(RELOC(" ... ")); + call_prom(RELOC("start-cpu"), 3, 0, node, + secondary_hold, cpuid); + + for(i = 0; (i < 100000000) && + (*acknowledge == ((unsigned long)-1)); i++ ); + + if (*acknowledge == cpuid) { + prom_print(RELOC("ok\n")); + /* Set the number of active processors. */ + _systemcfg->processorCount++; + _xPaca[cpuid].active = 1; + _xPaca[cpuid].available = 1; + } else { + prom_print(RELOC("failed: ")); + prom_print_hex(*acknowledge); + prom_print_nl(); + /* prom_panic(RELOC("cpu failed to start")); */ + } } else { - prom_print(RELOC("failed: ")); - prom_print_hex(*acknowledge); + prom_print_hex(cpuid); + prom_print(RELOC(" : booting cpu ")); + prom_print(path); prom_print_nl(); } + + /* Init paca for secondary threads. They start later. */ + for (i=1; i < cpu_threads; i++) { + cpuid++; + _xPaca[cpuid].xHwProcNum = interrupt_server[i]; + prom_print_hex(interrupt_server[i]); + prom_print(RELOC(" : preparing thread ... ")); + if (_naca->smt_state) { + _xPaca[cpuid].available = 1; + prom_print(RELOC("available")); + } else { + prom_print(RELOC("not available")); + } + prom_print_nl(); + } + cpuid++; } #ifdef CONFIG_HMT /* Only enable HMT on processors that provide support. */ @@ -1236,6 +1253,104 @@ #endif } +static void +smt_setup(void) +{ + char *p, *q; + char my_smt_enabled = SMT_DYNAMIC; + unsigned long my_smt_snooze_delay; + ihandle prom_options = NULL; + char option[9]; + unsigned long offset = reloc_offset(); + struct naca_struct *_naca = RELOC(naca); + char found = 0; + + if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) { + q = p + 12; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + if (q[0] == 'o' && q[1] == 'f' && + q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) { + my_smt_enabled = SMT_OFF; + } else if (q[0]=='o' && q[1] == 'n' && + (q[2] == ' ' || q[2] == '\0')) { + my_smt_enabled = SMT_ON; + } else { + my_smt_enabled = SMT_DYNAMIC; + } + } + } + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-enabled"), + option, sizeof(option)); + if (option[0] != 0) { + found = 1; + if (!strcmp(option, "off")) + my_smt_enabled = SMT_OFF; + else if (!strcmp(option, "on")) + my_smt_enabled = SMT_ON; + else + my_smt_enabled = SMT_DYNAMIC; + } + } + } + + if (!found ) + my_smt_enabled = SMT_DYNAMIC; /* default to on */ + + found = 0; + if (my_smt_enabled) { + if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) { + q = p + 17; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-snooze-delay"), + option, sizeof(option)); + if (option[0] != 0) { + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + q = option; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + } + + if (!found) { + my_smt_snooze_delay = 30000; /* default value */ + } + } else { + my_smt_snooze_delay = 0; /* default value */ + } + _naca->smt_snooze_delay = my_smt_snooze_delay; + _naca->smt_state = my_smt_enabled; +} + #ifdef CONFIG_PPCDBG extern char *trace_names[]; /* defined in udbg.c -- need a better interface */ @@ -1359,7 +1474,6 @@ char *p, *d; unsigned long phys; u32 getprop_rval; - struct naca_struct *_naca = RELOC(naca); struct systemcfg *_systemcfg = RELOC(systemcfg); struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct prom_t *_prom = PTRRELOC(&prom); @@ -1367,9 +1481,6 @@ /* Default machine type. */ _systemcfg->platform = PLATFORM_PSERIES; - /* Reset klimit to take into account the embedded system map */ - if (RELOC(embedded_sysmap_end)) - RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end))); /* Get a handle to the prom entry point before anything else */ _prom->entry = pp; @@ -1532,12 +1643,13 @@ /* Initialize some system info into the Naca early... */ mem = prom_initialize_naca(mem); + smt_setup(); + /* If we are on an SMP machine, then we *MUST* do the * following, regardless of whether we have an SMP * kernel or not. */ - if (_systemcfg->processorCount > 1) - prom_hold_cpus(mem); + prom_hold_cpus(mem); #ifdef DEBUG_PROM prom_print(RELOC("copying OF device tree...\n")); @@ -1697,46 +1809,6 @@ return DOUBLEWORD_ALIGN(mem); } -void -virt_irq_init(void) -{ - int i; - for (i = 0; i < NR_IRQS; i++) - virt_irq_to_real_map[i] = UNDEFINED_IRQ; - for (i = 0; i < NR_HW_IRQS; i++) - real_irq_to_virt_map[i] = UNDEFINED_IRQ; -} - -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. - */ -unsigned long -virt_irq_create_mapping(unsigned long real_irq) -{ - unsigned long virq; - if (naca->interrupt_controller == IC_OPEN_PIC) - return real_irq; /* no mapping for openpic (for now) */ - virq = real_irq_to_virt(real_irq); - if (virq == UNDEFINED_IRQ) { - /* Assign a virtual IRQ number */ - if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) { - /* A 1-1 mapping will work. */ - virq = real_irq; - } else { - while (last_virt_irq < NR_IRQS && - virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ) - /* skip irq's in use */; - if (last_virt_irq >= NR_IRQS) - panic("Too many IRQs are required on this system. NR_IRQS=%d\n", NR_IRQS); - virq = last_virt_irq; - } - virt_irq_to_real_map[virq] = real_irq; - real_irq_to_virt_map[real_irq] = virq; - } - return virq; -} - - static int __init prom_next_node(phandle *nodep) { @@ -1833,6 +1905,23 @@ *prev_propp = PTRUNRELOC(pp); prev_propp = &pp->next; } + + /* Add a "linux_phandle" value */ + if (np->node != NULL) { + u32 ibm_phandle = 0; + int len; + + /* First see if "ibm,phandle" exists and use its value */ + len = (int) call_prom(RELOC("getprop"), 4, 1, node, + RELOC("ibm,phandle"), + &ibm_phandle, sizeof(ibm_phandle)); + if (len < 0) { + np->linux_phandle = np->node; + } else { + np->linux_phandle = ibm_phandle; + } + } + *prev_propp = 0; /* get the node's full name */ @@ -1866,8 +1955,6 @@ { unsigned long mem = klimit; - virt_irq_init(); - mem = finish_node(allnodes, mem, NULL, 0, 0); dev_tree_size = mem - (unsigned long) allnodes; @@ -1972,7 +2059,7 @@ np->n_intrs = ipsize / isize; mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++)); + np->intrs[i].line = irq_offset_up(*interrupts++); np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; @@ -2334,7 +2421,7 @@ struct device_node *np; for (np = allnodes; np != 0; np = np->allnext) - if (np->node == ph) + if (np->linux_phandle == ph) return np; return NULL; } @@ -2425,7 +2512,7 @@ void __init -abort() +abort(void) { #ifdef CONFIG_XMON xmon(NULL); diff -urN linux-2.4.24/arch/ppc64/kernel/ptrace.c linux-2.4.25/arch/ppc64/kernel/ptrace.c --- linux-2.4.24/arch/ppc64/kernel/ptrace.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ptrace.c 2004-02-18 05:36:30.000000000 -0800 @@ -67,6 +67,28 @@ return -EIO; } +#ifdef CONFIG_ALTIVEC +/* + * Get contents of AltiVec register state in task TASK + */ +static inline int get_vrregs(unsigned long data, struct task_struct *task) +{ + return (copy_to_user((void *)data,&task->thread.vr[0], + offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])) ? -EFAULT : 0 ); +} + +/* + * Write contents of AltiVec register state into task TASK. + */ +static inline int set_vrregs(struct task_struct *task, unsigned long data) +{ + return (copy_from_user(&task->thread.vr[0],(void *)data, + offsetof(struct thread_struct,vrsave[2])- + offsetof(struct thread_struct,vr[0])) ? -EFAULT : 0 ); +} +#endif + static inline void set_single_step(struct task_struct *task) { @@ -316,6 +338,23 @@ } break; } +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = get_vrregs(data, child); + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + /* this is to clear the MSR_VEC bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = set_vrregs(child,data); + break; +#endif default: ret = -EIO; diff -urN linux-2.4.24/arch/ppc64/kernel/ptrace32.c linux-2.4.25/arch/ppc64/kernel/ptrace32.c --- linux-2.4.24/arch/ppc64/kernel/ptrace32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ptrace32.c 2004-02-18 05:36:30.000000000 -0800 @@ -31,6 +31,40 @@ #include #include +#ifdef CONFIG_ALTIVEC +/* + * Get contents of AltiVec register state in task TASK + */ +static inline int get_vrregs32(unsigned long data, struct task_struct *task) +{ + if(copy_to_user((void *)data,&task->thread.vr[0], + offsetof(struct thread_struct,vrsave)- + offsetof(struct thread_struct,vr[0]))) + return -EFAULT; + data+=offsetof(struct thread_struct,vrsave[1])- + offsetof(struct thread_struct,vr[0]); + if (put_user(task->thread.vrsave[1],((u32 *)data))) + return -EFAULT; + return 0; +} + +/* + * Write contents of AltiVec register state into task TASK. + */ +static inline int set_vrregs32(struct task_struct *task, unsigned long data) +{ + if(copy_from_user(&task->thread.vr[0],(void *)data, + offsetof(struct thread_struct,vrsave)- + offsetof(struct thread_struct,vr[0]))) + return -EFAULT; + data+=offsetof(struct thread_struct,vrsave[1])- + offsetof(struct thread_struct,vr[0]); + if (get_user(task->thread.vrsave[1],((u32 *)data))) + return -EFAULT; + return 0; +} +#endif + /* * Set of msr bits that gdb can change on behalf of a process. */ @@ -463,6 +497,23 @@ +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = get_vrregs32((unsigned long)data, child); + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + /* this is to clear the MSR_VEC bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = set_vrregs32(child,(unsigned long)data); + break; +#endif default: ret = -EIO; break; diff -urN linux-2.4.24/arch/ppc64/kernel/ras.c linux-2.4.25/arch/ppc64/kernel/ras.c --- linux-2.4.24/arch/ppc64/kernel/ras.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/ras.c 2004-02-18 05:36:30.000000000 -0800 @@ -73,7 +73,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_error_interrupt, 0, "RAS_ERROR", NULL); ireg++; @@ -84,7 +84,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_epow_interrupt, 0, "RAS_EPOW", NULL); ireg++; @@ -108,7 +108,7 @@ status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 0x500, irq, - EPOW_WARNING | POWERMGM_EVENTS, + RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS, 1, /* Time Critical */ __pa(&log_entry), size); @@ -116,6 +116,9 @@ *((unsigned long *)&log_entry), status); printk(KERN_WARNING "EPOW <0x%lx 0x%lx>\n",*((unsigned long *)&log_entry), status); + + /* format and print the extended information */ + log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, 0); } /* @@ -132,15 +135,23 @@ struct rtas_error_log log_entry; unsigned int size = sizeof(log_entry); long status = 0xdeadbeef; + int fatal; status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 0x500, irq, - INTERNAL_ERROR, + RTAS_INTERNAL_ERROR, 1, /* Time Critical */ __pa(&log_entry), size); - if((status != 1) && - (log_entry.severity >= SEVERITY_ERROR_SYNC)) { + if ((status == 0) && (log_entry.severity >= SEVERITY_ERROR_SYNC)) + fatal = 1; + else + fatal = 0; + + /* format and print the extended information */ + log_error((char *)&log_entry, ERR_TYPE_RTAS_LOG, fatal); + + if (fatal) { udbg_printf("HW Error <0x%lx 0x%lx>\n", *((unsigned long *)&log_entry), status); printk(KERN_EMERG @@ -150,6 +161,7 @@ #ifndef DEBUG /* Don't actually power off when debugging so we can test * without actually failing while injecting errors. + * Error data will not be logged to syslog. */ ppc_md.power_off(); #endif diff -urN linux-2.4.24/arch/ppc64/kernel/rtas-proc.c linux-2.4.25/arch/ppc64/kernel/rtas-proc.c --- linux-2.4.24/arch/ppc64/kernel/rtas-proc.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/rtas-proc.c 2004-02-18 05:36:30.000000000 -0800 @@ -124,6 +124,11 @@ static unsigned long rtas_tone_volume = 0; static unsigned int open_token = 0; +static int set_time_for_power_on = RTAS_UNKNOWN_SERVICE; +static int set_time_of_day = RTAS_UNKNOWN_SERVICE; +static int get_sensor_state = RTAS_UNKNOWN_SERVICE; +static int set_indicator = RTAS_UNKNOWN_SERVICE; + extern struct proc_dir_entry *proc_ppc64_root; extern struct proc_dir_entry *rtas_proc_dir; extern spinlock_t proc_ppc64_lock; @@ -215,6 +220,8 @@ void proc_rtas_init(void) { struct proc_dir_entry *entry; + int display_character; + int errinjct_token; rtas_node = find_devices("rtas"); if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) { @@ -240,29 +247,51 @@ return; } - /* /proc/rtas entries */ + /* + * /proc/rtas entries + * only create entries if rtas token exists for desired function + */ + + set_time_of_day = rtas_token("set-time-of-day"); + if (set_time_of_day != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("clock",S_IRUGO|S_IWUSR,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + } - entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + set_time_for_power_on = rtas_token("set-time-for-power-on"); + if (set_time_for_power_on != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("poweron",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + } - entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + get_sensor_state = rtas_token("get-sensor-state"); + if (get_sensor_state != RTAS_UNKNOWN_SERVICE) { + create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir, + ppc_rtas_sensor_read, NULL); + } - entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + set_indicator = rtas_token("set-indicator"); + if (set_indicator != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("frequency",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; - create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir, - ppc_rtas_sensor_read, NULL); - - entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + entry=create_proc_entry("volume",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + } - entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + display_character = rtas_token("display-character"); + if ((display_character != RTAS_UNKNOWN_SERVICE) || + (set_indicator != RTAS_UNKNOWN_SERVICE)) { + entry=create_proc_entry("progress",S_IRUGO|S_IWUSR,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + } #ifdef CONFIG_RTAS_ERRINJCT - entry = create_proc_entry("errinjct", S_IWUSR|S_IRUGO, rtas_proc_dir); - if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations; + errinjct_token = rtas_token("ibm,errinjct"); + if (errinjct_token != RTAS_UNKNOWN_SERVICE) { + entry=create_proc_entry("errinjct",S_IWUSR|S_IRUGO,rtas_proc_dir); + if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations; + } #endif } @@ -273,12 +302,19 @@ static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ struct rtc_time tm; unsigned long nowtime; char *dest; int error; - nowtime = simple_strtoul(buf, &dest, 10); + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + nowtime = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_poweron_write: Invalid time\n"); return count; @@ -287,11 +323,11 @@ to_tm(nowtime, &tm); - error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL, - tm.tm_year, tm.tm_mon, tm.tm_mday, + error = rtas_call(set_time_for_power_on, 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); if (error != 0) - printk(KERN_WARNING "error: setting poweron time returned: %s\n", + printk(KERN_WARNING "error: setting poweron time returned: %s\n", ppc_rtas_process_error(error)); return count; } @@ -299,18 +335,23 @@ static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ int n; + if (power_on_time == 0) - n = sprintf(buf, "Power on time not set\n"); + n = snprintf(stkbuf, 40, "Power on time not set\n"); else - n = sprintf(buf, "%lu\n", power_on_time); + n = snprintf(stkbuf, 40, "%lu\n", power_on_time); - if (*ppos >= strlen(buf)) + int sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; *ppos += n; return n; } @@ -323,11 +364,17 @@ { unsigned long hex; - strcpy(progress_led, buf); /* save the string */ + if (count >= MAX_LINELENGTH) + count = MAX_LINELENGTH -1; + if (copy_from_user(progress_led, buf, count)) + return -EFAULT; + + progress_led[count] = 0; + /* Lets see if the user passed hexdigits */ - hex = simple_strtoul(buf, NULL, 10); - - ppc_md.progress ((char *)buf, hex); + hex = simple_strtoul(progress_led, NULL, 10); + + ppc_md.progress((char *)progress_led, hex); return count; /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/ @@ -336,15 +383,32 @@ static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n = 0; - if (progress_led != NULL) - n = sprintf (buf, "%s\n", progress_led); - if (*ppos >= strlen(buf)) + int n = 0, sn; + + if (progress_led == NULL) + return 0; + + char * tmpbuf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); + if (!tmpbuf) { + printk(KERN_ERR "error: kmalloc failed\n"); + return -ENOMEM; + } + n = sprintf (tmpbuf, "%s\n", progress_led); + + sn = strlen (tmpbuf) +1; + if (*ppos >= sn) { + kfree(tmpbuf); return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + } + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, tmpbuf + (*ppos), n)) { + kfree(tmpbuf); + return -EFAULT; + } + kfree(tmpbuf); *ppos += n; return n; } @@ -355,12 +419,19 @@ static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ struct rtc_time tm; unsigned long nowtime; char *dest; int error; - nowtime = simple_strtoul(buf, &dest, 10); + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + nowtime = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_clock_write: Invalid time\n"); return count; @@ -388,21 +459,27 @@ year = ret[0]; mon = ret[1]; day = ret[2]; hour = ret[3]; min = ret[4]; sec = ret[5]; + char stkbuf[40]; /* its small, its on stack */ + if (error != 0){ printk(KERN_WARNING "error: reading the clock returned: %s\n", ppc_rtas_process_error(error)); - n = sprintf (buf, "0"); + n = snprintf(stkbuf, 40, "0"); } else { - n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); + n = snprintf(stkbuf, 40, "%lu\n", mktime(year, mon, day, hour, min, sec)); } kfree(ret); - if (*ppos >= strlen(buf)) + int sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } @@ -417,7 +494,6 @@ unsigned long ret; int state, error; char *buffer; - int get_sensor_state = rtas_token("get-sensor-state"); if (count < 0) return -EINVAL; @@ -431,8 +507,8 @@ memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS); n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n"); - n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n"); - n += sprintf ( buffer+n, "********************************************************\n"); + n += sprintf ( buffer+n, "%-17s\t%-15s\t%-15s\tLocation\n", "Sensor", "Value", "Condition"); + n += sprintf ( buffer+n, "***************************************************************************\n"); if (ppc_rtas_find_all_sensors() != 0) { n += sprintf ( buffer+n, "\nNo sensors are available\n"); @@ -538,10 +614,10 @@ int error, char * buf) { /* Defined return vales */ - const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" }; + const char * key_switch[] = { "Off", "Normal", "Secure", "Maintenance" }; const char * enclosure_switch[] = { "Closed", "Open" }; const char * lid_status[] = { " ", "Open", "Closed" }; - const char * power_source[] = { "AC\t", "Battery", "AC & Battery" }; + const char * power_source[] = { "AC", "Battery", "AC & Battery" }; const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" }; const char * epow_sensor[] = { "EPOW Reset", "Cooling warning", "Power warning", @@ -552,101 +628,108 @@ const char * ibm_drconnector[] = { "Empty", "Present" }; const char * ibm_intqueue[] = { "Disabled", "Enabled" }; - int have_strings = 0; int temperature = 0; int unknown = 0; int n = 0; + char *label_string = NULL; + const char **value_arr = NULL; + int value_arrsize = 0; /* What kind of sensor do we have here? */ switch (s.token) { case KEY_SWITCH: - n += sprintf(buf+n, "Key switch:\t"); - n += sprintf(buf+n, "%s\t", key_switch[state]); - have_strings = 1; + label_string = "Key switch:"; + value_arrsize = sizeof(key_switch)/sizeof(char *); + value_arr = key_switch; break; case ENCLOSURE_SWITCH: - n += sprintf(buf+n, "Enclosure switch:\t"); - n += sprintf(buf+n, "%s\t", enclosure_switch[state]); - have_strings = 1; + label_string = "Enclosure switch:"; + value_arrsize = sizeof(enclosure_switch)/sizeof(char *); + value_arr = enclosure_switch; break; case THERMAL_SENSOR: - n += sprintf(buf+n, "Temp. (°C/°F):\t"); + label_string = "Temp. (°C/°F):"; temperature = 1; break; case LID_STATUS: - n += sprintf(buf+n, "Lid status:\t"); - n += sprintf(buf+n, "%s\t", lid_status[state]); - have_strings = 1; + label_string = "Lid status:"; + value_arrsize = sizeof(lid_status)/sizeof(char *); + value_arr = lid_status; break; case POWER_SOURCE: - n += sprintf(buf+n, "Power source:\t"); - n += sprintf(buf+n, "%s\t", power_source[state]); - have_strings = 1; + label_string = "Power source:"; + value_arrsize = sizeof(power_source)/sizeof(char *); + value_arr = power_source; break; case BATTERY_VOLTAGE: - n += sprintf(buf+n, "Battery voltage:\t"); + label_string = "Battery voltage:"; break; case BATTERY_REMAINING: - n += sprintf(buf+n, "Battery remaining:\t"); - n += sprintf(buf+n, "%s\t", battery_remaining[state]); - have_strings = 1; + label_string = "Battery remaining:"; + value_arrsize = sizeof(battery_remaining)/sizeof(char *); + value_arr = battery_remaining; break; case BATTERY_PERCENTAGE: - n += sprintf(buf+n, "Battery percentage:\t"); + label_string = "Battery percentage:"; break; case EPOW_SENSOR: - n += sprintf(buf+n, "EPOW Sensor:\t"); - n += sprintf(buf+n, "%s\t", epow_sensor[state]); - have_strings = 1; + label_string = "EPOW Sensor:"; + value_arrsize = sizeof(epow_sensor)/sizeof(char *); + value_arr = epow_sensor; break; case BATTERY_CYCLESTATE: - n += sprintf(buf+n, "Battery cyclestate:\t"); - n += sprintf(buf+n, "%s\t", battery_cyclestate[state]); - have_strings = 1; + label_string = "Battery cyclestate:"; + value_arrsize = sizeof(battery_cyclestate)/sizeof(char *); + value_arr = battery_cyclestate; break; case BATTERY_CHARGING: - n += sprintf(buf+n, "Battery Charging:\t"); - n += sprintf(buf+n, "%s\t", battery_charging[state]); - have_strings = 1; + label_string = "Battery Charging:"; + value_arrsize = sizeof(battery_charging)/sizeof(char *); + value_arr = battery_charging; break; case IBM_SURVEILLANCE: - n += sprintf(buf+n, "Surveillance:\t"); + label_string = "Surveillance:"; break; case IBM_FANRPM: - n += sprintf(buf+n, "Fan (rpm):\t"); + label_string = "Fan (rpm):"; break; case IBM_VOLTAGE: - n += sprintf(buf+n, "Voltage (mv):\t"); + label_string = "Voltage (mv):"; break; case IBM_DRCONNECTOR: - n += sprintf(buf+n, "DR connector:\t"); - n += sprintf(buf+n, "%s\t", ibm_drconnector[state]); - have_strings = 1; + label_string = "DR connector:"; + value_arrsize = sizeof(ibm_drconnector)/sizeof(char *); + value_arr = ibm_drconnector; break; case IBM_POWERSUPPLY: - n += sprintf(buf+n, "Powersupply:\t"); + label_string = "Powersupply:"; break; case IBM_INTQUEUE: - n += sprintf(buf+n, "Interrupt queue:\t"); - n += sprintf(buf+n, "%s\t", ibm_intqueue[state]); - have_strings = 1; + label_string = "Interrupt queue:"; + value_arrsize = sizeof(ibm_intqueue)/sizeof(char *); + value_arr = ibm_intqueue; break; default: n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n", s.token); unknown = 1; - have_strings = 1; break; } - if (have_strings == 0) { + + if (label_string) + n += sprintf(buf+n, "%-17s\t", label_string); + + if (value_arr && state >= 0 && state < value_arrsize) { + n += sprintf(buf+n, "%-15s\t", value_arr[state]); + } else { if (temperature) { - n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state)); + n += sprintf(buf+n, "%2d / %2d \t", state, cel_to_fahr(state)); } else - n += sprintf(buf+n, "%10d\t", state); + n += sprintf(buf+n, "%-10d\t", state); } if (unknown == 0) { - n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error)); + n += sprintf ( buf+n, "%-15s\t", ppc_rtas_process_error(error)); n += get_location_code(s, buf+n); } return n; @@ -751,7 +834,7 @@ n += check_location_string(ret, buffer + n); n += sprintf ( buffer+n, " "); /* see how many characters we have printed */ - sprintf ( t, "%s ", ret); + snprintf( t, 50, "%s ", ret); pos += strlen(t); if (pos >= llen) pos=0; @@ -764,17 +847,25 @@ static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ unsigned long freq; char *dest; int error; - freq = simple_strtoul(buf, &dest, 10); + + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + freq = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n"); return count; } if (freq < 0) freq = 0; rtas_tone_frequency = freq; /* save it for later */ - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, + error = rtas_call(set_indicator, 3, 1, NULL, TONE_FREQUENCY, 0, freq); if (error != 0) printk(KERN_WARNING "error: setting tone frequency returned: %s\n", @@ -785,15 +876,21 @@ static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; - n = sprintf(buf, "%lu\n", rtas_tone_frequency); + int n, sn; + char stkbuf[40]; /* its small, its on stack */ + + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency); - if (*ppos >= strlen(buf)) + sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } @@ -803,10 +900,18 @@ static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[40]; /* its small, its on stack */ unsigned long volume; char *dest; int error; - volume = simple_strtoul(buf, &dest, 10); + + if (39 < count) + count = 39; + if (copy_from_user(stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + volume = simple_strtoul(stkbuf, &dest, 10); if (*dest != '\0' && *dest != '\n') { printk("ppc_rtas_tone_volume_write: Invalid tone volume\n"); return count; @@ -815,7 +920,7 @@ if (volume > 100) volume = 100; rtas_tone_volume = volume; /* save it for later */ - error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, + error = rtas_call(set_indicator, 3, 1, NULL, TONE_VOLUME, 0, volume); if (error != 0) printk(KERN_WARNING "error: setting tone volume returned: %s\n", @@ -826,15 +931,20 @@ static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; - n = sprintf(buf, "%lu\n", rtas_tone_volume); + int n, sn; + char stkbuf[40]; /* its small, its on stack */ - if (*ppos >= strlen(buf)) + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume); + sn = strlen(stkbuf) +1; + if (*ppos >= sn) return 0; - if (n > strlen(buf) - *ppos) - n = strlen(buf) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; + if (copy_to_user(buf, stkbuf + (*ppos), n)) + return -EFAULT; + *ppos += n; return n; } @@ -864,7 +974,7 @@ static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - + char * tmpbuf; char * ei_token; char * workspace = NULL; size_t max_len; @@ -878,16 +988,26 @@ max_len = ERRINJCT_TOKEN_LEN; } - token_len = strnlen(buf, max_len); + tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL); + if (!tmpbuf) { + printk(KERN_WARNING "error: kmalloc failed\n"); + return -ENOMEM; + } + if (copy_from_user (tmpbuf, buf, max_len)) { + kfree(tmpbuf); + return -EFAULT; + } + token_len = strnlen(tmpbuf, max_len); token_len++; /* Add one for the null termination */ ei_token = (char *)kmalloc(token_len, GFP_KERNEL); if (!ei_token) { printk(KERN_WARNING "error: kmalloc failed\n"); + kfree(tmpbuf); return -ENOMEM; } - strncpy(ei_token, buf, token_len); + strncpy(ei_token, tmpbuf, token_len); if (count > token_len + WORKSPACE_SIZE) { count = token_len + WORKSPACE_SIZE; @@ -907,11 +1027,12 @@ workspace = (char *)kmalloc(max_len, GFP_KERNEL); if (!workspace) { printk(KERN_WARNING "error: failed kmalloc\n"); + kfree(tmpbuf); kfree(ei_token); return -ENOMEM; } - memcpy(workspace, buf, max_len); + memcpy(workspace, tmpbuf, max_len); } rc = rtas_errinjct(open_token, ei_token, workspace); @@ -920,6 +1041,7 @@ kfree(workspace); } kfree(ei_token); + kfree(tmpbuf); return rc < 0 ? rc : count; } @@ -940,32 +1062,36 @@ size_t count, loff_t *ppos) { char * buffer; - int i; + int i, sn; int n = 0; - buffer = (char *)kmalloc(MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1), - GFP_KERNEL); + int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1); + buffer = (char *)kmalloc(m, GFP_KERNEL); if (!buffer) { printk(KERN_ERR "error: kmalloc failed\n"); return -ENOMEM; } for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) { - n += sprintf(buffer+n, ei_token_list[i].name); - n += sprintf(buffer+n, "\n"); + n += snprintf(buffer+n, m-n, ei_token_list[i].name); + n += snprintf(buffer+n, m-n, "\n"); } - if (*ppos >= strlen(buffer)) { + sn = strlen(buffer) +1; + if (*ppos >= sn) { kfree(buffer); return 0; } - if (n > strlen(buffer) - *ppos) - n = strlen(buffer) - *ppos; + if (n > sn - *ppos) + n = sn - *ppos; if (n > count) n = count; - memcpy(buf, buffer + *ppos, n); + if (copy_to_user(buf, buffer + *ppos, n)) { + kfree(buffer); + return -EFAULT; + } *ppos += n; diff -urN linux-2.4.24/arch/ppc64/kernel/rtas.c linux-2.4.25/arch/ppc64/kernel/rtas.c --- linux-2.4.24/arch/ppc64/kernel/rtas.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/rtas.c 2004-02-18 05:36:30.000000000 -0800 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -184,6 +185,26 @@ return (ulong)((nret > 0) ? rtas_args->rets[0] : 0); } +/* Given an RTAS status code of 990n compute the hinted delay of 10^n + * (last digit) milliseconds. For now we bound at n=3 (1 sec). + */ +unsigned int +rtas_extended_busy_delay_time(int status) +{ + int order = status - 9900; + unsigned int ms; + + if (order < 0) + order = 0; /* RTC depends on this for -2 clock busy */ + else if (order > 3) + order = 3; /* bound */ + + /* Use microseconds for reasonable accuracy */ + for (ms = 1000; order > 0; order--) + ms = ms * 10; + return ms / (1000000/HZ); /* round down is fine */ +} + #define FLASH_BLOCK_LIST_VERSION (1UL) static void rtas_flash_firmware(void) @@ -207,7 +228,8 @@ rtas_firmware_flash_list.num_blocks = 0; flist = (struct flash_block_list *)&rtas_firmware_flash_list; rtas_block_list = virt_to_absolute((unsigned long)flist); - if (rtas_block_list >= (4UL << 20)) { + + if (rtas_block_list >= 4UL*1024*1024*1024) { printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); return; } diff -urN linux-2.4.24/arch/ppc64/kernel/rtas_flash.c linux-2.4.25/arch/ppc64/kernel/rtas_flash.c --- linux-2.4.24/arch/ppc64/kernel/rtas_flash.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/rtas_flash.c 2004-02-18 05:36:30.000000000 -0800 @@ -25,6 +25,52 @@ #define MODULE_NAME "rtas_flash" #define FIRMWARE_FLASH_NAME "firmware_flash" +#define FIRMWARE_UPDATE_NAME "firmware_update" +#define MANAGE_FLASH_NAME "manage_flash" +#define VALIDATE_FLASH_NAME "validate_flash" + +/* General RTAS Status Codes */ +#define RTAS_RC_SUCCESS 0 +#define RTAS_RC_HW_ERR -1 +#define RTAS_RC_BUSY -2 + +/* Flash image status values */ +#define FLASH_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define FLASH_NO_OP -1099 /* No operation initiated by user */ +#define FLASH_IMG_SHORT -1005 /* Flash image shorter than expected */ +#define FLASH_IMG_BAD_LEN -1004 /* Bad length value in flash list block */ +#define FLASH_IMG_NULL_DATA -1003 /* Bad data value in flash list block */ +#define FLASH_IMG_READY 0 /* Firmware img ready for flash on reboot */ + +/* Manage image status values */ +#define MANAGE_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define MANAGE_ACTIVE_ERR -9001 /* RTAS Cannot Overwrite Active Img */ +#define MANAGE_NO_OP -1099 /* No operation initiated by user */ +#define MANAGE_PARAM_ERR -3 /* RTAS Parameter Error */ +#define MANAGE_HW_ERR -1 /* RTAS Hardware Error */ + +/* Validate image status values */ +#define VALIDATE_AUTH -9002 /* RTAS Not Service Authority Partition */ +#define VALIDATE_NO_OP -1099 /* No operation initiated by the user */ +#define VALIDATE_INCOMPLETE -1002 /* User copied < VALIDATE_BUF_SIZE */ +#define VALIDATE_READY -1001 /* Firmware image ready for validation */ +#define VALIDATE_PARAM_ERR -3 /* RTAS Parameter Error */ +#define VALIDATE_HW_ERR -1 /* RTAS Hardware Error */ +#define VALIDATE_TMP_UPDATE 0 /* Validate Return Status */ +#define VALIDATE_FLASH_AUTH 1 /* Validate Return Status */ +#define VALIDATE_INVALID_IMG 2 /* Validate Return Status */ +#define VALIDATE_CUR_UNKNOWN 3 /* Validate Return Status */ +#define VALIDATE_TMP_COMMIT_DL 4 /* Validate Return Status */ +#define VALIDATE_TMP_COMMIT 5 /* Validate Return Status */ +#define VALIDATE_TMP_UPDATE_DL 6 /* Validate Return Status */ + +/* ibm,manage-flash-image operation tokens */ +#define RTAS_REJECT_TMP_IMG 0 +#define RTAS_COMMIT_TMP_IMG 1 + +/* Array sizes */ +#define VALIDATE_BUF_SIZE 4096 +#define RTAS_MSG_MAXLEN 64 /* Local copy of the flash block list. * We only allow one open of the flash proc file and create this @@ -36,21 +82,35 @@ * is treated as the number of entries currently in the block * (i.e. not a byte count). This is all fixed on release. */ -static struct flash_block_list *flist; -static char *flash_msg; -static int flash_possible; - -static int rtas_flash_open(struct inode *inode, struct file *file) -{ - if ((file->f_mode & FMODE_WRITE) && flash_possible) { - if (flist) - return -EBUSY; - flist = (struct flash_block_list *)get_free_page(GFP_KERNEL); - if (!flist) - return -ENOMEM; - } - return 0; -} + +/* Status int must be first member of struct */ +struct rtas_update_flash_t +{ + int status; /* Flash update status */ + struct flash_block_list *flist; /* Local copy of flash block list */ +}; + +/* Status int must be first member of struct */ +struct rtas_manage_flash_t +{ + int status; /* Returned status */ + unsigned int op; /* Reject or commit image */ +}; + +/* Status int must be first member of struct */ +struct rtas_validate_flash_t +{ + int status; /* Returned status */ + char buf[VALIDATE_BUF_SIZE]; /* Candidate image buffer */ + unsigned int buf_size; /* Size of image buf */ + unsigned int update_results; /* Update results token */ +}; + +static spinlock_t flash_file_open_lock = SPIN_LOCK_UNLOCKED; +static struct proc_dir_entry *firmware_flash_pde = NULL; +static struct proc_dir_entry *firmware_update_pde = NULL; +static struct proc_dir_entry *validate_pde = NULL; +static struct proc_dir_entry *manage_pde = NULL; /* Do simple sanity checks on the flash image. */ static int flash_list_valid(struct flash_block_list *flist) @@ -59,32 +119,27 @@ int i; unsigned long block_size, image_size; - flash_msg = NULL; /* Paranoid self test here. We also collect the image size. */ image_size = 0; for (f = flist; f; f = f->next) { for (i = 0; i < f->num_blocks; i++) { if (f->blocks[i].data == NULL) { - flash_msg = "error: internal error null data\n"; - return 0; + return FLASH_IMG_NULL_DATA; } block_size = f->blocks[i].length; if (block_size <= 0 || block_size > PAGE_SIZE) { - flash_msg = "error: internal error bad length\n"; - return 0; + return FLASH_IMG_BAD_LEN; } image_size += block_size; } } - if (image_size < (256 << 10)) { - if (image_size < 2) - flash_msg = NULL; /* allow "clear" of image */ - else - flash_msg = "error: flash image short\n"; - return 0; - } + + if (image_size < 2) + return FLASH_NO_OP; + printk(KERN_INFO "FLASH: flash image with %ld bytes stored for hardware flash on reboot\n", image_size); - return 1; + + return FLASH_IMG_READY; } static void free_flash_list(struct flash_block_list *f) @@ -103,40 +158,80 @@ static int rtas_flash_release(struct inode *inode, struct file *file) { - if (flist) { - /* Always clear saved list on a new attempt. */ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; + + uf = (struct rtas_update_flash_t *) dp->data; + if (uf->flist) { + /* File was opened in write mode for a new flash attempt */ + /* Clear saved list */ if (rtas_firmware_flash_list.next) { free_flash_list(rtas_firmware_flash_list.next); rtas_firmware_flash_list.next = NULL; } - if (flash_list_valid(flist)) - rtas_firmware_flash_list.next = flist; + if (uf->status != FLASH_AUTH) + uf->status = flash_list_valid(uf->flist); + + if (uf->status == FLASH_IMG_READY) + rtas_firmware_flash_list.next = uf->flist; else - free_flash_list(flist); - flist = NULL; + free_flash_list(uf->flist); + + uf->flist = NULL; } + + atomic_dec(&dp->count); return 0; } +static void get_flash_status_msg(int status, char *buf) +{ + char *msg; + + switch (status) { + case FLASH_AUTH: + msg = "error: this partition does not have service authority\n"; + break; + case FLASH_NO_OP: + msg = "info: no firmware image for flash\n"; + break; + case FLASH_IMG_SHORT: + msg = "error: flash image short\n"; + break; + case FLASH_IMG_BAD_LEN: + msg = "error: internal error bad length\n"; + break; + case FLASH_IMG_NULL_DATA: + msg = "error: internal error null data\n"; + break; + case FLASH_IMG_READY: + msg = "ready: firmware image ready for flash on reboot\n"; + break; + default: + sprintf(buf, "error: unexpected status value %d\n", status); + return; + } + + strcpy(buf, msg); +} + /* Reading the proc file will show status (not the firmware contents) */ static ssize_t rtas_flash_read(struct file *file, char *buf, size_t count, loff_t *ppos) { + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; + char msg[RTAS_MSG_MAXLEN]; int error; - char *msg; int msglen; - if (!flash_possible) { - msg = "error: this partition does not have service authority\n"; - } else if (flist) { - msg = "info: this file is busy for write by some process\n"; - } else if (flash_msg) { - msg = flash_msg; /* message from last flash attempt */ - } else if (rtas_firmware_flash_list.next) { - msg = "ready: firmware image ready for flash on reboot\n"; - } else { - msg = "info: no firmware image for flash\n"; + uf = (struct rtas_update_flash_t *) dp->data; + + if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) { + get_flash_status_msg(uf->status, msg); + } else { /* FIRMWARE_UPDATE_NAME */ + sprintf(msg, "%d\n", uf->status); } msglen = strlen(msg); if (msglen > count) @@ -149,7 +244,8 @@ if (error) return -EINVAL; - copy_to_user(buf, msg, msglen); + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; if (ppos) *ppos = msglen; @@ -164,14 +260,28 @@ static ssize_t rtas_flash_write(struct file *file, const char *buffer, size_t count, loff_t *off) { - size_t len = count; + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_update_flash_t *uf; char *p; int next_free; - struct flash_block_list *fl = flist; + struct flash_block_list *fl; - if (!flash_possible || len == 0) - return len; /* discard data */ + uf = (struct rtas_update_flash_t *) dp->data; + if (uf->status == FLASH_AUTH || count == 0) + return count; /* discard data */ + + /* In the case that the image is not ready for flashing, the memory + * allocated for the block list will be freed upon the release of the + * proc file + */ + if (uf->flist == NULL) { + uf->flist = (struct flash_block_list *) get_free_page(GFP_KERNEL); + if (!uf->flist) + return -ENOMEM; + } + + fl = uf->flist; while (fl->next) fl = fl->next; /* seek to last block_list for append */ next_free = fl->num_blocks; @@ -184,47 +294,392 @@ next_free = 0; } - if (len > PAGE_SIZE) - len = PAGE_SIZE; + if (count > PAGE_SIZE) + count = PAGE_SIZE; p = (char *)get_free_page(GFP_KERNEL); if (!p) return -ENOMEM; - if(copy_from_user(p, buffer, len)) { + + if(copy_from_user(p, buffer, count)) { free_page((unsigned long)p); return -EFAULT; } fl->blocks[next_free].data = p; - fl->blocks[next_free].length = len; + fl->blocks[next_free].length = count; fl->num_blocks++; - return len; + return count; +} + +static int rtas_excl_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + + /* Enforce exclusive open with use count of PDE */ + spin_lock(&flash_file_open_lock); + if (atomic_read(&dp->count) > 1) { + spin_unlock(&flash_file_open_lock); + return -EBUSY; + } + + atomic_inc(&dp->count); + spin_unlock(&flash_file_open_lock); + + return 0; +} + +static int rtas_excl_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + + atomic_dec(&dp->count); + + return 0; +} + +static void manage_flash(struct rtas_manage_flash_t *args_buf) +{ + unsigned int wait_time; + s32 rc; + + while (1) { + rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1, + 1, NULL, (long) args_buf->op); + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } + + args_buf->status = rc; +} + +static ssize_t manage_flash_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_manage_flash_t *args_buf; + char msg[RTAS_MSG_MAXLEN]; + int msglen; + int error; + + args_buf = (struct rtas_manage_flash_t *) dp->data; + if (args_buf == NULL) + return 0; + + msglen = sprintf(msg, "%d\n", args_buf->status); + if (msglen > count) + msglen = count; + + if (ppos && *ppos != 0) + return 0; /* be cheap */ + + error = verify_area(VERIFY_WRITE, buf, msglen); + if (error) + return -EINVAL; + + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; + + if (ppos) + *ppos = msglen; + return msglen; +} + +static ssize_t manage_flash_write(struct file *file, const char *buf, + size_t count, loff_t *off) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_manage_flash_t *args_buf; + const char reject_str[] = "0"; + const char commit_str[] = "1"; + char stkbuf[10]; + int op; + + args_buf = (struct rtas_manage_flash_t *) dp->data; + if ((args_buf->status == MANAGE_AUTH) || (count == 0)) + return count; + + op = -1; + if (buf) { + if (count > 9) count = 9; + if (copy_from_user (stkbuf, buf, count)) { + return -EFAULT; + } + if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) + op = RTAS_REJECT_TMP_IMG; + else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) + op = RTAS_COMMIT_TMP_IMG; + } + + if (op == -1) /* buf is empty, or contains invalid string */ + return -EINVAL; + + args_buf->op = op; + manage_flash(args_buf); + + return count; +} + +static void validate_flash(struct rtas_validate_flash_t *args_buf) +{ + int token = rtas_token("ibm,validate-flash-image"); + unsigned int wait_time; + long update_results; + s32 rc; + + rc = 0; + while(1) { + spin_lock(&rtas_data_buf_lock); + memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); + rc = (s32) rtas_call(token, 2, 2, &update_results, + __pa(rtas_data_buf), args_buf->buf_size); + memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); + spin_unlock(&rtas_data_buf_lock); + + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } + + args_buf->status = rc; + args_buf->update_results = (u32) update_results; +} + +static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, + char *msg) +{ + int n; + + if (args_buf->status >= VALIDATE_TMP_UPDATE) { + n = sprintf(msg, "%d\n", args_buf->update_results); + if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || + (args_buf->update_results == VALIDATE_TMP_UPDATE)) + n += sprintf(msg + n, "%s\n", args_buf->buf); + } else { + n = sprintf(msg, "%d\n", args_buf->status); + } + return n; +} + +static ssize_t validate_flash_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + char msg[RTAS_MSG_MAXLEN]; + int msglen; + int error; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (ppos && *ppos != 0) + return 0; /* be cheap */ + + msglen = get_validate_flash_msg(args_buf, msg); + if (msglen > count) + msglen = count; + + error = verify_area(VERIFY_WRITE, buf, msglen); + if (error) + return -EINVAL; + + if (copy_to_user(buf, msg, msglen)) + return -EFAULT; + + if (ppos) + *ppos = msglen; + return msglen; +} + +static ssize_t validate_flash_write(struct file *file, const char *buf, + size_t count, loff_t *off) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + int rc; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (dp->data == NULL) { + dp->data = kmalloc(sizeof(struct rtas_validate_flash_t), + GFP_KERNEL); + if (dp->data == NULL) + return -ENOMEM; + } + + /* We are only interested in the first 4K of the + * candidate image */ + if ((*off >= VALIDATE_BUF_SIZE) || + (args_buf->status == VALIDATE_AUTH)) { + *off += count; + return count; + } + + if (*off + count >= VALIDATE_BUF_SIZE) { + count = VALIDATE_BUF_SIZE - *off; + args_buf->status = VALIDATE_READY; + } else { + args_buf->status = VALIDATE_INCOMPLETE; + } + + if (verify_area(VERIFY_READ, buf, count)) { + rc = -EFAULT; + goto done; + } + if (copy_from_user(args_buf->buf + *off, buf, count)) { + rc = -EFAULT; + goto done; + } + + *off += count; + rc = count; +done: + if (rc < 0) { + kfree(dp->data); + dp->data = NULL; + } + return rc; +} + +static int validate_flash_release(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip; + struct rtas_validate_flash_t *args_buf; + + args_buf = (struct rtas_validate_flash_t *) dp->data; + + if (args_buf->status == VALIDATE_READY) { + args_buf->buf_size = VALIDATE_BUF_SIZE; + validate_flash(args_buf); + } + + atomic_dec(&dp->count); + + return 0; +} + +static inline void remove_flash_pde(struct proc_dir_entry *dp) +{ + if (dp) { + if (dp->data != NULL) + kfree(dp->data); + remove_proc_entry(dp->name, rtas_proc_dir); + } +} + +static inline int initialize_flash_pde_data(const char *rtas_call_name, + size_t buf_size, + struct proc_dir_entry *dp) +{ + int *status; + int token; + + dp->data = kmalloc(buf_size, GFP_KERNEL); + if (dp->data == NULL) { + remove_flash_pde(dp); + return -ENOMEM; + } + + memset(dp->data, 0, buf_size); + + /* This code assumes that the status int is the first member of the + * struct + */ + status = (int *) dp->data; + token = rtas_token(rtas_call_name); + if (token == RTAS_UNKNOWN_SERVICE) + *status = FLASH_AUTH; + else + *status = FLASH_NO_OP; + + return 0; +} + +static inline struct proc_dir_entry * create_flash_pde(const char *filename, + struct file_operations *fops) +{ + struct proc_dir_entry *ent = NULL; + + ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, rtas_proc_dir); + if (ent != NULL) { + ent->nlink = 1; + ent->proc_fops = fops; + ent->owner = THIS_MODULE; + } + + return ent; } static struct file_operations rtas_flash_operations = { read: rtas_flash_read, write: rtas_flash_write, - open: rtas_flash_open, + open: rtas_excl_open, release: rtas_flash_release, }; +static struct file_operations manage_flash_operations = { + read: manage_flash_read, + write: manage_flash_write, + open: rtas_excl_open, + release: rtas_excl_release, +}; + +static struct file_operations validate_flash_operations = { + read: validate_flash_read, + write: validate_flash_write, + open: rtas_excl_open, + release: validate_flash_release, +}; int __init rtas_flash_init(void) { - struct proc_dir_entry *ent = NULL; + int rc; if (!rtas_proc_dir) { printk(KERN_WARNING "rtas proc dir does not already exist"); return -ENOENT; } - if (rtas_token("ibm,update-flash-64-and-reboot") != RTAS_UNKNOWN_SERVICE) - flash_possible = 1; + firmware_flash_pde = create_flash_pde(FIRMWARE_FLASH_NAME, + &rtas_flash_operations); + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", + sizeof(struct rtas_update_flash_t), + firmware_flash_pde); + if (rc != 0) + return rc; + + firmware_update_pde = create_flash_pde(FIRMWARE_UPDATE_NAME, + &rtas_flash_operations); + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", + sizeof(struct rtas_update_flash_t), + firmware_update_pde); + if (rc != 0) + return rc; + + validate_pde = create_flash_pde(VALIDATE_FLASH_NAME, + &validate_flash_operations); + rc = initialize_flash_pde_data("ibm,validate-flash-image", + sizeof(struct rtas_validate_flash_t), + validate_pde); + if (rc != 0) + return rc; + + manage_pde = create_flash_pde(MANAGE_FLASH_NAME, + &manage_flash_operations); + rc = initialize_flash_pde_data("ibm,manage-flash-image", + sizeof(struct rtas_manage_flash_t), + manage_pde); + if (rc != 0) + return rc; - if ((ent = create_proc_entry(FIRMWARE_FLASH_NAME, S_IRUSR | S_IWUSR, rtas_proc_dir)) != NULL) { - ent->nlink = 1; - ent->proc_fops = &rtas_flash_operations; - ent->owner = THIS_MODULE; - } return 0; } @@ -232,7 +687,10 @@ { if (!rtas_proc_dir) return; - remove_proc_entry(FIRMWARE_FLASH_NAME, rtas_proc_dir); + remove_flash_pde(firmware_flash_pde); + remove_flash_pde(firmware_update_pde); + remove_flash_pde(validate_pde); + remove_flash_pde(manage_pde); } module_init(rtas_flash_init); diff -urN linux-2.4.24/arch/ppc64/kernel/rtasd.c linux-2.4.25/arch/ppc64/kernel/rtasd.c --- linux-2.4.24/arch/ppc64/kernel/rtasd.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/rtasd.c 2004-02-18 05:36:30.000000000 -0800 @@ -17,11 +17,14 @@ #include #include #include +#include #include #include #include #include +#include +#include #if 0 #define DEBUG(A...) printk(KERN_ERR A) @@ -29,37 +32,181 @@ #define DEBUG(A...) #endif -static spinlock_t rtas_log_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t log_lock = SPIN_LOCK_UNLOCKED; DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait); -#define LOG_NUMBER 64 /* must be a power of two */ -#define LOG_NUMBER_MASK (LOG_NUMBER-1) - static char *rtas_log_buf; static unsigned long rtas_log_start; static unsigned long rtas_log_size; -static int surveillance_requested; +static int surveillance_timeout = -1; static unsigned int rtas_event_scan_rate; static unsigned int rtas_error_log_max; -#define EVENT_SCAN_ALL_EVENTS 0xf0000000 -#define SURVEILLANCE_TOKEN 9000 -#define SURVEILLANCE_TIMEOUT 1 -#define SURVEILLANCE_SCANRATE 1 +static unsigned int rtas_error_log_buffer_max; extern struct proc_dir_entry *proc_ppc64_root; extern struct proc_dir_entry *rtas_proc_dir; extern spinlock_t proc_ppc64_lock; +extern volatile int no_more_logging; + +volatile int error_log_cnt = 0; + /* * Since we use 32 bit RTAS, the physical address of this must be below * 4G or else bad things happen. Allocate this in the kernel data and * make it big enough. */ -#define RTAS_ERROR_LOG_MAX 1024 static unsigned char logdata[RTAS_ERROR_LOG_MAX]; +/* To see this info, grep RTAS /var/log/messages and each entry + * will be collected together with obvious begin/end. + * There will be a unique identifier on the begin and end lines. + * This will persist across reboots. + * + * format of error logs returned from RTAS: + * bytes (size) : contents + * -------------------------------------------------------- + * 0-7 (8) : rtas_error_log + * 8-47 (40) : extended info + * 48-51 (4) : vendor id + * 52-1023 (vendor specific) : location code and debug data + */ +static void printk_log_rtas(char *buf, int len) +{ + + int i,j,n; + int perline = 16; + char buffer[64]; + char * str = "RTAS event"; + + printk(RTAS_ERR "%d -------- %s begin --------\n", error_log_cnt, str); + + /* + * Print perline bytes on each line, each line will start + * with RTAS and a changing number, so syslogd will + * print lines that are otherwise the same. Separate every + * 4 bytes with a space. + */ + for (i=0; i < len; i++) { + j = i % perline; + if (j == 0) { + memset(buffer, 0, sizeof(buffer)); + n = sprintf(buffer, "RTAS %d:", i/perline); + } + + if ((i % 4) == 0) + n += sprintf(buffer+n, " "); + + n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]); + + if (j == (perline-1)) + printk(KERN_ERR "%s\n", buffer); + } + if ((i % perline) != 0) + printk(KERN_ERR "%s\n", buffer); + + printk(RTAS_ERR "%d -------- %s end ----------\n", error_log_cnt, str); +} + +static int log_rtas_len(char * buf) +{ + int len; + struct rtas_error_log *err; + + /* rtas fixed header */ + len = 8; + err = (struct rtas_error_log *)buf; + if (err->extended_log_length) { + + /* extended header */ + len += err->extended_log_length; + + if (len > RTAS_ERROR_LOG_MAX) + len = RTAS_ERROR_LOG_MAX; + } + return len; +} + +/* + * First write to nvram, if fatal error, that is the only + * place we log the info. The error will be picked up + * on the next reboot by rtasd. If not fatal, run the + * method for the type of error. Currently, only RTAS + * errors have methods implemented, but in the future + * there might be a need to store data in nvram before a + * call to panic(). +*/ +void pSeries_log_error(char *buf, unsigned int err_type, int fatal) +{ + unsigned long offset; + unsigned long s; + int len = 0; + + DEBUG("logging event\n"); + + if (buf == NULL) + return; + + spin_lock_irqsave(&log_lock, s); + + /* get length and increase count */ + switch (err_type & ERR_TYPE_MASK) { + case ERR_TYPE_RTAS_LOG: + len = log_rtas_len(buf); + if (!(err_type & ERR_FLAG_BOOT)) + error_log_cnt++; + break; + case ERR_TYPE_KERNEL_PANIC: + default: + spin_unlock_irqrestore(&log_lock, s); + return; + } + + /* Write error to NVRAM */ + if (!no_more_logging && !(err_type & ERR_FLAG_BOOT)) { + write_error_log_nvram(buf, len, err_type); + } + + /* Check to see if we need to or have stopped logging */ + if (fatal || no_more_logging) { + no_more_logging = 1; + spin_unlock_irqrestore(&log_lock, s); + return; + } + + /* call type specific method for error */ + switch (err_type & ERR_TYPE_MASK) { + case ERR_TYPE_RTAS_LOG: + /* put into syslog and error_log file */ + printk_log_rtas(buf, len); + + offset = rtas_error_log_buffer_max * + ((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK); + + /* First copy over sequence number */ + memcpy(&rtas_log_buf[offset], &error_log_cnt, sizeof(int)); + + /* Second copy over error log data */ + offset += sizeof(int); + memcpy(&rtas_log_buf[offset], buf, len); + + if (rtas_log_size < LOG_NUMBER) + rtas_log_size += 1; + else + rtas_log_start += 1; + + spin_unlock_irqrestore(&log_lock, s); + wake_up_interruptible(&rtas_log_wait); + break; + case ERR_TYPE_KERNEL_PANIC: + default: + spin_unlock_irqrestore(&log_lock, s); + return; + } + +} static int rtas_log_open(struct inode * inode, struct file * file) { return 0; @@ -70,36 +217,50 @@ return 0; } +/* This will check if all events are logged, if they are then, we + * know that we can safely clear the events in NVRAM. + * Next we'll sit and wait for something else to log. + */ static ssize_t rtas_log_read(struct file * file, char * buf, size_t count, loff_t *ppos) { int error; char *tmp; + unsigned long s; unsigned long offset; - if (!buf || count < rtas_error_log_max) + if (!buf || count < rtas_error_log_buffer_max) return -EINVAL; - count = rtas_error_log_max; + count = rtas_error_log_buffer_max; error = verify_area(VERIFY_WRITE, buf, count); if (error) - return -EINVAL; + return -EFAULT; - tmp = kmalloc(rtas_error_log_max, GFP_KERNEL); + tmp = kmalloc(count, GFP_KERNEL); if (!tmp) return -ENOMEM; + + spin_lock_irqsave(&log_lock, s); + /* if it's 0, then we know we got the last one (the one in NVRAM) */ + if (rtas_log_size == 0 && !no_more_logging) + clear_error_log_nvram(); + spin_unlock_irqrestore(&log_lock, s); + + error = wait_event_interruptible(rtas_log_wait, rtas_log_size); if (error) goto out; - spin_lock(&rtas_log_lock); - offset = rtas_error_log_max * (rtas_log_start & LOG_NUMBER_MASK); + spin_lock_irqsave(&log_lock, s); + offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); + rtas_log_start += 1; rtas_log_size -= 1; - spin_unlock(&rtas_log_lock); + spin_unlock_irqrestore(&log_lock, s); error = copy_to_user(buf, tmp, count) ? -EFAULT : count; out: @@ -122,607 +283,18 @@ .release = rtas_log_release, }; - -#define RTAS_ERR KERN_ERR "RTAS: " - -/* Extended error log header (12 bytes) */ -struct exthdr { - unsigned int valid:1; - unsigned int unrecoverable:1; - unsigned int recoverable:1; - unsigned int unrecoverable_bypassed:1; /* i.e. degraded performance */ - unsigned int predictive:1; - unsigned int newlog:1; - unsigned int bigendian:1; /* always 1 */ - unsigned int /* reserved */:1; - - unsigned int platform_specific:1; /* only in version 3+ */ - unsigned int /* reserved */:3; - unsigned int platform_value:4; /* valid iff platform_specific */ - - unsigned int power_pc:1; /* always 1 */ - unsigned int /* reserved */:2; - unsigned int addr_invalid:1; /* failing_address is invalid */ - unsigned int format_type:4; -#define EXTLOG_FMT_CPU 1 -#define EXTLOG_FMT_MEMORY 2 -#define EXTLOG_FMT_IO 3 -#define EXTLOG_FMT_POST 4 -#define EXTLOG_FMT_ENV 5 -#define EXTLOG_FMT_POW 6 -#define EXTLOG_FMT_IBMDIAG 12 -#define EXTLOG_FMT_IBMSP 13 - - /* This group is in version 3+ only */ - unsigned int non_hardware:1; /* Firmware or software is suspect */ - unsigned int hot_plug:1; /* Failing component may be hot plugged */ - unsigned int group_failure:1; /* Group of components should be replaced */ - unsigned int /* reserved */:1; - - unsigned int residual:1; /* Residual error from previous boot (maybe a crash) */ - unsigned int boot:1; /* Error during boot */ - unsigned int config_change:1; /* Configuration changed since last boot */ - unsigned int post:1; /* Error during POST */ - - unsigned int bcdtime:32; /* Time of error in BCD HHMMSS00 */ - unsigned int bcddate:32; /* Time of error in BCD YYYYMMDD */ -}; - -struct cpuhdr { - unsigned int internal:1; - unsigned int intcache:1; - unsigned int extcache_parity:1; /* or multi-bit ECC */ - unsigned int extcache_ecc:1; - unsigned int sysbus_timeout:1; - unsigned int io_timeout:1; - unsigned int sysbus_parity:1; - unsigned int sysbus_protocol:1; - unsigned int cpuid:8; - unsigned int element:16; - unsigned int failing_address_hi:32; - unsigned int failing_address_lo:32; - - /* These are version 4+ */ - unsigned int try_reboot:1; /* 1 => fault may be fixed by reboot */ - unsigned int /* reserved */:7; - /* 15 bytes reserved here */ -}; - -struct memhdr { - unsigned int uncorrectable:1; - unsigned int ECC:1; - unsigned int threshold_exceeded:1; - unsigned int control_internal:1; - unsigned int bad_address:1; - unsigned int bad_data:1; - unsigned int bus:1; - unsigned int timeout:1; - unsigned int sysbus_parity:1; - unsigned int sysbus_timeout:1; - unsigned int sysbus_protocol:1; - unsigned int hostbridge_timeout:1; - unsigned int hostbridge_parity:1; - unsigned int reserved1:1; - unsigned int support:1; - unsigned int sysbus_internal:1; - unsigned int mem_controller_detected:8; /* who detected fault? */ - unsigned int mem_controller_faulted:8; /* who caused fault? */ - unsigned int failing_address_hi:32; - unsigned int failing_address_lo:32; - unsigned int ecc_syndrome:16; - unsigned int memory_card:8; - unsigned int reserved2:8; - unsigned int sub_elements:32; /* one bit per element */ - unsigned int element:16; -}; - -struct iohdr { - unsigned int bus_addr_parity:1; - unsigned int bus_data_parity:1; - unsigned int bus_timeout:1; - unsigned int bridge_internal:1; - unsigned int non_pci:1; /* i.e. secondary bus such as ISA */ - unsigned int mezzanine_addr_parity:1; - unsigned int mezzanine_data_parity:1; - unsigned int mezzanine_timeout:1; - - unsigned int bridge_via_sysbus:1; - unsigned int bridge_via_mezzanine:1; - unsigned int bridge_via_expbus:1; - unsigned int detected_by_expbus:1; - unsigned int expbus_data_parity:1; - unsigned int expbus_timeout:1; - unsigned int expbus_connection_failure:1; - unsigned int expbus_not_operating:1; - - /* IOA signalling the error */ - unsigned int pci_sig_busno:8; - unsigned int pci_sig_devfn:8; - unsigned int pci_sig_deviceid:16; - unsigned int pci_sig_vendorid:16; - unsigned int pci_sig_revisionid:8; - unsigned int pci_sig_slot:8; /* 00 => system board, ff => multiple */ - - /* IOA sending at time of error */ - unsigned int pci_send_busno:8; - unsigned int pci_send_devfn:8; - unsigned int pci_send_deviceid:16; - unsigned int pci_send_vendorid:16; - unsigned int pci_send_revisionid:8; - unsigned int pci_send_slot:8; /* 00 => system board, ff => multiple */ -}; - -struct posthdr { - unsigned int firmware:1; - unsigned int config:1; - unsigned int cpu:1; - unsigned int memory:1; - unsigned int io:1; - unsigned int keyboard:1; - unsigned int mouse:1; - unsigned int display:1; - - unsigned int ipl_floppy:1; - unsigned int ipl_controller:1; - unsigned int ipl_cdrom:1; - unsigned int ipl_disk:1; - unsigned int ipl_net:1; - unsigned int ipl_other:1; - unsigned int /* reserved */:1; - unsigned int firmware_selftest:1; - - char devname[12]; - unsigned int post_code:4; - unsigned int firmware_rev:2; - unsigned int loc_code:8; /* currently unused */ -}; - -struct epowhdr { - unsigned int epow_sensor_value:32; - unsigned int sensor:1; - unsigned int power_fault:1; - unsigned int fan:1; - unsigned int temp:1; - unsigned int redundancy:1; - unsigned int CUoD:1; - unsigned int /* reserved */:2; - - unsigned int general:1; - unsigned int power_loss:1; - unsigned int power_supply:1; - unsigned int power_switch:1; - unsigned int /* reserved */:4; - - unsigned int /* reserved */:16; - unsigned int sensor_token:32; - unsigned int sensor_index:32; - unsigned int sensor_value:32; - unsigned int sensor_status:32; -}; - -struct pm_eventhdr { - unsigned int event_id:32; -}; - -struct sphdr { - unsigned int ibm:32; /* "IBM\0" */ - - unsigned int timeout:1; - unsigned int i2c_bus:1; - unsigned int i2c_secondary_bus:1; - unsigned int sp_memory:1; - unsigned int sp_registers:1; - unsigned int sp_communication:1; - unsigned int sp_firmware:1; - unsigned int sp_hardware:1; - - unsigned int vpd_eeprom:1; - unsigned int op_panel:1; - unsigned int power_controller:1; - unsigned int fan_sensor:1; - unsigned int thermal_sensor:1; - unsigned int voltage_sensor:1; - unsigned int reserved1:2; - - unsigned int serial_port:1; - unsigned int nvram:1; - unsigned int rtc:1; - unsigned int jtag:1; - unsigned int tod_battery:1; - unsigned int reserved2:1; - unsigned int heartbeat:1; - unsigned int surveillance:1; - - unsigned int pcn_connection:1; /* power control network */ - unsigned int pcn_node:1; - unsigned int reserved3:2; - unsigned int pcn_access:1; - unsigned int reserved:3; - - unsigned int sensor_token:32; /* zero if undef */ - unsigned int sensor_index:32; /* zero if undef */ -}; - - -static char *severity_names[] = { - "NO ERROR", "EVENT", "WARNING", "ERROR_SYNC", "ERROR", "FATAL", "(6)", "(7)" -}; -static char *rtas_disposition_names[] = { - "FULLY RECOVERED", "LIMITED RECOVERY", "NOT RECOVERED", "(4)" -}; -static char *entity_names[] = { /* for initiator & targets */ - "UNKNOWN", "CPU", "PCI", "ISA", "MEMORY", "POWER MANAGEMENT", "HOT PLUG", "(7)", "(8)", - "(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)" -}; -static char *error_type[] = { /* Not all types covered here so need to bounds check */ - "UNKNOWN", "RETRY", "TCE_ERR", "INTERN_DEV_FAIL", - "TIMEOUT", "DATA_PARITY", "ADDR_PARITY", "CACHE_PARITY", - "ADDR_INVALID", "ECC_UNCORR", "ECC_CORR", -}; - -static char *rtas_error_type(int type) -{ - if (type < 11) - return error_type[type]; - if (type == 64) - return "SENSOR"; - if (type >=96 && type <= 159) - return "POWER"; - return error_type[0]; -} - -static void printk_cpu_failure(int version, struct exthdr *exthdr, char *data) -{ - struct cpuhdr cpuhdr; - - memcpy(&cpuhdr, data, sizeof(cpuhdr)); - - if (cpuhdr.internal) printk(RTAS_ERR "Internal error (not cache)\n"); - if (cpuhdr.intcache) printk(RTAS_ERR "Internal cache\n"); - if (cpuhdr.extcache_parity) printk(RTAS_ERR "External cache parity (or multi-bit)\n"); - if (cpuhdr.extcache_ecc) printk(RTAS_ERR "External cache ECC\n"); - if (cpuhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n"); - if (cpuhdr.io_timeout) printk(RTAS_ERR "I/O timeout\n"); - if (cpuhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n"); - if (cpuhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n"); - printk(RTAS_ERR "CPU id: %d\n", cpuhdr.cpuid); - printk(RTAS_ERR "Failing element: 0x%04x\n", cpuhdr.element); - if (!exthdr->addr_invalid) - printk(RTAS_ERR "Failing address: %08x%08x\n", cpuhdr.failing_address_hi, cpuhdr.failing_address_lo); - if (version >= 4 && cpuhdr.try_reboot) - printk(RTAS_ERR "A reboot of the system may correct the problem\n"); -} - -static void printk_mem_failure(int version, struct exthdr *exthdr, char *data) -{ - struct memhdr memhdr; - - memcpy(&memhdr, data, sizeof(memhdr)); - if (memhdr.uncorrectable) printk(RTAS_ERR "Uncorrectable Memory error\n"); - if (memhdr.ECC) printk(RTAS_ERR "ECC Correctable error\n"); - if (memhdr.threshold_exceeded) printk(RTAS_ERR "Correctable threshold exceeded\n"); - if (memhdr.control_internal) printk(RTAS_ERR "Memory Controller internal error\n"); - if (memhdr.bad_address) printk(RTAS_ERR "Memory Address error\n"); - if (memhdr.bad_data) printk(RTAS_ERR "Memory Data error\n"); - if (memhdr.bus) printk(RTAS_ERR "Memory bus/switch internal error\n"); - if (memhdr.timeout) printk(RTAS_ERR "Memory timeout\n"); - if (memhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n"); - if (memhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n"); - if (memhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n"); - if (memhdr.hostbridge_timeout) printk(RTAS_ERR "I/O Host Bridge timeout\n"); - if (memhdr.hostbridge_parity) printk(RTAS_ERR "I/O Host Bridge parity\n"); - if (memhdr.support) printk(RTAS_ERR "System support function error\n"); - if (memhdr.sysbus_internal) printk(RTAS_ERR "System bus internal hardware/switch error\n"); - printk(RTAS_ERR "Memory Controller that detected failure: %d\n", memhdr.mem_controller_detected); - printk(RTAS_ERR "Memory Controller that faulted: %d\n", memhdr.mem_controller_faulted); - if (!exthdr->addr_invalid) - printk(RTAS_ERR "Failing address: 0x%016x%016x\n", memhdr.failing_address_hi, memhdr.failing_address_lo); - printk(RTAS_ERR "ECC syndrome bits: 0x%04x\n", memhdr.ecc_syndrome); - printk(RTAS_ERR "Memory Card: %d\n", memhdr.memory_card); - printk(RTAS_ERR "Failing element: 0x%04x\n", memhdr.element); - printk(RTAS_ERR "Sub element bits: 0x%08x\n", memhdr.sub_elements); -} - -static void printk_io_failure(int version, struct exthdr *exthdr, char *data) -{ - struct iohdr iohdr; - - memcpy(&iohdr, data, sizeof(iohdr)); - if (iohdr.bus_addr_parity) printk(RTAS_ERR "I/O bus address parity\n"); - if (iohdr.bus_data_parity) printk(RTAS_ERR "I/O bus data parity\n"); - if (iohdr.bus_timeout) printk(RTAS_ERR "I/O bus timeout, access or other\n"); - if (iohdr.bridge_internal) printk(RTAS_ERR "I/O bus bridge/device internal\n"); - if (iohdr.non_pci) printk(RTAS_ERR "Signaling IOA is a PCI to non-PCI bridge (e.g. ISA)\n"); - if (iohdr.mezzanine_addr_parity) printk(RTAS_ERR "Mezzanine/System bus address parity\n"); - if (iohdr.mezzanine_data_parity) printk(RTAS_ERR "Mezzanine/System bus data parity\n"); - if (iohdr.mezzanine_timeout) printk(RTAS_ERR "Mezzanine/System bus timeout, transfer or protocol\n"); - if (iohdr.bridge_via_sysbus) printk(RTAS_ERR "Bridge is connected to system bus\n"); - if (iohdr.bridge_via_mezzanine) printk(RTAS_ERR "Bridge is connected to memory controller via mezzanine bus\n"); - if (iohdr.bridge_via_expbus) printk(RTAS_ERR "Bridge is connected to I/O expansion bus\n"); - if (iohdr.detected_by_expbus) printk(RTAS_ERR "Error on system bus detected by I/O expansion bus controller\n"); - if (iohdr.expbus_data_parity) printk(RTAS_ERR "I/O expansion bus data error\n"); - if (iohdr.expbus_timeout) printk(RTAS_ERR "I/O expansion bus timeout, access or other\n"); - if (iohdr.expbus_connection_failure) printk(RTAS_ERR "I/O expansion bus connection failure\n"); - if (iohdr.expbus_not_operating) printk(RTAS_ERR "I/O expansion unit not in an operating state (powered off, off-line)\n"); - - printk(RTAS_ERR "IOA Signaling the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n", - iohdr.pci_sig_busno, iohdr.pci_sig_devfn >> 3, iohdr.pci_sig_devfn & 0x7, - iohdr.pci_sig_vendorid, iohdr.pci_sig_deviceid, iohdr.pci_sig_revisionid, iohdr.pci_sig_slot); - printk(RTAS_ERR "IOA Sending during the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n", - iohdr.pci_send_busno, iohdr.pci_send_devfn >> 3, iohdr.pci_send_devfn & 0x7, - iohdr.pci_send_vendorid, iohdr.pci_send_deviceid, iohdr.pci_send_revisionid, iohdr.pci_send_slot); - -} - -static void printk_post_failure(int version, struct exthdr *exthdr, char *data) -{ - struct posthdr posthdr; - - memcpy(&posthdr, data, sizeof(posthdr)); - - if (posthdr.devname[0]) printk(RTAS_ERR "Failing Device: %s\n", posthdr.devname); - if (posthdr.firmware) printk(RTAS_ERR "Firmware Error\n"); - if (posthdr.config) printk(RTAS_ERR "Configuration Error\n"); - if (posthdr.cpu) printk(RTAS_ERR "CPU POST Error\n"); - if (posthdr.memory) printk(RTAS_ERR "Memory POST Error\n"); - if (posthdr.io) printk(RTAS_ERR "I/O Subsystem POST Error\n"); - if (posthdr.keyboard) printk(RTAS_ERR "Keyboard POST Error\n"); - if (posthdr.mouse) printk(RTAS_ERR "Mouse POST Error\n"); - if (posthdr.display) printk(RTAS_ERR "Display POST Error\n"); - - if (posthdr.ipl_floppy) printk(RTAS_ERR "Floppy IPL Error\n"); - if (posthdr.ipl_controller) printk(RTAS_ERR "Drive Controller Error during IPL\n"); - if (posthdr.ipl_cdrom) printk(RTAS_ERR "CDROM IPL Error\n"); - if (posthdr.ipl_disk) printk(RTAS_ERR "Disk IPL Error\n"); - if (posthdr.ipl_net) printk(RTAS_ERR "Network IPL Error\n"); - if (posthdr.ipl_other) printk(RTAS_ERR "Other (tape,flash) IPL Error\n"); - if (posthdr.firmware_selftest) printk(RTAS_ERR "Self-test error in firmware extended diagnostics\n"); - printk(RTAS_ERR "POST Code: %d\n", posthdr.post_code); - printk(RTAS_ERR "Firmware Revision Code: %d\n", posthdr.firmware_rev); -} - -static void printk_epow_warning(int version, struct exthdr *exthdr, char *data) -{ - struct epowhdr epowhdr; - - memcpy(&epowhdr, data, sizeof(epowhdr)); - printk(RTAS_ERR "EPOW Sensor Value: 0x%08x\n", epowhdr.epow_sensor_value); - if (epowhdr.sensor) { - printk(RTAS_ERR "EPOW detected by a sensor\n"); - printk(RTAS_ERR "Sensor Token: 0x%08x\n", epowhdr.sensor_token); - printk(RTAS_ERR "Sensor Index: 0x%08x\n", epowhdr.sensor_index); - printk(RTAS_ERR "Sensor Value: 0x%08x\n", epowhdr.sensor_value); - printk(RTAS_ERR "Sensor Status: 0x%08x\n", epowhdr.sensor_status); - } - if (epowhdr.power_fault) printk(RTAS_ERR "EPOW caused by a power fault\n"); - if (epowhdr.fan) printk(RTAS_ERR "EPOW caused by fan failure\n"); - if (epowhdr.temp) printk(RTAS_ERR "EPOW caused by over-temperature condition\n"); - if (epowhdr.redundancy) printk(RTAS_ERR "EPOW warning due to loss of redundancy\n"); - if (epowhdr.CUoD) printk(RTAS_ERR "EPOW warning due to CUoD Entitlement Exceeded\n"); - - if (epowhdr.general) printk(RTAS_ERR "EPOW general power fault\n"); - if (epowhdr.power_loss) printk(RTAS_ERR "EPOW power fault due to loss of power source\n"); - if (epowhdr.power_supply) printk(RTAS_ERR "EPOW power fault due to internal power supply failure\n"); - if (epowhdr.power_switch) printk(RTAS_ERR "EPOW power fault due to activation of power switch\n"); -} - -static void printk_pm_event(int version, struct exthdr *exthdr, char *data) -{ - struct pm_eventhdr pm_eventhdr; - - memcpy(&pm_eventhdr, data, sizeof(pm_eventhdr)); - printk(RTAS_ERR "Event id: 0x%08x\n", pm_eventhdr.event_id); -} - -static void printk_sp_log_msg(int version, struct exthdr *exthdr, char *data) -{ - struct sphdr sphdr; - u32 eyecatcher; - - memcpy(&sphdr, data, sizeof(sphdr)); - - eyecatcher = sphdr.ibm; - if (strcmp((char *)&eyecatcher, "IBM") != 0) - printk(RTAS_ERR "This log entry may be corrupt (IBM signature malformed)\n"); - if (sphdr.timeout) printk(RTAS_ERR "Timeout on communication response from service processor\n"); - if (sphdr.i2c_bus) printk(RTAS_ERR "I2C general bus error\n"); - if (sphdr.i2c_secondary_bus) printk(RTAS_ERR "I2C secondary bus error\n"); - if (sphdr.sp_memory) printk(RTAS_ERR "Internal service processor memory error\n"); - if (sphdr.sp_registers) printk(RTAS_ERR "Service processor error accessing special registers\n"); - if (sphdr.sp_communication) printk(RTAS_ERR "Service processor reports unknown communcation error\n"); - if (sphdr.sp_firmware) printk(RTAS_ERR "Internal service processor firmware error\n"); - if (sphdr.sp_hardware) printk(RTAS_ERR "Other internal service processor hardware error\n"); - if (sphdr.vpd_eeprom) printk(RTAS_ERR "Service processor error accessing VPD EEPROM\n"); - if (sphdr.op_panel) printk(RTAS_ERR "Service processor error accessing Operator Panel\n"); - if (sphdr.power_controller) printk(RTAS_ERR "Service processor error accessing Power Controller\n"); - if (sphdr.fan_sensor) printk(RTAS_ERR "Service processor error accessing Fan Sensor\n"); - if (sphdr.thermal_sensor) printk(RTAS_ERR "Service processor error accessing Thermal Sensor\n"); - if (sphdr.voltage_sensor) printk(RTAS_ERR "Service processor error accessing Voltage Sensor\n"); - if (sphdr.serial_port) printk(RTAS_ERR "Service processor error accessing serial port\n"); - if (sphdr.nvram) printk(RTAS_ERR "Service processor detected NVRAM error\n"); - if (sphdr.rtc) printk(RTAS_ERR "Service processor error accessing real time clock\n"); - if (sphdr.jtag) printk(RTAS_ERR "Service processor error accessing JTAG/COP\n"); - if (sphdr.tod_battery) printk(RTAS_ERR "Service processor or RTAS detects loss of voltage from TOD battery\n"); - if (sphdr.heartbeat) printk(RTAS_ERR "Loss of heartbeat from Service processor\n"); - if (sphdr.surveillance) printk(RTAS_ERR "Service processor detected a surveillance timeout\n"); - if (sphdr.pcn_connection) printk(RTAS_ERR "Power Control Network general connection failure\n"); - if (sphdr.pcn_node) printk(RTAS_ERR "Power Control Network node failure\n"); - if (sphdr.pcn_access) printk(RTAS_ERR "Service processor error accessing Power Control Network\n"); - - if (sphdr.sensor_token) printk(RTAS_ERR "Sensor Token 0x%08x (%d)\n", sphdr.sensor_token, sphdr.sensor_token); - if (sphdr.sensor_index) printk(RTAS_ERR "Sensor Index 0x%08x (%d)\n", sphdr.sensor_index, sphdr.sensor_index); -} - - -static void printk_ext_raw_data(char *data) -{ - int i; - printk(RTAS_ERR "raw ext data: "); - for (i = 0; i < 40; i++) { - printk("%02x", data[i]); - } - printk("\n"); -} - -static void printk_ext_log_data(int version, char *buf) -{ - char *data = buf+12; - struct exthdr exthdr; - memcpy(&exthdr, buf, sizeof(exthdr)); /* copy for alignment */ - if (!exthdr.valid) { - if (exthdr.bigendian && exthdr.power_pc) - printk(RTAS_ERR "extended log data is not valid\n"); - else - printk(RTAS_ERR "extended log data can not be decoded\n"); - return; - } - - /* Dump useful stuff in the exthdr */ - printk(RTAS_ERR "Status:%s%s%s%s%s\n", - exthdr.unrecoverable ? " unrecoverable" : "", - exthdr.recoverable ? " recoverable" : "", - exthdr.unrecoverable_bypassed ? " bypassed" : "", - exthdr.predictive ? " predictive" : "", - exthdr.newlog ? " new" : ""); - printk(RTAS_ERR "Date/Time: %08x %08x\n", exthdr.bcddate, exthdr.bcdtime); - switch (exthdr.format_type) { - case EXTLOG_FMT_CPU: - printk(RTAS_ERR "CPU Failure\n"); - printk_cpu_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_MEMORY: - printk(RTAS_ERR "Memory Failure\n"); - printk_mem_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_IO: - printk(RTAS_ERR "I/O Failure\n"); - printk_io_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_POST: - printk(RTAS_ERR "POST Failure\n"); - printk_post_failure(version, &exthdr, data); - break; - case EXTLOG_FMT_ENV: - printk(RTAS_ERR "Environment and Power Warning\n"); - printk_epow_warning(version, &exthdr, data); - break; - case EXTLOG_FMT_POW: - printk(RTAS_ERR "Power Management Event\n"); - printk_pm_event(version, &exthdr, data); - break; - case EXTLOG_FMT_IBMDIAG: - printk(RTAS_ERR "IBM Diagnostic Log\n"); - printk_ext_raw_data(data); - break; - case EXTLOG_FMT_IBMSP: - printk(RTAS_ERR "IBM Service Processor Log\n"); - printk_sp_log_msg(version, &exthdr, data); - break; - default: - printk(RTAS_ERR "Unknown ext format type %d\n", exthdr.format_type); - printk_ext_raw_data(data); - break; - } -} - -#define MAX_LOG_DEBUG 10 -#define MAX_LOG_DEBUG_LEN 900 -/* Print log debug data. This appears after the location code. - * We limit the number of debug logs in case the data is somehow corrupt. - */ -static void printk_log_debug(char *buf) -{ - unsigned char *p = (unsigned char *)_ALIGN((unsigned long)buf, 4); - int len, n, logged; - - logged = 0; - while ((logged < MAX_LOG_DEBUG) && (len = ((p[0] << 8) | p[1])) >= 4) { - if (len > MAX_LOG_DEBUG_LEN) - len = MAX_LOG_DEBUG_LEN; /* bound it */ - printk("RTAS: Log Debug: %c%c ", p[2], p[3]); - for (n=4; n < len; n++) - printk("%02x", p[n]); - printk("\n"); - p = (unsigned char *)_ALIGN((unsigned long)p+len, 4); - logged++; - if (len == MAX_LOG_DEBUG_LEN) - return; /* no point continuing */ - } - if (logged == 0) - printk("RTAS: no log debug data present\n"); -} - - -/* Yeah, the output here is ugly, but we want a CE to be - * able to grep RTAS /var/log/messages and see all the info - * collected together with obvious begin/end. - */ -static void printk_log_rtas(char *buf) -{ - struct rtas_error_log *err = (struct rtas_error_log *)buf; - - printk(RTAS_ERR "-------- event-scan begin --------\n"); - if (strcmp(buf+8+40, "IBM") == 0) { - /* Location code follows */ - char *loc = buf+8+40+4; - int len = strlen(loc); - if (len < 64) { /* Sanity check */ - printk(RTAS_ERR "Location Code: %s\n", loc); - printk_log_debug(loc+len+1); - } - } - - printk(RTAS_ERR "%s: (%s) type: %s\n", - severity_names[err->severity], - rtas_disposition_names[err->disposition], - rtas_error_type(err->type)); - printk(RTAS_ERR "initiator: %s target: %s\n", - entity_names[err->initiator], entity_names[err->target]); - if (err->extended_log_length) - printk_ext_log_data(err->version, buf+8); - printk(RTAS_ERR "-------- event-scan end ----------\n"); -} - - -static void log_rtas(char *buf) -{ - unsigned long offset; - - DEBUG("logging rtas event\n"); - - /* Temporary -- perhaps we can do this when nobody has the log open? */ - printk_log_rtas(buf); - - spin_lock(&rtas_log_lock); - - offset = rtas_error_log_max * - ((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK); - - memcpy(&rtas_log_buf[offset], buf, rtas_error_log_max); - - if (rtas_log_size < LOG_NUMBER) - rtas_log_size += 1; - else - rtas_log_start += 1; - - spin_unlock(&rtas_log_lock); - wake_up_interruptible(&rtas_log_wait); -} - -static int enable_surveillance(void) +static int enable_surveillance(int timeout) { int error; error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL, SURVEILLANCE_TOKEN, - 0, SURVEILLANCE_TIMEOUT); + 0, timeout); if (error) { printk(KERN_ERR "rtasd: could not enable surveillance\n"); return -1; } - rtas_event_scan_rate = SURVEILLANCE_SCANRATE; - return 0; } @@ -754,6 +326,9 @@ rtas_error_log_max = RTAS_ERROR_LOG_MAX; } + /* Make room for the sequence number */ + rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int); + return 0; } @@ -761,20 +336,25 @@ static int rtasd(void *unused) { + unsigned int err_type; + unsigned long s; int cpu = 0; int error; int first_pass = 1; int event_scan = rtas_token("event-scan"); + int rc; if (event_scan == RTAS_UNKNOWN_SERVICE || get_eventscan_parms() == -1) goto error; - rtas_log_buf = vmalloc(rtas_error_log_max*LOG_NUMBER); + rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER); if (!rtas_log_buf) { printk(KERN_ERR "rtasd: no memory\n"); goto error; } + no_more_logging = 0; + DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); daemonize(); @@ -789,11 +369,23 @@ current->cpus_allowed = 1UL << cpu_logical_map(cpu); schedule(); + /* See if we have any error stored in NVRAM */ + memset(logdata, 0, rtas_error_log_max); + + rc = read_error_log_nvram(logdata, rtas_error_log_max, &err_type); + if (!rc) { + if (err_type != ERR_FLAG_ALREADY_LOGGED) { + pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0); + } + } + while(1) { + + do { memset(logdata, 0, rtas_error_log_max); error = rtas_call(event_scan, 4, 1, NULL, - EVENT_SCAN_ALL_EVENTS, 0, + RTAS_EVENT_SCAN_ALL_EVENTS, 0, __pa(logdata), rtas_error_log_max); if (error == -1) { printk(KERN_ERR "event-scan failed\n"); @@ -801,7 +393,7 @@ } if (error == 0) - log_rtas(logdata); + pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); } while(error == 0); @@ -810,9 +402,9 @@ cpu++; if (cpu >= smp_num_cpus) { - if (first_pass && surveillance_requested) { + if (first_pass && (surveillance_timeout != -1)) { DEBUG("enabling surveillance\n"); - if (enable_surveillance()) + if (enable_surveillance(surveillance_timeout)) goto error_vfree; DEBUG("surveillance enabled\n"); } @@ -824,8 +416,8 @@ current->cpus_allowed = 1UL << cpu_logical_map(cpu); /* Check all cpus for pending events before sleeping*/ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2); } error_vfree: @@ -846,10 +438,10 @@ if (!proc_ppc64_root) { spin_unlock(&proc_ppc64_lock); return -EINVAL; - } + } } spin_unlock(&proc_ppc64_lock); - + if (rtas_proc_dir == NULL) { rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root); } @@ -867,7 +459,7 @@ } } - if (kernel_thread(rtasd, 0, CLONE_FS) < 0) { + if (kernel_thread(rtasd, 0, CLONE_FS) < 0) { printk(KERN_ERR "Failed to start RTAS daemon\n"); ret = -EINVAL; } @@ -881,8 +473,8 @@ int i; if (get_option(&str,&i)) { - if (i == 1) - surveillance_requested = 1; + if (i >= 0 && i <= 255) + surveillance_timeout = i; } return 1; diff -urN linux-2.4.24/arch/ppc64/kernel/rtc.c linux-2.4.25/arch/ppc64/kernel/rtc.c --- linux-2.4.24/arch/ppc64/kernel/rtc.c 2004-01-05 05:53:56.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/rtc.c 2004-02-18 05:36:30.000000000 -0800 @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -273,20 +274,63 @@ } +#define MAX_RTC_WAIT 5000 /* 5 sec */ +#define RTAS_CLOCK_BUSY (-2) +void pSeries_get_boot_time(struct rtc_time *rtc_tm) +{ + unsigned long ret[8]; + int error, wait_time; + unsigned long max_wait_tb; + + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; + do { + error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + wait_time = rtas_extended_busy_delay_time(error); + /* This is boot time so we spin. */ + udelay(wait_time*1000); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); + + if (error != 0) { + printk(KERN_WARNING "error: reading the clock failed (%d)\n", + error); + return; + } + + rtc_tm->tm_sec = ret[5]; + rtc_tm->tm_min = ret[4]; + rtc_tm->tm_hour = ret[3]; + rtc_tm->tm_mday = ret[2]; + rtc_tm->tm_mon = ret[1] - 1; + rtc_tm->tm_year = ret[0] - 1900; +} + +/* NOTE: get_rtc_time will get an error if executed in interrupt context + * and if a delay is needed to read the clock. In this case we just + * silently return without updating rtc_tm. + */ void pSeries_get_rtc_time(struct rtc_time *rtc_tm) { unsigned long ret[8]; - int error; - int count; + int error, wait_time; + unsigned long max_wait_tb; - /* - * error -2 is clock busy, we keep retrying a few times to see - * if it will come good -- paulus - */ - count = 0; + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret); - } while (error == -2 && ++count < 1000); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + if (in_interrupt()) { + printk(KERN_WARNING "error: reading clock would delay interrupt\n"); + return; /* delay not allowed */ + } + wait_time = rtas_extended_busy_delay_time(error); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(wait_time); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", @@ -304,20 +348,24 @@ int pSeries_set_rtc_time(struct rtc_time *tm) { - int error; - int count; + int error, wait_time; + unsigned long max_wait_tb; - /* - * error -2 is clock busy, we keep retrying a few times to see - * if it will come good -- paulus - */ - count = 0; + max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, 0); - } while (error == -2 && ++count < 1000); + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + if (in_interrupt()) + return 1; /* probably decrementer */ + wait_time = rtas_extended_busy_delay_time(error); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(wait_time); + error = RTAS_CLOCK_BUSY; + } + } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) printk(KERN_WARNING "error: setting the clock failed (%d)\n", diff -urN linux-2.4.24/arch/ppc64/kernel/scanlog.c linux-2.4.25/arch/ppc64/kernel/scanlog.c --- linux-2.4.24/arch/ppc64/kernel/scanlog.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/scanlog.c 2004-02-18 05:36:30.000000000 -0800 @@ -129,17 +129,25 @@ static ssize_t scanlog_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { + char stkbuf[20]; unsigned long status; + if (count > 19) + count = 19; + if (copy_from_user (stkbuf, buf, count)) + return -EFAULT; + + stkbuf[count] = 0; + if (buf) { - if (strncmp(buf, "reset", 5) == 0) { + if (strncmp(stkbuf, "reset", 5) == 0) { DEBUG("reset scanlog\n"); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, NULL, 0); DEBUG("rtas returns %ld\n", status); - } else if (strncmp(buf, "debugon", 7) == 0) { + } else if (strncmp(stkbuf, "debugon", 7) == 0) { printk(KERN_ERR "scanlog: debug on\n"); scanlog_debug = 1; - } else if (strncmp(buf, "debugoff", 8) == 0) { + } else if (strncmp(stkbuf, "debugoff", 8) == 0) { printk(KERN_ERR "scanlog: debug off\n"); scanlog_debug = 0; } diff -urN linux-2.4.24/arch/ppc64/kernel/setup.c linux-2.4.25/arch/ppc64/kernel/setup.c --- linux-2.4.24/arch/ppc64/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/setup.c 2004-02-18 05:36:30.000000000 -0800 @@ -62,6 +62,7 @@ extern void pSeries_init_early( void ); extern void pSeriesLP_init_early(void); extern void mm_init_ppc64( void ); +extern void pseries_secondary_smp_init(unsigned long); unsigned long decr_overclock = 1; unsigned long decr_overclock_proc0 = 1; @@ -107,6 +108,8 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + unsigned int ret, i; + /* This should be fixed properly in kernel/resource.c */ iomem_resource.end = MEM_SPACE_LIMIT; @@ -143,12 +146,27 @@ udbg_printf("---- start early boot console ----\n"); } - printk("Starting Linux PPC64 %s\n", UTS_RELEASE); + if (systemcfg->platform & PLATFORM_PSERIES) { + finish_device_tree(); + chrp_init(r3, r4, r5, r6, r7); + + /* Start secondary threads on SMT systems */ + for (i = 0; i < NR_CPUS; i++) { + if(cpu_available(i) && !cpu_possible(i)) { + printk("%16.16lx : starting thread\n", i); + rtas_call(rtas_token("start-cpu"), 3, 1, + (void *)&ret, + i, *((unsigned long *)pseries_secondary_smp_init), i); + paca[i].active = 1; + systemcfg->processorCount++; + } + } + } printk("-----------------------------------------------------\n"); printk("naca = 0x%p\n", naca); printk("naca->pftSize = 0x%lx\n", naca->pftSize); - printk("naca->paca = 0x%lx\n\n", naca->paca); + printk("naca->paca = 0x%p\n\n", naca->paca); printk("systemcfg = 0x%p\n", systemcfg); printk("systemcfg->platform = 0x%x\n", systemcfg->platform); printk("systemcfg->processor = 0x%x\n", systemcfg->processor); @@ -160,13 +178,16 @@ printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs); printk("-----------------------------------------------------\n"); - if (systemcfg->platform & PLATFORM_PSERIES) { - finish_device_tree(); - chrp_init(r3, r4, r5, r6, r7); - } + printk("Starting Linux PPC64 %s\n", UTS_RELEASE); mm_init_ppc64(); + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + vpa_init(0); + } + + idle_setup(); + switch (systemcfg->platform) { case PLATFORM_ISERIES_LPAR: iSeries_init(); @@ -246,37 +267,7 @@ seq_printf(m, "\n"); -#if 0 - switch (PVR_VER(pvr)) { - case PV_NORTHSTAR: - seq_printf(m, "RS64-II (northstar)\n"); - break; - case PV_PULSAR: - seq_printf(m, "RS64-III (pulsar)\n"); - break; - case PV_POWER4: - seq_printf(m, "POWER4 (gp)\n"); - break; - case PV_ICESTAR: - seq_printf(m, "RS64-III (icestar)\n"); - break; - case PV_SSTAR: - seq_printf(m, "RS64-IV (sstar)\n"); - break; - case PV_630: - seq_printf(m, "POWER3 (630)\n"); - break; - case PV_630p: - seq_printf(m, "POWER3 (630+)\n"); - break; - case PV_POWER4p: - seq_printf(m, "POWER4+ (gq)\n"); - break; - default: - seq_printf(m, "Unknown (%08x)\n", pvr); - break; - } -#endif + /* * Assume here that all clock rates are the same in a * smp system. -- Cort @@ -328,7 +319,6 @@ void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - struct device_node *chosen; char *p; #ifdef CONFIG_BLK_DEV_INITRD @@ -401,7 +391,7 @@ } } - +#if 0 char *bi_tag2str(unsigned long tag) { switch (tag) { @@ -423,6 +413,7 @@ return "BI_UNKNOWN"; } } +#endif int parse_bootinfo(void) { @@ -607,20 +598,35 @@ udbg_puts(" "); udbg_puthex(srr1); udbg_puts("\n"); } -int set_spread_lpevents( char * str ) +void do_spread_lpevents(unsigned long n) { - /* The parameter is the number of processors to share in processing lp events */ - unsigned long i; - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) { - for ( i=1; i 0) && (val <= MAX_PACAS)) { + do_spread_lpevents(val); + } else printk("invalid spreaqd_lpevents %ld\n", val); + return 1; -} +} /* This should only be called on processor 0 during calibrate decr */ void setup_default_decr(void) diff -urN linux-2.4.24/arch/ppc64/kernel/signal.c linux-2.4.25/arch/ppc64/kernel/signal.c --- linux-2.4.24/arch/ppc64/kernel/signal.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/signal.c 2004-02-18 05:36:30.000000000 -0800 @@ -296,7 +296,9 @@ newsp = (current->sas_ss_sp + current->sas_ss_size); } - return (void *)((newsp - frame_size) & -8ul); + /* The ABI requires quadword alignment for the stack. */ + return (void *)((newsp - frame_size) & -16ul); + } static int diff -urN linux-2.4.24/arch/ppc64/kernel/signal32.c linux-2.4.25/arch/ppc64/kernel/signal32.c --- linux-2.4.24/arch/ppc64/kernel/signal32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/signal32.c 2004-02-18 05:36:30.000000000 -0800 @@ -761,7 +761,7 @@ memset (d, 0, sizeof(siginfo_t32)); d->si_signo = s->si_signo; d->si_errno = s->si_errno; - d->si_code = s->si_code & 0xffff; + d->si_code = (short)s->si_code; if (s->si_signo >= SIGRTMIN) { d->si_pid = s->si_pid; d->si_uid = s->si_uid; @@ -1067,7 +1067,8 @@ if (ka->sa.sa_flags & SA_SIGINFO) { siginfo64to32(&siginfo32bit,info); - *newspp -= sizeof(*rt_stack_frame); + /* The ABI requires quadword alignment for the stack. */ + *newspp = (*newspp - sizeof(*rt_stack_frame)) & -16ul; rt_stack_frame = (struct rt_sigframe_32 *) (u64)(*newspp) ; if (verify_area(VERIFY_WRITE, rt_stack_frame, sizeof(*rt_stack_frame))) @@ -1095,7 +1096,7 @@ } } else { /* Put a sigcontext on the stack */ - *newspp -= sizeof(*sc); + *newspp = (*newspp - sizeof(*sc)) & -16ul; sc = (struct sigcontext32 *)(u64)*newspp; if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) goto badframe; @@ -1310,7 +1311,8 @@ newsp = (current->sas_ss_sp + current->sas_ss_size); else newsp = regs->gpr[1]; - newsp = frame = newsp - sizeof(struct sigregs32); + /* The ABI requires quadword alignment for the stack. */ + newsp = frame = (newsp - sizeof(struct sigregs32)) & -16ul; /* Whee! Actually deliver the signal. */ handle_signal32(signr, ka, &info, oldset, regs, &newsp, frame); diff -urN linux-2.4.24/arch/ppc64/kernel/smp.c linux-2.4.25/arch/ppc64/kernel/smp.c --- linux-2.4.24/arch/ppc64/kernel/smp.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/smp.c 2004-02-18 05:36:30.000000000 -0800 @@ -28,7 +28,7 @@ #define __KERNEL_SYSCALLS__ #include #include -/* #include */ +#include #include #include @@ -52,9 +52,10 @@ #include #include "open_pic.h" #include +#include #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) int (*dump_ipi_function_ptr)(struct pt_regs *); -#include +#include #endif #ifdef CONFIG_KDB @@ -90,6 +91,9 @@ void xics_setup_cpu(void); void xics_cause_IPI(int cpu); +long h_register_vpa(unsigned long flags, unsigned long proc, + unsigned long vpa); + /* * XICS only has a single IPI, so encode the messages per CPU */ @@ -434,8 +438,17 @@ void smp_send_reschedule(int cpu) { + if ((systemcfg->platform & PLATFORM_LPAR) && + (paca[cpu].yielded == 1)) { +#ifdef CONFIG_PPC_ISERIES + HvCall_sendLpProd(cpu); +#else + prod_processor(cpu); +#endif + } else { smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); } +} #ifdef CONFIG_XMON void smp_send_xmon_break(int cpu) @@ -564,6 +577,7 @@ ret = 0; out: + call_data = NULL; HMT_medium(); spin_unlock_bh(&call_lock); return ret; @@ -571,9 +585,20 @@ void smp_call_function_interrupt(void) { - void (*func) (void *info) = call_data->func; - void *info = call_data->info; - int wait = call_data->wait; + void (*func) (void *info); + void *info; + int wait; + + + /* call_data will be NULL if the sender timed out while + * waiting on us to receive the call. + */ + if (!call_data) + return; + + func = call_data->func; + info = call_data->info; + wait = call_data->wait; /* * Notify initiating CPU that I've grabbed the data and am @@ -773,6 +798,12 @@ current->active_mm = &init_mm; smp_callin(); + get_paca()->yielded = 0; + + if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + vpa_init(cpu); + } + /* Go into the idle loop. */ return cpu_idle(NULL); } diff -urN linux-2.4.24/arch/ppc64/kernel/stab.c linux-2.4.25/arch/ppc64/kernel/stab.c --- linux-2.4.24/arch/ppc64/kernel/stab.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/stab.c 2004-02-18 05:36:30.000000000 -0800 @@ -159,7 +159,6 @@ inline void make_slbe(unsigned long esid, unsigned long vsid, int large) { unsigned long entry, castout_entry; - slb_dword0 castout_esid_data; union { unsigned long word0; slb_dword0 data; @@ -217,23 +216,37 @@ PMC_SW_PROCESSOR(stab_capacity_castouts); + /* + * Never cast out the segment for our own stack. Since we + * dont invalidate the ERAT we could have a valid translation + * for our stack during the first part of exception exit + * which gets invalidated due to a tlbie from another cpu at a + * non recoverable point (after setting srr0/1) - Anton + */ + castout_entry = get_paca()->xStab_data.next_round_robin; - __asm__ __volatile__("slbmfee %0,%1" - : "=r" (castout_esid_data) - : "r" (castout_entry)); - - entry = castout_entry; - castout_entry++; - if(castout_entry >= naca->slb_size) { - castout_entry = 1; - } + do { + entry = castout_entry; + castout_entry++; + if (castout_entry >= naca->slb_size) + castout_entry = 1; + asm volatile("slbmfee %0,%1" : "=r" (esid_data) : "r" (entry)); + } while (esid_data.data.esid == GET_ESID((unsigned long)_get_SP())); + get_paca()->xStab_data.next_round_robin = castout_entry; - /* Invalidate the old entry. */ - castout_esid_data.v = 0; /* Set the class to 0 */ - /* slbie not needed as the previous mapping is still valid. */ - __asm__ __volatile__("slbie %0" : : "r" (castout_esid_data)); - + /* We're executing this code on the interrupt stack, so the + * above code might pick the kernel stack segment as the victim. + * + * Because of this, we need to invalidate the old entry. We need + * to do this since it'll otherwise be in the ERAT and might come + * back and haunt us if it get's thrown out of there at the wrong + * time (i.e. similar to throwing out our own stack above). + */ + + esid_data.data.v = 0; + __asm__ __volatile__("slbie %0" : : "r" (esid_data)); + /* * Write the new SLB entry. */ diff -urN linux-2.4.24/arch/ppc64/kernel/sys_ppc32.c linux-2.4.25/arch/ppc64/kernel/sys_ppc32.c --- linux-2.4.24/arch/ppc64/kernel/sys_ppc32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/sys_ppc32.c 2004-02-18 05:36:30.000000000 -0800 @@ -104,11 +104,37 @@ return ret; } +asmlinkage int sys32_ustat(__kernel_dev_t32 dev, struct ustat32 * ubuf) +{ + + struct super_block *s; + struct ustat32 tmp; + struct statfs sbuf; + int err = -EINVAL; + + s = get_super(to_kdev_t(dev)); + if (s == NULL) + goto out; + err = vfs_statfs(s, &sbuf); + drop_super(s); + if (err) + goto out; + memset(&tmp,0,sizeof(struct ustat)); + tmp.f_tfree = sbuf.f_bfree; + tmp.f_tinode = sbuf.f_ffree; + + err = copy_to_user(ubuf, &tmp, sizeof(struct ustat32)) ? -EFAULT : 0; + +out: + return err; + +} struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; }; typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *); +typedef __kernel_ssize_t32 ssize_t32; static long do_readv_writev32(int type, struct file *file, const struct iovec32 *vector, u32 count) @@ -149,6 +175,11 @@ ivp->iov_len = (__kernel_size_t) len; vector++; ivp++; + if ((len < 0) || (tot_len != (ssize_t32)tot_len)) { + if (iov != iovstack) + kfree(iov); + return -EINVAL; + } i--; } @@ -467,7 +498,7 @@ }; -extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr); +extern asmlinkage long sys_quotactl(unsigned int cmd, const char *special, qid_t id, caddr_t addr); /* Note: it is necessary to treat cmd and id as unsigned ints, * with the corresponding cast to a signed int to insure that the @@ -476,9 +507,9 @@ */ asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, caddr_t addr) { - int cmd = (int)cmd_parm; - int id = (int)id_parm; - int cmds = cmd >> SUBCMDSHIFT; + unsigned int cmd = cmd_parm; + qid_t id = (qid_t)id_parm; + unsigned int cmds = cmd >> SUBCMDSHIFT; int err; struct v1c_mem_dqblk d; mm_segment_t old_fs; @@ -995,19 +1026,21 @@ static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) { - int err; - - err = put_user (kbuf->f_type, &ubuf->f_type); - err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize); - err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks); - err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree); - err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail); - err |= __put_user (kbuf->f_files, &ubuf->f_files); - err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree); - err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen); - err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); - err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); - return err; + struct statfs32 tmp; + memset(&tmp, 0, sizeof(tmp)); + + tmp.f_type = kbuf->f_type; + tmp.f_bsize = kbuf->f_bsize; + tmp.f_blocks = kbuf->f_blocks; + tmp.f_bfree = kbuf->f_bfree; + tmp.f_bavail = kbuf->f_bavail; + tmp.f_files = kbuf->f_files; + tmp.f_ffree = kbuf->f_ffree; + tmp.f_namelen = kbuf->f_namelen; + tmp.f_fsid.val[0] = kbuf->f_fsid.val[0]; + tmp.f_fsid.val[1] = kbuf->f_fsid.val[1]; + + return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0; } extern asmlinkage int sys_statfs(const char * path, struct statfs * buf); @@ -2567,7 +2600,7 @@ err = -EFAULT; if (get_user(pad, (u32 *)uptr)) return err; - if (third == SETVAL) + if ((third & (~IPC_64)) == SETVAL) fourth.val = (int)pad; else fourth.__pad = (void *)A(pad); @@ -3488,7 +3521,7 @@ if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) return -EFAULT; if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; + return -EMSGSIZE; err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); if (err < 0) goto out; @@ -3726,7 +3759,7 @@ if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) return -EFAULT; if(kern_msg.msg_iovlen > UIO_MAXIOV) - return -EINVAL; + return -EMSGSIZE; uaddr = kern_msg.msg_name; uaddr_len = &user_msg->msg_namelen; @@ -3987,8 +4020,10 @@ regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER32; +#ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = 0; +#endif current->thread.fpscr = 0; } @@ -4607,8 +4642,6 @@ extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, size_t count, loff_t pos); -typedef __kernel_ssize_t32 ssize_t32; - asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count, u32 reg6, u32 poshi, u32 poslo) { diff -urN linux-2.4.24/arch/ppc64/kernel/traps.c linux-2.4.25/arch/ppc64/kernel/traps.c --- linux-2.4.24/arch/ppc64/kernel/traps.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/traps.c 2004-02-18 05:36:30.000000000 -0800 @@ -49,6 +49,8 @@ /* This is true if we are using the firmware NMI handler (typically LPAR) */ extern int fwnmi_active; +/* This is true if we are using a check-exception based handler */ +extern int check_exception_flag; #ifdef CONFIG_XMON extern void xmon(struct pt_regs *regs); @@ -88,6 +90,9 @@ void set_local_DABR(void *valp); +/* do not want to kmalloc or wait on lock during machine check */ +char mce_data_buf[RTAS_ERROR_LOG_MAX]__page_aligned; + /* * Trap & Exception support */ @@ -128,7 +133,9 @@ (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) { savep = __va(errdata); regs->gpr[3] = savep[0]; /* restore original r3 */ - errhdr = (struct rtas_error_log *)(savep + 1); + memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX); + memcpy(mce_data_buf, (char *)(savep + 1), RTAS_ERROR_LOG_MAX); + errhdr = (struct rtas_error_log *)mce_data_buf; } else { printk("FWNMI: corrupt r3\n"); } @@ -166,17 +173,87 @@ #endif } +/* + * See if we can recover from a machine check exception. + * This is only called on power4 (or above) and only via + * the Firmware Non-Maskable Interrupts (fwnmi) handler + * which provides the error analysis for us. + * + * Return 1 if corrected (or delivered a signal). + * Return 0 if there is nothing we can do. + */ +static int recover_mce(struct pt_regs *regs, struct rtas_error_log *errp) +{ + siginfo_t info; + int nonfatal = 0; + + + if (errp->disposition == DISP_FULLY_RECOVERED) { + /* Platform corrected itself */ + nonfatal = 1; + } else if ((regs->msr & MSR_RI) && + user_mode(regs) && + errp->severity == SEVERITY_ERROR_SYNC && + errp->disposition == DISP_NOT_RECOVERED && + errp->target == TARGET_MEMORY && + errp->type == TYPE_ECC_UNCORR && + !(current->pid == 0 || current->pid == 1)) { + + /* Kill off a user process with an ECC error */ + printk(KERN_ERR "MCE: uncorrectable ecc error killed process %d (%s).\n", current->pid, current->comm); + + info.si_signo = SIGBUS; + info.si_errno = 0; + /* XXX better si_code for ECC error? */ + info.si_code = BUS_ADRERR; + info.si_addr = (void *)regs->nip; + _exception(SIGBUS, &info, regs); + nonfatal = 1; + } + + log_error((char *)errp, ERR_TYPE_RTAS_LOG, !nonfatal); + return nonfatal; +} + +/* + * Handle a machine check. + * + * Note that on Power 4 and beyond Firmware Non-Maskable Interrupts (fwnmi) + * should be present. If so the handler which called us tells us if the + * error was recovered (never true if RI=0). + * + * On hardware prior to Power 4 these exceptions were asynchronous which + * means we can't tell exactly where it occurred and so we can't recover. + * + * Note that the debugger should test RI=0 and warn the user that system + * state has been corrupted. + */ void MachineCheckException(struct pt_regs *regs) { + struct rtas_error_log *errp; if (fwnmi_active) { - struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs); - if (errhdr) { - /* ToDo: attempt to recover from some errors here */ - } + errp = FWNMI_get_errinfo(regs); FWNMI_release_errinfo(); + if (errp && recover_mce(regs, errp)) + return; + } else if (check_exception_flag) { + int status; + unsigned long long srr1 = regs->msr; + + memset(mce_data_buf, 0, RTAS_ERROR_LOG_MAX); + /* XXX + * We only pass the low 32 bits of SRR1, this could + * be changed to 7 input params and the high 32 bits + * of SRR1 could be passed as the extended info argument. + */ + status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, + 0x200, (uint)srr1, RTAS_INTERNAL_ERROR, 0, + __pa(mce_data_buf), RTAS_ERROR_LOG_MAX); + if (status == 0) + log_error((char *)mce_data_buf, ERR_TYPE_RTAS_LOG, 1); } #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) @@ -279,6 +356,19 @@ _exception(SIGFPE, info, regs); } +#ifndef CONFIG_ALTIVEC +void IllegalAltiVecInstruction(struct pt_regs *regs) +{ + siginfo_t info; + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void *)regs->nip; + _exception(SIGILL, &info, regs); +} +#endif + void ProgramCheckException(struct pt_regs *regs) { @@ -327,6 +417,47 @@ panic("Unrecoverable FP Unavailable Exception in Kernel"); } + +void +KernelAltiVecUnavailableException(struct pt_regs *regs) +{ + printk("Illegal Altivec used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n", + (unsigned long)current, regs->nip, (unsigned int)regs->trap); + panic("Unrecoverable Altivec Unavailable Exception in Kernel"); +} + +void +AltiVecAssistException(struct pt_regs *regs) +{ +#ifdef CONFIG_ALTIVEC + printk("Altivec assist called by %s, switching java mode off\n", + current->comm); + /* We do this the "hard" way, but that's ok for now, maybe one + * day, we'll have a proper implementation... + */ + if (regs->msr & MSR_VEC) + giveup_altivec(current); + current->thread.vscr.u[3] |= 0x00010000; +#else + siginfo_t info; + + printk("Altivec assist called by %s;, no altivec support !\n", + current->comm); + + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = 0; + info.si_addr = 0; + _exception(SIGTRAP, &info, regs); +#endif /* CONFIG_ALTIVEC */ +} + +void +ThermalInterrupt(struct pt_regs *regs) +{ + panic("Thermal interrupt exception not handled !"); +} + void SingleStepException(struct pt_regs *regs) { diff -urN linux-2.4.24/arch/ppc64/kernel/udbg.c linux-2.4.25/arch/ppc64/kernel/udbg.c --- linux-2.4.24/arch/ppc64/kernel/udbg.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/udbg.c 2004-02-18 05:36:30.000000000 -0800 @@ -130,8 +130,10 @@ { int remain = n; char c; + if (!ppc_md.udbg_putc) - for (;;); /* stop here for cpuctl */ + return 0; + if ( s && *s != '\0' ) { while ( (( c = *s++ ) != '\0') && (remain-- > 0)) { ppc_md.udbg_putc(c); diff -urN linux-2.4.24/arch/ppc64/kernel/vio.c linux-2.4.25/arch/ppc64/kernel/vio.c --- linux-2.4.24/arch/ppc64/kernel/vio.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/vio.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,503 @@ +/* + * IBM PowerPC Virtual I/O Infrastructure Support. + * + * Dave Engebretsen engebret@us.ibm.com + * Copyright (c) 2003 Dave Engebretsen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct TceTable *build_tce_table(struct TceTable *tbl); + +extern dma_addr_t get_tces(struct TceTable *, unsigned order, + void *page, unsigned numPages, int direction); +extern void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, + unsigned order, unsigned num_pages); + + +static struct vio_bus vio_bus; +static LIST_HEAD(registered_vio_drivers); +int vio_num_address_cells; +EXPORT_SYMBOL(vio_num_address_cells); + +/** + * vio_register_driver: - Register a new vio driver + * @drv: The vio_driver structure to be registered. + * + * Adds the driver structure to the list of registered drivers + * Returns the number of vio devices which were claimed by the driver + * during registration. The driver remains registered even if the + * return value is zero. + */ +int vio_register_driver(struct vio_driver *drv) +{ + int count = 0; + struct vio_dev *dev; + const struct vio_device_id* id; + /* + * Walk the vio_bus, find devices for this driver, and + * call back into the driver probe interface. + */ + + list_for_each_entry(dev, &vio_bus.devices, devices_list) { + id = vio_match_device(drv->id_table, dev); + if(drv && id) { + if (0 == drv->probe(dev, id)) { + dev->driver = drv; + count++; + } + } + } + + list_add_tail(&drv->node, ®istered_vio_drivers); + + return count; +} +EXPORT_SYMBOL(vio_register_driver); + +/** + * vio_unregister_driver - Remove registration of vio driver. + * @driver: The vio_driver struct to be removed form registration + * + * Searches for devices that are assigned to the driver and calls + * driver->remove() for each one. Removes the driver from the list + * of registered drivers. Returns the number of devices that were + * assigned to that driver. + */ +int vio_unregister_driver(struct vio_driver *driver) +{ + struct vio_dev *dev; + int devices_found = 0; + + list_for_each_entry(dev, &vio_bus.devices, devices_list) { + if (dev->driver == driver) { + driver->remove(dev); + dev->driver = NULL; + devices_found++; + } + } + + list_del(&driver->node); + + return devices_found; +} +EXPORT_SYMBOL(vio_unregister_driver); + +/** + * vio_match_device: - Tell if a VIO device has a matching VIO device id structure. + * @ids: array of VIO device id structures to search in + * @dev: the VIO device structure to match against + * + * Used by a driver to check whether a VIO device present in the + * system is in its list of supported devices. Returns the matching + * vio_device_id structure or NULL if there is no match. + */ +const struct vio_device_id * +vio_match_device(const struct vio_device_id *ids, const struct vio_dev *dev) +{ + while (ids->type) { + if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) && + device_is_compatible((struct device_node*)dev->archdata, ids->compat)) + return ids; + ids++; + } + return NULL; +} + +/** + * vio_bus_init: - Initialize the virtual IO bus + */ +int __init +vio_bus_init(void) +{ + struct device_node *node_vroot, *node_vdev; + + printk("vio_bus_init: start\n"); + + INIT_LIST_HEAD(&vio_bus.devices); + + /* + * Create device node entries for each virtual device + * identified in the device tree. + * Functionally takes the place of pci_scan_bus + */ + node_vroot = find_devices("vdevice"); + if (!node_vroot) { + printk(KERN_WARNING "vio_bus_init: no /vdevice node\n"); + return 0; + } + + vio_num_address_cells = prom_n_addr_cells(node_vroot->child); + + for (node_vdev = node_vroot->child; + node_vdev != NULL; + node_vdev = node_vdev->sibling) { + printk(KERN_INFO "vio_bus_init: processing %p\n", node_vdev); + + vio_register_device(node_vdev); + } + + printk(KERN_INFO "vio_bus_init: done\n"); + + return 0; +} + +__initcall(vio_bus_init); + + +/** + * vio_register_device: - Register a new vio device. + * @archdata: The OF node for this device. + * + * Creates and initializes a vio_dev structure from the data in + * node_vdev (archdata) and adds it to the list of virtual devices. + * Returns a pointer to the created vio_dev or NULL if node has + * NULL device_type or compatible fields. +*/ +struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev) +{ + struct vio_dev *dev; + unsigned int *unit_address; + unsigned int *irq_p; + + /* guarantee all vio_devs have 'device_type' field*/ + if ((NULL == node_vdev->type)) { + printk(KERN_WARNING "vio_register_device: node %s missing 'device_type' " + , node_vdev->name?node_vdev->name:"UNKNOWN"); + return NULL; + } + + unit_address = (unsigned int *)get_property(node_vdev, "reg", NULL); + if(!unit_address) { + printk(KERN_WARNING "Can't find %s reg property\n", node_vdev->name?node_vdev->name:"UNKNOWN_DEVICE"); + return NULL; + } + + /* allocate a vio_dev for this node */ + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + memset(dev, 0, sizeof(*dev)); + + dev->archdata = (void*)node_vdev; /* to become of_get_node(node_vdev); */ + dev->bus = &vio_bus; + dev->unit_address = *unit_address; + dev->tce_table = vio_build_tce_table(dev); + + irq_p = (unsigned int *) get_property(node_vdev, "interrupts", 0); + if(irq_p) { + dev->irq = irq_offset_up(*irq_p); + } else { + dev->irq = (unsigned int) -1; + } + + list_add_tail(&dev->devices_list, &vio_bus.devices); + + return dev; +} + +/** + * vio_find_driver: - Find driver for vio_dev. + * @dev: Device to search for a driver. + * + * Walks the registered_vio_drivers list calling vio_match_device() + * for every driver in the list. If there is a match, calls the + * driver's probe(). + * Returns a pointer to the matched driver or NULL if driver is not + * found. +*/ +struct vio_driver * vio_find_driver(struct vio_dev* dev) +{ + struct vio_driver *driver; + list_for_each_entry(driver, ®istered_vio_drivers, node) { + if(driver && vio_match_device(driver->id_table, dev)) { + if (0 < driver->probe(dev, NULL)) { + dev->driver = driver; + return driver; + } + } + } + + return NULL; +} + +/** + * vio_get_attribute: - get attribute for virtual device + * @vdev: The vio device to get property. + * @which: The property/attribute to be extracted. + * @length: Pointer to length of returned data size (unused if NULL). + * + * Calls prom.c's get_property() to return the value of the + * attribute specified by the preprocessor constant @which +*/ +const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) +{ + return get_property((struct device_node *)vdev->archdata, (char*)which, length); +} +EXPORT_SYMBOL(vio_get_attribute); + +/** + * vio_build_tce_table: - gets the dma information from OF and builds the TCE tree. + * @dev: the virtual device. + * + * Returns a pointer to the built tce tree, or NULL if it can't + * find property. +*/ +struct TceTable * vio_build_tce_table(struct vio_dev *dev) +{ + unsigned int *dma_window; + struct TceTable *newTceTable; + unsigned long offset; + unsigned long size; + int dma_window_property_size; + + dma_window = (unsigned int *) get_property((struct device_node *)dev->archdata, "ibm,my-dma-window", &dma_window_property_size); + if(!dma_window) { + return NULL; + } + + newTceTable = (struct TceTable *) kmalloc(sizeof(struct TceTable), GFP_KERNEL); + + /* RPA docs say that #address-cells is always 1 for virtual + devices, but some older boxes' OF returns 2. This should + be removed by GA, unless there is legacy OFs that still + have 2 for #address-cells */ + size = ((dma_window[1+vio_num_address_cells] + >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; + + /* This is just an ugly kludge. Remove as soon as the OF for all + machines actually follow the spec and encodes the offset field + as phys-encode (that is, #address-cells wide)*/ + if (dma_window_property_size == 12) { + size = ((dma_window[1] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; + } else if (dma_window_property_size == 20) { + size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; + } else { + printk(KERN_WARNING "vio_build_tce_table: Invalid size of ibm,my-dma-window=%i, using 0x80 for size\n", dma_window_property_size); + size = 0x80; + } + + /* There should be some code to extract the phys-encoded offset + using prom_n_addr_cells(). However, according to a comment + on earlier versions, it's always zero, so we don't bother */ + offset = dma_window[1] >> PAGE_SHIFT; + + /* TCE table size - measured in units of pages of tce table */ + newTceTable->size = size; + /* offset for VIO should always be 0 */ + newTceTable->startOffset = offset; + newTceTable->busNumber = 0; + newTceTable->index = (unsigned long)dma_window[0]; + newTceTable->tceType = TCE_VB; + + return build_tce_table(newTceTable); +} + +int vio_enable_interrupts(struct vio_dev *dev) +{ + int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE); + if (rc != H_Success) { + printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc); + } + return rc; +} +EXPORT_SYMBOL(vio_enable_interrupts); + +int vio_disable_interrupts(struct vio_dev *dev) +{ + int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE); + if (rc != H_Success) { + printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc); + } + return rc; +} +EXPORT_SYMBOL(vio_disable_interrupts); + +dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr, + size_t size, int direction ) +{ + struct TceTable * tbl; + dma_addr_t dma_handle = NO_TCE; + unsigned long uaddr; + unsigned order, nPages; + + if(direction == PCI_DMA_NONE) BUG(); + + uaddr = (unsigned long)vaddr; + nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + /* Client asked for way to much space. This is checked later anyway */ + /* It is easier to debug here for the drivers than in the tce tables.*/ + if(order >= NUM_TCE_LEVELS) { + printk("VIO_DMA: vio_map_single size to large: 0x%lx \n",size); + return NO_TCE; + } + + tbl = dev->tce_table; + + if(tbl) { + dma_handle = get_tces(tbl, order, vaddr, nPages, direction); + dma_handle |= (uaddr & ~PAGE_MASK); + } + + return dma_handle; +} +EXPORT_SYMBOL(vio_map_single); + +void vio_unmap_single(struct vio_dev *dev, dma_addr_t dma_handle, + size_t size, int direction) +{ + struct TceTable * tbl; + unsigned order, nPages; + + if (direction == PCI_DMA_NONE) BUG(); + + nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + /* Client asked for way to much space. This is checked later anyway */ + /* It is easier to debug here for the drivers than in the tce tables.*/ + if(order >= NUM_TCE_LEVELS) { + printk("VIO_DMA: vio_unmap_single 0x%lx size to large: 0x%lx \n",(unsigned long)dma_handle,(unsigned long)size); + return; + } + + tbl = dev->tce_table; + if(tbl) tce_free(tbl, dma_handle, order, nPages); +} +EXPORT_SYMBOL(vio_unmap_single); + +int vio_map_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems, + int direction) +{ + int i; + + for (i = 0; i < nelems; i++) { + + /* 2.4 scsi scatterlists use address field. + Not sure about other subsystems. */ + void *vaddr; + if (sglist->address) + vaddr = sglist->address; + else + vaddr = page_address(sglist->page) + sglist->offset; + + sglist->dma_address = vio_map_single(vdev, vaddr, + sglist->length, + direction); + sglist->dma_length = sglist->length; + sglist++; + } + + return nelems; +} +EXPORT_SYMBOL(vio_map_sg); + +void vio_unmap_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems, + int direction) +{ + while (nelems--) { + vio_unmap_single(vdev, sglist->dma_address, + sglist->dma_length, direction); + sglist++; + } +} + +void *vio_alloc_consistent(struct vio_dev *dev, size_t size, + dma_addr_t *dma_handle) +{ + struct TceTable * tbl; + void *ret = NULL; + unsigned order, nPages; + dma_addr_t tce; + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + /* Client asked for way to much space. This is checked later anyway */ + /* It is easier to debug here for the drivers than in the tce tables.*/ + if(order >= NUM_TCE_LEVELS) { + printk("VIO_DMA: vio_alloc_consistent size to large: 0x%lx \n",size); + return (void *)NO_TCE; + } + + tbl = dev->tce_table; + + if ( tbl ) { + /* Alloc enough pages (and possibly more) */ + ret = (void *)__get_free_pages( GFP_ATOMIC, order ); + if ( ret ) { + /* Page allocation succeeded */ + memset(ret, 0, nPages << PAGE_SHIFT); + /* Set up tces to cover the allocated range */ + tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL ); + if ( tce == NO_TCE ) { + PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: get_tces failed\n" ); + free_pages( (unsigned long)ret, order ); + ret = NULL; + } + else + { + *dma_handle = tce; + } + } + else PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: __get_free_pages failed for order = %d\n", order); + } + else PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: get_tce_table failed for 0x%016lx\n", dev); + + PPCDBG(PPCDBG_TCE, "\tvio_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle); + PPCDBG(PPCDBG_TCE, "\tvio_alloc_consistent: return = 0x%16.16lx\n", ret); + return ret; +} +EXPORT_SYMBOL(vio_alloc_consistent); + +void vio_free_consistent(struct vio_dev *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + struct TceTable * tbl; + unsigned order, nPages; + + PPCDBG(PPCDBG_TCE, "vio_free_consistent:\n"); + PPCDBG(PPCDBG_TCE, "\tdev = 0x%16.16lx, size = 0x%16.16lx, dma_handle = 0x%16.16lx, vaddr = 0x%16.16lx\n", dev, size, dma_handle, vaddr); + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + /* Client asked for way to much space. This is checked later anyway */ + /* It is easier to debug here for the drivers than in the tce tables.*/ + if(order >= NUM_TCE_LEVELS) { + printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size); + return; + } + + tbl = dev->tce_table; + + if ( tbl ) { + tce_free(tbl, dma_handle, order, nPages); + free_pages( (unsigned long)vaddr, order ); + } +} +EXPORT_SYMBOL(vio_free_consistent); + +EXPORT_SYMBOL(plpar_hcall_norets); +EXPORT_SYMBOL(plpar_hcall_8arg_2ret); + + diff -urN linux-2.4.24/arch/ppc64/kernel/viopath.c linux-2.4.25/arch/ppc64/kernel/viopath.c --- linux-2.4.24/arch/ppc64/kernel/viopath.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/arch/ppc64/kernel/viopath.c 2004-02-18 05:36:30.000000000 -0800 @@ -0,0 +1,811 @@ +/* -*- linux-c -*- + * arch/ppc64/viopath.c + * + * iSeries Virtual I/O Message Path code + * + * Authors: Dave Boutcher + * Ryan Arnold + * Colin Devilbiss + * + * (C) Copyright 2000 IBM Corporation + * + * This code is used by the iSeries virtual disk, cd, + * tape, and console to communicate with OS/400 in another + * partition. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) anyu later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +EXPORT_SYMBOL(viopath_hostLp); +EXPORT_SYMBOL(viopath_ourLp); +EXPORT_SYMBOL(vio_set_hostlp); +EXPORT_SYMBOL(vio_lookup_rc); +EXPORT_SYMBOL(viopath_open); +EXPORT_SYMBOL(viopath_close); +EXPORT_SYMBOL(viopath_isactive); +EXPORT_SYMBOL(viopath_sourceinst); +EXPORT_SYMBOL(viopath_targetinst); +EXPORT_SYMBOL(vio_setHandler); +EXPORT_SYMBOL(vio_clearHandler); +EXPORT_SYMBOL(vio_get_event_buffer); +EXPORT_SYMBOL(vio_free_event_buffer); + +extern struct pci_dev *iSeries_vio_dev; + +/* Status of the path to each other partition in the system. + * This is overkill, since we will only ever establish connections + * to our hosting partition and the primary partition on the system. + * But this allows for other support in the future. + */ +static struct viopathStatus { + int isOpen:1; /* Did we open the path? */ + int isActive:1; /* Do we have a mon msg outstanding */ + int users[VIO_MAX_SUBTYPES]; + HvLpInstanceId mSourceInst; + HvLpInstanceId mTargetInst; + int numberAllocated; +} viopathStatus[HVMAXARCHITECTEDLPS]; + +static spinlock_t statuslock = SPIN_LOCK_UNLOCKED; + +/* + * For each kind of event we allocate a buffer that is + * guaranteed not to cross a page boundary + */ +static void *event_buffer[VIO_MAX_SUBTYPES] = { }; +static atomic_t event_buffer_available[VIO_MAX_SUBTYPES] = { }; + +static void handleMonitorEvent(struct HvLpEvent *event); + +/* We use this structure to handle asynchronous responses. The caller + * blocks on the semaphore and the handler posts the semaphore. + */ +struct doneAllocParms_t { + struct semaphore *sem; + int number; +}; + +/* Put a sequence number in each mon msg. The value is not + * important. Start at something other than 0 just for + * readability. wrapping this is ok. + */ +static u8 viomonseq = 22; + +/* Our hosting logical partition. We get this at startup + * time, and different modules access this variable directly. + */ +HvLpIndex viopath_hostLp = 0xff; /* HvLpIndexInvalid */ +HvLpIndex viopath_ourLp = 0xff; + +/* For each kind of incoming event we set a pointer to a + * routine to call. + */ +static vio_event_handler_t *vio_handler[VIO_MAX_SUBTYPES]; + +static unsigned char e2a(unsigned char x) +{ + switch (x) { + case 0xF0: + return '0'; + case 0xF1: + return '1'; + case 0xF2: + return '2'; + case 0xF3: + return '3'; + case 0xF4: + return '4'; + case 0xF5: + return '5'; + case 0xF6: + return '6'; + case 0xF7: + return '7'; + case 0xF8: + return '8'; + case 0xF9: + return '9'; + case 0xC1: + return 'A'; + case 0xC2: + return 'B'; + case 0xC3: + return 'C'; + case 0xC4: + return 'D'; + case 0xC5: + return 'E'; + case 0xC6: + return 'F'; + case 0xC7: + return 'G'; + case 0xC8: + return 'H'; + case 0xC9: + return 'I'; + case 0xD1: + return 'J'; + case 0xD2: + return 'K'; + case 0xD3: + return 'L'; + case 0xD4: + return 'M'; + case 0xD5: + return 'N'; + case 0xD6: + return 'O'; + case 0xD7: + return 'P'; + case 0xD8: + return 'Q'; + case 0xD9: + return 'R'; + case 0xE2: + return 'S'; + case 0xE3: + return 'T'; + case 0xE4: + return 'U'; + case 0xE5: + return 'V'; + case 0xE6: + return 'W'; + case 0xE7: + return 'X'; + case 0xE8: + return 'Y'; + case 0xE9: + return 'Z'; + } + return ' '; +} + +/* Handle reads from the proc file system + */ +static int proc_read(char *buf, char **start, off_t offset, + int blen, int *eof, void *data) +{ + HvLpEvent_Rc hvrc; + DECLARE_MUTEX_LOCKED(Semaphore); + dma_addr_t dmaa = + pci_map_single(iSeries_vio_dev, buf, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + int len = PAGE_SIZE; + + if (len > blen) + len = blen; + + memset(buf, 0x00, len); + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_config | + vioconfigget, + HvLpEvent_AckInd_DoAck, + HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst + (viopath_hostLp), + viopath_targetinst + (viopath_hostLp), + (u64) (unsigned long) + &Semaphore, VIOVERSION << 16, + ((u64) dmaa) << 32, len, 0, + 0); + if (hvrc != HvLpEvent_Rc_Good) { + printk("viopath hv error on op %d\n", (int) hvrc); + } + + down(&Semaphore); + + pci_unmap_single(iSeries_vio_dev, dmaa, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + + sprintf(buf + strlen(buf), "SRLNBR="); + buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[2]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[3]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[1]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[2]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[3]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[4]); + buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[5]); + buf[strlen(buf)] = '\n'; + *eof = 1; + return strlen(buf); +} + +/* Handle writes to our proc file system + */ +static int proc_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + /* Doesn't do anything today!!! + */ + return count; +} + +/* setup our proc file system entries + */ +static void vio_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent; + ent = create_proc_entry("config", S_IFREG | S_IRUSR, iSeries_proc); + if (!ent) + return; + ent->nlink = 1; + ent->data = NULL; + ent->read_proc = proc_read; + ent->write_proc = proc_write; +} + +/* See if a given LP is active. Allow for invalid lps to be passed in + * and just return invalid + */ +int viopath_isactive(HvLpIndex lp) +{ + if (lp == HvLpIndexInvalid) + return 0; + if (lp < HVMAXARCHITECTEDLPS) + return viopathStatus[lp].isActive; + else + return 0; +} + +/* We cache the source and target instance ids for each + * partition. + */ +HvLpInstanceId viopath_sourceinst(HvLpIndex lp) +{ + return viopathStatus[lp].mSourceInst; +} + +HvLpInstanceId viopath_targetinst(HvLpIndex lp) +{ + return viopathStatus[lp].mTargetInst; +} + +/* Send a monitor message. This is a message with the acknowledge + * bit on that the other side will NOT explicitly acknowledge. When + * the other side goes down, the hypervisor will acknowledge any + * outstanding messages....so we will know when the other side dies. + */ +static void sendMonMsg(HvLpIndex remoteLp) +{ + HvLpEvent_Rc hvrc; + + viopathStatus[remoteLp].mSourceInst = + HvCallEvent_getSourceLpInstanceId(remoteLp, + HvLpEvent_Type_VirtualIo); + viopathStatus[remoteLp].mTargetInst = + HvCallEvent_getTargetLpInstanceId(remoteLp, + HvLpEvent_Type_VirtualIo); + + /* Deliberately ignore the return code here. if we call this + * more than once, we don't care. + */ + vio_setHandler(viomajorsubtype_monitor, handleMonitorEvent); + + hvrc = HvCallEvent_signalLpEventFast(remoteLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_monitor, + HvLpEvent_AckInd_DoAck, + HvLpEvent_AckType_DeferredAck, + viopathStatus[remoteLp]. + mSourceInst, + viopathStatus[remoteLp]. + mTargetInst, viomonseq++, + 0, 0, 0, 0, 0); + + if (hvrc == HvLpEvent_Rc_Good) { + viopathStatus[remoteLp].isActive = 1; + } else { + printk(KERN_WARNING_VIO + "could not connect to partition %d\n", remoteLp); + viopathStatus[remoteLp].isActive = 0; + } +} + +static void handleMonitorEvent(struct HvLpEvent *event) +{ + HvLpIndex remoteLp; + int i; + + /* This handler is _also_ called as part of the loop + * at the end of this routine, so it must be able to + * ignore NULL events... + */ + if (!event) + return; + + /* First see if this is just a normal monitor message from the + * other partition + */ + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { + remoteLp = event->xSourceLp; + if (!viopathStatus[remoteLp].isActive) + sendMonMsg(remoteLp); + return; + } + + /* This path is for an acknowledgement; the other partition + * died + */ + remoteLp = event->xTargetLp; + if ((event->xSourceInstanceId != + viopathStatus[remoteLp].mSourceInst) + || (event->xTargetInstanceId != + viopathStatus[remoteLp].mTargetInst)) { + printk(KERN_WARNING_VIO + "ignoring ack....mismatched instances\n"); + return; + } + + printk(KERN_WARNING_VIO "partition %d ended\n", remoteLp); + + viopathStatus[remoteLp].isActive = 0; + + /* For each active handler, pass them a NULL + * message to indicate that the other partition + * died + */ + for (i = 0; i < VIO_MAX_SUBTYPES; i++) { + if (vio_handler[i] != NULL) + (*vio_handler[i]) (NULL); + } +} + +int vio_setHandler(int subtype, vio_event_handler_t * beh) +{ + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) + return -EINVAL; + + if (vio_handler[subtype] != NULL) + return -EBUSY; + + vio_handler[subtype] = beh; + return 0; +} + +int vio_clearHandler(int subtype) +{ + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) + return -EINVAL; + + if (vio_handler[subtype] == NULL) + return -EAGAIN; + + vio_handler[subtype] = NULL; + return 0; +} + +static void handleConfig(struct HvLpEvent *event) +{ + if (!event) + return; + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { + printk(KERN_WARNING_VIO + "unexpected config request from partition %d", + event->xSourceLp); + + if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && + (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + return; + } + + up((struct semaphore *) event->xCorrelationToken); +} + +/* Initialization of the hosting partition + */ +void vio_set_hostlp(void) +{ + /* If this has already been set then we DON'T want to either change + * it or re-register the proc file system + */ + if (viopath_hostLp != HvLpIndexInvalid) + return; + + /* Figure out our hosting partition. This isn't allowed to change + * while we're active + */ + viopath_ourLp = HvLpConfig_getLpIndex(); + viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp); + + /* If we have a valid hosting LP, create a proc file system entry + * for config information + */ + if (viopath_hostLp != HvLpIndexInvalid) { + iSeries_proc_callback(&vio_proc_init); + vio_setHandler(viomajorsubtype_config, handleConfig); + } +} + +static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs) +{ + HvLpIndex remoteLp; + int subtype = + (event-> + xSubtype & VIOMAJOR_SUBTYPE_MASK) >> VIOMAJOR_SUBTYPE_SHIFT; + + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { + remoteLp = event->xSourceLp; + /* The isActive is checked because if the hosting partition + * went down and came back up it would not be active but it would have + * different source and target instances, in which case we'd want to + * reset them. This case really protects against an unauthorized + * active partition sending interrupts or acks to this linux partition. + */ + if (viopathStatus[remoteLp].isActive + && (event->xSourceInstanceId != + viopathStatus[remoteLp].mTargetInst)) { + printk(KERN_WARNING_VIO + "message from invalid partition. " + "int msg rcvd, source inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mTargetInst, + event->xSourceInstanceId); + return; + } + + if (viopathStatus[remoteLp].isActive + && (event->xTargetInstanceId != + viopathStatus[remoteLp].mSourceInst)) { + printk(KERN_WARNING_VIO + "message from invalid partition. " + "int msg rcvd, target inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mSourceInst, + event->xTargetInstanceId); + return; + } + } else { + remoteLp = event->xTargetLp; + if (event->xSourceInstanceId != + viopathStatus[remoteLp].mSourceInst) { + printk(KERN_WARNING_VIO + "message from invalid partition. " + "ack msg rcvd, source inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mSourceInst, + event->xSourceInstanceId); + return; + } + + if (event->xTargetInstanceId != + viopathStatus[remoteLp].mTargetInst) { + printk(KERN_WARNING_VIO + "message from invalid partition. " + "viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mTargetInst, + event->xTargetInstanceId); + return; + } + } + + if (vio_handler[subtype] == NULL) { + printk(KERN_WARNING_VIO + "unexpected virtual io event subtype %d from partition %d\n", + event->xSubtype, remoteLp); + /* No handler. Ack if necessary + */ + if ((event->xFlags.xFunction == HvLpEvent_Function_Int) && + (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + return; + } + + /* This innocuous little line is where all the real work happens + */ + (*vio_handler[subtype]) (event); +} + +static void viopath_donealloc(void *parm, int number) +{ + struct doneAllocParms_t *doneAllocParmsp = + (struct doneAllocParms_t *) parm; + doneAllocParmsp->number = number; + up(doneAllocParmsp->sem); +} + +static int allocateEvents(HvLpIndex remoteLp, int numEvents) +{ + struct doneAllocParms_t doneAllocParms; + DECLARE_MUTEX_LOCKED(Semaphore); + doneAllocParms.sem = &Semaphore; + + mf_allocateLpEvents(remoteLp, HvLpEvent_Type_VirtualIo, 250, /* It would be nice to put a real number here! */ + numEvents, + &viopath_donealloc, &doneAllocParms); + + down(&Semaphore); + + return doneAllocParms.number; +} + +int viopath_open(HvLpIndex remoteLp, int subtype, int numReq) +{ + int i; + unsigned long flags; + void *tempEventBuffer = NULL; + int tempNumAllocated; + + if ((remoteLp >= HvMaxArchitectedLps) + || (remoteLp == HvLpIndexInvalid)) + return -EINVAL; + + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) + return -EINVAL; + + /* + * NOTE: If VIO_MAX_SUBTYPES exceeds 16 then we need + * to allocate more than one page for the event_buffer. + */ + if (event_buffer[0] == NULL) { + if (VIO_MAX_SUBTYPES <= 16) { + tempEventBuffer = + (void *) get_free_page(GFP_KERNEL); + if (tempEventBuffer == NULL) + return -ENOMEM; + } else { + printk(KERN_INFO_VIO + "VIO_MAX_SUBTYPES > 16. Need more space."); + return -ENOMEM; + } + } + + spin_lock_irqsave(&statuslock, flags); + + /* + * OK...we can fit 16 maximum-sized events (256 bytes) in + * each page (4096). + */ + if (event_buffer[0] == NULL) { + event_buffer[0] = tempEventBuffer; + atomic_set(&event_buffer_available[0], 1); + /* + * Start at the second element because we've already + * set the pointer for the first element and set the + * pointers for every 256 bytes in the page we + * allocated earlier. + */ + for (i = 1; i < VIO_MAX_SUBTYPES; i++) { + event_buffer[i] = event_buffer[i - 1] + 256; + atomic_set(&event_buffer_available[i], 1); + } + } else { + /* + * While we were fetching the pages, which shouldn't + * be done in a spin lock, another call to viopath_open + * decided to do the same thing and allocated storage + * and set the event_buffer before we could so we'll + * free the one that we allocated and continue with our + * viopath_open operation. + */ + free_page((unsigned long) tempEventBuffer); + } + + viopathStatus[remoteLp].users[subtype]++; + + if (!viopathStatus[remoteLp].isOpen) { + viopathStatus[remoteLp].isOpen = 1; + HvCallEvent_openLpEventPath(remoteLp, + HvLpEvent_Type_VirtualIo); + + spin_unlock_irqrestore(&statuslock, flags); + /* + * Don't hold the spinlock during an operation that + * can sleep. + */ + tempNumAllocated = allocateEvents(remoteLp, 1); + spin_lock_irqsave(&statuslock, flags); + + viopathStatus[remoteLp].numberAllocated += + tempNumAllocated; + + if (viopathStatus[remoteLp].numberAllocated == 0) { + HvCallEvent_closeLpEventPath(remoteLp, + HvLpEvent_Type_VirtualIo); + + spin_unlock_irqrestore(&statuslock, flags); + return -ENOMEM; + } + + viopathStatus[remoteLp].mSourceInst = + HvCallEvent_getSourceLpInstanceId(remoteLp, + HvLpEvent_Type_VirtualIo); + viopathStatus[remoteLp].mTargetInst = + HvCallEvent_getTargetLpInstanceId(remoteLp, + HvLpEvent_Type_VirtualIo); + + HvLpEvent_registerHandler(HvLpEvent_Type_VirtualIo, + &vio_handleEvent); + + sendMonMsg(remoteLp); + + printk(KERN_INFO_VIO + "Opening connection to partition %d, setting sinst %d, tinst %d\n", + remoteLp, + viopathStatus[remoteLp].mSourceInst, + viopathStatus[remoteLp].mTargetInst); + } + + spin_unlock_irqrestore(&statuslock, flags); + tempNumAllocated = allocateEvents(remoteLp, numReq); + spin_lock_irqsave(&statuslock, flags); + viopathStatus[remoteLp].numberAllocated += tempNumAllocated; + spin_unlock_irqrestore(&statuslock, flags); + + return 0; +} + +int viopath_close(HvLpIndex remoteLp, int subtype, int numReq) +{ + unsigned long flags; + int i; + int numOpen; + struct doneAllocParms_t doneAllocParms; + DECLARE_MUTEX_LOCKED(Semaphore); + doneAllocParms.sem = &Semaphore; + + if ((remoteLp >= HvMaxArchitectedLps) + || (remoteLp == HvLpIndexInvalid)) + return -EINVAL; + + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) + return -EINVAL; + + spin_lock_irqsave(&statuslock, flags); + /* + * If the viopath_close somehow gets called before a + * viopath_open it could decrement to -1 which is a non + * recoverable state so we'll prevent this from + * happening. + */ + if (viopathStatus[remoteLp].users[subtype] > 0) { + viopathStatus[remoteLp].users[subtype]--; + } + spin_unlock_irqrestore(&statuslock, flags); + + mf_deallocateLpEvents(remoteLp, HvLpEvent_Type_VirtualIo, + numReq, &viopath_donealloc, &doneAllocParms); + down(&Semaphore); + + spin_lock_irqsave(&statuslock, flags); + for (i = 0, numOpen = 0; i < VIO_MAX_SUBTYPES; i++) { + numOpen += viopathStatus[remoteLp].users[i]; + } + + if ((viopathStatus[remoteLp].isOpen) && (numOpen == 0)) { + printk(KERN_INFO_VIO + "Closing connection to partition %d", remoteLp); + + HvCallEvent_closeLpEventPath(remoteLp, + HvLpEvent_Type_VirtualIo); + viopathStatus[remoteLp].isOpen = 0; + viopathStatus[remoteLp].isActive = 0; + + for (i = 0; i < VIO_MAX_SUBTYPES; i++) { + atomic_set(&event_buffer_available[i], 0); + } + + /* + * Precautionary check to make sure we don't + * erroneously try to free a page that wasn't + * allocated. + */ + if (event_buffer[0] != NULL) { + free_page((unsigned long) event_buffer[0]); + for (i = 0; i < VIO_MAX_SUBTYPES; i++) { + event_buffer[i] = NULL; + } + } + + } + spin_unlock_irqrestore(&statuslock, flags); + return 0; +} + +void *vio_get_event_buffer(int subtype) +{ + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) + return NULL; + + if (atomic_dec_if_positive(&event_buffer_available[subtype]) == 0) + return event_buffer[subtype]; + else + return NULL; +} + +void vio_free_event_buffer(int subtype, void *buffer) +{ + subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; + if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) { + printk(KERN_WARNING_VIO + "unexpected subtype %d freeing event buffer\n", + subtype); + return; + } + + if (atomic_read(&event_buffer_available[subtype]) != 0) { + printk(KERN_WARNING_VIO + "freeing unallocated event buffer, subtype %d\n", + subtype); + return; + } + + if (buffer != event_buffer[subtype]) { + printk(KERN_WARNING_VIO + "freeing invalid event buffer, subtype %d\n", + subtype); + } + + atomic_set(&event_buffer_available[subtype], 1); +} + +static const struct vio_error_entry vio_no_error = + { 0, 0, "Non-VIO Error" }; +static const struct vio_error_entry vio_unknown_error = + { 0, EIO, "Unknown Error" }; + +static const struct vio_error_entry vio_default_errors[] = { + {0x0001, EIO, "No Connection"}, + {0x0002, EIO, "No Receiver"}, + {0x0003, EIO, "No Buffer Available"}, + {0x0004, EBADRQC, "Invalid Message Type"}, + {0x0000, 0, NULL}, +}; + +const struct vio_error_entry *vio_lookup_rc(const struct vio_error_entry + *local_table, u16 rc) +{ + const struct vio_error_entry *cur; + if (!rc) + return &vio_no_error; + if (local_table) + for (cur = local_table; cur->rc; ++cur) + if (cur->rc == rc) + return cur; + for (cur = vio_default_errors; cur->rc; ++cur) + if (cur->rc == rc) + return cur; + return &vio_unknown_error; +} diff -urN linux-2.4.24/arch/ppc64/kernel/xics.c linux-2.4.25/arch/ppc64/kernel/xics.c --- linux-2.4.24/arch/ppc64/kernel/xics.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/xics.c 2004-02-18 05:36:30.000000000 -0800 @@ -51,7 +51,6 @@ }; #define XICS_IPI 2 -#define XICS_IRQ_OFFSET 0x10 #define XICS_IRQ_SPURIOUS 0 /* Want a priority other than 0. Various HW issues require this. */ @@ -136,17 +135,14 @@ void -xics_enable_irq( - u_int virq - ) +xics_enable_irq(u_int virq) { u_int irq; unsigned long status; long call_status; unsigned int interrupt_server = default_server; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); + irq = irq_offset_down(virq); if (irq == XICS_IPI) return; @@ -175,18 +171,14 @@ } void -xics_disable_irq( - u_int virq - ) +xics_disable_irq(u_int virq) { u_int irq; unsigned long status; long call_status; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); - call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, - irq); + irq = irq_offset_down(virq); + call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if( call_status != 0 ) { printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n", irq, call_status); @@ -195,16 +187,12 @@ } void -xics_end_irq( - u_int irq - ) +xics_end_irq(u_int irq) { int cpu = smp_processor_id(); - ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */ - iosync(); - ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET)))); iosync(); + ops->xirr_info_set(cpu, (0xff<<24) | irq_offset_down(irq)); } void @@ -212,7 +200,7 @@ { int cpu = smp_processor_id(); - if( irq < XICS_IRQ_OFFSET ) { + if (irq < irq_offset_value()) { i8259_pic.ack(irq); iosync(); ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real)); @@ -239,13 +227,13 @@ irq = i8259_irq(cpu); if(irq == -1) { /* Spurious cascaded interrupt. Still must ack xics */ - xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade); + xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); irq = -1; } } else if( vec == XICS_IRQ_SPURIOUS ) { irq = -1; } else { - irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET; + irq = irq_offset_up(vec); } return irq; } @@ -290,6 +278,15 @@ } #endif /* CONFIG_SMP */ +void xics_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &xics_pic; +} + void xics_init_IRQ( void ) { @@ -373,7 +370,7 @@ while (1); } xics_irq_8259_cascade_real = *ireg; - xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real); + xics_irq_8259_cascade = xics_irq_8259_cascade_real; } if (systemcfg->platform == PLATFORM_PSERIES) { @@ -398,36 +395,24 @@ xics_8259_pic.enable = i8259_pic.enable; xics_8259_pic.disable = i8259_pic.disable; for (i = 0; i < 16; ++i) - irq_desc[i].handler = &xics_8259_pic; - for (; i < NR_IRQS; ++i) - irq_desc[i].handler = &xics_pic; + real_irqdesc(i)->handler = &xics_8259_pic; ops->cppr_info(0, 0xff); iosync(); if (xics_irq_8259_cascade != -1) { - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) + if (request_irq(irq_offset_up(xics_irq_8259_cascade), + no_action, 0, "8259 cascade", 0)) printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); i8259_init(); } #ifdef CONFIG_SMP - real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI; - request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); - irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU; + request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, 0, "IPI", 0); + real_irqdesc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU; #endif ppc64_boot_msg(0x21, "XICS Done"); } -void xics_isa_init(void) -{ - return; - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) - printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); - i8259_init(); -} - /* * Find first logical cpu and return its physical cpu number */ @@ -445,21 +430,19 @@ return default_distrib_server; } -void xics_set_affinity(unsigned int virq, unsigned long cpumask) +void xics_set_affinity(unsigned int irq, unsigned long cpumask) { - irq_desc_t *desc = irq_desc + virq; - unsigned int irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; long status; unsigned long xics_status[2]; u32 newmask; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); + irq = irq_offset_down(irq); if (irq == XICS_IPI) return; - spin_lock_irqsave(&desc->lock, flags); + spin_lock_irqsave(&desc->lock, flags); status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq); @@ -485,5 +468,5 @@ } out: - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } diff -urN linux-2.4.24/arch/ppc64/kernel/xics.h linux-2.4.25/arch/ppc64/kernel/xics.h --- linux-2.4.24/arch/ppc64/kernel/xics.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/ppc64/kernel/xics.h 2004-02-18 05:36:30.000000000 -0800 @@ -18,7 +18,7 @@ extern struct hw_interrupt_type xics_8259_pic; void xics_init_IRQ(void); +void xics_init_irq_desc(irq_desc_t *); int xics_get_irq(struct pt_regs *); -void xics_isa_init(void); #endif /* _PPC_KERNEL_XICS_H */ diff -urN linux-2.4.24/arch/ppc64/mm/fault.c linux-2.4.25/arch/ppc64/mm/fault.c --- linux-2.4.24/arch/ppc64/mm/fault.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/ppc64/mm/fault.c 2004-02-18 05:36:30.000000000 -0800 @@ -59,6 +59,44 @@ #endif /* + * Check whether the instruction at regs->nip is a store using + * an update addressing form which will update r1. + */ +static int store_updates_sp(struct pt_regs *regs) +{ + unsigned int inst; + + if (get_user(inst, (unsigned int *)regs->nip)) + return 0; + /* check for 1 in the rA field */ + if (((inst >> 16) & 0x1f) != 1) + return 0; + /* check major opcode */ + switch (inst >> 26) { + case 37: /* stwu */ + case 39: /* stbu */ + case 45: /* sthu */ + case 53: /* stfsu */ + case 55: /* stfdu */ + return 1; + case 62: /* std or stdu */ + return (inst & 3) == 1; + case 31: + /* check minor opcode */ + switch ((inst >> 1) & 0x3ff) { + case 181: /* stdux */ + case 183: /* stwux */ + case 247: /* stbux */ + case 439: /* sthux */ + case 695: /* stfsux */ + case 759: /* stfdux */ + return 1; + } + } + return 0; +} + +/* * The error_code parameter is * - DSISR for a non-SLB data access fault, * - SRR1 & 0x08000000 for a non-SLB instruction access fault @@ -115,7 +153,39 @@ PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN); goto bad_area; } - vma = find_vma_prev(mm, address, &prev_vma); + + /* + * N.B. The POWER/Open ABI allows programs to access up to + * 288 bytes below the stack pointer. + * The kernel signal delivery code writes up to about 1.5kB + * below the stack pointer (r1) before decrementing it. + * The exec code can write slightly over 640kB to the stack + * before setting the user r1. Thus we allow the stack to + * expand to 1MB without further checks. + */ + if (address + 0x100000 < vma->vm_end) { + /* get user regs even if this fault is in kernel mode */ + struct pt_regs *uregs = current->thread.regs; + if (uregs == NULL) + goto bad_area; + + /* + * A user-mode access to an address a long way below + * the stack pointer is only valid if the instruction + * is one which would update the stack pointer to the + * address accessed if the instruction completed, + * i.e. either stwu rs,n(r1) or stwux rs,r1,rb + * (or the byte, halfword, float or double forms). + * + * If we don't check this then any write to the area + * between the last mapped region and the stack will + * expand the stack rather than segfaulting. + */ + if (address + 2048 < uregs->gpr[1] + && (!user_mode(regs) || !store_updates_sp(regs))) + goto bad_area; + } + if (expand_stack(vma, address)) { PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n"); goto bad_area; diff -urN linux-2.4.24/arch/ppc64/mm/init.c linux-2.4.25/arch/ppc64/mm/init.c --- linux-2.4.24/arch/ppc64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/ppc64/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -650,7 +651,8 @@ static struct vm_struct *get_shared_area(unsigned long size, unsigned long flags); -void *shared_malloc(unsigned long size) { +void *shared_malloc(unsigned long size) +{ pgprot_t prot; struct vm_struct *area; unsigned long ea; @@ -680,9 +682,9 @@ return(ea); } -void shared_free(void *addr) { +void shared_free(void *addr) +{ struct vm_struct **p, *tmp; - unsigned long size = 0; if (!addr) return; @@ -693,7 +695,7 @@ } spin_lock(&shared_malloc_lock); - printk("shared_free: addr = 0x%lx\n", addr); + printk("shared_free: addr = 0x%p\n", addr); /* Scan the memory list for an entry matching * the address to be freed, get the size (in bytes) @@ -715,7 +717,8 @@ } static struct vm_struct *get_shared_area(unsigned long size, - unsigned long flags) { + unsigned long flags) +{ unsigned long addr; struct vm_struct **p, *tmp, *area; @@ -755,14 +758,16 @@ return area; } -int shared_task_mark() { +int shared_task_mark(void) +{ current->thread.flags |= PPC_FLAG_SHARED; printk("current->thread.flags = 0x%lx\n", current->thread.flags); return 0; } -int shared_task_unmark() { +int shared_task_unmark() +{ if(current->thread.flags & PPC_FLAG_SHARED) { current->thread.flags &= (~PPC_FLAG_SHARED); return 0; diff -urN linux-2.4.24/arch/s390/defconfig linux-2.4.25/arch/s390/defconfig --- linux-2.4.24/arch/s390/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/s390/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -35,9 +35,11 @@ CONFIG_FAST_IRQ=y CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y +CONFIG_QDIO=m +# CONFIG_QDIO_PERF_STATS is not set CONFIG_IPL=y -CONFIG_IPL_TAPE=y -# CONFIG_IPL_VM is not set +# CONFIG_IPL_TAPE is not set +CONFIG_IPL_VM=y CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -106,8 +108,8 @@ # # S/390 tape hardware support # -CONFIG_S390_TAPE_3490=m -CONFIG_S390_TAPE_3480=m +CONFIG_S390_TAPE_3490=y +CONFIG_S390_TAPE_3480=y # # Network device drivers @@ -119,6 +121,7 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y +# CONFIG_C7000 is not set CONFIG_FDDI=y # @@ -169,6 +172,7 @@ CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set # CONFIG_IP_NF_MATCH_ECN is not set # CONFIG_IP_NF_MATCH_DSCP is not set CONFIG_IP_NF_MATCH_AH_ESP=m @@ -201,8 +205,14 @@ CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m +# CONFIG_IP_NF_ARP_MANGLE 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=m # @@ -227,8 +237,13 @@ CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_TARGET_MARK=m -CONFIG_SHARED_IPV6_CARDS=y # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -267,6 +282,7 @@ # 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 @@ -276,6 +292,7 @@ # 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 @@ -317,6 +334,11 @@ # 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 @@ -325,6 +347,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y @@ -414,9 +437,17 @@ # Kernel hacking # CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/s390/kernel/process.c linux-2.4.25/arch/s390/kernel/process.c --- linux-2.4.24/arch/s390/kernel/process.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/s390/kernel/process.c 2004-02-18 05:36:30.000000000 -0800 @@ -60,7 +60,9 @@ current->nice = 20; current->counter = -100; while (1) { + __cli(); if (current->need_resched) { + __sti(); schedule(); check_pgt_cache(); continue; diff -urN linux-2.4.24/arch/s390/kernel/s390_ksyms.c linux-2.4.25/arch/s390/kernel/s390_ksyms.c --- linux-2.4.24/arch/s390/kernel/s390_ksyms.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390/kernel/s390_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -23,6 +23,7 @@ EXPORT_SYMBOL_NOVERS(__copy_from_user_asm); EXPORT_SYMBOL_NOVERS(__copy_to_user_asm); EXPORT_SYMBOL_NOVERS(__clear_user_asm); +EXPORT_SYMBOL(diag10); /* * semaphore ops diff -urN linux-2.4.24/arch/s390/mm/init.c linux-2.4.25/arch/s390/mm/init.c --- linux-2.4.24/arch/s390/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -67,6 +67,11 @@ return freed; } +void diag10(unsigned long addr) +{ + asm volatile ("diag %0,%0,0x10" : : "a" (addr)); +} + void show_mem(void) { int i, total = 0, reserved = 0; diff -urN linux-2.4.24/arch/s390x/defconfig linux-2.4.25/arch/s390x/defconfig --- linux-2.4.24/arch/s390x/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/s390x/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -19,9 +19,9 @@ # Processor type and features # CONFIG_SMP=y +CONFIG_NR_CPUS=32 CONFIG_S390_SUPPORT=y CONFIG_BINFMT_ELF32=y -CONFIG_NR_CPUS=32 # # Loadable module support @@ -36,9 +36,11 @@ CONFIG_FAST_IRQ=y CONFIG_MACHCHK_WARNING=y CONFIG_CHSC=y +CONFIG_QDIO=m +# CONFIG_QDIO_PERF_STATS is not set CONFIG_IPL=y -CONFIG_IPL_TAPE=y -# CONFIG_IPL_VM is not set +# CONFIG_IPL_TAPE is not set +CONFIG_IPL_VM=y CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -106,8 +108,8 @@ # # S/390 tape hardware support # -CONFIG_S390_TAPE_3490=m -CONFIG_S390_TAPE_3480=m +CONFIG_S390_TAPE_3490=y +CONFIG_S390_TAPE_3480=y # # Network device drivers @@ -119,6 +121,7 @@ # CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y +# CONFIG_C7000 is not set CONFIG_FDDI=y # @@ -162,6 +165,11 @@ # 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=m # @@ -169,8 +177,13 @@ # # CONFIG_IP6_NF_QUEUE is not set # CONFIG_IP6_NF_IPTABLES is not set -CONFIG_SHARED_IPV6_CARDS=y # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set CONFIG_VLAN_8021Q=m @@ -209,6 +222,7 @@ # 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 @@ -218,6 +232,7 @@ # 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 @@ -259,6 +274,11 @@ # 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 @@ -267,6 +287,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y @@ -358,9 +379,17 @@ # Kernel hacking # CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set # # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set +# CONFIG_FW_LOADER is not set diff -urN linux-2.4.24/arch/s390x/kernel/head.S linux-2.4.25/arch/s390x/kernel/head.S --- linux-2.4.24/arch/s390x/kernel/head.S 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390x/kernel/head.S 2004-02-18 05:36:30.000000000 -0800 @@ -553,6 +553,10 @@ bne 1f-.LPG1(%r13) oi 7(%r12),4 # set P/390 flag 1: + chi %r0,0x2084 # new stidp format? + bne 2f-.LPG1(%r13) + oi 7(%r12),64 # set new stidp flag +2: # # find out if we have the MVPG instruction diff -urN linux-2.4.24/arch/s390x/kernel/linux32.c linux-2.4.25/arch/s390x/kernel/linux32.c --- linux-2.4.24/arch/s390x/kernel/linux32.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390x/kernel/linux32.c 2004-02-18 05:36:30.000000000 -0800 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -1873,7 +1874,11 @@ u32 totalswap; u32 freeswap; unsigned short procs; - char _f[22]; + unsigned short pad; + u32 totalhigh; + u32 freehigh; + unsigned int mem_unit; + char _f[8]; }; extern asmlinkage int sys_sysinfo(struct sysinfo *info); @@ -1898,6 +1903,9 @@ err |= __put_user (s.totalswap, &info->totalswap); err |= __put_user (s.freeswap, &info->freeswap); err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); if (err) return -EFAULT; return ret; diff -urN linux-2.4.24/arch/s390x/kernel/process.c linux-2.4.25/arch/s390x/kernel/process.c --- linux-2.4.24/arch/s390x/kernel/process.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/s390x/kernel/process.c 2004-02-18 05:36:30.000000000 -0800 @@ -60,7 +60,9 @@ current->nice = 20; current->counter = -100; while (1) { + __cli(); if (current->need_resched) { + __sti(); schedule(); check_pgt_cache(); continue; diff -urN linux-2.4.24/arch/s390x/kernel/s390_ksyms.c linux-2.4.25/arch/s390x/kernel/s390_ksyms.c --- linux-2.4.24/arch/s390x/kernel/s390_ksyms.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390x/kernel/s390_ksyms.c 2004-02-18 05:36:30.000000000 -0800 @@ -13,6 +13,7 @@ #include #include #include +#include #if CONFIG_IP_MULTICAST #include #endif @@ -26,6 +27,7 @@ EXPORT_SYMBOL_NOVERS(__copy_from_user_asm); EXPORT_SYMBOL_NOVERS(__copy_to_user_asm); EXPORT_SYMBOL_NOVERS(__clear_user_asm); +EXPORT_SYMBOL(diag10); /* * semaphore ops @@ -66,14 +68,9 @@ /* * Dynamically add/remove 31 bit ioctl conversion functions. */ -extern int register_ioctl32_conversion(unsigned int cmd, - int (*handler)(unsigned int, - unsigned int, - unsigned long, - struct file *)); -int unregister_ioctl32_conversion(unsigned int cmd); EXPORT_SYMBOL(register_ioctl32_conversion); EXPORT_SYMBOL(unregister_ioctl32_conversion); +EXPORT_SYMBOL(sys_ioctl); #endif /* diff -urN linux-2.4.24/arch/s390x/mm/init.c linux-2.4.25/arch/s390x/mm/init.c --- linux-2.4.24/arch/s390x/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/s390x/mm/init.c 2004-02-18 05:36:30.000000000 -0800 @@ -170,6 +170,15 @@ return freed; } +void diag10(unsigned long addr) +{ + if (addr >= 0x80000000) + return; + asm volatile ("sam31\n\t" + "diag %0,%0,0x10\n\t" + "sam64" : : "a" (addr) ); +} + void show_mem(void) { int i, total = 0,reserved = 0; diff -urN linux-2.4.24/arch/sh/config.in linux-2.4.25/arch/sh/config.in --- linux-2.4.24/arch/sh/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sh/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -285,6 +285,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER + source drivers/parport/Config.in endmenu @@ -307,7 +309,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/sh/defconfig linux-2.4.25/arch/sh/defconfig --- linux-2.4.24/arch/sh/defconfig 2001-10-15 13:36:48.000000000 -0700 +++ linux-2.4.25/arch/sh/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -121,7 +121,6 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff -urN linux-2.4.24/arch/sh/kernel/entry.S linux-2.4.25/arch/sh/kernel/entry.S --- linux-2.4.24/arch/sh/kernel/entry.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sh/kernel/entry.S 2004-02-18 05:36:30.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.1.1.1.2.18 2003/10/23 22:08:56 yoshii Exp $ +/* $Id: entry.S,v 1.1.1.1.2.19 2003/11/26 21:28:28 kkojima Exp $ * * linux/arch/sh/entry.S * @@ -560,7 +560,6 @@ ldc.l @r15+, gbr lds.l @r15+, mach lds.l @r15+, macl - add #4, r15 ! skip placeholder #ifdef CONFIG_SH_DSP mov.l @r15+, k0 ! DSP mode marker @@ -751,7 +750,6 @@ ! Save the user registers on the stack. mov.l k2, @-r15 ! EXPEVT - add #-4, r15 ! placeholder ! sts.l macl, @-r15 sts.l mach, @-r15 diff -urN linux-2.4.24/arch/sh64/config.in linux-2.4.25/arch/sh64/config.in --- linux-2.4.24/arch/sh64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sh64/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -155,6 +155,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER + # source drivers/parport/Config.in endmenu @@ -175,7 +177,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/sh64/defconfig linux-2.4.25/arch/sh64/defconfig --- linux-2.4.24/arch/sh64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sh64/defconfig 2004-02-18 05:36:30.000000000 -0800 @@ -171,7 +171,6 @@ # ATA/IDE/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # diff -urN linux-2.4.24/arch/sh64/kernel/Makefile linux-2.4.25/arch/sh64/kernel/Makefile --- linux-2.4.24/arch/sh64/kernel/Makefile 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/sh64/kernel/Makefile 2004-02-18 05:36:30.000000000 -0800 @@ -29,7 +29,7 @@ obj-$(CONFIG_SH_DMA) += dma.o -export-objs := sh_ksyms.o +export-objs := sh_ksyms.o dma.o ifndef CONFIG_NOFPU_SUPPORT obj-y += fpu.o diff -urN linux-2.4.24/arch/sh64/kernel/time.c linux-2.4.25/arch/sh64/kernel/time.c --- linux-2.4.24/arch/sh64/kernel/time.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/sh64/kernel/time.c 2004-02-18 05:36:30.000000000 -0800 @@ -113,7 +113,8 @@ extern unsigned long wall_jiffies; extern unsigned long volatile jiffies; -static unsigned long tmu_base, rtc_base, cprc_base; +static unsigned long tmu_base, rtc_base; +unsigned long cprc_base; /* Variables to allow interpolation of time of day to resolution better than a * jiffy. */ diff -urN linux-2.4.24/arch/sparc/config.in linux-2.4.25/arch/sparc/config.in --- linux-2.4.24/arch/sparc/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc/config.in 2004-02-18 05:36:30.000000000 -0800 @@ -76,6 +76,7 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC bool 'SunOS binary emulation' CONFIG_SUNOS_EMUL +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/parport/Config.in dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT endmenu @@ -126,14 +127,12 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu else define_bool CONFIG_IDE n - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi diff -urN linux-2.4.24/arch/sparc/defconfig linux-2.4.25/arch/sparc/defconfig --- linux-2.4.24/arch/sparc/defconfig 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/sparc/defconfig 2004-02-18 05:36:31.000000000 -0800 @@ -53,6 +53,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_SUNOS_EMUL=y +# CONFIG_OOM_KILLER is not set # # Parallel port support @@ -154,6 +155,15 @@ # CONFIG_SYN_COOKIES is not set CONFIG_IPV6=m # CONFIG_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_ADLER32 is not set +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -191,7 +201,6 @@ # CONFIG_NET_PKTGEN=m # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -279,6 +288,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m # CONFIG_REISERFS_FS is not set @@ -288,6 +298,9 @@ # CONFIG_ADFS_FS_RW is not set CONFIG_AFFS_FS=m # CONFIG_HFS_FS is not set +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set CONFIG_EXT3_FS=m CONFIG_JBD=m @@ -305,6 +318,9 @@ CONFIG_ISO9660_FS=m # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set CONFIG_MINIX_FS=m # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -324,6 +340,11 @@ # CONFIG_UDF_RW is not set CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -332,9 +353,11 @@ CONFIG_INTERMEZZO_FS=m CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set +CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m @@ -349,7 +372,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -415,4 +437,17 @@ # # Kernel hacking # -# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.24/arch/sparc/kernel/devices.c linux-2.4.25/arch/sparc/kernel/devices.c --- linux-2.4.24/arch/sparc/kernel/devices.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc/kernel/devices.c 2004-02-18 05:36:31.000000000 -0800 @@ -72,7 +72,7 @@ if (linux_num_cpus == 0) { printk("No CPU nodes found, cannot continue.\n"); /* Probably a sun4e, Sun is trying to trick us ;-) */ - halt(); + prom_halt(); } printk("Found %d CPU prom device tree node(s).\n", linux_num_cpus); } diff -urN linux-2.4.24/arch/sparc/kernel/ioport.c linux-2.4.25/arch/sparc/kernel/ioport.c --- linux-2.4.24/arch/sparc/kernel/ioport.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/sparc/kernel/ioport.c 2004-02-18 05:36:31.000000000 -0800 @@ -760,7 +760,7 @@ default: printk("ioport_init: cpu type %d is unknown.\n", sparc_cpu_model); - halt(); + prom_halt(); }; } diff -urN linux-2.4.24/arch/sparc64/config.in linux-2.4.25/arch/sparc64/config.in --- linux-2.4.24/arch/sparc64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/config.in 2004-02-18 05:36:31.000000000 -0800 @@ -82,6 +82,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Solaris binary emulation (EXPERIMENTAL)' CONFIG_SOLARIS_EMUL fi +bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER source drivers/parport/Config.in dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT if [ "$CONFIG_PCI" = "y" ]; then @@ -131,7 +132,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu @@ -305,6 +305,7 @@ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE bool ' D-cache flush debugging' CONFIG_DEBUG_DCFLUSH + bool ' Debug BOOTMEM initialization' CONFIG_DEBUG_BOOTMEM fi bool 'Stack Overflow Detection Support' CONFIG_STACK_DEBUG if [ "$CONFIG_STACK_DEBUG" = "y" ] ; then diff -urN linux-2.4.24/arch/sparc64/defconfig linux-2.4.25/arch/sparc64/defconfig --- linux-2.4.24/arch/sparc64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/defconfig 2004-02-18 05:36:31.000000000 -0800 @@ -59,6 +59,7 @@ CONFIG_BINFMT_MISC=m # CONFIG_SUNOS_EMUL is not set CONFIG_SOLARIS_EMUL=m +# CONFIG_OOM_KILLER is not set # # Parallel port support @@ -74,6 +75,7 @@ # CONFIG_PARPORT_ATARI is not set # CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_IP22 is not set # CONFIG_PARPORT_OTHER is not set CONFIG_PARPORT_1284=y CONFIG_PRINTER=m @@ -448,7 +450,6 @@ # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y CONFIG_BLK_DEV_ATARAID=m CONFIG_BLK_DEV_ATARAID_PDC=m CONFIG_BLK_DEV_ATARAID_HPT=m @@ -717,6 +718,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_UINPUT=m # # File systems @@ -774,6 +776,11 @@ CONFIG_UDF_RW=y CONFIG_UFS_FS=m CONFIG_UFS_FS_WRITE=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set # # Network File Systems @@ -955,6 +962,7 @@ CONFIG_USB_PWC=m CONFIG_USB_SE401=m CONFIG_USB_STV680=m +# CONFIG_USB_W9968CF is not set CONFIG_USB_VICAM=m CONFIG_USB_DSBR=m CONFIG_USB_DABUSB=m @@ -1030,6 +1038,7 @@ # # USB Peripheral Controller Drivers # +# CONFIG_USB_GADGET_CONTROLLER is not set # CONFIG_USB_NET2280 is not set # CONFIG_USB_GADGET_CONTROLLER is not set @@ -1049,8 +1058,7 @@ # Bluetooth device drivers # CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_SCO=y -CONFIG_BLUEZ_USB_ZERO_PACKET=y +CONFIG_BLUEZ_HCIUSB_SCO=y CONFIG_BLUEZ_HCIUART=m CONFIG_BLUEZ_HCIUART_H4=y CONFIG_BLUEZ_HCIUART_BCSP=y diff -urN linux-2.4.24/arch/sparc64/kernel/ebus.c linux-2.4.25/arch/sparc64/kernel/ebus.c --- linux-2.4.24/arch/sparc64/kernel/ebus.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.25/arch/sparc64/kernel/ebus.c 2004-02-18 05:36:31.000000000 -0800 @@ -177,7 +177,8 @@ static int __init child_regs_nonstandard(struct linux_ebus_device *dev) { - if (!strcmp(dev->prom_name, "i2c")) + if (!strcmp(dev->prom_name, "i2c") || + !strcmp(dev->prom_name, "SUNW,lombus")) return 1; return 0; } diff -urN linux-2.4.24/arch/sparc64/kernel/head.S linux-2.4.25/arch/sparc64/kernel/head.S --- linux-2.4.24/arch/sparc64/kernel/head.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/head.S 2004-02-18 05:36:31.000000000 -0800 @@ -54,7 +54,15 @@ .ascii "HdrS" .word LINUX_VERSION_CODE - .half 0x0203 /* HdrS version */ + + /* History: + * + * 0x0300 : Supports being located at other than 0x4000 + * 0x0202 : Supports kernel params string + * 0x0201 : Supports reboot_command + */ + .half 0x0300 /* HdrS version */ + root_flags: .half 1 root_dev: @@ -151,12 +159,31 @@ blu,pt %xcc, 1b add %l0, (1 << 3), %l0 + /* Search the small TLB. OBP never maps us like that but + * newer SILO can. + */ + clr %l0 + +1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 + membar #Sync + andn %g1, %l2, %g1 + cmp %g1, %g2 + be,pn %xcc, cheetah_got_tlbentry + nop + cmp %l0, (15 << 3) + blu,pt %xcc, 1b + add %l0, (1 << 3), %l0 + + /* BUG() if we get here... */ + ta 0x5 + cheetah_got_tlbentry: ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0 ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 membar #Sync and %g1, %g3, %g1 - sub %g1, %g2, %g1 + set 0x5fff, %l0 + andn %g1, %l0, %g1 or %g5, %g1, %g5 /* Clear out any KERNBASE area entries. */ @@ -333,13 +360,17 @@ blu,pt %xcc, 1b add %l0, (1 << 3), %l0 + /* BUG() if we get here... */ + ta 0x5 + spitfire_got_tlbentry: /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ nop nop nop and %g1, %g3, %g1 /* Mask to just get paddr bits. */ - sub %g1, %g2, %g1 /* Get rid of %pc offset to get base. */ + set 0x5fff, %l3 /* Mask offset to get phys base. */ + andn %g1, %l3, %g1 /* NOTE: We hold on to %g1 paddr base as we need it below to lock * NOTE: the PROM cif code into the TLB. diff -urN linux-2.4.24/arch/sparc64/kernel/ioctl32.c linux-2.4.25/arch/sparc64/kernel/ioctl32.c --- linux-2.4.24/arch/sparc64/kernel/ioctl32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/ioctl32.c 2004-02-18 05:36:31.000000000 -0800 @@ -4524,7 +4524,6 @@ /* Big T */ COMPATIBLE_IOCTL(TUNSETNOCSUM) COMPATIBLE_IOCTL(TUNSETDEBUG) -COMPATIBLE_IOCTL(TUNSETIFF) COMPATIBLE_IOCTL(TUNSETPERSIST) COMPATIBLE_IOCTL(TUNSETOWNER) /* Big V */ @@ -5146,6 +5145,7 @@ HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) +HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) diff -urN linux-2.4.24/arch/sparc64/kernel/pci_common.c linux-2.4.25/arch/sparc64/kernel/pci_common.c --- linux-2.4.24/arch/sparc64/kernel/pci_common.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/pci_common.c 2004-02-18 05:36:31.000000000 -0800 @@ -317,14 +317,23 @@ { struct resource *res; int breg = (ap->phys_hi & 0xff); - int space = (ap->phys_hi >> 24) & 3; switch (breg) { case PCI_ROM_ADDRESS: + /* Unfortunately I have seen several cases where + * buggy FCODE uses a space value of '1' (I/O space) + * in the register property for the ROM address + * so disable this sanity check for now. + */ +#if 0 + { + int space = (ap->phys_hi >> 24) & 3; + /* It had better be MEM space. */ if (space != 2) bad_assignment(pdev, ap, NULL, 0); - + } +#endif res = &pdev->resource[PCI_ROM_RESOURCE]; break; diff -urN linux-2.4.24/arch/sparc64/kernel/pci_sabre.c linux-2.4.25/arch/sparc64/kernel/pci_sabre.c --- linux-2.4.24/arch/sparc64/kernel/pci_sabre.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/pci_sabre.c 2004-02-18 05:36:31.000000000 -0800 @@ -325,16 +325,22 @@ return PCIBIOS_SUCCESSFUL; } +/* When accessing PCI config space of the PCI controller itself (bus + * 0, device slot 0, function 0) there are restrictions. Each + * register must be accessed as it's natural size. Thus, for example + * the Vendor ID must be accessed as a 16-bit quantity. + */ + static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value) { - if (dev->bus->number) - return __sabre_read_byte(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_byte(dev, where, value); + if (where < 8) { u16 tmp; @@ -350,14 +356,14 @@ static int sabre_read_word(struct pci_dev *dev, int where, u16 *value) { - if (dev->bus->number) - return __sabre_read_word(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xffff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_word(dev, where, value); + if (where < 8) return __sabre_read_word(dev, where, value); else { @@ -375,14 +381,14 @@ { u16 tmp; - if (dev->bus->number) - return __sabre_read_dword(dev, where, value); - - if (sabre_out_of_range(dev->devfn)) { + if (!dev->bus->number && sabre_out_of_range(dev->devfn)) { *value = 0xffffffff; return PCIBIOS_SUCCESSFUL; } + if (dev->bus->number || PCI_SLOT(dev->devfn)) + return __sabre_read_dword(dev, where, value); + sabre_read_word(dev, where, &tmp); *value = tmp; sabre_read_word(dev, where + 2, &tmp); diff -urN linux-2.4.24/arch/sparc64/kernel/setup.c linux-2.4.25/arch/sparc64/kernel/setup.c --- linux-2.4.24/arch/sparc64/kernel/setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/setup.c 2004-02-18 05:36:31.000000000 -0800 @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef CONFIG_IP_PNP #include @@ -456,7 +457,7 @@ char saved_command_line[256]; char reboot_command[256]; -extern unsigned long phys_base; +extern unsigned long phys_base, kern_base, kern_size; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; @@ -527,6 +528,22 @@ highest_paddr = top; } + switch (tlb_type) { + default: + case spitfire: + kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent()); + kern_base &= _PAGE_PADDR_SF; + break; + + case cheetah: + case cheetah_plus: + kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); + kern_base &= _PAGE_PADDR; + break; + }; + + kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; + if (!root_flags) root_mountflags &= ~MS_RDONLY; ROOT_DEV = to_kdev_t(root_dev); diff -urN linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c linux-2.4.25/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.24/arch/sparc64/kernel/sys_sparc32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/sparc64/kernel/sys_sparc32.c 2004-02-18 05:36:31.000000000 -0800 @@ -4454,6 +4454,9 @@ extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) { +#ifndef CONFIG_SYSCTL + return -ENOSYS; +#else struct __sysctl_args32 tmp; int error; size_t oldlen, *oldlenp = NULL; @@ -4488,4 +4491,5 @@ copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } return error; +#endif } diff -urN linux-2.4.24/arch/sparc64/lib/VIScopy.S linux-2.4.25/arch/sparc64/lib/VIScopy.S --- linux-2.4.24/arch/sparc64/lib/VIScopy.S 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/arch/sparc64/lib/VIScopy.S 2004-02-18 05:36:31.000000000 -0800 @@ -120,7 +120,6 @@ #define EXVIS2(x,y) EXVISN(x,y,2) #define EXVIS3(x,y) EXVISN(x,y,3) #define EXVIS4(x,y) EXVISN(x,y,4) -#define EXVIS5(x,y) EXVISN(x,y,5) #define FREG_FROB(f1, f2, f3, f4, f5, f6, f7, f8, f9) \ faligndata %f1, %f2, %f48; \ @@ -135,7 +134,7 @@ #define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \ EXVIS(LDBLK [%src] ASIBLK, %fdest); \ ASI_SETDST_BLK \ - EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS(STBLK %fsrc, [%dest] ASIBLK); \ add %src, 0x40, %src; \ subcc %len, 0x40, %len; \ be,pn %xcc, jmptgt; \ @@ -156,14 +155,14 @@ #ifdef __KERNEL__ #define STORE_JUMP(dest, fsrc, target) \ srl asi_dest, 3, %g5; \ - EXVIS3(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ xor asi_dest, ASI_BLK_XOR1, asi_dest;\ add %dest, 0x40, %dest; \ xor asi_dest, %g5, asi_dest; \ ba,pt %xcc, target; #else #define STORE_JUMP(dest, fsrc, target) \ - EXVIS3(STBLK %fsrc, [%dest] ASIBLK); \ + EXVIS2(STBLK %fsrc, [%dest] ASIBLK); \ add %dest, 0x40, %dest; \ ba,pt %xcc, target; #endif @@ -182,7 +181,7 @@ subcc %left, 8, %left; \ bl,pn %xcc, vis_out; \ faligndata %f0, %f1, %f48; \ - EXVIS4(STDF %f48, [%dest] ASINORMAL); \ + EXVIS3(STDF %f48, [%dest] ASINORMAL); \ add %dest, 8, %dest; #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ @@ -675,21 +674,21 @@ xor asi_src, %g5, asi_src ! IEU0 Group #endif vis_slk:ASI_SETSRC_NOBLK ! LSU Group - EXVIS4(LDDF [%o1] ASINORMAL, %f2) ! Load Group + EXVIS3(LDDF [%o1] ASINORMAL, %f2) ! Load Group add %o1, 8, %o1 ! IEU0 subcc %g3, 8, %g3 ! IEU1 ASI_SETDST_NOBLK ! LSU Group faligndata %f0, %f2, %f8 ! GRU Group - EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store + EXVIS4(STDF %f8, [%o0] ASINORMAL) ! Store bl,pn %xcc, vis_out_slp ! CTI add %o0, 8, %o0 ! IEU0 Group ASI_SETSRC_NOBLK ! LSU Group - EXVIS4(LDDF [%o1] ASINORMAL, %f0) ! Load Group + EXVIS3(LDDF [%o1] ASINORMAL, %f0) ! Load Group add %o1, 8, %o1 ! IEU0 subcc %g3, 8, %g3 ! IEU1 ASI_SETDST_NOBLK ! LSU Group faligndata %f2, %f0, %f8 ! GRU Group - EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store + EXVIS4(STDF %f8, [%o0] ASINORMAL) ! Store bge,pt %xcc, vis_slk ! CTI add %o0, 8, %o0 ! IEU0 Group vis_out_slp: @@ -1138,20 +1137,18 @@ sub %g7, %g2, %g7 ba,pt %xcc, VIScopyfixup_ret add %g7, %o2, %o1 -VIScopyfixup_vis3: - sub %o2, 0x80, %o2 VIScopyfixup_vis2: - add %o2, 0x40, %o2 + sub %o2, 0x40, %o2 VIScopyfixup_vis0: add %o2, 0x80, %o2 VIScopyfixup_vis1: add %g7, %g3, %g7 ba,pt %xcc, VIScopyfixup_ret add %o2, %g7, %o1 -VIScopyfixup_vis5: - add %g3, 8, %g3 VIScopyfixup_vis4: add %g3, 8, %g3 +VIScopyfixup_vis3: + add %g3, 8, %g3 ba,pt %xcc, VIScopyfixup_ret add %o2, %g3, %o1 #endif diff -urN linux-2.4.24/arch/sparc64/mm/init.c linux-2.4.25/arch/sparc64/mm/init.c --- linux-2.4.24/arch/sparc64/mm/init.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/arch/sparc64/mm/init.c 2004-02-18 05:36:31.000000000 -0800 @@ -34,6 +34,7 @@ #include #include #include +#include mmu_gather_t mmu_gathers[NR_CPUS]; @@ -44,7 +45,16 @@ unsigned long *sparc64_valid_addr_bitmap; /* Ugly, but necessary... -DaveM */ -unsigned long phys_base; +unsigned long phys_base, kern_base, kern_size; + +/* This is even uglier. We have a problem where the kernel may not be + * located at phys_base. However, initial __alloc_bootmem() calls need to + * be adjusted to be within the 4-8Megs that the kernel is mapped to, else + * those page mappings wont work. Things are ok after inherit_prom_mappings + * is called though. Dave says he'll clean this up some other time. + * -- BenC + */ +static unsigned long bootmap_base; /* get_new_mmu_context() uses "cache + 1". */ spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED; @@ -52,9 +62,6 @@ #define CTX_BMAP_SLOTS (1UL << (CTX_VERSION_SHIFT - 6)) unsigned long mmu_context_bmap[CTX_BMAP_SLOTS]; -/* References to section boundaries */ -extern char __init_begin, __init_end, _start, _end, etext, edata; - /* Initial ramdisk setup */ extern unsigned int sparc_ramdisk_image; extern unsigned int sparc_ramdisk_size; @@ -344,7 +351,7 @@ n += 5 * sizeof(struct linux_prom_translation); for (tsz = 1; tsz < n; tsz <<= 1) /* empty */; - trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, 0UL); + trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base); if (trans == NULL) { prom_printf("inherit_prom_mappings: Cannot alloc translations.\n"); prom_halt(); @@ -364,7 +371,7 @@ * in inherit_locked_prom_mappings()). */ #define OBP_PMD_SIZE 2048 - prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, 0UL); + prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base); if (prompmd == NULL) early_pgtable_allocfail("pmd"); memset(prompmd, 0, OBP_PMD_SIZE); @@ -382,7 +389,7 @@ if (pmd_none(*pmdp)) { ptep = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE, - 0UL); + bootmap_base); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(ptep, 0, BASE_PAGE_SIZE); @@ -1202,6 +1209,10 @@ unsigned long bootmap_pfn, bytes_avail, size; int i; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("bootmem_init: Scan sp_banks, "); +#endif + bytes_avail = 0UL; for (i = 0; sp_banks[i].num_bytes != 0; i++) { end_of_phys_memory = sp_banks[i].base_addr + @@ -1232,15 +1243,8 @@ * image. The kernel is hard mapped below PAGE_OFFSET in a * 4MB locked TLB translation. */ - start_pfn = PAGE_ALIGN((unsigned long) &_end) - - ((unsigned long) KERNBASE); + start_pfn = PAGE_ALIGN(kern_base + kern_size) >> PAGE_SHIFT; - /* Adjust up to the physical address where the kernel begins. */ - start_pfn += phys_base; - - /* Now shift down to get the real physical page frame number. */ - start_pfn >>= PAGE_SHIFT; - bootmap_pfn = start_pfn; end_pfn = end_of_phys_memory >> PAGE_SHIFT; @@ -1268,19 +1272,33 @@ /* Initialize the boot-time allocator. */ max_pfn = max_low_pfn = end_pfn; min_low_pfn = phys_base >> PAGE_SHIFT; - bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn); + +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n", + min_low_pfn, bootmap_pfn, max_low_pfn); +#endif + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, min_low_pfn, end_pfn); + + bootmap_base = bootmap_pfn << PAGE_SHIFT; /* Now register the available physical memory with the * allocator. */ - for (i = 0; sp_banks[i].num_bytes != 0; i++) - free_bootmem(sp_banks[i].base_addr, - sp_banks[i].num_bytes); + for (i = 0; sp_banks[i].num_bytes != 0; i++) { +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("free_bootmem(sp_banks:%d): base[%lx] size[%lx]\n", + i, sp_banks[i].base_addr, sp_banks[i].num_bytes); +#endif + free_bootmem(sp_banks[i].base_addr, sp_banks[i].num_bytes); + } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { size = initrd_end - initrd_start; - +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(initrd): base[%lx] size[%lx]\n", + initrd_start, size); +#endif /* Resert the initrd image area. */ reserve_bootmem(initrd_start, size); *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -1290,15 +1308,21 @@ } #endif /* Reserve the kernel text/data/bss. */ - size = (start_pfn << PAGE_SHIFT) - phys_base; - reserve_bootmem(phys_base, size); - *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size); +#endif + reserve_bootmem(kern_base, kern_size); + *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT; /* Reserve the bootmem map. We do not account for it * in pages_avail because we will release that memory * in free_all_bootmem. */ size = bootmap_size; +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n", + (bootmap_pfn << PAGE_SHIFT), size); +#endif reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size); *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -1317,7 +1341,7 @@ extern pmd_t swapper_pmd_dir[1024]; extern unsigned int sparc64_vpte_patchme1[1]; extern unsigned int sparc64_vpte_patchme2[1]; - unsigned long alias_base = phys_base + PAGE_OFFSET; + unsigned long alias_base = kern_base + PAGE_OFFSET; unsigned long second_alias_page = 0; unsigned long pt, flags, end_pfn, pages_avail; unsigned long shift = alias_base - ((unsigned long)KERNBASE); @@ -1337,7 +1361,7 @@ * if this were not true we wouldn't boot up to this point * anyways. */ - pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB; + pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB; pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; __save_and_cli(flags); if (tlb_type == spitfire) { @@ -1417,14 +1441,6 @@ pages_avail = 0; last_valid_pfn = end_pfn = bootmem_init(&pages_avail); -#ifdef CONFIG_SUN_SERIAL - /* This does not logically belong here, but we need to - * call it at the moment we are able to use the bootmem - * allocator. - */ - sun_serial_setup(); -#endif - /* Inherit non-locked OBP mappings. */ inherit_prom_mappings(); @@ -1439,7 +1455,16 @@ } inherit_locked_prom_mappings(1); - + +#ifdef CONFIG_SUN_SERIAL + /* This does not logically belong here, but we need to call it at + * the moment we are able to use the bootmem allocator. This _has_ + * to be done after the prom_mappings above so since + * __alloc_bootmem() doesn't work correctly until then. + */ + sun_serial_setup(); +#endif + /* We only created DTLB mapping of this stuff. */ spitfire_flush_dtlb_nucleus_page(alias_base); if (second_alias_page) @@ -1609,17 +1634,15 @@ i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); i += 1; sparc64_valid_addr_bitmap = (unsigned long *) - __alloc_bootmem(i << 3, SMP_CACHE_BYTES, 0UL); + __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base); if (sparc64_valid_addr_bitmap == NULL) { prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); prom_halt(); } memset(sparc64_valid_addr_bitmap, 0, i << 3); - addr = PAGE_OFFSET + phys_base; - last = PAGE_ALIGN((unsigned long)&_end) - - ((unsigned long) KERNBASE); - last += PAGE_OFFSET + phys_base; + addr = PAGE_OFFSET + kern_base; + last = PAGE_ALIGN(kern_size) + addr; while (addr < last) { set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap); addr += PAGE_SIZE; @@ -1630,6 +1653,9 @@ max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT); high_memory = __va(last_valid_pfn << PAGE_SHIFT); +#ifdef CONFIG_DEBUG_BOOTMEM + prom_printf("mem_init: Calling free_all_bootmem().\n"); +#endif num_physpages = free_all_bootmem() - 1; /* @@ -1656,7 +1682,7 @@ /* Put empty_pg_dir on pgd_quicklist */ extern pgd_t empty_pg_dir[1024]; unsigned long addr = (unsigned long)empty_pg_dir; - unsigned long alias_base = phys_base + PAGE_OFFSET - + unsigned long alias_base = kern_base + PAGE_OFFSET - (long)(KERNBASE); memset(empty_pg_dir, 0, sizeof(empty_pg_dir)); @@ -1691,7 +1717,7 @@ struct page *p; page = (addr + - ((unsigned long) __va(phys_base)) - + ((unsigned long) __va(kern_base)) - ((unsigned long) KERNBASE)); p = virt_to_page(page); diff -urN linux-2.4.24/arch/x86_64/config.in linux-2.4.25/arch/x86_64/config.in --- linux-2.4.24/arch/x86_64/config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/config.in 2004-02-18 05:36:31.000000000 -0800 @@ -70,10 +70,12 @@ fi bool 'Machine check support' CONFIG_MCE -bool 'K8 NUMA support' CONFIG_K8_NUMA -if [ "$CONFIG_K8_NUMA" = "y" ]; then +if [ "$CONFIG_SMP" = "y" ]; then + bool 'K8 NUMA support' CONFIG_K8_NUMA + if [ "$CONFIG_K8_NUMA" = "y" ]; then define_bool CONFIG_DISCONTIGMEM y define_bool CONFIG_NUMA y + fi fi endmenu @@ -139,7 +141,6 @@ if [ "$CONFIG_IDE" != "n" ]; then source drivers/ide/Config.in else - define_bool CONFIG_BLK_DEV_IDE_MODES n define_bool CONFIG_BLK_DEV_HD n fi endmenu diff -urN linux-2.4.24/arch/x86_64/defconfig linux-2.4.25/arch/x86_64/defconfig --- linux-2.4.24/arch/x86_64/defconfig 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/defconfig 2004-02-18 05:36:31.000000000 -0800 @@ -272,7 +272,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set @@ -477,6 +476,7 @@ # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set # # Character devices @@ -528,6 +528,7 @@ # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set # CONFIG_SCx200_GPIO is not set # CONFIG_AMD_RNG is not set # CONFIG_INTEL_RNG is not set @@ -560,6 +561,7 @@ # # CONFIG_DRM is not set # CONFIG_MWAVE is not set +# CONFIG_OBMOUSE is not set # # Multimedia devices @@ -620,6 +622,11 @@ # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set # CONFIG_SIMICSFS 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 diff -urN linux-2.4.24/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.25/arch/x86_64/ia32/ia32_ioctl.c --- linux-2.4.24/arch/x86_64/ia32/ia32_ioctl.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/ia32/ia32_ioctl.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,4 +1,4 @@ -/* $Id: ia32_ioctl.c,v 1.37 2003/08/20 11:00:23 ak Exp $ +/* $Id: ia32_ioctl.c,v 1.39 2004/01/29 03:01:57 ak Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) @@ -112,10 +113,16 @@ #include - #define A(__x) ((void *)(unsigned long)(__x)) #define AA(__x) A(__x) +/* Allocate memory on the user stack */ +static __inline__ void *compat_alloc_user_space(long len) +{ + struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); + return (void *)regs->rsp - len; +} + /* Aiee. Someone does not find a difference between int and long */ #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) @@ -2917,7 +2924,7 @@ return ret; case RTC_IRQP_SET32: - cmd = RTC_EPOCH_SET; + cmd = RTC_IRQP_SET; break; case RTC_EPOCH_READ32: @@ -3484,6 +3491,50 @@ return err; } + +struct compat_iw_point { + __u32 pointer; + __u16 length; + __u16 flags; +}; + +static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct iwreq *iwr, *iwr_u; + struct iw_point *iwp; + struct compat_iw_point *iwp_u; + __u32 pointer; + __u16 length, flags; + + iwr_u = (struct iwreq *) (u64)arg; + iwp_u = (struct compat_iw_point *) &iwr_u->u.data; + iwr = compat_alloc_user_space(sizeof(*iwr)); + if (iwr == NULL) + return -ENOMEM; + + iwp = &iwr->u.data; + + if (verify_area(VERIFY_WRITE, iwr, sizeof(*iwr))) + return -EFAULT; + + if (__copy_in_user(&iwr->ifr_ifrn.ifrn_name[0], + &iwr_u->ifr_ifrn.ifrn_name[0], + sizeof(iwr->ifr_ifrn.ifrn_name))) + return -EFAULT; + + if (__get_user(pointer, &iwp_u->pointer) || + __get_user(length, &iwp_u->length) || + __get_user(flags, &iwp_u->flags)) + return -EFAULT; + + if (__put_user((u64)pointer, &iwp->pointer) || + __put_user(length, &iwp->length) || + __put_user(flags, &iwp->flags)) + return -EFAULT; + + return sys_ioctl(fd, cmd, (unsigned long) iwr); +} + struct ioctl_trans { unsigned long cmd; int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); @@ -4357,6 +4408,21 @@ HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32) HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32) HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32) +/* wireless */ +HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) +COMPATIBLE_IOCTL(SIOCGIWNAME) IOCTL_TABLE_END #define IOCTL_HASHSIZE 256 diff -urN linux-2.4.24/arch/x86_64/ia32/ia32entry.S linux-2.4.25/arch/x86_64/ia32/ia32entry.S --- linux-2.4.24/arch/x86_64/ia32/ia32entry.S 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/ia32/ia32entry.S 2004-02-18 05:36:31.000000000 -0800 @@ -3,7 +3,7 @@ * * Copyright 2000,2001 Andi Kleen, SuSE Labs. * - * $Id: ia32entry.S,v 1.41 2003/09/22 04:25:53 ak Exp $ + * $Id: ia32entry.S,v 1.42 2003/11/27 00:55:43 ak Exp $ */ #include diff -urN linux-2.4.24/arch/x86_64/ia32/ptrace32.c linux-2.4.25/arch/x86_64/ia32/ptrace32.c --- linux-2.4.24/arch/x86_64/ia32/ptrace32.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/arch/x86_64/ia32/ptrace32.c 2004-02-18 05:36:31.000000000 -0800 @@ -8,7 +8,7 @@ * This allows to access 64bit processes too; but there is no way to see the extended * register contents. * - * $Id: ptrace32.c,v 1.17 2003/03/24 09:25:15 ak Exp $ + * $Id: ptrace32.c,v 1.18 2004/01/29 00:50:29 ak Exp $ */ #include @@ -25,6 +25,10 @@ #include #include +/* determines which flags the user has access to. */ +/* 1 = access 0 = no access */ +#define FLAG_MASK 0x44dd5UL + #define R32(l,q) \ case offsetof(struct user32, regs.l): stack[offsetof(struct pt_regs, q)/8] = val; break diff -urN linux-2.4.24/arch/x86_64/ia32/sys_ia32.c linux-2.4.25/arch/x86_64/ia32/sys_ia32.c --- linux-2.4.24/arch/x86_64/ia32/sys_ia32.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/ia32/sys_ia32.c 2004-02-18 05:36:31.000000000 -0800 @@ -16,7 +16,7 @@ * * This file assumes that there is a hole at the end of user address space. * - * $Id: sys_ia32.c,v 1.66 2003/11/10 13:09:54 ak Exp $ + * $Id: sys_ia32.c,v 1.69 2004/01/29 02:52:13 ak Exp $ */ #include @@ -174,12 +174,15 @@ return putstat(statbuf, &s); } +extern long sys_truncate(char *, loff_t); + asmlinkage long sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high) { return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); } +extern long sys_ftruncate(int, loff_t); asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offset_high) @@ -1453,8 +1456,12 @@ asmlinkage long sys32_ni_syscall(int call) { + /* Disable for now because the emulation should be pretty complete + and we miss some syscalls from 2.6. */ +#if 0 printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, current->comm); +#endif return -ENOSYS; } @@ -3035,7 +3042,7 @@ static int __init ia32_init (void) { - printk("IA32 emulation $Id: sys_ia32.c,v 1.66 2003/11/10 13:09:54 ak Exp $\n"); + printk("IA32 emulation $Id: sys_ia32.c,v 1.69 2004/01/29 02:52:13 ak Exp $\n"); ia32_exec_domain.signal_map = default_exec_domain.signal_map; ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; register_exec_domain(&ia32_exec_domain); diff -urN linux-2.4.24/arch/x86_64/kernel/acpi.c linux-2.4.25/arch/x86_64/kernel/acpi.c --- linux-2.4.24/arch/x86_64/kernel/acpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/kernel/acpi.c 2004-02-18 05:36:31.000000000 -0800 @@ -411,8 +411,10 @@ * Initialize the ACPI boot-time table parser. */ result = acpi_table_init(); - if (result) + if (result) { + acpi_disabled = 1; return result; + } #ifdef CONFIG_X86_LOCAL_APIC diff -urN linux-2.4.24/arch/x86_64/kernel/bluesmoke.c linux-2.4.25/arch/x86_64/kernel/bluesmoke.c --- linux-2.4.24/arch/x86_64/kernel/bluesmoke.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/kernel/bluesmoke.c 2004-02-18 05:36:31.000000000 -0800 @@ -25,14 +25,6 @@ static int banks; static unsigned long ignored_banks, disabled_banks; -/* Machine Check on everything dubious. This is a good setting - for device driver testing. */ -#define K8_DRIVER_DEBUG ((1<<13)-1) -/* Report RAM errors and Hyper Transport Problems, but ignore Device - aborts and GART errors. */ -#define K8_NORMAL_OP 0xff -static u32 k8_nb_flags __initdata = K8_NORMAL_OP; - static void generic_machine_check(struct pt_regs * regs, long error_code) { int recover=1; @@ -201,53 +193,48 @@ if (header) printk(KERN_ERR "CPU %d: Silent Northbridge MCE\n", smp_processor_id()); - printk(KERN_ERR "Northbridge status %08x%08x\n", + printk(KERN_ERR "Northbridge status %08x:%08x\n", statushigh,statuslow); + printk(KERN_ERR " Error %s\n", extendederr[(statuslow >> 16) & 0xf]); + unsigned short errcode = statuslow & 0xffff; - switch (errcode >> 8) { - case 0: + switch ((statuslow >> 16) & 0xF) { + case 5: printk(KERN_ERR " GART TLB error %s %s\n", transaction[(errcode >> 2) & 3], cachelevel[errcode & 3]); break; - case 1: - if (errcode & (1<<11)) { - printk(KERN_ERR " bus error %s %s %s %s %s\n", - partproc[(errcode >> 10) & 0x3], - timeout[(errcode >> 9) & 1], + case 8: + printk(KERN_ERR " ECC error syndrome %x\n", + (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); + /*FALL THROUGH*/ + default: + printk(KERN_ERR " bus error %s, %s\n %s\n %s, %s\n", + partproc[(errcode >> 9) & 0x3], + timeout[(errcode >> 8) & 1], memtrans[(errcode >> 4) & 0xf], memoryio[(errcode >> 2) & 0x3], cachelevel[(errcode & 0x3)]); - } else if (errcode & (1<<8)) { - printk(KERN_ERR " memory error %s %s %s\n", - memtrans[(errcode >> 4) & 0xf], - transaction[(errcode >> 2) & 0x3], - cachelevel[(errcode & 0x3)]); - } else { - printk(KERN_ERR " unknown error code %x\n", errcode); - } + /* should only print when it was a HyperTransport related error. */ + printk(KERN_ERR " link number %x\n", (statushigh >> 4) & 3); break; } - if (statushigh & ((1<<14)|(1<<13))) - printk(KERN_ERR " ECC syndrome bits %x\n", - (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); - errcode = (statuslow >> 16) & 0xf; - printk(KERN_ERR " extended error %s\n", extendederr[(statuslow >> 16) & 0xf]); - /* should only print when it was a HyperTransport related error. */ - printk(KERN_ERR " link number %x\n", (statushigh >> 4) & 3); int i; - for (i = 0; i < 32; i++) + for (i = 0; i < 32; i++) { + if (i == 26 || i == 28) + continue; if (highbits[i] && (statushigh & (1<rip, regs->rsp); - others: generic_machine_check(regs, error_code); } @@ -353,12 +337,13 @@ machine_check_vector = k8_machine_check; for (i = 0; i < banks; i++) { u64 val = ((1UL< disable bank NUMBER mce=enable enable bank number - mce=device Enable device driver test reporting in NB mce=NUMBER mcheck timer interval number seconds. Can be also comma separated in a single mce= */ static int __init mcheck_enable(char *str) @@ -472,8 +456,6 @@ disabled_banks |= ~(1< #include diff -urN linux-2.4.24/arch/x86_64/kernel/mtrr.c linux-2.4.25/arch/x86_64/kernel/mtrr.c --- linux-2.4.24/arch/x86_64/kernel/mtrr.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/arch/x86_64/kernel/mtrr.c 2004-02-18 05:36:31.000000000 -0800 @@ -70,6 +70,9 @@ #define MTRR_VERSION "2.02 (20020716)" +#define MTRR_BEG_BIT 12 +#define MTRR_END_BIT 7 + #undef Dprintk #define Dprintk(...) @@ -192,8 +195,9 @@ static void get_mtrr (unsigned int reg, u64 *base, u32 *size, mtrr_type * type) { - u32 mask_lo, mask_hi, base_lo, base_hi; - u64 newsize; + u32 count, tmp, mask_lo, mask_hi; + int i; + u32 base_lo, base_hi; rdmsr (MSR_MTRRphysMask(reg), mask_lo, mask_hi); if ((mask_lo & 0x800) == 0) { @@ -206,10 +210,16 @@ rdmsr (MSR_MTRRphysBase(reg), base_lo, base_hi); - /* Work out the shifted address mask. */ - newsize = (u64) mask_hi << 32 | (mask_lo & ~0x800); - newsize = ~newsize+1; - *size = (u32) newsize >> PAGE_SHIFT; + count = 0; + tmp = mask_lo >> MTRR_BEG_BIT; + for (i = MTRR_BEG_BIT; i <= 31; i++, tmp = tmp >> 1) + count = (count << (~tmp & 1)) | (~tmp & 1); + + tmp = mask_hi; + for (i = 0; i <= MTRR_END_BIT; i++, tmp = tmp >> 1) + count = (count << (~tmp & 1)) | (~tmp & 1); + + *size = (count+1); *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; *type = base_lo & 0xff; } @@ -243,7 +253,7 @@ base64 = (base << PAGE_SHIFT) & size_and_mask; wrmsr (MSR_MTRRphysBase(reg), base64 | type, base64 >> 32); - size64 = ~((size << PAGE_SHIFT) - 1); + size64 = ~(((u64)size << PAGE_SHIFT) - 1); size64 = size64 & size_and_mask; wrmsr (MSR_MTRRphysMask(reg), (u32) (size64 | 0x800), (u32) (size64 >> 32)); } diff -urN linux-2.4.24/arch/x86_64/kernel/pci-gart.c linux-2.4.25/arch/x86_64/kernel/pci-gart.c --- linux-2.4.24/arch/x86_64/kernel/pci-gart.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/kernel/pci-gart.c 2004-02-18 05:36:31.000000000 -0800 @@ -8,7 +8,7 @@ * See Documentation/DMA-mapping.txt for the interface specification. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: pci-gart.c,v 1.28 2003/09/19 07:01:58 ak Exp $ + * $Id: pci-gart.c,v 1.30 2004/01/13 09:09:32 ak Exp $ */ #include @@ -42,6 +42,7 @@ #else int force_mmu = 0; #endif +int iommu_fullflush = 1; extern int fallback_aper_order; extern int fallback_aper_force; @@ -97,6 +98,8 @@ next_bit = 0; } } + if (iommu_fullflush) + need_flush = 1; spin_unlock_irqrestore(&iommu_bitmap_lock, flags); return offset; } @@ -123,8 +126,12 @@ /* recheck flush count inside lock */ if (need_flush) { for (i = 0; northbridges[i]; i++) { + u32 w; pci_write_config_dword(northbridges[i], 0x9c, northbridge_flush_word[i] | 1); + do { + pci_read_config_dword(northbridges[i], 0x9c, &w); + } while (w & 1); flushed++; } if (!flushed) @@ -463,6 +470,7 @@ nommu: /* XXX: reject 0xffffffff mask now in pci mapping functions */ + if (end_pfn >= 0xffffffff>>PAGE_SHIFT) printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction."); return -1; @@ -570,6 +578,8 @@ memaper[=order] allocate an own aperture over RAM with size 32MB^order. noforce don't force IOMMU usage. Default force Force IOMMU for all devices. + nofullflush use optimized IOMMU flushing (may break on some devices). + default off. */ __init int iommu_setup(char *opt) { @@ -585,6 +595,8 @@ force_mmu = 1; if (!memcmp(p,"noforce", 7)) force_mmu = 0; + if (!memcmp(p,"nofullflush", 11)) + iommu_fullflush = 0; if (!memcmp(p, "memaper", 7)) { fallback_aper_force = 1; p += 7; diff -urN linux-2.4.24/arch/x86_64/kernel/process.c linux-2.4.25/arch/x86_64/kernel/process.c --- linux-2.4.24/arch/x86_64/kernel/process.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/kernel/process.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,7 @@ * X86-64 port * Andi Kleen. * - * $Id: process.c,v 1.74 2003/08/13 13:43:16 ak Exp $ + * $Id: process.c,v 1.75 2004/01/13 09:04:32 ak Exp $ */ /* @@ -159,7 +159,7 @@ __setup("idle=", idle_setup); -static long no_idt[3]; +static struct { long x; } no_idt[3]; static enum { BOOT_BIOS = 'b', BOOT_TRIPLE = 't', diff -urN linux-2.4.24/arch/x86_64/mm/k8topology.c linux-2.4.25/arch/x86_64/mm/k8topology.c --- linux-2.4.24/arch/x86_64/mm/k8topology.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/arch/x86_64/mm/k8topology.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ * Instead the northbridge registers are read directly. * * Copyright 2002 Andi Kleen, SuSE Labs. - * $Id: k8topology.c,v 1.11 2003/09/12 01:55:37 ak Exp $ + * $Id: k8topology.c,v 1.12 2004/01/29 00:51:01 ak Exp $ */ #include #include @@ -100,7 +100,7 @@ printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); - numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3; + numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 7; memset(&nodes,0,sizeof(nodes)); prevbase = 0; @@ -111,7 +111,7 @@ base = read_pci_config(0, nb, 1, 0x40 + i*8); limit = read_pci_config(0, nb, 1, 0x44 + i*8); - nodeid = limit & 3; + nodeid = limit & 7; if ((base & 3) == 0) { continue; } diff -urN linux-2.4.24/crypto/Config.in linux-2.4.25/crypto/Config.in --- linux-2.4.24/crypto/Config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -71,6 +71,7 @@ tristate ' Serpent cipher algorithm' CONFIG_CRYPTO_SERPENT tristate ' AES cipher algorithms' CONFIG_CRYPTO_AES tristate ' CAST5 (CAST-128) cipher algorithm' CONFIG_CRYPTO_CAST5 + tristate ' CAST6 (CAST-256) cipher algorithm' CONFIG_CRYPTO_CAST6 if [ "$CONFIG_INET_IPCOMP" = "y" -o \ "$CONFIG_INET_IPCOMP" = "m" -o \ "$CONFIG_INET6_IPCOMP" = "y" -o \ diff -urN linux-2.4.24/crypto/Makefile linux-2.4.25/crypto/Makefile --- linux-2.4.24/crypto/Makefile 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -25,6 +25,7 @@ obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o obj-$(CONFIG_CRYPTO_AES) += aes.o obj-$(CONFIG_CRYPTO_CAST5) += cast5.o +obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -urN linux-2.4.24/crypto/aes.c linux-2.4.25/crypto/aes.c --- linux-2.4.24/crypto/aes.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/aes.c 2004-02-18 05:36:31.000000000 -0800 @@ -442,7 +442,6 @@ .cipher = { .cia_min_keysize = AES_MIN_KEY_SIZE, .cia_max_keysize = AES_MAX_KEY_SIZE, - .cia_ivsize = AES_BLOCK_SIZE, .cia_setkey = aes_set_key, .cia_encrypt = aes_encrypt, .cia_decrypt = aes_decrypt diff -urN linux-2.4.24/crypto/api.c linux-2.4.25/crypto/api.c --- linux-2.4.24/crypto/api.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/api.c 2004-02-18 05:36:31.000000000 -0800 @@ -37,6 +37,9 @@ struct crypto_alg *crypto_alg_lookup(const char *name) { struct crypto_alg *q, *alg = NULL; + + if (!name) + return NULL; down_read(&crypto_alg_sem); diff -urN linux-2.4.24/crypto/blowfish.c linux-2.4.25/crypto/blowfish.c --- linux-2.4.24/crypto/blowfish.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/blowfish.c 2004-02-18 05:36:31.000000000 -0800 @@ -456,7 +456,6 @@ .cra_u = { .cipher = { .cia_min_keysize = BF_MIN_KEY_SIZE, .cia_max_keysize = BF_MAX_KEY_SIZE, - .cia_ivsize = BF_BLOCK_SIZE, .cia_setkey = bf_setkey, .cia_encrypt = bf_encrypt, .cia_decrypt = bf_decrypt } } diff -urN linux-2.4.24/crypto/cast5.c linux-2.4.25/crypto/cast5.c --- linux-2.4.24/crypto/cast5.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/cast5.c 2004-02-18 05:36:31.000000000 -0800 @@ -826,7 +826,6 @@ .cipher = { .cia_min_keysize = CAST5_MIN_KEY_SIZE, .cia_max_keysize = CAST5_MAX_KEY_SIZE, - .cia_ivsize = CAST5_BLOCK_SIZE, .cia_setkey = cast5_setkey, .cia_encrypt = cast5_encrypt, .cia_decrypt = cast5_decrypt diff -urN linux-2.4.24/crypto/cast6.c linux-2.4.25/crypto/cast6.c --- linux-2.4.24/crypto/cast6.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/crypto/cast6.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,562 @@ +/* Kernel cryptographic api. + * cast6.c - Cast6 cipher algorithm [rfc2612]. + * + * CAST-256 (*cast6*) is a DES like Substitution-Permutation Network (SPN) + * cryptosystem built upon the CAST-128 (*cast5*) [rfc2144] encryption + * algorithm. + * + * Copyright (C) 2003 Kartikey Mahendra Bhatt . + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include +#include +#include +#include +#include + +#define CAST6_BLOCK_SIZE 16 +#define CAST6_MIN_KEY_SIZE 16 +#define CAST6_MAX_KEY_SIZE 32 + +struct cast6_ctx { + u32 Km[12][4]; + u8 Kr[12][4]; +}; + +#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) ) + +#define F1(D,r,m) ( (I = ((m) + (D))), (I=rol((r),I)), \ + (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) ) +#define F2(D,r,m) ( (I = ((m) ^ (D))), (I=rol((r),I)), \ + (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) ) +#define F3(D,r,m) ( (I = ((m) - (D))), (I=rol((r),I)), \ + (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) + +static const u32 s1[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, + 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, + 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, + 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, + 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, + 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, + 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, + 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, + 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, + 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, + 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, + 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, + 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, + 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, + 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, + 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, + 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, + 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, + 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, + 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, + 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, + 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, + 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, + 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, + 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, + 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, + 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, + 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, + 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, + 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, + 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, + 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, + 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf +}; + +static const u32 s2[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, + 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, + 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, + 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, + 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, + 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, + 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, + 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, + 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, + 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, + 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, + 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, + 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, + 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, + 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, + 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, + 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, + 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, + 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, + 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, + 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, + 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, + 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, + 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, + 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, + 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, + 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, + 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, + 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, + 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, + 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, + 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, + 0x73bfbe70, 0x83877605, 0x4523ecf1 +}; + +static const u32 s3[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, + 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, + 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, + 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, + 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, + 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, + 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, + 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, + 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, + 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, + 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, + 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, + 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, + 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, + 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, + 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, + 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, + 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, + 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, + 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, + 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, + 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, + 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, + 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, + 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, + 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, + 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, + 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, + 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, + 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, + 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, + 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, + 0xa133c501, 0xe9d3531c, 0xee353783 +}; + +static const u32 s4[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, + 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, + 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, + 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, + 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, + 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, + 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, + 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, + 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, + 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, + 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, + 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, + 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, + 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, + 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, + 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, + 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, + 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, + 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, + 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, + 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, + 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, + 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, + 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, + 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, + 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, + 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, + 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, + 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, + 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, + 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, + 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, + 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 +}; + +static const u32 Tm[24][8] = { + { 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d, + 0x84c413be, 0xf39dff5f, 0x6277eb00 } , + { 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525, + 0xfb9370c6, 0x6a6d5c67, 0xd9474808 } , + { 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d, + 0x7262cdce, 0xe13cb96f, 0x5016a510 } , + { 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35, + 0xe9322ad6, 0x580c1677, 0xc6e60218 } , + { 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d, + 0x600187de, 0xcedb737f, 0x3db55f20 } , + { 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945, + 0xd6d0e4e6, 0x45aad087, 0xb484bc28 } , + { 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d, + 0x4da041ee, 0xbc7a2d8f, 0x2b541930 } , + { 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355, + 0xc46f9ef6, 0x33498a97, 0xa2237638 } , + { 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d, + 0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } , + { 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65, + 0xb20e5906, 0x20e844a7, 0x8fc23048 } , + { 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d, + 0x28ddb60e, 0x97b7a1af, 0x06918d50 } , + { 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775, + 0x9fad1316, 0x0e86feb7, 0x7d60ea58 } , + { 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d, + 0x167c701e, 0x85565bbf, 0xf4304760 } , + { 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185, + 0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } , + { 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d, + 0x041b2a2e, 0x72f515cf, 0xe1cf0170 } , + { 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95, + 0x7aea8736, 0xe9c472d7, 0x589e5e78 } , + { 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d, + 0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } , + { 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5, + 0x68894146, 0xd7632ce7, 0x463d1888 } , + { 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad, + 0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } , + { 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5, + 0x5627fb56, 0xc501e6f7, 0x33dbd298 } , + { 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd, + 0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } , + { 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5, + 0x43c6b566, 0xb2a0a107, 0x217a8ca8 } , + { 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd, + 0xba96126e, 0x296ffe0f, 0x9849e9b0 } , + { 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5, + 0x31656f76, 0xa03f5b17, 0x0f1946b8 } +}; + +static const u8 Tr[4][8] = { + { 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } , + { 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } , + { 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } , + { 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 } +}; + +/* forward octave */ +static inline void W(u32 *key, unsigned int i) { + u32 I; + key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]); + key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]); + key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]); + key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]); + key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]); + key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]); + key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]); + key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]); +} + +static int +cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags) +{ + int i; + u32 key[8]; + u8 p_key[32]; /* padded key */ + struct cast6_ctx *c = (struct cast6_ctx *) ctx; + + if (key_len < 16 || key_len > 32 || key_len % 4 != 0) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + memset (p_key, 0, 32); + memcpy (p_key, in_key, key_len); + + key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; /* A */ + key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; /* B */ + key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; /* C */ + key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; /* D */ + key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19]; /* E */ + key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23]; /* F */ + key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27]; /* G */ + key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31]; /* H */ + + + + for (i = 0; i < 12; i++) { + W (key, 2 * i); + W (key, 2 * i + 1); + + c->Kr[i][0] = key[0] & 0x1f; + c->Kr[i][1] = key[2] & 0x1f; + c->Kr[i][2] = key[4] & 0x1f; + c->Kr[i][3] = key[6] & 0x1f; + + c->Km[i][0] = key[7]; + c->Km[i][1] = key[5]; + c->Km[i][2] = key[3]; + c->Km[i][3] = key[1]; + } + + return 0; +} + +/*forward quad round*/ +static inline void Q (u32 * block, u8 * Kr, u32 * Km) { + u32 I; + block[2] ^= F1(block[3], Kr[0], Km[0]); + block[1] ^= F2(block[2], Kr[1], Km[1]); + block[0] ^= F3(block[1], Kr[2], Km[2]); + block[3] ^= F1(block[0], Kr[3], Km[3]); +} + +/*reverse quad round*/ +static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) { + u32 I; + block[3] ^= F1(block[0], Kr[3], Km[3]); + block[0] ^= F3(block[1], Kr[2], Km[2]); + block[1] ^= F2(block[2], Kr[1], Km[1]); + block[2] ^= F1(block[3], Kr[0], Km[0]); +} + +static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; + u32 block[4]; + u32 * Km; + u8 * Kr; + + block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11]; + block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15]; + + Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km); + Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km); + Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km); + Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km); + Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km); + Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km); + Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km); + Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km); + Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km); + Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km); + Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km); + Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km); + + outbuf[0] = (block[0] >> 24) & 0xff; + outbuf[1] = (block[0] >> 16) & 0xff; + outbuf[2] = (block[0] >> 8) & 0xff; + outbuf[3] = block[0] & 0xff; + outbuf[4] = (block[1] >> 24) & 0xff; + outbuf[5] = (block[1] >> 16) & 0xff; + outbuf[6] = (block[1] >> 8) & 0xff; + outbuf[7] = block[1] & 0xff; + outbuf[8] = (block[2] >> 24) & 0xff; + outbuf[9] = (block[2] >> 16) & 0xff; + outbuf[10] = (block[2] >> 8) & 0xff; + outbuf[11] = block[2] & 0xff; + outbuf[12] = (block[3] >> 24) & 0xff; + outbuf[13] = (block[3] >> 16) & 0xff; + outbuf[14] = (block[3] >> 8) & 0xff; + outbuf[15] = block[3] & 0xff; +} + +static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; + u32 block[4]; + u32 * Km; + u8 * Kr; + + block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11]; + block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15]; + + Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km); + Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km); + Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km); + Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km); + Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km); + Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km); + Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km); + Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km); + Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km); + Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km); + Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km); + Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km); + + outbuf[0] = (block[0] >> 24) & 0xff; + outbuf[1] = (block[0] >> 16) & 0xff; + outbuf[2] = (block[0] >> 8) & 0xff; + outbuf[3] = block[0] & 0xff; + outbuf[4] = (block[1] >> 24) & 0xff; + outbuf[5] = (block[1] >> 16) & 0xff; + outbuf[6] = (block[1] >> 8) & 0xff; + outbuf[7] = block[1] & 0xff; + outbuf[8] = (block[2] >> 24) & 0xff; + outbuf[9] = (block[2] >> 16) & 0xff; + outbuf[10] = (block[2] >> 8) & 0xff; + outbuf[11] = block[2] & 0xff; + outbuf[12] = (block[3] >> 24) & 0xff; + outbuf[13] = (block[3] >> 16) & 0xff; + outbuf[14] = (block[3] >> 8) & 0xff; + outbuf[15] = block[3] & 0xff; +} + +static struct crypto_alg alg = { + .cra_name = "cast6", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = CAST6_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct cast6_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = CAST6_MIN_KEY_SIZE, + .cia_max_keysize = CAST6_MAX_KEY_SIZE, + .cia_setkey = cast6_setkey, + .cia_encrypt = cast6_encrypt, + .cia_decrypt = cast6_decrypt} + } +}; + +static int __init init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cast6 Cipher Algorithm"); diff -urN linux-2.4.24/crypto/cipher.c linux-2.4.25/crypto/cipher.c --- linux-2.4.24/crypto/cipher.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/cipher.c 2004-02-18 05:36:31.000000000 -0800 @@ -345,7 +345,6 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) { int ret = 0; - struct crypto_alg *alg = tfm->__crt_alg; struct cipher_tfm *ops = &tfm->crt_cipher; ops->cit_setkey = setkey; @@ -381,8 +380,7 @@ BUG(); } - if (alg->cra_cipher.cia_ivsize && - ops->cit_mode != CRYPTO_TFM_MODE_ECB) { + if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -401,7 +399,8 @@ goto out; } - ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL); + ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); + ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL); if (ops->cit_iv == NULL) ret = -ENOMEM; } diff -urN linux-2.4.24/crypto/crypto_null.c linux-2.4.25/crypto/crypto_null.c --- linux-2.4.24/crypto/crypto_null.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/crypto_null.c 2004-02-18 05:36:31.000000000 -0800 @@ -89,7 +89,6 @@ .cra_u = { .cipher = { .cia_min_keysize = NULL_KEY_SIZE, .cia_max_keysize = NULL_KEY_SIZE, - .cia_ivsize = 0, .cia_setkey = null_setkey, .cia_encrypt = null_encrypt, .cia_decrypt = null_decrypt } } diff -urN linux-2.4.24/crypto/des.c linux-2.4.25/crypto/des.c --- linux-2.4.24/crypto/des.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/des.c 2004-02-18 05:36:31.000000000 -0800 @@ -1249,7 +1249,6 @@ .cra_u = { .cipher = { .cia_min_keysize = DES_KEY_SIZE, .cia_max_keysize = DES_KEY_SIZE, - .cia_ivsize = DES_BLOCK_SIZE, .cia_setkey = des_setkey, .cia_encrypt = des_encrypt, .cia_decrypt = des_decrypt } } @@ -1265,7 +1264,6 @@ .cra_u = { .cipher = { .cia_min_keysize = DES3_EDE_KEY_SIZE, .cia_max_keysize = DES3_EDE_KEY_SIZE, - .cia_ivsize = DES3_EDE_BLOCK_SIZE, .cia_setkey = des3_ede_setkey, .cia_encrypt = des3_ede_encrypt, .cia_decrypt = des3_ede_decrypt } } diff -urN linux-2.4.24/crypto/proc.c linux-2.4.25/crypto/proc.c --- linux-2.4.24/crypto/proc.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/proc.c 2004-02-18 05:36:31.000000000 -0800 @@ -66,8 +66,6 @@ alg->cra_cipher.cia_min_keysize); seq_printf(m, "max keysize : %u\n", alg->cra_cipher.cia_max_keysize); - seq_printf(m, "ivsize : %u\n", - alg->cra_cipher.cia_ivsize); break; case CRYPTO_ALG_TYPE_DIGEST: diff -urN linux-2.4.24/crypto/serpent.c linux-2.4.25/crypto/serpent.c --- linux-2.4.24/crypto/serpent.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/serpent.c 2004-02-18 05:36:31.000000000 -0800 @@ -483,7 +483,6 @@ .cra_u = { .cipher = { .cia_min_keysize = SERPENT_MIN_KEY_SIZE, .cia_max_keysize = SERPENT_MAX_KEY_SIZE, - .cia_ivsize = SERPENT_BLOCK_SIZE, .cia_setkey = setkey, .cia_encrypt = encrypt, .cia_decrypt = decrypt } } diff -urN linux-2.4.24/crypto/sha256.c linux-2.4.25/crypto/sha256.c --- linux-2.4.24/crypto/sha256.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/sha256.c 2004-02-18 05:36:31.000000000 -0800 @@ -34,12 +34,12 @@ static inline u32 Ch(u32 x, u32 y, u32 z) { - return ((x & y) ^ (~x & z)); + return z ^ (x & (y ^ z)); } static inline u32 Maj(u32 x, u32 y, u32 z) { - return ((x & y) ^ (x & z) ^ (y & z)); + return (x & y) | (z & (x | y)); } static inline u32 RORu32(u32 x, u32 y) @@ -295,7 +295,7 @@ u8 bits[8]; unsigned int index, pad_len, t; int i, j; - const u8 padding[64] = { 0x80, }; + static u8 padding[64] = { 0x80, }; /* Save number of bits */ t = sctx->count[0]; diff -urN linux-2.4.24/crypto/sha512.c linux-2.4.25/crypto/sha512.c --- linux-2.4.24/crypto/sha512.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/sha512.c 2004-02-18 05:36:31.000000000 -0800 @@ -34,12 +34,12 @@ static inline u64 Ch(u64 x, u64 y, u64 z) { - return ((x & y) ^ (~x & z)); + return z ^ (x & (y ^ z)); } static inline u64 Maj(u64 x, u64 y, u64 z) { - return ((x & y) ^ (x & z) ^ (y & z)); + return (x & y) | (z & (x | y)); } static inline u64 RORu64(u64 x, u64 y) @@ -249,7 +249,7 @@ { struct sha512_ctx *sctx = ctx; - const static u8 padding[128] = { 0x80, }; + static u8 padding[128] = { 0x80, }; u32 t; u64 t2; diff -urN linux-2.4.24/crypto/tcrypt.c linux-2.4.25/crypto/tcrypt.c --- linux-2.4.24/crypto/tcrypt.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/tcrypt.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,16 +6,18 @@ * * Copyright (c) 2002 James Morris * Copyright (c) 2002 Jean-Francois Dive - * + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * + * 14 - 09 - 2003 + * Rewritten by Kartikey Mahendra Bhatt */ + #include #include -#include #include #include #include @@ -24,6 +26,8 @@ #include #include "tcrypt.h" +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) + /* * Need to kmalloc() memory for testing kmap(). */ @@ -38,2254 +42,375 @@ #define IDX3 1 #define IDX4 8193 #define IDX5 22222 -#define IDX6 17101 -#define IDX7 27333 -#define IDX8 3000 - -static int mode = 0; -static char *xbuf; -static char *tvmem; - -static char *check[] = { - "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", - "twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate", - NULL -}; - -static void -hexdump(unsigned char *buf, unsigned int len) -{ - while (len--) - printk("%02x", *buf++); - - printk("\n"); -} - -static void -test_md5(void) -{ - char *p; - unsigned int i; - struct scatterlist sg[2]; - char result[128]; - struct crypto_tfm *tfm; - struct md5_testvec *md5_tv; - unsigned int tsize; - - printk("\ntesting md5\n"); - - tsize = sizeof (md5_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, md5_tv_template, tsize); - md5_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("md5", 0); - if (tfm == NULL) { - printk("failed to load transform for md5\n"); - return; - } - - for (i = 0; i < MD5_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = md5_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(md5_tv[i].plaintext); - - crypto_digest_init(tfm); - crypto_digest_update(tfm, sg, 1); - crypto_digest_final(tfm, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, md5_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - printk("\ntesting md5 across pages\n"); - - /* setup the dummy buffer first */ - memset(xbuf, 0, XBUFSIZE); - memcpy(&xbuf[IDX1], "abcdefghijklm", 13); - memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 13; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 13; - - memset(result, 0, sizeof (result)); - crypto_digest_digest(tfm, sg, 2, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - - printk("%s\n", - memcmp(result, md5_tv[4].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); - crypto_free_tfm(tfm); -} - -#ifdef CONFIG_CRYPTO_HMAC -static void -test_hmac_md5(void) -{ - char *p; - unsigned int i, klen; - struct scatterlist sg[2]; - char result[128]; - struct crypto_tfm *tfm; - struct hmac_md5_testvec *hmac_md5_tv; - unsigned int tsize; - - tfm = crypto_alloc_tfm("md5", 0); - if (tfm == NULL) { - printk("failed to load transform for md5\n"); - return; - } - - printk("\ntesting hmac_md5\n"); - - tsize = sizeof (hmac_md5_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - - memcpy(tvmem, hmac_md5_tv_template, tsize); - hmac_md5_tv = (void *) tvmem; - - for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = hmac_md5_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(hmac_md5_tv[i].plaintext); - - klen = strlen(hmac_md5_tv[i].key); - crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, hmac_md5_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - printk("\ntesting hmac_md5 across pages\n"); - - memset(xbuf, 0, XBUFSIZE); - - memcpy(&xbuf[IDX1], "what do ya want ", 16); - memcpy(&xbuf[IDX2], "for nothing?", 12); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 16; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 12; - - memset(result, 0, sizeof (result)); - klen = strlen(hmac_md5_tv[7].key); - crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - - printk("%s\n", - memcmp(result, hmac_md5_tv[7].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); -out: - crypto_free_tfm(tfm); -} - -static void -test_hmac_sha1(void) -{ - char *p; - unsigned int i, klen; - struct crypto_tfm *tfm; - struct hmac_sha1_testvec *hmac_sha1_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA1_DIGEST_SIZE]; - - tfm = crypto_alloc_tfm("sha1", 0); - if (tfm == NULL) { - printk("failed to load transform for sha1\n"); - return; - } - - printk("\ntesting hmac_sha1\n"); - - tsize = sizeof (hmac_sha1_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - - memcpy(tvmem, hmac_sha1_tv_template, tsize); - hmac_sha1_tv = (void *) tvmem; - - for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = hmac_sha1_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(hmac_sha1_tv[i].plaintext); - - klen = strlen(hmac_sha1_tv[i].key); - - crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result); - - hexdump(result, sizeof (result)); - printk("%s\n", - memcmp(result, hmac_sha1_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - printk("\ntesting hmac_sha1 across pages\n"); - - /* setup the dummy buffer first */ - memset(xbuf, 0, XBUFSIZE); - - memcpy(&xbuf[IDX1], "what do ya want ", 16); - memcpy(&xbuf[IDX2], "for nothing?", 12); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 16; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 12; - - memset(result, 0, sizeof (result)); - klen = strlen(hmac_sha1_tv[7].key); - crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - - printk("%s\n", - memcmp(result, hmac_sha1_tv[7].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); -out: - crypto_free_tfm(tfm); -} - -static void -test_hmac_sha256(void) -{ - char *p; - unsigned int i, klen; - struct crypto_tfm *tfm; - struct hmac_sha256_testvec *hmac_sha256_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA256_DIGEST_SIZE]; - - tfm = crypto_alloc_tfm("sha256", 0); - if (tfm == NULL) { - printk("failed to load transform for sha256\n"); - return; - } - - printk("\ntesting hmac_sha256\n"); - - tsize = sizeof (hmac_sha256_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - - memcpy(tvmem, hmac_sha256_tv_template, tsize); - hmac_sha256_tv = (void *) tvmem; - - for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = hmac_sha256_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(hmac_sha256_tv[i].plaintext); - - klen = strlen(hmac_sha256_tv[i].key); - - hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key)); - crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, hmac_sha256_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); - } - -out: - crypto_free_tfm(tfm); -} - -#endif /* CONFIG_CRYPTO_HMAC */ - -static void -test_md4(void) -{ - char *p; - unsigned int i; - struct scatterlist sg[1]; - char result[128]; - struct crypto_tfm *tfm; - struct md4_testvec *md4_tv; - unsigned int tsize; - - printk("\ntesting md4\n"); - - tsize = sizeof (md4_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, md4_tv_template, tsize); - md4_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("md4", 0); - if (tfm == NULL) { - printk("failed to load transform for md4\n"); - return; - } - - for (i = 0; i < MD4_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = md4_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(md4_tv[i].plaintext); - - crypto_digest_digest(tfm, sg, 1, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, md4_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - crypto_free_tfm(tfm); -} - -static void -test_sha1(void) -{ - char *p; - unsigned int i; - struct crypto_tfm *tfm; - struct sha1_testvec *sha1_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA1_DIGEST_SIZE]; - - printk("\ntesting sha1\n"); - - tsize = sizeof (sha1_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, sha1_tv_template, tsize); - sha1_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("sha1", 0); - if (tfm == NULL) { - printk("failed to load transform for sha1\n"); - return; - } - - for (i = 0; i < SHA1_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = sha1_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(sha1_tv[i].plaintext); - - crypto_digest_init(tfm); - crypto_digest_update(tfm, sg, 1); - crypto_digest_final(tfm, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha1_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - printk("\ntesting sha1 across pages\n"); - - /* setup the dummy buffer first */ - memset(xbuf, 0, XBUFSIZE); - memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); - memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 28; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 28; - - memset(result, 0, sizeof (result)); - crypto_digest_digest(tfm, sg, 2, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha1_tv[1].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); - crypto_free_tfm(tfm); -} - -static void -test_sha256(void) -{ - char *p; - unsigned int i; - struct crypto_tfm *tfm; - struct sha256_testvec *sha256_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA256_DIGEST_SIZE]; - - printk("\ntesting sha256\n"); - - tsize = sizeof (sha256_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, sha256_tv_template, tsize); - sha256_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("sha256", 0); - if (tfm == NULL) { - printk("failed to load transform for sha256\n"); - return; - } - - for (i = 0; i < SHA256_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = sha256_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(sha256_tv[i].plaintext); - - crypto_digest_init(tfm); - crypto_digest_update(tfm, sg, 1); - crypto_digest_final(tfm, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha256_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - printk("\ntesting sha256 across pages\n"); - - /* setup the dummy buffer first */ - memset(xbuf, 0, XBUFSIZE); - memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); - memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 28; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 28; - - memset(result, 0, sizeof (result)); - crypto_digest_digest(tfm, sg, 2, result); - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha256_tv[1].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); - - crypto_free_tfm(tfm); -} - -static void -test_sha384(void) -{ - char *p; - unsigned int i; - struct crypto_tfm *tfm; - struct sha384_testvec *sha384_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA384_DIGEST_SIZE]; - - printk("\ntesting sha384\n"); - - tsize = sizeof (sha384_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, sha384_tv_template, tsize); - sha384_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("sha384", 0); - if (tfm == NULL) { - printk("failed to load transform for sha384\n"); - return; - } - - for (i = 0; i < SHA384_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = sha384_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(sha384_tv[i].plaintext); - - crypto_digest_init(tfm); - crypto_digest_update(tfm, sg, 1); - crypto_digest_final(tfm, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha384_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - crypto_free_tfm(tfm); -} - -static void -test_sha512(void) -{ - char *p; - unsigned int i; - struct crypto_tfm *tfm; - struct sha512_testvec *sha512_tv; - struct scatterlist sg[2]; - unsigned int tsize; - char result[SHA512_DIGEST_SIZE]; - - printk("\ntesting sha512\n"); - - tsize = sizeof (sha512_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, sha512_tv_template, tsize); - sha512_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("sha512", 0); - if (tfm == NULL) { - printk("failed to load transform for sha512\n"); - return; - } - - for (i = 0; i < SHA512_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - memset(result, 0, sizeof (result)); - - p = sha512_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = strlen(sha512_tv[i].plaintext); - - crypto_digest_init(tfm); - crypto_digest_update(tfm, sg, 1); - crypto_digest_final(tfm, result); - - hexdump(result, crypto_tfm_alg_digestsize(tfm)); - printk("%s\n", - memcmp(result, sha512_tv[i].digest, - crypto_tfm_alg_digestsize(tfm)) ? "fail" : - "pass"); - } - - crypto_free_tfm(tfm); -} - -void -test_des(void) -{ - unsigned int ret, i, len; - unsigned int tsize; - char *p, *q; - struct crypto_tfm *tfm; - char *key; - char res[8]; - struct des_tv *des_tv; - struct scatterlist sg[8]; - - printk("\ntesting des encryption\n"); - - tsize = sizeof (des_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, des_enc_tv_template, tsize); - des_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("des", 0); - if (tfm == NULL) { - printk("failed to load transform for des (default ecb)\n"); - return; - } - - for (i = 0; i < DES_ENC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - key = des_tv[i].key; - tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!des_tv[i].fail) - goto out; - } - - len = des_tv[i].len; - - p = des_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, sg, len); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - - } - - printk("\ntesting des ecb encryption across pages\n"); - - i = 5; - key = des_tv[i].key; - tfm->crt_flags = 0; - - hexdump(key, 8); - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); - memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 8; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 8; - - ret = crypto_cipher_encrypt(tfm, sg, sg, 16); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); - - printk("\ntesting des ecb encryption chunking scenario A\n"); - - /* - * Scenario A: - * - * F1 F2 F3 - * [8 + 6] [2 + 8] [8] - * ^^^^^^ ^ - * a b c - * - * Chunking should begin at a, then end with b, and - * continue encrypting at an offset of 2 until c. - * - */ - i = 7; - - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - - /* Frag 1: 8 + 6 */ - memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14); - - /* Frag 2: 2 + 8 */ - memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10); - - /* Frag 3: 8 */ - memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8); - - p = &xbuf[IDX3]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 14; - - p = &xbuf[IDX4]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 10; - - p = &xbuf[IDX5]; - sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); - sg[2].length = 8; - - ret = crypto_cipher_encrypt(tfm, sg, sg, 32); - - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 14); - printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 10); - printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass"); - - printk("page 3\n"); - q = kmap(sg[2].page) + sg[2].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass"); - - printk("\ntesting des ecb encryption chunking scenario B\n"); - - /* - * Scenario B: - * - * F1 F2 F3 F4 - * [2] [1] [3] [2 + 8 + 8] - */ - i = 7; - - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - - /* Frag 1: 2 */ - memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); - - /* Frag 2: 1 */ - memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1); - - /* Frag 3: 3 */ - memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3); - - /* Frag 4: 2 + 8 + 8 */ - memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18); - - p = &xbuf[IDX3]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 2; - - p = &xbuf[IDX4]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 1; - - p = &xbuf[IDX5]; - sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); - sg[2].length = 3; - - p = &xbuf[IDX6]; - sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); - sg[3].length = 18; - - ret = crypto_cipher_encrypt(tfm, sg, sg, 24); - - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 2); - printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 1); - printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass"); - - printk("page 3\n"); - q = kmap(sg[2].page) + sg[2].offset; - hexdump(q, 3); - printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass"); - - printk("page 4\n"); - q = kmap(sg[3].page) + sg[3].offset; - hexdump(q, 18); - printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass"); - - printk("\ntesting des ecb encryption chunking scenario C\n"); - - /* - * Scenario B: - * - * F1 F2 F3 F4 F5 - * [2] [2] [2] [2] [8] - */ - i = 7; - - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - - /* Frag 1: 2 */ - memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); - - /* Frag 2: 2 */ - memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2); - - /* Frag 3: 2 */ - memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2); - - /* Frag 4: 2 */ - memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2); - - /* Frag 5: 8 */ - memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8); - - p = &xbuf[IDX3]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 2; - - p = &xbuf[IDX4]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 2; - - p = &xbuf[IDX5]; - sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); - sg[2].length = 2; - - p = &xbuf[IDX6]; - sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); - sg[3].length = 2; - - p = &xbuf[IDX7]; - sg[4].page = virt_to_page(p); - sg[4].offset = ((long) p & ~PAGE_MASK); - sg[4].length = 8; - - ret = crypto_cipher_encrypt(tfm, sg, sg, 16); - - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 2); - printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 2); - printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass"); - - printk("page 3\n"); - q = kmap(sg[2].page) + sg[2].offset; - hexdump(q, 2); - printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass"); - - printk("page 4\n"); - q = kmap(sg[3].page) + sg[3].offset; - hexdump(q, 2); - printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass"); - - printk("page 5\n"); - q = kmap(sg[4].page) + sg[4].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); - - printk("\ntesting des ecb encryption chunking scenario D\n"); - - /* - * Scenario D, torture test, one byte per frag. - */ - i = 7; - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, XBUFSIZE); - - xbuf[IDX1] = des_tv[i].plaintext[0]; - xbuf[IDX2] = des_tv[i].plaintext[1]; - xbuf[IDX3] = des_tv[i].plaintext[2]; - xbuf[IDX4] = des_tv[i].plaintext[3]; - xbuf[IDX5] = des_tv[i].plaintext[4]; - xbuf[IDX6] = des_tv[i].plaintext[5]; - xbuf[IDX7] = des_tv[i].plaintext[6]; - xbuf[IDX8] = des_tv[i].plaintext[7]; - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 1; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 1; - - p = &xbuf[IDX3]; - sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); - sg[2].length = 1; - - p = &xbuf[IDX4]; - sg[3].page = virt_to_page(p); - sg[3].offset = ((long) p & ~PAGE_MASK); - sg[3].length = 1; - - p = &xbuf[IDX5]; - sg[4].page = virt_to_page(p); - sg[4].offset = ((long) p & ~PAGE_MASK); - sg[4].length = 1; - - p = &xbuf[IDX6]; - sg[5].page = virt_to_page(p); - sg[5].offset = ((long) p & ~PAGE_MASK); - sg[5].length = 1; - - p = &xbuf[IDX7]; - sg[6].page = virt_to_page(p); - sg[6].offset = ((long) p & ~PAGE_MASK); - sg[6].length = 1; - - p = &xbuf[IDX8]; - sg[7].page = virt_to_page(p); - sg[7].offset = ((long) p & ~PAGE_MASK); - sg[7].length = 1; - - ret = crypto_cipher_encrypt(tfm, sg, sg, 8); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - for (i = 0; i < 8; i++) - res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset); - - hexdump(res, 8); - printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass"); - - printk("\ntesting des decryption\n"); - - tsize = sizeof (des_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - memcpy(tvmem, des_dec_tv_template, tsize); - des_tv = (void *) tvmem; - - for (i = 0; i < DES_DEC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - key = des_tv[i].key; - - tfm->crt_flags = 0; - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - len = des_tv[i].len; - - p = des_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("des_decrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - - } - - printk("\ntesting des ecb decryption across pages\n"); - - i = 6; - - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); - memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 8; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 8; - - ret = crypto_cipher_decrypt(tfm, sg, sg, 16); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 8); - printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); - - /* - * Scenario E: - * - * F1 F2 F3 - * [3] [5 + 7] [1] - * - */ - printk("\ntesting des ecb decryption chunking scenario E\n"); - i = 2; - - key = des_tv[i].key; - tfm->crt_flags = 0; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - - memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3); - memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12); - memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 3; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 12; - - p = &xbuf[IDX3]; - sg[2].page = virt_to_page(p); - sg[2].offset = ((long) p & ~PAGE_MASK); - sg[2].length = 1; - - ret = crypto_cipher_decrypt(tfm, sg, sg, 16); - - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 3); - printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 12); - printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass"); - - printk("page 3\n"); - q = kmap(sg[2].page) + sg[2].offset; - hexdump(q, 1); - printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass"); - - crypto_free_tfm(tfm); - - tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); - if (tfm == NULL) { - printk("failed to load transform for des cbc\n"); - return; - } - - printk("\ntesting des cbc encryption\n"); - - tsize = sizeof (des_cbc_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - memcpy(tvmem, des_cbc_enc_tv_template, tsize); - des_tv = (void *) tvmem; - - crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm)); - - if (memcmp(res, des_tv[i].iv, sizeof(res))) { - printk("crypto_cipher_[set|get]_iv() failed\n"); - goto out; - } - - for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - key = des_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - len = des_tv[i].len; - p = des_tv[i].plaintext; - - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - - crypto_cipher_set_iv(tfm, des_tv[i].iv, - crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_encrypt(tfm, sg, sg, len); - if (ret) { - printk("des_cbc_encrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - } - - crypto_free_tfm(tfm); - - /* - * Scenario F: - * - * F1 F2 - * [8 + 5] [3 + 8] - * - */ - printk("\ntesting des cbc encryption chunking scenario F\n"); - i = 4; - - tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); - if (tfm == NULL) { - printk("failed to load transform for CRYPTO_ALG_DES_CCB\n"); - return; - } - - tfm->crt_flags = 0; - key = des_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - - memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13); - memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 13; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 11; - - crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_encrypt(tfm, sg, sg, 24); - if (ret) { - printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 13); - printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 11); - printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass"); - - tsize = sizeof (des_cbc_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - memcpy(tvmem, des_cbc_dec_tv_template, tsize); - des_tv = (void *) tvmem; - - printk("\ntesting des cbc decryption\n"); - - for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - tfm->crt_flags = 0; - key = des_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - len = des_tv[i].len; - p = des_tv[i].plaintext; - - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - - crypto_cipher_set_iv(tfm, des_tv[i].iv, - crypto_tfm_alg_blocksize(tfm)); - - ret = crypto_cipher_decrypt(tfm, sg, sg, len); - if (ret) { - printk("des_cbc_decrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - hexdump(tfm->crt_cipher.cit_iv, 8); - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - } - - /* - * Scenario G: - * - * F1 F2 - * [4] [4] - * - */ - printk("\ntesting des cbc decryption chunking scenario G\n"); - i = 3; - - tfm->crt_flags = 0; - key = des_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, 8); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - /* setup the dummy buffer first */ - memset(xbuf, 0, sizeof (xbuf)); - memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4); - memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4); - - p = &xbuf[IDX1]; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = 4; - - p = &xbuf[IDX2]; - sg[1].page = virt_to_page(p); - sg[1].offset = ((long) p & ~PAGE_MASK); - sg[1].length = 4; - - crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_decrypt(tfm, sg, sg, 8); - if (ret) { - printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - printk("page 1\n"); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, 4); - printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass"); - - printk("page 2\n"); - q = kmap(sg[1].page) + sg[1].offset; - hexdump(q, 4); - printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass"); - - out: - crypto_free_tfm(tfm); -} - -void -test_des3_ede(void) -{ - unsigned int ret, i, len; - unsigned int tsize; - char *p, *q; - struct crypto_tfm *tfm; - char *key; - /*char res[8]; */ - struct des_tv *des_tv; - struct scatterlist sg[8]; - - printk("\ntesting des3 ede encryption\n"); - - tsize = sizeof (des3_ede_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, des3_ede_enc_tv_template, tsize); - des_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB); - if (tfm == NULL) { - printk("failed to load transform for 3des ecb\n"); - return; - } - - for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - key = des_tv[i].key; - ret = crypto_cipher_setkey(tfm, key, 24); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!des_tv[i].fail) - goto out; - } - - len = des_tv[i].len; - - p = des_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, sg, len); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - } - - printk("\ntesting des3 ede decryption\n"); - - tsize = sizeof (des3_ede_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, des3_ede_dec_tv_template, tsize); - des_tv = (void *) tvmem; - - for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) { - printk("test %u:\n", i + 1); - - key = des_tv[i].key; - ret = crypto_cipher_setkey(tfm, key, 24); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!des_tv[i].fail) - goto out; - } - - len = des_tv[i].len; - - p = des_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = len; - ret = crypto_cipher_decrypt(tfm, sg, sg, len); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, len); - - printk("%s\n", - memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); - } - - out: - crypto_free_tfm(tfm); -} - -void -test_blowfish(void) -{ - unsigned int ret, i; - unsigned int tsize; - char *p, *q; - struct crypto_tfm *tfm; - char *key; - struct bf_tv *bf_tv; - struct scatterlist sg[1]; - - printk("\ntesting blowfish encryption\n"); - - tsize = sizeof (bf_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, bf_enc_tv_template, tsize); - bf_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("blowfish", 0); - if (tfm == NULL) { - printk("failed to load transform for blowfish (default ecb)\n"); - return; - } - - for (i = 0; i < BF_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, bf_tv[i].keylen * 8); - key = bf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!bf_tv[i].fail) - goto out; - } - - p = bf_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, bf_tv[i].rlen); - - printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? - "fail" : "pass"); - } - - printk("\ntesting blowfish decryption\n"); - - tsize = sizeof (bf_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, bf_dec_tv_template, tsize); - bf_tv = (void *) tvmem; - - for (i = 0; i < BF_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, bf_tv[i].keylen * 8); - key = bf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!bf_tv[i].fail) - goto out; - } - - p = bf_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, bf_tv[i].rlen); - - printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? - "fail" : "pass"); - } - - crypto_free_tfm(tfm); - - tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC); - if (tfm == NULL) { - printk("failed to load transform for blowfish cbc\n"); - return; - } - - printk("\ntesting blowfish cbc encryption\n"); - - tsize = sizeof (bf_cbc_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - memcpy(tvmem, bf_cbc_enc_tv_template, tsize); - bf_tv = (void *) tvmem; - - for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, bf_tv[i].keylen * 8); - - key = bf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - p = bf_tv[i].plaintext; - - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = bf_tv[i].plen; - - crypto_cipher_set_iv(tfm, bf_tv[i].iv, - crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("blowfish_cbc_encrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, bf_tv[i].rlen); - - printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) - ? "fail" : "pass"); - } - - printk("\ntesting blowfish cbc decryption\n"); - - tsize = sizeof (bf_cbc_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - memcpy(tvmem, bf_cbc_dec_tv_template, tsize); - bf_tv = (void *) tvmem; - - for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, bf_tv[i].keylen * 8); - key = bf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - p = bf_tv[i].plaintext; +#define IDX6 17101 +#define IDX7 27333 +#define IDX8 3000 - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = bf_tv[i].plen; +/* +* Used by test_cipher() +*/ +#define ENCRYPT 1 +#define DECRYPT 0 +#define MODE_ECB 1 +#define MODE_CBC 0 - crypto_cipher_set_iv(tfm, bf_tv[i].iv, - crypto_tfm_alg_ivsize(tfm)); +static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("blowfish_cbc_decrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } +static int mode; +static char *xbuf; +static char *tvmem; - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, bf_tv[i].rlen); +static char *check[] = { + "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", + "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", + "deflate", NULL +}; - printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) - ? "fail" : "pass"); - } +static void +hexdump(unsigned char *buf, unsigned int len) +{ + while (len--) + printk("%02x", *buf++); -out: - crypto_free_tfm(tfm); + printk("\n"); } - -void -test_twofish(void) +static void +test_hash (char * algo, struct hash_testvec * template, unsigned int tcount) { - unsigned int ret, i; - unsigned int tsize; - char *p, *q; - struct crypto_tfm *tfm; - char *key; - struct tf_tv *tf_tv; - struct scatterlist sg[1]; - - printk("\ntesting twofish encryption\n"); + char *p; + unsigned int i, j, k, temp; + struct scatterlist sg[8]; + char result[64]; + struct crypto_tfm *tfm; + struct hash_testvec *hash_tv; + unsigned int tsize; + + printk("\ntesting %s\n", algo); - tsize = sizeof (tf_enc_tv_template); + tsize = sizeof (struct hash_testvec); + tsize *= tcount; + if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); + printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } - memcpy(tvmem, tf_enc_tv_template, tsize); - tf_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("twofish", 0); + memcpy(tvmem, template, tsize); + hash_tv = (void *) tvmem; + tfm = crypto_alloc_tfm(algo, 0); if (tfm == NULL) { - printk("failed to load transform for blowfish (default ecb)\n"); + printk("failed to load transform for %s\n", algo); return; } - for (i = 0; i < TF_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, tf_tv[i].keylen * 8); - key = tf_tv[i].key; + for (i = 0; i < tcount; i++) { + printk ("test %u:\n", i + 1); + memset (result, 0, 64); - ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!tf_tv[i].fail) - goto out; - } - - p = tf_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } + p = hash_tv[i].plaintext; + sg[0].page = virt_to_page (p); + sg[0].offset = offset_in_page (p); + sg[0].length = hash_tv[i].psize; - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, tf_tv[i].rlen); + crypto_digest_init (tfm); + crypto_digest_update (tfm, sg, 1); + crypto_digest_final (tfm, result); - printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? - "fail" : "pass"); - } - - printk("\ntesting twofish decryption\n"); - - tsize = sizeof (tf_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; + hexdump (result, crypto_tfm_alg_digestsize (tfm)); + printk("%s\n", + memcmp(result, hash_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); } - memcpy(tvmem, tf_dec_tv_template, tsize); - tf_tv = (void *) tvmem; + printk ("testing %s across pages\n", algo); - for (i = 0; i < TF_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, tf_tv[i].keylen * 8); - key = tf_tv[i].key; + /* setup the dummy buffer first */ + memset(xbuf, 0, XBUFSIZE); - ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); + j = 0; + for (i = 0; i < tcount; i++) { + if (hash_tv[i].np) { + j++; + printk ("test %u:\n", j); + memset (result, 0, 64); - if (!tf_tv[i].fail) - goto out; - } + temp = 0; + for (k = 0; k < hash_tv[i].np; k++) { + memcpy (&xbuf[IDX[k]], hash_tv[i].plaintext + temp, + hash_tv[i].tap[k]); + temp += hash_tv[i].tap[k]; + p = &xbuf[IDX[k]]; + sg[k].page = virt_to_page (p); + sg[k].offset = offset_in_page (p); + sg[k].length = hash_tv[i].tap[k]; + } - p = tf_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; + crypto_digest_digest (tfm, sg, hash_tv[i].np, result); + + hexdump (result, crypto_tfm_alg_digestsize (tfm)); + printk("%s\n", + memcmp(result, hash_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, tf_tv[i].rlen); - - printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? - "fail" : "pass"); } - - crypto_free_tfm(tfm); - tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC); - if (tfm == NULL) { - printk("failed to load transform for twofish cbc\n"); - return; - } - - printk("\ntesting twofish cbc encryption\n"); - - tsize = sizeof (tf_cbc_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - memcpy(tvmem, tf_cbc_enc_tv_template, tsize); - tf_tv = (void *) tvmem; - - for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, tf_tv[i].keylen * 8); - - key = tf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - p = tf_tv[i].plaintext; - - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = tf_tv[i].plen; - - crypto_cipher_set_iv(tfm, tf_tv[i].iv, - crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("blowfish_cbc_encrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, tf_tv[i].rlen); - - printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) - ? "fail" : "pass"); - } - - printk("\ntesting twofish cbc decryption\n"); - - tsize = sizeof (tf_cbc_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - goto out; - } - memcpy(tvmem, tf_cbc_dec_tv_template, tsize); - tf_tv = (void *) tvmem; - - for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, tf_tv[i].keylen * 8); - - key = tf_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - p = tf_tv[i].plaintext; - - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = tf_tv[i].plen; - - crypto_cipher_set_iv(tfm, tf_tv[i].iv, - crypto_tfm_alg_ivsize(tfm)); - - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("blowfish_cbc_decrypt() failed flags=%x\n", - tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, tf_tv[i].rlen); + crypto_free_tfm (tfm); +} - printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) - ? "fail" : "pass"); - } -out: - crypto_free_tfm(tfm); -} +#ifdef CONFIG_CRYPTO_HMAC -void -test_serpent(void) +static void +test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount) { - unsigned int ret, i, tsize; - u8 *p, *q, *key; + char *p; + unsigned int i, j, k, temp; + struct scatterlist sg[8]; + char result[64]; struct crypto_tfm *tfm; - struct serpent_tv *serp_tv; - struct scatterlist sg[1]; - - printk("\ntesting serpent encryption\n"); + struct hmac_testvec *hmac_tv; + unsigned int tsize, klen; - tfm = crypto_alloc_tfm("serpent", 0); + tfm = crypto_alloc_tfm(algo, 0); if (tfm == NULL) { - printk("failed to load transform for serpent (default ecb)\n"); + printk("failed to load transform for %s\n", algo); return; } - tsize = sizeof (serpent_enc_tv_template); + printk("\ntesting hmac_%s\n", algo); + + tsize = sizeof (struct hmac_testvec); + tsize *= tcount; if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); - return; + goto out; } - memcpy(tvmem, serpent_enc_tv_template, tsize); - serp_tv = (void *) tvmem; - for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); - key = serp_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); + memcpy(tvmem, template, tsize); + hmac_tv = (void *) tvmem; - if (!serp_tv[i].fail) - goto out; - } + for (i = 0; i < tcount; i++) { + printk("test %u:\n", i + 1); + memset(result, 0, sizeof (result)); - p = serp_tv[i].plaintext; + p = hmac_tv[i].plaintext; + klen = hmac_tv[i].ksize; sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, sizeof(serp_tv[i].result)); - - printk("%s\n", memcmp(q, serp_tv[i].result, - sizeof(serp_tv[i].result)) ? "fail" : "pass"); - } + sg[0].offset = offset_in_page(p); + sg[0].length = hmac_tv[i].psize; - printk("\ntesting serpent decryption\n"); + crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result); - tsize = sizeof (serpent_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + printk("%s\n", + memcmp(result, hmac_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); } - memcpy(tvmem, serpent_dec_tv_template, tsize); - serp_tv = (void *) tvmem; - for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); - key = serp_tv[i].key; + printk("\ntesting hmac_%s across pages\n", algo); - ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!serp_tv[i].fail) - goto out; - } - - p = serp_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; + memset(xbuf, 0, XBUFSIZE); + + j = 0; + for (i = 0; i < tcount; i++) { + if (hmac_tv[i].np) { + j++; + printk ("test %u:\n",j); + memset (result, 0, 64); + + temp = 0; + klen = hmac_tv[i].ksize; + for (k = 0; k < hmac_tv[i].np; k++) { + memcpy (&xbuf[IDX[k]], hmac_tv[i].plaintext + temp, + hmac_tv[i].tap[k]); + temp += hmac_tv[i].tap[k]; + p = &xbuf[IDX[k]]; + sg[k].page = virt_to_page (p); + sg[k].offset = offset_in_page (p); + sg[k].length = hmac_tv[i].tap[k]; + } + + crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, hmac_tv[i].np, + result); + hexdump(result, crypto_tfm_alg_digestsize(tfm)); + + printk("%s\n", + memcmp(result, hmac_tv[i].digest, + crypto_tfm_alg_digestsize(tfm)) ? "fail" : + "pass"); } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, sizeof(serp_tv[i].result)); - - printk("%s\n", memcmp(q, serp_tv[i].result, - sizeof(serp_tv[i].result)) ? "fail" : "pass"); } - out: crypto_free_tfm(tfm); } +#endif /* CONFIG_CRYPTO_HMAC */ + void -test_aes(void) +test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount) { - unsigned int ret, i; + unsigned int ret, i, j, k, temp; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; - struct aes_tv *aes_tv; - struct scatterlist sg[1]; - - printk("\ntesting aes encryption\n"); - - tsize = sizeof (aes_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, aes_enc_tv_template, tsize); - aes_tv = (void *) tvmem; - - tfm = crypto_alloc_tfm("aes", 0); - if (tfm == NULL) { - printk("failed to load transform for aes (default ecb)\n"); - return; - } - - for (i = 0; i < AES_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, aes_tv[i].keylen * 8); - key = aes_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!aes_tv[i].fail) - goto out; - } + struct cipher_testvec *cipher_tv; + struct scatterlist sg[8]; + char e[11], m[4]; - p = aes_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } + if (enc == ENCRYPT) + strncpy(e, "encryption", 11); + else + strncpy(e, "decryption", 11); + if (mode == MODE_ECB) + strncpy(m, "ECB", 4); + else + strncpy(m, "CBC", 4); - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, aes_tv[i].rlen); + printk("\ntesting %s %s %s \n", algo, m, e); - printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? - "fail" : "pass"); - } + tsize = sizeof (struct cipher_testvec); + tsize *= tcount; - printk("\ntesting aes decryption\n"); - - tsize = sizeof (aes_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } - memcpy(tvmem, aes_dec_tv_template, tsize); - aes_tv = (void *) tvmem; - - for (i = 0; i < AES_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", - i + 1, aes_tv[i].keylen * 8); - key = aes_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!aes_tv[i].fail) - goto out; - } - - p = aes_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, aes_tv[i].rlen); - - printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? - "fail" : "pass"); - } - -out: - crypto_free_tfm(tfm); -} - -void -test_cast5(void) -{ - unsigned int ret, i, tsize; - u8 *p, *q, *key; - struct crypto_tfm *tfm; - struct cast5_tv *c5_tv; - struct scatterlist sg[1]; - - printk("\ntesting cast5 encryption\n"); + memcpy(tvmem, template, tsize); + cipher_tv = (void *) tvmem; - tfm = crypto_alloc_tfm("cast5", 0); + if (mode) + tfm = crypto_alloc_tfm (algo, 0); + else + tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC); + if (tfm == NULL) { - printk("failed to load transform for cast5 (default ecb)\n"); - return; - } - - tsize = sizeof (cast5_enc_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); + printk("failed to load transform for %s %s\n", algo, m); return; } + + j = 0; + for (i = 0; i < tcount; i++) { + if (!(cipher_tv[i].np)) { + j++; + printk("test %u (%d bit key):\n", + j, cipher_tv[i].klen * 8); - memcpy(tvmem, cast5_enc_tv_template, tsize); - c5_tv = (void *) tvmem; - for (i = 0; i < CAST5_ENC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8); - key = c5_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); + tfm->crt_flags = 0; + if (cipher_tv[i].wk) + tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; + key = cipher_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!cipher_tv[i].fail) + goto out; + } - if (!c5_tv[i].fail) + p = cipher_tv[i].input; + sg[0].page = virt_to_page(p); + sg[0].offset = offset_in_page(p); + sg[0].length = cipher_tv[i].ilen; + + if (!mode) { + crypto_cipher_set_iv(tfm, cipher_tv[i].iv, + crypto_tfm_alg_ivsize (tfm)); + } + + if (enc) + ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen); + else + ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen); + + + if (ret) { + printk("%s () failed flags=%x\n", e, tfm->crt_flags); goto out; + } + + q = kmap(sg[0].page) + sg[0].offset; + hexdump(q, cipher_tv[i].rlen); + + printk("%s\n", + memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" : + "pass"); } - - p = c5_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = sizeof(c5_tv[i].plaintext); - ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("encrypt() failed flags=%x\n", tfm->crt_flags); - goto out; - } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, sizeof(c5_tv[i].ciphertext)); - - printk("%s\n", memcmp(q, c5_tv[i].ciphertext, - sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass"); } - tsize = sizeof (cast5_dec_tv_template); - if (tsize > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", tsize, - TVMEMSIZE); - return; - } - - memcpy(tvmem, cast5_dec_tv_template, tsize); - c5_tv = (void *) tvmem; - for (i = 0; i < CAST5_DEC_TEST_VECTORS; i++) { - printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8); - key = c5_tv[i].key; - - ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen); - if (ret) { - printk("setkey() failed flags=%x\n", tfm->crt_flags); - - if (!c5_tv[i].fail) - goto out; - } - - p = c5_tv[i].plaintext; - sg[0].page = virt_to_page(p); - sg[0].offset = ((long) p & ~PAGE_MASK); - sg[0].length = sizeof(c5_tv[i].plaintext); - ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); - if (ret) { - printk("decrypt() failed flags=%x\n", tfm->crt_flags); - goto out; + printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e); + memset(xbuf, 0, XBUFSIZE); + + j = 0; + for (i = 0; i < tcount; i++) { + if (cipher_tv[i].np) { + j++; + printk("test %u (%d bit key):\n", + j, cipher_tv[i].klen * 8); + + tfm->crt_flags = 0; + if (cipher_tv[i].wk) + tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; + key = cipher_tv[i].key; + + ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen); + if (ret) { + printk("setkey() failed flags=%x\n", tfm->crt_flags); + + if (!cipher_tv[i].fail) + goto out; + } + + temp = 0; + for (k = 0; k < cipher_tv[i].np; k++) { + memcpy (&xbuf[IDX[k]], cipher_tv[i].input + temp, + cipher_tv[i].tap[k]); + temp += cipher_tv[i].tap[k]; + p = &xbuf[IDX[k]]; + sg[k].page = virt_to_page (p); + sg[k].offset = offset_in_page (p); + sg[k].length = cipher_tv[i].tap[k]; + } + + if (!mode) { + crypto_cipher_set_iv(tfm, cipher_tv[i].iv, + crypto_tfm_alg_ivsize (tfm)); + } + + if (enc) + ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen); + else + ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen); + + if (ret) { + printk("%s () failed flags=%x\n", e, tfm->crt_flags); + goto out; + } + + temp = 0; + for (k = 0; k < cipher_tv[i].np; k++) { + printk("page %u\n", k); + q = kmap(sg[k].page) + sg[k].offset; + hexdump(q, cipher_tv[i].tap[k]); + printk("%s\n", + memcmp(q, cipher_tv[i].result + temp, + cipher_tv[i].tap[k]) ? "fail" : + "pass"); + temp += cipher_tv[i].tap[k]; + } } - - q = kmap(sg[0].page) + sg[0].offset; - hexdump(q, sizeof(c5_tv[i].ciphertext)); - - printk("%s\n", memcmp(q, c5_tv[i].ciphertext, - sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass"); } + out: - crypto_free_tfm (tfm); + crypto_free_tfm(tfm); } static void @@ -2387,73 +512,118 @@ switch (mode) { case 0: - test_md5(); - test_sha1(); - test_des(); - test_des3_ede(); - test_md4(); - test_sha256(); - test_blowfish(); - test_twofish(); - test_serpent(); - test_aes(); - test_sha384(); - test_sha512(); - test_deflate(); - test_cast5(); + test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); + + test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); + + //DES + test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); + test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); + test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); + test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); + + //DES3_EDE + test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); + test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); + + test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); + + test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); + + //BLOWFISH + test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); + test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); + test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); + test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); + + //TWOFISH + test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); + test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); + test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); + test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); + + //SERPENT + test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS); + test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS); + + //AES + test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); + test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); + + //CAST5 + test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); + test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); + + //CAST6 + test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); + test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); + + test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); + test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); + test_deflate(); #ifdef CONFIG_CRYPTO_HMAC - test_hmac_md5(); - test_hmac_sha1(); - test_hmac_sha256(); + test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); + test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); + test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); #endif break; case 1: - test_md5(); + test_hash("md5", md5_tv_template, MD5_TEST_VECTORS); break; case 2: - test_sha1(); + test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS); break; case 3: - test_des(); + test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS); + test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS); + test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS); + test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS); break; case 4: - test_des3_ede(); + test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS); + test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); break; case 5: - test_md4(); + test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); break; case 6: - test_sha256(); + test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS); break; case 7: - test_blowfish(); + test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS); + test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS); + test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS); + test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS); break; case 8: - test_twofish(); + test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS); + test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS); + test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS); + test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS); break; - + case 9: - test_serpent(); break; case 10: - test_aes(); + test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS); + test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS); break; case 11: - test_sha384(); + test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); break; case 12: - test_sha512(); + test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); break; case 13: @@ -2461,20 +631,26 @@ break; case 14: - test_cast5(); + test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS); + test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS); + break; + + case 15: + test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); + test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); break; #ifdef CONFIG_CRYPTO_HMAC case 100: - test_hmac_md5(); + test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); break; case 101: - test_hmac_sha1(); + test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); break; case 102: - test_hmac_sha256(); + test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); break; #endif @@ -2510,7 +686,14 @@ return 0; } +/* + * If an init function is provided, an exit function must also be provided + * to allow module unload. + */ +static void __exit fini(void) { } + module_init(init); +module_exit(fini); MODULE_PARM(mode, "i"); diff -urN linux-2.4.24/crypto/tcrypt.h linux-2.4.25/crypto/tcrypt.h --- linux-2.4.24/crypto/tcrypt.h 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/crypto/tcrypt.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,4 +1,4 @@ -/* +/* * Quick & dirty crypto testing module. * * This will only exist until we have a better testing mechanism @@ -6,565 +6,165 @@ * * Copyright (c) 2002 James Morris * Copyright (c) 2002 Jean-Francois Dive - * + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * + * 14 - 09 - 2003 Changes by Kartikey Mahendra Bhatt + * */ #ifndef _CRYPTO_TCRYPT_H #define _CRYPTO_TCRYPT_H -#define MD5_DIGEST_SIZE 16 -#define MD4_DIGEST_SIZE 16 -#define SHA1_DIGEST_SIZE 20 -#define SHA256_DIGEST_SIZE 32 -#define SHA384_DIGEST_SIZE 48 -#define SHA512_DIGEST_SIZE 64 - -/* - * MD4 test vectors from RFC1320 - */ -#define MD4_TEST_VECTORS 7 - -struct md4_testvec { - char plaintext[128]; - char digest[MD4_DIGEST_SIZE]; -} md4_tv_template[] = { - { "", - { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, - 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 } - }, - - { "a", - { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, - 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 } - }, - - { "abc", - { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, - 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d } - }, - - { "message digest", - { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, - 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b } - }, - - { "abcdefghijklmnopqrstuvwxyz", - { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, - 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 } - }, - - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, - 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 } - }, - - { "123456789012345678901234567890123456789012345678901234567890123" - "45678901234567890", - { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, - 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 } - }, -}; +#define MAX_DIGEST_SIZE 64 +#define MAX_TAP 8 -/* - * MD5 test vectors from RFC1321 - */ -#define MD5_TEST_VECTORS 7 +#define MAX_KEYLEN 56 +#define MAX_IVLEN 32 -struct md5_testvec { +struct hash_testvec { char plaintext[128]; - char digest[MD5_DIGEST_SIZE]; -} md5_tv_template[] = { - { "", - { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, - 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, - - { "a", - { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, - 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, - - { "abc", - { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, - 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, - - { "message digest", - { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, - 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, - - { "abcdefghijklmnopqrstuvwxyz", - { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, - 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, - - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, - 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, - - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890", - { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, - 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } } + unsigned char psize; + char digest[MAX_DIGEST_SIZE]; + unsigned char np; + unsigned char tap[MAX_TAP]; }; -#ifdef CONFIG_CRYPTO_HMAC -/* - * HMAC-MD5 test vectors from RFC2202 - * (These need to be fixed to not use strlen). - */ -#define HMAC_MD5_TEST_VECTORS 7 - -struct hmac_md5_testvec { +struct hmac_testvec { char key[128]; + unsigned char ksize; char plaintext[128]; - char digest[MD5_DIGEST_SIZE]; + unsigned char psize; + char digest[MAX_DIGEST_SIZE]; + unsigned char np; + unsigned char tap[MAX_TAP]; }; -struct hmac_md5_testvec hmac_md5_tv_template[] = -{ - - { - { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00}, - - "Hi There", - - { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, - 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d } - }, - - { - { 'J', 'e', 'f', 'e', 0 }, - - "what do ya want for nothing?", - - { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, - 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, - - { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0x00 }, - - { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, - 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 } - }, - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 }, - - { - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0x00 }, - - { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, - 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 } - }, - - { - { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 }, - - "Test With Truncation", - - { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, - 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c } - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x00 }, - - "Test Using Larger Than Block-Size Key - Hash Key First", - - { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, - 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd } - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x00 }, - - "Test Using Larger Than Block-Size Key and Larger Than One " - "Block-Size Data", - - { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, - 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e } - }, - - /* cross page test, need to retain key */ - - { - { 'J', 'e', 'f', 'e', 0 }, - - "what do ya want for nothing?", - - { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, - 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } - }, - +struct cipher_testvec { + unsigned char fail; + unsigned char wk; /* weak key flag */ + char key[MAX_KEYLEN]; + unsigned char klen; + char iv[MAX_IVLEN]; + char input[48]; + unsigned char ilen; + char result[48]; + unsigned char rlen; + int np; + unsigned char tap[MAX_TAP]; }; - /* - * HMAC-SHA1 test vectors from RFC2202 + * MD4 test vectors from RFC1320 */ +#define MD4_TEST_VECTORS 7 -#define HMAC_SHA1_TEST_VECTORS 7 - -struct hmac_sha1_testvec { - char key[128]; - char plaintext[128]; - char digest[SHA1_DIGEST_SIZE]; -} hmac_sha1_tv_template[] = { - - { - { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x00}, - - "Hi There", - - { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, - 0xe2, 0x8b, 0xc0, 0xb6, 0xfb ,0x37, 0x8c, 0x8e, 0xf1, - 0x46, 0xbe, 0x00 } - }, - - { - { 'J', 'e', 'f', 'e', 0 }, - - "what do ya want for nothing?", - - { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, - 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 } - - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x00}, - - - { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0x00 }, - - { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, - 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 } - - }, - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 }, - - { - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0x00 }, - - { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, - 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda } - - }, - - { - { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x00 }, - - "Test With Truncation", - - { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, - 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 } - - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x00 }, - - "Test Using Larger Than Block-Size Key - Hash Key First", - - { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, - 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 } - - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x00 }, - - "Test Using Larger Than Block-Size Key and Larger Than One " - "Block-Size Data", - - { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, - 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 } - }, - - /* cross page test */ +struct hash_testvec md4_tv_template [] = { { - { 'J', 'e', 'f', 'e', 0 }, - - "what do ya want for nothing?", - - { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, - 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 } - + .plaintext = "", + .digest = { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 }, + }, { + .plaintext = "a", + .psize = 1, + .digest = { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 }, + }, { + .plaintext = "abc", + .psize = 3, + .digest = { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d }, + }, { + .plaintext = "message digest", + .psize = 14, + .digest = { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b }, + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 }, + .np = 2, + .tap = { 13, 13 }, + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 }, + }, { + .plaintext = "123456789012345678901234567890123456789012345678901234567890123" + "45678901234567890", + .psize = 80, + .digest = { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 }, }, - }; /* - * HMAC-SHA256 test vectors from - * draft-ietf-ipsec-ciph-sha-256-01.txt + * MD5 test vectors from RFC1321 */ -#define HMAC_SHA256_TEST_VECTORS 10 - -struct hmac_sha256_testvec { - char key[128]; - char plaintext[128]; - char digest[SHA256_DIGEST_SIZE]; -} hmac_sha256_tv_template[] = { - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, - - - { "abc" }, - - { 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a, - 0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a, - 0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66, - 0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 }, - - }, - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - - { 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08, - 0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae, - 0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49, - 0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 } - }, - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - - { 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34, - 0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab, - 0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5, - 0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 } - }, - - { - { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00 }, - - { "Hi There" }, - - { 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6, - 0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5, - 0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c, - 0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 } - }, - - { - { "Jefe" }, - - { "what do ya want for nothing?" }, - - { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, - 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, - 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, - 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, - - { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0x00 }, - - { 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea, - 0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62, - 0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc, - 0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 } - }, - - { - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x00 }, - - { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcd, 0xcd, 0x00 }, - - { 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74, - 0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55, - 0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85, - 0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 } - }, - - { - { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 }, - - { "Test With Truncation" }, - - { 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b, - 0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17, - 0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27, - 0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 } - }, - - { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, - - { "Test Using Larger Than Block-Size Key - Hash Key First" }, - - { 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09, - 0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb, - 0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e, - 0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f } - }, +#define MD5_TEST_VECTORS 7 +struct hash_testvec md5_tv_template[] = { { - { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 }, - - { "Test Using Larger Than Block-Size Key and Larger Than " - "One Block-Size Data" }, - - { 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3, - 0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8, - 0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc, - 0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 } - }, + .digest = { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e }, + }, { + .plaintext = "a", + .psize = 1, + .digest = { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 }, + }, { + .plaintext = "abc", + .psize = 3, + .digest = { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 }, + }, { + .plaintext = "message digest", + .psize = 14, + .digest = { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 }, + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b }, + .np = 2, + .tap = {13, 13} + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f }, + }, { + .plaintext = "12345678901234567890123456789012345678901234567890123456789012" + "345678901234567890", + .psize = 80, + .digest = { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a }, + } }; - -#endif /* CONFIG_CRYPTO_HMAC */ - /* * SHA1 test vectors from from FIPS PUB 180-1 */ #define SHA1_TEST_VECTORS 2 -struct sha1_testvec { - char plaintext[128]; - char digest[SHA1_DIGEST_SIZE]; -} sha1_tv_template[] = { - { "abc", - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C ,0x9C, 0xD0, 0xD8, 0x9D } - }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E ,0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } +struct hash_testvec sha1_tv_template[] = { + { + .plaintext = "abc", + .psize = 3, + .digest = { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, + 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d }, + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, + 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 }, + .np = 2, + .tap = { 28, 28 } } }; @@ -573,22 +173,23 @@ */ #define SHA256_TEST_VECTORS 2 -struct sha256_testvec { - char plaintext[128]; - char digest[SHA256_DIGEST_SIZE]; -} sha256_tv_template[] = { - { "abc", - { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } - }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, - 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, - 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, - 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } +struct hash_testvec sha256_tv_template[] = { + { + .plaintext = "abc", + .psize = 3, + .digest = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }, + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }, + .np = 2, + .tap = { 28, 28 } }, }; @@ -597,47 +198,47 @@ */ #define SHA384_TEST_VECTORS 4 -struct sha384_testvec { - char plaintext[128]; - char digest[SHA384_DIGEST_SIZE]; -} sha384_tv_template[] = { - - { "abc", - { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, - 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, - 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, - 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, - 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, - 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } - }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, - 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, - 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, - 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, - 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, - 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b } - }, - - { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", - { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, - 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, - 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, - 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, - 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, - 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } - }, - - { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" - "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", - { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb, - 0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a, - 0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc, - 0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a, - 0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a, - 0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 } +struct hash_testvec sha384_tv_template[] = { + { + .plaintext= "abc", + .psize = 3, + .digest = { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }, + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, + 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, + 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, + 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, + 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, + 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b}, + }, { + .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + .psize = 112, + .digest = { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }, + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + .psize = 104, + .digest = { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb, + 0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a, + 0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc, + 0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a, + 0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a, + 0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 }, + .np = 4, + .tap = { 26, 26, 26, 26 } }, }; @@ -646,439 +247,616 @@ */ #define SHA512_TEST_VECTORS 4 -struct sha512_testvec { - char plaintext[128]; - char digest[SHA512_DIGEST_SIZE]; -} sha512_tv_template[] = { - - { "abc", - { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, - 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, - 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, - 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, - 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, - 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, - 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, - 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } - }, - - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, - 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, - 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, - 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, - 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, - 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, - 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, - 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 } - }, - - { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", - { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, - 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, - 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, - 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, - 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, - 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, - 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, - 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } - }, - - { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" - "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", - { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11, - 0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d, - 0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c, - 0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d, - 0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67, - 0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe, - 0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8, - 0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9 - } +struct hash_testvec sha512_tv_template[] = { + { + .plaintext = "abc", + .psize = 3, + .digest = { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }, + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, + 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, + 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, + 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, + 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, + 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, + 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, + 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }, + }, { + .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + .psize = 112, + .digest = { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }, + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + .psize = 104, + .digest = { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11, + 0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d, + 0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c, + 0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d, + 0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67, + 0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe, + 0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8, + 0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9 }, + .np = 4, + .tap = { 26, 26, 26, 26 } }, }; +#ifdef CONFIG_CRYPTO_HMAC /* - * DES test vectors. + * HMAC-MD5 test vectors from RFC2202 + * (These need to be fixed to not use strlen). */ -#define DES_ENC_TEST_VECTORS 5 -#define DES_DEC_TEST_VECTORS 2 -#define DES_CBC_ENC_TEST_VECTORS 4 -#define DES_CBC_DEC_TEST_VECTORS 3 -#define DES3_EDE_ENC_TEST_VECTORS 3 -#define DES3_EDE_DEC_TEST_VECTORS 3 - -struct des_tv { - unsigned int len; - int fail; - char key[24]; - char iv[8]; - char plaintext[128]; - char result[128]; -}; - -struct des_tv des_enc_tv_template[] = { - - /* From Applied Cryptography */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d } - }, - - /* Same key, different plaintext block */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0 }, - { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, - { 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b } - }, - - /* Sbox test from NBS */ - { - 8, 0, - - { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 }, - { 0 }, - { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 }, - { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B } - }, - - /* Three blocks */ - { - 24, 0, - - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - - { 0 }, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef }, - - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, - 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, - 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 }, - }, - - /* Weak key */ - { - 8, 1, - - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, - { 0 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d } - }, - - /* Two blocks -- for testing encryption across pages */ - { - 16, 0, - - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - - { 0 }, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, - - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, - 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b } - }, +#define HMAC_MD5_TEST_VECTORS 7 - /* Two blocks -- for testing decryption across pages */ - { - 16, 0, - - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - - { 0 }, - - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, - 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, - }, - - /* Four blocks -- for testing encryption with chunking */ +struct hmac_testvec hmac_md5_tv_template[] = +{ { - 24, 0, - - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - - { 0 }, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, - - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, - 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, - 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90, - 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + .key = { [0 ... 15] = 0x0b }, + .ksize = 16, + .plaintext = "Hi There", + .psize = 8, + .digest = { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }, + }, { + .key = { 'J', 'e', 'f', 'e' }, + .ksize = 4, + .plaintext = "what do ya want for nothing?", + .psize = 28, + .digest = { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }, + .np = 2, + .tap = {14, 14} + }, { + .key = { [0 ... 15] = 0xaa }, + .ksize = 16, + .plaintext = { [0 ... 49] = 0xdd }, + .psize = 50, + .digest = { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }, + }, { + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, }, + .ksize = 25, + .plaintext = { [0 ... 49] = 0xcd }, + .psize = 50, + .digest = { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }, + }, { + .key = { [0 ... 15] = 0x0c }, + .ksize = 16, + .plaintext = "Test With Truncation", + .psize = 20, + .digest = { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First", + .psize = 54, + .digest = { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + .psize = 73, + .digest = { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }, }, - }; -struct des_tv des_dec_tv_template[] = { - - /* From Applied Cryptography */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0 }, - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, - }, - - /* Sbox test from NBS */ - { - 8, 0, +/* + * HMAC-SHA1 test vectors from RFC2202 + */ +#define HMAC_SHA1_TEST_VECTORS 7 - { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 }, - { 0 }, - { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }, - { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 } - }, - - /* Two blocks, for chunking test */ +struct hmac_testvec hmac_sha1_tv_template[] = { { - 16, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0 }, - - { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, - 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, - 0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 } + .key = { [0 ... 19] = 0x0b }, + .ksize = 20, + .plaintext = "Hi There", + .psize = 8, + .digest = { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, + 0x46, 0xbe }, + }, { + .key = { 'J', 'e', 'f', 'e' }, + .ksize = 4, + .plaintext = "what do ya want for nothing?", + .psize = 28, + .digest = { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, + 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }, + .np = 2, + .tap = { 14, 14 } + }, { + .key = { [0 ... 19] = 0xaa }, + .ksize = 20, + .plaintext = { [0 ... 49] = 0xdd }, + .psize = 50, + .digest = { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, + 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 }, + }, { + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 }, + .ksize = 25, + .plaintext = { [0 ... 49] = 0xcd }, + .psize = 50, + .digest = { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, + 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda }, + }, { + .key = { [0 ... 19] = 0x0c }, + .ksize = 20, + .plaintext = "Test With Truncation", + .psize = 20, + .digest = { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First", + .psize = 54, + .digest = { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, + 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + .psize = 73, + .digest = { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, + 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 }, }, - }; -struct des_tv des_cbc_enc_tv_template[] = { - /* From OpenSSL */ - { - 24, 0, - - {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, - - { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, - 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 }, - - { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, - 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, - 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, - 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 } - }, +/* + * HMAC-SHA256 test vectors from + * draft-ietf-ipsec-ciph-sha-256-01.txt + */ +#define HMAC_SHA256_TEST_VECTORS 10 - /* FIPS Pub 81 */ +struct hmac_testvec hmac_sha256_tv_template[] = { { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, - { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, - { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, - + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20}, + .ksize = 32, + .plaintext = "abc", + .psize = 3, + .digest = { 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a, + 0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a, + 0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66, + 0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 }, + }, { + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 }, + .ksize = 32, + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = { 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08, + 0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae, + 0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49, + 0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 }, + }, { + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 }, + .ksize = 32, + .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .psize = 112, + .digest = { 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34, + 0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab, + 0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5, + 0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 }, + }, { + .key = { [0 ... 31] = 0x0b }, + .ksize = 32, + .plaintext = "Hi There", + .psize = 8, + .digest = { 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6, + 0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5, + 0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c, + 0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 }, + }, { + .key = "Jefe", + .ksize = 4, + .plaintext = "what do ya want for nothing?", + .psize = 28, + .digest = { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, + 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, + 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, + 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 }, + .np = 2, + .tap = { 14, 14 } + }, { + .key = { [0 ... 31] = 0xaa }, + .ksize = 32, + .plaintext = { [0 ... 49] = 0xdd }, + .psize = 50, + .digest = { 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea, + 0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62, + 0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc, + 0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 }, + }, { + .key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25 }, + .ksize = 37, + .plaintext = { [0 ... 49] = 0xcd }, + .psize = 50, + .digest = { 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74, + 0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55, + 0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85, + 0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 }, + }, { + .key = { [0 ... 31] = 0x0c }, + .ksize = 32, + .plaintext = "Test With Truncation", + .psize = 20, + .digest = { 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b, + 0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17, + 0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27, + 0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First", + .psize = 54, + .digest = { 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09, + 0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb, + 0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e, + 0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f }, + }, { + .key = { [0 ... 79] = 0xaa }, + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key and Larger Than " + "One Block-Size Data", + .psize = 73, + .digest = { 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3, + 0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8, + 0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc, + 0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 }, }, - - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, - { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, - { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, - }, - - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, - { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, - { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, - }, - - /* Copy of openssl vector for chunk testing */ - - /* From OpenSSL */ - { - 24, 0, - - {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, - {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, - - { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, - 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 }, - - { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, - 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, - 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, - 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 } - }, - - }; -struct des_tv des_cbc_dec_tv_template[] = { +#endif /* CONFIG_CRYPTO_HMAC */ - /* FIPS Pub 81 */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, - { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, - { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, - }, - - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, - { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, - { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, - }, - - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, - { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, - { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, - }, - - /* Copy of above, for chunk testing */ - - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, - { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, - { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, +/* + * DES test vectors. + */ +#define DES_ENC_TEST_VECTORS 10 +#define DES_DEC_TEST_VECTORS 4 +#define DES_CBC_ENC_TEST_VECTORS 5 +#define DES_CBC_DEC_TEST_VECTORS 4 +#define DES3_EDE_ENC_TEST_VECTORS 3 +#define DES3_EDE_DEC_TEST_VECTORS 3 + +struct cipher_testvec des_enc_tv_template[] = { + { /* From Applied Cryptography */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + .ilen = 8, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, + .rlen = 8, + }, { /* Same key, different plaintext block */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + .ilen = 8, + .result = { 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + .rlen = 8, + }, { /* Sbox test from NBS */ + .key = { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }, + .klen = 8, + .input = { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 }, + .ilen = 8, + .result = { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }, + .rlen = 8, + }, { /* Three blocks */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef }, + .ilen = 24, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, + 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 }, + .rlen = 24, + }, { /* Weak key */ + .fail = 1, + .wk = 1, + .key = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + .ilen = 8, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, + .rlen = 8, + }, { /* Two blocks -- for testing encryption across pages */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + .ilen = 16, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + .rlen = 16, + .np = 2, + .tap = { 8, 8 } + }, { /* Four blocks -- for testing encryption with chunking */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + .ilen = 32, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, + 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + .rlen = 32, + .np = 3, + .tap = { 14, 10, 8 } + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef }, + .ilen = 24, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b, + 0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 }, + .rlen = 24, + .np = 4, + .tap = { 2, 1, 3, 18 } + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + .ilen = 16, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }, + .rlen = 16, + .np = 5, + .tap = { 2, 2, 2, 2, 8 } + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + .ilen = 8, + .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, + .rlen = 8, + .np = 8, + .tap = { 1, 1, 1, 1, 1, 1, 1, 1 } + }, +}; + +struct cipher_testvec des_dec_tv_template[] = { + { /* From Applied Cryptography */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 }, + .rlen = 8, + }, { /* Sbox test from NBS */ + .key = { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }, + .klen = 8, + .input = { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }, + .ilen = 8, + .result = { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 }, + .rlen = 8, + }, { /* Two blocks, for chunking test */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }, + .ilen = 16, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 }, + .rlen = 16, + .np = 2, + .tap = { 8, 8 } + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d, + 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }, + .ilen = 16, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7, + 0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 }, + .rlen = 16, + .np = 3, + .tap = { 3, 12, 1 } + }, +}; + +struct cipher_testvec des_cbc_enc_tv_template[] = { + { /* From OpenSSL */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + .klen = 8, + .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + .input = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + .ilen = 24, + .result = { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, + .rlen = 24, + }, { /* FIPS Pub 81 */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, + .input = { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, + .ilen = 8, + .result = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + .input = { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + .ilen = 8, + .result = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + .input = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + .ilen = 8, + .result = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + .rlen = 8, + }, { /* Copy of openssl vector for chunk testing */ + /* From OpenSSL */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + .klen = 8, + .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + .input = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + .ilen = 24, + .result = { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, + .rlen = 24, + .np = 2, + .tap = { 13, 11 } + }, +}; + +struct cipher_testvec des_cbc_dec_tv_template[] = { + { /* FIPS Pub 81 */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }, + .input = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + .ilen = 8, + .result = { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c }, + .input = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + .ilen = 8, + .result = { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + .input = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + .ilen = 8, + .result = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + .rlen = 8, + }, { /* Copy of above, for chunk testing */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .iv = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f }, + .input = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, + .ilen = 8, + .result = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 }, + .rlen = 8, + .np = 2, + .tap = { 4, 4 } }, }; /* * We really need some more test vectors, especially for DES3 CBC. */ -struct des_tv des3_ede_enc_tv_template[] = { - - /* These are from openssl */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, - - { 0 }, - - { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61 }, - - { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, - }, - - { - 8, 0, - - { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, - 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, - 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, - - { 0 }, - - { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, - - { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 } - }, - - - { - 8, 0, - - { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, - 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, - 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, - - { 0 }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - - { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b } +struct cipher_testvec des3_ede_enc_tv_template[] = { + { /* These are from openssl */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + .klen = 24, + .input = { 0x73, 0x6f, 0x6d, 0x65, 0x64, 0x61, 0x74, 0x61 }, + .ilen = 8, + .result = { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, + .rlen = 8, + }, { + .key = { 0x03, 0x52, 0x02, 0x07, 0x67, 0x20, 0x82, 0x17, + 0x86, 0x02, 0x87, 0x66, 0x59, 0x08, 0x21, 0x98, + 0x64, 0x05, 0x6a, 0xbd, 0xfe, 0xa9, 0x34, 0x57 }, + .klen = 24, + .input = { 0x73, 0x71, 0x75, 0x69, 0x67, 0x67, 0x6c, 0x65 }, + .ilen = 8, + .result = { 0xc0, 0x7d, 0x2a, 0x0f, 0xa5, 0x66, 0xfa, 0x30 }, + .rlen = 8, + }, { + .key = { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01, + 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 }, + .klen = 24, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ilen = 8, + .result = { 0xe1, 0xef, 0x62, 0xc3, 0x32, 0xfe, 0x82, 0x5b }, + .rlen = 8, }, }; -struct des_tv des3_ede_dec_tv_template[] = { - - /* These are from openssl */ - { - 8, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, - - { 0 }, - - - { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, - - { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61 }, - }, - - { - 8, 0, - - { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, - 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, - 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, - - { 0 }, - - { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 }, - - { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, - - }, - - - { - 8, 0, - - { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, - 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, - 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, - - { 0 }, - - { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b }, - - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, +struct cipher_testvec des3_ede_dec_tv_template[] = { + { /* These are from openssl */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, + .klen = 24, + .input = { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 }, + .ilen = 8, + .result = { 0x73, 0x6f, 0x6d, 0x65, 0x64, 0x61, 0x74, 0x61 }, + .rlen = 8, + }, { + .key = { 0x03, 0x52, 0x02, 0x07, 0x67, 0x20, 0x82, 0x17, + 0x86, 0x02, 0x87, 0x66, 0x59, 0x08, 0x21, 0x98, + 0x64, 0x05, 0x6a, 0xbd, 0xfe, 0xa9, 0x34, 0x57 }, + .klen = 24, + .input = { 0xc0, 0x7d, 0x2a, 0x0f, 0xa5, 0x66, 0xfa, 0x30 }, + .ilen = 8, + .result = { 0x73, 0x71, 0x75, 0x69, 0x67, 0x67, 0x6c, 0x65 }, + .rlen = 8, + }, { + .key = { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20, + 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01, + 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 }, + .klen = 24, + .input = { 0xe1, 0xef, 0x62, 0xc3, 0x32, 0xfe, 0x82, 0x5b }, + .ilen = 8, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .rlen = 8, }, }; @@ -1090,189 +868,151 @@ #define BF_CBC_ENC_TEST_VECTORS 1 #define BF_CBC_DEC_TEST_VECTORS 1 -struct bf_tv { - unsigned int keylen; - unsigned int plen; - unsigned int rlen; - int fail; - char key[56]; - char iv[8]; - char plaintext[32]; - char result[32]; -}; - -struct bf_tv bf_enc_tv_template[] = { - - /* DES test vectors from OpenSSL */ - { - 8, 8, 8, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, - { 0 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 }, - }, - - { - 8, 8, 8, 0, - { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, }, - { 0 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, - { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE }, - }, - - { - 8, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, }, - { 0 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 } - }, - - /* Vary the keylength... */ - - { - 16, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F }, - { 0 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C } - }, - - { - 21, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, - 0x00, 0x11, 0x22, 0x33, 0x44 }, - { 0 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F } - }, - - /* Generated with bf488 */ - { - 56, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, - 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, - 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 } - } - -}; - -struct bf_tv bf_dec_tv_template[] = { - - /* DES test vectors from OpenSSL */ - { - 8, 8, 8, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, - { 0 }, - { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - - { - 8, 8, 8, 0, - { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, }, - { 0 }, - { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } - }, - - { - 8, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, }, - { 0 }, - { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } - }, - - /* Vary the keylength... */ - - { - 16, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F }, - { 0 }, - { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } - }, - - { - 21, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, - 0x00, 0x11, 0x22, 0x33, 0x44 }, - { 0 }, - { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } - }, - - /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */ - { - 56, 8, 8, 0, - { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, - 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, - 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0 }, - { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }, - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 } - } -}; - -struct bf_tv bf_cbc_enc_tv_template[] = { - - /* From OpenSSL */ - { - 16, 32, 32, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, - - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - - { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, - 0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }, - - { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, - 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, - 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, - 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC } - }, -}; - -struct bf_tv bf_cbc_dec_tv_template[] = { - - /* From OpenSSL */ - { - 16, 32, 32, 0, - - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, - - { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, - - { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, - 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, - 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, - 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC }, - - { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, - 0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 } +struct cipher_testvec bf_enc_tv_template[] = { + { /* DES test vectors from OpenSSL */ + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, + .klen = 8, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ilen = 8, + .result = { 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78 }, + .rlen = 8, + }, { + .key = { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .ilen = 8, + .result = { 0xa7, 0x90, 0x79, 0x51, 0x08, 0xea, 0x3c, 0xae }, + .rlen = 8, + }, { + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + .klen = 8, + .input = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .ilen = 8, + .result = { 0xe8, 0x7a, 0x24, 0x4e, 0x2c, 0xc8, 0x5e, 0x82 }, + .rlen = 8, + }, { /* Vary the keylength... */ + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f }, + .klen = 16, + .input = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .ilen = 8, + .result = { 0x93, 0x14, 0x28, 0x87, 0xee, 0x3b, 0xe1, 0x5c }, + .rlen = 8, + }, { + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0x00, 0x11, 0x22, 0x33, 0x44 }, + .klen = 21, + .input = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .ilen = 8, + .result = { 0xe6, 0xf5, 0x1e, 0xd7, 0x9b, 0x9d, 0xb2, 0x1f }, + .rlen = 8, + }, { /* Generated with bf488 */ + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, + 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, + 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .klen = 56, + .input = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .ilen = 8, + .result = { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }, + .rlen = 8, + }, +}; + +struct cipher_testvec bf_dec_tv_template[] = { + { /* DES test vectors from OpenSSL */ + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .klen = 8, + .input = { 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78 }, + .ilen = 8, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .rlen = 8, + }, { + .key = { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e }, + .klen = 8, + .input = { 0xa7, 0x90, 0x79, 0x51, 0x08, 0xea, 0x3c, 0xae }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .rlen = 8, + }, { + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + .klen = 8, + .input = { 0xe8, 0x7a, 0x24, 0x4e, 0x2c, 0xc8, 0x5e, 0x82 }, + .ilen = 8, + .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .rlen = 8, + }, { /* Vary the keylength... */ + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f }, + .klen = 16, + .input = { 0x93, 0x14, 0x28, 0x87, 0xee, 0x3b, 0xe1, 0x5c }, + .ilen = 8, + .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .rlen = 8, + }, { + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0x00, 0x11, 0x22, 0x33, 0x44 }, + .klen = 21, + .input = { 0xe6, 0xf5, 0x1e, 0xd7, 0x9b, 0x9d, 0xb2, 0x1f }, + .ilen = 8, + .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .rlen = 8, + }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */ + .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, + 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, + 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + .klen = 56, + .input = { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }, + .ilen = 8, + .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .rlen = 8, + }, +}; + +struct cipher_testvec bf_cbc_enc_tv_template[] = { + { /* From OpenSSL */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + .klen = 16, + .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .input = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }, + .ilen = 32, + .result = { 0x6b, 0x77, 0xb4, 0xd6, 0x30, 0x06, 0xde, 0xe6, + 0x05, 0xb1, 0x56, 0xe2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xde, 0xb9, 0xe7, 0x15, 0x46, 0x16, 0xd9, + 0x59, 0xf1, 0x65, 0x2b, 0xd5, 0xff, 0x92, 0xcc }, + .rlen = 32, + }, +}; + +struct cipher_testvec bf_cbc_dec_tv_template[] = { + { /* From OpenSSL */ + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + .klen = 16, + .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + .input = { 0x6b, 0x77, 0xb4, 0xd6, 0x30, 0x06, 0xde, 0xe6, + 0x05, 0xb1, 0x56, 0xe2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xde, 0xb9, 0xe7, 0x15, 0x46, 0x16, 0xd9, + 0x59, 0xf1, 0x65, 0x2b, 0xd5, 0xff, 0x92, 0xcc }, + .ilen = 32, + .result = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }, + .rlen = 32, }, }; @@ -1284,212 +1024,161 @@ #define TF_CBC_ENC_TEST_VECTORS 4 #define TF_CBC_DEC_TEST_VECTORS 4 -struct tf_tv { - unsigned int keylen; - unsigned int plen; - unsigned int rlen; - int fail; - char key[32]; - char iv[16]; - char plaintext[48]; - char result[48]; -}; - -struct tf_tv tf_enc_tv_template[] = { +struct cipher_testvec tf_enc_tv_template[] = { { - 16, 16, 16, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, - 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A } - }, - { - 24, 16, 16, 0, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 0 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, - 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 } - }, - { - 32, 16, 16, 0, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, - { 0 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, - 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 } - }, -}; - -struct tf_tv tf_dec_tv_template[] = { - { - 16, 16, 16, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0 }, - { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, - 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, - { - 24, 16, 16, 0, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 0 }, - { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, - 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, - { - 32, 16, 16, 0, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, - { 0 }, - { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, - 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, -}; - -struct tf_tv tf_cbc_enc_tv_template[] = { - /* Generated with Nettle */ - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, - }, - - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, - }, - - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, - 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, - }, - - { - 16, 48, 48, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, - 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, - 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, - 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, - }, -}; - -struct tf_tv tf_cbc_dec_tv_template[] = { - /* Reverse of the first four above */ - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, - - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, - { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, - - { - 16, 16, 16, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, - { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, - 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - }, - - { - 16, 48, 48, 0, - - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, - 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, - 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, - 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, - 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, - 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .rlen = 16, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + .klen = 24, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf, + 0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48 }, + .rlen = 16, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .klen = 32, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8, + 0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20 }, + .rlen = 16, + }, +}; + +struct cipher_testvec tf_dec_tv_template[] = { + { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .input = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + .klen = 24, + .input = { 0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf, + 0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48 }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .klen = 32, + .input = { 0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8, + 0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20 }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, +}; + +struct cipher_testvec tf_cbc_enc_tv_template[] = { + { /* Generated with Nettle */ + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { [0 ... 15] = 0x00 }, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { [0 ... 15] = 0x00 }, + .input = { [0 ... 47] = 0x00 }, + .ilen = 48, + .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, + 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, + 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + .rlen = 48, + }, +}; + +struct cipher_testvec tf_cbc_dec_tv_template[] = { + { /* Reverse of the first four above */ + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { [0 ... 15] = 0x00 }, + .input = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a }, + .input = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 }, + .input = { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { [0 ... 15] = 0x00 }, + .klen = 16, + .iv = { [0 ... 15] = 0x00 }, + .input = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32, + 0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a, + 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e, + 0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19, + 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26, + 0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 }, + .ilen = 48, + .result = { [0 ... 47] = 0x00 }, + .rlen = 48, }, }; @@ -1500,185 +1189,242 @@ #define SERPENT_ENC_TEST_VECTORS 4 #define SERPENT_DEC_TEST_VECTORS 4 -struct serpent_tv { - unsigned int keylen, fail; - u8 key[32], plaintext[16], result[16]; -}; - -struct serpent_tv serpent_enc_tv_template[] = +struct cipher_testvec serpent_enc_tv_template[] = { { - 0, 0, - { 0 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, - 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 } + .input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .ilen = 16, + .result = { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, + 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .klen = 16, + .input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .ilen = 16, + .result = { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, + 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + .klen = 32, + .input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .ilen = 16, + .result = { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, + 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }, + .rlen = 16, + }, { + .key = { [15] = 0x80 }, + .klen = 16, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, + 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}, + .rlen = 16, }, - { - 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, - 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d } - }, - { - 32, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, - 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c } - }, - { - 16, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, - 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49} - } }; -struct serpent_tv serpent_dec_tv_template[] = +struct cipher_testvec serpent_dec_tv_template[] = { { - 0, 0, - { 0 }, - { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, - 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - + .input = { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47, + 0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }, + .ilen = 16, + .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .klen = 16, + .input = { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, + 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }, + .ilen = 16, + .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + .klen = 32, + .input = { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, + 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }, + .ilen = 16, + .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .rlen = 16, + }, { + .key = { [15] = 0x80 }, + .klen = 16, + .input = { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, + 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, }, +}; + +/* Cast6 test vectors from RFC 2612 */ +#define CAST6_ENC_TEST_VECTORS 3 +#define CAST6_DEC_TEST_VECTORS 3 + +struct cipher_testvec cast6_enc_tv_template[] = +{ { - 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c, - 0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d }, + .klen = 16, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, + 0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b }, + .rlen = 16, + }, { + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 }, + .klen = 24, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, + 0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 }, + .rlen = 16, + }, { + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46, + 0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 }, + .klen = 32, + .input = { [0 ... 15] = 0x00 }, + .ilen = 16, + .result = { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, + 0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa }, + .rlen = 16, }, +}; + +struct cipher_testvec cast6_dec_tv_template[] = +{ { - 32, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - - { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, - 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d }, + .klen = 16, + .input = { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, + 0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 }, + .klen = 24, + .input = { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, + 0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, + }, { + .key = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, + 0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, + 0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46, + 0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 }, + .klen = 32, + .input = { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, + 0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa }, + .ilen = 16, + .result = { [0 ... 15] = 0x00 }, + .rlen = 16, }, - { - 16, 0, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, - { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c, - 0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - } }; + /* * AES test vectors. */ #define AES_ENC_TEST_VECTORS 3 #define AES_DEC_TEST_VECTORS 3 -struct aes_tv { - unsigned int keylen; - unsigned int plen; - unsigned int rlen; - int fail; - char key[32]; - char iv[8]; - char plaintext[16]; - char result[16]; -}; - -struct aes_tv aes_enc_tv_template[] = { - /* From FIPS-197 */ - { - 16, 16, 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0 }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, - 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, - }, - { - 24, 16, 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, - { 0 }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, - 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, - }, - { - 32, 16, 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - { 0 }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, - 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, - }, -}; - -struct aes_tv aes_dec_tv_template[] = { - /* From FIPS-197 */ - { - 16, 16, 16, 0, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0 }, - { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, - 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - }, - - { - 24, 16, 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, - { 0 }, - { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, - 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - }, - { - 32, 16, 16, 0, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - { 0 }, - { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, - 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, +struct cipher_testvec aes_enc_tv_template[] = { + { /* From FIPS-197 */ + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .klen = 16, + .input = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .ilen = 16, + .result = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + .klen = 24, + .input = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .ilen = 16, + .result = { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + .klen = 32, + .input = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .ilen = 16, + .result = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, + .rlen = 16, + }, +}; + +struct cipher_testvec aes_dec_tv_template[] = { + { /* From FIPS-197 */ + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + .klen = 16, + .input = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }, + .ilen = 16, + .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + .klen = 24, + .input = { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }, + .ilen = 16, + .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .rlen = 16, + }, { + .key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + .klen = 32, + .input = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }, + .ilen = 16, + .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + .rlen = 16, }, }; @@ -1686,68 +1432,60 @@ #define CAST5_ENC_TEST_VECTORS 3 #define CAST5_DEC_TEST_VECTORS 3 -struct cast5_tv { - unsigned keylen; - unsigned fail; - u8 key[16]; - u8 plaintext[8]; - u8 ciphertext[8]; -}; - -struct cast5_tv cast5_enc_tv_template[] = +struct cipher_testvec cast5_enc_tv_template[] = { { - 16, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, - 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, - - }, - { - 10, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, - 0x23, 0x45 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, + .key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a }, + .klen = 16, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .ilen = 8, + .result = { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45 }, + .klen = 10, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .ilen = 8, + .result = { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x12 }, + .klen = 5, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .ilen = 8, + .result = { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, + .rlen = 8, }, - { - 5, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, - } }; -struct cast5_tv cast5_dec_tv_template[] = +struct cipher_testvec cast5_dec_tv_template[] = { { - 16, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, - 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A }, - { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - - }, - { - 10, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, - 0x23, 0x45 }, - { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a }, + .klen = 16, + .input = { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45 }, + .klen = 10, + .input = { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x12 }, + .klen = 5, + .input = { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .rlen = 8, }, - { - 5, - 0, - { 0x01, 0x23, 0x45, 0x67, 0x12 }, - { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e }, - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, - } }; /* @@ -1770,83 +1508,73 @@ struct comp_testvec deflate_comp_tv_template[] = { { - 70, 38, - - "Join us now and share the software " - "Join us now and share the software ", - - { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, - 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, - 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, - 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, - 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 - }, - }, - - { - 191, 122, - - "This document describes a compression method based on the DEFLATE" - "compression algorithm. This document defines the application of " - "the DEFLATE algorithm to the IP Payload Compression Protocol.", - - { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, - 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, - 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, - 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, - 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, - 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, - 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, - 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, - 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, - 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, - 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, - 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, - 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, - 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, - 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, - 0xfa, 0x02 }, + .inlen = 70, + .outlen = 38, + .input = "Join us now and share the software " + "Join us now and share the software ", + .output = { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 }, + }, { + .inlen = 191, + .outlen = 122, + .input = "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + .output = { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, }, }; struct comp_testvec deflate_decomp_tv_template[] = { { - 122, 191, - - { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, - 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, - 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, - 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, - 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, - 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, - 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, - 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, - 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, - 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, - 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, - 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, - 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, - 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, - 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, - 0xfa, 0x02 }, - - "This document describes a compression method based on the DEFLATE" - "compression algorithm. This document defines the application of " - "the DEFLATE algorithm to the IP Payload Compression Protocol.", - }, - - { - 38, 70, - - { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, - 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, - 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, - 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, - 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 - }, - - "Join us now and share the software " - "Join us now and share the software ", + .inlen = 122, + .outlen = 191, + .input = { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04, + 0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09, + 0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8, + 0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49, + 0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27, + 0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2, + 0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad, + 0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4, + 0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b, + 0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f, + 0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf, + 0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02, + 0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98, + 0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a, + 0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79, + 0xfa, 0x02 }, + .output = "This document describes a compression method based on the DEFLATE" + "compression algorithm. This document defines the application of " + "the DEFLATE algorithm to the IP Payload Compression Protocol.", + }, { + .inlen = 38, + .outlen = 70, + .input = { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56, + 0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51, + 0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9, + 0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07, + 0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 }, + .output = "Join us now and share the software " + "Join us now and share the software ", }, }; diff -urN linux-2.4.24/crypto/twofish.c linux-2.4.25/crypto/twofish.c --- linux-2.4.24/crypto/twofish.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/crypto/twofish.c 2004-02-18 05:36:31.000000000 -0800 @@ -877,7 +877,6 @@ .cra_u = { .cipher = { .cia_min_keysize = TF_MIN_KEY_SIZE, .cia_max_keysize = TF_MAX_KEY_SIZE, - .cia_ivsize = TF_BLOCK_SIZE, .cia_setkey = twofish_setkey, .cia_encrypt = twofish_encrypt, .cia_decrypt = twofish_decrypt } } diff -urN linux-2.4.24/drivers/acpi/Config.in linux-2.4.25/drivers/acpi/Config.in --- linux-2.4.24/drivers/acpi/Config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -32,7 +32,7 @@ tristate ' Toshiba Laptop Extras' CONFIG_ACPI_TOSHIBA bool ' Debug Statements' CONFIG_ACPI_DEBUG bool ' Relaxed AML Checking' CONFIG_ACPI_RELAXED_AML - else + else if [ "$CONFIG_SMP" = "y" ]; then define_bool CONFIG_ACPI_BOOT y fi diff -urN linux-2.4.24/drivers/acpi/ac.c linux-2.4.25/drivers/acpi/ac.c --- linux-2.4.24/drivers/acpi/ac.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.25/drivers/acpi/ac.c 2004-02-18 05:36:31.000000000 -0800 @@ -93,7 +93,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_ac_dir = NULL; +struct proc_dir_entry *acpi_ac_dir; static int acpi_ac_read_state ( diff -urN linux-2.4.24/drivers/acpi/asus_acpi.c linux-2.4.25/drivers/acpi/asus_acpi.c --- linux-2.4.24/drivers/acpi/asus_acpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/asus_acpi.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,7 +2,7 @@ * asus_acpi.c - Asus Laptop ACPI Extras * * - * Copyright (C) 2002, 2003 Julien Lerouge, Karol Kozimor + * Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,16 +23,16 @@ * http://sourceforge.net/projects/acpi4asus/ * * Credits: + * Pontus Fuchs - Helper functions, cleanup * Johann Wiesner - Small compile fixes * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * * TODO: * add Fn key status * Add mode selection on module loading (parameter) -> still necessary? - * Complete display switching -- may require dirty hacks? + * Complete display switching -- may require dirty hacks or calling _DOS? */ -#include #include #include #include @@ -41,12 +41,13 @@ #include #include -#define ASUS_ACPI_VERSION "0.26" +#define ASUS_ACPI_VERSION "0.27" #define PROC_ASUS "asus" //the directory #define PROC_MLED "mled" #define PROC_WLED "wled" -#define PROC_INFOS "info" +#define PROC_TLED "tled" +#define PROC_INFO "info" #define PROC_LCD "lcd" #define PROC_BRN "brn" #define PROC_DISP "disp" @@ -67,36 +68,40 @@ */ #define MLED_ON 0x01 //is MLED ON ? #define WLED_ON 0x02 +#define TLED_ON 0x04 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); MODULE_DESCRIPTION(ACPI_HOTK_NAME); MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; -static uid_t asus_uid = 0; -static gid_t asus_gid = 0; +static uid_t asus_uid; +static gid_t asus_gid; MODULE_PARM(asus_uid, "i"); MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n"); MODULE_PARM(asus_gid, "i"); MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n"); -/* For each model, all features implemented */ +/* For each model, all features implemented, + * those marked with R are relative to HOTK, A for absolute */ struct model_data { - char *name; //name of the laptop - char *mt_mled; //method to handle mled - char *mled_status; //node to handle mled reading - char *mt_wled; //method to handle wled - char *wled_status; //node to handle wled reading - char *mt_lcd_switch; //method to turn LCD ON/OFF - char *lcd_status; //node to read LCD panel state - char *brightness_up; //method to set brightness up - char *brightness_down; //guess what ? - char *brightness_set; //method to set absolute brightness - char *brightness_get; //method to get absolute brightness - char *brightness_status;//node to get brightness - char *display_set; //method to set video output - char *display_get; //method to get video output + char *name; //name of the laptop________________A + char *mt_mled; //method to handle mled_____________R + char *mled_status; //node to handle mled reading_______A + char *mt_wled; //method to handle wled_____________R + char *wled_status; //node to handle wled reading_______A + char *mt_tled; //method to handle tled_____________R + char *tled_status; //node to handle tled reading_______A + char *mt_lcd_switch; //method to turn LCD ON/OFF_________A + char *lcd_status; //node to read LCD panel state______A + char *brightness_up; //method to set brightness up_______A + char *brightness_down; //guess what ?______________________A + char *brightness_set; //method to set absolute brightness_R + char *brightness_get; //method to get absolute brightness_R + char *brightness_status; //node to get brightness____________A + char *display_set; //method to set video output________R + char *display_get; //method to get video output________R }; /* @@ -104,102 +109,250 @@ * about the hotk device */ struct asus_hotk { - struct acpi_device *device; //the device we are in - acpi_handle handle; //the handle of the hotk device - char status; //status of the hotk, for LEDs, ... - struct model_data *methods; //methods available on the laptop - u8 brightness; //brighness level + struct acpi_device *device; //the device we are in + acpi_handle handle; //the handle of the hotk device + char status; //status of the hotk, for LEDs, ... + struct model_data *methods; //methods available on the laptop + u8 brightness; //brightness level enum { - A1X=0, //A1340D, A1300F - A2X, //A2500H - D1X, //D1 - L1X, //L1400B - L2X, //L2000D -> TODO check Q11 (Fn+F8) - // Calling this method simply hangs the - // computer, ISMI method hangs the laptop. - L3D, //L3400D - L3X, //L3C - L5X, //L5C TODO this model seems to have one more - // LED, add support - M2X, //M2400E - M3N, //M3700N, but also S1300N -> TODO WLED - S1X, //S1300A -> TODO special keys do not work ? - S2X, //S200 (J1 reported), Victor MP-XP7210 - //TODO A1370D does not seem to have an ATK device - // L8400 model doesn't have ATK + A1x = 0, //A1340D, A1300F + A2x, //A2500H + D1x, //D1 + L2D, //L2000D + L3C, //L3800C + L3D, //L3400D + L3H, //L3H, but also L2000E + L5x, //L5800C + L8L, //L8400L + M1A, //M1300A + M2E, //M2400E + S1x, //S1300A, but also L1400B and M2400A (L84F) + S2x, //S200 (J1 reported), Victor MP-XP7210 + //TODO A1370D does not seem to have an ATK device + // L8400 model doesn't have ATK + xxN, //M2400N, M3700N, S1300N (Centrino) END_MODEL - } model; //Models currently supported - u16 event_count[128]; //count for each event TODO make this better + } model; //Models currently supported + u16 event_count[128]; //count for each event TODO make this better }; /* Here we go */ -#define L3X_PREFIX "\\_SB.PCI0.PX40.ECD0." -#define S1X_PREFIX "\\_SB.PCI0.PX40." -#define L1X_PREFIX S1X_PREFIX -#define A1X_PREFIX "\\_SB.PCI0.ISA.EC0." -#define S2X_PREFIX A1X_PREFIX -#define M3N_PREFIX "\\_SB.PCI0.SBRG.EC0." +#define A1x_PREFIX "\\_SB.PCI0.ISA.EC0." +#define L3C_PREFIX "\\_SB.PCI0.PX40.ECD0." +#define M1A_PREFIX "\\_SB.PCI0.PX40.EC0." +#define S1x_PREFIX "\\_SB.PCI0.PX40." +#define S2x_PREFIX A1x_PREFIX +#define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0." static struct model_data model_conf[END_MODEL] = { /* - * name| mled |mled read| wled |wled read| lcd sw |lcd read | - * br up|br down | br set | br read | br status|set disp | get disp - * - * br set and read shall be in hotk device ! - * same for set disp + * Those pathnames are relative to the HOTK / ATKD device : + * - mt_mled + * - mt_wled + * - brightness_set + * - brightness_get + * - display_set + * - display_get * * TODO I have seen a SWBX and AIBX method on some models, like L1400B, * it seems to be a kind of switch, but what for ? * */ - {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI", - A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL}, - - {"A2X", "MLED", NULL, "WLED", "\\SG66", "\\Q10", "\\BAOF", - "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\CMOD", "SDSP", "\\INFB"}, - - {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", - "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"}, - {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", - L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, - - {"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0", - "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"}, - - {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG", - "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"}, - - {"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32", - L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP", - "\\_SB.PCI0.PCI1.VGAC.NMAP"}, - - {"L5X", "MLED", NULL, "WLED", "WRED", "\\Q0D", "\\BAOF", - "\\Q0C","\\Q0B", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"}, - - {"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06", - "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"}, - - {"M3N", "MLED", NULL, "WLED", "\\PO33", M3N_PREFIX "_Q10", "\\BKLT", - M3N_PREFIX "_Q0F", M3N_PREFIX "_Q0E", "SPLV", "GPLV", "\\LBTN", "SDSP", - "\\ADVG"}, - - {"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF", - S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL}, - - {"S2X", "MLED", "\\MAIL", NULL, NULL, S2X_PREFIX "_Q10", "\\BKLI", - S2X_PREFIX "_Q0B", S2X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL} + { + .name = "A1x", + .mt_mled = "MLED", + .mled_status = "\\MAIL", + .mt_lcd_switch = A1x_PREFIX "_Q10", + .lcd_status = "\\BKLI", + .brightness_up = A1x_PREFIX "_Q0E", + .brightness_down = A1x_PREFIX "_Q0F", + }, + + { + .name = "A2x", + .mt_mled = "MLED", + .mt_wled = "WLED", + .wled_status = "\\SG66", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\BAOF", + .brightness_up = "\\Q0E", + .brightness_down = "\\Q0F", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .brightness_status = "\\CMOD", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "D1x", + .mt_mled = "MLED", + .mt_lcd_switch = "\\Q0D", + .lcd_status = "\\GP11", + .brightness_up = "\\Q0C", + .brightness_down = "\\Q0B", + .brightness_status = "\\BLVL", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "L2D", + .mt_mled = "MLED", + .mled_status = "\\SGP6", + .mt_wled = "WLED", + .wled_status = "\\RCP3", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\SGP0", + .brightness_up = "\\Q0E", + .brightness_down = "\\Q0F", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "L3C", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = L3C_PREFIX "_Q10", + .lcd_status = "\\GL32", + .brightness_up = L3C_PREFIX "_Q0F", + .brightness_down = L3C_PREFIX "_Q0E", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .brightness_status = "\\BLVL", + .display_set = "SDSP", + .display_get = "\\_SB.PCI0.PCI1.VGAC.NMAP" + }, + + { + .name = "L3D", + .mt_mled = "MLED", + .mled_status = "\\MALD", + .mt_wled = "WLED", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\BKLG", + .brightness_up = "\\Q0E", + .brightness_down = "\\Q0F", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .brightness_status = "\\BLVL", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "L3H", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = "EHK", + .lcd_status = "\\_SB.PCI0.PM.PBC", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "L5x", + .mt_mled = "MLED", +// .mt_wled = "WLED", +// .wled_status = "\\WRED", +/* Present, but not controlled by ACPI */ + .mt_tled = "TLED", + .mt_lcd_switch = "\\Q0D", + .lcd_status = "\\BAOF", + .brightness_up = "\\Q0C", + .brightness_down = "\\Q0B", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "L8L" +/* No features, but at least support the hotkeys */ + }, + + { + .name = "M1A", + .mt_mled = "MLED", + .mt_lcd_switch = M1A_PREFIX "Q10", + .lcd_status = "\\PNOF", + .brightness_up = M1A_PREFIX "Q0E", + .brightness_down = M1A_PREFIX "Q0F", + .brightness_status = "\\BRIT", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "M2E", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\GP06", + .brightness_up = "\\Q0E", + .brightness_down = "\\Q0F", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB" + }, + + { + .name = "S1x", + .mt_mled = "MLED", + .mled_status = "\\EMLE", + .mt_wled = "WLED", + .mt_lcd_switch = S1x_PREFIX "Q10" , + .lcd_status = "\\PNOF", + .brightness_up = S1x_PREFIX "Q0F", + .brightness_down = S1x_PREFIX "Q0E", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .brightness_status = "\\BRIT", + }, + + { + .name = "S2x", + .mt_mled = "MLED", + .mled_status = "\\MAIL", + .mt_lcd_switch = S2x_PREFIX "_Q10", + .lcd_status = "\\BKLI", + .brightness_up = S2x_PREFIX "_Q0B", + .brightness_down = S2x_PREFIX "_Q0A", + }, + + { + .name = "xxN", + .mt_mled = "MLED", +// .mt_wled = "WLED", +// .wled_status = "\\PO33", +/* Present, but not controlled by ACPI */ + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\BKLT", + .brightness_up = xxN_PREFIX "_Q0F", + .brightness_down = xxN_PREFIX "_Q0E", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .brightness_status = "\\LBTN", + .display_set = "SDSP", + .display_get = "\\ADVG" + } }; /* procdir we use */ -static struct proc_dir_entry *asus_proc_dir = NULL; +static struct proc_dir_entry *asus_proc_dir; /* * This header is made available to allow proper configuration given model, * revision number , ... this info cannot go in struct asus_hotk because it is * available before the hotk */ -static struct acpi_table_header *asus_info = NULL; +static struct acpi_table_header *asus_info; /* * The hotkey driver declaration @@ -264,7 +417,7 @@ void *data) { int len = 0; - int sfun; + int temp; struct asus_hotk *hotk = (struct asus_hotk *) data; char buf[16]; //enough for all info /* @@ -275,8 +428,23 @@ len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); len += sprintf(page + len, "Model reference : %s\n", hotk->methods->name); - if(read_acpi_int(hotk->handle, "SFUN", &sfun)) - len += sprintf(page + len, "SFUN value : 0x%04x\n", sfun); + /* + * The SFUN method probably allows the original driver to get the list + * of features supported by a given model. For now, 0x0100 or 0x0800 + * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. + * The significance of others is yet to be found. + */ + if (read_acpi_int(hotk->handle, "SFUN", &temp)) + len += sprintf(page + len, "SFUN value : 0x%04x\n", temp); + /* + * Another value for userspace: the ASYM method returns 0x02 for + * battery low and 0x04 for battery critical, it's readings tend to be + * more accurate than those provided by _BST. + * Note: since not all the laptops provide this method, errors are + * silently ignored. + */ + if (read_acpi_int(hotk->handle, "ASYM", &temp)) + len += sprintf(page + len, "ASYM value : 0x%04x\n", temp); if (asus_info) { snprintf(buf, 16, "%d", asus_info->length); len += sprintf(page + len, "DSDT length : %s\n", buf); @@ -300,128 +468,179 @@ } -/* - * proc file handlers +/* + * /proc handlers + * We write our info in page, we begin at offset off and cannot write more + * than count bytes. We set eof to 1 if we handle those 2 values. We return the + * number of bytes written in page */ + +/* Generic LED functions */ static int -proc_read_mled(char *page, char **start, off_t off, int count, int *eof, - void *data) +read_led(struct asus_hotk *hotk, const char *ledname, int ledmask) { - int len = 0; - struct asus_hotk *hotk = (struct asus_hotk *) data; - int led_status = 0; - /* - * We use the easy way, we don't care of off and count, so we don't set eof - * to 1 - */ - if (hotk->methods->mled_status) { - if (read_acpi_int(NULL, hotk->methods->mled_status, - &led_status)) - len = sprintf(page, "%d\n", led_status); + if (ledname) { + int led_status; + + if (read_acpi_int(NULL, ledname, &led_status)) + return led_status; else - printk(KERN_WARNING "Asus ACPI: Error reading MLED " + printk(KERN_WARNING "Asus ACPI: Error reading LED " "status\n"); - } else { - len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0); } - - return len; + return (hotk->status & ledmask) ? 1 : 0; } +/* FIXME: kill extraneous args so it can be called independently */ static int -proc_write_mled(struct file *file, const char *buffer, - unsigned long count, void *data) +write_led(const char *buffer, unsigned long count, struct asus_hotk *hotk, + char *ledname, int ledmask, int invert) { int value; int led_out = 0; - struct asus_hotk *hotk = (struct asus_hotk *) data; - - - /* scan expression. Multiple expressions may be delimited with ; */ if (sscanf(buffer, "%i", &value) == 1) - led_out = ~value & 1; + led_out = value ? 1 : 0; hotk->status = - (value) ? (hotk->status | MLED_ON) : (hotk->status & ~MLED_ON); - - /* We don't have to check mt_mled exists if we are here :) */ - if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out, - NULL)) - printk(KERN_WARNING "Asus ACPI: MLED write failed\n"); + (led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask); + if (invert) /* invert target value */ + led_out = !led_out & 0x1; + if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) + printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", ledname); return count; } + /* - * We write our info in page, we begin at offset off and cannot write more - * than count bytes. We set eof to 1 if we handle those 2 values. We return the - * number of bytes written in page + * Proc handlers for MLED */ static int -proc_read_wled(char *page, char **start, off_t off, int count, int *eof, +proc_read_mled(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = 0; struct asus_hotk *hotk = (struct asus_hotk *) data; - int led_status; + return sprintf(page, "%d\n", read_led(hotk, hotk->methods->mled_status, MLED_ON)); +} - if (hotk->methods->wled_status) { - if (read_acpi_int(NULL, hotk->methods->wled_status, - &led_status)) - len = sprintf(page, "%d\n", led_status); - else - printk(KERN_WARNING "Asus ACPI: Error reading WLED " - "status\n"); - } else { - len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0); - } - return len; +static int +proc_write_mled(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct asus_hotk *hotk = (struct asus_hotk *) data; + return write_led(buffer, count, hotk, hotk->methods->mt_mled, MLED_ON, 1); +} + +/* + * Proc handlers for WLED + */ +static int +proc_read_wled(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + struct asus_hotk *hotk = (struct asus_hotk *) data; + return sprintf(page, "%d\n", read_led(hotk, hotk->methods->wled_status, WLED_ON)); } static int proc_write_wled(struct file *file, const char *buffer, unsigned long count, void *data) { - int value; - int led_out = 0; struct asus_hotk *hotk = (struct asus_hotk *) data; + return write_led(buffer, count, hotk, hotk->methods->mt_wled, WLED_ON, 0); +} - /* scan expression. Multiple expressions may be delimited with ; */ - if (sscanf(buffer, "%i", &value) == 1) - led_out = value & 1; - - hotk->status = - (value) ? (hotk->status | WLED_ON) : (hotk->status & ~WLED_ON); - - /* We don't have to check if mt_wled exists if we are here :) */ - if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out, - NULL)) - printk(KERN_WARNING "Asus ACPI: WLED write failed\n"); - +/* + * Proc handlers for TLED + */ +static int +proc_read_tled(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + struct asus_hotk *hotk = (struct asus_hotk *) data; + return sprintf(page, "%d\n", read_led(hotk, hotk->methods->tled_status, TLED_ON)); +} - return count; +static int +proc_write_tled(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct asus_hotk *hotk = (struct asus_hotk *) data; + return write_led(buffer, count, hotk, hotk->methods->mt_tled, TLED_ON, 0); } + static int get_lcd_state(struct asus_hotk *hotk) { int lcd = 0; - /* We don't have to check anything, if we are here */ - if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) - printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n"); + if (hotk->model != L3H) { + /* We don't have to check anything if we are here */ + if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) + printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n"); - if (hotk->model == L2X) - lcd = ~lcd; + if (hotk->model == L2D) + lcd = ~lcd; + } else { /* L3H and the like have to be handled differently */ + acpi_status status = 0; + struct acpi_object_list input; + union acpi_object mt_params[2]; + struct acpi_buffer output; + union acpi_object out_obj; + + input.count = 2; + input.pointer = mt_params; + /* Note: the following values are partly guessed up, but + otherwise they seem to work */ + mt_params[0].type = ACPI_TYPE_INTEGER; + mt_params[0].integer.value = 0x02; + mt_params[1].type = ACPI_TYPE_INTEGER; + mt_params[1].integer.value = 0x02; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(NULL, hotk->methods->lcd_status, &input, &output); + if (status != AE_OK) + return -1; + if (out_obj.type == ACPI_TYPE_INTEGER) + /* That's what the AML code does */ + lcd = out_obj.integer.value >> 8; + } return (lcd & 1); } +static int set_lcd_state(struct asus_hotk *hotk, int value) +{ + int lcd = 0; + acpi_status status = 0; + + lcd = value ? 1 : 0; + if (lcd != get_lcd_state(hotk)) { + /* switch */ + if (hotk->model != L3H) { + status = + acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch, + NULL, NULL); + } else { /* L3H and the like have to be handled differently */ + if (!write_acpi_int(hotk->handle, hotk->methods->mt_lcd_switch, 0x07, NULL)) + status = AE_ERROR; + /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, + the exact behaviour is simulated here */ + } + if (ACPI_FAILURE(status)) + printk(KERN_WARNING "Asus ACPI: Error switching LCD\n"); + } + return 0; + +} static int proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, @@ -436,26 +655,10 @@ unsigned long count, void *data) { int value; - int lcd = 0; - acpi_status status = 0; - int lcd_status = 0; struct asus_hotk *hotk = (struct asus_hotk *) data; - - /* scan expression. Multiple expressions may be delimited with ; */ + if (sscanf(buffer, "%i", &value) == 1) - lcd = value & 1; - - lcd_status = get_lcd_state(hotk); - - if (lcd_status != lcd) { - /* switch */ - status = - acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch, - NULL, NULL); - if (ACPI_FAILURE(status)) - printk(KERN_WARNING "Asus ACPI: Error switching LCD\n"); - } - + set_lcd_state(hotk, value); return count; } @@ -521,7 +724,6 @@ int value; struct asus_hotk *hotk = (struct asus_hotk *) data; - /* scan expression. Multiple expressions may be delimited with ; */ if (sscanf(buffer, "%d", &value) == 1) { value = (0 < value) ? ((15 < value) ? 15 : value) : 0; /* 0 <= value <= 15 */ @@ -546,7 +748,6 @@ * Now, *this* one could be more user-friendly, but so far, no-one has * complained. The significance of bits is the same as in proc_write_disp() */ - static int proc_read_disp(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -560,12 +761,11 @@ } /* - * Experimental support for display switching. As of now: 0x01 should activate - * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination + * Experimental support for display switching. As of now: 1 should activate + * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination * (bitwise) of these will suffice. I never actually tested 3 displays hooked up - * simultaneously, so be warned. + * simultaneously, so be warned. See the acpi4asus README for more info. */ - static int proc_write_disp(struct file *file, const char *buffer, unsigned long count, void *data) @@ -573,7 +773,6 @@ int value; struct asus_hotk *hotk = (struct asus_hotk *) data; - /* scan expression. Multiple expressions may be delimited with ; */ if (sscanf(buffer, "%d", &value) == 1) set_display(value, hotk); else { @@ -583,6 +782,31 @@ return count; } + +typedef int (proc_readfunc)(char *page, char **start, off_t off, int count, + int *eof, void *data); +typedef int (proc_writefunc)(struct file *file, const char *buffer, + unsigned long count, void *data); + +static int +__init asus_proc_add(char *name, proc_writefunc *writefunc, + proc_readfunc *readfunc, mode_t mode, + struct acpi_device *device) +{ + struct proc_dir_entry *proc = create_proc_entry(name, mode, acpi_device_dir(device)); + if(!proc) { + printk(KERN_WARNING " Unable to create %s fs entry\n", name); + return -1; + } + proc->write_proc = writefunc; + proc->read_proc = readfunc; + proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid; + return 0; +} + static int __init asus_hotk_add_fs(struct acpi_device *device) { struct proc_dir_entry *proc; @@ -605,46 +829,28 @@ if (!acpi_device_dir(device)) return(-ENODEV); - proc = create_proc_entry(PROC_INFOS, mode, acpi_device_dir(device)); + proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device)); if (proc) { proc->read_proc = proc_read_info; proc->data = acpi_driver_data(device); proc->owner = THIS_MODULE; proc->uid = asus_uid; - proc->gid = asus_gid;; + proc->gid = asus_gid; } else { - printk(KERN_WARNING " Unable to create " PROC_INFOS + printk(KERN_WARNING " Unable to create " PROC_INFO " fs entry\n"); } if (hotk->methods->mt_wled) { - proc = create_proc_entry(PROC_WLED, mode, acpi_device_dir(device)); - if (proc) { - proc->write_proc = proc_write_wled; - proc->read_proc = proc_read_wled; - proc->data = acpi_driver_data(device); - proc->owner = THIS_MODULE; - proc->uid = asus_uid; - proc->gid = asus_gid;; - } else { - printk(KERN_WARNING " Unable to create " PROC_WLED - " fs entry\n"); - } + asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, mode, device); } if (hotk->methods->mt_mled) { - proc = create_proc_entry(PROC_MLED, mode, acpi_device_dir(device)); - if (proc) { - proc->write_proc = proc_write_mled; - proc->read_proc = proc_read_mled; - proc->data = acpi_driver_data(device); - proc->owner = THIS_MODULE; - proc->uid = asus_uid; - proc->gid = asus_gid;; - } else { - printk(KERN_WARNING " Unable to create " PROC_MLED - " fs entry\n"); - } + asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, mode, device); + } + + if (hotk->methods->mt_tled) { + asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, mode, device); } /* @@ -652,49 +858,17 @@ * from keyboard */ if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { - proc = create_proc_entry(PROC_LCD, mode, acpi_device_dir(device)); - if (proc) { - proc->write_proc = proc_write_lcd; - proc->read_proc = proc_read_lcd; - proc->data = acpi_driver_data(device); - proc->owner = THIS_MODULE; - proc->uid = asus_uid; - proc->gid = asus_gid;; - } else { - printk(KERN_WARNING " Unable to create " PROC_LCD - " fs entry\n"); - } + asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, device); } if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || (hotk->methods->brightness_get && hotk->methods->brightness_get)) { - proc = create_proc_entry(PROC_BRN, mode, acpi_device_dir(device)); - if (proc) { - proc->write_proc = proc_write_brn; - proc->read_proc = proc_read_brn; - proc->data = acpi_driver_data(device); - proc->owner = THIS_MODULE; - proc->uid = asus_uid; - proc->gid = asus_gid;; - } else { - printk(KERN_WARNING " Unable to create " PROC_BRN - " fs entry\n"); - } + asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, device); } if (hotk->methods->display_set) { - proc = create_proc_entry(PROC_DISP, mode, acpi_device_dir(device)); - if (proc) { - proc->write_proc = proc_write_disp; - proc->read_proc = proc_read_disp; - proc->data = acpi_driver_data(device); - proc->owner = THIS_MODULE; - proc->uid = asus_uid; - proc->gid = asus_gid;; - } else { - printk(KERN_WARNING " Unable to create " PROC_DISP - " fs entry\n"); - } + asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, mode, device); + } return 0; @@ -761,11 +935,6 @@ else if (bsts_result) printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", bsts_result); - /* - * Here, we also use asus_info to make decision. For example, on INIT - * method, S1X and L1X models both reports to be L84F, but they don't - * have the same methods (L1X has WLED, S1X don't) - */ model = (union acpi_object *) buffer.pointer; if (model->type == ACPI_TYPE_STRING) { printk(KERN_NOTICE " %s model detected, ", model->string.pointer); @@ -774,52 +943,63 @@ hotk->model = END_MODEL; if (strncmp(model->string.pointer, "L3D", 3) == 0) hotk->model = L3D; - /* - * L2B has same settings that L3X, except for GL32, but as - * there is no node to get the LCD status, and as GL32 is never - * used anywhere else, I assume it's safe, even if lcd get is - * broken for this model (TODO fix it ?) - */ + else if (strncmp(model->string.pointer, "L3H", 3) == 0 || + strncmp(model->string.pointer, "L2E", 3) == 0) + hotk->model = L3H; else if (strncmp(model->string.pointer, "L3", 2) == 0 || strncmp(model->string.pointer, "L2B", 3) == 0) - hotk->model = L3X; + hotk->model = L3C; + else if (strncmp(model->string.pointer, "L8L", 3) == 0) + hotk->model = L8L; + else if (strncmp(model->string.pointer, "M2N", 3) == 0 || + strncmp(model->string.pointer, "M3N", 3) == 0 || + strncmp(model->string.pointer, "S1N", 3) == 0 || + strncmp(model->string.pointer, "S5N", 3) == 0) + hotk->model = xxN; + else if (strncmp(model->string.pointer, "M1", 2) == 0) + hotk->model = M1A; else if (strncmp(model->string.pointer, "M2", 2) == 0) - hotk->model = M2X; - else if (strncmp(model->string.pointer, "M3N", 3) == 0 || - strncmp(model->string.pointer, "S1N", 3) == 0) - hotk->model = M3N; /* S1300N is similar enough */ + hotk->model = M2E; else if (strncmp(model->string.pointer, "L2", 2) == 0) - hotk->model = L2X; - else if (strncmp(model->string.pointer, "L8", 2) == 0) { - /* S1300A reports L84F, but L1400B too */ - if (asus_info) { - if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) - hotk->model = L1X; - } else - hotk->model = S1X; - } + hotk->model = L2D; + else if (strncmp(model->string.pointer, "L8", 2) == 0) + hotk->model = S1x; else if (strncmp(model->string.pointer, "D1", 2) == 0) - hotk->model = D1X; + hotk->model = D1x; else if (strncmp(model->string.pointer, "A1", 2) == 0) - hotk->model = A1X; + hotk->model = A1x; else if (strncmp(model->string.pointer, "A2", 2) == 0) - hotk->model = A2X; + hotk->model = A2x; else if (strncmp(model->string.pointer, "J1", 2) == 0) - hotk->model = S2X; + hotk->model = S2x; else if (strncmp(model->string.pointer, "L5", 2) == 0) - hotk->model = L5X; + hotk->model = L5x; if (hotk->model == END_MODEL) { /* By default use the same values, as I don't know others */ printk("unsupported, trying default values, supply the " "developers with your DSDT\n"); - hotk->model = L2X; + hotk->model = M2E; } else { printk("supported\n"); } hotk->methods = &model_conf[hotk->model]; + /* Sort of per-model blacklist */ + if (strncmp(model->string.pointer, "L2B", 3) == 0) + hotk->methods->lcd_status = NULL; + /* L2B is similar enough to L3C to use its settings, with this only + exception */ + else if (strncmp(model->string.pointer, "S5N", 3) == 0) + hotk->methods->mt_mled = NULL; + /* S5N has no MLED */ + else if (asus_info) { + if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) + hotk->methods->mled_status = NULL; + /* S1300A reports L84F, but L1400B too, account for that */ + } + acpi_os_free(model); return AE_OK; @@ -917,8 +1097,6 @@ } - - static int asus_hotk_remove(struct acpi_device *device, int type) { acpi_status status = 0; @@ -940,15 +1118,13 @@ } - - static int __init asus_acpi_init(void) { int result; asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); if (!asus_proc_dir) { - printk(KERN_ERR "Asus ACPI: Unable to create /proc entry"); + printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); return(-ENODEV); } asus_proc_dir->owner = THIS_MODULE; @@ -963,7 +1139,6 @@ } - static void __exit asus_acpi_exit(void) { acpi_bus_unregister_driver(&asus_hotk_driver); diff -urN linux-2.4.24/drivers/acpi/battery.c linux-2.4.25/drivers/acpi/battery.c --- linux-2.4.24/drivers/acpi/battery.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/battery.c 2004-02-18 05:36:31.000000000 -0800 @@ -328,7 +328,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_battery_dir = NULL; +struct proc_dir_entry *acpi_battery_dir; static int acpi_battery_read_info ( diff -urN linux-2.4.24/drivers/acpi/bus.c linux-2.4.25/drivers/acpi/bus.c --- linux-2.4.24/drivers/acpi/bus.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/bus.c 2004-02-18 05:36:31.000000000 -0800 @@ -2047,8 +2047,10 @@ #endif result = acpi_bus_init(); - if (result) + if (result) { + acpi_disabled = 1; return_VALUE(result); + } #ifdef CONFIG_PM pm_active = 1; diff -urN linux-2.4.24/drivers/acpi/button.c linux-2.4.25/drivers/acpi/button.c --- linux-2.4.24/drivers/acpi/button.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/button.c 2004-02-18 05:36:31.000000000 -0800 @@ -68,7 +68,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -static struct proc_dir_entry *acpi_button_dir = NULL; +static struct proc_dir_entry *acpi_button_dir; static int acpi_button_read_info ( diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsfield.c linux-2.4.25/drivers/acpi/dispatcher/dsfield.c --- linux-2.4.24/drivers/acpi/dispatcher/dsfield.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dsfield.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsinit.c linux-2.4.25/drivers/acpi/dispatcher/dsinit.c --- linux-2.4.24/drivers/acpi/dispatcher/dsinit.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dsinit.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,7 +106,7 @@ status = acpi_ds_initialize_region (obj_handle); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n", - obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii, + obj_handle, acpi_ut_get_node_name (obj_handle), acpi_format_exception (status))); } @@ -141,7 +141,7 @@ status = acpi_ds_parse_method (obj_handle); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n", - obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii, + obj_handle, acpi_ut_get_node_name (obj_handle), acpi_format_exception (status))); /* This parse failed, but we will continue parsing more methods */ diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsmethod.c linux-2.4.25/drivers/acpi/dispatcher/dsmethod.c --- linux-2.4.24/drivers/acpi/dispatcher/dsmethod.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/dispatcher/dsmethod.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,7 +94,7 @@ } ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n", - ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle)); + acpi_ut_get_node_name (obj_handle), obj_handle)); /* Extract the method object from the method Node */ @@ -169,7 +169,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", - ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle, op)); + acpi_ut_get_node_name (obj_handle), obj_handle, op)); acpi_ps_delete_parse_tree (op); return_ACPI_STATUS (status); diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsmthdat.c linux-2.4.25/drivers/acpi/dispatcher/dsmthdat.c --- linux-2.4.24/drivers/acpi/dispatcher/dsmthdat.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/dispatcher/dsmthdat.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -203,9 +203,10 @@ while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) { /* * A valid parameter. - * Store the argument in the method/walk descriptor + * Store the argument in the method/walk descriptor. + * Do not copy the arg in order to implement call by reference */ - status = acpi_ds_store_object_to_local (AML_ARG_OP, index, params[index], + status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -567,13 +568,13 @@ acpi_status status; struct acpi_namespace_node *node; union acpi_operand_object *current_obj_desc; + union acpi_operand_object *new_obj_desc; ACPI_FUNCTION_TRACE ("ds_store_object_to_local"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", opcode, index, obj_desc)); - /* Parameter validation */ if (!obj_desc) { @@ -595,6 +596,18 @@ } /* + * If the reference count on the object is more than one, we must + * take a copy of the object before we store. + */ + new_obj_desc = obj_desc; + if (obj_desc->common.reference_count > 1) { + status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do @@ -624,8 +637,8 @@ * operand objects of type Reference. */ if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) { - ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: %X\n", - current_obj_desc->common.type)); + ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n", + acpi_ut_get_descriptor_name (current_obj_desc))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -636,15 +649,21 @@ if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) && (current_obj_desc->reference.opcode == AML_REF_OF_OP)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Arg (%p) is an obj_ref(Node), storing in node %p\n", - obj_desc, current_obj_desc)); + "Arg (%p) is an obj_ref(Node), storing in node %p\n", + new_obj_desc, current_obj_desc)); /* * Store this object to the Node * (perform the indirect store) */ - status = acpi_ex_store_object_to_node (obj_desc, + status = acpi_ex_store_object_to_node (new_obj_desc, current_obj_desc->reference.object, walk_state); + + /* Remove local reference if we copied the object above */ + + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } return_ACPI_STATUS (status); } } @@ -657,12 +676,18 @@ } /* - * Install the obj_stack descriptor (*obj_desc) into + * Install the Obj descriptor (*new_obj_desc) into * the descriptor for the Arg or Local. - * Install the new object in the stack entry * (increments the object reference count by one) */ - status = acpi_ds_method_data_set_value (opcode, index, obj_desc, walk_state); + status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state); + + /* Remove local reference if we copied the object above */ + + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } + return_ACPI_STATUS (status); } diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsobject.c linux-2.4.25/drivers/acpi/dispatcher/dsobject.c --- linux-2.4.24/drivers/acpi/dispatcher/dsobject.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/dispatcher/dsobject.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsopcode.c linux-2.4.25/drivers/acpi/dispatcher/dsopcode.c --- linux-2.4.24/drivers/acpi/dispatcher/dsopcode.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dsopcode.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -201,7 +201,7 @@ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n", - node->name.ascii)); + acpi_ut_get_node_name (node))); /* Execute the AML code for the term_arg arguments */ @@ -346,7 +346,7 @@ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n", - node->name.ascii, extra_desc->extra.aml_start)); + acpi_ut_get_node_name (node), extra_desc->extra.aml_start)); /* Execute the argument AML */ @@ -438,8 +438,8 @@ * after resolution in acpi_ex_resolve_operands(). */ if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n", - acpi_ps_get_opcode_name (aml_opcode))); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n", + acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc))); status = AE_AML_OPERAND_TYPE; goto cleanup; @@ -514,14 +514,16 @@ goto cleanup; } - /* Entire field must fit within the current length of the buffer */ if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Field size %d exceeds Buffer size %d (bits)\n", - bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length)); + "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", + acpi_ut_get_node_name (result_desc), + bit_offset + bit_count, + acpi_ut_get_node_name (buffer_desc->buffer.node), + 8 * (u32) buffer_desc->buffer.length)); status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -742,7 +744,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n", obj_desc, - ACPI_HIDWORD (obj_desc->region.address), ACPI_LODWORD (obj_desc->region.address), + ACPI_FORMAT_UINT64 (obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ diff -urN linux-2.4.24/drivers/acpi/dispatcher/dsutils.c linux-2.4.25/drivers/acpi/dispatcher/dsutils.c --- linux-2.4.24/drivers/acpi/dispatcher/dsutils.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dsutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/dispatcher/dswexec.c linux-2.4.25/drivers/acpi/dispatcher/dswexec.c --- linux-2.4.24/drivers/acpi/dispatcher/dswexec.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/dispatcher/dswexec.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -416,10 +416,24 @@ status = acpi_gbl_op_type_dispatch [op_type] (walk_state); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "[%s]: Could not resolve operands, %s\n", - acpi_ps_get_opcode_name (walk_state->opcode), - acpi_format_exception (status))); + /* + * Treat constructs of the form "Store(local_x,local_x)" as noops when the + * Local is uninitialized. + */ + if ((status == AE_AML_UNINITIALIZED_LOCAL) && + (walk_state->opcode == AML_STORE_OP) && + (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && + (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && + (walk_state->operands[0]->reference.opcode == + walk_state->operands[1]->reference.opcode)) { + status = AE_OK; + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "[%s]: Could not resolve operands, %s\n", + acpi_ps_get_opcode_name (walk_state->opcode), + acpi_format_exception (status))); + } } /* Always delete the argument objects and clear the operand stack */ diff -urN linux-2.4.24/drivers/acpi/dispatcher/dswload.c linux-2.4.25/drivers/acpi/dispatcher/dswload.c --- linux-2.4.24/drivers/acpi/dispatcher/dswload.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dswload.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -167,7 +167,7 @@ object_type = walk_state->op_info->object_type; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "State=%p Op=%p [%s] ", walk_state, op, acpi_ut_get_type_name (object_type))); + "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type))); switch (walk_state->opcode) { case AML_SCOPE_OP: @@ -260,10 +260,12 @@ if ((walk_state->opcode != AML_SCOPE_OP) && (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { flags |= ACPI_NS_ERROR_IF_FOUND; - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Cannot already exist\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", + acpi_ut_get_type_name (object_type))); } else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Both Find or Create allowed\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n", + acpi_ut_get_type_name (object_type))); } /* diff -urN linux-2.4.24/drivers/acpi/dispatcher/dswscope.c linux-2.4.25/drivers/acpi/dispatcher/dswscope.c --- linux-2.4.24/drivers/acpi/dispatcher/dswscope.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dswscope.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -146,7 +146,7 @@ if (old_scope_info) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "[%4.4s] (%s)", - old_scope_info->scope.node->name.ascii, + acpi_ut_get_node_name (old_scope_info->scope.node), acpi_ut_get_type_name (old_scope_info->common.value))); } else { @@ -156,7 +156,7 @@ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, ", New scope -> [%4.4s] (%s)\n", - scope_info->scope.node->name.ascii, + acpi_ut_get_node_name (scope_info->scope.node), acpi_ut_get_type_name (scope_info->common.value))); /* Push new scope object onto stack */ @@ -207,14 +207,14 @@ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%.2d] Popped scope [%4.4s] (%s), New scope -> ", (u32) walk_state->scope_depth, - scope_info->scope.node->name.ascii, + acpi_ut_get_node_name (scope_info->scope.node), acpi_ut_get_type_name (scope_info->common.value))); new_scope_info = walk_state->scope_info; if (new_scope_info) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "[%4.4s] (%s)\n", - new_scope_info->scope.node->name.ascii, + acpi_ut_get_node_name (new_scope_info->scope.node), acpi_ut_get_type_name (new_scope_info->common.value))); } else { diff -urN linux-2.4.24/drivers/acpi/dispatcher/dswstate.c linux-2.4.25/drivers/acpi/dispatcher/dswstate.c --- linux-2.4.24/drivers/acpi/dispatcher/dswstate.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/dispatcher/dswstate.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/ec.c linux-2.4.25/drivers/acpi/ec.c --- linux-2.4.24/drivers/acpi/ec.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/ec.c 2004-02-18 05:36:31.000000000 -0800 @@ -471,7 +471,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_ec_dir = NULL; +struct proc_dir_entry *acpi_ec_dir; static int diff -urN linux-2.4.24/drivers/acpi/events/evevent.c linux-2.4.25/drivers/acpi/events/evevent.c --- linux-2.4.24/drivers/acpi/events/evevent.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evevent.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/events/evgpe.c linux-2.4.25/drivers/acpi/events/evgpe.c --- linux-2.4.24/drivers/acpi/events/evgpe.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/events/evgpe.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,12 +139,10 @@ { u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; - u8 bit_mask; struct acpi_gpe_register_info *gpe_register_info; u32 in_value; acpi_status status; struct acpi_gpe_block_info *gpe_block; - u32 gpe_number; u32 i; u32 j; @@ -187,11 +185,9 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", - ACPI_HIDWORD (gpe_register_info->status_address.address), - ACPI_LODWORD (gpe_register_info->status_address.address), + ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address), gpe_register_info->status, - ACPI_HIDWORD (gpe_register_info->enable_address.address), - ACPI_LODWORD (gpe_register_info->enable_address.address), + ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address), gpe_register_info->enable)); /* First check if there is anything active at all in this register */ @@ -206,18 +202,16 @@ /* Now look at the individual GPEs in this byte register */ - for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) { + for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Examine one GPE bit */ - if (enabled_status_byte & bit_mask) { + if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) { /* * Found an active GPE. Dispatch the event to a handler * or method. */ - gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j; - int_status |= acpi_ev_gpe_dispatch ( - &gpe_block->event_info[gpe_number], + &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); } } @@ -294,7 +288,7 @@ if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception (status), - local_gpe_event_info.method_node->name.ascii, gpe_number)); + acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number)); } } @@ -367,6 +361,18 @@ /* Invoke the installed handler (at interrupt level) */ gpe_event_info->handler (gpe_event_info->context); + + /* It is now safe to clear level-triggered events. */ + + if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) { + status = acpi_hw_clear_gpe (gpe_event_info); + if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (( + "acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n", + gpe_number)); + return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); + } + } } else if (gpe_event_info->method_node) { /* @@ -375,13 +381,16 @@ */ status = acpi_hw_disable_gpe (gpe_event_info); if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", + ACPI_REPORT_ERROR (( + "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", gpe_number)); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); } - /* Execute the method associated with the GPE. */ - + /* + * Execute the method associated with the GPE + * NOTE: Level-triggered GPEs are cleared after the method completes. + */ if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE, acpi_ev_asynch_execute_gpe_method, gpe_event_info))) { @@ -399,22 +408,12 @@ /* * Disable the GPE. The GPE will remain disabled until the ACPI - * Core Subsystem is restarted, or the handler is reinstalled. + * Core Subsystem is restarted, or a handler is installed. */ status = acpi_hw_disable_gpe (gpe_event_info); if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", - gpe_number)); - return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); - } - } - - /* It is now safe to clear level-triggered events. */ - - if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) { - status = acpi_hw_clear_gpe (gpe_event_info); - if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n", + ACPI_REPORT_ERROR (( + "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n", gpe_number)); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); } diff -urN linux-2.4.24/drivers/acpi/events/evgpeblk.c linux-2.4.25/drivers/acpi/events/evgpeblk.c --- linux-2.4.24/drivers/acpi/events/evgpeblk.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evgpeblk.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -477,7 +477,7 @@ * * RETURN: Status * - * DESCRIPTION: Install new GPE block with mutex support + * DESCRIPTION: Remove a GPE block * ******************************************************************************/ @@ -743,8 +743,7 @@ ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), gpe_device->name.ascii, gpe_block->register_count, - ACPI_HIDWORD (gpe_block->block_address.address), - ACPI_LODWORD (gpe_block->block_address.address), + ACPI_FORMAT_UINT64 (gpe_block->block_address.address), interrupt_level)); /* Find all GPE methods (_Lxx, _Exx) for this block */ diff -urN linux-2.4.24/drivers/acpi/events/evmisc.c linux-2.4.25/drivers/acpi/events/evmisc.c --- linux-2.4.24/drivers/acpi/events/evmisc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evmisc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -195,7 +195,8 @@ /* There is no per-device notify handler for this device */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "No notify handler for [%4.4s] node %p\n", node->name.ascii, node)); + "No notify handler for [%4.4s] node %p\n", + acpi_ut_get_node_name (node), node)); } return (status); diff -urN linux-2.4.24/drivers/acpi/events/evregion.c linux-2.4.25/drivers/acpi/events/evregion.c --- linux-2.4.24/drivers/acpi/events/evregion.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/events/evregion.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ #define ACPI_NUM_DEFAULT_SPACES 4 -u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { +static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_ADR_SPACE_SYSTEM_IO, ACPI_ADR_SPACE_PCI_CONFIG, @@ -136,7 +136,7 @@ * ******************************************************************************/ -static acpi_status +acpi_status acpi_ev_execute_reg_method ( union acpi_operand_object *region_obj, u32 function) @@ -202,7 +202,7 @@ * * FUNCTION: acpi_ev_address_space_dispatch * - * PARAMETERS: region_obj - internal region object + * PARAMETERS: region_obj - Internal region object * space_id - ID of the address space (0-255) * Function - Read or Write operation * Address - Where in the space to read or write @@ -243,9 +243,11 @@ /* Ensure that there is a handler associated with this region */ - handler_desc = region_obj->region.address_space; + handler_desc = region_obj->region.handler; if (!handler_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No handler for Region [%4.4s] (%p) [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); return_ACPI_STATUS (AE_NOT_EXIST); @@ -320,8 +322,8 @@ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", - ®ion_obj->region.address_space->address_space, handler, - ACPI_HIDWORD (address), ACPI_LODWORD (address), + ®ion_obj->region.handler->address_space, handler, + ACPI_FORMAT_UINT64 (address), acpi_ut_get_region_name (region_obj->region.space_id))); if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { @@ -359,6 +361,7 @@ return_ACPI_STATUS (status); } + /******************************************************************************* * * FUNCTION: acpi_ev_detach_region @@ -398,7 +401,7 @@ /* Get the address handler from the region object */ - handler_obj = region_obj->region.address_space; + handler_obj = region_obj->region.handler; if (!handler_obj) { /* This region has no handler, all done */ @@ -472,7 +475,7 @@ * If the region is on the handler's list * this better be the region's handler */ - region_obj->region.address_space = NULL; + region_obj->region.handler = NULL; acpi_ut_remove_reference (handler_obj); return_VOID; @@ -515,17 +518,15 @@ union acpi_operand_object *region_obj, u8 acpi_ns_is_locked) { - acpi_status status; - acpi_status status2; - ACPI_FUNCTION_TRACE ("ev_attach_region"); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Adding Region %p to address handler %p [%s]\n", - region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - + "Adding Region [%4.4s] %p to address handler %p [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), + region_obj, handler_obj, + acpi_ut_get_region_name (region_obj->region.space_id))); /* Link this region to the front of the handler's list */ @@ -534,34 +535,14 @@ /* Install the region's handler */ - if (region_obj->region.address_space) { + if (region_obj->region.handler) { return_ACPI_STATUS (AE_ALREADY_EXISTS); } - region_obj->region.address_space = handler_obj; + region_obj->region.handler = handler_obj; acpi_ut_add_reference (handler_obj); - /* - * Tell all users that this region is usable by running the _REG - * method - */ - if (acpi_ns_is_locked) { - status2 = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status2)) { - return_ACPI_STATUS (status2); - } - } - - status = acpi_ev_execute_reg_method (region_obj, 1); - - if (acpi_ns_is_locked) { - status2 = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status2)) { - return_ACPI_STATUS (status2); - } - } - - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } @@ -569,9 +550,7 @@ * * FUNCTION: acpi_ev_install_handler * - * PARAMETERS: Handle - Node to be dumped - * Level - Nesting level of the handle - * Context - Passed into acpi_ns_walk_namespace + * PARAMETERS: walk_namespace callback * * DESCRIPTION: This routine installs an address handler into objects that are * of type Region or Device. @@ -640,7 +619,7 @@ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) { /* Check if this Device already has a handler for this address space */ - next_handler_obj = obj_desc->device.address_space; + next_handler_obj = obj_desc->device.handler; while (next_handler_obj) { /* Found a handler, is it for the same address space? */ @@ -697,4 +676,74 @@ return (status); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_reg_run + * + * PARAMETERS: walk_namespace callback + * + * DESCRIPTION: Run _REg method for region objects of the requested space_iD + * + ******************************************************************************/ + +acpi_status +acpi_ev_reg_run ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + union acpi_operand_object *handler_obj; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + acpi_status status; + + + handler_obj = (union acpi_operand_object *) context; + + /* Parameter validation */ + + if (!handler_obj) { + return (AE_OK); + } + + /* Convert and validate the device handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + return (AE_BAD_PARAMETER); + } + + /* + * We only care about regions.and objects + * that are allowed to have address space handlers + */ + if ((node->type != ACPI_TYPE_REGION) && + (node != acpi_gbl_root_node)) { + return (AE_OK); + } + + /* Check for an existing internal object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, just exit */ + + return (AE_OK); + } + + + /* Object is a Region */ + + if (obj_desc->region.space_id != handler_obj->address_space.space_id) { + /* + * This region is for a different address space + * -- just ignore it + */ + return (AE_OK); + } + + status = acpi_ev_execute_reg_method (obj_desc, 1); + return (status); +} diff -urN linux-2.4.24/drivers/acpi/events/evrgnini.c linux-2.4.25/drivers/acpi/events/evrgnini.c --- linux-2.4.24/drivers/acpi/events/evrgnini.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evrgnini.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -177,7 +177,7 @@ ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); - handler_obj = region_obj->region.address_space; + handler_obj = region_obj->region.handler; if (!handler_obj) { /* * No installed handler. This shouldn't happen because the dispatch @@ -239,7 +239,7 @@ else { ACPI_REPORT_ERROR (( "Could not install pci_config handler for Root Bridge %4.4s, %s\n", - pci_root_node->name.ascii, acpi_format_exception (status))); + acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status))); } } break; @@ -469,7 +469,7 @@ /* Setup defaults */ - region_obj->region.address_space = NULL; + region_obj->region.handler = NULL; region_obj2->extra.method_REG = NULL; region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE); region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED; @@ -502,17 +502,17 @@ switch (node->type) { case ACPI_TYPE_DEVICE: - handler_obj = obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; break; case ACPI_TYPE_PROCESSOR: - handler_obj = obj_desc->processor.address_space; + handler_obj = obj_desc->processor.handler; break; case ACPI_TYPE_THERMAL: - handler_obj = obj_desc->thermal_zone.address_space; + handler_obj = obj_desc->thermal_zone.handler; break; default: @@ -533,6 +533,26 @@ status = acpi_ev_attach_region (handler_obj, region_obj, acpi_ns_locked); + /* + * Tell all users that this region is usable by running the _REG + * method + */ + if (acpi_ns_locked) { + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + status = acpi_ev_execute_reg_method (region_obj, 1); + + if (acpi_ns_locked) { + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.24/drivers/acpi/events/evsci.c linux-2.4.25/drivers/acpi/events/evsci.c --- linux-2.4.24/drivers/acpi/events/evsci.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evsci.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/events/evxface.c linux-2.4.25/drivers/acpi/events/evxface.c --- linux-2.4.24/drivers/acpi/events/evxface.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evxface.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/events/evxfevnt.c linux-2.4.25/drivers/acpi/events/evxfevnt.c --- linux-2.4.24/drivers/acpi/events/evxfevnt.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evxfevnt.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/events/evxfregn.c linux-2.4.25/drivers/acpi/events/evxfregn.c --- linux-2.4.24/drivers/acpi/events/evxfregn.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/events/evxfregn.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -173,7 +173,7 @@ * The attached device object already exists. * Make sure the handler is not already installed. */ - handler_obj = obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; /* Walk the handler list for this device */ @@ -240,7 +240,8 @@ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", - acpi_ut_get_region_name (space_id), space_id, node->name.ascii, node, obj_desc)); + acpi_ut_get_region_name (space_id), space_id, + acpi_ut_get_node_name (node), node, obj_desc)); /* * Install the handler @@ -267,13 +268,13 @@ /* Install at head of Device.address_space list */ - handler_obj->address_space.next = obj_desc->device.address_space; + handler_obj->address_space.next = obj_desc->device.handler; /* * The Device object is the first reference on the handler_obj. * Each region that uses the handler adds a reference. */ - obj_desc->device.address_space = handler_obj; + obj_desc->device.handler = handler_obj; /* * Walk the namespace finding all of the regions this @@ -291,6 +292,17 @@ ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, handler_obj, NULL); + /* + * Now we can run the _REG methods for all Regions for this + * space ID. This is a separate walk in order to handle any + * interdependencies between regions and _REG methods. (i.e. handlers + * must be installed for all regions of this Space ID before we + * can run any _REG methods. + */ + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, + handler_obj, NULL); + unlock_and_exit: (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); @@ -357,8 +369,8 @@ /* Find the address handler the user requested */ - handler_obj = obj_desc->device.address_space; - last_obj_ptr = &obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; + last_obj_ptr = &obj_desc->device.handler; while (handler_obj) { /* We have a handler, see if user requested this one */ diff -urN linux-2.4.24/drivers/acpi/executer/exconfig.c linux-2.4.25/drivers/acpi/executer/exconfig.c --- linux-2.4.24/drivers/acpi/executer/exconfig.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exconfig.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exconvrt.c linux-2.4.25/drivers/acpi/executer/exconvrt.c --- linux-2.4.24/drivers/acpi/executer/exconvrt.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exconvrt.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/excreate.c linux-2.4.25/drivers/acpi/executer/excreate.c --- linux-2.4.24/drivers/acpi/executer/excreate.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/excreate.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exdump.c linux-2.4.25/drivers/acpi/executer/exdump.c --- linux-2.4.24/drivers/acpi/executer/exdump.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exdump.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,27 +89,27 @@ if (!obj_desc) { /* - * This usually indicates that something serious is wrong -- - * since most (if not all) - * code that dumps the stack expects something to be there! + * This usually indicates that something serious is wrong */ - acpi_os_printf ("Null stack entry ptr\n"); + acpi_os_printf ("Null Object Descriptor\n"); return; } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p NS Node: ", obj_desc)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc)); ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC); return; } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is not a local object\n", obj_desc)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "%p is not a node or operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc))); ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object)); return; } - /* obj_desc is a valid object */ + /* obj_desc is a valid object */ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc)); @@ -151,11 +151,10 @@ obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { - /* Value is a Number */ + /* Value is an Integer */ acpi_os_printf (" value is [%8.8X%8.8x]", - ACPI_HIDWORD(obj_desc->integer.value), - ACPI_LODWORD(obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); } acpi_os_printf ("\n"); @@ -169,11 +168,10 @@ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { - /* Value is a Number */ + /* Value is an Integer */ acpi_os_printf (" value is [%8.8X%8.8x]", - ACPI_HIDWORD(obj_desc->integer.value), - ACPI_LODWORD(obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); } acpi_os_printf ("\n"); @@ -189,7 +187,7 @@ default: - /* unknown opcode */ + /* Unknown opcode */ acpi_os_printf ("Unknown Reference opcode=%X\n", obj_desc->reference.opcode); @@ -229,8 +227,7 @@ case ACPI_TYPE_INTEGER: acpi_os_printf ("Integer %8.8X%8.8X\n", - ACPI_HIDWORD (obj_desc->integer.value), - ACPI_LODWORD (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; @@ -271,8 +268,7 @@ } else { acpi_os_printf (" base %8.8X%8.8X Length %X\n", - ACPI_HIDWORD (obj_desc->region.address), - ACPI_LODWORD (obj_desc->region.address), + ACPI_FORMAT_UINT64 (obj_desc->region.address), obj_desc->region.length); } break; @@ -494,7 +490,7 @@ acpi_os_printf ("%20s : %p\n", title, value); #else acpi_os_printf ("%20s : %8.8X%8.8X\n", title, - ACPI_HIDWORD (value), ACPI_LODWORD (value)); + ACPI_FORMAT_UINT64 (value)); #endif } @@ -525,7 +521,7 @@ } } - acpi_os_printf ("%20s : %4.4s\n", "Name", node->name.ascii); + acpi_os_printf ("%20s : %4.4s\n", "Name", acpi_ut_get_node_name (node)); acpi_ex_out_string ("Type", acpi_ut_get_type_name (node->type)); acpi_ex_out_integer ("Flags", node->flags); acpi_ex_out_integer ("Owner Id", node->owner_id); @@ -573,7 +569,8 @@ } if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) { - acpi_os_printf ("ex_dump_object_descriptor: %p is not a valid ACPI object\n", obj_desc); + acpi_os_printf ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc)); return_VOID; } @@ -589,8 +586,7 @@ case ACPI_TYPE_INTEGER: acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value", - ACPI_HIDWORD (obj_desc->integer.value), - ACPI_LODWORD (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; @@ -635,7 +631,7 @@ case ACPI_TYPE_DEVICE: - acpi_ex_out_pointer ("address_space", obj_desc->device.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->device.handler); acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify); break; @@ -673,7 +669,7 @@ acpi_ex_out_integer ("Flags", obj_desc->region.flags); acpi_ex_out_address ("Address", obj_desc->region.address); acpi_ex_out_integer ("Length", obj_desc->region.length); - acpi_ex_out_pointer ("address_space", obj_desc->region.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->region.handler); acpi_ex_out_pointer ("Next", obj_desc->region.next); break; @@ -694,7 +690,7 @@ acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); - acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->processor.handler); break; @@ -702,7 +698,7 @@ acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); - acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler); break; diff -urN linux-2.4.24/drivers/acpi/executer/exfield.c linux-2.4.25/drivers/acpi/executer/exfield.c --- linux-2.4.24/drivers/acpi/executer/exfield.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exfield.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exfldio.c linux-2.4.25/drivers/acpi/executer/exfldio.c --- linux-2.4.24/drivers/acpi/executer/exfldio.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exfldio.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -138,8 +138,9 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", - obj_desc->common_field.node->name.ascii, obj_desc->common_field.access_byte_width, - rgn_desc->region.node->name.ascii, rgn_desc->region.length)); + acpi_ut_get_node_name (obj_desc->common_field.node), + obj_desc->common_field.access_byte_width, + acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); } /* @@ -148,9 +149,10 @@ */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n", - obj_desc->common_field.node->name.ascii, obj_desc->common_field.base_byte_offset, + acpi_ut_get_node_name (obj_desc->common_field.node), + obj_desc->common_field.base_byte_offset, field_datum_byte_offset, obj_desc->common_field.access_byte_width, - rgn_desc->region.node->name.ascii, rgn_desc->region.length)); + acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); #ifdef CONFIG_ACPI_RELAXED_AML { @@ -261,7 +263,7 @@ obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, field_datum_byte_offset, - ACPI_HIDWORD (address), ACPI_LODWORD (address))); + ACPI_FORMAT_UINT64 (address))); /* Invoke the appropriate address_space/op_region handler */ @@ -514,12 +516,12 @@ if (ACPI_SUCCESS (status)) { if (read_write == ACPI_READ) { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + ACPI_FORMAT_UINT64 (*value), obj_desc->common_field.access_byte_width)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + ACPI_FORMAT_UINT64 (*value), obj_desc->common_field.access_byte_width)); } } @@ -612,11 +614,11 @@ ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", - ACPI_HIDWORD (mask), ACPI_LODWORD (mask), + ACPI_FORMAT_UINT64 (mask), field_datum_byte_offset, obj_desc->common_field.access_byte_width, - ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value), - ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value))); + ACPI_FORMAT_UINT64 (field_value), + ACPI_FORMAT_UINT64 (merged_value))); /* Write the merged value */ @@ -784,12 +786,13 @@ { acpi_status status; u32 field_datum_byte_offset; - u32 datum_offset; - acpi_integer previous_raw_datum; + u32 buffer_datum_offset; + acpi_integer previous_raw_datum = 0; acpi_integer this_raw_datum = 0; acpi_integer merged_datum = 0; u32 byte_field_length; u32 datum_count; + u32 i; ACPI_FUNCTION_TRACE ("ex_extract_from_field"); @@ -812,77 +815,74 @@ datum_count = ACPI_ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + /* + * If the field is not aligned on a datum boundary and does not + * fit within a single datum, we must read an extra datum. + * + * We could just split the aligned and non-aligned cases since the + * aligned case is so very simple, but this would require more code. + */ + if ((obj_desc->common_field.end_field_valid_bits != 0) && + (!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) { + datum_count++; + } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "byte_len %X, datum_len %X, byte_gran %X\n", byte_field_length, datum_count,obj_desc->common_field.access_byte_width)); /* * Clear the caller's buffer (the whole buffer length as given) - * This is very important, especially in the cases where a byte is read, - * but the buffer is really a u32 (4 bytes). + * This is very important, especially in the cases where the buffer + * is longer than the size of the field. */ ACPI_MEMSET (buffer, 0, buffer_length); - /* Read the first raw datum to prime the loop */ - field_datum_byte_offset = 0; - datum_offset= 0; - - status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, - &previous_raw_datum, ACPI_READ); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - + buffer_datum_offset= 0; - /* We might actually be done if the request fits in one datum */ + /* Read the entire field */ - if ((datum_count == 1) && - (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) { - /* 1) Shift the valid data bits down to start at bit 0 */ + for (i = 0; i < datum_count; i++) { + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &this_raw_datum, ACPI_READ); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + /* We might actually be done if the request fits in one datum */ - /* 2) Mask off any upper unused bits (bits not part of the field) */ + if ((datum_count == 1) && + (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) { + /* 1) Shift the valid data bits down to start at bit 0 */ - if (obj_desc->common_field.end_buffer_valid_bits) { - merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); - } + merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset); - /* Store the datum to the caller buffer */ + /* 2) Mask off any upper unused bits (bits not part of the field) */ - acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, - obj_desc->common_field.access_byte_width, datum_offset); + if (obj_desc->common_field.end_buffer_valid_bits) { + merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); + } - return_ACPI_STATUS (AE_OK); - } + /* Store the datum to the caller buffer */ + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); - /* We need to get more raw data to complete one or more field data */ + return_ACPI_STATUS (AE_OK); + } - while (datum_offset < datum_count) { - field_datum_byte_offset += obj_desc->common_field.access_byte_width; + /* Special handling for the last datum to ignore extra bits */ - /* - * If the field is aligned on a byte boundary, we don't want - * to perform a final read, since this would potentially read - * past the end of the region. - * - * We could just split the aligned and non-aligned cases since the - * aligned case is so very simple, but this would require more code. - */ - if ((obj_desc->common_field.start_field_bit_offset != 0) || - ((obj_desc->common_field.start_field_bit_offset == 0) && - (datum_offset < (datum_count -1)))) { + if ((i >= (datum_count -1)) && + (obj_desc->common_field.end_field_valid_bits)) { /* - * Get the next raw datum, it contains some or all bits - * of the current field datum + * This is the last iteration of the loop. We need to clear + * any unused bits (bits that are not part of this field) before + * we store the final merged datum into the caller buffer. */ - status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, - &this_raw_datum, ACPI_READ); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + this_raw_datum &= + ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); } /* @@ -891,48 +891,48 @@ if (obj_desc->common_field.start_field_bit_offset == 0) { /* Field is not skewed and we can just copy the datum */ - merged_datum = previous_raw_datum; + acpi_ex_set_buffer_datum (this_raw_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); + buffer_datum_offset++; } else { - /* - * Put together the appropriate bits of the two raw data to make a - * single complete field datum - * - * 1) Normalize the first datum down to bit 0 - */ - merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + /* Not aligned -- on the first iteration, just save the datum */ - /* 2) Insert the second datum "above" the first datum */ - - merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits); - - if ((datum_offset >= (datum_count -1))) { + if (i != 0) { /* - * This is the last iteration of the loop. We need to clear - * any unused bits (bits that are not part of this field) that - * came from the last raw datum before we store the final - * merged datum into the caller buffer. + * Put together the appropriate bits of the two raw data to make a + * single complete field datum + * + * 1) Normalize the first datum down to bit 0 */ - if (obj_desc->common_field.end_buffer_valid_bits) { - merged_datum &= - ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits); - } + merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset); + + /* 2) Insert the second datum "above" the first datum */ + + merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits); + + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); + buffer_datum_offset++; } + + /* + * Save the raw datum that was just acquired since it may contain bits + * of the *next* field datum + */ + previous_raw_datum = this_raw_datum; } - /* - * Store the merged field datum in the caller's buffer, according to - * the granularity of the field (size of each datum). - */ - acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, - obj_desc->common_field.access_byte_width, datum_offset); + field_datum_byte_offset += obj_desc->common_field.access_byte_width; + } - /* - * Save the raw datum that was just acquired since it may contain bits - * of the *next* field datum. Update offsets - */ - previous_raw_datum = this_raw_datum; - datum_offset++; + /* For non-aligned case, there is one last datum to insert */ + + if (obj_desc->common_field.start_field_bit_offset != 0) { + merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset); + + acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length, + obj_desc->common_field.access_byte_width, buffer_datum_offset); } return_ACPI_STATUS (AE_OK); diff -urN linux-2.4.24/drivers/acpi/executer/exmisc.c linux-2.4.25/drivers/acpi/executer/exmisc.c --- linux-2.4.24/drivers/acpi/executer/exmisc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exmisc.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,8 +121,8 @@ default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n", - ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p has invalid descriptor [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc))); return_ACPI_STATUS (AE_TYPE); } @@ -139,7 +139,7 @@ *return_desc = reference_obj; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n", - obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc)); + obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc)); return_ACPI_STATUS (AE_OK); } diff -urN linux-2.4.24/drivers/acpi/executer/exmutex.c linux-2.4.25/drivers/acpi/executer/exmutex.c --- linux-2.4.24/drivers/acpi/executer/exmutex.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exmutex.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -159,7 +159,7 @@ if (!walk_state->thread) { ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n", - obj_desc->mutex.node->name.ascii)); + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -169,7 +169,7 @@ */ if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n", - obj_desc->mutex.node->name.ascii)); + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } @@ -242,7 +242,7 @@ if (!obj_desc->mutex.owner_thread) { ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n", - obj_desc->mutex.node->name.ascii)); + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } @@ -250,7 +250,7 @@ if (!walk_state->thread) { ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n", - obj_desc->mutex.node->name.ascii)); + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -260,7 +260,7 @@ ACPI_REPORT_ERROR (( "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", walk_state->thread->thread_id, - obj_desc->mutex.node->name.ascii, + acpi_ut_get_node_name (obj_desc->mutex.node), obj_desc->mutex.owner_thread->thread_id)); return_ACPI_STATUS (AE_AML_NOT_OWNER); } @@ -271,7 +271,7 @@ */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n", - obj_desc->mutex.node->name.ascii)); + acpi_ut_get_node_name (obj_desc->mutex.node))); return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } diff -urN linux-2.4.24/drivers/acpi/executer/exnames.c linux-2.4.25/drivers/acpi/executer/exnames.c --- linux-2.4.24/drivers/acpi/executer/exnames.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exnames.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exoparg1.c linux-2.4.25/drivers/acpi/executer/exoparg1.c --- linux-2.4.24/drivers/acpi/executer/exoparg1.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exoparg1.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -351,8 +351,7 @@ if (digit > 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n", - ACPI_HIDWORD(operand[0]->integer.value), - ACPI_LODWORD(operand[0]->integer.value))); + ACPI_FORMAT_UINT64 (operand[0]->integer.value))); status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } diff -urN linux-2.4.24/drivers/acpi/executer/exoparg2.c linux-2.4.25/drivers/acpi/executer/exoparg2.c --- linux-2.4.24/drivers/acpi/executer/exoparg2.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exoparg2.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exoparg3.c linux-2.4.25/drivers/acpi/executer/exoparg3.c --- linux-2.4.24/drivers/acpi/executer/exoparg3.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exoparg3.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -101,15 +101,14 @@ switch (walk_state->opcode) { - case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", - (u32) operand[0]->integer.value, (u32) operand[1]->integer.value, + (u32) operand[0]->integer.value, + (u32) operand[1]->integer.value, (u32) operand[2]->integer.value)); - fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info)); if (fatal) { fatal->type = (u32) operand[0]->integer.value; diff -urN linux-2.4.24/drivers/acpi/executer/exoparg6.c linux-2.4.25/drivers/acpi/executer/exoparg6.c --- linux-2.4.24/drivers/acpi/executer/exoparg6.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exoparg6.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exprep.c linux-2.4.25/drivers/acpi/executer/exprep.c --- linux-2.4.24/drivers/acpi/executer/exprep.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exprep.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -351,7 +351,7 @@ */ nearest_byte_address = ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position); - obj_desc->common_field.base_byte_offset = + obj_desc->common_field.base_byte_offset = (u32) ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment); /* @@ -539,7 +539,7 @@ acpi_ns_get_type (info->field_node)); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n", - info->field_node, info->field_node->name.ascii, obj_desc)); + info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc)); /* Remove local reference to the object */ diff -urN linux-2.4.24/drivers/acpi/executer/exregion.c linux-2.4.25/drivers/acpi/executer/exregion.c --- linux-2.4.24/drivers/acpi/executer/exregion.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exregion.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -161,7 +161,7 @@ (void **) &mem_info->mapped_logical_address); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n", - ACPI_HIDWORD (address), ACPI_LODWORD (address), (u32) window_size)); + ACPI_FORMAT_UINT64 (address), (u32) window_size)); mem_info->mapped_length = 0; return_ACPI_STATUS (status); } @@ -180,8 +180,8 @@ ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, - ACPI_HIDWORD (address), ACPI_LODWORD (address))); + "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, + ACPI_FORMAT_UINT64 (address))); /* * Perform the memory read or write @@ -290,8 +290,8 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, - ACPI_HIDWORD (address), ACPI_LODWORD (address))); + "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width, + ACPI_FORMAT_UINT64 (address))); /* Decode the function parameter */ diff -urN linux-2.4.24/drivers/acpi/executer/exresnte.c linux-2.4.25/drivers/acpi/executer/exresnte.c --- linux-2.4.24/drivers/acpi/executer/exresnte.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exresnte.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exresolv.c linux-2.4.25/drivers/acpi/executer/exresolv.c --- linux-2.4.24/drivers/acpi/executer/exresolv.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exresolv.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -349,6 +349,8 @@ /* All "References" point to a NS node */ if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { + ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -399,7 +401,9 @@ /* All "References" point to a NS node */ if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { - return_ACPI_STATUS (AE_AML_INTERNAL); + ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); + return_ACPI_STATUS (AE_AML_INTERNAL); } /* Get the attached object */ diff -urN linux-2.4.24/drivers/acpi/executer/exresop.c linux-2.4.25/drivers/acpi/executer/exresop.c --- linux-2.4.24/drivers/acpi/executer/exresop.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exresop.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -247,8 +247,8 @@ /* Invalid descriptor */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Bad descriptor type %X in Obj %p\n", - ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc)); + "Invalid descriptor %p [%s]\n", + obj_desc, acpi_ut_get_descriptor_name (obj_desc))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } diff -urN linux-2.4.24/drivers/acpi/executer/exstore.c linux-2.4.25/drivers/acpi/executer/exstore.c --- linux-2.4.24/drivers/acpi/executer/exstore.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exstore.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -190,8 +190,7 @@ case ACPI_TYPE_INTEGER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n", - ACPI_HIDWORD (source_desc->integer.value), - ACPI_LODWORD (source_desc->integer.value))); + ACPI_FORMAT_UINT64 (source_desc->integer.value))); break; diff -urN linux-2.4.24/drivers/acpi/executer/exstoren.c linux-2.4.25/drivers/acpi/executer/exstoren.c --- linux-2.4.24/drivers/acpi/executer/exstoren.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exstoren.c 2004-02-18 05:36:31.000000000 -0800 @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exstorob.c linux-2.4.25/drivers/acpi/executer/exstorob.c --- linux-2.4.24/drivers/acpi/executer/exstorob.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exstorob.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/executer/exsystem.c linux-2.4.25/drivers/acpi/executer/exsystem.c --- linux-2.4.24/drivers/acpi/executer/exsystem.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/executer/exsystem.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,11 +111,16 @@ * * FUNCTION: acpi_ex_system_do_stall * - * PARAMETERS: how_long - The amount of time to stall + * PARAMETERS: how_long - The amount of time to stall, + * in microseconds * * RETURN: Status * * DESCRIPTION: Suspend running thread for specified amount of time. + * Note: ACPI specification requires that Stall() does not + * relinquish the processor, and delays longer than 100 usec + * should use Sleep() instead. We allow stalls up to 255 usec + * for compatibility with other interpreters and existing BIOSs. * ******************************************************************************/ @@ -129,12 +134,15 @@ ACPI_FUNCTION_ENTRY (); - if (how_long > 100) /* 100 microseconds */ { + if (how_long > 255) /* 255 microseconds */ { /* - * Longer than 100 usec, use sleep instead - * (according to ACPI specification) + * Longer than 255 usec, this is an error + * + * (ACPI specifies 100 usec as max, but this gives some slack in + * order to support existing BIOSs) */ - status = acpi_ex_system_do_suspend ((how_long / 1000) + 1); + ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long)); + status = AE_AML_OPERAND_VALUE; } else { acpi_os_stall (how_long); @@ -148,7 +156,8 @@ * * FUNCTION: acpi_ex_system_do_suspend * - * PARAMETERS: how_long - The amount of time to suspend + * PARAMETERS: how_long - The amount of time to suspend, + * in milliseconds * * RETURN: None * diff -urN linux-2.4.24/drivers/acpi/executer/exutils.c linux-2.4.25/drivers/acpi/executer/exutils.c --- linux-2.4.24/drivers/acpi/executer/exutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/executer/exutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/fan.c linux-2.4.25/drivers/acpi/fan.c --- linux-2.4.24/drivers/acpi/fan.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/fan.c 2004-02-18 05:36:31.000000000 -0800 @@ -65,7 +65,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_fan_dir = NULL; +struct proc_dir_entry *acpi_fan_dir; static int diff -urN linux-2.4.24/drivers/acpi/hardware/hwacpi.c linux-2.4.25/drivers/acpi/hardware/hwacpi.c --- linux-2.4.24/drivers/acpi/hardware/hwacpi.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/hardware/hwacpi.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -119,7 +119,7 @@ * system does not support mode transition. */ if (!acpi_gbl_FADT->smi_cmd) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No SMI_CMD in FADT, mode transition failed.\n")); + ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n")); return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } @@ -131,7 +131,7 @@ * transitions are not supported. */ if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No mode transition supported in this system.\n")); + ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n")); return_ACPI_STATUS (AE_OK); } @@ -162,6 +162,7 @@ } if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -171,18 +172,16 @@ */ retry = 3000; while (retry) { - status = AE_NO_HARDWARE_RESPONSE; - if (acpi_hw_get_mode() == mode) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); - status = AE_OK; - break; + return_ACPI_STATUS (AE_OK); } acpi_os_stall(1000); retry--; } - return_ACPI_STATUS (status); + ACPI_REPORT_ERROR (("Hardware never changed modes\n")); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } diff -urN linux-2.4.24/drivers/acpi/hardware/hwgpe.c linux-2.4.25/drivers/acpi/hardware/hwgpe.c --- linux-2.4.24/drivers/acpi/hardware/hwgpe.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/hardware/hwgpe.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -348,17 +348,14 @@ struct acpi_gpe_block_info *gpe_block) { u32 i; - struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - /* Get the register info for the entire GPE block */ - - gpe_register_info = gpe_block->register_info; - /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { + /* Disable all GPEs in this register */ + status = acpi_hw_low_level_write (8, 0x00, &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE (status)) { @@ -389,17 +386,14 @@ struct acpi_gpe_block_info *gpe_block) { u32 i; - struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - /* Get the register info for the entire GPE block */ - - gpe_register_info = gpe_block->register_info; - /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { + /* Clear all GPEs in this register */ + status = acpi_hw_low_level_write (8, 0xFF, &gpe_block->register_info[i].status_address); if (ACPI_FAILURE (status)) { diff -urN linux-2.4.24/drivers/acpi/hardware/hwregs.c linux-2.4.25/drivers/acpi/hardware/hwregs.c --- linux-2.4.24/drivers/acpi/hardware/hwregs.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/hardware/hwregs.c 2004-02-18 05:36:31.000000000 -0800 @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -418,16 +418,14 @@ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", register_value, - ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address), - ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address))); + ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address))); ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, bit_reg_info->access_bit_mask, value); ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", register_value, - ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address), - ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address))); + ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address))); status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM2_CONTROL, (u8) (register_value)); @@ -763,8 +761,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *value, width, - ACPI_HIDWORD (reg->address), - ACPI_LODWORD (reg->address), + ACPI_FORMAT_UINT64 (reg->address), acpi_ut_get_region_name (reg->address_space_id))); return (status); @@ -850,8 +847,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", value, width, - ACPI_HIDWORD (reg->address), - ACPI_LODWORD (reg->address), + ACPI_FORMAT_UINT64 (reg->address), acpi_ut_get_region_name (reg->address_space_id))); return (status); diff -urN linux-2.4.24/drivers/acpi/hardware/hwsleep.c linux-2.4.25/drivers/acpi/hardware/hwsleep.c --- linux-2.4.24/drivers/acpi/hardware/hwsleep.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/hardware/hwsleep.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -181,6 +181,13 @@ return_ACPI_STATUS (status); } + /* Set the system indicators to show the desired sleep state. */ + + status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + return_ACPI_STATUS (AE_OK); } @@ -220,30 +227,31 @@ return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } - sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); - /* Clear wake status */ + if (sleep_state != ACPI_STATE_S5) { + /* Clear wake status */ - status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* Disable BM arbitration */ + /* Disable BM arbitration */ - status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } - status = acpi_hw_disable_non_wakeup_gpes(); + status = acpi_hw_disable_non_wakeup_gpes (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -266,6 +274,11 @@ PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); + /* + * We split the writes of SLP_TYP and SLP_EN to workaround + * poorly implemented hardware. + */ + /* Write #1: fill in SLP_TYP data */ status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); @@ -297,13 +310,15 @@ return_ACPI_STATUS (status); } - /* - * Wait a second, then try again. This is to get S4/5 to work on all machines. - */ if (sleep_state > ACPI_STATE_S3) { /* + * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that + * we are still executing!) + * + * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines. + * * We wait so long to allow chipsets that poll this reg very slowly to - * still read the right value. Ideally, this entire block would go + * still read the right value. Ideally, this block would go * away entirely. */ acpi_os_stall (10000000); @@ -354,12 +369,23 @@ ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios"); - acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); - acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); - acpi_hw_disable_non_wakeup_gpes(); + status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + status = acpi_hw_disable_non_wakeup_gpes (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - ACPI_FLUSH_CPU_CACHE(); + ACPI_FLUSH_CPU_CACHE (); status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8); @@ -389,16 +415,56 @@ acpi_status acpi_leave_sleep_state ( - u8 sleep_state) + u8 sleep_state) { - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status; + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; + u32 PM1Acontrol; + u32 PM1Bcontrol; ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state"); + /* + * Set SLP_TYPE and SLP_EN to state S0. + * This is unclear from the ACPI Spec, but it is required + * by some machines. + */ + status = acpi_get_sleep_type_data (ACPI_STATE_S0, + &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b); + if (ACPI_SUCCESS (status)) { + sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); + sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); + + /* Get current value of PM1A control */ + + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); + if (ACPI_SUCCESS (status)) { + /* Clear SLP_EN and SLP_TYP fields */ + + PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | + sleep_enable_reg_info->access_bit_mask); + PM1Bcontrol = PM1Acontrol; + + /* Insert SLP_TYP bits */ + + PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); + PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); + + /* Just ignore any errors */ + + (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); + (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); + } + } + /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; @@ -407,12 +473,17 @@ arg_list.count = 1; arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = sleep_state; /* Ignore any errors from these methods */ + arg.integer.value = 0; + status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + + arg.integer.value = sleep_state; status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); @@ -425,13 +496,13 @@ /* _WAK returns stuff - do we want to look at it? */ - status = acpi_hw_enable_non_wakeup_gpes(); + status = acpi_hw_enable_non_wakeup_gpes (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* Disable BM arbitration */ - status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); + /* Enable BM arbitration */ + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); return_ACPI_STATUS (status); } diff -urN linux-2.4.24/drivers/acpi/hardware/hwtimer.c linux-2.4.25/drivers/acpi/hardware/hwtimer.c --- linux-2.4.24/drivers/acpi/hardware/hwtimer.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/hardware/hwtimer.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsaccess.c linux-2.4.25/drivers/acpi/namespace/nsaccess.c --- linux-2.4.24/drivers/acpi/namespace/nsaccess.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsaccess.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -314,8 +314,8 @@ else { prefix_node = scope_info->scope.node; if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%p] Not a namespace node\n", - prefix_node)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p Not a namespace node [%s]\n", + prefix_node, acpi_ut_get_descriptor_name (prefix_node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -379,7 +379,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching relative to prefix scope [%4.4s] (%p)\n", - prefix_node->name.ascii, prefix_node)); + acpi_ut_get_node_name (prefix_node), prefix_node)); /* * Handle multiple Parent Prefixes (carat) by just getting @@ -413,7 +413,7 @@ if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Search scope is [%4.4s], path has %d carat(s)\n", - this_node->name.ascii, num_carats)); + acpi_ut_get_node_name (this_node), num_carats)); } } diff -urN linux-2.4.24/drivers/acpi/namespace/nsalloc.c linux-2.4.25/drivers/acpi/namespace/nsalloc.c --- linux-2.4.24/drivers/acpi/namespace/nsalloc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsalloc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -271,7 +271,7 @@ * alphabetic placement. */ previous_child_node = NULL; - while (acpi_ns_compare_names (child_node->name.ascii, node->name.ascii) < 0) { + while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) { if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { /* Last peer; Clear end-of-list flag */ @@ -335,8 +335,9 @@ node->type = (u8) type; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", - node->name.ascii, acpi_ut_get_type_name (node->type), - parent_node->name.ascii, acpi_ut_get_type_name (parent_node->type), parent_node, node)); + acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), + acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type), + parent_node, node)); /* * Increment the reference count(s) of all parents up to diff -urN linux-2.4.24/drivers/acpi/namespace/nsdump.c linux-2.4.25/drivers/acpi/namespace/nsdump.c --- linux-2.4.24/drivers/acpi/namespace/nsdump.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/namespace/nsdump.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,8 +50,8 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nsdump") -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /******************************************************************************* * @@ -76,7 +76,7 @@ return; } - /* Print the entire name */ + /* Print the entire name */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); @@ -205,7 +205,7 @@ * Now we can print out the pertinent information */ acpi_os_printf ("%4.4s %-12s %p ", - this_node->name.ascii, acpi_ut_get_type_name (type), this_node); + acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node); dbg_level = acpi_dbg_level; acpi_dbg_level = 0; @@ -250,8 +250,7 @@ case ACPI_TYPE_INTEGER: acpi_os_printf ("= %8.8X%8.8X\n", - ACPI_HIDWORD (obj_desc->integer.value), - ACPI_LODWORD (obj_desc->integer.value)); + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; @@ -302,8 +301,7 @@ acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id)); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n", - ACPI_HIDWORD (obj_desc->region.address), - ACPI_LODWORD (obj_desc->region.address), + ACPI_FORMAT_UINT64 (obj_desc->region.address), obj_desc->region.length); } else { @@ -324,7 +322,7 @@ if (obj_desc->buffer_field.buffer_obj && obj_desc->buffer_field.buffer_obj->buffer.node) { acpi_os_printf ("Buf [%4.4s]", - obj_desc->buffer_field.buffer_obj->buffer.node->name.ascii); + acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node)); } break; @@ -332,29 +330,29 @@ case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_os_printf ("Rgn [%4.4s]", - obj_desc->common_field.region_obj->region.node->name.ascii); + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node)); break; case ACPI_TYPE_LOCAL_BANK_FIELD: acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]", - obj_desc->common_field.region_obj->region.node->name.ascii, - obj_desc->bank_field.bank_obj->common_field.node->name.ascii); + acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node), + acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]", - obj_desc->index_field.index_obj->common_field.node->name.ascii, - obj_desc->index_field.data_obj->common_field.node->name.ascii); + acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node), + acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node)); break; case ACPI_TYPE_LOCAL_ALIAS: - acpi_os_printf ("Target %4.4s (%p)\n", ((struct acpi_namespace_node *) obj_desc)->name.ascii, obj_desc); + acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), obj_desc); break; default: @@ -371,7 +369,7 @@ case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_os_printf ("Off %.2X Len %.2X Acc %.2hd\n", + acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n", (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.bit_length, @@ -408,8 +406,8 @@ case ACPI_TYPE_INTEGER: - acpi_os_printf (" N:%X%X\n", ACPI_HIDWORD(obj_desc->integer.value), - ACPI_LODWORD(obj_desc->integer.value)); + acpi_os_printf (" I:%8.8X8.8%X\n", + ACPI_FORMAT_UINT64 (obj_desc->integer.value)); break; case ACPI_TYPE_STRING: @@ -485,7 +483,8 @@ default: - acpi_os_printf ("(String or Buffer ptr - not an object descriptor)\n"); + acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n", + acpi_ut_get_descriptor_name (obj_desc)); bytes_to_dump = 16; break; } @@ -581,7 +580,6 @@ info.owner_id = owner_id; info.display_type = display_type; - (void) acpi_ns_walk_namespace (type, start_handle, max_depth, ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, (void *) &info, NULL); @@ -628,7 +626,6 @@ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n")); } - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, ACPI_UINT32_MAX, search_handle); return_VOID; diff -urN linux-2.4.24/drivers/acpi/namespace/nsdumpdv.c linux-2.4.25/drivers/acpi/namespace/nsdumpdv.c --- linux-2.4.24/drivers/acpi/namespace/nsdumpdv.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsdumpdv.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -93,7 +93,7 @@ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", info->hardware_id.value, - ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address), + ACPI_FORMAT_UINT64 (info->address), info->current_status)); ACPI_MEM_FREE (info); } diff -urN linux-2.4.24/drivers/acpi/namespace/nseval.c linux-2.4.25/drivers/acpi/namespace/nseval.c --- linux-2.4.24/drivers/acpi/namespace/nseval.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nseval.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsinit.c linux-2.4.25/drivers/acpi/namespace/nsinit.c --- linux-2.4.24/drivers/acpi/namespace/nsinit.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsinit.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -144,10 +144,17 @@ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:")); - /* Walk namespace for all objects of type Device */ + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + /* Walk namespace for all objects of type Device or Processor */ - status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL); + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL); + + (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n", @@ -290,7 +297,8 @@ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not execute arguments for [%4.4s] (%s), %s\n", - node->name.ascii, acpi_ut_get_type_name (type), acpi_format_exception (status))); + acpi_ut_get_node_name (node), acpi_ut_get_type_name (type), + acpi_format_exception (status))); } /* Print a dot for each object unless we are going to print the entire pathname */ @@ -338,45 +346,48 @@ ACPI_FUNCTION_TRACE ("ns_init_one_device"); - if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); - } - - info->device_count++; - - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - node = acpi_ns_map_handle_to_node (obj_handle); if (!node) { - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (AE_BAD_PARAMETER); } - status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + /* + * We will run _STA/_INI on Devices and Processors only + */ + if ((node->type != ACPI_TYPE_DEVICE) && + (node->type != ACPI_TYPE_PROCESSOR)) { + return_ACPI_STATUS (AE_OK); } + if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, ".")); + } + + info->device_count++; + /* * Run _STA to determine if we can run _INI on the device. */ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA")); status = acpi_ut_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { - /* Ignore error and move on to next device */ + if (node->type == ACPI_TYPE_DEVICE) { + /* Ignore error and move on to next device */ - return_ACPI_STATUS (AE_OK); - } + return_ACPI_STATUS (AE_OK); + } - info->num_STA++; + /* _STA is not required for Processor objects */ + } + else { + info->num_STA++; - if (!(flags & 0x01)) { - /* don't look at children of a not present device */ + if (!(flags & 0x01)) { + /* Don't look at children of a not present device */ - return_ACPI_STATUS(AE_CTRL_DEPTH); + return_ACPI_STATUS(AE_CTRL_DEPTH); + } } /* diff -urN linux-2.4.24/drivers/acpi/namespace/nsload.c linux-2.4.25/drivers/acpi/namespace/nsload.c --- linux-2.4.24/drivers/acpi/namespace/nsload.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsload.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsnames.c linux-2.4.25/drivers/acpi/namespace/nsnames.c --- linux-2.4.24/drivers/acpi/namespace/nsnames.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsnames.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsobject.c linux-2.4.25/drivers/acpi/namespace/nsobject.c --- linux-2.4.24/drivers/acpi/namespace/nsobject.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsobject.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -104,7 +104,8 @@ if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { /* Not a name handle */ - ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle\n")); + ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n", + node, acpi_ut_get_descriptor_name (node))); return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -151,7 +152,7 @@ } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", - obj_desc, node, node->name.ascii)); + obj_desc, node, acpi_ut_get_node_name (node))); /* Detach an existing attached object if present */ @@ -234,7 +235,7 @@ node->type = ACPI_TYPE_ANY; ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n", - node, node->name.ascii, obj_desc)); + node, acpi_ut_get_node_name (node), obj_desc)); /* Remove one reference on the object (and all subobjects) */ diff -urN linux-2.4.24/drivers/acpi/namespace/nsparse.c linux-2.4.25/drivers/acpi/namespace/nsparse.c --- linux-2.4.24/drivers/acpi/namespace/nsparse.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsparse.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nssearch.c linux-2.4.25/drivers/acpi/namespace/nssearch.c --- linux-2.4.24/drivers/acpi/namespace/nssearch.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/namespace/nssearch.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -119,7 +119,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", (char *) &target_name, acpi_ut_get_type_name (next_node->type), - next_node, node->name.ascii, node)); + next_node, acpi_ut_get_node_name (node), node)); *return_node = next_node; return_ACPI_STATUS (AE_OK); @@ -145,7 +145,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", (char *) &target_name, acpi_ut_get_type_name (type), - node->name.ascii, node, node->child)); + acpi_ut_get_node_name (node), node, node->child)); return_ACPI_STATUS (AE_NOT_FOUND); } diff -urN linux-2.4.24/drivers/acpi/namespace/nsutils.c linux-2.4.25/drivers/acpi/namespace/nsutils.c --- linux-2.4.24/drivers/acpi/namespace/nsutils.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/namespace/nsutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -977,8 +977,8 @@ parent_node = acpi_ns_get_parent_node (child_node); if (parent_node) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n", - child_node, child_node->name.ascii, - parent_node, parent_node->name.ascii)); + child_node, acpi_ut_get_node_name (child_node), + parent_node, acpi_ut_get_node_name (parent_node))); if (parent_node->name.integer) { return_VALUE ((acpi_name) parent_node->name.integer); @@ -986,7 +986,7 @@ } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n", - child_node, child_node->name.ascii)); + child_node, acpi_ut_get_node_name (child_node))); } return_VALUE (ACPI_UNKNOWN_NAME); diff -urN linux-2.4.24/drivers/acpi/namespace/nswalk.c linux-2.4.25/drivers/acpi/namespace/nswalk.c --- linux-2.4.24/drivers/acpi/namespace/nswalk.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nswalk.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsxfeval.c linux-2.4.25/drivers/acpi/namespace/nsxfeval.c --- linux-2.4.24/drivers/acpi/namespace/nsxfeval.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsxfeval.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/namespace/nsxfname.c linux-2.4.25/drivers/acpi/namespace/nsxfname.c --- linux-2.4.24/drivers/acpi/namespace/nsxfname.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsxfname.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -199,7 +199,7 @@ /* Just copy the ACPI name from the Node and zero terminate it */ - ACPI_STRNCPY (buffer->pointer, node->name.ascii, + ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node), ACPI_NAME_SIZE); ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0; status = AE_OK; diff -urN linux-2.4.24/drivers/acpi/namespace/nsxfobj.c linux-2.4.25/drivers/acpi/namespace/nsxfobj.c --- linux-2.4.24/drivers/acpi/namespace/nsxfobj.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/namespace/nsxfobj.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/osl.c linux-2.4.25/drivers/acpi/osl.c --- linux-2.4.24/drivers/acpi/osl.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/osl.c 2004-02-18 05:36:31.000000000 -0800 @@ -60,13 +60,13 @@ #ifdef ENABLE_DEBUGGER #include /* stuff for debugger support */ -int acpi_in_debugger = 0; +int acpi_in_debugger; extern char line_buf[80]; #endif /*ENABLE_DEBUGGER*/ -static int acpi_irq_irq = 0; -static OSD_HANDLER acpi_irq_handler = NULL; -static void *acpi_irq_context = NULL; +static int acpi_irq_irq; +static OSD_HANDLER acpi_irq_handler; +static void *acpi_irq_context; acpi_status diff -urN linux-2.4.24/drivers/acpi/parser/psargs.c linux-2.4.25/drivers/acpi/parser/psargs.c --- linux-2.4.24/drivers/acpi/parser/psargs.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/psargs.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -490,7 +490,7 @@ acpi_ps_get_next_field ( struct acpi_parse_state *parser_state) { - u32 aml_offset = ACPI_PTR_DIFF (parser_state->aml, + u32 aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start); union acpi_parse_object *field; u16 opcode; @@ -677,7 +677,7 @@ /* Fill in bytelist data */ - arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end, + arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end, parser_state->aml); arg->named.data = parser_state->aml; diff -urN linux-2.4.24/drivers/acpi/parser/psopcode.c linux-2.4.25/drivers/acpi/parser/psopcode.c --- linux-2.4.24/drivers/acpi/parser/psopcode.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/psopcode.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/parser/psparse.c linux-2.4.25/drivers/acpi/parser/psparse.c --- linux-2.4.24/drivers/acpi/parser/psparse.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/parser/psparse.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -498,7 +498,7 @@ if (!op) { /* Get the next opcode from the AML stream */ - walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml, + walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start); walk_state->opcode = acpi_ps_peek_opcode (parser_state); @@ -710,7 +710,7 @@ while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) { - walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml, + walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start); status = acpi_ps_get_next_arg (walk_state, parser_state, GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg); diff -urN linux-2.4.24/drivers/acpi/parser/psscope.c linux-2.4.25/drivers/acpi/parser/psscope.c --- linux-2.4.24/drivers/acpi/parser/psscope.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/psscope.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/parser/pstree.c linux-2.4.25/drivers/acpi/parser/pstree.c --- linux-2.4.24/drivers/acpi/parser/pstree.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/pstree.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/parser/psutils.c linux-2.4.25/drivers/acpi/parser/psutils.c --- linux-2.4.24/drivers/acpi/parser/psutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/psutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/parser/pswalk.c linux-2.4.25/drivers/acpi/parser/pswalk.c --- linux-2.4.24/drivers/acpi/parser/pswalk.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/pswalk.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/parser/psxface.c linux-2.4.25/drivers/acpi/parser/psxface.c --- linux-2.4.24/drivers/acpi/parser/psxface.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/parser/psxface.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -127,7 +127,8 @@ op = acpi_ps_create_scope_op (); if (!op) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup1; } /* @@ -142,20 +143,24 @@ walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, NULL, NULL, NULL); if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup2; } status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (walk_state); - return_ACPI_STATUS (status); + goto cleanup3; } /* Parse the AML */ status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); + if (ACPI_FAILURE (status)) { + goto cleanup1; /* Walk state is already deleted */ + + } /* * 2) Execute the method. Performs second pass parse simultaneously @@ -168,7 +173,8 @@ op = acpi_ps_create_scope_op (); if (!op) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup1; } /* Init new op with the method name and pointer back to the NS node */ @@ -180,22 +186,30 @@ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup2; } status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, params, return_obj_desc, 3); if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (walk_state); - return_ACPI_STATUS (status); + goto cleanup3; } /* * The walk of the parse tree is where we actually execute the method */ status = acpi_ps_parse_aml (walk_state); + goto cleanup2; /* Walk state already deleted */ + + +cleanup3: + acpi_ds_delete_walk_state (walk_state); + +cleanup2: acpi_ps_delete_parse_tree (op); +cleanup1: if (params) { /* Take away the extra reference that we gave the parameters above */ @@ -206,6 +220,10 @@ } } + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + /* * If the method has returned an object, signal this to the caller with * a control exception code diff -urN linux-2.4.24/drivers/acpi/pci_irq.c linux-2.4.25/drivers/acpi/pci_irq.c --- linux-2.4.24/drivers/acpi/pci_irq.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/pci_irq.c 2004-02-18 05:36:31.000000000 -0800 @@ -318,7 +318,6 @@ { int irq = 0; u8 pin = 0; - static u16 irq_mask = 0; ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); @@ -375,10 +374,13 @@ * Make sure all (legacy) PCI IRQs are set as level-triggered. */ #ifdef CONFIG_X86 - if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); - irq_mask |= (1 << dev->irq); - eisa_set_level_irq(dev->irq); + { + static u16 irq_mask; + if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); + irq_mask |= (1 << dev->irq); + eisa_set_level_irq(dev->irq); + } } #endif #ifdef CONFIG_IOSAPIC diff -urN linux-2.4.24/drivers/acpi/pci_root.c linux-2.4.25/drivers/acpi/pci_root.c --- linux-2.4.24/drivers/acpi/pci_root.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/pci_root.c 2004-02-18 05:36:31.000000000 -0800 @@ -61,8 +61,6 @@ acpi_handle handle; struct acpi_pci_id id; struct pci_bus *bus; - u64 mem_tra; - u64 io_tra; }; static LIST_HEAD(acpi_pci_roots); @@ -114,97 +112,6 @@ } } -void -acpi_pci_get_translations ( - struct acpi_pci_id *id, - u64 *mem_tra, - u64 *io_tra) -{ - struct list_head *node = NULL; - struct acpi_pci_root *entry; - - /* TBD: Locking */ - list_for_each(node, &acpi_pci_roots) { - entry = list_entry(node, struct acpi_pci_root, node); - if ((id->segment == entry->id.segment) - && (id->bus == entry->id.bus)) { - *mem_tra = entry->mem_tra; - *io_tra = entry->io_tra; - return; - } - } - - *mem_tra = 0; - *io_tra = 0; -} - - -static u64 -acpi_pci_root_bus_tra ( - struct acpi_resource *resource, - int type) -{ - struct acpi_resource_address16 *address16; - struct acpi_resource_address32 *address32; - struct acpi_resource_address64 *address64; - - while (1) { - switch (resource->id) { - case ACPI_RSTYPE_END_TAG: - return 0; - - case ACPI_RSTYPE_ADDRESS16: - address16 = (struct acpi_resource_address16 *) &resource->data; - if (type == address16->resource_type) { - return address16->address_translation_offset; - } - break; - - case ACPI_RSTYPE_ADDRESS32: - address32 = (struct acpi_resource_address32 *) &resource->data; - if (type == address32->resource_type) { - return address32->address_translation_offset; - } - break; - - case ACPI_RSTYPE_ADDRESS64: - address64 = (struct acpi_resource_address64 *) &resource->data; - if (type == address64->resource_type) { - return address64->address_translation_offset; - } - break; - } - resource = ACPI_PTR_ADD (struct acpi_resource, - resource, resource->length); - } - - return 0; -} - - -static int -acpi_pci_evaluate_crs ( - struct acpi_pci_root *root) -{ - acpi_status status; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - - ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs"); - - status = acpi_get_current_resources (root->handle, &buffer); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - root->io_tra = acpi_pci_root_bus_tra ((struct acpi_resource *) - buffer.pointer, ACPI_IO_RANGE); - root->mem_tra = acpi_pci_root_bus_tra ((struct acpi_resource *) - buffer.pointer, ACPI_MEMORY_RANGE); - - acpi_os_free(buffer.pointer); - return_VALUE(0); -} - - static int acpi_pci_root_add ( struct acpi_device *device) @@ -289,10 +196,8 @@ root->id.function = device->pnp.bus_address & 0xFFFF; /* - * Evaluate _CRS to get root bridge resources * TBD: Need PCI interface for enumeration/configuration of roots. */ - acpi_pci_evaluate_crs(root); /* TBD: Locking */ list_add_tail(&root->node, &acpi_pci_roots); diff -urN linux-2.4.24/drivers/acpi/power.c linux-2.4.25/drivers/acpi/power.c --- linux-2.4.24/drivers/acpi/power.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/power.c 2004-02-18 05:36:31.000000000 -0800 @@ -373,7 +373,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_power_dir = NULL; +struct proc_dir_entry *acpi_power_dir; static int diff -urN linux-2.4.24/drivers/acpi/processor.c linux-2.4.25/drivers/acpi/processor.c --- linux-2.4.24/drivers/acpi/processor.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/processor.c 2004-02-18 05:36:31.000000000 -0800 @@ -144,6 +144,8 @@ int platform_limit; u16 control_register; u16 status_register; + u8 control_register_bit_width; + u8 status_register_bit_width; int state_count; struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; }; @@ -212,7 +214,7 @@ static struct acpi_processor *processors[NR_CPUS]; static struct acpi_processor_errata errata; -static void (*pm_idle_save)(void) = NULL; +static void (*pm_idle_save)(void); /* -------------------------------------------------------------------------- @@ -902,7 +904,7 @@ } pr->performance.control_register = (u16) reg->address; - + pr->performance.control_register_bit_width = reg->bit_width; /* * status_register */ @@ -929,6 +931,7 @@ } pr->performance.status_register = (u16) reg->address; + pr->performance.status_register_bit_width = reg->bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "control_register[0x%04x] status_register[0x%04x]\n", @@ -1018,6 +1021,42 @@ return_VALUE(result); } +static int +acpi_processor_write_port( + u16 port, + u8 bit_width, + u32 value) +{ + if (bit_width <= 8) { + outb(value, port); + } else if (bit_width <= 16) { + outw(value, port); + } else if (bit_width <= 32) { + outl(value, port); + } else { + return -ENODEV; + } + return 0; +} + +static int +acpi_processor_read_port( + u16 port, + u8 bit_width, + u32 *ret) +{ + *ret = 0; + if (bit_width <= 8) { + *ret = inb(port); + } else if (bit_width <= 16) { + *ret = inw(port); + } else if (bit_width <= 32) { + *ret = inl(port); + } else { + return -ENODEV; + } + return 0; +} static int acpi_processor_set_performance ( @@ -1025,7 +1064,9 @@ int state) { u16 port = 0; - u8 value = 0; + u8 bit_width = 0; + int ret = 0; + u32 value = 0; int i = 0; ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); @@ -1064,12 +1105,18 @@ */ port = pr->performance.control_register; - value = (u16) pr->performance.states[state].control; + value = (u32) pr->performance.states[state].control; + bit_width = pr->performance.control_register_bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing 0x%02x to port 0x%04x\n", value, port)); + "Writing 0x%08x to port 0x%04x\n", value, port)); - outb(value, port); + ret = acpi_processor_write_port(port, bit_width, value); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid port width 0x%04x\n", bit_width)); + return_VALUE(ret); + } /* * Then we read the 'status_register' and compare the value with the @@ -1079,19 +1126,25 @@ */ port = pr->performance.status_register; + bit_width = pr->performance.status_register_bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Looking for 0x%02x from port 0x%04x\n", - (u8) pr->performance.states[state].status, port)); + "Looking for 0x%08x from port 0x%04x\n", + (u32) pr->performance.states[state].status, port)); for (i=0; i<100; i++) { - value = inb(port); - if (value == (u8) pr->performance.states[state].status) + ret = acpi_processor_read_port(port, bit_width, &value); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid port width 0x%04x\n", bit_width)); + return_VALUE(ret); + } + if (value == (u32) pr->performance.states[state].status) break; udelay(10); } - if (value != pr->performance.states[state].status) { + if (value != (u32) pr->performance.states[state].status) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); return_VALUE(-ENODEV); } diff -urN linux-2.4.24/drivers/acpi/resources/rsaddr.c linux-2.4.25/drivers/acpi/resources/rsaddr.c --- linux-2.4.24/drivers/acpi/resources/rsaddr.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/resources/rsaddr.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/resources/rscalc.c linux-2.4.25/drivers/acpi/resources/rscalc.c --- linux-2.4.24/drivers/acpi/resources/rscalc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rscalc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -696,7 +696,7 @@ default: /* * If we get here, everything is out of sync, - * so exit with an error + * exit with an error */ return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); } @@ -704,7 +704,7 @@ /* * Update the return value and counter */ - buffer_size += ACPI_ALIGN_RESOURCE_SIZE(structure_size); + buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size); bytes_parsed += bytes_consumed; /* diff -urN linux-2.4.24/drivers/acpi/resources/rscreate.c linux-2.4.25/drivers/acpi/resources/rscreate.c --- linux-2.4.24/drivers/acpi/resources/rscreate.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rscreate.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -331,7 +331,7 @@ /* Now align the current length */ - user_prt->length = ACPI_ROUND_UP_to_64_bITS (user_prt->length); + user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length); /* * 4) Fourth subobject: Dereference the PRT.source_index diff -urN linux-2.4.24/drivers/acpi/resources/rsdump.c linux-2.4.25/drivers/acpi/resources/rsdump.c --- linux-2.4.24/drivers/acpi/resources/rsdump.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsdump.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -899,24 +899,19 @@ "" : "not "); acpi_os_printf (" Granularity: %8.8X%8.8X\n", - ACPI_HIDWORD (address64_data->granularity), - ACPI_LODWORD (address64_data->granularity)); + ACPI_FORMAT_UINT64 (address64_data->granularity)); acpi_os_printf (" Address range min: %8.8X%8.8X\n", - ACPI_HIDWORD (address64_data->min_address_range), - ACPI_HIDWORD (address64_data->min_address_range)); + ACPI_FORMAT_UINT64 (address64_data->min_address_range)); acpi_os_printf (" Address range max: %8.8X%8.8X\n", - ACPI_HIDWORD (address64_data->max_address_range), - ACPI_HIDWORD (address64_data->max_address_range)); + ACPI_FORMAT_UINT64 (address64_data->max_address_range)); acpi_os_printf (" Address translation offset: %8.8X%8.8X\n", - ACPI_HIDWORD (address64_data->address_translation_offset), - ACPI_HIDWORD (address64_data->address_translation_offset)); + ACPI_FORMAT_UINT64 (address64_data->address_translation_offset)); acpi_os_printf (" Address Length: %8.8X%8.8X\n", - ACPI_HIDWORD (address64_data->address_length), - ACPI_HIDWORD (address64_data->address_length)); + ACPI_FORMAT_UINT64 (address64_data->address_length)); if(0xFF != address64_data->resource_source.index) { acpi_os_printf (" Resource Source Index: %X\n", @@ -1126,8 +1121,7 @@ acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++); acpi_os_printf (" Address: %8.8X%8.8X\n", - ACPI_HIDWORD (prt_element->address), - ACPI_LODWORD (prt_element->address)); + ACPI_FORMAT_UINT64 (prt_element->address)); acpi_os_printf (" Pin: %X\n", prt_element->pin); diff -urN linux-2.4.24/drivers/acpi/resources/rsio.c linux-2.4.25/drivers/acpi/resources/rsio.c --- linux-2.4.24/drivers/acpi/resources/rsio.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsio.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/resources/rsirq.c linux-2.4.25/drivers/acpi/resources/rsirq.c --- linux-2.4.24/drivers/acpi/resources/rsirq.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/resources/rsirq.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,26 +132,28 @@ temp8 = *buffer; /* - * Check for HE, LL or HL + * Check for HE, LL interrupts */ - if (temp8 & 0x01) { + switch (temp8 & 0x09) { + case 0x01: /* HE */ output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; - } - else { - if (temp8 & 0x8) { - output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; - output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; - } - else { - /* - * Only _LL and _HE polarity/trigger interrupts - * are allowed (ACPI spec v1.0b ection 6.4.2.1), - * so an error will occur if we reach this point - */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n")); - return_ACPI_STATUS (AE_BAD_DATA); - } + break; + + case 0x08: /* LL */ + output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; + break; + + default: + /* + * Only _LL and _HE polarity/trigger interrupts + * are allowed (ACPI spec, section "IRQ Format") + * so 0x00 and 0x09 are illegal. + */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Invalid interrupt polarity/trigger in resource list, %X\n", temp8)); + return_ACPI_STATUS (AE_BAD_DATA); } /* @@ -419,7 +421,7 @@ * Point the String pointer to the end of this structure. */ output_struct->data.extended_irq.resource_source.string_ptr = - (char *)(output_struct + struct_size); + (char *)((char *) output_struct + struct_size); temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr; diff -urN linux-2.4.24/drivers/acpi/resources/rslist.c linux-2.4.25/drivers/acpi/resources/rslist.c --- linux-2.4.24/drivers/acpi/resources/rslist.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rslist.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -312,8 +312,8 @@ * Set the Buffer to the next structure */ resource = ACPI_CAST_PTR (struct acpi_resource, buffer); - resource->length = ACPI_ALIGN_RESOURCE_SIZE(resource->length); - buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size); + resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length); + buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size); } /* end while */ diff -urN linux-2.4.24/drivers/acpi/resources/rsmemory.c linux-2.4.25/drivers/acpi/resources/rsmemory.c --- linux-2.4.24/drivers/acpi/resources/rsmemory.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsmemory.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/resources/rsmisc.c linux-2.4.25/drivers/acpi/resources/rsmisc.c --- linux-2.4.24/drivers/acpi/resources/rsmisc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsmisc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/resources/rsutils.c linux-2.4.25/drivers/acpi/resources/rsutils.c --- linux-2.4.24/drivers/acpi/resources/rsutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/resources/rsxface.c linux-2.4.25/drivers/acpi/resources/rsxface.c --- linux-2.4.24/drivers/acpi/resources/rsxface.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/resources/rsxface.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/tables/tbconvrt.c linux-2.4.25/drivers/acpi/tables/tbconvrt.c --- linux-2.4.24/drivers/acpi/tables/tbconvrt.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/tables/tbconvrt.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -138,11 +138,11 @@ for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { if (acpi_gbl_RSDP->revision < 2) { ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], - ((struct rsdt_descriptor_rev1 *) table_info->pointer)->table_offset_entry[i]); + (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]); } else { new_table->table_offset_entry[i] = - ((XSDT_DESCRIPTOR *) table_info->pointer)->table_offset_entry[i]; + (ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i]; } } @@ -152,7 +152,7 @@ /* Point the table descriptor to the new table */ - table_info->pointer = (struct acpi_table_header *) new_table; + table_info->pointer = ACPI_CAST_PTR (struct acpi_table_header, new_table); table_info->length = table_size; table_info->allocation = ACPI_MEM_ALLOCATED; @@ -469,7 +469,7 @@ /* Install the new table */ - table_desc->pointer = (struct acpi_table_header *) acpi_gbl_FADT; + table_desc->pointer = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT); table_desc->allocation = ACPI_MEM_ALLOCATED; table_desc->length = sizeof (struct fadt_descriptor_rev2); diff -urN linux-2.4.24/drivers/acpi/tables/tbget.c linux-2.4.25/drivers/acpi/tables/tbget.c --- linux-2.4.24/drivers/acpi/tables/tbget.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbget.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -148,8 +148,7 @@ (void *) &header); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n", - ACPI_HIDWORD (address->pointer.physical), - ACPI_LODWORD (address->pointer.physical), + ACPI_FORMAT_UINT64 (address->pointer.physical), sizeof (struct acpi_table_header))); return_ACPI_STATUS (status); } @@ -365,8 +364,7 @@ if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n", header->signature, - ACPI_HIDWORD (address->pointer.physical), - ACPI_LODWORD (address->pointer.physical), header->length)); + ACPI_FORMAT_UINT64 (address->pointer.physical), header->length)); return (status); } @@ -408,8 +406,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", full_table->signature, - ACPI_HIDWORD (address->pointer.physical), - ACPI_LODWORD (address->pointer.physical), full_table)); + ACPI_FORMAT_UINT64 (address->pointer.physical), full_table)); return_ACPI_STATUS (status); } @@ -458,6 +455,7 @@ if (instance == 1) { /* Get the first */ + *table_ptr_loc = NULL; if (acpi_gbl_table_lists[table_type].next) { *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer; } diff -urN linux-2.4.24/drivers/acpi/tables/tbgetall.c linux-2.4.25/drivers/acpi/tables/tbgetall.c --- linux-2.4.24/drivers/acpi/tables/tbgetall.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbgetall.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -240,8 +240,7 @@ if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n", acpi_format_exception (status), - ACPI_HIDWORD (address.pointer.value), - ACPI_LODWORD (address.pointer.value))); + ACPI_FORMAT_UINT64 (address.pointer.value))); } } diff -urN linux-2.4.24/drivers/acpi/tables/tbinstal.c linux-2.4.25/drivers/acpi/tables/tbinstal.c --- linux-2.4.24/drivers/acpi/tables/tbinstal.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/tables/tbinstal.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/tables/tbrsdt.c linux-2.4.25/drivers/acpi/tables/tbrsdt.c --- linux-2.4.24/drivers/acpi/tables/tbrsdt.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbrsdt.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -233,6 +233,15 @@ acpi_gbl_RSDP->rsdt_physical_address, (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); + if (acpi_gbl_RSDP->revision < 2) { + ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n")) + } + else { + ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n")) + } + + ACPI_DUMP_BUFFER ((char *) table_ptr, 48); + return (AE_BAD_SIGNATURE); } @@ -278,8 +287,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n", acpi_gbl_RSDP, - ACPI_HIDWORD (address.pointer.value), - ACPI_LODWORD (address.pointer.value))); + ACPI_FORMAT_UINT64 (address.pointer.value))); /* Check the RSDT or XSDT signature */ @@ -306,7 +314,7 @@ return_ACPI_STATUS (status); } - acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer; + acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); return_ACPI_STATUS (status); diff -urN linux-2.4.24/drivers/acpi/tables/tbutils.c linux-2.4.25/drivers/acpi/tables/tbutils.c --- linux-2.4.24/drivers/acpi/tables/tbutils.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbutils.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/tables/tbxface.c linux-2.4.25/drivers/acpi/tables/tbxface.c --- linux-2.4.24/drivers/acpi/tables/tbxface.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbxface.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -251,7 +251,7 @@ /* Find all tables of the requested type */ table_desc = acpi_gbl_table_lists[table_type].next; - while (table_desc); { + while (table_desc) { /* * Delete all namespace entries owned by this table. Note that these * entries can appear anywhere in the namespace by virtue of the AML diff -urN linux-2.4.24/drivers/acpi/tables/tbxfroot.c linux-2.4.25/drivers/acpi/tables/tbxfroot.c --- linux-2.4.24/drivers/acpi/tables/tbxfroot.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/tables/tbxfroot.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -211,8 +211,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP located at %p, RSDT physical=%8.8X%8.8X \n", acpi_gbl_RSDP, - ACPI_HIDWORD (address.pointer.value), - ACPI_LODWORD (address.pointer.value))); + ACPI_FORMAT_UINT64 (address.pointer.value))); /* Insert processor_mode flags */ @@ -242,11 +241,11 @@ /* Get the next table pointer, handle RSDT vs. XSDT */ if (acpi_gbl_RSDP->revision < 2) { - address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i]; + address.pointer.value = (ACPI_CAST_PTR (RSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; } else { address.pointer.value = - ((XSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i]; + (ACPI_CAST_PTR (XSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i]; } /* Get the table header */ diff -urN linux-2.4.24/drivers/acpi/tables.c linux-2.4.25/drivers/acpi/tables.c --- linux-2.4.24/drivers/acpi/tables.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/tables.c 2004-02-18 05:36:31.000000000 -0800 @@ -60,6 +60,9 @@ [ACPI_HPET] = "HPET", }; +static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; +static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; + /* System Description Table (RSDT/XSDT) */ struct acpi_table_sdt { unsigned long pa; @@ -136,8 +139,14 @@ { struct acpi_table_int_src_ovr *p = (struct acpi_table_int_src_ovr*) header; - printk(KERN_INFO PREFIX "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n", - p->bus, p->bus_irq, p->global_irq, p->flags.polarity, p->flags.trigger); + printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", + p->bus, p->bus_irq, p->global_irq, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger]); + if(p->flags.reserved) + printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n", + p->flags.reserved); + } break; @@ -145,8 +154,9 @@ { struct acpi_table_nmi_src *p = (struct acpi_table_nmi_src*) header; - printk(KERN_INFO PREFIX "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n", - p->flags.polarity, p->flags.trigger, p->global_irq); + printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n", + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->global_irq); } break; @@ -154,8 +164,10 @@ { struct acpi_table_lapic_nmi *p = (struct acpi_table_lapic_nmi*) header; - printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n", - p->acpi_id, p->flags.polarity, p->flags.trigger, p->lint); + printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", + p->acpi_id, + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], p->lint); } break; @@ -190,8 +202,10 @@ { struct acpi_table_plat_int_src *p = (struct acpi_table_plat_int_src*) header; - printk(KERN_INFO PREFIX "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - p->flags.polarity, p->flags.trigger, p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); + printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", + mps_inti_flags_polarity[p->flags.polarity], + mps_inti_flags_trigger[p->flags.trigger], + p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); } break; @@ -262,10 +276,17 @@ /* Map the DSDT header via the pointer in the FADT */ if (id == ACPI_DSDT) { - struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header; + struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header; + + if (fadt->revision == 3 && fadt->Xdsdt) { + *header = (void *) __acpi_map_table(fadt->Xdsdt, + sizeof(struct acpi_table_header)); + } else if (fadt->V1_dsdt) { + *header = (void *) __acpi_map_table(fadt->V1_dsdt, + sizeof(struct acpi_table_header)); + } else + *header = 0; - *header = (void *) __acpi_map_table(fadt->dsdt_addr, - sizeof(struct acpi_table_header)); if (!*header) { printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); return -ENODEV; diff -urN linux-2.4.24/drivers/acpi/thermal.c linux-2.4.25/drivers/acpi/thermal.c --- linux-2.4.24/drivers/acpi/thermal.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/thermal.c 2004-02-18 05:36:31.000000000 -0800 @@ -50,7 +50,7 @@ MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); MODULE_LICENSE("GPL"); -static int tzp = 0; +static int tzp; MODULE_PARM(tzp, "i"); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); @@ -405,6 +405,7 @@ if (result) return_VALUE(result); + printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature)); acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); @@ -703,7 +704,7 @@ FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_thermal_dir = NULL; +struct proc_dir_entry *acpi_thermal_dir; static int diff -urN linux-2.4.24/drivers/acpi/toshiba_acpi.c linux-2.4.25/drivers/acpi/toshiba_acpi.c --- linux-2.4.24/drivers/acpi/toshiba_acpi.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/toshiba_acpi.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,7 +2,7 @@ * toshiba_acpi.c - Toshiba Laptop ACPI Extras * * - * Copyright (C) 2002-2003 John Belmonte + * Copyright (C) 2002-2004 John Belmonte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ * */ -#define TOSHIBA_ACPI_VERSION "0.16" +#define TOSHIBA_ACPI_VERSION "0.17" #define PROC_INTERFACE_VERSION 1 #include @@ -49,9 +49,15 @@ MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); MODULE_LICENSE("GPL"); +#define MY_LOGPREFIX "toshiba_acpi: " +#define MY_ERR KERN_ERR MY_LOGPREFIX +#define MY_NOTICE KERN_NOTICE MY_LOGPREFIX +#define MY_INFO KERN_INFO MY_LOGPREFIX + /* Toshiba ACPI method paths */ #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" -#define METHOD_HCI "\\_SB_.VALD.GHCI" +#define METHOD_HCI_1 "\\_SB_.VALD.GHCI" +#define METHOD_HCI_2 "\\_SB_.VALZ.GHCI" #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" /* Toshiba HCI interface definitions @@ -122,6 +128,16 @@ */ static int +is_valid_acpi_path(const char* methodName) +{ + acpi_handle handle; + acpi_status status; + + status = acpi_get_handle(0, (char*)methodName, &handle); + return !ACPI_FAILURE(status); +} + +static int write_acpi_int(const char* methodName, int val) { struct acpi_object_list params; @@ -155,6 +171,8 @@ } #endif +static const char* method_hci /*= 0*/; + /* Perform a raw HCI call. Here we don't care about input or output buffer * format. */ @@ -178,7 +196,7 @@ results.length = sizeof(out_objs); results.pointer = out_objs; - status = acpi_evaluate_object(0, METHOD_HCI, ¶ms, + status = acpi_evaluate_object(0, (char*)method_hci, ¶ms, &results); if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { for (i = 0; i < out_objs->package.count; ++i) { @@ -216,7 +234,7 @@ return status; } -static struct proc_dir_entry* toshiba_proc_dir = NULL; +static struct proc_dir_entry* toshiba_proc_dir /*= 0*/; static int force_fan; static int last_key_event; static int key_event_valid; @@ -271,7 +289,7 @@ p += sprintf(p, "brightness_levels: %d\n", HCI_LCD_BRIGHTNESS_LEVELS); } else { - p += sprintf(p, "ERROR\n"); + printk(MY_ERR "Error reading LCD brightness\n"); } return p; @@ -311,7 +329,7 @@ p += sprintf(p, "crt_out: %d\n", is_crt); p += sprintf(p, "tv_out: %d\n", is_tv); } else { - p += sprintf(p, "ERROR\n"); + printk(MY_ERR "Error reading video out status\n"); } return p; @@ -321,25 +339,31 @@ write_video(const char* buffer, unsigned long count) { int value; - const char* buffer_end = buffer + count; + int remain = count; int lcd_out = -1; int crt_out = -1; int tv_out = -1; u32 hci_result; int video_out; - /* scan expression. Multiple expressions may be delimited with ; */ - do { - if (snscanf(buffer, count, " lcd_out : %i", &value) == 1) + /* scan expression. Multiple expressions may be delimited with ; + * + * NOTE: to keep scanning simple, invalid fields are ignored + */ + while (remain) { + if (snscanf(buffer, remain, " lcd_out : %i", &value) == 1) lcd_out = value & 1; - else if (snscanf(buffer, count, " crt_out : %i", &value) == 1) + else if (snscanf(buffer, remain, " crt_out : %i", &value) == 1) crt_out = value & 1; - else if (snscanf(buffer, count, " tv_out : %i", &value) == 1) + else if (snscanf(buffer, remain, " tv_out : %i", &value) == 1) tv_out = value & 1; /* advance to one character past the next ; */ - do ++buffer; - while ((buffer < buffer_end) && (*(buffer-1) != ';')); - } while (buffer < buffer_end); + do { + ++buffer; + --remain; + } + while (remain && *(buffer-1) != ';'); + } hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); if (hci_result == HCI_SUCCESS) { @@ -354,6 +378,8 @@ * video setting if something changed. */ if (new_video_out != video_out) write_acpi_int(METHOD_VIDEO_OUT, new_video_out); + } else { + return -EFAULT; } return count; @@ -370,7 +396,7 @@ p += sprintf(p, "running: %d\n", (value > 0)); p += sprintf(p, "force_on: %d\n", force_fan); } else { - p += sprintf(p, "ERROR\n"); + printk(MY_ERR "Error reading fan status\n"); } return p; @@ -414,8 +440,9 @@ * some machines where system events sporadically * become disabled. */ hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); } else { - p += sprintf(p, "ERROR\n"); + printk(MY_ERR "Error reading hotkey status\n"); goto end; } } @@ -466,7 +493,7 @@ { 0 , 0 , 0 }, }; -static acpi_status +static acpi_status __init add_device(void) { struct proc_dir_entry* proc; @@ -484,7 +511,7 @@ return(AE_OK); } -static acpi_status +static acpi_status __exit remove_device(void) { ProcItem* item; @@ -498,15 +525,19 @@ toshiba_acpi_init(void) { acpi_status status = AE_OK; - int value; u32 hci_result; - /* simple device detection: try reading an HCI register */ - hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); - if (hci_result != HCI_SUCCESS) + /* simple device detection: look for HCI method */ + if (is_valid_acpi_path(METHOD_HCI_1)) + method_hci = METHOD_HCI_1; + else if (is_valid_acpi_path(METHOD_HCI_2)) + method_hci = METHOD_HCI_2; + else return -ENODEV; - printk("Toshiba Laptop ACPI Extras version %s\n", TOSHIBA_ACPI_VERSION); + printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", + TOSHIBA_ACPI_VERSION); + printk(MY_INFO " HCI method: %s\n", method_hci); force_fan = 0; key_event_valid = 0; diff -urN linux-2.4.24/drivers/acpi/utilities/utalloc.c linux-2.4.25/drivers/acpi/utilities/utalloc.c --- linux-2.4.24/drivers/acpi/utilities/utalloc.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/utilities/utalloc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -902,71 +902,30 @@ descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space); if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { - acpi_os_printf ("%p Len %04X %9.9s-%d ", + acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ", descriptor, element->size, element->module, - element->line); + element->line, acpi_ut_get_descriptor_name (descriptor)); - /* Most of the elements will be internal objects. */ + /* Most of the elements will be Operand objects. */ switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { case ACPI_DESC_TYPE_OPERAND: - acpi_os_printf ("obj_type %12.12s R%hd", + acpi_os_printf ("%12.12s R%hd", acpi_ut_get_type_name (descriptor->object.common.type), descriptor->object.common.reference_count); break; case ACPI_DESC_TYPE_PARSER: - acpi_os_printf ("parse_obj aml_opcode %04hX", + acpi_os_printf ("aml_opcode %04hX", descriptor->op.asl.aml_opcode); break; case ACPI_DESC_TYPE_NAMED: - acpi_os_printf ("Node %4.4s", - descriptor->node.name.ascii); - break; - - case ACPI_DESC_TYPE_STATE: - acpi_os_printf ("Untyped state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_UPDATE: - acpi_os_printf ("UPDATE state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_PACKAGE: - acpi_os_printf ("PACKAGE state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_CONTROL: - acpi_os_printf ("CONTROL state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_RPSCOPE: - acpi_os_printf ("ROOT-PARSE-SCOPE state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_PSCOPE: - acpi_os_printf ("PARSE-SCOPE state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_WSCOPE: - acpi_os_printf ("WALK-SCOPE state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_RESULT: - acpi_os_printf ("RESULT state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_NOTIFY: - acpi_os_printf ("NOTIFY state_obj"); - break; - - case ACPI_DESC_TYPE_STATE_THREAD: - acpi_os_printf ("THREAD state_obj"); + acpi_os_printf ("%4.4s", + acpi_ut_get_node_name (&descriptor->node)); break; default: - /* All types should appear above */ break; } diff -urN linux-2.4.24/drivers/acpi/utilities/utcopy.c linux-2.4.25/drivers/acpi/utilities/utcopy.c --- linux-2.4.24/drivers/acpi/utilities/utcopy.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utcopy.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/utilities/utdebug.c linux-2.4.25/drivers/acpi/utilities/utdebug.c --- linux-2.4.24/drivers/acpi/utilities/utdebug.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utdebug.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -447,7 +447,7 @@ acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info, "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str, - ACPI_HIDWORD (value), ACPI_LODWORD (value)); + ACPI_FORMAT_UINT64 (value)); acpi_gbl_nesting_level--; } diff -urN linux-2.4.24/drivers/acpi/utilities/utdelete.c linux-2.4.25/drivers/acpi/utilities/utdelete.c --- linux-2.4.24/drivers/acpi/utilities/utdelete.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/utilities/utdelete.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -140,7 +140,7 @@ /* Walk the handler list for this device */ - handler_desc = object->device.address_space; + handler_desc = object->device.handler; while (handler_desc) { next_desc = handler_desc->address_space.next; acpi_ut_remove_reference (handler_desc); @@ -193,7 +193,7 @@ * default handlers -- and therefore, we created the context object * locally, it was not created by an external caller. */ - handler_desc = object->region.address_space; + handler_desc = object->region.handler; if (handler_desc) { if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { obj_pointer = second_desc->extra.region_context; diff -urN linux-2.4.24/drivers/acpi/utilities/uteval.c linux-2.4.25/drivers/acpi/utilities/uteval.c --- linux-2.4.24/drivers/acpi/utilities/uteval.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/uteval.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -91,7 +91,7 @@ if (ACPI_FAILURE (status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", - prefix_node->name.ascii, path)); + acpi_ut_get_node_name (prefix_node), path)); } else { ACPI_REPORT_METHOD_ERROR ("Method execution failed", @@ -544,7 +544,7 @@ if (AE_NOT_FOUND == status) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "_STA on %4.4s was not found, assuming device is present\n", - device_node->name.ascii)); + acpi_ut_get_node_name (device_node))); *flags = 0x0F; status = AE_OK; diff -urN linux-2.4.24/drivers/acpi/utilities/utglobal.c linux-2.4.25/drivers/acpi/utilities/utglobal.c --- linux-2.4.24/drivers/acpi/utilities/utglobal.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/acpi/utilities/utglobal.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -358,7 +358,7 @@ /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE}, /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, - /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, 0, 0}, + /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE}, }; /***************************************************************************** @@ -534,6 +534,99 @@ } +/***************************************************************************** + * + * FUNCTION: acpi_ut_get_node_name + * + * PARAMETERS: Object - A namespace node + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Validate the node and return the node's ACPI name. + * + ****************************************************************************/ + +char * +acpi_ut_get_node_name ( + void *object) +{ + struct acpi_namespace_node *node; + + + if (!object) + { + return ("NULL NODE"); + } + + node = (struct acpi_namespace_node *) object; + + if (node->descriptor != ACPI_DESC_TYPE_NAMED) + { + return ("****"); + } + + if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii)) + { + return ("----"); + } + + return (node->name.ascii); +} + + +/***************************************************************************** + * + * FUNCTION: acpi_ut_get_descriptor_name + * + * PARAMETERS: Object - An ACPI object + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Validate object and return the descriptor type + * + ****************************************************************************/ + +static const char *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */ +{ + /* 00 */ "Invalid", + /* 01 */ "Cached", + /* 02 */ "State-Generic", + /* 03 */ "State-Update", + /* 04 */ "State-Package", + /* 05 */ "State-Control", + /* 06 */ "State-root_parse_scope", + /* 07 */ "State-parse_scope", + /* 08 */ "State-walk_scope", + /* 09 */ "State-Result", + /* 10 */ "State-Notify", + /* 11 */ "State-Thread", + /* 12 */ "Walk", + /* 13 */ "Parser", + /* 14 */ "Operand", + /* 15 */ "Node" +}; + + +char * +acpi_ut_get_descriptor_name ( + void *object) +{ + + if (!object) + { + return ("NULL OBJECT"); + } + + if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX) + { + return ((char *) acpi_gbl_bad_type); + } + + return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]); + +} + + #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* * Strings and procedures used for debug only diff -urN linux-2.4.24/drivers/acpi/utilities/utinit.c linux-2.4.25/drivers/acpi/utilities/utinit.c --- linux-2.4.24/drivers/acpi/utilities/utinit.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utinit.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/utilities/utmath.c linux-2.4.25/drivers/acpi/utilities/utmath.c --- linux-2.4.24/drivers/acpi/utilities/utmath.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utmath.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/acpi/utilities/utmisc.c linux-2.4.25/drivers/acpi/utilities/utmisc.c --- linux-2.4.24/drivers/acpi/utilities/utmisc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utmisc.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -304,16 +304,20 @@ u32 name) { char *name_ptr = (char *) &name; - u32 i; + char character; + acpi_native_uint i; ACPI_FUNCTION_ENTRY (); for (i = 0; i < ACPI_NAME_SIZE; i++) { - if (!((name_ptr[i] == '_') || - (name_ptr[i] >= 'A' && name_ptr[i] <= 'Z') || - (name_ptr[i] >= '0' && name_ptr[i] <= '9'))) { + character = *name_ptr; + name_ptr++; + + if (!((character == '_') || + (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9'))) { return (FALSE); } } diff -urN linux-2.4.24/drivers/acpi/utilities/utobject.c linux-2.4.25/drivers/acpi/utilities/utobject.c --- linux-2.4.24/drivers/acpi/utilities/utobject.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utobject.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -223,29 +223,10 @@ return (TRUE); - case ACPI_DESC_TYPE_NAMED: - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is a named obj, not ACPI obj\n", object)); - break; - - case ACPI_DESC_TYPE_PARSER: - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "**** Obj %p is a parser obj, not ACPI obj\n", object)); - break; - - case ACPI_DESC_TYPE_CACHED: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "**** Obj %p has already been released to internal cache\n", object)); - break; - default: - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "**** Obj %p has unknown descriptor type %X\n", object, - ACPI_GET_DESCRIPTOR_TYPE (object))); + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "%p is not not an ACPI operand obj [%s]\n", + object, acpi_ut_get_descriptor_name (object))); break; } @@ -322,7 +303,8 @@ if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Obj %p is not an ACPI object\n", object)); + "%p is not an ACPI Operand object [%s]\n", object, + acpi_ut_get_descriptor_name (object))); return_VOID; } diff -urN linux-2.4.24/drivers/acpi/utilities/utxface.c linux-2.4.25/drivers/acpi/utilities/utxface.c --- linux-2.4.24/drivers/acpi/utilities/utxface.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/acpi/utilities/utxface.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2003, R. Byron Moore + * Copyright (C) 2000 - 2004, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff -urN linux-2.4.24/drivers/atm/atmdev_init.c linux-2.4.25/drivers/atm/atmdev_init.c --- linux-2.4.24/drivers/atm/atmdev_init.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/drivers/atm/atmdev_init.c 2004-02-18 05:36:31.000000000 -0800 @@ -10,9 +10,6 @@ #ifdef CONFIG_ATM_ZATM extern int zatm_detect(void); #endif -#ifdef CONFIG_ATM_NICSTAR -extern int nicstar_detect(void); -#endif #ifdef CONFIG_ATM_AMBASSADOR extern int amb_detect(void); #endif @@ -41,9 +38,6 @@ #ifdef CONFIG_ATM_ZATM devs += zatm_detect(); #endif -#ifdef CONFIG_ATM_NICSTAR - devs += nicstar_detect(); -#endif #ifdef CONFIG_ATM_AMBASSADOR devs += amb_detect(); #endif diff -urN linux-2.4.24/drivers/atm/he.c linux-2.4.25/drivers/atm/he.c --- linux-2.4.24/drivers/atm/he.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/atm/he.c 2004-02-18 05:36:31.000000000 -0800 @@ -179,9 +179,7 @@ unsigned flags) { he_writel(he_dev, val, CON_DAT); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, CON_DAT); -#endif + (void) he_readl(he_dev, CON_DAT); /* flush posted writes */ he_writel(he_dev, flags | CON_CTL_WRITE | CON_CTL_ADDR(addr), CON_CTL); while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY); } @@ -1951,9 +1949,6 @@ he_writel(he_dev, RBRQ_MASK(he_dev->rbrq_head), G0_RBRQ_H + (group * 16)); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, G0_RBRQ_H + (group * 16)); -#endif } return pdus_assembled; @@ -2047,9 +2042,6 @@ he_writel(he_dev, TBRQ_MASK(he_dev->tbrq_head), G0_TBRQ_H + (group * 16)); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, G0_TBRQ_H + (group * 16)); -#endif } } @@ -2077,12 +2069,8 @@ ++moved; } - if (moved) { + if (moved) he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, G0_RBPL_T); -#endif - } } #ifdef USE_RBPS @@ -2109,12 +2097,8 @@ ++moved; } - if (moved) { + if (moved) he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, G0_RBPS_T); -#endif - } } #endif /* USE_RBPS */ @@ -2211,7 +2195,7 @@ IRQ_SIZE(CONFIG_IRQ_SIZE) | IRQ_THRESH(CONFIG_IRQ_THRESH) | IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD); - (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */ + (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata; flush posted writes */ } #ifdef USE_TASKLET spin_unlock_irqrestore(&he_dev->global_lock, flags); @@ -2252,11 +2236,8 @@ #else he_tasklet((unsigned long) he_dev); #endif - he_writel(he_dev, INT_CLEAR_A, INT_FIFO); - /* clear interrupt */ -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, INT_FIFO); -#endif + he_writel(he_dev, INT_CLEAR_A, INT_FIFO); /* clear interrupt */ + (void) he_readl(he_dev, INT_FIFO); /* flush posted writes */ } spin_unlock_irqrestore(&he_dev->global_lock, flags); return IRQ_RETVAL(handled); @@ -2325,9 +2306,7 @@ he_dev->tpdrq_tail = new_tail; he_writel(he_dev, TPDRQ_MASK(he_dev->tpdrq_tail), TPDRQ_T); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, TPDRQ_T); -#endif + (void) he_readl(he_dev, TPDRQ_T); /* flush posted writes */ } static int @@ -2482,9 +2461,7 @@ he_writel_tsr12(he_dev, 0x0, cid); he_writel_tsr13(he_dev, 0x0, cid); he_writel_tsr14(he_dev, 0x0, cid); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl_tsr0(he_dev, cid); -#endif + (void) he_readl_tsr0(he_dev, cid); /* flush posted writes */ spin_unlock_irqrestore(&he_dev->global_lock, flags); } @@ -2538,9 +2515,7 @@ the open/closed indication in rsr0 */ he_writel_rsr0(he_dev, rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl_rsr0(he_dev, cid); -#endif + (void) he_readl_rsr0(he_dev, cid); /* flush posted writes */ spin_unlock_irqrestore(&he_dev->global_lock, flags); } @@ -2594,9 +2569,7 @@ set_current_state(TASK_UNINTERRUPTIBLE); he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl_rsr0(he_dev, cid); -#endif + (void) he_readl_rsr0(he_dev, cid); /* flush posted writes */ he_writel_mbox(he_dev, cid, RXCON_CLOSE); spin_unlock_irqrestore(&he_dev->global_lock, flags); @@ -2646,9 +2619,6 @@ spin_lock_irqsave(&he_dev->global_lock, flags); he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid); /* also clears TSR4_SESSION_ENDED */ -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl_tsr4(he_dev, cid); -#endif switch (vcc->qos.txtp.traffic_class) { case ATM_UBR: @@ -2660,6 +2630,7 @@ he_writel_tsr14_upper(he_dev, TSR14_DELETE, cid); break; } + (void) he_readl_tsr4(he_dev, cid); /* flush posted writes */ tpd = __alloc_tpd(he_dev); if (tpd == NULL) { @@ -2922,9 +2893,7 @@ spin_lock_irqsave(&he_dev->global_lock, flags); he_writel(he_dev, val, FRAMER + (addr*4)); -#ifdef CONFIG_IA64_SGI_SN2 - (void) he_readl(he_dev, FRAMER + (addr*4)); -#endif + (void) he_readl(he_dev, FRAMER + (addr*4)); /* flush posted writes */ spin_unlock_irqrestore(&he_dev->global_lock, flags); } diff -urN linux-2.4.24/drivers/atm/horizon.c linux-2.4.25/drivers/atm/horizon.c --- linux-2.4.24/drivers/atm/horizon.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/atm/horizon.c 2004-02-18 05:36:31.000000000 -0800 @@ -359,8 +359,8 @@ static unsigned short debug = 0; static unsigned short vpi_bits = 0; -static unsigned short max_tx_size = 9000; -static unsigned short max_rx_size = 9000; +static int max_tx_size = 9000; +static int max_rx_size = 9000; static unsigned char pci_lat = 0; /********** access functions **********/ @@ -2919,11 +2919,11 @@ PRINTK (KERN_ERR, "vpi_bits has been limited to %hu", vpi_bits = HRZ_MAX_VPI); - if (max_tx_size > TX_AAL5_LIMIT) + if (max_tx_size < 0 || max_tx_size > TX_AAL5_LIMIT) PRINTK (KERN_NOTICE, "max_tx_size has been limited to %hu", max_tx_size = TX_AAL5_LIMIT); - if (max_rx_size > RX_AAL5_LIMIT) + if (max_rx_size < 0 || max_rx_size > RX_AAL5_LIMIT) PRINTK (KERN_NOTICE, "max_rx_size has been limited to %hu", max_rx_size = RX_AAL5_LIMIT); @@ -2938,8 +2938,8 @@ MODULE_LICENSE("GPL"); MODULE_PARM(debug, "h"); MODULE_PARM(vpi_bits, "h"); -MODULE_PARM(max_tx_size, "h"); -MODULE_PARM(max_rx_size, "h"); +MODULE_PARM(max_tx_size, "i"); +MODULE_PARM(max_rx_size, "i"); MODULE_PARM(pci_lat, "b"); MODULE_PARM_DESC(debug, "debug bitmap, see .h file"); MODULE_PARM_DESC(vpi_bits, "number of bits (0..4) to allocate to VPIs"); diff -urN linux-2.4.24/drivers/atm/idt77252.c linux-2.4.25/drivers/atm/idt77252.c --- linux-2.4.24/drivers/atm/idt77252.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/atm/idt77252.c 2004-02-18 05:36:31.000000000 -0800 @@ -665,8 +665,8 @@ skb_queue_head_init(&scq->transmit); skb_queue_head_init(&scq->pending); - TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08x\n", - scq->base, scq->next, scq->last, scq->paddr); + TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08llx\n", + scq->base, scq->next, scq->last, (unsigned long long)scq->paddr); return scq; } diff -urN linux-2.4.24/drivers/atm/nicstar.c linux-2.4.25/drivers/atm/nicstar.c --- linux-2.4.24/drivers/atm/nicstar.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/atm/nicstar.c 2004-02-18 05:36:31.000000000 -0800 @@ -214,8 +214,8 @@ static u32 ns_read_sram(ns_dev *card, u32 sram_address); static void ns_write_sram(ns_dev *card, u32 sram_address, u32 *value, int count); -static int __init ns_init_card(int i, struct pci_dev *pcidev); -static void __init ns_init_card_error(ns_dev *card, int error); +static int __devinit ns_init_card(int i, struct pci_dev *pcidev); +static void __devinit ns_init_card_error(ns_dev *card, int error); static scq_info *get_scq(int size, u32 scd); static void free_scq(scq_info *scq, struct atm_vcc *vcc); static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1, @@ -276,198 +276,152 @@ /* Functions*******************************************************************/ -#ifdef MODULE - -int __init init_module(void) +static int __devinit nicstar_init_one(struct pci_dev *pcidev, + const struct pci_device_id *ent) { - int i; - unsigned error = 0; /* Initialized to remove compile warning */ - struct pci_dev *pcidev; - - XPRINTK("nicstar: init_module() called.\n"); - if(!pci_present()) - { - printk("nicstar: no PCI subsystem found.\n"); - return -EIO; - } + static int index = -1; + unsigned int error; - for(i = 0; i < NS_MAX_CARDS; i++) - cards[i] = NULL; + index++; + cards[index] = NULL; - pcidev = NULL; - for(i = 0; i < NS_MAX_CARDS; i++) - { - if ((pcidev = pci_find_device(PCI_VENDOR_ID_IDT, - PCI_DEVICE_ID_IDT_IDT77201, - pcidev)) == NULL) - break; - - error = ns_init_card(i, pcidev); - if (error) - cards[i--] = NULL; /* Try to find another card but don't increment index */ + error = ns_init_card(index, pcidev); + if (error) { + cards[index--] = NULL; /* don't increment index */ + goto err_out; } - if (i == 0) - { - if (!error) - { - printk("nicstar: no cards found.\n"); - return -ENXIO; - } - else - return -EIO; - } - TXPRINTK("nicstar: TX debug enabled.\n"); - RXPRINTK("nicstar: RX debug enabled.\n"); - PRINTK("nicstar: General debug enabled.\n"); -#ifdef PHY_LOOPBACK - printk("nicstar: using PHY loopback.\n"); -#endif /* PHY_LOOPBACK */ - XPRINTK("nicstar: init_module() returned.\n"); - - init_timer(&ns_timer); - ns_timer.expires = jiffies + NS_POLL_PERIOD; - ns_timer.data = 0UL; - ns_timer.function = ns_poll; - add_timer(&ns_timer); return 0; +err_out: + return -ENODEV; } -void cleanup_module(void) +static void __devexit nicstar_remove_one(struct pci_dev *pcidev) { int i, j; - unsigned short pci_command; - ns_dev *card; + ns_dev *card = pci_get_drvdata(pcidev); struct sk_buff *hb; struct sk_buff *iovb; struct sk_buff *lb; struct sk_buff *sb; - XPRINTK("nicstar: cleanup_module() called.\n"); - - if (MOD_IN_USE) - printk("nicstar: module in use, remove delayed.\n"); + i = card->index; - del_timer(&ns_timer); - - for (i = 0; i < NS_MAX_CARDS; i++) - { - if (cards[i] == NULL) - continue; - - card = cards[i]; + if (cards[i] == NULL) + return; - if (card->atmdev->phy && card->atmdev->phy->stop) - card->atmdev->phy->stop(card->atmdev); + if (card->atmdev->phy && card->atmdev->phy->stop) + card->atmdev->phy->stop(card->atmdev); - /* Stop everything */ - writel(0x00000000, card->membase + CFG); + /* Stop everything */ + writel(0x00000000, card->membase + CFG); - /* De-register device */ - atm_dev_deregister(card->atmdev); + /* De-register device */ + atm_dev_deregister(card->atmdev); - /* Disable memory mapping and busmastering */ - if (pci_read_config_word(card->pcidev, PCI_COMMAND, &pci_command) != 0) - { - printk("nicstar%d: can't read PCI_COMMAND.\n", i); - } - pci_command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - if (pci_write_config_word(card->pcidev, PCI_COMMAND, pci_command) != 0) - { - printk("nicstar%d: can't write PCI_COMMAND.\n", i); - } - - /* Free up resources */ - j = 0; - PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); - while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) - { - dev_kfree_skb_any(hb); - j++; - } - PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); - j = 0; - PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); - while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) - { - dev_kfree_skb_any(iovb); - j++; - } - PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); - while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) - dev_kfree_skb_any(lb); - while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) - dev_kfree_skb_any(sb); - free_scq(card->scq0, NULL); - for (j = 0; j < NS_FRSCD_NUM; j++) - { - if (card->scd2vc[j] != NULL) - free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); - } - kfree(card->rsq.org); - kfree(card->tsq.org); - free_irq(card->pcidev->irq, card); - iounmap((void *) card->membase); - kfree(card); - + /* Disable PCI device */ + pci_disable_device(pcidev); + + /* Free up resources */ + j = 0; + PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); + while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) + { + dev_kfree_skb_any(hb); + j++; } - XPRINTK("nicstar: cleanup_module() returned.\n"); + PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); + j = 0; + PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); + while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) + { + dev_kfree_skb_any(iovb); + j++; + } + PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); + while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) + dev_kfree_skb_any(lb); + while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) + dev_kfree_skb_any(sb); + free_scq(card->scq0, NULL); + for (j = 0; j < NS_FRSCD_NUM; j++) + { + if (card->scd2vc[j] != NULL) + free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); + } + kfree(card->rsq.org); + kfree(card->tsq.org); + free_irq(card->pcidev->irq, card); + iounmap((void *) card->membase); + kfree(card); } -#else -int __init nicstar_detect(void) +static struct pci_device_id nicstar_pci_tbl[] __devinitdata = { - int i; - unsigned error = 0; /* Initialized to remove compile warning */ - struct pci_dev *pcidev; + {PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77201, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl); - if(!pci_present()) - { - printk("nicstar: no PCI subsystem found.\n"); - return -EIO; - } - for(i = 0; i < NS_MAX_CARDS; i++) - cards[i] = NULL; - pcidev = NULL; - for(i = 0; i < NS_MAX_CARDS; i++) - { - if ((pcidev = pci_find_device(PCI_VENDOR_ID_IDT, - PCI_DEVICE_ID_IDT_IDT77201, - pcidev)) == NULL) - break; +static struct pci_driver nicstar_driver = { + .name = "nicstar", + .id_table = nicstar_pci_tbl, + .probe = nicstar_init_one, + .remove = __devexit_p(nicstar_remove_one), +}; - error = ns_init_card(i, pcidev); - if (error) - cards[i--] = NULL; /* Try to find another card but don't increment index */ - } - if (i == 0 && error) - return -EIO; +static int __init nicstar_init(void) +{ + unsigned error = 0; /* Initialized to remove compile warning */ + + XPRINTK("nicstar: nicstar_init() called.\n"); + + error = pci_module_init(&nicstar_driver); + TXPRINTK("nicstar: TX debug enabled.\n"); RXPRINTK("nicstar: RX debug enabled.\n"); PRINTK("nicstar: General debug enabled.\n"); #ifdef PHY_LOOPBACK printk("nicstar: using PHY loopback.\n"); #endif /* PHY_LOOPBACK */ - XPRINTK("nicstar: init_module() returned.\n"); + XPRINTK("nicstar: nicstar_init() returned.\n"); - init_timer(&ns_timer); - ns_timer.expires = jiffies + NS_POLL_PERIOD; - ns_timer.data = 0UL; - ns_timer.function = ns_poll; - add_timer(&ns_timer); - return i; + if (!error) { + init_timer(&ns_timer); + ns_timer.expires = jiffies + NS_POLL_PERIOD; + ns_timer.data = 0UL; + ns_timer.function = ns_poll; + add_timer(&ns_timer); + } + + return error; } -#endif /* MODULE */ + +static void __exit nicstar_cleanup(void) +{ + XPRINTK("nicstar: nicstar_cleanup() called.\n"); + + if (MOD_IN_USE) + printk("nicstar: module in use, remove delayed.\n"); + + del_timer(&ns_timer); + + pci_unregister_driver(&nicstar_driver); + + XPRINTK("nicstar: nicstar_cleanup() returned.\n"); +} + static u32 ns_read_sram(ns_dev *card, u32 sram_address) @@ -509,11 +463,10 @@ } -static int __init ns_init_card(int i, struct pci_dev *pcidev) +static int __devinit ns_init_card(int i, struct pci_dev *pcidev) { int j; struct ns_dev *card = NULL; - unsigned short pci_command; unsigned char pci_latency; unsigned error; u32 data; @@ -542,6 +495,8 @@ spin_lock_init(&card->int_lock); spin_lock_init(&card->res_lock); + pci_set_drvdata(pcidev, card); + card->index = i; card->atmdev = NULL; card->pcidev = pcidev; @@ -556,21 +511,7 @@ } PRINTK("nicstar%d: membase at 0x%x.\n", i, card->membase); - if (pci_read_config_word(pcidev, PCI_COMMAND, &pci_command) != 0) - { - printk("nicstar%d: can't read PCI_COMMAND.\n", i); - error = 4; - ns_init_card_error(card, error); - return error; - } - pci_command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - if (pci_write_config_word(pcidev, PCI_COMMAND, pci_command) != 0) - { - printk("nicstar%d: can't write PCI_COMMAND.\n", i); - error = 5; - ns_init_card_error(card, error); - return error; - } + pci_set_master(pcidev); if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) { @@ -996,7 +937,7 @@ -static void __init ns_init_card_error(ns_dev *card, int error) +static void __devinit ns_init_card_error(ns_dev *card, int error) { if (error >= 17) { @@ -1045,6 +986,7 @@ } if (error >= 3) { + pci_disable_device(card->pcidev); kfree(card); } } @@ -3148,3 +3090,8 @@ spin_unlock_irqrestore(&card->res_lock, flags); return (unsigned char) data; } + + + +module_init(nicstar_init); +module_exit(nicstar_cleanup); diff -urN linux-2.4.24/drivers/block/cciss.c linux-2.4.25/drivers/block/cciss.c --- linux-2.4.24/drivers/block/cciss.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/block/cciss.c 2004-02-18 05:36:31.000000000 -0800 @@ -2537,8 +2537,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) { ushort subsystem_vendor_id, subsystem_device_id, command; - unchar irq = pdev->irq; - __u32 board_id; + unchar irq = pdev->irq, ready = 0; + __u32 board_id, scratchpad; __u64 cfg_offset; __u32 cfg_base_addr; __u64 cfg_base_addr_index; @@ -2609,10 +2609,24 @@ printk("address 0 = %x\n", c->paddr); #endif /* CCISS_DEBUG */ c->vaddr = remap_pci_mem(c->paddr, 200); + /* Wait for the board to become ready. (PCI hotplug needs this.) + * We poll for up to 120 secs, once per 100ms. */ + for (i=0; i < 1200; i++) { + scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == 0xffff0000) { + ready = 1; + break; + } + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); /* wait 100ms */ + } + if (!ready) { + printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); + return -1; + } /* get the address index number */ cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET); - /* I am not prepared to deal with a 64 bit address value */ cfg_base_addr &= (__u32) 0x0000ffff; #ifdef CCISS_DEBUG printk("cfg base address = %x\n", cfg_base_addr); @@ -2624,7 +2638,7 @@ #endif /* CCISS_DEBUG */ if (cfg_base_addr_index == -1) { printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); - release_io_mem(hba[i]); + release_io_mem(c); return -1; } @@ -2661,6 +2675,17 @@ printk("Does not appear to be a valid CISS config table\n"); return -1; } + +#ifdef CONFIG_X86 +{ + /* Need to enable prefetch in the SCSI core for 6400 in x86 */ + __u32 prefetch; + prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); +} +#endif + #ifdef CCISS_DEBUG printk("Trying to put board into Simple mode\n"); #endif /* CCISS_DEBUG */ diff -urN linux-2.4.24/drivers/block/cciss.h linux-2.4.25/drivers/block/cciss.h --- linux-2.4.24/drivers/block/cciss.h 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/block/cciss.h 2004-02-18 05:36:31.000000000 -0800 @@ -137,6 +137,7 @@ #define SA5_REPLY_INTR_MASK_OFFSET 0x34 #define SA5_REPLY_PORT_OFFSET 0x44 #define SA5_INTR_STATUS 0x30 +#define SA5_SCRATCHPAD_OFFSET 0xB0 #define SA5_CTCFG_OFFSET 0xB4 #define SA5_CTMEM_OFFSET 0xB8 diff -urN linux-2.4.24/drivers/block/cciss_cmd.h linux-2.4.25/drivers/block/cciss_cmd.h --- linux-2.4.24/drivers/block/cciss_cmd.h 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/drivers/block/cciss_cmd.h 2004-02-18 05:36:31.000000000 -0800 @@ -266,6 +266,7 @@ DWORD Reserved; BYTE ServerName[16]; DWORD HeartBeat; + DWORD SCSI_Prefetch; } CfgTable_struct; #pragma pack() #endif /* CCISS_CMD_H */ diff -urN linux-2.4.24/drivers/block/cpqarray.c linux-2.4.25/drivers/block/cpqarray.c --- linux-2.4.24/drivers/block/cpqarray.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/drivers/block/cpqarray.c 2004-02-18 05:36:31.000000000 -0800 @@ -41,13 +41,13 @@ #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.25)" -#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,25) +#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.28)" +#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,28) /* Embedded module documentation macros - see modules.h */ /* Original author Chris Frantz - Compaq Computer Corporation */ MODULE_AUTHOR("Compaq Computer Corporation"); -MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.25"); +MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.28"); MODULE_LICENSE("GPL"); #define MAJOR_NR COMPAQ_SMART2_MAJOR @@ -180,6 +180,7 @@ static int deregister_disk(int ctlr, int logvol); static int register_new_disk(int cltr,int logvol); +static int cpqarray_register_ctlr(int ctlr, int type); #ifdef CONFIG_PROC_FS static void ida_procinit(int i); @@ -470,10 +471,111 @@ return 1; } +static int cpqarray_register_ctlr(int ctlr, int type) +{ + request_queue_t *q; + int j; + + /* + * register block devices + * Find disks and fill in structs + * Get an interrupt, set the Q depth and get into /proc + */ + + /* If this successful it should insure that we are the only */ + /* instance of the driver for this card */ + if (register_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname, &ida_fops)) { + printk(KERN_ERR "cpqarray: Unable to get major number %d\n", MAJOR_NR+ctlr); + goto err_out; + } + + hba[ctlr]->access.set_intr_mask(hba[ctlr], 0); + if (request_irq(hba[ctlr]->intr, do_ida_intr, + SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM, + hba[ctlr]->devname, hba[ctlr])) { + printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", + hba[ctlr]->intr, hba[ctlr]->devname); + unregister_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname); + goto err_out; + } + hba[ctlr]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( + hba[ctlr]->pci_dev, NR_CMDS * sizeof(cmdlist_t), + &(hba[ctlr]->cmd_pool_dhandle)); + hba[ctlr]->cmd_pool_bits = (__u32*)kmalloc( + ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL); + + if (hba[ctlr]->cmd_pool_bits == NULL || hba[ctlr]->cmd_pool == NULL) { + if (hba[ctlr]->cmd_pool_bits) + kfree(hba[ctlr]->cmd_pool_bits); + if (hba[ctlr]->cmd_pool) + pci_free_consistent(hba[ctlr]->pci_dev, + NR_CMDS * sizeof(cmdlist_t), + hba[ctlr]->cmd_pool, + hba[ctlr]->cmd_pool_dhandle); + + free_irq(hba[ctlr]->intr, hba[ctlr]); + unregister_blkdev(MAJOR_NR+ctlr, hba[ctlr]->devname); + printk( KERN_ERR "cpqarray: out of memory"); + goto err_out; + } + memset(hba[ctlr]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); + memset(hba[ctlr]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32)); + printk(KERN_INFO "cpqarray: Finding drives on %s", hba[ctlr]->devname); + getgeometry(ctlr); + start_fwbk(ctlr); + + hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY); + + ida_procinit(ctlr); + + q = BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr); + q->queuedata = hba[ctlr]; + blk_init_queue(q, do_ida_request); + if (type) + blk_queue_bounce_limit(q, hba[ctlr]->pci_dev->dma_mask); + blk_queue_headactive(q, 0); + blksize_size[MAJOR_NR+ctlr] = hba[ctlr]->blocksizes; + hardsect_size[MAJOR_NR+ctlr] = hba[ctlr]->hardsizes; + read_ahead[MAJOR_NR+ctlr] = READ_AHEAD; + + q->back_merge_fn = cpq_back_merge_fn; + q->front_merge_fn = cpq_front_merge_fn; + q->merge_requests_fn = cpq_merge_requests_fn; + + hba[ctlr]->gendisk.major = MAJOR_NR + ctlr; + hba[ctlr]->gendisk.major_name = "ida"; + hba[ctlr]->gendisk.minor_shift = NWD_SHIFT; + hba[ctlr]->gendisk.max_p = IDA_MAX_PART; + hba[ctlr]->gendisk.part = hba[ctlr]->hd; + hba[ctlr]->gendisk.sizes = hba[ctlr]->sizes; + hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun+1; + hba[ctlr]->gendisk.fops = &ida_fops; + + /* Get on the disk list */ + add_gendisk(&(hba[ctlr]->gendisk)); + + init_timer(&hba[ctlr]->timer); + hba[ctlr]->timer.expires = jiffies + IDA_TIMER; + hba[ctlr]->timer.data = (unsigned long)hba[ctlr]; + hba[ctlr]->timer.function = ida_timer; + add_timer(&hba[ctlr]->timer); + + ida_geninit(ctlr); + for(j=0; jgendisk), MKDEV(MAJOR_NR+ctlr,j<<4), + IDA_MAX_PART, &ida_fops, hba[ctlr]->drv[j].nr_blks); + return(ctlr); + +err_out: + release_io_mem(hba[ctlr]); + free_hba(ctlr); + return (-1); +} + + static int __init cpqarray_init_one( struct pci_dev *pdev, const struct pci_device_id *ent) { - request_queue_t *q; int i,j; @@ -500,102 +602,7 @@ return (-1); } - /* - * register block devices - * Find disks and fill in structs - * Get an interrupt, set the Q depth and get into /proc - */ - - /* If this successful it should insure that we are the only */ - /* instance of the driver */ - if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) { - printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n", - MAJOR_NR+i); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - - - hba[i]->access.set_intr_mask(hba[i], 0); - if (request_irq(hba[i]->intr, do_ida_intr, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, - hba[i]->devname, hba[i])) { - - printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", - hba[i]->intr, hba[i]->devname); - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( - hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), - &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = (__u32*)kmalloc( - ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL); - - if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL) { - if(hba[i]->cmd_pool_bits) - kfree(hba[i]->cmd_pool_bits); - if(hba[i]->cmd_pool) - pci_free_consistent(hba[i]->pci_dev, - NR_CMDS * sizeof(cmdlist_t), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - free_irq(hba[i]->intr, hba[i]); - unregister_blkdev(MAJOR_NR+i, hba[i]->devname); - printk( KERN_ERR "cpqarray: out of memory"); - release_io_mem(hba[i]); - free_hba(i); - return (-1); - } - memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32)); - printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); - getgeometry(i); - start_fwbk(i); - - hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY); - - ida_procinit(i); - - q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); - q->queuedata = hba[i]; - blk_init_queue(q, do_ida_request); - blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); - blk_queue_headactive(q, 0); - blksize_size[MAJOR_NR+i] = hba[i]->blocksizes; - hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes; - read_ahead[MAJOR_NR+i] = READ_AHEAD; - - q->back_merge_fn = cpq_back_merge_fn; - q->front_merge_fn = cpq_front_merge_fn; - q->merge_requests_fn = cpq_merge_requests_fn; - - hba[i]->gendisk.major = MAJOR_NR + i; - hba[i]->gendisk.major_name = "ida"; - hba[i]->gendisk.minor_shift = NWD_SHIFT; - hba[i]->gendisk.max_p = IDA_MAX_PART; - hba[i]->gendisk.part = hba[i]->hd; - hba[i]->gendisk.sizes = hba[i]->sizes; - hba[i]->gendisk.nr_real = hba[i]->highest_lun+1; - hba[i]->gendisk.fops = &ida_fops; - - /* Get on the disk list */ - add_gendisk(&(hba[i]->gendisk)); - - init_timer(&hba[i]->timer); - hba[i]->timer.expires = jiffies + IDA_TIMER; - hba[i]->timer.data = (unsigned long)hba[i]; - hba[i]->timer.function = ida_timer; - add_timer(&hba[i]->timer); - - ida_geninit(i); - for(j=0; jgendisk), MKDEV(MAJOR_NR+i,j<<4), - IDA_MAX_PART, &ida_fops, hba[i]->drv[j].nr_blks); - - return(i); + return (cpqarray_register_ctlr(i, 1)); } static struct pci_driver cpqarray_pci_driver = { name: "cpqarray", @@ -616,7 +623,7 @@ /* detect controllers */ printk(DRIVER_NAME "\n"); - pci_register_driver(&cpqarray_pci_driver); + pci_module_init(&cpqarray_pci_driver); cpqarray_eisa_detect(); for(i=0; i< MAX_CTLR; i++) { @@ -868,6 +875,11 @@ num_ctlr++; i++; + + if (cpqarray_register_ctlr(ctlr, 0) == -1) + printk(KERN_WARNING + "cpqarray%d: Can't register EISA controller\n", + ctlr); } return num_ctlr; @@ -1377,6 +1389,7 @@ case BLKFLSBUF: case BLKBSZSET: case BLKBSZGET: + case BLKSSZGET: case BLKROSET: case BLKROGET: case BLKRASET: diff -urN linux-2.4.24/drivers/block/genhd.c linux-2.4.25/drivers/block/genhd.c --- linux-2.4.24/drivers/block/genhd.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/block/genhd.c 2004-02-18 05:36:31.000000000 -0800 @@ -201,7 +201,7 @@ disk_round_stats(hd); seq_printf(s, "%4d %4d %10d %s " - "%d %d %d %d %d %d %d %d %d %d %d\n", + "%u %u %u %u %u %u %u %u %d %u %u\n", gp->major, n, gp->sizes[n], disk_name(gp, n, buf), hd->rd_ios, hd->rd_merges, diff -urN linux-2.4.24/drivers/block/ll_rw_blk.c linux-2.4.25/drivers/block/ll_rw_blk.c --- linux-2.4.24/drivers/block/ll_rw_blk.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/block/ll_rw_blk.c 2004-02-18 05:36:31.000000000 -0800 @@ -1377,9 +1377,7 @@ for (i = 0; i < nr; i++) { struct buffer_head *bh = bhs[i]; - /* Only one thread can actually submit the I/O. */ - if (test_and_set_bit(BH_Lock, &bh->b_state)) - continue; + lock_buffer(bh); /* We have the buffer lock */ atomic_inc(&bh->b_count); diff -urN linux-2.4.24/drivers/bluetooth/Config.in linux-2.4.25/drivers/bluetooth/Config.in --- linux-2.4.24/drivers/bluetooth/Config.in 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.25/drivers/bluetooth/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -7,7 +7,7 @@ dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then - bool ' SCO (voice) support' CONFIG_BLUEZ_USB_SCO + bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO fi dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ diff -urN linux-2.4.24/drivers/bluetooth/hci_usb.c linux-2.4.25/drivers/bluetooth/hci_usb.c --- linux-2.4.24/drivers/bluetooth/hci_usb.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/bluetooth/hci_usb.c 2004-02-18 05:36:31.000000000 -0800 @@ -62,7 +62,7 @@ #define BT_DMP( A... ) #endif -#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET +#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET #undef USB_ZERO_PACKET #define USB_ZERO_PACKET 0 #endif @@ -139,6 +139,7 @@ return _urb_dequeue(__completed_q(husb, type)); } +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static void __fill_isoc_desc(struct urb *urb, int len, int mtu) { int offset = 0, i; @@ -158,6 +159,7 @@ } urb->number_of_packets = i; } +#endif static int hci_usb_intr_rx_submit(struct hci_usb *husb) { @@ -235,7 +237,7 @@ return err; } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static int hci_usb_isoc_rx_submit(struct hci_usb *husb) { struct _urb *_urb; @@ -306,7 +308,7 @@ for (i = 0; i < HCI_MAX_BULK_RX; i++) hci_usb_bulk_rx_submit(husb); -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO if (husb->isoc_iface) for (i = 0; i < HCI_MAX_ISOC_RX; i++) hci_usb_isoc_rx_submit(husb); @@ -475,7 +477,7 @@ return __tx_submit(husb, _urb); } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb) { struct _urb *_urb = __get_completed(husb, skb->pkt_type); @@ -526,7 +528,7 @@ skb_queue_head(q, skb); } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO /* Process SCO queue */ q = __transmit_q(husb, HCI_SCODATA_PKT); if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX && @@ -585,7 +587,7 @@ hdev->stat.acl_tx++; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case HCI_SCODATA_PKT: hdev->stat.sco_tx++; break; @@ -635,7 +637,7 @@ } else return -EILSEQ; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case HCI_SCODATA_PKT: if (count >= HCI_SCO_HDR_SIZE) { hci_sco_hdr *h = data; @@ -700,7 +702,7 @@ goto resubmit; if (_urb->type == HCI_SCODATA_PKT) { -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO int i; for (i=0; i < urb->number_of_packets; i++) { BT_DBG("desc %d status %d offset %d len %d", i, @@ -835,7 +837,7 @@ bulk_out_ep[i] = ep; break; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO case USB_ENDPOINT_XFER_ISOC: if (ep->wMaxPacketSize < size || a > 2) break; @@ -861,7 +863,7 @@ goto done; } -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO if (!isoc_in_ep[1] || !isoc_out_ep[1]) { BT_DBG("Isoc endpoints not found"); isoc_iface = NULL; @@ -885,7 +887,7 @@ else husb->ctrl_req = HCI_CTRL_REQ; -#ifdef CONFIG_BLUEZ_USB_SCO +#ifdef CONFIG_BLUEZ_HCIUSB_SCO if (isoc_iface) { BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts); if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) { diff -urN linux-2.4.24/drivers/char/Config.in linux-2.4.25/drivers/char/Config.in --- linux-2.4.24/drivers/char/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -82,37 +82,56 @@ fi fi if [ "$CONFIG_MIPS" = "y" ]; then - bool ' TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 - dep_bool ' Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 - bool ' Enable Au1000 UART Support' CONFIG_AU1000_UART - if [ "$CONFIG_AU1000_UART" = "y" ]; then - bool ' Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE - fi - bool 'TXx927 SIO support' CONFIG_TXX927_SERIAL - if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then - bool 'TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE - fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for sb1250 onchip DUART' CONFIG_SIBYTE_SB1250_DUART - if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then - bool ' Console on SB1250 DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE - if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then - define_bool CONFIG_SERIAL_CONSOLE y - fi - int ' Output buffers size (in bytes)' CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE 1024 - bool ' Leave port 1 alone (for kgdb or audio)' CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - fi - fi - fi - if [ "$CONFIG_IA64" = "y" ]; then - bool ' SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL - if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then - bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE - fi - if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then - bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL - fi - fi + bool ' TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 + dep_bool ' Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 + bool ' TMPTX39XX/49XX serial port support' CONFIG_SERIAL_TXX9 + dep_bool ' Console on TMPTX39XX/49XX serial port' CONFIG_SERIAL_TXX9_CONSOLE $CONFIG_SERIAL_TXX9 + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + bool ' Enable Au1x00 UART Support' CONFIG_AU1X00_UART + if [ "$CONFIG_AU1X00_UART" = "y" ]; then + bool ' Enable Au1x00 serial console' CONFIG_AU1X00_SERIAL_CONSOLE + fi + dep_tristate ' Au1x00 USB TTY Device support' CONFIG_AU1X00_USB_TTY $CONFIG_SOC_AU1X00 + if [ "$CONFIG_AU1000_USB_TTY" != "y" ]; then + dep_tristate ' Au1x00 USB Raw Device support' CONFIG_AU1X00_USB_RAW $CONFIG_SOC_AU1X00 + fi + if [ "$CONFIG_AU1X00_USB_TTY" != "n" -o \ + "$CONFIG_AU1X00_USB_RAW" != "n" ]; then + define_bool CONFIG_AU1X00_USB_DEVICE y + fi + fi + bool ' TXx927 SIO support' CONFIG_TXX927_SERIAL + if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then + bool ' TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE + fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + bool ' Support for BCM1xxx onchip DUART' CONFIG_SIBYTE_SB1250_DUART + if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then + bool ' Console on BCM1xxx DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE + if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then + define_bool CONFIG_SERIAL_CONSOLE y + fi + fi + fi + fi + if [ "$CONFIG_DECSTATION" = "y" ]; then + bool ' DECstation serial support' CONFIG_SERIAL_DEC + dep_bool ' Support for console on a DECstation serial port' CONFIG_SERIAL_DEC_CONSOLE $CONFIG_SERIAL_DEC + dep_bool ' DZ11 serial support' CONFIG_DZ $CONFIG_SERIAL_DEC $CONFIG_MIPS32 + dep_bool ' Z85C30 serial support' CONFIG_ZS $CONFIG_SERIAL_DEC $CONFIG_TC + fi + if [ "$CONFIG_SGI_IP22" = "y" ]; then + bool ' SGI Zilog85C30 serial support' CONFIG_IP22_SERIAL + fi + if [ "$CONFIG_IA64" = "y" ]; then + bool ' SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL + if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then + bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE + fi + if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then + bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL + fi + fi fi if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232 @@ -125,14 +144,6 @@ fi bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE fi - if [ "$CONFIG_MIPS" = "y" ]; then - bool ' TMPTX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 - dep_bool ' Console on TMPTX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 - bool ' Enable Au1000 UART Support' CONFIG_AU1000_UART - if [ "$CONFIG_AU1000_UART" = "y" ]; then - bool ' Enable Au1000 serial console' CONFIG_AU1000_SERIAL_CONSOLE - fi - fi if [ "$CONFIG_PARISC" = "y" ]; then bool ' PDC software console support' CONFIG_PDC_CONSOLE fi @@ -154,6 +165,9 @@ fi bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 fi +if [ "$CONFIG_CPU_VR41XX" = "y" ]; then + bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU +fi bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 @@ -186,6 +200,9 @@ if [ "$CONFIG_ADB" = "y" -a "$CONFIG_ADB_KEYBOARD" = "y" ]; then dep_tristate ' Apple Desktop Bus mouse support (old driver)' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE fi +# if [ "$CONFIG_DECSTATION" = "y" ]; then +# dep_bool ' MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS +# fi fi tristate 'Mouse Support (not serial and bus mice)' CONFIG_MOUSE @@ -237,9 +254,6 @@ tristate ' Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT tristate ' ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT - if [ "$CONFIG_SGI_IP22" = "y" ]; then - dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 - fi tristate ' Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT @@ -256,7 +270,13 @@ fi fi tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 + fi dep_tristate ' AMD 766/768 TCO Timer/Watchdog' CONFIG_AMD7XX_TCO $CONFIG_EXPERIMENTAL + if [ "$CONFIG_8xx" = "y" ]; then + tristate ' MPC8xx Watchdog Timer' CONFIG_8xx_WDT + fi fi endmenu @@ -268,7 +288,8 @@ fi tristate 'NetWinder flash support' CONFIG_NWFLASH fi -dep_tristate 'NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 +tristate 'NatSemi SCx200 Support' CONFIG_SCx200 +dep_tristate ' NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then bool 'SGI SN2 fetchop support' CONFIG_FETCHOP @@ -293,6 +314,18 @@ if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then bool 'Tadpole ANA H8 Support (OBSOLETE)' CONFIG_H8 fi +if [ "$CONFIG_MIPS" = "y" -a "$CONFIG_NEW_TIME_C" = "y" ]; then + tristate 'Generic MIPS RTC Support' CONFIG_MIPS_RTC +fi +if [ "$CONFIG_SGI_IP22" = "y" ]; then + bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 +fi +if [ "$CONFIG_SGI_IP27" = "y" ]; then + bool 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC +fi +if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + tristate 'Dallas DS1742 RTC support' CONFIG_DS1742 +fi tristate 'Double Talk PC internal speech card support' CONFIG_DTLK tristate 'Siemens R3964 line discipline' CONFIG_R3964 @@ -307,6 +340,7 @@ if [ "$CONFIG_FTAPE" != "n" ]; then source drivers/char/ftape/Config.in fi + endmenu if [ "$CONFIG_GART_IOMMU" = "y" ]; then @@ -355,9 +389,9 @@ if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then source drivers/char/pcmcia/Config.in fi -if [ "$CONFIG_MIPS_AU1000" = "y" ]; then - tristate ' Alchemy Au1000 GPIO device support' CONFIG_AU1000_GPIO - tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1000_ADS7846 +if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + tristate ' Alchemy Au1x00 GPIO device support' CONFIG_AU1X00_GPIO + tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1X00_ADS7846 fi if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then tristate ' ITE GPIO' CONFIG_ITE_GPIO @@ -365,6 +399,7 @@ if [ "$CONFIG_X86" = "y" ]; then tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE + dep_tristate 'HP OB600 C/CT Pop-up mouse support' CONFIG_OBMOUSE $CONFIG_INPUT_MOUSEDEV fi endmenu diff -urN linux-2.4.24/drivers/char/Makefile linux-2.4.25/drivers/char/Makefile --- linux-2.4.24/drivers/char/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -24,7 +24,8 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \ misc.o pty.o random.o selection.o serial.o \ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ - au1000_gpio.o hp_psaux.o nvram.o scx200.o fetchop.o + au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \ + scx200.o fetchop.o mod-subdirs := joystick ftape drm drm-4.0 pcmcia @@ -46,6 +47,10 @@ ifneq ($(CONFIG_PC_KEYB),y) KEYBD = endif + ifeq ($(CONFIG_VR41XX_KIU),y) + KEYMAP = + KEYBD = vr41xx_keyb.o + endif endif ifeq ($(ARCH),s390x) @@ -140,12 +145,11 @@ ifeq ($(CONFIG_DECSTATION),y) KEYMAP = KEYBD = - SERIAL = decserial.o endif ifeq ($(CONFIG_BAGET_MIPS),y) KEYBD = - SERIAL = + SERIAL = vac-serial.o endif ifeq ($(CONFIG_NINO),y) @@ -171,7 +175,8 @@ obj-$(CONFIG_SERIAL_21285) += serial_21285.o obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o -obj-$(CONFIG_TS_AU1000_ADS7846) += au1000_ts.o +obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o +obj-$(CONFIG_SERIAL_DEC) += decserial.o ifndef CONFIG_SUN_KEYBOARD obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD) @@ -211,6 +216,9 @@ obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o +obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o +obj-$(CONFIG_IP22_SERIAL) += sgiserial.o +obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o subdir-$(CONFIG_RIO) += rio @@ -220,6 +228,7 @@ obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o obj-$(CONFIG_PRINTER) += lp.o obj-$(CONFIG_TIPAR) += tipar.o +obj-$(CONFIG_OBMOUSE) += obmouse.o ifeq ($(CONFIG_INPUT),y) obj-y += joystick/js.o @@ -241,12 +250,16 @@ obj-$(CONFIG_RTC) += rtc.o obj-$(CONFIG_GEN_RTC) += genrtc.o obj-$(CONFIG_EFI_RTC) += efirtc.o +obj-$(CONFIG_SGI_DS1286) += ds1286.o +obj-$(CONFIG_MIPS_RTC) += mips_rtc.o +obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o ifeq ($(CONFIG_PPC),) obj-$(CONFIG_NVRAM) += nvram.o endif obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_I8K) += i8k.o obj-$(CONFIG_DS1620) += ds1620.o +obj-$(CONFIG_DS1742) += ds1742.o obj-$(CONFIG_INTEL_RNG) += i810_rng.o obj-$(CONFIG_AMD_RNG) += amd768_rng.o obj-$(CONFIG_HW_RANDOM) += hw_random.o @@ -254,7 +267,9 @@ obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o obj-$(CONFIG_ITE_GPIO) += ite_gpio.o -obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o +obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o +obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o +obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o obj-$(CONFIG_COBALT_LCD) += lcd.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o @@ -274,7 +289,8 @@ obj-$(CONFIG_DZ) += dz.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o -obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o scx200.o +obj-$(CONFIG_SCx200) += scx200.o +obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o # Only one watchdog can succeed. We probe the hardware watchdog # drivers first, then the softdog driver. This means if your hardware @@ -305,6 +321,8 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o +obj-$(CONFIG_INDYDOG) += indydog.o +obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o subdir-$(CONFIG_MWAVE) += mwave ifeq ($(CONFIG_MWAVE),y) diff -urN linux-2.4.24/drivers/char/agp/agp.h linux-2.4.25/drivers/char/agp/agp.h --- linux-2.4.24/drivers/char/agp/agp.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/agp/agp.h 2004-02-18 05:36:31.000000000 -0800 @@ -319,6 +319,9 @@ #ifndef PCI_DEVICE_ID_ATI_RS250 #define PCI_DEVICE_ID_ATI_RS250 0xcab3 #endif +#ifndef PCI_DEVICE_ID_ATI_RS200_B +#define PCI_DEVICE_ID_ATI_RS200_B 0xcbb3 +#endif #ifndef PCI_DEVICE_ID_ATI_RS300_100 #define PCI_DEVICE_ID_ATI_RS300_100 0x5830 #endif diff -urN linux-2.4.24/drivers/char/agp/agpgart_be.c linux-2.4.25/drivers/char/agp/agpgart_be.c --- linux-2.4.24/drivers/char/agp/agpgart_be.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/agp/agpgart_be.c 2004-02-18 05:36:31.000000000 -0800 @@ -5644,7 +5644,7 @@ #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr)) #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) -#undef GET_GATT(addr) +#undef GET_GATT #define GET_GATT(addr) (ati_generic_private.gatt_pages[\ GET_PAGE_DIR_IDX(addr)]->remapped) @@ -5738,6 +5738,7 @@ if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); temp = (((temp & ~(0x0000000e)) | current_size->size_value) @@ -5791,6 +5792,7 @@ if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); } else { @@ -5823,6 +5825,7 @@ if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { pci_write_config_dword(agp_bridge.dev, ATI_RS100_IG_AGPMODE, 0x20000); } else { @@ -5860,6 +5863,7 @@ /* Write back the previous size and disable gart translation */ if ((agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS100) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200) || + (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS200_B) || (agp_bridge.dev->device == PCI_DEVICE_ID_ATI_RS250)) { pci_read_config_dword(agp_bridge.dev, ATI_RS100_APSIZE, &temp); temp = ((temp & ~(0x0000000f)) | previous_size->size_value); @@ -6428,6 +6432,12 @@ "ATI", "IGP330/340/345/350/M", ati_generic_setup }, + { PCI_DEVICE_ID_ATI_RS200_B, + PCI_VENDOR_ID_ATI, + ATI_RS200, + "ATI", + "IGP330/340/345/350/M", + ati_generic_setup }, { PCI_DEVICE_ID_ATI_RS250, PCI_VENDOR_ID_ATI, ATI_RS250, diff -urN linux-2.4.24/drivers/char/alim7101_wdt.c linux-2.4.25/drivers/char/alim7101_wdt.c --- linux-2.4.24/drivers/char/alim7101_wdt.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/char/alim7101_wdt.c 2004-02-18 05:36:31.000000000 -0800 @@ -209,7 +209,7 @@ static int fop_close(struct inode * inode, struct file * file) { - if(wdt_expect_close) + if ((wdt_expect_close) || (! nowayout)) wdt_turnoff(); else { printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n"); diff -urN linux-2.4.24/drivers/char/amd76x_pm.c linux-2.4.25/drivers/char/amd76x_pm.c --- linux-2.4.24/drivers/char/amd76x_pm.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/amd76x_pm.c 2004-02-18 05:36:31.000000000 -0800 @@ -474,7 +474,7 @@ } #endif - +#ifdef AMD76X_POS /* * Activate sleep state via its ACPI register (PM1_CNT). */ @@ -489,8 +489,6 @@ outw(regshort, amd76x_pm_cfg.slp_reg); } - -#ifdef AMD76X_POS /* * Wrapper function to activate POS sleep state. */ diff -urN linux-2.4.24/drivers/char/drm/drmP.h linux-2.4.25/drivers/char/drm/drmP.h --- linux-2.4.24/drivers/char/drm/drmP.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drmP.h 2004-02-18 05:36:31.000000000 -0800 @@ -328,16 +328,16 @@ if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } /* Mapping helper macros */ -#define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) +#define DRM_IOREMAP(map, dev) \ + (map)->handle = DRM(ioremap)((map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAP_NOCACHE(map) \ - (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) +#define DRM_IOREMAP_NOCACHE(map, dev) \ + (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAPFREE(map) \ +#define DRM_IOREMAPFREE(map, dev) \ do { \ if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ + DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \ } while (0) #define DRM_FIND_MAP(_map, _o) \ @@ -789,9 +789,9 @@ extern unsigned long DRM(alloc_pages)(int order, int area); extern void DRM(free_pages)(unsigned long address, int order, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); diff -urN linux-2.4.24/drivers/char/drm/drm_agpsupport.h linux-2.4.25/drivers/char/drm/drm_agpsupport.h --- linux-2.4.24/drivers/char/drm/drm_agpsupport.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_agpsupport.h 2004-02-18 05:36:31.000000000 -0800 @@ -79,7 +79,7 @@ return -EBUSY; if(!drm_agp->acquire) return -EINVAL; - if (retcode = drm_agp->acquire()) + if ((retcode = drm_agp->acquire())) return retcode; dev->agp->acquired = 1; return 0; diff -urN linux-2.4.24/drivers/char/drm/drm_bufs.h linux-2.4.25/drivers/char/drm/drm_bufs.h --- linux-2.4.24/drivers/char/drm/drm_bufs.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_bufs.h 2004-02-18 05:36:31.000000000 -0800 @@ -123,7 +123,7 @@ MTRR_TYPE_WRCOMB, 1 ); } #endif - map->handle = DRM(ioremap)( map->offset, map->size ); + map->handle = DRM(ioremap)( map->offset, map->size, dev ); break; case _DRM_SHM: @@ -245,7 +245,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.24/drivers/char/drm/drm_drv.h linux-2.4.25/drivers/char/drm/drm_drv.h --- linux-2.4.24/drivers/char/drm/drm_drv.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_drv.h 2004-02-18 05:36:31.000000000 -0800 @@ -443,7 +443,7 @@ DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map->handle, map->size, dev ); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.24/drivers/char/drm/drm_memory.h linux-2.4.25/drivers/char/drm/drm_memory.h --- linux-2.4.24/drivers/char/drm/drm_memory.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_memory.h 2004-02-18 05:36:31.000000000 -0800 @@ -290,7 +290,7 @@ } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -313,7 +313,7 @@ return pt; } -void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) +void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -336,7 +336,7 @@ return pt; } -void DRM(ioremapfree)(void *pt, unsigned long size) +void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; diff -urN linux-2.4.24/drivers/char/drm/drm_os_linux.h linux-2.4.25/drivers/char/drm/drm_os_linux.h --- linux-2.4.24/drivers/char/drm/drm_os_linux.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_os_linux.h 2004-02-18 05:36:31.000000000 -0800 @@ -13,12 +13,10 @@ return -EFAULT -#warning the author of this code needs to read up on list_entry #define DRM_GETSAREA() \ do { \ - struct list_head *list; \ - list_for_each( list, &dev->maplist->head ) { \ - drm_map_list_t *entry = (drm_map_list_t *)list; \ + drm_map_list_t *entry; \ + list_for_each_entry( entry, &dev->maplist->head, head ) { \ if ( entry->map && \ entry->map->type == _DRM_SHM && \ (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ diff -urN linux-2.4.24/drivers/char/drm/drm_vm.h linux-2.4.25/drivers/char/drm/drm_vm.h --- linux-2.4.24/drivers/char/drm/drm_vm.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/drm_vm.h 2004-02-18 05:36:31.000000000 -0800 @@ -206,7 +206,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.24/drivers/char/drm/ffb_drv.c linux-2.4.25/drivers/char/drm/ffb_drv.c --- linux-2.4.24/drivers/char/drm/ffb_drv.c 2001-10-21 10:40:36.000000000 -0700 +++ linux-2.4.25/drivers/char/drm/ffb_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -372,25 +372,6 @@ return ret; } -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init ffb_options(char *str) -{ - DRM(parse_options)(str); - return 1; -} - -__setup(DRIVER_NAME "=", ffb_options); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff -urN linux-2.4.24/drivers/char/drm/gamma_dma.c linux-2.4.25/drivers/char/drm/gamma_dma.c --- linux-2.4.24/drivers/char/drm/gamma_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/gamma_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -638,7 +638,7 @@ } else { DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->buffers, dev ); buf = dma->buflist[GLINT_DRI_BUF_COUNT]; pgt = buf->address; @@ -668,7 +668,7 @@ if ( dev->dev_private ) { drm_gamma_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), DRM_MEM_DRIVER ); diff -urN linux-2.4.24/drivers/char/drm/i810_dma.c linux-2.4.25/drivers/char/drm/i810_dma.c --- linux-2.4.24/drivers/char/drm/i810_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/i810_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -276,7 +276,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -292,7 +292,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -362,7 +362,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -415,7 +415,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -urN linux-2.4.24/drivers/char/drm/i830_dma.c linux-2.4.25/drivers/char/drm/i830_dma.c --- linux-2.4.24/drivers/char/drm/i830_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/i830_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -252,7 +252,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -277,7 +277,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -353,7 +353,7 @@ *buf_priv->in_use = I830_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -407,7 +407,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -urN linux-2.4.24/drivers/char/drm/mga_dma.c linux-2.4.25/drivers/char/drm/mga_dma.c --- linux-2.4.24/drivers/char/drm/mga_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/mga_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -556,9 +556,9 @@ (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DRM_IOREMAP( dev_priv->warp ); - DRM_IOREMAP( dev_priv->primary ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->warp, dev ); + DRM_IOREMAP( dev_priv->primary, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->warp->handle || !dev_priv->primary->handle || @@ -644,9 +644,9 @@ if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->warp, dev ); + DRM_IOREMAPFREE( dev_priv->primary, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); diff -urN linux-2.4.24/drivers/char/drm/r128_cce.c linux-2.4.25/drivers/char/drm/r128_cce.c --- linux-2.4.24/drivers/char/drm/r128_cce.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/r128_cce.c 2004-02-18 05:36:31.000000000 -0800 @@ -542,9 +542,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cce_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cce_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cce_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -618,9 +618,9 @@ #if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { #endif - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cce_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); #if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, diff -urN linux-2.4.24/drivers/char/drm/r128_state.c linux-2.4.25/drivers/char/drm/r128_state.c --- linux-2.4.24/drivers/char/drm/r128_state.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/r128_state.c 2004-02-18 05:36:31.000000000 -0800 @@ -23,8 +23,20 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * RED HAT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * THIS SOFTWARE IS NOT INTENDED FOR USE IN SAFETY CRITICAL SYSTEMS + * * Authors: * Gareth Hughes + * + * Memory allocation size checks added 14/01/2003, Alan Cox */ #include "r128.h" @@ -901,6 +913,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if( count > 4096 ) + return -EMSGSIZE; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } @@ -994,6 +1009,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if( count > 4096 ) + return -EMSGSIZE; x = kmalloc( count * sizeof(*x), GFP_KERNEL ); if ( x == NULL ) { @@ -1109,6 +1127,9 @@ DRM_DEBUG( "%s\n", __FUNCTION__ ); count = depth->n; + + if ( count > 4096 ) + return -EMSGSIZE; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } diff -urN linux-2.4.24/drivers/char/drm/radeon_cp.c linux-2.4.25/drivers/char/drm/radeon_cp.c --- linux-2.4.24/drivers/char/drm/radeon_cp.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/radeon_cp.c 2004-02-18 05:36:31.000000000 -0800 @@ -1145,9 +1145,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cp_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cp_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -1266,9 +1266,9 @@ drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); } else { #if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, diff -urN linux-2.4.24/drivers/char/drm/radeon_drv.h linux-2.4.25/drivers/char/drm/radeon_drv.h --- linux-2.4.24/drivers/char/drm/radeon_drv.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/drm/radeon_drv.h 2004-02-18 05:36:31.000000000 -0800 @@ -839,14 +839,6 @@ * Ring control */ -#if defined(__powerpc__) -#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) -#else -#define radeon_flush_write_combine() wmb() -#warning PCI posting bug -#endif - - #define RADEON_VERBOSE 0 #define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; diff -urN linux-2.4.24/drivers/char/drm-4.0/bufs.c linux-2.4.25/drivers/char/drm-4.0/bufs.c --- linux-2.4.24/drivers/char/drm-4.0/bufs.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/bufs.c 2004-02-18 05:36:31.000000000 -0800 @@ -87,7 +87,7 @@ MTRR_TYPE_WRCOMB, 1); } #endif - map->handle = drm_ioremap(map->offset, map->size); + map->handle = drm_ioremap(map->offset, map->size, dev); break; diff -urN linux-2.4.24/drivers/char/drm-4.0/drmP.h linux-2.4.25/drivers/char/drm-4.0/drmP.h --- linux-2.4.24/drivers/char/drm-4.0/drmP.h 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/drmP.h 2004-02-18 05:36:31.000000000 -0800 @@ -679,8 +679,8 @@ extern unsigned long drm_alloc_pages(int order, int area); extern void drm_free_pages(unsigned long address, int order, int area); -extern void *drm_ioremap(unsigned long offset, unsigned long size); -extern void drm_ioremapfree(void *pt, unsigned long size); +extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) extern agp_memory *drm_alloc_agp(int pages, u32 type); diff -urN linux-2.4.24/drivers/char/drm-4.0/ffb_drv.c linux-2.4.25/drivers/char/drm-4.0/ffb_drv.c --- linux-2.4.24/drivers/char/drm-4.0/ffb_drv.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/ffb_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -158,7 +158,7 @@ switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: diff -urN linux-2.4.24/drivers/char/drm-4.0/gamma_drv.c linux-2.4.25/drivers/char/drm-4.0/gamma_drv.c --- linux-2.4.24/drivers/char/drm-4.0/gamma_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/gamma_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -258,7 +258,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/drm-4.0/i810_dma.c linux-2.4.25/drivers/char/drm-4.0/i810_dma.c --- linux-2.4.24/drivers/char/drm-4.0/i810_dma.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.25/drivers/char/drm-4.0/i810_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -305,7 +305,7 @@ if(dev_priv->ring.virtual_start) { drm_ioremapfree((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { i810_free_page(dev, dev_priv->hw_status_page); @@ -319,7 +319,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_ioremapfree(buf_priv->kernel_virtual, buf->total); + drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -393,7 +393,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -430,7 +430,7 @@ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; diff -urN linux-2.4.24/drivers/char/drm-4.0/i810_drv.c linux-2.4.25/drivers/char/drm-4.0/i810_drv.c --- linux-2.4.24/drivers/char/drm-4.0/i810_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/i810_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/drm-4.0/memory.c linux-2.4.25/drivers/char/drm-4.0/memory.c --- linux-2.4.24/drivers/char/drm-4.0/memory.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/memory.c 2004-02-18 05:36:31.000000000 -0800 @@ -296,7 +296,7 @@ } } -void *drm_ioremap(unsigned long offset, unsigned long size) +void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -319,7 +319,7 @@ return pt; } -void drm_ioremapfree(void *pt, unsigned long size) +void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; diff -urN linux-2.4.24/drivers/char/drm-4.0/mga_dma.c linux-2.4.25/drivers/char/drm-4.0/mga_dma.c --- linux-2.4.24/drivers/char/drm-4.0/mga_dma.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/mga_dma.c 2004-02-18 05:36:31.000000000 -0800 @@ -308,7 +308,7 @@ temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, - temp); + temp, dev); if(dev_priv->ioremap == NULL) { DRM_ERROR("Ioremap failed\n"); return -ENOMEM; @@ -635,7 +635,7 @@ dev_priv->primary_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; - drm_ioremapfree((void *) dev_priv->ioremap, temp); + drm_ioremapfree((void *) dev_priv->ioremap, temp, dev); } if(dev_priv->status_page != NULL) { iounmap(dev_priv->status_page); diff -urN linux-2.4.24/drivers/char/drm-4.0/mga_drv.c linux-2.4.25/drivers/char/drm-4.0/mga_drv.c --- linux-2.4.24/drivers/char/drm-4.0/mga_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/mga_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/drm-4.0/r128_cce.c linux-2.4.25/drivers/char/drm-4.0/r128_cce.c --- linux-2.4.24/drivers/char/drm-4.0/r128_cce.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/r128_cce.c 2004-02-18 05:36:31.000000000 -0800 @@ -86,12 +86,12 @@ }; -#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_REMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_REMAPFREE(_m) \ +#define DO_REMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d)); \ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -481,12 +481,12 @@ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_REMAP( dev_priv->cce_ring ); - DO_REMAP( dev_priv->ring_rptr ); - DO_REMAP( dev_priv->buffers ); + DO_REMAP( dev_priv->cce_ring, dev ); + DO_REMAP( dev_priv->ring_rptr, dev ); + DO_REMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAP( dev_priv->agp_textures ); + DO_REMAP( dev_priv->agp_textures, dev ); } #endif @@ -521,12 +521,12 @@ if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; - DO_REMAPFREE( dev_priv->cce_ring ); - DO_REMAPFREE( dev_priv->ring_rptr ); - DO_REMAPFREE( dev_priv->buffers ); + DO_REMAPFREE( dev_priv->cce_ring, dev ); + DO_REMAPFREE( dev_priv->ring_rptr, dev ); + DO_REMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAPFREE( dev_priv->agp_textures ); + DO_REMAPFREE( dev_priv->agp_textures, dev ); } #endif diff -urN linux-2.4.24/drivers/char/drm-4.0/r128_drv.c linux-2.4.25/drivers/char/drm-4.0/r128_drv.c --- linux-2.4.24/drivers/char/drm-4.0/r128_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/r128_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -296,7 +296,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/drm-4.0/radeon_cp.c linux-2.4.25/drivers/char/drm-4.0/radeon_cp.c --- linux-2.4.24/drivers/char/drm-4.0/radeon_cp.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/radeon_cp.c 2004-02-18 05:36:31.000000000 -0800 @@ -300,12 +300,12 @@ }; -#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_IOREMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_IOREMAPFREE(_m) \ +#define DO_IOREMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d));\ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -757,12 +757,12 @@ (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_IOREMAP( dev_priv->cp_ring ); - DO_IOREMAP( dev_priv->ring_rptr ); - DO_IOREMAP( dev_priv->buffers ); + DO_IOREMAP( dev_priv->cp_ring, dev ); + DO_IOREMAP( dev_priv->ring_rptr, dev ); + DO_IOREMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAP( dev_priv->agp_textures ); + DO_IOREMAP( dev_priv->agp_textures, dev ); } #endif @@ -828,12 +828,12 @@ if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; - DO_IOREMAPFREE( dev_priv->cp_ring ); - DO_IOREMAPFREE( dev_priv->ring_rptr ); - DO_IOREMAPFREE( dev_priv->buffers ); + DO_IOREMAPFREE( dev_priv->cp_ring, dev ); + DO_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DO_IOREMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAPFREE( dev_priv->agp_textures ); + DO_IOREMAPFREE( dev_priv->agp_textures, dev ); } #endif diff -urN linux-2.4.24/drivers/char/drm-4.0/radeon_drv.c linux-2.4.25/drivers/char/drm-4.0/radeon_drv.c --- linux-2.4.24/drivers/char/drm-4.0/radeon_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/radeon_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -294,7 +294,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/drm-4.0/tdfx_drv.c linux-2.4.25/drivers/char/drm-4.0/tdfx_drv.c --- linux-2.4.24/drivers/char/drm-4.0/tdfx_drv.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/char/drm-4.0/tdfx_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -264,7 +264,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.24/drivers/char/ds1286.c linux-2.4.25/drivers/char/ds1286.c --- linux-2.4.24/drivers/char/ds1286.c 2004-01-05 05:53:56.000000000 -0800 +++ linux-2.4.25/drivers/char/ds1286.c 2004-02-18 05:36:31.000000000 -0800 @@ -422,7 +422,7 @@ rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; + rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x3f; rtc_tm->tm_mday = CMOS_READ(RTC_DATE); rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; rtc_tm->tm_year = CMOS_READ(RTC_YEAR); diff -urN linux-2.4.24/drivers/char/ds1742.c linux-2.4.25/drivers/char/ds1742.c --- linux-2.4.24/drivers/char/ds1742.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/char/ds1742.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,348 @@ +/* + * linux/drivers/char/ds1742.c + * + * Dallas DS1742 Real Time Clock driver + * + * Copyright (C) 2003 TimeSys Corp. + * S. James Hill (James.Hill@timesys.com) + * (sjhill@realitydiluted.com) + * + * Copyright (C) 2001 MontaVista Software Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DS1742_VERSION "2.0" + +/* + * Registers + */ +#define RTC_CONTROL (rtc_base + 0x7f8) +#define RTC_CENTURY (rtc_base + 0x7f8) +#define RTC_SECONDS (rtc_base + 0x7f9) +#define RTC_MINUTES (rtc_base + 0x7fa) +#define RTC_HOURS (rtc_base + 0x7fb) +#define RTC_DAY (rtc_base + 0x7fc) +#define RTC_DATE (rtc_base + 0x7fd) +#define RTC_MONTH (rtc_base + 0x7fe) +#define RTC_YEAR (rtc_base + 0x7ff) + +#define RTC_CENTURY_MASK 0x3f +#define RTC_SECONDS_MASK 0x7f +#define RTC_DAY_MASK 0x07 + +/* + * Bits in the Control/Century register + */ +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 + +/* + * Bits in the Seconds register + */ +#define RTC_STOP 0x80 + +/* + * Bits in the Day register + */ +#define RTC_BATT_FLAG 0x80 +#define RTC_FREQ_TEST 0x40 + +/* + * Conversion between binary and BCD + */ +#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) + +/* + * CMOS Year Epoch + */ +#define EPOCH 2000 + +/* + * The entry /dev/rtc is being used + */ +#define RTC_IS_OPEN 0x1 + +static unsigned long rtc_base = 0; +static unsigned long rtc_status = 0; +static spinlock_t rtc_lock; + +extern void to_tm(unsigned long tim, struct rtc_time * tm); + +static unsigned long rtc_ds1742_get_time(void) +{ + unsigned int year, month, day, hour, minute, second; + unsigned int century; + + CMOS_WRITE(RTC_READ, RTC_CONTROL); + second = BCD_TO_BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + minute = BCD_TO_BIN(CMOS_READ(RTC_MINUTES)); + hour = BCD_TO_BIN(CMOS_READ(RTC_HOURS)); + day = BCD_TO_BIN(CMOS_READ(RTC_DATE)); + month = BCD_TO_BIN(CMOS_READ(RTC_MONTH)); + year = BCD_TO_BIN(CMOS_READ(RTC_YEAR)); + century = BCD_TO_BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); + CMOS_WRITE(0, RTC_CONTROL); + + year += century * 100; + + return mktime(year, month, day, hour, minute, second); +} + +static int rtc_ds1742_set_time(unsigned long t) +{ + struct rtc_time tm; + u8 year, month, day, hour, minute, second; + u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; + int cmos_century; + + CMOS_WRITE(RTC_READ, RTC_CONTROL); + cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + cmos_minute = (u8)CMOS_READ(RTC_MINUTES); + cmos_hour = (u8)CMOS_READ(RTC_HOURS); + cmos_day = (u8)CMOS_READ(RTC_DATE); + cmos_month = (u8)CMOS_READ(RTC_MONTH); + cmos_year = (u8)CMOS_READ(RTC_YEAR); + cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; + + CMOS_WRITE(RTC_WRITE, RTC_CONTROL); + + /* convert */ + to_tm(t, &tm); + + /* check each field one by one */ + year = BIN_TO_BCD(tm.tm_year - EPOCH); + if (year != cmos_year) { + CMOS_WRITE(year,RTC_YEAR); + } + + month = BIN_TO_BCD(tm.tm_mon + 1); + if (month != (cmos_month & 0x1f)) { + CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); + } + + day = BIN_TO_BCD(tm.tm_mday); + if (day != cmos_day) + CMOS_WRITE(day, RTC_DATE); + + if (cmos_hour & 0x40) { + /* 12 hour format */ + hour = 0x40; + if (tm.tm_hour > 12) { + hour |= 0x20 | (BIN_TO_BCD(hour-12) & 0x1f); + } else { + hour |= BIN_TO_BCD(tm.tm_hour); + } + } else { + /* 24 hour format */ + hour = BIN_TO_BCD(tm.tm_hour) & 0x3f; + } + if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); + + minute = BIN_TO_BCD(tm.tm_min); + if (minute != cmos_minute) { + CMOS_WRITE(minute, RTC_MINUTES); + } + + second = BIN_TO_BCD(tm.tm_sec); + if (second != cmos_second) { + CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); + } + + /* RTC_CENTURY and RTC_CONTROL share same address... */ + CMOS_WRITE(cmos_century, RTC_CONTROL); + + return 0; +} + +void __init rtc_ds1742_init(unsigned long base) +{ + u8 cmos_second; + + /* remember the base */ + rtc_base = base; + db_assert((rtc_base & 0xe0000000) == KSEG1); + + /* set the function pointers */ + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + /* clear oscillator stop bit */ + CMOS_WRITE(RTC_READ, RTC_CONTROL); + cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + CMOS_WRITE(RTC_WRITE, RTC_CONTROL); + CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ + CMOS_WRITE(0, RTC_CONTROL); +} + +static int get_ds1742_status(char *buf) +{ + char *p; + struct rtc_time tm; + unsigned long curr_time; + + curr_time = rtc_ds1742_get_time(); + to_tm(curr_time, &tm); + + p = buf; + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, 0L); + + return p - buf; +} + +static int ds1742_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int len = get_ds1742_status(page); + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + return len; +} + +void rtc_ds1742_wait(void) +{ + while (CMOS_READ(RTC_SECONDS) & 1); + while (!(CMOS_READ(RTC_SECONDS) & 1)); +} + +static int ds1742_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct rtc_time rtc_tm; + ulong curr_time; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + curr_time = rtc_ds1742_get_time(); + to_tm(curr_time, &rtc_tm); + rtc_tm.tm_year -= 1900; + return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? + -EFAULT : 0; + case RTC_SET_TIME: /* Set the RTC */ + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, + (struct rtc_time *) arg, + sizeof(struct rtc_time))) + return -EFAULT; + + curr_time = mktime(rtc_tm.tm_year + 1900, + rtc_tm.tm_mon + 1, /* tm_mon starts from 0 */ + rtc_tm.tm_mday, + rtc_tm.tm_hour, + rtc_tm.tm_min, + rtc_tm.tm_sec); + return rtc_ds1742_set_time(curr_time); + default: + return -EINVAL; + } +} + +static int ds1742_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + + spin_unlock_irq(&rtc_lock); + return 0; +} + +static int ds1742_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + return 0; +} + +static struct file_operations ds1742_fops = { + owner:THIS_MODULE, + llseek:no_llseek, + ioctl:ds1742_ioctl, + open:ds1742_open, + release:ds1742_release, +}; + +static struct miscdevice ds1742_dev = { + RTC_MINOR, + "rtc", + &ds1742_fops +}; + +static int __init ds1742_init(void) +{ + printk(KERN_INFO "DS1742 Real Time Clock Driver v%s\n", DS1742_VERSION); + misc_register(&ds1742_dev); + create_proc_read_entry("driver/rtc", 0, 0, ds1742_read_proc, NULL); + return 0; +} + +static void __exit ds1742_exit(void) +{ + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&ds1742_dev); +} + +module_init(ds1742_init); +module_exit(ds1742_exit); +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Steven J. Hill"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/char/dz.c linux-2.4.25/drivers/char/dz.c --- linux-2.4.24/drivers/char/dz.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/dz.c 2004-02-18 05:36:31.000000000 -0800 @@ -21,7 +21,7 @@ * [07-SEP-99] Bugfixes */ -#define DEBUG_DZ 1 +#undef DEBUG_DZ #include #include @@ -254,13 +254,19 @@ if (tmp & DZ_PERR) { *tty->flip.flag_buf_ptr = TTY_PARITY; +#ifdef DEBUG_DZ debug_console("PERR\n", 5); +#endif } else if (tmp & DZ_FERR) { *tty->flip.flag_buf_ptr = TTY_FRAME; +#ifdef DEBUG_DZ debug_console("FERR\n", 5); +#endif } if (tmp & DZ_OERR) { +#ifdef DEBUG_DZ debug_console("OERR\n", 5); +#endif if (tty->flip.count < TTY_FLIPBUF_SIZE) { tty->flip.count++; tty->flip.flag_buf_ptr++; @@ -1299,7 +1305,7 @@ int __init dz_init(void) { - int i, tmp; + int i; long flags; struct dz_serial *info; @@ -1413,7 +1419,7 @@ /* reset the chip */ #ifndef CONFIG_SERIAL_DEC_CONSOLE dz_out(info, DZ_CSR, DZ_CLR); - while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR); + while (dz_in(info, DZ_CSR) & DZ_CLR); iob(); /* enable scanning */ diff -urN linux-2.4.24/drivers/char/genrtc.c linux-2.4.25/drivers/char/genrtc.c --- linux-2.4.24/drivers/char/genrtc.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.25/drivers/char/genrtc.c 2004-02-18 05:36:31.000000000 -0800 @@ -378,69 +378,13 @@ return 0; } -static int gen_rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - - -/* - * The various file operations we support. - */ - -static struct file_operations gen_rtc_fops = { - .owner = THIS_MODULE, -#ifdef CONFIG_GEN_RTC_X - .read = gen_rtc_read, - .poll = gen_rtc_poll, -#endif - .ioctl = gen_rtc_ioctl, - .open = gen_rtc_open, - .release = gen_rtc_release, -}; - -static struct miscdevice rtc_gen_dev = -{ - .minor = RTC_MINOR, - .name = "rtc", - .fops = &gen_rtc_fops, -}; - -static int __init rtc_generic_init(void) -{ - int retval; - - printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); - - retval = misc_register(&rtc_gen_dev); - if(retval < 0) - return retval; #ifdef CONFIG_PROC_FS - if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ - misc_deregister(&rtc_gen_dev); - return -ENOMEM; - } -#endif - - return 0; -} - -static void __exit rtc_generic_exit(void) -{ - remove_proc_entry ("driver/rtc", NULL); - misc_deregister(&rtc_gen_dev); -} - -module_init(rtc_generic_init); -module_exit(rtc_generic_exit); -EXPORT_NO_SYMBOLS; - /* * Info exported via "/proc/rtc". */ -#ifdef CONFIG_PROC_FS - static int gen_rtc_proc_output(char *buf) { char *p; @@ -528,6 +472,59 @@ #endif /* CONFIG_PROC_FS */ +/* + * The various file operations we support. + */ + +static struct file_operations gen_rtc_fops = { + .owner = THIS_MODULE, +#ifdef CONFIG_GEN_RTC_X + .read = gen_rtc_read, + .poll = gen_rtc_poll, +#endif + .ioctl = gen_rtc_ioctl, + .open = gen_rtc_open, + .release = gen_rtc_release, +}; + +static struct miscdevice rtc_gen_dev = +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &gen_rtc_fops, +}; + +static int __init rtc_generic_init(void) +{ + int retval; + + printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); + + retval = misc_register(&rtc_gen_dev); + if(retval < 0) + return retval; + +#ifdef CONFIG_PROC_FS + if((create_proc_read_entry ("driver/rtc", 0, 0, gen_rtc_read_proc, NULL)) == NULL){ + misc_deregister(&rtc_gen_dev); + return -ENOMEM; + } +#endif + + return 0; +} + +static void __exit rtc_generic_exit(void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_gen_dev); +} + + +module_init(rtc_generic_init); +module_exit(rtc_generic_exit); +EXPORT_NO_SYMBOLS; + MODULE_AUTHOR("Richard Zidlicky"); MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/char/hvc_console.c linux-2.4.25/drivers/char/hvc_console.c --- linux-2.4.24/drivers/char/hvc_console.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/char/hvc_console.c 2004-02-18 05:36:31.000000000 -0800 @@ -252,7 +252,11 @@ hvc_driver.magic = TTY_DRIVER_MAGIC; hvc_driver.driver_name = "hvc"; +#ifdef CONFIG_DEVFS_FS hvc_driver.name = "hvc/%d"; +#else + hvc_driver.name = "hvc"; +#endif hvc_driver.major = HVC_MAJOR; hvc_driver.minor_start = HVC_MINOR; hvc_driver.num = hvc_count(&hvc_offset); diff -urN linux-2.4.24/drivers/char/ip27-rtc.c linux-2.4.25/drivers/char/ip27-rtc.c --- linux-2.4.24/drivers/char/ip27-rtc.c 2004-01-05 05:53:56.000000000 -0800 +++ linux-2.4.25/drivers/char/ip27-rtc.c 2004-02-18 05:36:31.000000000 -0800 @@ -226,8 +226,8 @@ return -ENOENT; } - rtc_freq = 1024; + return 0; } diff -urN linux-2.4.24/drivers/char/misc.c linux-2.4.25/drivers/char/misc.c --- linux-2.4.24/drivers/char/misc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/misc.c 2004-02-18 05:36:31.000000000 -0800 @@ -66,7 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; extern int psaux_init(void); -extern void gfx_register(void); extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int ds1286_init(void); @@ -264,12 +263,6 @@ #ifdef CONFIG_PMAC_PBOOK pmu_device_init(); #endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); -#endif -#ifdef CONFIG_SGI_NEWPORT_GFX - gfx_register (); -#endif #ifdef CONFIG_TOSHIBA tosh_init(); #endif diff -urN linux-2.4.24/drivers/char/mpc8xx_wdt.c linux-2.4.25/drivers/char/mpc8xx_wdt.c --- linux-2.4.24/drivers/char/mpc8xx_wdt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/char/mpc8xx_wdt.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,191 @@ +/* + * mpc8xx_wdt.c - MPC8xx watchdog userspace interface + * + * Copyright (C) 2002 Florian Schirmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int m8xx_wdt_get_timeout(void); +extern void m8xx_wdt_reset(void); + +static struct semaphore wdt_sem; +static int wdt_status; + +static struct watchdog_info ident = { + .identity = "MPC8xx watchdog", + .options = WDIOF_KEEPALIVEPING, +}; + +static void +mpc8xx_wdt_handler_disable(void) +{ + volatile immap_t *imap = (volatile immap_t *) IMAP_ADDR; + + imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE); + + printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); +} + +static void +mpc8xx_wdt_handler_enable(void) +{ + volatile immap_t *imap = (volatile immap_t *) IMAP_ADDR; + + imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE; + + printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); +} + +static int +mpc8xx_wdt_open(struct inode *inode, struct file *file) +{ + switch (MINOR(inode->i_rdev)) { + case WATCHDOG_MINOR: + if (down_trylock(&wdt_sem)) + return -EBUSY; + + m8xx_wdt_reset(); + mpc8xx_wdt_handler_disable(); + break; + + default: + return -ENODEV; + } + + return 0; +} + +static int +mpc8xx_wdt_release(struct inode *inode, struct file *file) +{ + m8xx_wdt_reset(); + +#if !defined(CONFIG_WATCHDOG_NOWAYOUT) + mpc8xx_wdt_handler_enable(); +#endif + + up(&wdt_sem); + + return 0; +} + +static ssize_t +mpc8xx_wdt_write(struct file *file, const char *data, size_t len, loff_t * ppos) +{ + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + + if (!len) + return 0; + + m8xx_wdt_reset(); + + return 1; +} + +static int +mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user((void *) arg, &ident, sizeof (ident))) + return -EFAULT; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + if (put_user(wdt_status, (int *) arg)) + return -EFAULT; + wdt_status &= ~WDIOF_KEEPALIVEPING; + break; + + case WDIOC_KEEPALIVE: + m8xx_wdt_reset(); + wdt_status |= WDIOF_KEEPALIVEPING; + break; + + case WDIOC_GETTIMEOUT: + { + int timeout = m8xx_wdt_get_timeout(); + if (put_user(timeout, (int *) arg)) + return -EFAULT; + break; + } + + default: + return -ENOTTY; + } + + return 0; +} + +static struct file_operations mpc8xx_wdt_fops = { + .owner = THIS_MODULE, + .write = mpc8xx_wdt_write, + .ioctl = mpc8xx_wdt_ioctl, + .open = mpc8xx_wdt_open, + .release = mpc8xx_wdt_release, +}; + +static struct miscdevice mpc8xx_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &mpc8xx_wdt_fops, +}; + +static int __init +mpc8xx_wdt_init(void) +{ + int ret; + + sema_init(&wdt_sem, 1); + + if ((ret = misc_register(&mpc8xx_wdt_miscdev))) { + printk(KERN_WARNING + "mpc8xx_wdt: could not register userspace interface\n"); + return ret; + } + + return 0; +} + +static void __exit +mpc8xx_wdt_exit(void) +{ + misc_deregister(&mpc8xx_wdt_miscdev); + + m8xx_wdt_reset(); + mpc8xx_wdt_handler_enable(); +} + +module_init(mpc8xx_wdt_init); +module_exit(mpc8xx_wdt_exit); + +MODULE_AUTHOR("Florian Schirmer "); +MODULE_DESCRIPTION("MPC8xx watchdog driver"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/char/obmouse.c linux-2.4.25/drivers/char/obmouse.c --- linux-2.4.24/drivers/char/obmouse.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/char/obmouse.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,321 @@ +/* obmouse.c -- HP omnibook 600C/CT pop-up mouse driver + * + * Copyright (C) 1999 Olivier Florent + * Copyright (C) 1999 Chuck Slivkoff + * Copyright (C) 1999-2004 Grant Grundler + * + * OB600C/CT mouse can be compared to a tablet, as absolute coordinates + * are given by the hardware. This driver emulates a basic serial mouse + * protocol by translating absolute coordinates to relative moves. + * This works with gpm -t pnp and Xfree86 as a standard Micro$oft mouse. + * + * FIXME: This driver lacks a detection routine. + * i.e you must know that you have a 600C/CT before using it. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * 0.7 January 2004 grant + * convert to /dev/input + * + * 0.6 2 January 2004 grant + * converted to busmouse + * + * 0.5 27 december 2003 grant + * fix "built-in" code - added module_* calls + * + * 0.4 27 december 2002 grant grundler + * Add MODULES_ stuff (author, license, etc) + * fix read to return 0 if no change. + * + * 0.3 26 november 1999 grant grundler + * removed ifdefs for EMULATE_SERIAL_MOUSE and EMULATE_NCR_PEN. + * Only support "basic serial mouse protocol (gpm -t pnp)" which + * is also supported directly by Xfree. + * + * Moved delta(x,y) calculations into ob_interrupt. + * If we only get interrupts when the mouse moves, + * then only need to update delta(x,y) then too. + * + * 0.2 22 november 1999, grant grundler + * "man 4 mouse" explains really well how PNP mouse works. Read it. + * + * Fixed algorithm which generated delta(x,y) from current-last + * position reported. Now handles "roll-over" properly and + * speed scales _inversely_ (ie bigger number is slower). + * "speed" parameter can be set with "insmod obmouse speed=5" (default). + * + * 0.1a 16 november 1999, charles_slivkoff_at_hp.com + * File did not compile as received. + * Modified ob_write,ob_read parameters to match 2.2.x kernel. + * Added uaccess.h. Tried to fix ob_interrupt. + * + * 0.1 17 february 1999, olivier_florent_AT_hp.com + * original author. + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#undef OBMOUSE_DEBUG /* define to enable lots of printf */ + +#define OBMOUSE_NAME "HP omnibook 600C/CT pop-up mouse" +#define OBMOUSE_DEV_NAME "obmouse" +#define OBMOUSE_VERSION "v0.7" + + +/* +** "speed" of the mouse. Determines how "fast" the mouse "moves". +** Similar (but not the same) as acceleration. Using slower acceleration +** together with lower speed value might result in better mouse control. +** I've only used the default acceleration. +*/ +int speed = 4; /* my personal preference */ + +/* +** OB 600 mouse doesn't completely act like a tablet. +** The xy-coordinates do in fact roll over which would +** not happen on a tablet. +*/ +#define OB_ROLL_LIMIT 0xd00 + +/* +** obmouse HW specific data +*/ +#define OBMOUSE_BASE (0x238) /* base address of the hardware */ +#define OBMOUSE_EXTENT (3) /* from 0x238 to 0x23b */ +#define OBMOUSE_IRQ (12) /* irq 12 */ + +/* The 4 high bits of OBMOUSE_INTR_CTL */ +#define OBMOUSE_BTN_IRQ_MASK (0x10) /* WR: enable/disable button irq */ +#define OBMOUSE_MOV_IRQ_MASK (0x20) /* WR: enable/disable movement irq */ +#define OBMOUSE_BUTTON1_MASK (0x40) /* RD: status of button 1 */ +#define OBMOUSE_BUTTON2_MASK (0x80) /* RD: status of button 2 */ + +#define OBMOUSE_COORD_ONLY(v) ((v) & 0xfff) /* ignore high 4 bits */ + +#define OBMOUSE_INTR_CTL (OBMOUSE_BASE+3) +#define OBMOUSE_INTR_BITS (OBMOUSE_BTN_IRQ_MASK | OBMOUSE_MOV_IRQ_MASK) + +/* Enable/disable both button and movement interrupt */ +#define OBMOUSE_ENABLE_INTR() outb(OBMOUSE_INTR_BITS, OBMOUSE_INTR_CTL) +#define OBMOUSE_DISABLE_INTR() outb(~OBMOUSE_INTR_BITS, OBMOUSE_INTR_CTL) + +/* Amount mouse has to move before the hardware launchs a new +** interrupt (I think). 0x08 is the standard value. +** Write value to OBMOUSE_BASE each time an interrupt is handled to +** enable the next one. +*/ +#define OBMOUSE_SENSITIVITY (0x08) + +/* reset the sensitivity to enable next interrupt */ +#define OBMOUSE_ENABLE_SENSE() outb(OBMOUSE_SENSITIVITY,OBMOUSE_BASE) +#define OBMOUSE_DISABLE_SENSE() outb(0,OBMOUSE_BASE) + + +static unsigned short lastx; /* last reported normalized coords */ +static unsigned short lasty; +static unsigned char ob_opened = 0; /* 0=closed, 1=opened */ +static struct input_dev obdev; + + +/* +** Omnibook 600 mouse ISR. +** Read the HW state and resets "SENSITIVITY" in order to re-arm +** the interrupt. +*/ +static void +ob_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + short dx, dy; + unsigned short rawx, rawy; + + rawx = inb(OBMOUSE_BASE+0) + (inb(OBMOUSE_BASE+1) << 8); + rawy = inb(OBMOUSE_BASE+2) + (inb(OBMOUSE_BASE+3) << 8); + +#ifdef OBMOUSE_DEBUG +/* This printk is really useful for learning how the mouse actually behaves. */ +printk("ob_intr: %4x,%4x\n", rawx, rawy); +#endif + + /* reset the sensitivity */ + OBMOUSE_ENABLE_SENSE(); + + /* ------------------------------------ + ** update delta(x,y) values. + ** ------------------------------------ + */ + dx = (short) rawx - (short) lastx ; + lastx = rawx; + + { + register unsigned short coordY = OBMOUSE_COORD_ONLY(rawy); + dy = (short) coordY - (short) lasty ; + lasty = coordY; + } + + /* + ** determine if the reading "rolled" over. + ** Not fool-proof but should be good enough. + */ + if (dx > OB_ROLL_LIMIT) { + /* 0xf80 - 0x80 = 0xf00 (and we want 0x100) */ + dx = 0x1000 - dx; + } else if (-dx > OB_ROLL_LIMIT) { + /* + ** 0x80 - 0xf80 = -0xf00 (and we want -0x100) + ** -0x1000 - (-0xf00) = -0x1000 + 0xf00 = -0x100 + */ + dx = -0x1000 - dx; + } + + /* Same story with the Y-coordinate */ + if ( dy > OB_ROLL_LIMIT) dy = 0x1000 - dy; + else if (-dy > OB_ROLL_LIMIT) dy = -0x1000 - dy; + + dx /= speed; /* scale */ + dy /= speed; + + rawy = ~rawy; /* invert mouse buttons */ + input_report_key(&obdev, BTN_LEFT, (rawy & 0x8000)); + input_report_key(&obdev, BTN_RIGHT, (rawy & 0x4000)); + + /* obmouse acts like a table *EXCEPT* for the "roll-over". */ + if (dx) input_report_rel(&obdev, REL_X, -dx); + if (dy) input_report_rel(&obdev, REL_Y, dy); +} + + +static int ob_open(struct input_dev *dev) +{ + /* device is already opened */ + if (ob_opened) + return -EBUSY; + +#ifdef OBMOUSE_DEBUG +printk(OBMOUSE_DEV_NAME ": attempt request irq %d\n",OBMOUSE_IRQ); +#endif + + /* Try to get the interrupt */ + if (request_irq(OBMOUSE_IRQ,ob_interrupt,0,OBMOUSE_DEV_NAME,NULL)) { + printk (OBMOUSE_DEV_NAME ": request_irq failed for %d\n",OBMOUSE_IRQ); + return -EBUSY; + } + +#ifdef OBMOUSE_DEBUG +printk(OBMOUSE_DEV_NAME ": irq %d registered\n",OBMOUSE_IRQ); +#endif + + OBMOUSE_ENABLE_INTR() ; + OBMOUSE_ENABLE_SENSE() ; + + MOD_INC_USE_COUNT; + ob_opened = 1 ; + return 0; +} + + +void ob_close(struct input_dev *dev) +{ + /* device has never been opened */ + if (!ob_opened) + return; + + OBMOUSE_DISABLE_INTR() ; + free_irq(OBMOUSE_IRQ, NULL); + + MOD_DEC_USE_COUNT; + ob_opened = 0 ; +} + + +#ifndef MODULE +static int __init obmouse_setup(char *str) +{ + int ints[4]; + + str = get_options(str, ARRAY_SIZE(ints), ints); + if (ints[0] > 0) + speed=ints[1]; + + return 1; +} + +__setup("speed=", obmouse_setup); +#endif /* !MODULE */ + + +static int obmouse_init(void) +{ + /* Get the IO Port region first */ + if (request_region(OBMOUSE_BASE,OBMOUSE_EXTENT,OBMOUSE_DEV_NAME) < 0) { + printk(KERN_ERR OBMOUSE_DEV_NAME ": IO Port 0x%d not available!\n", OBMOUSE_BASE); + return -ENODEV; + + } + + OBMOUSE_DISABLE_INTR() ; + OBMOUSE_DISABLE_SENSE() ; + + memset(&obdev, 0, sizeof(obdev)); + + obdev.name = OBMOUSE_NAME " " OBMOUSE_VERSION; + obdev.idbus = BUS_ISA; + obdev.idvendor = 0x103c; /* PCI_VENDOR_ID_HP */ + obdev.idproduct = 0x0001; + obdev.idversion = 0x0100; + + obdev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + obdev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + obdev.relbit[0] = BIT(REL_X) | BIT(REL_Y); + obdev.open = ob_open; + obdev.close = ob_close; + + input_register_device(&obdev); + printk( OBMOUSE_NAME " " OBMOUSE_VERSION + " (0x%x, IRQ %d), Grant Grundler\n", OBMOUSE_BASE, OBMOUSE_IRQ); + + return 0; +} + +static void obmouse_exit(void) +{ + OBMOUSE_DISABLE_INTR() ; + OBMOUSE_DISABLE_SENSE() ; + + input_unregister_device(&obdev); + release_region(OBMOUSE_BASE,OBMOUSE_EXTENT); + printk(OBMOUSE_DEV_NAME ": closed\n"); +} + +module_init(obmouse_init); +module_exit(obmouse_exit); + +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Grant Grundler "); +MODULE_DESCRIPTION(OBMOUSE_NAME); +MODULE_PARM(speed, "i"); +MODULE_PARM_DESC(speed, "obmouse speed (not accel) control"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/char/random.c linux-2.4.25/drivers/char/random.c --- linux-2.4.24/drivers/char/random.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/random.c 2004-02-18 05:36:31.000000000 -0800 @@ -715,7 +715,9 @@ static struct timer_rand_state keyboard_timer_state; static struct timer_rand_state mouse_timer_state; static struct timer_rand_state extract_timer_state; +#ifndef CONFIG_ARCH_S390 static struct timer_rand_state *irq_timer_state[NR_IRQS]; +#endif static struct timer_rand_state *blkdev_timer_state[MAX_BLKDEV]; /* @@ -791,6 +793,7 @@ batch_entropy_store(num, time, entropy); } +#ifndef CONFIG_ARCH_S390 void add_keyboard_randomness(unsigned char scancode) { static unsigned char last_scancode; @@ -813,6 +816,7 @@ add_timer_randomness(irq_timer_state[irq], 0x100+irq); } +#endif void add_blkdev_randomness(int major) { @@ -1445,8 +1449,10 @@ #ifdef CONFIG_SYSCTL sysctl_init_random(random_state); #endif +#ifndef CONFIG_ARCH_S390 for (i = 0; i < NR_IRQS; i++) irq_timer_state[i] = NULL; +#endif for (i = 0; i < MAX_BLKDEV; i++) blkdev_timer_state[i] = NULL; memset(&keyboard_timer_state, 0, sizeof(struct timer_rand_state)); @@ -1455,6 +1461,7 @@ extract_timer_state.dont_count_entropy = 1; } +#ifndef CONFIG_ARCH_S390 void rand_initialize_irq(int irq) { struct timer_rand_state *state; @@ -1472,6 +1479,7 @@ irq_timer_state[irq] = state; } } +#endif void rand_initialize_blkdev(int major, int mode) { @@ -2304,9 +2312,11 @@ +#ifndef CONFIG_ARCH_S390 EXPORT_SYMBOL(add_keyboard_randomness); EXPORT_SYMBOL(add_mouse_randomness); EXPORT_SYMBOL(add_interrupt_randomness); +#endif EXPORT_SYMBOL(add_blkdev_randomness); EXPORT_SYMBOL(batch_entropy_store); EXPORT_SYMBOL(generate_random_uuid); diff -urN linux-2.4.24/drivers/char/rtc.c linux-2.4.25/drivers/char/rtc.c --- linux-2.4.24/drivers/char/rtc.c 2004-01-05 05:53:56.000000000 -0800 +++ linux-2.4.25/drivers/char/rtc.c 2004-02-18 05:36:31.000000000 -0800 @@ -35,17 +35,16 @@ * 1.09a Pete Zaitcev: Sun SPARC * 1.09b Jeff Garzik: Modularize, init cleanup * 1.09c Jeff Garzik: SMP cleanup - * 1.10 Paul Barton-Davis: add support for async I/O + * 1.10 Paul Barton-Davis: add support for async I/O * 1.10a Andrea Arcangeli: Alpha updates * 1.10b Andrew Morton: SMP lock fix * 1.10c Cesar Barros: SMP locking fixes and cleanup * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. + * 1.10f Maciej W. Rozycki: Handle memory-mapped chips properly. */ -#define RTC_VERSION "1.10e" - -#define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */ +#define RTC_VERSION "1.10f" /* * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with @@ -84,7 +83,9 @@ static int rtc_irq = PCI_IRQ_NONE; #endif +#if RTC_IRQ static int rtc_has_irq = 1; +#endif /* * We sponge a minor off of the misc major. No need slurping @@ -97,7 +98,9 @@ static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); +#if RTC_IRQ static struct timer_list rtc_irq_timer; +#endif static ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos); @@ -238,7 +241,15 @@ if (rtc_has_irq == 0) return -EIO; - if (count < sizeof(unsigned long)) + /* + * Historically this function used to assume that sizeof(unsigned long) + * is the same in userspace and kernelspace. This lead to problems + * for configurations with multiple ABIs such a the MIPS o32 and 64 + * ABIs supported on the same kernel. So now we support read of both + * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the + * userspace ABI. + */ + if (count != sizeof(unsigned int) && count != sizeof(unsigned long)) return -EINVAL; add_wait_queue(&rtc_wait, &wait); @@ -268,9 +279,12 @@ schedule(); } while (1); - retval = put_user(data, (unsigned long *)buf); + if (count == sizeof(unsigned int)) + retval = put_user(data, (unsigned int *)buf); + else + retval = put_user(data, (unsigned long *)buf); if (!retval) - retval = sizeof(unsigned long); + retval = count; out: current->state = TASK_RUNNING; remove_wait_queue(&rtc_wait, &wait); @@ -707,6 +721,9 @@ struct isa_device *isa_dev; #endif #endif +#ifndef __sparc__ + void *r; +#endif #ifdef __sparc__ for_each_ebus(ebus) { @@ -753,18 +770,24 @@ } no_irq: #else - if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) - { - printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0)); + if (RTC_IOMAPPED) + r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); + else + r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); + if (!r) { + printk(KERN_ERR "rtc: I/O resource %lx is not free.\n", + (long)(RTC_PORT(0))); return -EIO; } #if RTC_IRQ - if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) - { + if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) { /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); - release_region(RTC_PORT(0), RTC_IO_EXTENT); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); return -EIO; } #endif @@ -848,7 +871,10 @@ if (rtc_has_irq) free_irq (rtc_irq, &rtc_port); #else - release_region (RTC_PORT (0), RTC_IO_EXTENT); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); #if RTC_IRQ if (rtc_has_irq) free_irq (RTC_IRQ, NULL); diff -urN linux-2.4.24/drivers/char/sb1250_duart.c linux-2.4.25/drivers/char/sb1250_duart.c --- linux-2.4.24/drivers/char/sb1250_duart.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/sb1250_duart.c 2004-02-18 05:36:31.000000000 -0800 @@ -368,7 +368,7 @@ spin_lock_irqsave(&us->outp_lock, flags); - if (us->outp_count >= SERIAL_XMIT_SIZE - 1) { + if (us->outp_count == SERIAL_XMIT_SIZE) { spin_unlock_irqrestore(&us->outp_lock, flags); return; } @@ -910,6 +910,8 @@ port->mode_2, i); WRITE_SERCSR(V_DUART_BAUD_RATE(115200), port->clk_sel, i); + WRITE_SERCSR(M_DUART_RX_EN|M_DUART_TX_EN, + port->cmd, i); } return 0; } diff -urN linux-2.4.24/drivers/char/serial.c linux-2.4.25/drivers/char/serial.c --- linux-2.4.24/drivers/char/serial.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/serial.c 2004-02-18 05:36:31.000000000 -0800 @@ -3746,7 +3746,14 @@ /* Check for Startech UART's */ serial_outp(info, UART_LCR, UART_LCR_DLAB); if (serial_in(info, UART_EFR) == 0) { + serial_outp(info, UART_EFR, 0xA8); + if (serial_in(info, UART_EFR) == 0) { + /* We are a NS16552D/Motorola + * 8xxx DUART, stop. */ + goto out; + } state->type = PORT_16650; + serial_outp(info, UART_EFR, 0); } else { serial_outp(info, UART_LCR, 0xBF); if (serial_in(info, UART_EFR) == 0) @@ -3795,6 +3802,7 @@ } } #endif +out: serial_outp(info, UART_LCR, save_lcr); if (state->type == PORT_16450) { scratch = serial_in(info, UART_SCR); diff -urN linux-2.4.24/drivers/char/sgiserial.c linux-2.4.25/drivers/char/sgiserial.c --- linux-2.4.24/drivers/char/sgiserial.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/sgiserial.c 2004-02-18 05:36:31.000000000 -0800 @@ -13,9 +13,6 @@ * thorough pass to merge in the rest of the updates. * Better still, someone really ought to make it a common * code module for both platforms. kevink@mips.com - * - * 20010616 - Klaus Naumann : Make serial console work with - * any speed - not only 9600 */ #include /* for CONFIG_KGDB */ @@ -2079,14 +2076,14 @@ static int __init zs_console_setup(struct console *con, char *options) { struct sgi_serial *info; - int baud; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - char *s, *dbaud; - int i, brg; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + char *s; + int i, brg; - if (options) { + if(options) { baud = simple_strtoul(options, NULL, 10); s = options; while(*s >= '0' && *s <= '9') @@ -2094,25 +2091,7 @@ if (*s) parity = *s++; if (*s) bits = *s - '0'; } - else { - /* If the user doesn't set console=... try to read the - * PROM variable - if this fails use 9600 baud and - * inform the user about the problem - */ - dbaud = ArcGetEnvironmentVariable("dbaud"); - if(dbaud) baud = simple_strtoul(dbaud, NULL, 10); - else { - /* Use prom_printf() to make sure that the user - * is getting anything ... - */ - prom_printf("No dbaud set in PROM ?!? Using 9600.\n"); - baud = 9600; - } - } - - /* - * Now construct a cflag setting. - */ + /* Now construct a cflag setting. */ switch(baud) { case 1200: cflag |= B1200; diff -urN linux-2.4.24/drivers/char/shwdt.c linux-2.4.25/drivers/char/shwdt.c --- linux-2.4.24/drivers/char/shwdt.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.25/drivers/char/shwdt.c 2004-02-18 05:36:31.000000000 -0800 @@ -3,7 +3,7 @@ * * Watchdog driver for integrated watchdog in the SuperH processors. * - * Copyright (C) 2001, 2002 Paul Mundt + * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,6 +12,7 @@ * * 14-Dec-2001 Matt Domsch * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT + * * 19-Apr-2002 Rob Radez * Added expect close support, made emulated timeout runtime changeable * general cleanups, add some ioctls @@ -31,8 +32,10 @@ #include #if defined(CONFIG_CPU_SH5) - #define WTCNT CPRC_BASE + 0x10 - #define WTCSR CPRC_BASE + 0x18 + extern unsigned long cprc_base; + + #define WTCNT (cprc_base+0x10) + #define WTCSR (cprc_base+0x18) #elif defined(CONFIG_CPU_SH4) #define WTCNT 0xffc00008 #define WTCSR 0xffc0000c @@ -82,22 +85,43 @@ #define WTCSR_CKS_4096 0x07 /* - * Default clock division ratio is 5.25 msecs. Overload this at module load - * time. Any value not in the msec range will default to a timeout of one - * jiffy, which exceeds the usec overflow periods. + * Default clock division ratio is 5.25 msecs. For an additional table of + * values, consult the asm-sh/watchdog.h. Overload this at module load + * time. + * + * In order for this to work reliably we need to have HZ set to 1000 or + * something quite higher than 100 (or we need a proper high-res timer + * implementation that will deal with this properly), otherwise the 10ms + * resolution of a jiffy is enough to trigger the overflow. For things like + * the SH-4 and SH-5, this isn't necessarily that big of a problem, though + * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely + * necssary. + * + * As a result of this timing problem, the only modes that are particularly + * feasible are the 4096 and the 2048 divisors, which yeild 5.25 and 2.62ms + * overflow periods respectively. + * + * Also, since we can't really expect userspace to be responsive enough + * before the overflow happens, we maintain two seperate timers .. One in + * the kernel for clearing out WOVF every 2ms or so (again, this depends on + * HZ == 1000), and another for monitoring userspace writes to the WDT device. + * + * As such, we currently use a configurable heartbeat interval which defaults + * to 30s. In this case, the userspace daemon is only responsible for periodic + * writes to the device before the next heartbeat is scheduled. If the daemon + * misses its deadline, the kernel timer will allow the WDT to overflow. */ static int clock_division_ratio = WTCSR_CKS_4096; -#define msecs_to_jiffies(msecs) (jiffies + ((HZ * msecs + 999) / 1000)) +#define msecs_to_jiffies(msecs) (jiffies + (HZ * msecs + 9999) / 10000) #define next_ping_period(cks) msecs_to_jiffies(cks - 4) -static unsigned long sh_is_open; +static unsigned long shwdt_is_open; static struct watchdog_info sh_wdt_info; static char shwdt_expect_close; - static struct timer_list timer; static unsigned long next_heartbeat; -static int sh_heartbeat = 30; +static int heartbeat = 30; #ifdef CONFIG_WATCHDOG_NOWAYOUT static int nowayout = 1; @@ -119,6 +143,22 @@ } /** + * sh_wdt_read_csr - Read from Control/Status Register + * + * Reads back the WTCSR value. + */ +static inline __u8 sh_wdt_read_csr(void) +{ + /* + * XXX: This is pretty straightforward on SH-3 and up, though on + * anything lower we have seperate locations for reading and + * writing the CSR value. We just keep this around for general + * completeness. + */ + return ctrl_inb(WTCSR); +} + +/** * sh_wdt_write_csr - Write to Control/Status Register * * @val: Value to write @@ -138,13 +178,29 @@ */ static void sh_wdt_start(void) { - timer.expires = next_ping_period(clock_division_ratio); - next_heartbeat = jiffies + (sh_heartbeat * HZ); - add_timer(&timer); + __u8 csr; + + mod_timer(&timer, next_ping_period(clock_division_ratio)); + next_heartbeat = jiffies + (heartbeat * HZ); + + csr = sh_wdt_read_csr(); + csr |= WTCSR_WT | clock_division_ratio; + sh_wdt_write_csr(csr); - sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096); sh_wdt_write_cnt(0); - sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME)); + + /* + * These processors have a bit of an inconsistent initialization + * process.. starting with SH-3, RSTS was moved to WTCSR, and the + * RSTCSR register was removed. + * + * On the SH-2 these semantics are even odder, as we have to deal + * with RSTCSR outright. See the 2.6 code for this. + */ + csr = sh_wdt_read_csr(); + csr |= WTCSR_TME; + csr &= ~WTCSR_RSTS; + sh_wdt_write_csr(csr); } /** @@ -154,9 +210,13 @@ */ static void sh_wdt_stop(void) { + __u8 csr; + del_timer(&timer); - sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME)); + csr = sh_wdt_read_csr(); + csr &= ~WTCSR_TME; + sh_wdt_write_csr(csr); } /** @@ -169,11 +229,15 @@ static void sh_wdt_ping(unsigned long data) { if (time_before(jiffies, next_heartbeat)) { - sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF)); + __u8 csr; + + csr = sh_wdt_read_csr(); + csr &= ~WTCSR_IOVF; + sh_wdt_write_csr(csr); + sh_wdt_write_cnt(0); - timer.expires = next_ping_period(clock_division_ratio); - add_timer(&timer); + mod_timer(&timer, next_ping_period(clock_division_ratio)); } } @@ -187,7 +251,7 @@ */ static int sh_wdt_open(struct inode *inode, struct file *file) { - if (test_and_set_bit(0, &sh_is_open)) + if (test_and_set_bit(0, &shwdt_is_open)) return -EBUSY; sh_wdt_start(); @@ -209,9 +273,10 @@ sh_wdt_stop(); } else { printk(KERN_CRIT "shwdt: Unexpected close, not stopping watchdog!\n"); - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); } - clear_bit(0, &sh_is_open); + + clear_bit(0, &shwdt_is_open); shwdt_expect_close = 0; return 0; @@ -246,7 +311,7 @@ if (c == 'V') shwdt_expect_close = 42; } - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); } return count; @@ -275,13 +340,13 @@ sizeof(sh_wdt_info))) { return -EFAULT; } - + break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: - next_heartbeat = jiffies + (sh_heartbeat * HZ); + next_heartbeat = jiffies + (heartbeat * HZ); break; case WDIOC_SETTIMEOUT: @@ -289,11 +354,11 @@ return -EFAULT; if (new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ return -EINVAL; - sh_heartbeat = new_timeout; - next_heartbeat = jiffies + (sh_heartbeat * HZ); + heartbeat = new_timeout; + next_heartbeat = jiffies + (heartbeat * HZ); /* Fall */ case WDIOC_GETTIMEOUT: - return put_user(sh_heartbeat, (int *)arg); + return put_user(heartbeat, (int *)arg); case WDIOC_SETOPTIONS: { int options, retval = -EINVAL; @@ -310,7 +375,7 @@ sh_wdt_start(); retval = 0; } - + return retval; } default: diff -urN linux-2.4.24/drivers/char/tipar.c linux-2.4.25/drivers/char/tipar.c --- linux-2.4.24/drivers/char/tipar.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.25/drivers/char/tipar.c 2004-02-18 05:36:31.000000000 -0800 @@ -71,9 +71,11 @@ #define DRIVER_DESC "Device driver for TI/PC parallel link cables" #define DRIVER_LICENSE "GPL" -#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq)) -#if LINUX_VERSION_CODE < VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) # define minor(x) MINOR(x) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) # define need_resched() (current->need_resched) #endif diff -urN linux-2.4.24/drivers/char/tty_io.c linux-2.4.25/drivers/char/tty_io.c --- linux-2.4.24/drivers/char/tty_io.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/char/tty_io.c 2004-02-18 05:36:31.000000000 -0800 @@ -164,6 +164,7 @@ extern void txx9_serial_console_init(void); extern void sb1250_serial_console_init(void); extern void arc_console_init(void); +extern int hvc_console_init(void); #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -2238,6 +2239,9 @@ #ifdef CONFIG_EARLY_PRINTK disable_early_printk(); #endif +#ifdef CONFIG_HVC_CONSOLE + hvc_console_init(); +#endif #ifdef CONFIG_VT con_init(); #endif diff -urN linux-2.4.24/drivers/char/vac-serial.c linux-2.4.25/drivers/char/vac-serial.c --- linux-2.4.24/drivers/char/vac-serial.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/char/vac-serial.c 2004-02-18 05:36:31.000000000 -0800 @@ -10,7 +10,9 @@ #define CONFIG_SERIAL_NOPAUSE_IO #define SERIAL_DO_RESTART +#ifndef CONFIG_SERIAL_SHARE_IRQ #define CONFIG_SERIAL_SHARE_IRQ +#endif /* Set of debugging defines */ diff -urN linux-2.4.24/drivers/char/vr41xx_keyb.c linux-2.4.25/drivers/char/vr41xx_keyb.c --- linux-2.4.24/drivers/char/vr41xx_keyb.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/char/vr41xx_keyb.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,410 @@ +/* + * FILE NAME + * drivers/char/vr41xx_keyb.c + * + * BRIEF MODULE DESCRIPTION + * Keyboard driver for NEC VR4100 series Keyboard Interface Unit. + * + * Copyright (C) 1999 Bradley D. LaRonde + * Copyright (C) 1999 Hiroshi Kawashima + * Copyright (C) 2000 Michael Klar + * Copyright (C) 2002,2003 Yoichi Yuasa + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +/* + * Changes: + * version 1.0 + * Yoichi Yuasa Mon, 25 Mar 2002 + * - Rewrote extensively because of 2.4.18. + * + * version 1.1 + * Yoichi Yuasa Wed, 9 Sep 200 + * - Added NEC VRC4173 KIU support. + */ +#include +#include +#include +#include +#ifdef CONFIG_PCI +#include +#endif +#include + +#include +#include +#include +#include +#include +#ifdef CONFIG_VRC4173 +#include +#endif + +#define KIU_BASE KSEG1ADDR(0x0b000180) +#define MKIUINTREG KSEG1ADDR(0x0b000092) + +#define VRC4173_KIU_OFFSET 0x100 +#define VRC4173_MKIUINTREG_OFFSET 0x072 + +#define KIUDAT0 0x00 +#define KIUDAT1 0x02 +#define KIUDAT2 0x04 +#define KIUDAT3 0x06 +#define KIUDAT4 0x08 +#define KIUDAT5 0x0a +#define KIUDAT6 0x0c +#define KIUDAT7 0x0e +#define KIUSCANREP 0x10 + #define KIUSCANREP_KEYEN 0x8000 + #define KIUSCANREP_STPREP(x) ((x) << 4) + #define KIUSCANREP_SCANSTP 0x0008 + #define KIUSCANREP_SCANSTART 0x0004 + #define KIUSCANREP_ATSTP 0x0002 + #define KIUSCANREP_ATSCAN 0x0001 +#define KIUSCANS 0x12 + #define KIUSCANS_SCANNING 0x0003 + #define KIUSCANS_INTERVAL 0x0002 + #define KIUSCANS_WAITKEYIN 0x0001 + #define KIUSCANS_STOPPED 0x0000 +#define KIUWKS 0x14 + #define KIUWKS_T3CNT 0x7c00 + #define KIUWKS_T3CNT_SHIFT 10 + #define KIUWKS_T2CNT 0x03e0 + #define KIUWKS_T2CNT_SHIFT 5 + #define KIUWKS_T1CNT 0x001f + #define KIUWKS_T1CNT_SHIFT 0 + #define KIUWKS_CNT_USEC(x) (((x) / 30) - 1) +#define KIUWKI 0x16 + #define KIUWKI_INTERVAL_USEC(x) ((x) / 30) +#define KIUINT 0x18 + #define KIUINT_KDATLOST 0x0004 + #define KIUINT_KDATRDY 0x0002 + #define KIUINT_SCANINT 0x0001 +#define KIURST 0x1a + #define KIURST_KIURST 0x0001 +#define KIUGPEN 0x1c + #define KIUGPEN_KGPEN(x) ((uint16_t)1 << (x)) +#define SCANLINE 0x1e + #define SCANLINE_DONTUSE 0x0003 + #define SCANLINE_8LINES 0x0002 + #define SCANLINE_10LINES 0x0001 + #define SCANLINE_12LINES 0x0000 + +static unsigned long kiu_base; +static unsigned long mkiuintreg; + +#ifdef CONFIG_VRC4173 +#define kiu_readw(offset) vrc4173_inw(kiu_base + (offset)) +#define kiu_writew(val, offset) vrc4173_outw(val, kiu_base + (offset)) +#define mkiuintreg_writew(val) vrc4173_outw((val), mkiuintreg) +#else +#define kiu_readw(offset) readw(kiu_base + (offset)) +#define kiu_writew(val, offset) writew(val, kiu_base + (offset)) +#define mkiuintreg_writew(val) writew((val), mkiuintreg) +#endif + +#define KIU_CLOCK 0x0008 + +#ifdef CONFIG_VRC4173 +#define KIU_IRQ VRC4173_KIU_IRQ +#else +#define KIU_IRQ SYSINT1_IRQ(7) +#endif + +#define KEY_UP 0 +#define KEY_DOWN 1 + +#define DEFAULT_KIUDAT_REGS 6 +#define DEFAULT_DATA_NOT_REVERSED 0 +#define DEFAULT_T3CNT KIUWKS_CNT_USEC(200) +#define DEFAULT_T2CNT KIUWKS_CNT_USEC(200) +#define DEFAULT_T1CNT KIUWKS_CNT_USEC(200) +#define DEFAULT_SCAN_INTERVAL KIUWKI_INTERVAL_USEC(30000) +#define DEFAULT_REPEAT_DELAY HZ/4 +#define DEFAULT_REPEAT_RATE HZ/25 + +static char *kiu_driver_name = "Keyboard driver"; +static char *kiu_driver_version = "1.1"; +static char *kiu_driver_revdate = "2003-09-09"; +static char *kiu_driver_device_name = "NEC VR4100 series KIU"; + +static unsigned char kiudat_regs = DEFAULT_KIUDAT_REGS; +static unsigned char data_reverse = DEFAULT_DATA_NOT_REVERSED; +static uint16_t scanlines = SCANLINE_12LINES; +static uint16_t t3cnt = DEFAULT_T3CNT; +static uint16_t t2cnt = DEFAULT_T2CNT; +static uint16_t t1cnt = DEFAULT_T1CNT; +static uint16_t scan_interval = DEFAULT_SCAN_INTERVAL; + +static unsigned long repeat_delay = DEFAULT_REPEAT_DELAY; +static unsigned long repeat_rate = DEFAULT_REPEAT_RATE; + +static int repeat_scancode = -1; +static unsigned long next_handle_time; + +struct kiudat_t { + uint32_t reg; + uint16_t data; +}; + +static struct kiudat_t kiudat [8] = { + {KIUDAT0, 0}, {KIUDAT1, 0}, + {KIUDAT2, 0}, {KIUDAT3, 0}, + {KIUDAT4, 0}, {KIUDAT5, 0}, + {KIUDAT6, 0}, {KIUDAT7, 0}, +}; + +int kbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + return (scancode == keycode) ? 0 : -EINVAL; +} + +int kbd_getkeycode(unsigned int scancode) +{ + return scancode; +} + +int kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) +{ + *keycode = scancode; + return 1; +} + +char kbd_unexpected_up(unsigned char keycode) +{ + printk(KERN_WARNING "vr41xx_keyb: unexpected up, keycode 0x%02x\n", keycode); + return 0x80; +} + +void kbd_leds(unsigned char leds) +{ + return; +} + +static inline void handle_kiudat(uint16_t data, uint16_t cmp_data, int scancode) +{ + uint16_t mask; + int down, candidate_scancode = 0; + + for (mask = 0x0001; mask ; mask <<= 1) { + if (cmp_data & mask) { + down = data & mask ? KEY_DOWN : KEY_UP; + if (down == KEY_DOWN) { + repeat_scancode = scancode; + next_handle_time = jiffies + repeat_delay; + } + else { + if (repeat_scancode == scancode) + repeat_scancode = -1; + } + handle_scancode(scancode, down); + } + if (data & mask) { + candidate_scancode = scancode; + } + scancode++; + } + + if ((repeat_scancode < 0) && (candidate_scancode > 0)) { + repeat_scancode = candidate_scancode; + next_handle_time = jiffies + repeat_delay; + } +} + +static inline void handle_kiu_event(void) +{ + struct kiudat_t *kiu = kiudat; + uint16_t data, last_data, cmp_data; + int i; + + for (i = 0; i < kiudat_regs; i++) { + last_data = kiu->data; + data = kiu_readw(kiu->reg); + if (data_reverse) + data = ~data; + kiu->data = data; + cmp_data = data ^ last_data; + handle_kiudat(data, cmp_data, i * 16); + kiu++; + } + + if ((repeat_scancode >= 0) && + (time_after_eq(jiffies, next_handle_time))) { + handle_scancode(repeat_scancode, KEY_DOWN); + next_handle_time = jiffies + repeat_rate; + } +} + +static void kiu_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + uint16_t status; + + mkiuintreg_writew(0); + + status = kiu_readw(KIUINT); + kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT); + + if (status & KIUINT_KDATRDY) + handle_kiu_event(); + + mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY); +} + +#ifdef CONFIG_PM + +static int pm_kiu_request(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + switch (rqst) { + case PM_SUSPEND: + mkiuintreg_writew(KIUINT_SCANINT); + break; + case PM_RESUME: + kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT); + mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY, MKIUINTREG); + break; + } + + return 0; +} + +#endif + +void __devinit kbd_init_hw(void) +{ + uint16_t kiugpen = 0; + int i; + + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) { + kiu_base = KIU_BASE; + mkiuintreg = MKIUINTREG; +#if defined(CONFIG_PCI) && defined(CONFIG_VRC4173) + } else if (current_cpu_data.cputype == CPU_VR4122 || + current_cpu_data.cputype == CPU_VR4131) { + struct pci_dev *dev; + int found = 0; + dev = pci_find_device(PCI_VENDOR_ID_NEC, + PCI_DEVICE_ID_NEC_VRC4173, NULL); + if (dev != NULL) { + switch (scanlines) { + case SCANLINE_8LINES: + vrc4173_select_function(KIU8_SELECT); + found = 1; + break; + case SCANLINE_10LINES: + vrc4173_select_function(KIU10_SELECT); + found = 1; + break; + case SCANLINE_12LINES: + vrc4173_select_function(KIU12_SELECT); + found = 1; + break; + default: + break; + } + + if (found != 0) { + kiu_base = VRC4173_KIU_OFFSET; + mkiuintreg = VRC4173_MKIUINTREG_OFFSET; + vrc4173_clock_supply(VRC4173_KIU_CLOCK); + } + } +#endif + } + + if (kiu_base == 0 || mkiuintreg == 0) + return; + + printk(KERN_INFO "%s version %s (%s) for %s\n", + kiu_driver_name, kiu_driver_version, + kiu_driver_revdate, kiu_driver_device_name); + + mkiuintreg_writew(0); + + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) + vr41xx_clock_supply(KIU_CLOCK); + + kiu_writew(KIURST_KIURST, KIURST); + + for (i = 0; i < scanlines; i++) + kiugpen &= ~(0x0001 << i); + + kiu_writew(kiugpen, KIUGPEN); + kiu_writew(scanlines, SCANLINE); + kiu_writew((t3cnt << KIUWKS_T3CNT_SHIFT) | + (t2cnt << KIUWKS_T2CNT_SHIFT) | + (t1cnt << KIUWKS_T1CNT_SHIFT), KIUWKS); + kiu_writew(scan_interval, KIUWKI); + kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT); + + + request_irq(KIU_IRQ, kiu_interrupt, 0, "keyboard", NULL); + + mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY); + kiu_writew(KIUSCANREP_KEYEN | KIUSCANREP_STPREP(1) | + KIUSCANREP_ATSTP | KIUSCANREP_ATSCAN, KIUSCANREP); + +#ifdef CONFIG_PM + pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kiu_request); +#endif +} + +static int __devinit vr41xx_kbd_setup(char *options) +{ + char *this_opt; + int num; + + if (!options || !*options) + return 1; + + for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) { + if (!strncmp(this_opt, "regs:", 5)) { + num = simple_strtoul(this_opt+5, NULL, 0); + if (num == 6 || num == 8) + kiudat_regs = num; + } else if (!strncmp(this_opt, "lines:", 6)) { + num = simple_strtoul(this_opt+6, NULL, 0); + if (num == 8) + scanlines = SCANLINE_8LINES; + else if (num == 10) + scanlines = SCANLINE_10LINES; + else if (num == 12) + scanlines = SCANLINE_12LINES; + } else if (!strncmp(this_opt, "reverse:", 8)) { + num = simple_strtoul(this_opt+8, NULL, 0); + if (num == 0 || num == 1) + data_reverse = num; + } else if (!strncmp(this_opt, "t3cnt:", 6)) { + num = simple_strtoul(this_opt+6, NULL, 0); + if (num >= 60 && num <= 960) + t3cnt = KIUWKS_CNT_USEC(num); + } else if (!strncmp(this_opt, "t2cnt:", 6)) { + num = simple_strtoul(this_opt+6, NULL, 0); + if (num >= 60 && num <= 960) + t2cnt = KIUWKS_CNT_USEC(num); + } else if (!strncmp(this_opt, "t1cnt:", 6)) { + num = simple_strtoul(this_opt+6, NULL, 0); + if (num >= 60 && num <= 960) + t1cnt = KIUWKS_CNT_USEC(num); + } else if (!strncmp(this_opt, "interval:", 9)) { + num = simple_strtoul(this_opt+9, NULL, 0); + if (num >= 30 && num <= 30690) + scan_interval = KIUWKI_INTERVAL_USEC(num); + } else if (!strncmp(this_opt, "delay:", 6)) { + num = simple_strtoul(this_opt+6, NULL, 0); + if (num > 0 && num <= HZ) + repeat_delay = num; + } else if (!strncmp(this_opt, "rate:", 5)) { + num = simple_strtoul(this_opt+5, NULL, 0); + if (num > 0 && num <= HZ) + repeat_rate = num; + } + } + + return 1; +} + +__setup("vr41xx_kbd=", vr41xx_kbd_setup); diff -urN linux-2.4.24/drivers/i2c/Config.in linux-2.4.25/drivers/i2c/Config.in --- linux-2.4.24/drivers/i2c/Config.in 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/i2c/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -7,20 +7,20 @@ tristate 'I2C support' CONFIG_I2C if [ "$CONFIG_I2C" != "n" ]; then - dep_tristate 'I2C bit-banging interfaces' CONFIG_I2C_ALGOBIT $CONFIG_I2C if [ "$CONFIG_I2C_ALGOBIT" != "n" ]; then dep_tristate ' Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT $CONFIG_PARPORT dep_tristate ' ELV adapter' CONFIG_I2C_ELV $CONFIG_I2C_ALGOBIT - dep_tristate ' Velleman K9000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT + dep_tristate ' Velleman K8000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT dep_tristate ' NatSemi SCx200 I2C using GPIO pins' CONFIG_SCx200_I2C $CONFIG_SCx200 $CONFIG_I2C_ALGOBIT if [ "$CONFIG_SCx200_I2C" != "n" ]; then int ' GPIO pin used for SCL' CONFIG_SCx200_I2C_SCL 12 int ' GPIO pin used for SDA' CONFIG_SCx200_I2C_SDA 13 fi - dep_tristate ' NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C fi + dep_tristate 'NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C + dep_tristate 'I2C PCF 8584 interfaces' CONFIG_I2C_ALGOPCF $CONFIG_I2C if [ "$CONFIG_I2C_ALGOPCF" != "n" ]; then dep_tristate ' Elektor ISA card' CONFIG_I2C_ELEKTOR $CONFIG_I2C_ALGOPCF @@ -35,7 +35,7 @@ if [ "$CONFIG_8xx" = "y" ]; then dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then - dep_tristate ' Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX + dep_tristate ' Embedded Planet RPX Lite/Classic support' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX fi fi if [ "$CONFIG_405" = "y" ]; then @@ -54,11 +54,14 @@ dep_tristate ' MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE fi + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate 'I2C SGI interfaces' CONFIG_I2C_ALGO_SGI $CONFIG_I2C + fi + # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C - dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C - + dep_tristate 'I2C /proc interface (required for hardware sensors)' CONFIG_I2C_PROC $CONFIG_I2C $CONFIG_SYSCTL fi endmenu diff -urN linux-2.4.24/drivers/i2c/Makefile linux-2.4.25/drivers/i2c/Makefile --- linux-2.4.24/drivers/i2c/Makefile 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/i2c/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,8 @@ O_TARGET := i2c.o export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ - i2c-algo-ite.o i2c-proc.o i2c-algo-sibyte.o + i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \ + i2c-proc.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o @@ -23,6 +24,7 @@ obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o i2c-sibyte.o obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o +obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -urN linux-2.4.24/drivers/i2c/i2c-adap-ite.c linux-2.4.25/drivers/i2c/i2c-adap-ite.c --- linux-2.4.24/drivers/i2c/i2c-adap-ite.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-adap-ite.c 2004-02-18 05:36:31.000000000 -0800 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -61,11 +60,7 @@ static int i2c_debug=0; static struct iic_ite gpi; -#if (LINUX_VERSION_CODE < 0x020301) -static struct wait_queue *iic_wait = NULL; -#else static wait_queue_head_t iic_wait; -#endif static int iic_pending; /* ----- global defines ----------------------------------------------- */ @@ -271,9 +266,6 @@ piic->iic_own = own; iic_ite_data.data = (void *)piic; -#if (LINUX_VERSION_CODE >= 0x020301) - init_waitqueue_head(&iic_wait); -#endif if (iic_hw_resrc_init() == 0) { if (i2c_iic_add_bus(&iic_ite_ops) < 0) return -ENODEV; diff -urN linux-2.4.24/drivers/i2c/i2c-algo-bit.c linux-2.4.25/drivers/i2c/i2c-algo-bit.c --- linux-2.4.24/drivers/i2c/i2c-algo-bit.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-algo-bit.c 2004-02-18 05:36:31.000000000 -0800 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -123,7 +122,7 @@ if (current->need_resched) schedule(); } - DEBSTAT(printk("needed %ld jiffies\n", jiffies-start)); + DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); #ifdef SLO_IO SLO_IO #endif @@ -179,12 +178,12 @@ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ - DEB2(printk(" i2c_outb:%2.2X\n",c&0xff)); + DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff)); for ( i=7 ; i>=0 ; i-- ) { sb = c & ( 1 << i ); setsda(adap,sb); udelay(adap->udelay); - DEBPROTO(printk("%d",sb!=0)); + DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); if (sclhi(adap)<0) { /* timed out */ sdahi(adap); /* we don't want to block the net */ return -ETIMEDOUT; @@ -201,10 +200,10 @@ }; /* read ack: SDA should be pulled down by slave */ ack=getsda(adap); /* ack: sda is pulled low ->success. */ - DEB2(printk(" i2c_outb: getsda() = 0x%2.2x\n", ~ack )); + DEB2(printk(KERN_DEBUG " i2c_outb: getsda() = 0x%2.2x\n", ~ack )); - DEBPROTO( printk("[%2.2x]",c&0xff) ); - DEBPROTO(if (0==ack){ printk(" A ");} else printk(" NA ") ); + DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); + DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); scllo(adap); return 0==ack; /* return 1 if device acked */ /* assert: scl is low (sda undef) */ @@ -220,7 +219,7 @@ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ - DEB2(printk("i2c_inb.\n")); + DEB2(printk(KERN_DEBUG "i2c_inb.\n")); sdahi(adap); for (i=0;i<8;i++) { @@ -233,7 +232,7 @@ scllo(adap); } /* assert: scl is low */ - DEBPROTO(printk(" %2.2x", indata & 0xff)); + DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff)); return (int) (indata & 0xff); } @@ -341,7 +340,7 @@ i2c_start(adap); udelay(adap->udelay); } - DEB2(if (i) printk("i2c-algo-bit.o: needed %d retries for %d\n", + DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n", i,addr)); return ret; } @@ -356,7 +355,7 @@ while (count > 0) { c = *temp; - DEB2(printk("i2c-algo-bit.o: %s i2c_write: writing %2.2X\n", + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n", i2c_adap->name, c&0xff)); retval = i2c_outb(i2c_adap,c); if (retval>0) { @@ -364,7 +363,7 @@ temp++; wrcount++; } else { /* arbitration or no acknowledge */ - printk("i2c-algo-bit.o: %s i2c_write: error - bailout.\n", + printk(KERN_ERR "i2c-algo-bit.o: %s sendbytes: error - bailout.\n", i2c_adap->name); i2c_stop(adap); return (retval<0)? retval : -EFAULT; @@ -392,7 +391,7 @@ *temp = inval; rdcount++; } else { /* read timed out */ - printk("i2c-algo-bit.o: i2c_read: i2c_inb timed out.\n"); + printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n"); break; } @@ -405,7 +404,7 @@ } if (sclhi(adap)<0) { /* timeout */ sdahi(adap); - printk("i2c-algo-bit.o: i2c_read: Timeout at ack\n"); + printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); return -ETIMEDOUT; }; scllo(adap); @@ -435,18 +434,18 @@ if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - DEB2(printk("addr0: %d\n",addr)); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ ret = i2c_outb(i2c_adap,msg->addr & 0x7f); if (ret != 1) { /* the chip did not ack / xmission error occurred */ - printk("died at 2nd address code.\n"); + printk(KERN_ERR "died at 2nd address code.\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { @@ -455,7 +454,7 @@ addr |= 0x01; ret = try_address(i2c_adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } } @@ -490,22 +489,22 @@ } ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries); if (ret != 0) { - DEB2(printk("i2c-algo-bit.o: NAK from device adr %#2x msg #%d\n" - ,msgs[i].addr,i)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n", + msgs[i].addr,i)); return (ret<0) ? ret : -EREMOTEIO; } } if (pmsg->flags & I2C_M_RD ) { /* read bytes into buffer*/ ret = readbytes(i2c_adap,pmsg->buf,pmsg->len); - DEB2(printk("i2c-algo-bit.o: read %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); if (ret < pmsg->len ) { return (ret<0)? ret : -EREMOTEIO; } } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len); - DEB2(printk("i2c-algo-bit.o: wrote %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); if (ret < pmsg->len ) { return (ret<0) ? ret : -EREMOTEIO; } @@ -555,7 +554,7 @@ return -ENODEV; } - DEB2(printk("i2c-algo-bit.o: hw routines for %s registered.\n", + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: hw routines for %s registered.\n", adap->name)); /* register new adapter to i2c module... */ diff -urN linux-2.4.24/drivers/i2c/i2c-algo-ite.c linux-2.4.25/drivers/i2c/i2c-algo-ite.c --- linux-2.4.24/drivers/i2c/i2c-algo-ite.c 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-algo-ite.c 2004-02-18 05:36:31.000000000 -0800 @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff -urN linux-2.4.24/drivers/i2c/i2c-algo-pcf.c linux-2.4.25/drivers/i2c/i2c-algo-pcf.c --- linux-2.4.24/drivers/i2c/i2c-algo-pcf.c 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-algo-pcf.c 2004-02-18 05:36:31.000000000 -0800 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +98,7 @@ } #endif if (timeout <= 0) { - printk("Timeout waiting for Bus Busy\n"); + printk(KERN_ERR "Timeout waiting for Bus Busy\n"); } return (timeout<=0); @@ -144,7 +143,7 @@ { unsigned char temp; - DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); @@ -152,7 +151,7 @@ PCF8584 does that when ESO is zero */ /* PCF also resets PIN bit */ if ((temp = get_pcf(adap, 1)) != (0)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* definetly not PCF8584 */ } @@ -160,7 +159,7 @@ i2c_outb(adap, get_own(adap)); /* check it's realy writen */ if ((temp = i2c_inb(adap)) != get_own(adap)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); return -ENXIO; } @@ -168,7 +167,7 @@ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); return -ENXIO; } @@ -176,7 +175,7 @@ i2c_outb(adap, get_clock(adap)); /* check it's realy writen, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); return -ENXIO; } @@ -185,11 +184,11 @@ /* check to see PCF is realy idled and we can access status register */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { - DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } - printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n"); + printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n"); return 0; } @@ -215,7 +214,7 @@ i2c_stop(adap); udelay(adap->udelay); } - DEB2(if (i) printk("i2c-algo-pcf.o: needed %d retries for %d\n",i, + DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i, addr)); return ret; } @@ -228,20 +227,20 @@ int wrcount, status, timeout; for (wrcount=0; wrcountname, buf[wrcount]&0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { i2c_stop(adap); - printk("i2c-algo-pcf.o: %s i2c_write: " + printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: " "error - timeout.\n", i2c_adap->name); return -EREMOTEIO; /* got a better one ?? */ } #ifndef STUB_I2C if (status & I2C_PCF_LRB) { i2c_stop(adap); - printk("i2c-algo-pcf.o: %s i2c_write: " + printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: " "error - no ack.\n", i2c_adap->name); return -EREMOTEIO; /* got a better one ?? */ } @@ -269,14 +268,14 @@ if (wait_for_pin(adap, &status)) { i2c_stop(adap); - printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n"); + printk(KERN_ERR "i2c-algo-pcf.o: pcf_readbytes timed out.\n"); return (-1); } #ifndef STUB_I2C if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); - printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n"); + printk(KERN_ERR "i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n"); return (-1); } #endif @@ -312,18 +311,18 @@ if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - DEB2(printk("addr0: %d\n",addr)); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); /* try extended address code...*/ ret = try_address(adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ i2c_outb(adap,msg->addr & 0x7f); /* Status check comes here */ if (ret != 1) { - printk("died at 2nd address code.\n"); + printk(KERN_ERR "died at 2nd address code.\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { @@ -332,7 +331,7 @@ addr |= 0x01; ret = try_address(adap, addr, retries); if (ret!=1) { - printk("died at extended address code.\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } } @@ -360,7 +359,7 @@ /* Check for bus busy */ timeout = wait_for_bb(adap); if (timeout) { - DEB2(printk("i2c-algo-pcf.o: " + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " "Timeout waiting for BB in pcf_xfer\n");) return -EIO; } @@ -368,7 +367,7 @@ for (i = 0;ret >= 0 && i < num; i++) { pmsg = &msgs[i]; - DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", pmsg->flags & I2C_M_RD ? "read" : "write", pmsg->len, pmsg->addr, i + 1, num);) @@ -383,7 +382,7 @@ timeout = wait_for_pin(adap, &status); if (timeout) { i2c_stop(adap); - DEB2(printk("i2c-algo-pcf.o: Timeout waiting " + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " "for PIN(1) in pcf_xfer\n");) return (-EREMOTEIO); } @@ -392,12 +391,12 @@ /* Check LRB (last rcvd bit - slave ack) */ if (status & I2C_PCF_LRB) { i2c_stop(adap); - DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) return (-EREMOTEIO); } #endif - DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", i, msgs[i].addr, msgs[i].flags, msgs[i].len);) /* Read */ @@ -407,20 +406,20 @@ (i + 1 == num)); if (ret != pmsg->len) { - DEB2(printk("i2c-algo-pcf.o: fail: " + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only read %d bytes.\n",ret)); } else { - DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); } } else { /* Write */ ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i + 1 == num)); if (ret != pmsg->len) { - DEB2(printk("i2c-algo-pcf.o: fail: " + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only wrote %d bytes.\n",ret)); } else { - DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret)); + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret)); } } } @@ -461,7 +460,7 @@ int i, status; struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; - DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n", + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n", adap->name)); /* register new adapter to i2c module... */ diff -urN linux-2.4.24/drivers/i2c/i2c-algo-sgi.c linux-2.4.25/drivers/i2c/i2c-algo-sgi.c --- linux-2.4.24/drivers/i2c/i2c-algo-sgi.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/i2c/i2c-algo-sgi.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,189 @@ +/* + * i2c-algo-sgi.c: i2c driver algorithms for SGI adapters. + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * Copyright (C) 2003 Ladislav Michl + */ + +#include +#include +#include +#include +#include + +#include +#include + + +#define SGI_I2C_FORCE_IDLE (0 << 0) +#define SGI_I2C_NOT_IDLE (1 << 0) +#define SGI_I2C_WRITE (0 << 1) +#define SGI_I2C_READ (1 << 1) +#define SGI_I2C_RELEASE_BUS (0 << 2) +#define SGI_I2C_HOLD_BUS (1 << 2) +#define SGI_I2C_XFER_DONE (0 << 4) +#define SGI_I2C_XFER_BUSY (1 << 4) +#define SGI_I2C_ACK (0 << 5) +#define SGI_I2C_NACK (1 << 5) +#define SGI_I2C_BUS_OK (0 << 7) +#define SGI_I2C_BUS_ERR (1 << 7) + +#define get_control() adap->getctrl(adap->data) +#define set_control(val) adap->setctrl(adap->data, val) +#define read_data() adap->rdata(adap->data) +#define write_data(val) adap->wdata(adap->data, val) + + +static int wait_xfer_done(struct i2c_algo_sgi_data *adap) +{ + int i; + + for (i = 0; i < adap->xfer_timeout; i++) { + if ((get_control() & SGI_I2C_XFER_BUSY) == 0) + return 0; + udelay(1); + } + + return -ETIMEDOUT; +} + +static int wait_ack(struct i2c_algo_sgi_data *adap) +{ + int i; + + if (wait_xfer_done(adap)) + return -ETIMEDOUT; + for (i = 0; i < adap->ack_timeout; i++) { + if ((get_control() & SGI_I2C_NACK) == 0) + return 0; + udelay(1); + } + + return -ETIMEDOUT; +} + +static int force_idle(struct i2c_algo_sgi_data *adap) +{ + int i; + + set_control(SGI_I2C_FORCE_IDLE); + for (i = 0; i < adap->xfer_timeout; i++) { + if ((get_control() & SGI_I2C_NOT_IDLE) == 0) + goto out; + udelay(1); + } + return -ETIMEDOUT; +out: + if (get_control() & SGI_I2C_BUS_ERR) + return -EIO; + return 0; +} + +static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr, + int rd) +{ + if (rd) + set_control(SGI_I2C_NOT_IDLE); + /* Check if bus is idle, eventually force it to do so */ + if (get_control() & SGI_I2C_NOT_IDLE) + if (force_idle(adap)) + return -EIO; + /* Write out the i2c chip address and specify operation */ + set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE); + if (rd) + addr |= 1; + write_data(addr); + if (wait_ack(adap)) + return -EIO; + return 0; +} + +static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf, + unsigned int len) +{ + int i; + + set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE); + for (i = 0; i < len; i++) { + if (wait_xfer_done(adap)) + return -EIO; + buf[i] = read_data(); + } + set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE); + + return 0; + +} + +static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf, + unsigned int len) +{ + int i; + + /* We are already in write state */ + for (i = 0; i < len; i++) { + write_data(buf[i]); + if (wait_ack(adap)) + return -EIO; + } + return 0; +} + +static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], + int num) +{ + struct i2c_algo_sgi_data *adap = i2c_adap->algo_data; + struct i2c_msg *p; + int i, err = 0; + + for (i = 0; !err && i < num; i++) { + p = &msgs[i]; + err = do_address(adap, p->addr, p->flags & I2C_M_RD); + if (err || !p->len) + continue; + if (p->flags & I2C_M_RD) + err = i2c_read(adap, p->buf, p->len); + else + err = i2c_write(adap, p->buf, p->len); + } + + return err; +} + +static u32 sgi_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm sgi_algo = { + .name = "SGI algorithm", + .id = I2C_ALGO_SGI, + .master_xfer = sgi_xfer, + .functionality = sgi_func, +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_sgi_add_bus(struct i2c_adapter *adap) +{ + adap->id |= sgi_algo.id; + adap->algo = &sgi_algo; + + return i2c_add_adapter(adap); +} + + +int i2c_sgi_del_bus(struct i2c_adapter *adap) +{ + return i2c_del_adapter(adap); +} + +EXPORT_SYMBOL(i2c_sgi_add_bus); +EXPORT_SYMBOL(i2c_sgi_del_bus); + +MODULE_AUTHOR("Ladislav Michl "); +MODULE_DESCRIPTION("I2C-Bus SGI algorithm"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/i2c/i2c-core.c linux-2.4.25/drivers/i2c/i2c-core.c --- linux-2.4.24/drivers/i2c/i2c-core.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-core.c 2004-02-18 05:36:31.000000000 -0800 @@ -33,13 +33,8 @@ /* ----- compatibility stuff ----------------------------------------------- */ -#include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) -#define init_MUTEX(s) do { *(s) = MUTEX; } while(0) -#endif - #include /* ----- global defines ---------------------------------------------------- */ @@ -84,10 +79,6 @@ static int i2cproc_init(void); static int i2cproc_cleanup(void); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27)) -static void monitor_bus_i2c(struct inode *inode, int fill); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ - static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, loff_t *ppos); static int read_bus_i2c(char *buf, char **start, off_t offset, int len, @@ -99,12 +90,6 @@ read: i2cproc_bus_read, }; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) -static struct inode_operations i2cproc_inode_operations = { - &i2cproc_operations -}; -#endif - static int i2cproc_initialized = 0; #else /* undef CONFIG_PROC_FS */ @@ -164,16 +149,8 @@ goto ERROR1; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48)) proc_entry->proc_fops = &i2cproc_operations; -#else - proc_entry->ops = &i2cproc_inode_operations; -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) proc_entry->owner = THIS_MODULE; -#else - proc_entry->fill_inode = &monitor_bus_i2c; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ adap->inode = proc_entry->low_ino; } @@ -188,7 +165,7 @@ drivers[j]->attach_adapter(adap); DRV_UNLOCK(); - DEB(printk("i2c-core.o: adapter %s registered as adapter %d.\n", + DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n", adap->name,i)); return 0; @@ -214,7 +191,7 @@ if (adap == adapters[i]) break; if (I2C_ADAP_MAX == i) { - printk( "i2c-core.o: unregister_adapter adap [%s] not found.\n", + printk(KERN_WARNING "i2c-core.o: unregister_adapter adap [%s] not found.\n", adap->name); res = -ENODEV; goto ERROR0; @@ -229,7 +206,7 @@ for (j = 0; j < I2C_DRIVER_MAX; j++) if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY)) if ((res = drivers[j]->attach_adapter(adap))) { - printk("i2c-core.o: can't detach adapter %s " + printk(KERN_WARNING "i2c-core.o: can't detach adapter %s " "while detaching driver %s: driver not " "detached!",adap->name,drivers[j]->name); goto ERROR1; @@ -247,7 +224,7 @@ * must be deleted, as this would cause invalid states. */ if ((res=client->driver->detach_client(client))) { - printk("i2c-core.o: adapter %s not " + printk(KERN_ERR "i2c-core.o: adapter %s not " "unregistered, because client at " "address %02x can't be detached. ", adap->name, client->addr); @@ -266,7 +243,7 @@ adap_count--; ADAP_UNLOCK(); - DEB(printk("i2c-core.o: adapter unregistered: %s\n",adap->name)); + DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name)); return 0; ERROR0: @@ -305,7 +282,7 @@ DRV_UNLOCK(); /* driver was successfully added */ - DEB(printk("i2c-core.o: driver %s registered.\n",driver->name)); + DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name)); ADAP_LOCK(); @@ -340,7 +317,7 @@ * attached. If so, detach them to be able to kill the driver * afterwards. */ - DEB2(printk("i2c-core.o: unregister_driver - looking for clients.\n")); + DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n")); /* removing clients does not depend on the notify flag, else * invalid operation might (will!) result, when using stale client * pointers. @@ -350,7 +327,7 @@ struct i2c_adapter *adap = adapters[k]; if (adap == NULL) /* skip empty entries. */ continue; - DEB2(printk("i2c-core.o: examining adapter %s:\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: examining adapter %s:\n", adap->name)); if (driver->flags & I2C_DF_DUMMY) { /* DUMMY drivers do not register their clients, so we have to @@ -359,7 +336,7 @@ * this or hell will break loose... */ if ((res = driver->attach_adapter(adap))) { - printk("i2c-core.o: while unregistering " + printk(KERN_WARNING "i2c-core.o: while unregistering " "dummy driver %s, adapter %s could " "not be detached properly; driver " "not unloaded!",driver->name, @@ -372,13 +349,13 @@ struct i2c_client *client = adap->clients[j]; if (client != NULL && client->driver == driver) { - DEB2(printk("i2c-core.o: " + DEB2(printk(KERN_DEBUG "i2c-core.o: " "detaching client %s:\n", client->name)); if ((res = driver-> detach_client(client))) { - printk("i2c-core.o: while " + printk(KERN_ERR "i2c-core.o: while " "unregistering driver " "`%s', the client at " "address %02x of " @@ -400,7 +377,7 @@ driver_count--; DRV_UNLOCK(); - DEB(printk("i2c-core.o: driver unregistered: %s\n",driver->name)); + DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name)); return 0; } @@ -436,10 +413,10 @@ if (adapter->client_register) if (adapter->client_register(client)) - printk("i2c-core.o: warning: client_register seems " + printk(KERN_DEBUG "i2c-core.o: warning: client_register seems " "to have failed for client %02x at adapter %s\n", client->addr,adapter->name); - DEB(printk("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", + DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", client->name, adapter->name,i)); if(client->flags & I2C_CLIENT_ALLOW_USE) @@ -470,7 +447,7 @@ if (adapter->client_unregister != NULL) if ((res = adapter->client_unregister(client))) { - printk("i2c-core.o: client_unregister [%s] failed, " + printk(KERN_ERR "i2c-core.o: client_unregister [%s] failed, " "client not detached",client->name); return res; } @@ -478,7 +455,7 @@ adapter->clients[i] = NULL; adapter->client_count--; - DEB(printk("i2c-core.o: client [%s] unregistered.\n",client->name)); + DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] unregistered.\n",client->name)); return 0; } @@ -611,18 +588,6 @@ #ifdef CONFIG_PROC_FS -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,27)) -/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc impossible - if some process still uses it or some file in it */ -void monitor_bus_i2c(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} -#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,37)) */ - /* This function generates the output for /proc/bus/i2c */ int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, void *private) @@ -727,16 +692,12 @@ } proc_bus_i2c = create_proc_entry("i2c",0,proc_bus); if (!proc_bus_i2c) { - printk("i2c-core.o: Could not create /proc/bus/i2c"); + printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c"); i2cproc_cleanup(); return -ENOENT; } proc_bus_i2c->read_proc = &read_bus_i2c; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) proc_bus_i2c->owner = THIS_MODULE; -#else - proc_bus_i2c->fill_inode = &monitor_bus_i2c; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */ i2cproc_initialized += 2; return 0; } @@ -764,7 +725,7 @@ int ret; if (adap->algo->master_xfer) { - DEB2(printk("i2c-core.o: master_xfer: %s with %d msgs.\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_xfer: %s with %d msgs.\n", adap->name,num)); I2C_LOCK(adap); @@ -773,7 +734,7 @@ return ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", adap->id); return -ENOSYS; } @@ -791,7 +752,7 @@ msg.len = count; (const char *)msg.buf = buf; - DEB2(printk("i2c-core.o: master_send: writing %d bytes on %s.\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n", count,client->adapter->name)); I2C_LOCK(adap); @@ -803,7 +764,7 @@ */ return (ret == 1 )? count : ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", client->adapter->id); return -ENOSYS; } @@ -821,14 +782,14 @@ msg.len = count; msg.buf = buf; - DEB2(printk("i2c-core.o: master_recv: reading %d bytes on %s.\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n", count,client->adapter->name)); I2C_LOCK(adap); ret = adap->algo->master_xfer(adap,&msg,1); I2C_UNLOCK(adap); - DEB2(printk("i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", ret, count, client->addr)); /* if everything went ok (i.e. 1 msg transmitted), return #bytes @@ -836,7 +797,7 @@ */ return (ret == 1 )? count : ret; } else { - printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", + printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", client->adapter->id); return -ENOSYS; } @@ -849,7 +810,7 @@ int ret = 0; struct i2c_adapter *adap = client->adapter; - DEB2(printk("i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg)); + DEB2(printk(KERN_DEBUG "i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg)); switch ( cmd ) { case I2C_RETRIES: adap->retries = arg; @@ -894,7 +855,7 @@ if (((adap_id == address_data->force[i]) || (address_data->force[i] == ANY_I2C_BUS)) && (addr == address_data->force[i+1])) { - DEB2(printk("i2c-core.o: found force parameter for adapter %d, addr %04x\n", + DEB2(printk(KERN_DEBUG "i2c-core.o: found force parameter for adapter %d, addr %04x\n", adap_id,addr)); if ((err = found_proc(adapter,addr,0,0))) return err; @@ -912,7 +873,7 @@ if (((adap_id == address_data->ignore[i]) || ((address_data->ignore[i] == ANY_I2C_BUS))) && (addr == address_data->ignore[i+1])) { - DEB2(printk("i2c-core.o: found ignore parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore parameter for adapter %d, " "addr %04x\n", adap_id ,addr)); found = 1; } @@ -924,7 +885,7 @@ ((address_data->ignore_range[i]==ANY_I2C_BUS))) && (addr >= address_data->ignore_range[i+1]) && (addr <= address_data->ignore_range[i+2])) { - DEB2(printk("i2c-core.o: found ignore_range parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adap_id,addr)); found = 1; } @@ -939,7 +900,7 @@ i += 1) { if (addr == address_data->normal_i2c[i]) { found = 1; - DEB2(printk("i2c-core.o: found normal i2c entry for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c entry for adapter %d, " "addr %02x", adap_id,addr)); } } @@ -950,7 +911,7 @@ if ((addr >= address_data->normal_i2c_range[i]) && (addr <= address_data->normal_i2c_range[i+1])) { found = 1; - DEB2(printk("i2c-core.o: found normal i2c_range entry for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adap_id,addr)); } } @@ -962,7 +923,7 @@ ((address_data->probe[i] == ANY_I2C_BUS))) && (addr == address_data->probe[i+1])) { found = 1; - DEB2(printk("i2c-core.o: found probe parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found probe parameter for adapter %d, " "addr %04x\n", adap_id,addr)); } } @@ -974,7 +935,7 @@ (addr >= address_data->probe_range[i+1]) && (addr <= address_data->probe_range[i+2])) { found = 1; - DEB2(printk("i2c-core.o: found probe_range parameter for adapter %d, " + DEB2(printk(KERN_DEBUG "i2c-core.o: found probe_range parameter for adapter %d, " "addr %04x\n", adap_id,addr)); } } @@ -1101,8 +1062,8 @@ { union i2c_smbus_data data; int i; - if (length > 32) - length = 32; + if (length > I2C_SMBUS_BLOCK_MAX) + length = I2C_SMBUS_BLOCK_MAX; for (i = 1; i <= length; i++) data.block[i] = values[i-1]; data.block[0] = length; @@ -1116,8 +1077,8 @@ { union i2c_smbus_data data; int i; - if (length > 32) - length = 32; + if (length > I2C_SMBUS_I2C_BLOCK_MAX) + length = I2C_SMBUS_I2C_BLOCK_MAX; for (i = 1; i <= length; i++) data.block[i] = values[i-1]; data.block[0] = length; @@ -1186,15 +1147,15 @@ break; case I2C_SMBUS_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) { - printk("i2c-core.o: Block read not supported under " - "I2C emulation!\n"); - return -1; + printk(KERN_ERR "i2c-core.o: Block read not supported " + "under I2C emulation!\n"); + return -1; } else { msg[0].len = data->block[0] + 2; - if (msg[0].len > 34) { - printk("i2c-core.o: smbus_access called with " + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { + printk(KERN_ERR "i2c-core.o: smbus_access called with " "invalid block write size (%d)\n", - msg[0].len); + data->block[0]); return -1; } for (i = 1; i <= msg[0].len; i++) @@ -1202,7 +1163,7 @@ } break; default: - printk("i2c-core.o: smbus_access called with invalid size (%d)\n", + printk(KERN_ERR "i2c-core.o: smbus_access called with invalid size (%d)\n", size); return -1; } @@ -1264,7 +1225,7 @@ static int __init i2c_init(void) { - printk(KERN_INFO "i2c-core.o: i2c core module\n"); + printk(KERN_INFO "i2c-core.o: i2c core module version %s (%s)\n", I2C_VERSION, I2C_DATE); memset(adapters,0,sizeof(adapters)); memset(drivers,0,sizeof(drivers)); adap_count=0; @@ -1427,9 +1388,10 @@ #ifdef MODULE MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus main module"); +MODULE_LICENSE("GPL"); + MODULE_PARM(i2c_debug, "i"); MODULE_PARM_DESC(i2c_debug,"debug level"); -MODULE_LICENSE("GPL"); int init_module(void) { diff -urN linux-2.4.24/drivers/i2c/i2c-dev.c linux-2.4.25/drivers/i2c/i2c-dev.c --- linux-2.4.24/drivers/i2c/i2c-dev.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-dev.c 2004-02-18 05:36:31.000000000 -0800 @@ -35,10 +35,7 @@ #include #include #include -#include -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) #include -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ #ifdef CONFIG_DEVFS_FS #include #endif @@ -60,9 +57,6 @@ /* struct file_operations changed too often in the 2.1 series for nice code */ -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) -static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin); -#endif static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset); static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, @@ -88,14 +82,8 @@ static int i2cdev_cleanup(void); static struct file_operations i2cdev_fops = { -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) owner: THIS_MODULE, -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) - llseek: i2cdev_lseek, -#else llseek: no_llseek, -#endif read: i2cdev_read, write: i2cdev_write, ioctl: i2cdev_ioctl, @@ -133,20 +121,6 @@ static int i2cdev_initialized; -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,9) -/* Note that the lseek function is called llseek in 2.1 kernels. But things - are complicated enough as is. */ -loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin) -{ -#ifdef DEBUG - struct inode *inode = file->f_dentry->d_inode; - printk("i2c-dev.o: i2c-%d lseek to %ld bytes relative to %d.\n", - MINOR(inode->i_rdev),(long) offset,origin); -#endif /* DEBUG */ - return -ESPIPE; -} -#endif - static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset) { @@ -159,16 +133,16 @@ struct i2c_client *client = (struct i2c_client *)file->private_data; - if(count > 8192) + if (count > 8192) count = 8192; - + /* copy user space data to kernel space. */ tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; #ifdef DEBUG - printk("i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), + printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), count); #endif @@ -190,9 +164,9 @@ struct inode *inode = file->f_dentry->d_inode; #endif /* DEBUG */ - if(count > 8192) + if (count > 8192) count = 8192; - + /* copy user space data to kernel space. */ tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) @@ -203,7 +177,7 @@ } #ifdef DEBUG - printk("i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), + printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), count); #endif ret = i2c_master_send(client,tmp,count); @@ -224,7 +198,7 @@ unsigned long funcs; #ifdef DEBUG - printk("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", + printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", MINOR(inode->i_rdev),cmd, arg); #endif /* DEBUG */ @@ -346,7 +320,7 @@ (data_arg.size != I2C_SMBUS_BLOCK_DATA) && (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) { #ifdef DEBUG - printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", + printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.size); #endif return -EINVAL; @@ -356,7 +330,7 @@ if ((data_arg.read_write != I2C_SMBUS_READ) && (data_arg.read_write != I2C_SMBUS_WRITE)) { #ifdef DEBUG - printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", + printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", data_arg.read_write); #endif return -EINVAL; @@ -376,7 +350,7 @@ if (data_arg.data == NULL) { #ifdef DEBUG - printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); + printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); #endif return -EINVAL; } @@ -418,7 +392,7 @@ if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) { #ifdef DEBUG - printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n", + printk(KERN_DEBUG "i2c-dev.o: Trying to open unattached adapter i2c-%d\n", minor); #endif return -ENODEV; @@ -434,12 +408,9 @@ if (i2cdev_adaps[minor]->inc_use) i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) - MOD_INC_USE_COUNT; -#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */ #ifdef DEBUG - printk("i2c-dev.o: opened i2c-%d\n",minor); + printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor); #endif return 0; } @@ -450,18 +421,12 @@ kfree(file->private_data); file->private_data=NULL; #ifdef DEBUG - printk("i2c-dev.o: Closed: i2c-%d\n", minor); + printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor); #endif -#if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) - MOD_DEC_USE_COUNT; -#else /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ lock_kernel(); -#endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */ if (i2cdev_adaps[minor]->dec_use) i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); -#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) unlock_kernel(); -#endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */ return 0; } @@ -471,11 +436,11 @@ char name[8]; if ((i = i2c_adapter_id(adap)) < 0) { - printk("i2c-dev.o: Unknown adapter ?!?\n"); + printk(KERN_DEBUG "i2c-dev.o: Unknown adapter ?!?\n"); return -ENODEV; } if (i >= I2CDEV_ADAPS_MAX) { - printk("i2c-dev.o: Adapter number too large?!? (%d)\n",i); + printk(KERN_DEBUG "i2c-dev.o: Adapter number too large?!? (%d)\n",i); return -ENODEV; } @@ -488,7 +453,7 @@ S_IFCHR | S_IRUSR | S_IWUSR, &i2cdev_fops, NULL); #endif - printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); + printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); } else { /* This is actually a detach_adapter call! */ #ifdef CONFIG_DEVFS_FS @@ -496,7 +461,7 @@ #endif i2cdev_adaps[i] = NULL; #ifdef DEBUG - printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name); + printk(KERN_DEBUG "i2c-dev.o: Adapter unregistered: %s\n",adap->name); #endif } @@ -518,7 +483,7 @@ { int res; - printk("i2c-dev.o: i2c /dev entries driver module\n"); + printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE); i2cdev_initialized = 0; #ifdef CONFIG_DEVFS_FS @@ -526,7 +491,7 @@ #else if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) { #endif - printk("i2c-dev.o: unable to get major %d for i2c bus\n", + printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n", I2C_MAJOR); return -EIO; } @@ -536,7 +501,7 @@ i2cdev_initialized ++; if ((res = i2c_add_driver(&i2cdev_driver))) { - printk("i2c-dev.o: Driver registration failed, module not inserted.\n"); + printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n"); i2cdev_cleanup(); return res; } diff -urN linux-2.4.24/drivers/i2c/i2c-elektor.c linux-2.4.25/drivers/i2c/i2c-elektor.c --- linux-2.4.24/drivers/i2c/i2c-elektor.c 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-elektor.c 2004-02-18 05:36:31.000000000 -0800 @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -55,11 +54,7 @@ in some functions, called from the algo-pcf module. Sometimes it's need to be rewriten - but for now just remove this for simpler reading */ -#if (LINUX_VERSION_CODE < 0x020301) -static struct wait_queue *pcf_wait = NULL; -#else static wait_queue_head_t pcf_wait; -#endif static int pcf_pending; /* ----- global defines ----------------------------------------------- */ @@ -78,7 +73,7 @@ val |= I2C_PCF_ENI; } - DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255)); switch (mmapped) { case 0: /* regular I/O */ @@ -99,7 +94,7 @@ int address = ctl ? (base + 1) : base; int val = mmapped ? readb(address) : inb(address); - DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); return (val); } @@ -142,7 +137,9 @@ { if (!mmapped) { if (check_region(base, 2) < 0 ) { - printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base); + printk(KERN_ERR + "i2c-elektor.o: requested I/O region (0x%X:2) " + "is in use.\n", base); return -ENODEV; } else { request_region(base, 2, "i2c (isa bus adapter)"); @@ -150,7 +147,7 @@ } if (irq > 0) { if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) { - printk("i2c-elektor.o: Request irq%d failed\n", irq); + printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq); irq = 0; } else enable_irq(irq); @@ -238,7 +235,7 @@ /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { - DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config)); + DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config)); /* UP2000 board has this register set to 0xe1, but the most significant bit as seems can be @@ -260,7 +257,7 @@ 8.25 MHz (PCI/4) clock (this can be read from cypress) */ clock = I2C_PCF_CLK | I2C_PCF_TRNS90; - printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n"); + printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n"); } } } @@ -269,19 +266,17 @@ /* sanity checks for mmapped I/O */ if (mmapped && base < 0xc8000) { - printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); + printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); return -ENODEV; } - printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n"); + printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base == 0) { base = DEFAULT_BASE; } -#if (LINUX_VERSION_CODE >= 0x020301) init_waitqueue_head(&pcf_wait); -#endif if (pcf_isa_init() == 0) { if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) return -ENODEV; @@ -289,7 +284,7 @@ return -ENODEV; } - printk("i2c-elektor.o: found device at %#x.\n", base); + printk(KERN_DEBUG "i2c-elektor.o: found device at %#x.\n", base); return 0; } diff -urN linux-2.4.24/drivers/i2c/i2c-elv.c linux-2.4.25/drivers/i2c/i2c-elv.c --- linux-2.4.24/drivers/i2c/i2c-elv.c 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-elv.c 2004-02-18 05:36:31.000000000 -0800 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -95,14 +94,14 @@ } else { /* test for ELV adap. */ if (inb(base+1) & 0x80) { /* BUSY should be high */ - DEBINIT(printk("i2c-elv.o: Busy was low.\n")); + DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n")); return -ENODEV; } else { outb(0x0c,base+2); /* SLCT auf low */ udelay(400); if ( !(inb(base+1) && 0x10) ) { outb(0x04,base+2); - DEBINIT(printk("i2c-elv.o: Select was high.\n")); + DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n")); return -ENODEV; } } @@ -170,7 +169,7 @@ int __init i2c_bitelv_init(void) { - printk("i2c-elv.o: i2c ELV parallel port adapter module\n"); + printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base==0) { /* probe some values */ base=DEFAULT_BASE; @@ -190,7 +189,7 @@ return -ENODEV; } } - printk("i2c-elv.o: found device at %#x.\n",base); + printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base); return 0; } @@ -202,7 +201,6 @@ MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter"); MODULE_LICENSE("GPL"); - MODULE_PARM(base, "i"); int init_module(void) diff -urN linux-2.4.24/drivers/i2c/i2c-keywest.c linux-2.4.25/drivers/i2c/i2c-keywest.c --- linux-2.4.24/drivers/i2c/i2c-keywest.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/i2c/i2c-keywest.c 2004-02-18 05:36:31.000000000 -0800 @@ -45,7 +45,6 @@ #include #include -#include #include #include #include diff -urN linux-2.4.24/drivers/i2c/i2c-philips-par.c linux-2.4.25/drivers/i2c/i2c-philips-par.c --- linux-2.4.24/drivers/i2c/i2c-philips-par.c 2001-09-30 12:26:05.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-philips-par.c 2004-02-18 05:36:31.000000000 -0800 @@ -190,18 +190,18 @@ struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par), GFP_KERNEL); if (!adapter) { - printk("i2c-philips-par: Unable to malloc.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n"); return; } - printk("i2c-philips-par.o: attaching to %s\n", port->name); + printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name); adapter->pdev = parport_register_device(port, "i2c-philips-par", NULL, NULL, NULL, PARPORT_FLAG_EXCL, NULL); if (!adapter->pdev) { - printk("i2c-philips-par: Unable to register with parport.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n"); return; } @@ -212,13 +212,13 @@ /* reset hardware to sane state */ parport_claim_or_block(adapter->pdev); - bit_lp_setsda(port, 1); - bit_lp_setscl(port, 1); + adapter->bit_lp_data.setsda(port, 1); + adapter->bit_lp_data.setscl(port, 1); parport_release(adapter->pdev); if (i2c_bit_add_bus(&adapter->adapter) < 0) { - printk("i2c-philips-par: Unable to register with I2C.\n"); + printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n"); parport_unregister_device(adapter->pdev); kfree(adapter); return; /* No good */ @@ -250,41 +250,25 @@ } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) static struct parport_driver i2c_driver = { "i2c-philips-par", i2c_parport_attach, i2c_parport_detach, NULL }; -#endif int __init i2c_bitlp_init(void) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,4) - struct parport *port; -#endif - printk("i2c-philips-par.o: i2c Philips parallel port adapter module\n"); + printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) parport_register_driver(&i2c_driver); -#else - for (port = parport_enumerate(); port; port=port->next) - i2c_parport_attach(port); -#endif return 0; } void __exit i2c_bitlp_exit(void) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4) parport_unregister_driver(&i2c_driver); -#else - struct parport *port; - for (port = parport_enumerate(); port; port=port->next) - i2c_parport_detach(port); -#endif } EXPORT_NO_SYMBOLS; diff -urN linux-2.4.24/drivers/i2c/i2c-proc.c linux-2.4.25/drivers/i2c/i2c-proc.c --- linux-2.4.24/drivers/i2c/i2c-proc.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-proc.c 2004-02-18 05:36:31.000000000 -0800 @@ -23,7 +23,6 @@ This driver puts entries in /proc/sys/dev/sensors for each I2C device */ -#include #include #include #include @@ -38,10 +37,6 @@ #include -/* FIXME need i2c versioning */ -#define LM_DATE "20010825" -#define LM_VERSION "2.6.1" - #ifndef THIS_MODULE #define THIS_MODULE NULL #endif @@ -67,10 +62,6 @@ static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX]; static unsigned short i2c_inodes[SENSORS_ENTRY_MAX]; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) -static void i2c_fill_inode(struct inode *inode, int fill); -static void i2c_dir_fill_inode(struct inode *inode, int fill); -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1) */ static ctl_table sysctl_table[] = { {CTL_DEV, "dev", NULL, 0, 0555}, @@ -200,12 +191,7 @@ #endif /* DEBUG */ i2c_inodes[id - 256] = new_header->ctl_table->child->child->de->low_ino; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) new_header->ctl_table->child->child->de->owner = controlling_mod; -#else - new_header->ctl_table->child->child->de->fill_inode = - &i2c_dir_fill_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)) */ return id; } @@ -684,7 +670,7 @@ && (addr == this_force->force[j + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n", + (KERN_DEBUG "i2c-proc.o: found force parameter for adapter %d, addr %04x\n", adapter_id, addr); #endif if ( @@ -714,7 +700,7 @@ && (addr == address_data->ignore[i + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found ignore parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found ignore parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -734,7 +720,7 @@ && (addr <= address_data->ignore_range[i + 2])) { #ifdef DEBUG printk - ("i2c-proc.o: found ignore_range parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -753,7 +739,7 @@ if (addr == address_data->normal_isa[i]) { #ifdef DEBUG printk - ("i2c-proc.o: found normal isa entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal isa entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif @@ -775,7 +761,7 @@ 0)) { #ifdef DEBUG printk - ("i2c-proc.o: found normal isa_range entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal isa_range entry for adapter %d, " "addr %04x", adapter_id, addr); #endif found = 1; @@ -789,7 +775,7 @@ found = 1; #ifdef DEBUG printk - ("i2c-proc.o: found normal i2c entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal i2c entry for adapter %d, " "addr %02x", adapter_id, addr); #endif } @@ -805,7 +791,7 @@ { #ifdef DEBUG printk - ("i2c-proc.o: found normal i2c_range entry for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -822,7 +808,7 @@ && (addr == address_data->probe[i + 1])) { #ifdef DEBUG printk - ("i2c-proc.o: found probe parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found probe parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; @@ -841,7 +827,7 @@ found = 1; #ifdef DEBUG printk - ("i2c-proc.o: found probe_range parameter for adapter %d, " + (KERN_DEBUG "i2c-proc.o: found probe_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif } @@ -862,17 +848,12 @@ int __init sensors_init(void) { - printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE); + printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE); i2c_initialized = 0; if (! (i2c_proc_header = register_sysctl_table(i2c_proc, 0))) return -ENOMEM; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE; -#else - i2c_proc_header->ctl_table->child->de->fill_inode = - &i2c_fill_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)) */ i2c_initialized++; return 0; } diff -urN linux-2.4.24/drivers/i2c/i2c-velleman.c linux-2.4.25/drivers/i2c/i2c-velleman.c --- linux-2.4.24/drivers/i2c/i2c-velleman.c 2001-10-11 08:05:47.000000000 -0700 +++ linux-2.4.25/drivers/i2c/i2c-velleman.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------- */ -/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters */ +/* i2c-velleman.c i2c-hw access for Velleman K8000 adapters */ /* ------------------------------------------------------------------------- */ /* Copyright (C) 1995-96, 2000 Simon G. Vogl @@ -160,7 +160,7 @@ int __init i2c_bitvelle_init(void) { - printk("i2c-velleman.o: i2c Velleman K8000 adapter module\n"); + printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); if (base==0) { /* probe some values */ base=DEFAULT_BASE; @@ -180,7 +180,7 @@ return -ENODEV; } } - printk("i2c-velleman.o: found device at %#x.\n",base); + printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base); return 0; } diff -urN linux-2.4.24/drivers/ide/Config.in linux-2.4.25/drivers/ide/Config.in --- linux-2.4.24/drivers/ide/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ide/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -116,6 +116,9 @@ if [ "$CONFIG_ATARI" = "y" ]; then dep_bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI fi + if [ "$CONFIG_CPCI405" = "y" ]; then + dep_bool ' CPCI-405 IDE interface support' CONFIG_BLK_DEV_CPCI405_IDE $CONFIG_CPCI405 + fi if [ "$CONFIG_MAC" = "y" ]; then dep_bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE $CONFIG_MAC fi @@ -184,41 +187,6 @@ ## dep_mbool CONFIG_BLK_DEV_NTF_DISK $CONFIG_BLK_DEV_IDEDISK ##fi -if [ "$CONFIG_BLK_DEV_4DRIVES" = "y" -o \ - "$CONFIG_BLK_DEV_ALI14XX" != "n" -o \ - "$CONFIG_BLK_DEV_DTC2278" != "n" -o \ - "$CONFIG_BLK_DEV_HT6560B" != "n" -o \ - "$CONFIG_BLK_DEV_PDC4030" != "n" -o \ - "$CONFIG_BLK_DEV_QD65XX" != "n" -o \ - "$CONFIG_BLK_DEV_UMC8672" != "n" -o \ - "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ - "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ - "$CONFIG_BLK_DEV_AMD74XX" = "y" -o \ - "$CONFIG_BLK_DEV_CMD640" = "y" -o \ - "$CONFIG_BLK_DEV_CMD64X" = "y" -o \ - "$CONFIG_BLK_DEV_CS5530" = "y" -o \ - "$CONFIG_BLK_DEV_CY82C693" = "y" -o \ - "$CONFIG_BLK_DEV_HPT34X" = "y" -o \ - "$CONFIG_BLK_DEV_HPT366" = "y" -o \ - "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \ - "$CONFIG_BLK_DEV_IT8172" = "y" -o \ - "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" -o \ - "$CONFIG_BLK_DEV_NFORCE" = "y" -o \ - "$CONFIG_BLK_DEV_OPTI621" = "y" -o \ - "$CONFIG_BLK_DEV_SVWKS" = "y" -o \ - "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ - "$CONFIG_BLK_DEV_PIIX" = "y" -o \ - "$CONFIG_BLK_DEV_SVWKS" = "y" -o \ - "$CONFIG_BLK_DEV_SIIMAGE" = "y" -o \ - "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ - "$CONFIG_BLK_DEV_SL82C105" = "y" -o \ - "$CONFIG_BLK_DEV_SLC90E66" = "y" -o \ - "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDE_MODES y -else - define_bool CONFIG_BLK_DEV_IDE_MODES n -fi - dep_tristate 'Support for IDE Raid controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL dep_tristate ' Support Promise software RAID (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID dep_tristate ' Highpoint 370 software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID diff -urN linux-2.4.24/drivers/ide/ide-iops.c linux-2.4.25/drivers/ide/ide-iops.c --- linux-2.4.24/drivers/ide/ide-iops.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ide/ide-iops.c 2004-02-18 05:36:31.000000000 -0800 @@ -666,6 +666,15 @@ timeout += jiffies; while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { if (time_after(jiffies, timeout)) { + /* + * One last read after the timeout in case + * heavy interrupt load made us not make any + * progress during the timeout.. + */ + stat = hwif->INB(IDE_STATUS_REG); + if (!(stat & BUSY_STAT)) + break; + local_irq_restore(flags); *startstop = DRIVER(drive)->error(drive, "status timeout", stat); return 1; diff -urN linux-2.4.24/drivers/ide/ide-proc.c linux-2.4.25/drivers/ide/ide-proc.c --- linux-2.4.24/drivers/ide/ide-proc.c 2003-08-25 04:44:41.000000000 -0700 +++ linux-2.4.25/drivers/ide/ide-proc.c 2004-02-18 05:36:31.000000000 -0800 @@ -794,7 +794,6 @@ for (d = 0; d < MAX_DRIVES; d++) { ide_drive_t *drive = &hwif->drives[d]; - ide_driver_t *driver = drive->driver; if (!drive->present) continue; @@ -802,13 +801,8 @@ continue; drive->proc = proc_mkdir(drive->name, parent); - if (drive->proc) { + if (drive->proc) ide_add_proc_entries(drive->proc, generic_drive_entries, drive); - if (driver) { - ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); - ide_add_proc_entries(drive->proc, driver->proc, drive); - } - } sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); ent = proc_symlink(drive->name, proc_ide_root, name); if (!ent) return; diff -urN linux-2.4.24/drivers/ide/ide.c linux-2.4.25/drivers/ide/ide.c --- linux-2.4.24/drivers/ide/ide.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ide/ide.c 2004-02-18 05:36:31.000000000 -0800 @@ -2548,6 +2548,12 @@ macide_init(); } #endif /* CONFIG_BLK_DEV_MAC_IDE */ +#ifdef CONFIG_BLK_DEV_CPCI405_IDE + { + extern void cpci405ide_init(void); + cpci405ide_init(); + } +#endif /* CONFIG_BLK_DEV_CPCI405_IDE */ #ifdef CONFIG_BLK_DEV_Q40IDE { extern void q40ide_init(void); @@ -2850,8 +2856,10 @@ drive->revalidate = 1; drive->suspend_reset = 0; #ifdef CONFIG_PROC_FS - ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); - ide_add_proc_entries(drive->proc, driver->proc, drive); + if (drive->driver != &idedefault_driver) { + ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); + ide_add_proc_entries(drive->proc, driver->proc, drive); + } #endif return 0; } diff -urN linux-2.4.24/drivers/ide/legacy/buddha.c linux-2.4.25/drivers/ide/legacy/buddha.c --- linux-2.4.24/drivers/ide/legacy/buddha.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.25/drivers/ide/legacy/buddha.c 2004-02-18 05:36:31.000000000 -0800 @@ -146,6 +146,7 @@ void __init buddha_init(void) { hw_regs_t hw; + ide_hwif_t *hwif; int i, index; struct zorro_dev *z = NULL; @@ -212,8 +213,9 @@ IRQ_AMIGA_PORTS); } - index = ide_register_hw(&hw, NULL); + index = ide_register_hw(&hw, &hwif); if (index != -1) { + hwif->mmio = 2; printk("ide%d: ", index); switch(type) { case BOARD_BUDDHA: diff -urN linux-2.4.24/drivers/ide/legacy/gayle.c linux-2.4.25/drivers/ide/legacy/gayle.c --- linux-2.4.24/drivers/ide/legacy/gayle.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.25/drivers/ide/legacy/gayle.c 2004-02-18 05:36:31.000000000 -0800 @@ -29,7 +29,7 @@ */ #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ -#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 */ +#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ /* * Offsets from one of the above bases @@ -118,9 +118,17 @@ if (!MACH_IS_AMIGA) return; - if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE)) - return; + if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) + goto found; + +#ifdef CONFIG_ZORRO + if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, + NULL)) + goto found; +#endif + return; +found: for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { ide_ioreg_t base, ctrlport, irqport; ide_ack_intr_t *ack_intr; @@ -174,16 +182,5 @@ } } else release_mem_region(res_start, res_n); - -#if 1 /* TESTING */ - if (i == 1) { - volatile u_short *addr = (u_short *)base; - u_short data; - printk("+++ Probing for IDE doubler... "); - *addr = 0xffff; - data = *addr; - printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data); - } -#endif /* TESTING */ } } diff -urN linux-2.4.24/drivers/ide/ppc/Makefile linux-2.4.25/drivers/ide/ppc/Makefile --- linux-2.4.24/drivers/ide/ppc/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/ide/ppc/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -4,6 +4,7 @@ obj-y := obj-m := +obj-$(CONFIG_BLK_DEV_CPCI405_IDE) += cpci405ide.o obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o diff -urN linux-2.4.24/drivers/ide/ppc/cpci405ide.c linux-2.4.25/drivers/ide/ppc/cpci405ide.c --- linux-2.4.24/drivers/ide/ppc/cpci405ide.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/ide/ppc/cpci405ide.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,72 @@ +/* + * linux/drivers/ide/ppc/cpci405ide.c -- CPCI405 IDE Driver + * + * Copyright (C) 2001-2003 Stefan Roese, stefan.roese@esd-electronics.de + * + * This driver was written based on information obtained from the MacOS IDE + * driver binary by Mikael Forselius + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Base of the IDE interface + */ + +#define CPCI405_HD_BASE 0xf0100000 + +/* + * Offsets from the above base (scaling 4) + */ + +#define CPCI405_HD_DATA 0x00 +#define CPCI405_HD_ERROR 0x01 /* see err-bits */ +#define CPCI405_HD_NSECTOR 0x02 /* nr of sectors to read/write */ +#define CPCI405_HD_SECTOR 0x03 /* starting sector */ +#define CPCI405_HD_LCYL 0x04 /* starting cylinder */ +#define CPCI405_HD_HCYL 0x05 /* high byte of starting cyl */ +#define CPCI405_HD_SELECT 0x06 /* 101dhhhh , d=drive, hhhh=head */ +#define CPCI405_HD_STATUS 0x07 /* see status-bits */ +#define CPCI405_HD_CONTROL 0x0e /* control/altstatus */ + +#define CPCI405_IRQ_IDE 0x1f + +static int cpci405ide_offsets[IDE_NR_PORTS] __initdata = { + CPCI405_HD_DATA, CPCI405_HD_ERROR, CPCI405_HD_NSECTOR, CPCI405_HD_SECTOR, + CPCI405_HD_LCYL, CPCI405_HD_HCYL, CPCI405_HD_SELECT, CPCI405_HD_STATUS, + CPCI405_HD_CONTROL +}; + +static void *cpci405_ide_base_mapped; + + +/* + * Probe for a CPCI405 IDE interface + */ + +void __init cpci405ide_init(void) +{ + hw_regs_t hw; + int index = -1; + + cpci405_ide_base_mapped = + ioremap((unsigned long) CPCI405_HD_BASE, 0x200) - _IO_BASE; + ide_setup_ports(&hw, (ide_ioreg_t)cpci405_ide_base_mapped, + cpci405ide_offsets, 0, 0, NULL, CPCI405_IRQ_IDE); + index = ide_register_hw(&hw, NULL); + if (index != -1) + printk("ide%d: CPCI405 IDE interface\n", index); + +} diff -urN linux-2.4.24/drivers/ide/raid/hptraid.c linux-2.4.25/drivers/ide/raid/hptraid.c --- linux-2.4.24/drivers/ide/raid/hptraid.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ide/raid/hptraid.c 2004-02-18 05:36:31.000000000 -0800 @@ -146,7 +146,7 @@ make_request: hptraid01_make_request }; -static __init struct { +static __initdata struct { struct raid_device_operations *op; u_int8_t type; char label[8]; diff -urN linux-2.4.24/drivers/ide/raid/pdcraid.c linux-2.4.25/drivers/ide/raid/pdcraid.c --- linux-2.4.24/drivers/ide/raid/pdcraid.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ide/raid/pdcraid.c 2004-02-18 05:36:31.000000000 -0800 @@ -360,9 +360,13 @@ return 0; if (ideinfo->sect==0) return 0; - lba = (ideinfo->capacity / (ideinfo->head*ideinfo->sect)); - lba = lba * (ideinfo->head*ideinfo->sect); - lba = lba - ideinfo->sect; + if (ideinfo->head!=255) { + lba = (ideinfo->capacity / (ideinfo->head*ideinfo->sect)); + lba = lba * (ideinfo->head*ideinfo->sect); + lba = lba - ideinfo->sect; } + else { + lba = ideinfo->capacity - ideinfo->sect; + } return lba; } diff -urN linux-2.4.24/drivers/ieee1394/csr.c linux-2.4.25/drivers/ieee1394/csr.c --- linux-2.4.24/drivers/ieee1394/csr.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ieee1394/csr.c 2004-02-18 05:36:31.000000000 -0800 @@ -117,7 +117,7 @@ /* Just to keep from rounding low */ csr->expire++; - HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%lu", csr->expire, HZ); + HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%d", csr->expire, HZ); } diff -urN linux-2.4.24/drivers/ieee1394/nodemgr.c linux-2.4.25/drivers/ieee1394/nodemgr.c --- linux-2.4.24/drivers/ieee1394/nodemgr.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/ieee1394/nodemgr.c 2004-02-18 05:36:31.000000000 -0800 @@ -1028,12 +1028,11 @@ ne->nodeid = nodeid; } + ne->generation = generation; + if (ne->busopt.generation != ((busoptions >> 4) & 0xf)) nodemgr_process_config_rom (ne, busoptions); - /* Since that's done, we can declare this record current */ - ne->generation = generation; - list_for_each (lh, &ne->unit_directories) { ud = list_entry (lh, struct unit_directory, node_list); if (ud->driver && ud->driver->update != NULL) diff -urN linux-2.4.24/drivers/input/Config.in linux-2.4.25/drivers/input/Config.in --- linux-2.4.24/drivers/input/Config.in 2001-09-12 15:34:06.000000000 -0700 +++ linux-2.4.25/drivers/input/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -14,5 +14,6 @@ fi dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT +dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT endmenu diff -urN linux-2.4.24/drivers/input/Makefile linux-2.4.25/drivers/input/Makefile --- linux-2.4.24/drivers/input/Makefile 2000-12-29 14:07:22.000000000 -0800 +++ linux-2.4.25/drivers/input/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -24,6 +24,7 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o obj-$(CONFIG_INPUT_JOYDEV) += joydev.o obj-$(CONFIG_INPUT_EVDEV) += evdev.o +obj-$(CONFIG_INPUT_UINPUT) += uinput.o # The global Rules.make. diff -urN linux-2.4.24/drivers/input/keybdev.c linux-2.4.25/drivers/input/keybdev.c --- linux-2.4.24/drivers/input/keybdev.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/input/keybdev.c 2004-02-18 05:36:31.000000000 -0800 @@ -154,16 +154,18 @@ static struct input_handler keybdev_handler; +static unsigned int ledstate = 0xff; + void keybdev_ledfunc(unsigned int led) { struct input_handle *handle; - for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { + ledstate = led; + for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04)); - } } @@ -202,7 +204,12 @@ input_open_device(handle); // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); - kbd_refresh_leds(); + + if (ledstate != 0xff) { + input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01)); + input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02)); + input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04)); + } return handle; } diff -urN linux-2.4.24/drivers/input/uinput.c linux-2.4.25/drivers/input/uinput.c --- linux-2.4.24/drivers/input/uinput.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/input/uinput.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,428 @@ +/* + * User level driver support for input subsystem + * + * Heavily based on evdev.c by Vojtech Pavlik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Aristeu Sergio Rozanski Filho + * + * Changes/Revisions: + * 0.1 20/06/2002 + * - first public version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int uinput_dev_open(struct input_dev *dev) +{ + return 0; +} + +static void uinput_dev_close(struct input_dev *dev) +{ +} + +static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + struct uinput_device *udev; + + udev = (struct uinput_device *)dev->private; + + udev->buff[udev->head].type = type; + udev->buff[udev->head].code = code; + udev->buff[udev->head].value = value; + do_gettimeofday(&udev->buff[udev->head].time); + udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; + + wake_up_interruptible(&udev->waitq); + + return 0; +} + +static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) +{ + return 0; +} + +static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) +{ + return 0; +} + +static int uinput_create_device(struct uinput_device *udev) +{ + if (!udev->dev->name) { + printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); + return -EINVAL; + } + + udev->dev->open = uinput_dev_open; + udev->dev->close = uinput_dev_close; + udev->dev->event = uinput_dev_event; + udev->dev->upload_effect = uinput_dev_upload_effect; + udev->dev->erase_effect = uinput_dev_erase_effect; + udev->dev->private = udev; + + init_waitqueue_head(&(udev->waitq)); + + input_register_device(udev->dev); + + set_bit(UIST_CREATED, &(udev->state)); + + return 0; +} + +static int uinput_destroy_device(struct uinput_device *udev) +{ + if (!test_bit(UIST_CREATED, &(udev->state))) { + printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME); + return -EINVAL; + } + + input_unregister_device(udev->dev); + + clear_bit(UIST_CREATED, &(udev->state)); + + return 0; +} + +static int uinput_open(struct inode *inode, struct file *file) +{ + struct uinput_device *newdev; + struct input_dev *newinput; + + newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL); + if (!newdev) + goto error; + memset(newdev, 0, sizeof(struct uinput_device)); + + newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); + if (!newinput) + goto cleanup; + memset(newinput, 0, sizeof(struct input_dev)); + + newdev->dev = newinput; + + file->private_data = newdev; + + return 0; +cleanup: + kfree(newdev); +error: + return -ENOMEM; +} + +static int uinput_validate_absbits(struct input_dev *dev) +{ + unsigned int cnt; + int retval = 0; + + for (cnt = 0; cnt < ABS_MAX; cnt++) { + if (!test_bit(cnt, dev->absbit)) + continue; + + if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */ + (dev->absmax[cnt] <= dev->absmin[cnt])) { + printk(KERN_DEBUG + "%s: invalid abs[%02x] min:%d max:%d\n", + UINPUT_NAME, cnt, + dev->absmin[cnt], dev->absmax[cnt]); + retval = -EINVAL; + break; + } + + if ((dev->absflat[cnt] < dev->absmin[cnt]) || + (dev->absflat[cnt] > dev->absmax[cnt])) { + printk(KERN_DEBUG + "%s: absflat[%02x] out of range: %d " + "(min:%d/max:%d)\n", + UINPUT_NAME, cnt, dev->absflat[cnt], + dev->absmin[cnt], dev->absmax[cnt]); + retval = -EINVAL; + break; + } + } + return retval; +} + +static int uinput_alloc_device(struct file *file, const char *buffer, size_t count) +{ + struct uinput_user_dev *user_dev; + struct input_dev *dev; + struct uinput_device *udev; + int size, + retval; + + retval = count; + + udev = (struct uinput_device *)file->private_data; + dev = udev->dev; + + user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL); + if (!user_dev) { + retval = -ENOMEM; + goto exit; + } + + if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) { + retval = -EFAULT; + goto exit; + } + + if (NULL != dev->name) + kfree(dev->name); + + size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; + dev->name = kmalloc(size, GFP_KERNEL); + if (!dev->name) { + retval = -ENOMEM; + goto exit; + } + + strncpy(dev->name, user_dev->name, size); + dev->idbus = user_dev->idbus; + dev->idvendor = user_dev->idvendor; + dev->idproduct = user_dev->idproduct; + dev->idversion = user_dev->idversion; + dev->ff_effects_max = user_dev->ff_effects_max; + + size = sizeof(int) * (ABS_MAX + 1); + memcpy(dev->absmax, user_dev->absmax, size); + memcpy(dev->absmin, user_dev->absmin, size); + memcpy(dev->absfuzz, user_dev->absfuzz, size); + memcpy(dev->absflat, user_dev->absflat, size); + + /* check if absmin/absmax/absfuzz/absflat are filled as + * told in Documentation/input/input-programming.txt */ + if (test_bit(EV_ABS, dev->evbit)) { + retval = uinput_validate_absbits(dev); + if (retval < 0) + kfree(dev->name); + } + +exit: + kfree(user_dev); + return retval; +} + +static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + struct uinput_device *udev = file->private_data; + + if (test_bit(UIST_CREATED, &(udev->state))) { + struct input_event ev; + + if (copy_from_user(&ev, buffer, sizeof(struct input_event))) + return -EFAULT; + input_event(udev->dev, ev.type, ev.code, ev.value); + } + else + count = uinput_alloc_device(file, buffer, count); + + return count; +} + +static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + struct uinput_device *udev = file->private_data; + int retval = 0; + + if (!test_bit(UIST_CREATED, &(udev->state))) + return -ENODEV; + + if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK)) + return -EAGAIN; + + retval = wait_event_interruptible(udev->waitq, + (udev->head != udev->tail) || + !test_bit(UIST_CREATED, &(udev->state))); + + if (retval) + return retval; + + if (!test_bit(UIST_CREATED, &(udev->state))) + return -ENODEV; + + while ((udev->head != udev->tail) && + (retval + sizeof(struct input_event) <= count)) { + if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), + sizeof(struct input_event))) return -EFAULT; + udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; + retval += sizeof(struct input_event); + } + + return retval; +} + +static unsigned int uinput_poll(struct file *file, poll_table *wait) +{ + struct uinput_device *udev = file->private_data; + + poll_wait(file, &udev->waitq, wait); + + if (udev->head != udev->tail) + return POLLIN | POLLRDNORM; + + return 0; +} + +static int uinput_burn_device(struct uinput_device *udev) +{ + if (test_bit(UIST_CREATED, &(udev->state))) + uinput_destroy_device(udev); + + kfree(udev->dev); + kfree(udev); + + return 0; +} + +static int uinput_close(struct inode *inode, struct file *file) +{ + return uinput_burn_device((struct uinput_device *)file->private_data); +} + +static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + struct uinput_device *udev; + + udev = (struct uinput_device *)file->private_data; + + /* device attributes can not be changed after the device is created */ + if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state))) + return -EINVAL; + + switch (cmd) { + case UI_DEV_CREATE: + retval = uinput_create_device(udev); + break; + + case UI_DEV_DESTROY: + retval = uinput_destroy_device(udev); + break; + + case UI_SET_EVBIT: + if (arg > EV_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->evbit); + break; + + case UI_SET_KEYBIT: + if (arg > KEY_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->keybit); + break; + + case UI_SET_RELBIT: + if (arg > REL_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->relbit); + break; + + case UI_SET_ABSBIT: + if (arg > ABS_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->absbit); + break; + + case UI_SET_MSCBIT: + if (arg > MSC_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->mscbit); + break; + + case UI_SET_LEDBIT: + if (arg > LED_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->ledbit); + break; + + case UI_SET_SNDBIT: + if (arg > SND_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->sndbit); + break; + + case UI_SET_FFBIT: + if (arg > FF_MAX) { + retval = -EINVAL; + break; + } + set_bit(arg, udev->dev->ffbit); + break; + + default: + retval = -EFAULT; + } + return retval; +} + +struct file_operations uinput_fops = { + owner: THIS_MODULE, + open: uinput_open, + release: uinput_close, + read: uinput_read, + write: uinput_write, + poll: uinput_poll, + ioctl: uinput_ioctl, +}; + +static struct miscdevice uinput_misc = { + fops: &uinput_fops, + minor: UINPUT_MINOR, + name: UINPUT_NAME, +}; + +static int __init uinput_init(void) +{ + return misc_register(&uinput_misc); +} + +static void __exit uinput_exit(void) +{ + misc_deregister(&uinput_misc); +} + +MODULE_AUTHOR("Aristeu Sergio Rozanski Filho"); +MODULE_DESCRIPTION("User level driver support for input subsystem"); +MODULE_LICENSE("GPL"); + +module_init(uinput_init); +module_exit(uinput_exit); + diff -urN linux-2.4.24/drivers/isdn/hisax/amd7930_fn.c linux-2.4.25/drivers/isdn/hisax/amd7930_fn.c --- linux-2.4.24/drivers/isdn/hisax/amd7930_fn.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/isdn/hisax/amd7930_fn.c 2004-02-18 05:36:31.000000000 -0800 @@ -61,6 +61,40 @@ #include #include +static WORD initAMD[] __devinitdata = { + 0x0100, + + 0x00A5, 3, 0x01, 0x40, 0x58, // LPR, LMR1, LMR2 + 0x0086, 1, 0x0B, // DMR1 (D-Buffer TH-Interrupts on) + 0x0087, 1, 0xFF, // DMR2 + 0x0092, 1, 0x03, // EFCR (extended mode d-channel-fifo on) + 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F, // FRAR4, SRAR4, DMR3, DMR4 (address recognition ) + 0x0084, 2, 0x80, 0x00, // DRLR + 0x00C0, 1, 0x47, // PPCR1 + 0x00C8, 1, 0x01, // PPCR2 + + 0x0102, + 0x0107, + 0x01A1, 1, + 0x0121, 1, + 0x0189, 2, + + 0x0045, 4, 0x61, 0x72, 0x00, 0x00, // MCR1, MCR2, MCR3, MCR4 + 0x0063, 2, 0x08, 0x08, // GX + 0x0064, 2, 0x08, 0x08, // GR + 0x0065, 2, 0x99, 0x00, // GER + 0x0066, 2, 0x7C, 0x8B, // STG + 0x0067, 2, 0x00, 0x00, // FTGR1, FTGR2 + 0x0068, 2, 0x20, 0x20, // ATGR1, ATGR2 + 0x0069, 1, 0x4F, // MMR1 + 0x006A, 1, 0x00, // MMR2 + 0x006C, 1, 0x40, // MMR3 + 0x0021, 1, 0x02, // INIT + 0x00A3, 1, 0x40, // LMR1 + + 0xFFFF}; + + static void Amd7930_new_ph(struct IsdnCardState *cs); diff -urN linux-2.4.24/drivers/isdn/hisax/amd7930_fn.h linux-2.4.25/drivers/isdn/hisax/amd7930_fn.h --- linux-2.4.24/drivers/isdn/hisax/amd7930_fn.h 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/isdn/hisax/amd7930_fn.h 2004-02-18 05:36:31.000000000 -0800 @@ -32,38 +32,5 @@ #define DBUSY_TIMER_VALUE 80 -static WORD initAMD[] = { - 0x0100, - - 0x00A5, 3, 0x01, 0x40, 0x58, // LPR, LMR1, LMR2 - 0x0086, 1, 0x0B, // DMR1 (D-Buffer TH-Interrupts on) - 0x0087, 1, 0xFF, // DMR2 - 0x0092, 1, 0x03, // EFCR (extended mode d-channel-fifo on) - 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F, // FRAR4, SRAR4, DMR3, DMR4 (address recognition ) - 0x0084, 2, 0x80, 0x00, // DRLR - 0x00C0, 1, 0x47, // PPCR1 - 0x00C8, 1, 0x01, // PPCR2 - - 0x0102, - 0x0107, - 0x01A1, 1, - 0x0121, 1, - 0x0189, 2, - - 0x0045, 4, 0x61, 0x72, 0x00, 0x00, // MCR1, MCR2, MCR3, MCR4 - 0x0063, 2, 0x08, 0x08, // GX - 0x0064, 2, 0x08, 0x08, // GR - 0x0065, 2, 0x99, 0x00, // GER - 0x0066, 2, 0x7C, 0x8B, // STG - 0x0067, 2, 0x00, 0x00, // FTGR1, FTGR2 - 0x0068, 2, 0x20, 0x20, // ATGR1, ATGR2 - 0x0069, 1, 0x4F, // MMR1 - 0x006A, 1, 0x00, // MMR2 - 0x006C, 1, 0x40, // MMR3 - 0x0021, 1, 0x02, // INIT - 0x00A3, 1, 0x40, // LMR1 - - 0xFFFF}; - extern void Amd7930_interrupt(struct IsdnCardState *cs, unsigned char irflags); extern void Amd7930_init(struct IsdnCardState *cs); diff -urN linux-2.4.24/drivers/macintosh/adb-iop.c linux-2.4.25/drivers/macintosh/adb-iop.c --- linux-2.4.24/drivers/macintosh/adb-iop.c 2000-02-15 22:39:01.000000000 -0800 +++ linux-2.4.25/drivers/macintosh/adb-iop.c 2004-02-18 05:36:31.000000000 -0800 @@ -106,6 +106,9 @@ struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; uint flags; +#ifdef DEBUG_ADB_IOP + int i; +#endif save_flags(flags); cli(); @@ -113,12 +116,10 @@ req = current_req; #ifdef DEBUG_ADB_IOP - printk("adb_iop_listen: rcvd packet, %d bytes: %02X %02X", + printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req, (uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd); - i = 0; - while (i < amsg->count) { - printk(" %02X", (uint) amsg->data[i++]); - } + for (i = 0; i < amsg->count; i++) + printk(" %02X", (uint) amsg->data[i]); printk("\n"); #endif @@ -136,7 +137,7 @@ adb_iop_end_req(req, idle); } } else { - /* TODO: is it possible for more tha one chunk of data */ + /* TODO: is it possible for more than one chunk of data */ /* to arrive before the timeout? If so we need to */ /* use reply_ptr here like the other drivers do. */ if ((adb_iop_state == awaiting_reply) && @@ -165,6 +166,9 @@ unsigned long flags; struct adb_request *req; struct adb_iopmsg amsg; +#ifdef DEBUG_ADB_IOP + int i; +#endif /* get the packet to send */ req = current_req; @@ -174,7 +178,7 @@ cli(); #ifdef DEBUG_ADB_IOP - printk("adb_iop_start: sending packet, %d bytes:", req->nbytes); + printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes); for (i = 0 ; i < req->nbytes ; i++) printk(" %02X", (uint) req->data[i]); printk("\n"); @@ -271,13 +275,17 @@ int adb_iop_reset_bus(void) { - struct adb_request req; + struct adb_request req = { + .reply_expected = 0, + .nbytes = 2, + .data = { ADB_PACKET, 0 }, + }; - req.reply_expected = 0; - req.nbytes = 2; - req.data[0] = ADB_PACKET; - req.data[1] = 0; /* RESET */ adb_iop_write(&req); - while (!req.complete) adb_iop_poll(); + while (!req.complete) { + adb_iop_poll(); + schedule(); + } + return 0; } diff -urN linux-2.4.24/drivers/macintosh/via-macii.c linux-2.4.25/drivers/macintosh/via-macii.c --- linux-2.4.24/drivers/macintosh/via-macii.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/macintosh/via-macii.c 2004-02-18 05:36:31.000000000 -0800 @@ -21,13 +21,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include static volatile unsigned char *via; diff -urN linux-2.4.24/drivers/md/lvm-snap.c linux-2.4.25/drivers/md/lvm-snap.c --- linux-2.4.24/drivers/md/lvm-snap.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/md/lvm-snap.c 2004-02-18 05:36:31.000000000 -0800 @@ -44,6 +44,7 @@ * 26/06/2002 - support for new list_move macro [patch@luckynet.dynu.com] * 26/07/2002 - removed conditional list_move macro because we will * discontinue LVM1 before 2.6 anyway + * 27/08/2003 - fixed unsafe list handling in lvm_find_exception_table() [HM] * */ @@ -114,7 +115,7 @@ org_start, lv_t * lv) { - struct list_head *hash_table = lv->lv_snapshot_hash_table, *next; + struct list_head *hash_table = lv->lv_snapshot_hash_table, *next, *n; unsigned long mask = lv->lv_snapshot_hash_mask; int chunk_size = lv->lv_chunk_size; lv_block_exception_t *ret; @@ -123,8 +124,9 @@ hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; ret = NULL; - for (next = hash_table->next; next != hash_table; - next = next->next) { + + for (next = hash_table->next, n = next->next; next != hash_table; + next = n, n = next->next) { lv_block_exception_t *exception; exception = list_entry(next, lv_block_exception_t, hash); diff -urN linux-2.4.24/drivers/md/lvm.c linux-2.4.25/drivers/md/lvm.c --- linux-2.4.24/drivers/md/lvm.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/md/lvm.c 2004-02-18 05:36:31.000000000 -0800 @@ -2594,8 +2594,9 @@ new_lv->lv_block_exception[e]. rsector_org, new_lv); - vg_ptr->pe_allocated -= old_lv->lv_allocated_le; + vg_ptr->pe_allocated -= old_lv->lv_allocated_snapshot_le; vg_ptr->pe_allocated += new_lv->lv_allocated_le; + old_lv->lv_allocated_snapshot_le = new_lv->lv_allocated_le; } else { vfree(old_lv->lv_current_pe); vfree(old_lv->lv_snapshot_hash_table); diff -urN linux-2.4.24/drivers/md/raid1.c linux-2.4.25/drivers/md/raid1.c --- linux-2.4.24/drivers/md/raid1.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/md/raid1.c 2004-02-18 05:36:31.000000000 -0800 @@ -1436,7 +1436,7 @@ block_nr = sector_nr; bsize = 512; while (!(block_nr & 1) && bsize < PAGE_SIZE - && (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) { + && (block_nr+2)*(bsize>>9) <= (mddev->sb->size *2)) { block_nr >>= 1; bsize <<= 1; } diff -urN linux-2.4.24/drivers/media/video/Config.in linux-2.4.25/drivers/media/video/Config.in --- linux-2.4.24/drivers/media/video/Config.in 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/media/video/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -39,8 +39,8 @@ dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_SGI_IP22" = "y" ]; then - dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV + if [ "$CONFIG_SGI_IP22" = "y" -a "$CONFIG_I2C" != "n" ]; then + dep_tristate ' SGI VINO (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_I2C_ALGO_SGI fi dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI fi diff -urN linux-2.4.24/drivers/media/video/Makefile linux-2.4.25/drivers/media/video/Makefile --- linux-2.4.24/drivers/media/video/Makefile 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/media/video/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -38,9 +38,9 @@ tda7432.o tda9875.o tda9887.o tuner.o obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o -obj-$(CONFIG_VIDEO_ZR36120) += zoran.o +obj-$(CONFIG_VIDEO_ZR36120) += zoran.o i2c-old.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o i2c-old.o -obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o i2c-old.o +obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o obj-$(CONFIG_VIDEO_W9966) += w9966.o @@ -48,11 +48,10 @@ obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o -obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_PLANB) += planb.o -obj-$(CONFIG_VIDEO_VINO) += vino.o -obj-$(CONFIG_VIDEO_STRADIS) += stradis.o +obj-$(CONFIG_VIDEO_VINO) += saa7191.o indycam.o vino.o +obj-$(CONFIG_VIDEO_STRADIS) += stradis.o i2c-old.o obj-$(CONFIG_VIDEO_CPIA) += cpia.o obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o @@ -81,8 +80,8 @@ fastdep: -zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o - $(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o +zoran.o: $(zoran-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(zoran-objs) bttv.o: $(bttv-objs) $(LD) $(LD_RFLAG) -r -o $@ $(bttv-objs) diff -urN linux-2.4.24/drivers/media/video/i2c-old.c linux-2.4.25/drivers/media/video/i2c-old.c --- linux-2.4.24/drivers/media/video/i2c-old.c 2001-09-30 12:26:06.000000000 -0700 +++ linux-2.4.25/drivers/media/video/i2c-old.c 2004-02-18 05:36:31.000000000 -0800 @@ -36,28 +36,11 @@ static struct i2c_driver *drivers[I2C_DRIVER_MAX]; static int bus_count = 0, driver_count = 0; -#ifdef CONFIG_VIDEO_BUZ -extern int saa7111_init(void); -extern int saa7185_init(void); -#endif -#ifdef CONFIG_VIDEO_LML33 -extern int bt819_init(void); -extern int bt856_init(void); -#endif - int i2c_init(void) { printk(KERN_INFO "i2c: initialized%s\n", scan ? " (i2c bus scan enabled)" : ""); - /* anything to do here ? */ -#ifdef CONFIG_VIDEO_BUZ - saa7111_init(); - saa7185_init(); -#endif -#ifdef CONFIG_VIDEO_LML33 - bt819_init(); - bt856_init(); -#endif + return 0; } diff -urN linux-2.4.24/drivers/media/video/indycam.c linux-2.4.25/drivers/media/video/indycam.c --- linux-2.4.24/drivers/media/video/indycam.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/media/video/indycam.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,218 @@ +/* + * indycam.c - IndyCam digital camera driver + * + * Copyright (C) 2003 Ladislav Michl + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +/* IndyCam decodes stream of photons into digital image representation ;-) */ +#include +#include + +#include "indycam.h" + +#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO) + +struct indycam { + struct i2c_client *client; + int version; +}; + +static struct i2c_driver i2c_driver_indycam; + +static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) +{ + static const unsigned char initseq[] = { + 0, + INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ + INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */ + 0x80, /* INDYCAM_GAIN */ + 0xf0, /* INDYCAM_BRIGHTNESS */ + 0x18, /* INDYCAM_RED_BALANCE */ + 0xa4, /* INDYCAM_BLUE_BALANCE */ + 0x80, /* INDYCAM_RED_SATURATION */ + 0xc0, /* INDYCAM_BLUE_SATURATION */ + 0x80, /* INDYCAM_GAMMA */ + }; + + int err = 0; + struct indycam *camera; + struct i2c_client *client; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; + camera = kmalloc(sizeof(*camera), GFP_KERNEL); + if (!camera) { + err = -ENOMEM; + goto out_free_client; + } + + client->data = camera; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_indycam; + strcpy(client->name, "IndyCam client"); + camera->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_camera; + + camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION); + if (camera->version != CAMERA_VERSION_INDY && + camera->version != CAMERA_VERSION_MOOSE) { + err = -ENODEV; + goto out_detach_client; + } + printk(KERN_INFO "Indycam v%d.%d detected.\n", + INDYCAM_VERSION_MAJOR(camera->version), + INDYCAM_VERSION_MINOR(camera->version)); + + err = i2c_master_send(client, initseq, sizeof(initseq)); + if (err) + printk(KERN_INFO "IndyCam initalization failed\n"); + + MOD_INC_USE_COUNT; + return 0; + +out_detach_client: + i2c_detach_client(client); +out_free_camera: + kfree(camera); +out_free_client: + kfree(client); + return err; +} + +static int indycam_probe(struct i2c_adapter *adap) +{ + /* Indy specific crap */ + if (adap->id == VINO_ADAPTER) + return indycam_attach(adap, INDYCAM_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; +} + +static int indycam_detach(struct i2c_client *client) +{ + struct indycam *camera = client->data; + + i2c_detach_client(client); + kfree(camera); + kfree(client); + MOD_DEC_USE_COUNT; + return 0; +} + +static int indycam_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + struct indycam *camera = client->data; + + switch (cmd) { + + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_NTSC; + cap->inputs = 1; + cap->outputs = 1; + break; + } +#if 0 + case DECODER_GET_VERSION: { + int *iarg = arg; + + *iarg = camera->version; + break; + } +#endif + case DECODER_GET_STATUS: { + int *iarg = arg; + + *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC | + DECODER_STATUS_COLOR; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_NTSC: + break; + default: + return -EINVAL; + } + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + struct video_picture *pic = arg; + /* TODO */ + break; + } + default: + return -EINVAL; + } + + return 0; +} + +static struct i2c_driver i2c_driver_indycam = { + .name = "indycam", + .id = I2C_DRIVERID_INDYCAM, + .flags = I2C_DF_NOTIFY, + .attach_adapter = indycam_probe, + .detach_client = indycam_detach, + .command = indycam_command, +}; + +static int indycam_init(void) +{ + return i2c_add_driver(&i2c_driver_indycam); +} + +static void indycam_exit(void) +{ + i2c_del_driver(&i2c_driver_indycam); +} + +module_init(indycam_init); +module_exit(indycam_exit); + +MODULE_DESCRIPTION("SGI IndyCam driver"); +MODULE_AUTHOR("Ladislav Michl "); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/media/video/indycam.h linux-2.4.25/drivers/media/video/indycam.h --- linux-2.4.24/drivers/media/video/indycam.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/media/video/indycam.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,49 @@ +#ifndef _indycam_h_ +#define _indycam_h_ + +/* I2C address for the Guinness Camera */ +#define INDYCAM_ADDR 0x56 + +/* Camera version */ +#define CAMERA_VERSION_INDY 0x10 /* v1.0 */ +#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */ +#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4) +#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f) + +/* Register bus addresses */ +#define INDYCAM_CONTROL 0x00 +#define INDYCAM_SHUTTER 0x01 +#define INDYCAM_GAIN 0x02 +#define INDYCAM_BRIGHTNESS 0x03 +#define INDYCAM_RED_BALANCE 0x04 +#define INDYCAM_BLUE_BALANCE 0x05 +#define INDYCAM_RED_SATURATION 0x06 +#define INDYCAM_BLUE_SATURATION 0x07 +#define INDYCAM_GAMMA 0x08 +#define INDYCAM_VERSION 0x0e +#define INDYCAM_RESET 0x0f +#define INDYCAM_LED 0x46 +#define INDYCAM_ORIENTATION 0x47 +#define INDYCAM_BUTTON 0x48 + +/* Field definitions of registers */ +#define INDYCAM_CONTROL_AGCENA (1<<0) +#define INDYCAM_CONTROL_AWBCTL (1<<1) + /* 2-3 are reserved */ +#define INDYCAM_CONTROL_EVNFLD (1<<4) + +#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */ +#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */ +#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */ +#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */ +#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */ +#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */ +#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */ +#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */ +#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */ + +#define INDYCAM_BUTTON_RELEASED (1<<4) +#define INDYCAM_LED_ACTIVE (1<<5) +#define INDYCAM_BOTTOM_TO_TOP (1<<6) + +#endif diff -urN linux-2.4.24/drivers/media/video/saa7110.c linux-2.4.25/drivers/media/video/saa7110.c --- linux-2.4.24/drivers/media/video/saa7110.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/media/video/saa7110.c 2004-02-18 05:36:31.000000000 -0800 @@ -404,7 +404,7 @@ { "saa7110", /* name */ - I2C_DRIVERID_VIDEODECODER, /* in i2c.h */ + I2C_DRIVERID_VIDEODECODER, /* in i2c-old.h */ I2C_SAA7110, I2C_SAA7110+1, /* Addr range */ saa7110_attach, diff -urN linux-2.4.24/drivers/media/video/saa7146.h linux-2.4.25/drivers/media/video/saa7146.h --- linux-2.4.24/drivers/media/video/saa7146.h 2000-12-11 13:15:51.000000000 -0800 +++ linux-2.4.25/drivers/media/video/saa7146.h 2004-02-18 05:36:31.000000000 -0800 @@ -25,7 +25,7 @@ #include #include -#include +#include #include #ifndef O_NONCAP diff -urN linux-2.4.24/drivers/media/video/saa7191.c linux-2.4.25/drivers/media/video/saa7191.c --- linux-2.4.24/drivers/media/video/saa7191.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/media/video/saa7191.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,320 @@ +/* + * saa7191 - Philips SAA7191 video decoder driver + * + * Copyright (C) 2003 Ladislav Michl + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "saa7191.h" + +#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO) + +struct saa7191 { + struct i2c_client *client; + unsigned char reg[25]; + unsigned char norm; + unsigned char input; + unsigned char bright; + unsigned char contrast; + unsigned char hue; + unsigned char sat; +}; + +static struct i2c_driver i2c_driver_saa7191; + +static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind) +{ + static const unsigned char initseq[] = { + 0, + 0x50, /* SAA7191_REG_IDEL */ + 0x30, /* SAA7191_REG_HSYB */ + 0x00, /* SAA7191_REG_HSYS */ + 0xe8, /* SAA7191_REG_HCLB */ + 0xb6, /* SAA7191_REG_HCLS */ + 0xf4, /* SAA7191_REG_HPHI */ + 0x01, /* SAA7191_REG_LUMA */ + 0x00, /* SAA7191_REG_HUEC */ + 0xf8, /* SAA7191_REG_CKTQ */ + 0xf8, /* SAA7191_REG_CKTS */ + 0x90, /* SAA7191_REG_PLSE */ + 0x90, /* SAA7191_REG_SESE */ + 0x00, /* SAA7191_REG_GAIN */ + 0x8c, /* SAA7191_REG_STDC */ + 0x78, /* SAA7191_REG_IOCK */ + 0x99, /* SAA7191_REG_CTL3 */ + 0x00, /* SAA7191_REG_CTL4 */ + 0x2c, /* SAA7191_REG_CHCV */ + 0x00, /* unused */ + 0x00, /* unused */ + 0x34, /* SAA7191_REG_HS6B */ + 0x0a, /* SAA7191_REG_HS6S */ + 0xf4, /* SAA7191_REG_HC6B */ + 0xce, /* SAA7191_REG_HC6S */ + 0xf4, /* SAA7191_REG_HP6I */ + }; + int err = 0; + struct saa7191 *decoder; + struct i2c_client *client; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; + decoder = kmalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) { + err = -ENOMEM; + goto out_free_client; + } + client->data = decoder; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_saa7191; + strcpy(client->name, "saa7191 client"); + decoder->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_decoder; + + decoder->norm = VIDEO_DECODER_PAL | VIDEO_MODE_NTSC | + VIDEO_DECODER_AUTO; + decoder->input = 0; + /* Registers are 8bit wide and we are storing shifted values */ + decoder->bright = 128; + decoder->contrast = 128; + decoder->hue = 128; + decoder->sat = 128; + + memcpy(decoder->reg, initseq, sizeof(initseq)); + err = i2c_master_send(client, initseq, sizeof(initseq)); + if (err) + printk(KERN_INFO "saa7191 initialization failed (%d)\n", err); + + MOD_INC_USE_COUNT; + return 0; + +out_free_decoder: + kfree(decoder); +out_free_client: + kfree(client); + return err; +} + +static int saa7191_probe(struct i2c_adapter *adap) +{ + /* Always connected to VINO */ + if (adap->id == VINO_ADAPTER) + return saa7191_attach(adap, SAA7191_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; +} + +static int saa7191_detach(struct i2c_client *client) +{ + struct saa7191 *decoder = client->data; + + i2c_detach_client(client); + kfree(decoder); + kfree(client); + MOD_DEC_USE_COUNT; + return 0; +} + +static unsigned char saa7191_read(struct i2c_client *client, + unsigned char command) +{ + return ((struct saa7191 *)client->data)->reg[command]; +} + +static int saa7191_write(struct i2c_client *client, unsigned char command, + unsigned char value) +{ + ((struct saa7191 *)client->data)->reg[command] = value; + return i2c_smbus_write_byte_data(client, command, value); +} + +static int vino_set_input(struct i2c_client *client, int val) +{ + unsigned char luma = saa7191_read(client, SAA7191_REG_LUMA); + unsigned char iock = saa7191_read(client, SAA7191_REG_IOCK); + + switch (val) { + case 0: /* Set Composite input */ + iock &= ~0x03; + /* Chrominance trap active */ + luma |= ~SAA7191_LUMA_BYPS; + break; + case 1: /* Set S-Video input */ + iock |= 2; + /* Chrominance trap bypassed */ + luma |= SAA7191_LUMA_BYPS; + break; + default: + return -EINVAL; + } + saa7191_write(client, SAA7191_REG_LUMA, luma); + saa7191_write(client, SAA7191_REG_IOCK, iock); + + return 0; +} + +static int saa7191_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + struct saa7191 *decoder = client->data; + + switch (cmd) { + + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | + VIDEO_DECODER_AUTO; + cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: { + int *iarg = arg; + int status; + int res = 0; + + status = i2c_smbus_read_byte_data(client, SAA7191_REG_STATUS); + if ((status & SAA7191_STATUS_HLCK) == 0) + res |= DECODER_STATUS_GOOD; + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case VIDEO_MODE_PAL: + res |= DECODER_STATUS_PAL; + break; + case VIDEO_MODE_AUTO: + default: + if (status & SAA7191_STATUS_FIDT) + res |= DECODER_STATUS_NTSC; + else + res |= DECODER_STATUS_PAL; + if (status & SAA7191_STATUS_CODE) + res |= DECODER_STATUS_COLOR; + break; + } + *iarg = res; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_NTSC: + break; + case VIDEO_MODE_PAL: + break; + default: + return -EINVAL; + } + decoder->norm = *iarg; + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + switch (client->adapter->id) { + case VINO_ADAPTER: + return vino_set_input(client, *iarg); + default: + if (*iarg != 0) + return -EINVAL; + } + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + struct video_picture *pic = arg; + unsigned val; +#if 0 + /* TODO */ + val = pic->brightness >> 8; + if (decoder->bright != val) { + decoder->bright = val; + i2c_smbus_write_byte_data(client, XXX, val); + } + val = pic->contrast >> 8; + if (decoder->contrast != val) { + decoder->contrast = val; + i2c_smbus_write_byte_data(client, XXX, val); + } + val = pic->colour >> 8; + if (decoder->sat != val) { + decoder->sat = val; + i2c_smbus_write_byte_data(client, XXX, val); + } +#endif + val = (pic->hue >> 8) - 0x80; + if (decoder->hue != val) { + decoder->hue = val; + i2c_smbus_write_byte_data(client, SAA7191_REG_HUEC, + val); + } + break; + } + default: + return -EINVAL; + } + + return 0; +} + +static struct i2c_driver i2c_driver_saa7191 = { + .name = "saa7191", + .id = I2C_DRIVERID_SAA7191, + .flags = I2C_DF_NOTIFY, + .attach_adapter = saa7191_probe, + .detach_client = saa7191_detach, + .command = saa7191_command +}; + +static int saa7191_init(void) +{ + return i2c_add_driver(&i2c_driver_saa7191); +} + +static void saa7191_exit(void) +{ + i2c_del_driver(&i2c_driver_saa7191); +} + +module_init(saa7191_init); +module_exit(saa7191_exit); + +MODULE_DESCRIPTION("Philips SAA7191 video decoder driver"); +MODULE_AUTHOR("Ladislav Michl "); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/media/video/saa7191.h linux-2.4.25/drivers/media/video/saa7191.h --- linux-2.4.24/drivers/media/video/saa7191.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/media/video/saa7191.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,46 @@ +#ifndef _saa7191_h_ +#define _saa7191_h_ + +/* Phillips SAA7191 DMSD I2C bus address */ +#define SAA7191_ADDR 0x8a + +/* Register subaddresses. */ +#define SAA7191_REG_IDEL 0x00 +#define SAA7191_REG_HSYB 0x01 +#define SAA7191_REG_HSYS 0x02 +#define SAA7191_REG_HCLB 0x03 +#define SAA7191_REG_HCLS 0x04 +#define SAA7191_REG_HPHI 0x05 +#define SAA7191_REG_LUMA 0x06 +#define SAA7191_REG_HUEC 0x07 +#define SAA7191_REG_CKTQ 0x08 +#define SAA7191_REG_CKTS 0x09 +#define SAA7191_REG_PLSE 0x0a +#define SAA7191_REG_SESE 0x0b +#define SAA7191_REG_GAIN 0x0c +#define SAA7191_REG_STDC 0x0d +#define SAA7191_REG_IOCK 0x0e +#define SAA7191_REG_CTL3 0x0f +#define SAA7191_REG_CTL4 0x10 +#define SAA7191_REG_CHCV 0x11 +#define SAA7191_REG_HS6B 0x14 +#define SAA7191_REG_HS6S 0x15 +#define SAA7191_REG_HC6B 0x16 +#define SAA7191_REG_HC6S 0x17 +#define SAA7191_REG_HP6I 0x18 +#define SAA7191_REG_STATUS 0xff /* not really a subaddress */ + +/* Status Register definitions */ +#define SAA7191_STATUS_CODE 0x01 /* color detected flag */ +#define SAA7191_STATUS_FIDT 0x20 /* format type NTSC/PAL */ +#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked/locked */ +#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */ + +/* Luminance Control Register definitions */ +#define SAA7191_LUMA_BYPS 0x80 + +/* I/O and Clock Control Register definitions */ +#define SAA7191_IOCK_HPLL 0x80 +#define SAA7191_IOCK_CHRS 0x04 + +#endif diff -urN linux-2.4.24/drivers/media/video/vino.c linux-2.4.25/drivers/media/video/vino.c --- linux-2.4.24/drivers/media/video/vino.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/media/video/vino.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,257 +1,1196 @@ /* - * (incomplete) Driver for the Vino Video input system found in SGI Indys. + * Driver for the VINO (Video In No Out) system found in SGI Indys. + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 as published by the Free Software Foundation. * - * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se) - * - * This isn't complete yet, please don't expect any video until I've written - * some more code. + * Copyright (C) 2003 Ladislav Michl */ #include +#include #include #include -#include #include +#include +#include +#include +#include +#include #include - -#include -#include +#include +#include +#include + +#include +#include +#include +#include +#include #include "vino.h" +/* debugging? */ +#if 1 +#define DEBUG(x...) printk(x); +#else +#define DEBUG(x...) +#endif + +/* VINO video size */ +#define VINO_PAL_WIDTH 768 +#define VINO_PAL_HEIGHT 576 +#define VINO_NTSC_WIDTH 646 +#define VINO_NTSC_HEIGHT 486 + +/* set this to some sensible values. note: VINO_MIN_WIDTH has to be 8*x */ +#define VINO_MIN_WIDTH 32 +#define VINO_MIN_HEIGHT 32 + +/* channel selection */ +#define VINO_INPUT_COMP 0 +#define VINO_INPUT_SVIDEO 1 +#define VINO_INPUT_CAMERA 2 +#define VINO_INPUT_CHANNELS 3 + +#define PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE) + +/* VINO ASIC registers */ +struct sgi_vino *vino; + +static const char *vinostr = "VINO IndyCam/TV"; +static int threshold_a = 512; +static int threshold_b = 512; + struct vino_device { struct video_device vdev; +#define VINO_CHAN_A 1 +#define VINO_CHAN_B 2 + int chan; + int alpha; + /* clipping... */ + unsigned int left, right, top, bottom; + /* decimation used */ + unsigned int decimation; + /* palette used, picture hue, etc */ + struct video_picture picture; + /* VINO_INPUT_COMP, VINO_INPUT_SVIDEO or VINO_INPUT_CAMERA */ + unsigned int input; + /* bytes per line */ + unsigned int line_size; + /* descriptor table (virtual addresses) */ + unsigned long *desc; + /* # of allocated pages */ + int page_count; + /* descriptor table (dma addresses) */ + struct { + dma_addr_t *cpu; + dma_addr_t dma; + } dma_desc; + /* add some more space to let VINO trigger End Of Field interrupt + * before reaching end of buffer */ +#define VINO_FBUFSIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 + 2 * PAGE_SIZE) + unsigned int frame_size; +#define VINO_BUF_UNUSED 0 +#define VINO_BUF_GRABBING 1 +#define VINO_BUF_DONE 2 + int buffer_state; + + wait_queue_head_t dma_wait; + spinlock_t state_lock; + struct semaphore sem; - unsigned long chan; -#define VINO_CHAN_A 0 -#define VINO_CHAN_B 1 + /* Make sure we only have one user at the time */ + int users; +}; - unsigned long flags; -#define VINO_DMA_ACTIVE (1<<0) +struct vino_client { + struct i2c_client *driver; + int owner; }; -/* We can actually receive TV and IndyCam input at the same time. Believe it or - * not.. - */ -static struct vino_device vino[2]; +struct vino_video { + struct vino_device chA; + struct vino_device chB; + + struct vino_client decoder; + struct vino_client camera; + spinlock_t vino_lock; + spinlock_t input_lock; + + /* Loaded into VINO descriptors to clear End Of Descriptors table + * interupt condition */ + unsigned long dummy_desc; + struct { + dma_addr_t *cpu; + dma_addr_t dma; + } dummy_dma; +}; + +static struct vino_video *Vino; + +/* --- */ + +unsigned i2c_vino_getctrl(void *data) +{ + return vino->i2c_control; +} + +void i2c_vino_setctrl(void *data, unsigned val) +{ + vino->i2c_control = val; +} + +unsigned i2c_vino_rdata(void *data) +{ + return vino->i2c_data; +} + +void i2c_vino_wdata(void *data, unsigned val) +{ + vino->i2c_data = val; +} -/* Those registers have to be accessed by either *one* 64 bit write or *one* 64 - * bit read. We need some asm to fix this. We can't use mips3 as standard - * because we just save 32 bits at context switch. +static struct i2c_algo_sgi_data i2c_sgi_vino_data = +{ + .getctrl = &i2c_vino_getctrl, + .setctrl = &i2c_vino_setctrl, + .rdata = &i2c_vino_rdata, + .wdata = &i2c_vino_wdata, + .xfer_timeout = 200, + .ack_timeout = 1000, +}; + +/* + * There are two possible clients on VINO I2C bus, so we limit usage only + * to them. */ +static int i2c_vino_client_reg(struct i2c_client *client) +{ + int res = 0; + + spin_lock(&Vino->input_lock); + switch (client->driver->id) { + case I2C_DRIVERID_SAA7191: + if (Vino->decoder.driver) + res = -EBUSY; + else + Vino->decoder.driver = client; + break; + case I2C_DRIVERID_INDYCAM: + if (Vino->camera.driver) + res = -EBUSY; + else + Vino->camera.driver = client; + break; + default: + res = -ENODEV; + } + spin_unlock(&Vino->input_lock); + + return res; +} -static __inline__ unsigned long long vino_reg_read(unsigned long addr) +static int i2c_vino_client_unreg(struct i2c_client *client) { - unsigned long long ret __attribute__ ((aligned (64))); - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long flags; - - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1,(%0)\n\t" - "sd\t$1,(%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : - :"r" (virt_addr), "r" (&ret)); - restore_flags(flags); + int res = 0; + + spin_lock(&Vino->input_lock); + if (client == Vino->decoder.driver) { + if (Vino->decoder.owner) + res = -EBUSY; + else + Vino->decoder.driver = NULL; + } else if (client == Vino->camera.driver) { + if (Vino->camera.owner) + res = -EBUSY; + else + Vino->camera.driver = NULL; + } + spin_unlock(&Vino->input_lock); - return ret; + return res; } -static __inline__ void vino_reg_write(unsigned long long value, - unsigned long addr) +static struct i2c_adapter vino_i2c_adapter = { - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long flags; + .name = "VINO I2C bus", + .id = I2C_HW_SGI_VINO, + .algo_data = &i2c_sgi_vino_data, + .client_register = &i2c_vino_client_reg, + .client_unregister = &i2c_vino_client_unreg, +}; - /* we might lose the upper parts of the registers which are not saved - * if there comes an interrupt in our way, play safe */ +static int vino_i2c_add_bus(void) +{ + return i2c_sgi_add_bus(&vino_i2c_adapter); +} - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1,(%0)\n\t" - "sd\t$1,(%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : - :"r" (&value), "r" (virt_addr)); - restore_flags(flags); -} - -static __inline__ void vino_reg_and(unsigned long long value, - unsigned long addr) -{ - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long tmp, flags; - - __save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\t\t\t# vino_reg_and\n\t" - ".set\tnoat\n\t" - "ld\t$1, (%1)\n\t" - "ld\t%0, (%2)\n\t" - "and\t$1, $1, %0\n\t" - "sd\t$1, (%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : "=&r" (tmp) - : "r" (virt_addr), "r" (&value)); - __restore_flags(flags); -} - -static __inline__ void vino_reg_or(unsigned long long value, - unsigned long addr) -{ - unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE); - unsigned long tmp, flags; - - save_and_cli(flags); - __asm__ __volatile__( - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "ld\t$1, (%1)\n\t" - "ld\t%0, (%2)\n\t" - "or\t$1, $1, %0\n\t" - "sd\t$1, (%1)\n\t" - ".set\tat\n\t" - ".set\tmips0" - : "=&r" (tmp) - : "r" (virt_addr), "r" (&value)); - restore_flags(flags); +static int vino_i2c_del_bus(void) +{ + return i2c_sgi_del_bus(&vino_i2c_adapter); } -static int vino_dma_setup(void) +static int i2c_camera_command(unsigned int cmd, void *arg) +{ + return Vino->camera.driver->driver->command(Vino->camera.driver, + cmd, arg); +} + +static int i2c_decoder_command(unsigned int cmd, void *arg) +{ + return Vino->decoder.driver->driver->command(Vino->decoder.driver, + cmd, arg); +} + +/* --- */ + +static int bytes_per_pixel(struct vino_device *v) { + switch (v->picture.palette) { + case VIDEO_PALETTE_GREY: + return 1; + case VIDEO_PALETTE_YUV422: + return 2; + default: /* VIDEO_PALETTE_RGB32 */ + return 4; + } +} + +static int get_capture_norm(struct vino_device *v) +{ + if (v->input == VINO_INPUT_CAMERA) + return VIDEO_MODE_NTSC; + else { + /* TODO */ + return VIDEO_MODE_NTSC; + } +} + +/* + * Set clipping. Try new values to fit, if they don't return -EINVAL + */ +static int set_clipping(struct vino_device *v, int x, int y, int w, int h, + int d) +{ + int maxwidth, maxheight, lsize; + + if (d < 1) + d = 1; + if (d > 8) + d = 8; + if (w / d < VINO_MIN_WIDTH || h / d < VINO_MIN_HEIGHT) + return -EINVAL; + if (get_capture_norm(v) == VIDEO_MODE_NTSC) { + maxwidth = VINO_NTSC_WIDTH; + maxheight = VINO_NTSC_HEIGHT; + } else { + maxwidth = VINO_PAL_WIDTH; + maxheight = VINO_PAL_HEIGHT; + } + if (x < 0) + x = 0; + if (y < 0) + y = 0; + y &= ~1; /* odd/even fields */ + if (x + w > maxwidth) { + w = maxwidth - x; + if (w / d < VINO_MIN_WIDTH) + x = maxwidth - VINO_MIN_WIDTH * d; + } + if (y + h > maxheight) { + h = maxheight - y; + if (h / d < VINO_MIN_HEIGHT) + y = maxheight - VINO_MIN_HEIGHT * d; + } + /* line size must be multiple of 8 bytes */ + lsize = (bytes_per_pixel(v) * w / d) & ~7; + w = lsize * d / bytes_per_pixel(v); + v->left = x; + v->top = y; + v->right = x + w; + v->bottom = y + h; + v->decimation = d; + v->line_size = lsize; + DEBUG("VINO: clipping %d, %d, %d, %d / %d - %d\n", v->left, v->top, + v->right, v->bottom, v->decimation, v->line_size); return 0; } -static void vino_dma_stop(void) +static int set_scaling(struct vino_device *v, int w, int h) { + int maxwidth, maxheight, lsize, d; + + if (w < VINO_MIN_WIDTH || h < VINO_MIN_HEIGHT) + return -EINVAL; + if (get_capture_norm(v) == VIDEO_MODE_NTSC) { + maxwidth = VINO_NTSC_WIDTH; + maxheight = VINO_NTSC_HEIGHT; + } else { + maxwidth = VINO_PAL_WIDTH; + maxheight = VINO_PAL_HEIGHT; + } + if (w > maxwidth) + w = maxwidth; + if (h > maxheight) + h = maxheight; + d = max(maxwidth / w, maxheight / h); + if (d > 8) + d = 8; + /* line size must be multiple of 8 bytes */ + lsize = (bytes_per_pixel(v) * w) & ~7; + w = lsize * d / bytes_per_pixel(v); + h *= d; + if (v->left + w > maxwidth) + v->left = maxwidth - w; + if (v->top + h > maxheight) + v->top = (maxheight - h) & ~1; /* odd/even fields */ + /* FIXME: -1 bug... Verify clipping with video signal generator */ + v->right = v->left + w; + v->bottom = v->top + h; + v->decimation = d; + v->line_size = lsize; + DEBUG("VINO: scaling %d, %d, %d, %d / %d - %d\n", v->left, v->top, + v->right, v->bottom, v->decimation, v->line_size); + return 0; } -static int vino_init(void) +/* + * Prepare vino for DMA transfer... (execute only with vino_lock locked) + */ +static int dma_setup(struct vino_device *v) { - unsigned long ret; - unsigned short rev, id; - unsigned long long foo; - unsigned long *bar; - - bar = (unsigned long *) &foo; - - ret = vino_reg_read(VINO_REVID); - - rev = (ret & VINO_REVID_REV_MASK); - id = (ret & VINO_REVID_ID_MASK) >> 4; - - printk("Vino: ID:%02hx Rev:%02hx\n", id, rev); - - foo = vino_reg_read(VINO_A_DESC_DATA0); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA1); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA2); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_A_DESC_DATA3); - printk("0x%lx", bar[0]); - printk("%lx\n", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA0); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA1); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA2); - printk("0x%lx", bar[0]); - printk("%lx ", bar[1]); - foo = vino_reg_read(VINO_B_DESC_DATA3); - printk("0x%lx", bar[0]); - printk("%lx\n", bar[1]); + u32 ctrl, intr; + struct sgi_vino_channel *ch; + + ch = (v->chan == VINO_CHAN_A) ? &vino->a : &vino->b; + ch->page_index = 0; + ch->line_count = 0; + /* let VINO know where to transfer data */ + ch->start_desc_tbl = v->dma_desc.dma; + ch->next_4_desc = v->dma_desc.dma; + /* give vino time to fetch the first four descriptors, 5 usec + * should be more than enough time */ + udelay(5); + /* VINO line size register is set 8 bytes less than actual */ + ch->line_size = v->line_size - 8; + /* set the alpha register */ + ch->alpha = v->alpha; + /* set cliping registers */ + ch->clip_start = VINO_CLIP_ODD(v->top) | VINO_CLIP_EVEN(v->top+1) | + VINO_CLIP_X(v->left); + ch->clip_end = VINO_CLIP_ODD(v->bottom) | VINO_CLIP_EVEN(v->bottom+1) | + VINO_CLIP_X(v->right); + /* FIXME: end-of-field bug workaround + VINO_CLIP_X(VINO_PAL_WIDTH); + */ + /* init the frame rate and norm (full frame rate only for now...) */ + ch->frame_rate = VINO_FRAMERT_RT(0x1fff) | + (get_capture_norm(v) == VIDEO_MODE_PAL ? + VINO_FRAMERT_PAL : 0); + ctrl = vino->control; + intr = vino->intr_status; + if (v->chan == VINO_CHAN_A) { + /* All interrupt conditions for this channel was cleared + * so clear the interrupt status register and enable + * interrupts */ + intr &= ~VINO_INTSTAT_A; + ctrl |= VINO_CTRL_A_INT; + /* enable synchronization */ + ctrl |= VINO_CTRL_A_SYNC_ENBL; + /* enable frame assembly */ + ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL; + /* set decimation used */ + if (v->decimation < 2) + ctrl &= ~VINO_CTRL_A_DEC_ENBL; + else { + ctrl |= VINO_CTRL_A_DEC_ENBL; + ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK; + ctrl |= (v->decimation - 1) << + VINO_CTRL_A_DEC_SCALE_SHIFT; + } + /* select input interface */ + if (v->input == VINO_INPUT_CAMERA) + ctrl |= VINO_CTRL_A_SELECT; + else + ctrl &= ~VINO_CTRL_A_SELECT; + /* palette */ + ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB | + VINO_CTRL_A_DITHER); + } else { + intr &= ~VINO_INTSTAT_B; + ctrl |= VINO_CTRL_B_INT; + ctrl |= VINO_CTRL_B_SYNC_ENBL; + ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL; + if (v->decimation < 2) + ctrl &= ~VINO_CTRL_B_DEC_ENBL; + else { + ctrl |= VINO_CTRL_B_DEC_ENBL; + ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK; + ctrl |= (v->decimation - 1) << + VINO_CTRL_B_DEC_SCALE_SHIFT; + } + if (v->input == VINO_INPUT_CAMERA) + ctrl |= VINO_CTRL_B_SELECT; + else + ctrl &= ~VINO_CTRL_B_SELECT; + ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB | + VINO_CTRL_B_DITHER); + } + /* set palette */ + switch (v->picture.palette) { + case VIDEO_PALETTE_GREY: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY; + break; + case VIDEO_PALETTE_RGB32: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_RGB : VINO_CTRL_B_RGB; + break; +#if 0 + /* FIXME: this is NOT in v4l API :-( */ + case VIDEO_PALETTE_RGB332: + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER : + VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER; + break; +#endif + } + vino->control = ctrl; + vino->intr_status = intr; return 0; } -static void vino_dma_go(struct vino_device *v) +/* (execute only with vino_lock locked) */ +static void dma_stop(struct vino_device *v) { - + u32 ctrl = vino->control; + ctrl &= (v->chan == VINO_CHAN_A) ? + ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; } -/* Reset the vino back to default state */ +/* (execute only with vino_lock locked) */ +static void dma_go(struct vino_device *v) +{ + u32 ctrl = vino->control; + ctrl |= (v->chan == VINO_CHAN_A) ? + VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; +} -static void vino_setup(struct vino_device *v) +/* + * Load dummy page to descriptor registers. This prevents generating of + * spurious interrupts. (execute only with vino_lock locked) + */ +static void clear_eod(struct vino_device *v) { - + struct sgi_vino_channel *ch; + + DEBUG("VINO: chnl %c clear EOD\n", (v->chan == VINO_CHAN_A) ? 'A':'B'); + ch = (v->chan == VINO_CHAN_A) ? &vino->a : &vino->b; + ch->page_index = 0; + ch->line_count = 0; + ch->start_desc_tbl = Vino->dummy_dma.dma; + ch->next_4_desc = Vino->dummy_dma.dma; + udelay(5); } -static int vino_open(struct video_device *dev, int flags) +static void field_done(struct vino_device *v) { - return 0; + spin_lock(&v->state_lock); + if (v->buffer_state == VINO_BUF_GRABBING) + v->buffer_state = VINO_BUF_DONE; + spin_unlock(&v->state_lock); + wake_up(&v->dma_wait); } -static void vino_close(struct video_device *dev) +static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + u32 intr, ctrl; + + spin_lock(&Vino->vino_lock); + ctrl = vino->control; + intr = vino->intr_status; + DEBUG("VINO: intr status %04x\n", intr); + if (intr & (VINO_INTSTAT_A_FIFO | VINO_INTSTAT_A_EOD)) { + ctrl &= ~VINO_CTRL_A_DMA_ENBL; + vino->control = ctrl; + clear_eod(&Vino->chA); + } + if (intr & (VINO_INTSTAT_B_FIFO | VINO_INTSTAT_B_EOD)) { + ctrl &= ~VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; + clear_eod(&Vino->chB); + } + vino->intr_status = ~intr; + spin_unlock(&Vino->vino_lock); + /* FIXME: For now we are assuming that interrupt means that frame is + * done. That's not true, but we can live with such brokeness for + * a while ;-) */ + field_done(&Vino->chA); } -static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +static int vino_grab(struct vino_device *v, int frame) { + int err = 0; + + spin_lock_irq(&v->state_lock); + if (v->buffer_state == VINO_BUF_GRABBING) + err = -EBUSY; + v->buffer_state = VINO_BUF_GRABBING; + spin_unlock_irq(&v->state_lock); + + if (err) + return err; + + spin_lock_irq(&Vino->vino_lock); + dma_setup(v); + dma_go(v); + spin_unlock_irq(&Vino->vino_lock); + return 0; } -static int vino_mmap(struct video_device *dev, const char *adr, - unsigned long size) +static int vino_waitfor(struct vino_device *v, int frame) +{ + wait_queue_t wait; + int i, err = 0; + + if (frame != 0) + return -EINVAL; + + spin_lock_irq(&v->state_lock); + switch (v->buffer_state) { + case VINO_BUF_GRABBING: + init_waitqueue_entry(&wait, current); + /* add ourselves into wait queue */ + add_wait_queue(&v->dma_wait, &wait); + /* and set current state */ + set_current_state(TASK_INTERRUPTIBLE); + /* before releasing spinlock */ + spin_unlock_irq(&v->state_lock); + /* to ensure that schedule_timeout will return imediately + * if VINO interrupt was triggred meanwhile */ + schedule_timeout(HZ / 10); + if (signal_pending(current)) + err = -EINTR; + spin_lock_irq(&v->state_lock); + remove_wait_queue(&v->dma_wait, &wait); + /* don't rely on schedule_timeout return value and check what + * really happened */ + if (!err && v->buffer_state == VINO_BUF_GRABBING) + err = -EIO; + /* fall through */ + case VINO_BUF_DONE: + for (i = 0; i < v->page_count; i++) + pci_dma_sync_single(NULL, v->dma_desc.cpu[PAGE_RATIO*i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + v->buffer_state = VINO_BUF_UNUSED; + break; + default: + err = -EINVAL; + } + spin_unlock_irq(&v->state_lock); + + if (err && err != -EINVAL) { + DEBUG("VINO: waiting for frame failed\n"); + spin_lock_irq(&Vino->vino_lock); + dma_stop(v); + clear_eod(v); + spin_unlock_irq(&Vino->vino_lock); + } + + return err; +} + +static int alloc_buffer(struct vino_device *v, int size) { + int count, i, j, err; + + err = i = 0; + count = (size / PAGE_SIZE + 4) & ~3; + v->desc = (unsigned long *) kmalloc(count * sizeof(unsigned long), + GFP_KERNEL); + if (!v->desc) + return -ENOMEM; + + v->dma_desc.cpu = pci_alloc_consistent(NULL, PAGE_RATIO * (count+4) * + sizeof(dma_addr_t), + &v->dma_desc.dma); + if (!v->dma_desc.cpu) { + err = -ENOMEM; + goto out_free_desc; + } + while (i < count) { + dma_addr_t dma; + + v->desc[i] = get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!v->desc[i]) + break; + dma = pci_map_single(NULL, (void *)v->desc[i], PAGE_SIZE, + PCI_DMA_FROMDEVICE); + for (j = 0; j < PAGE_RATIO; j++) + v->dma_desc.cpu[PAGE_RATIO * i + j ] = + dma + VINO_PAGE_SIZE * j; + mem_map_reserve(virt_to_page(v->desc[i])); + i++; + } + v->dma_desc.cpu[PAGE_RATIO * count] = VINO_DESC_STOP; + if (i-- < count) { + while (i >= 0) { + mem_map_unreserve(virt_to_page(v->desc[i])); + pci_unmap_single(NULL, v->dma_desc.cpu[PAGE_RATIO * i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + free_page(v->desc[i]); + i--; + } + pci_free_consistent(NULL, + PAGE_RATIO * (count+4) * sizeof(dma_addr_t), + (void *)v->dma_desc.cpu, v->dma_desc.dma); + err = -ENOBUFS; + goto out_free_desc; + } + v->page_count = count; return 0; + +out_free_desc: + kfree(v->desc); + return err; } -static struct video_device vino_dev = { - owner: THIS_MODULE, - name: "Vino IndyCam/TV", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_VINO, - open: vino_open, - close: vino_close, - ioctl: vino_ioctl, - mmap: vino_mmap, -}; +static void free_buffer(struct vino_device *v) +{ + int i; + + for (i = 0; i < v->page_count; i++) { + mem_map_unreserve(virt_to_page(v->desc[i])); + pci_unmap_single(NULL, v->dma_desc.cpu[PAGE_RATIO * i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + free_page(v->desc[i]); + } + pci_free_consistent(NULL, + PAGE_RATIO * (v->page_count+4) * sizeof(dma_addr_t), + (void *)v->dma_desc.cpu, v->dma_desc.dma); + kfree(v->desc); +} -int __init init_vino(struct video_device *dev) +static int vino_open(struct inode *inode, struct file *file) { - int err; + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + int err = 0; + + down(&v->sem); + if (v->users) { + err = -EBUSY; + goto out; + } + /* Check for input device (IndyCam, saa7191) availability. + * Both DMA channels can run from the same source, but only + * source owner is allowed to change its parameters */ + spin_lock(&Vino->input_lock); + if (Vino->camera.driver) { + v->input = VINO_INPUT_CAMERA; + if (!Vino->camera.owner) + Vino->camera.owner = v->chan; + } + if (Vino->decoder.driver && Vino->camera.owner != v->chan) { + /* There are two inputs (Composite and SVideo) but only + * one output available to VINO DMA engine */ + if (!Vino->decoder.owner) { + Vino->decoder.owner = v->chan; + v->input = VINO_INPUT_COMP; + i2c_decoder_command(DECODER_SET_INPUT, &v->input); + } else + v->input = (v->chan == VINO_CHAN_A) ? + Vino->chB.input : Vino->chA.input; + } + if (v->input == -1) + err = -ENODEV; + spin_unlock(&Vino->input_lock); - err = vino_init(); if (err) + goto out; + if (alloc_buffer(v, VINO_FBUFSIZE)) { + err = -ENOBUFS; + goto out; + } + v->users++; +out: + up(&v->sem); + return err; +} + +static int vino_close(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + + down(&v->sem); + v->users--; + if (!v->users) { + struct vino_device *w = (v->chan == VINO_CHAN_A) ? + &Vino->chB : &Vino->chA; + /* Eventually make other channel owner of input device */ + spin_lock(&Vino->input_lock); + if (Vino->camera.owner == v->chan) + Vino->camera.owner = (w->input == VINO_INPUT_CAMERA) ? + w->chan : 0; + else if (Vino->decoder.owner == v->chan) + Vino->decoder.owner = (w->input == VINO_INPUT_COMP || + w->input == VINO_INPUT_SVIDEO) ? + w->chan : 0; + v->input = -1; + spin_unlock(&Vino->input_lock); + + vino_waitfor(v, 0); + free_buffer(v); + } + up(&v->sem); + return 0; +} + +static int vino_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + int i, err = 0; + + if (down_interruptible(&v->sem)) + return -EINTR; + if (size > v->page_count * PAGE_SIZE) { + err = -EINVAL; + goto out; + } + for (i = 0; i < v->page_count; i++) { + unsigned long page = virt_to_phys((void *)v->desc[i]); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_READONLY)) { + err = -EAGAIN; + goto out; + } + start += PAGE_SIZE; + if (size <= PAGE_SIZE) break; + size -= PAGE_SIZE; + } +out: + up(&v->sem); + return err; + +} + +static int vino_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; + + switch (cmd) { + case VIDIOCGCAP: { + struct video_capability *cap = arg; + + strcpy(cap->name, vinostr); + cap->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; + cap->channels = VINO_INPUT_CHANNELS; + cap->audios = 0; + cap->maxwidth = VINO_PAL_WIDTH; + cap->maxheight = VINO_PAL_HEIGHT; + cap->minwidth = VINO_MIN_WIDTH; + cap->minheight = VINO_MIN_HEIGHT; + break; + } + case VIDIOCGCHAN: { + struct video_channel *ch = arg; + + ch->flags = 0; + ch->tuners = 0; + switch (ch->channel) { + case VINO_INPUT_COMP: + ch->norm = VIDEO_MODE_PAL | VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_TV; + strcpy(ch->name, "Composite"); + break; + case VINO_INPUT_SVIDEO: + ch->norm = VIDEO_MODE_PAL | VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_TV; + strcpy(ch->name, "S-Video"); + break; + case VINO_INPUT_CAMERA: + ch->norm = VIDEO_MODE_NTSC; + ch->type = VIDEO_TYPE_CAMERA; + strcpy(ch->name, "IndyCam"); + break; + default: + return -EINVAL; + } + break; + } + case VIDIOCSCHAN: { + struct video_channel *ch = arg; + int err = 0; + struct vino_device *w = (v->chan == VINO_CHAN_A) ? + &Vino->chB : &Vino->chA; + + spin_lock(&Vino->input_lock); + switch (ch->channel) { + case VINO_INPUT_COMP: + case VINO_INPUT_SVIDEO: + if (!Vino->decoder.driver) { + err = -ENODEV; + break; + } + if (!Vino->decoder.owner) + Vino->decoder.owner = v->chan; + if (Vino->decoder.owner == v->chan) + i2c_decoder_command(DECODER_SET_INPUT, + &ch->channel); + else + if (ch->channel != w->input) { + err = -EBUSY; + break; + } + if (Vino->camera.owner == v->chan) + Vino->camera.owner = + (w->input == VINO_INPUT_CAMERA) ? + w->chan : 0; + break; + case VINO_INPUT_CAMERA: + if (!Vino->camera.driver) { + err = -ENODEV; + break; + } + if (!Vino->camera.owner) + Vino->camera.owner = v->chan; + if (Vino->decoder.owner == v->chan) + Vino->decoder.owner = + (w->input == VINO_INPUT_COMP || + w->input == VINO_INPUT_SVIDEO) ? + w->chan : 0; + break; + default: + err = -EINVAL; + } + if (!err) + v->input = ch->channel; + spin_unlock(&Vino->input_lock); + return err; + } + case VIDIOCGPICT: { + struct video_picture *pic = arg; -#if 0 - if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) { - return -ENODEV; + memcpy(pic, &v->picture, sizeof(struct video_picture)); + break; } -#endif + case VIDIOCSPICT: { + struct video_picture *pic = arg; + switch (pic->palette) { + case VIDEO_PALETTE_GREY: + pic->depth = 8; + break; + case VIDEO_PALETTE_YUV422: + pic->depth = 16; + break; + case VIDEO_PALETTE_RGB32: + pic->depth = 24; + break; + default: + return -EINVAL; + } + if (v->picture.palette != pic->palette) { + v->picture.palette = pic->palette; + v->picture.depth = pic->depth; + /* TODO: we need to change line size */ + } + DEBUG("XXX %d, %d\n", v->input, Vino->camera.owner); + spin_lock(&Vino->input_lock); + if (v->input == VINO_INPUT_CAMERA) { + if (Vino->camera.owner == v->chan) { + spin_unlock(&Vino->input_lock); + memcpy(&v->picture, pic, + sizeof(struct video_picture)); + i2c_camera_command(DECODER_SET_PICTURE, pic); + goto out_unlocked; + } + } else { + if (Vino->decoder.owner == v->chan) { + spin_unlock(&Vino->input_lock); + memcpy(&v->picture, pic, + sizeof(struct video_picture)); + i2c_decoder_command(DECODER_SET_PICTURE, pic); + goto out_unlocked; + } + } + spin_unlock(&Vino->input_lock); +out_unlocked: + break; + } + /* get cropping */ + case VIDIOCGCAPTURE: { + struct video_capture *capture = arg; + + capture->x = v->left; + capture->y = v->top; + capture->width = v->right - v->left; + capture->height = v->bottom - v->top; + capture->decimation = v->decimation; + capture->flags = 0; + break; + } + /* set cropping */ + case VIDIOCSCAPTURE: { + struct video_capture *capture = arg; + + return set_clipping(v, capture->x, capture->y, capture->width, + capture->height, capture->decimation); + } + /* get scaling */ + case VIDIOCGWIN: { + struct video_window *win = arg; + + memset(win, 0, sizeof(*win)); + win->width = (v->right - v->left) / v->decimation; + win->height = (v->bottom - v->top) / v->decimation; + break; + } + /* set scaling */ + case VIDIOCSWIN: { + struct video_window *win = arg; + + if (win->x || win->y || win->clipcount || win->clips) + return -EINVAL; + return set_scaling(v, win->width, win->height); + } + case VIDIOCGMBUF: { + struct video_mbuf *buf = arg; + + buf->frames = 1; + buf->offsets[0] = 0; + buf->size = v->page_count * PAGE_SIZE; + break; + } + case VIDIOCMCAPTURE: { + struct video_mmap *mmap = arg; + + if (mmap->width != v->right - v->left || + mmap->height != v->bottom - v->top || + mmap->format != v->picture.palette || + mmap->frame != 0) + return -EINVAL; + + return vino_grab(v, mmap->frame); + } + case VIDIOCSYNC: + return vino_waitfor(v, *((int*)arg)); + default: + return -ENOIOCTLCMD; + } return 0; } -#ifdef MODULE -int init_module(void) +static int vino_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { + struct video_device *dev = video_devdata(file); + struct vino_device *v = dev->priv; int err; - err = vino_init(); - if (err) - return err; + if (down_interruptible(&v->sem)) + return -EINTR; + err = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); + up(&v->sem); + return err; +} + +static struct file_operations vino_fops = { + .owner = THIS_MODULE, + .open = vino_open, + .release = vino_close, + .ioctl = vino_ioctl, + .mmap = vino_mmap, + .llseek = no_llseek, +}; + +static const struct video_device vino_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE, + .hardware = VID_HARDWARE_VINO, + .name = "VINO", + .fops = &vino_fops, + .minor = -1, +}; + +static void init_channel_data(struct vino_device *v, int channel) +{ + init_waitqueue_head(&v->dma_wait); + init_MUTEX(&v->sem); + spin_lock_init(&v->state_lock); + memcpy(&v->vdev, &vino_template, sizeof(vino_template)); + v->vdev.priv = v; + v->chan = channel; + v->input = -1; + v->picture.palette = VIDEO_PALETTE_GREY; + v->picture.depth = 8; + v->buffer_state = VINO_BUF_UNUSED; + v->users = 0; + set_clipping(v, 0, 0, VINO_NTSC_WIDTH, VINO_NTSC_HEIGHT, 1); +} + +static int __init vino_init(void) +{ + unsigned long rev; + dma_addr_t dma; + int i, ret = 0; + + /* VINO is Indy specific beast */ + if (ip22_is_fullhouse()) + return -ENODEV; + + /* + * VINO is in the EISA address space, so the sysid register will tell + * us if the EISA_PRESENT pin on MC has been pulled low. + * + * If EISA_PRESENT is not set we definitely don't have a VINO equiped + * system. + */ + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_ERR "VINO not found\n"); + return -ENODEV; + } + + vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); + if (!vino) + return -EIO; + + /* Okay, once we know that VINO is present we'll read its revision + * safe way. One never knows... */ + if (get_dbe(rev, &(vino->rev_id))) { + printk(KERN_ERR "VINO: failed to read revision register\n"); + ret = -ENODEV; + goto out_unmap; + } + if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) { + printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev); + ret = -ENODEV; + goto out_unmap; + } + printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev)); + + Vino = (struct vino_video *) + kmalloc(sizeof(struct vino_video), GFP_KERNEL); + if (!Vino) { + ret = -ENOMEM; + goto out_unmap; + } + memset(Vino, 0, sizeof(struct vino_video)); + + Vino->dummy_desc = get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!Vino->dummy_desc) { + ret = -ENOMEM; + goto out_free_vino; + } + Vino->dummy_dma.cpu = pci_alloc_consistent(NULL, 4 * sizeof(dma_addr_t), + &Vino->dummy_dma.dma); + if (!Vino->dummy_dma.cpu) { + ret = -ENOMEM; + goto out_free_dummy_desc; + } + dma = pci_map_single(NULL, (void *)Vino->dummy_desc, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + for (i = 0; i < 4; i++) + Vino->dummy_dma.cpu[i] = dma; + + vino->control = 0; + /* prevent VINO from throwing spurious interrupts */ + vino->a.next_4_desc = Vino->dummy_dma.dma; + vino->b.next_4_desc = Vino->dummy_dma.dma; + udelay(5); + vino->intr_status = 0; + /* set threshold level */ + vino->a.fifo_thres = threshold_a; + vino->b.fifo_thres = threshold_b; + + spin_lock_init(&Vino->vino_lock); + spin_lock_init(&Vino->input_lock); + init_channel_data(&Vino->chA, VINO_CHAN_A); + init_channel_data(&Vino->chB, VINO_CHAN_B); + + if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) { + printk(KERN_ERR "VINO: request irq%02d failed\n", + SGI_VINO_IRQ); + ret = -EAGAIN; + goto out_unmap_dummy_desc; + } + ret = vino_i2c_add_bus(); + if (ret) { + printk(KERN_ERR "VINO: I2C bus registration failed\n"); + goto out_free_irq; + } + + if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) { + printk("%s, chnl %d: device registration failed.\n", + Vino->chA.vdev.name, Vino->chA.chan); + ret = -EINVAL; + goto out_i2c_del_bus; + } + if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) { + printk("%s, chnl %d: device registration failed.\n", + Vino->chB.vdev.name, Vino->chB.chan); + ret = -EINVAL; + goto out_unregister_vdev; + } + +#if defined(CONFIG_KMOD) && defined (MODULE) + request_module("saa7191"); + request_module("indycam"); +#endif return 0; + +out_unregister_vdev: + video_unregister_device(&Vino->chA.vdev); +out_i2c_del_bus: + vino_i2c_del_bus(); +out_free_irq: + free_irq(SGI_VINO_IRQ, NULL); +out_unmap_dummy_desc: + pci_unmap_single(NULL, Vino->dummy_dma.dma, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + pci_free_consistent(NULL, 4 * sizeof(dma_addr_t), + (void *)Vino->dummy_dma.cpu, Vino->dummy_dma.dma); +out_free_dummy_desc: + free_page(Vino->dummy_desc); +out_free_vino: + kfree(Vino); +out_unmap: + iounmap(vino); + + return ret; } -void cleanup_module(void) +static void __exit vino_exit(void) { + video_unregister_device(&Vino->chA.vdev); + video_unregister_device(&Vino->chB.vdev); + vino_i2c_del_bus(); + free_irq(SGI_VINO_IRQ, NULL); + pci_unmap_single(NULL, Vino->dummy_dma.dma, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + pci_free_consistent(NULL, 4 * sizeof(dma_addr_t), + (void *)Vino->dummy_dma.cpu, Vino->dummy_dma.dma); + free_page(Vino->dummy_desc); + kfree(Vino); + iounmap(vino); } -#endif + +module_init(vino_init); +module_exit(vino_exit); + +MODULE_AUTHOR("Ladislav Michl "); +MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/media/video/vino.h linux-2.4.25/drivers/media/video/vino.h --- linux-2.4.24/drivers/media/video/vino.h 2001-09-07 09:28:38.000000000 -0700 +++ linux-2.4.25/drivers/media/video/vino.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,64 +1,85 @@ /* - * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se) - * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Ulf Karlsson + * Copyright (C) 2003 Ladislav Michl */ -#define VINO_BASE 0x00080000 /* In EISA address space */ +#ifndef VINO_H +#define VINO_H -#define VINO_REVID 0x0000 -#define VINO_CTRL 0x0008 -#define VINO_INTSTAT 0x0010 /* Interrupt status */ -#define VINO_I2C_CTRL 0x0018 -#define VINO_I2C_DATA 0x0020 -#define VINO_A_ALPHA 0x0028 /* Channel A ... */ -#define VINO_A_CLIPS 0x0030 /* Clipping start */ -#define VINO_A_CLIPE 0x0038 /* Clipping end */ -#define VINO_A_FRAMERT 0x0040 /* Framerate */ -#define VINO_A_FLDCNT 0x0048 /* Field counter */ -#define VINO_A_LNSZ 0x0050 -#define VINO_A_LNCNT 0x0058 -#define VINO_A_PGIX 0x0060 /* Page index */ -#define VINO_A_DESC_PTR 0x0068 /* Ptr to next four descriptors */ -#define VINO_A_DESC_TLB_PTR 0x0070 /* Ptr to start of descriptor table */ -#define VINO_A_DESC_DATA0 0x0078 /* Descriptor data 0 */ -#define VINO_A_DESC_DATA1 0x0080 /* ... */ -#define VINO_A_DESC_DATA2 0x0088 -#define VINO_A_DESC_DATA3 0x0090 -#define VINO_A_FIFO_THRESHOLD 0x0098 /* FIFO threshold */ -#define VINO_A_FIFO_RP 0x00a0 -#define VINO_A_FIFO_WP 0x00a8 -#define VINO_B_ALPHA 0x00b0 /* Channel B ... */ -#define VINO_B_CLIPS 0x00b8 -#define VINO_B_CLIPE 0x00c0 -#define VINO_B_FRAMERT 0x00c8 -#define VINO_B_FLDCNT 0x00d0 -#define VINO_B_LNSZ 0x00d8 -#define VINO_B_LNCNT 0x00e0 -#define VINO_B_PGIX 0x00e8 -#define VINO_B_DESC_PTR 0x00f0 -#define VINO_B_DESC_TLB_PTR 0x00f8 -#define VINO_B_DESC_DATA0 0x0100 -#define VINO_B_DESC_DATA1 0x0108 -#define VINO_B_DESC_DATA2 0x0110 -#define VINO_B_DESC_DATA3 0x0118 -#define VINO_B_FIFO_THRESHOLD 0x0120 -#define VINO_B_FIFO_RP 0x0128 -#define VINO_B_FIFO_WP 0x0130 - -/* Bits in the VINO_REVID register */ - -#define VINO_REVID_REV_MASK 0x000f /* bits 0:3 */ -#define VINO_REVID_ID_MASK 0x00f0 /* bits 4:7 */ - -/* Bits in the VINO_CTRL register */ +#define VINO_BASE 0x00080000 /* Vino is in the EISA address space, + * but it is not an EISA bus card */ +#define VINO_PAGE_SIZE 4096 + +struct sgi_vino_channel { + u32 _pad_alpha; + volatile u32 alpha; + +#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */ +#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */ +#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */ + u32 _pad_clip_start; + volatile u32 clip_start; + u32 _pad_clip_end; + volatile u32 clip_end; + +#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ +#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */ + u32 _pad_frame_rate; + volatile u32 frame_rate; + + u32 _pad_field_counter; + volatile u32 field_counter; + u32 _pad_line_size; + volatile u32 line_size; + u32 _pad_line_count; + volatile u32 line_count; + u32 _pad_page_index; + volatile u32 page_index; + u32 _pad_next_4_desc; + volatile u32 next_4_desc; + u32 _pad_start_desc_tbl; + volatile u32 start_desc_tbl; + +#define VINO_DESC_JUMP (1<<30) +#define VINO_DESC_STOP (1<<31) +#define VINO_DESC_VALID (1<<32) + u32 _pad_desc_0; + volatile u32 desc_0; + u32 _pad_desc_1; + volatile u32 desc_1; + u32 _pad_desc_2; + volatile u32 desc_2; + u32 _pad_Bdesc_3; + volatile u32 desc_3; + + u32 _pad_fifo_thres; + volatile u32 fifo_thres; + u32 _pad_fifo_read; + volatile u32 fifo_read; + u32 _pad_fifo_write; + volatile u32 fifo_write; +}; + +struct sgi_vino { +#define VINO_CHIP_ID 0xb +#define VINO_REV_NUM(x) ((x) & 0x0f) +#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4) + u32 _pad_rev_id; + volatile u32 rev_id; #define VINO_CTRL_LITTLE_ENDIAN (1<<0) -#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */ -#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */ -#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */ -#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */ -#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */ -#define VINO_CTRL_B_END_DESC_TLB_INT (1<<6) /* End of desc table int */ +#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */ +#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */ +#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */ +#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \ + VINO_CTRL_A_FIFO_INT | \ + VINO_CTRL_A_EOD_INT) +#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */ +#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */ +#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */ +#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \ + VINO_CTRL_B_FIFO_INT | \ + VINO_CTRL_B_EOD_INT) #define VINO_CTRL_A_DMA_ENBL (1<<7) #define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8) #define VINO_CTRL_A_SYNC_ENBL (1<<9) @@ -67,51 +88,45 @@ #define VINO_CTRL_A_LUMA_ONLY (1<<12) #define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */ #define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */ +#define VINO_CTRL_A_DEC_SCALE_SHIFT (14) #define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */ #define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */ #define VINO_CTRL_B_DMA_ENBL (1<<19) #define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20) #define VINO_CTRL_B_SYNC_ENBL (1<<21) #define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */ -#define VINO_CTRL_B_RGB (1<<22) /* 1=RGB 0=YUV */ -#define VINO_CTRL_B_LUMA_ONLY (1<<23) -#define VINO_CTRL_B_DEC_ENBL (1<<24) /* Decimation */ -#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 25:28 */ +#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */ +#define VINO_CTRL_B_LUMA_ONLY (1<<24) +#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */ +#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */ +#define VINO_CTRL_B_DEC_SCALE_SHIFT (26) #define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */ #define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */ + u32 _pad_control; + volatile u32 control; -/* Bits in the Interrupt and Status register */ - -#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */ -#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */ -#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */ -#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */ -#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */ -#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */ - -/* Bits in the Clipping Start register */ - -#define VINO_CLIPS_START 0x3ff /* bits 0:9 */ -#define VINO_CLIPS_ODD_MASK 0x7fc00 /* bits 10:18 */ -#define VINO_CLIPS_EVEN_MASK 0xff80000 /* bits 19:27 */ - -/* Bits in the Clipping End register */ - -#define VINO_CLIPE_END 0x3ff /* bits 0:9 */ -#define VINO_CLIPE_ODD_MASK 0x7fc00 /* bits 10:18 */ -#define VINO_CLIPE_EVEN_MASK 0xff80000 /* bits 19:27 */ - -/* Bits in the Frame Rate register */ - -#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ -#define VINO_FRAMERT_RT_MASK 0x1ffe /* bits 1:12 */ - -/* Bits in the VINO_I2C_CTRL */ +#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */ +#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */ +#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */ +#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \ + VINO_INTSTAT_A_FIFO | \ + VINO_INTSTAT_A_EOD) +#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */ +#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */ +#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */ +#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \ + VINO_INTSTAT_B_FIFO | \ + VINO_INTSTAT_B_EOD) + u32 _pad_intr_status; + volatile u32 intr_status; + + u32 _pad_i2c_control; + volatile u32 i2c_control; + u32 _pad_i2c_data; + volatile u32 i2c_data; + + struct sgi_vino_channel a; + struct sgi_vino_channel b; +}; -#define VINO_CTRL_I2C_IDLE (1<<0) /* write: 0=force idle - * read: 0=idle 1=not idle */ -#define VINO_CTRL_I2C_DIR (1<<1) /* 0=read 1=write */ -#define VINO_CTRL_I2C_MORE_BYTES (1<<2) /* 0=last byte 1=more bytes */ -#define VINO_CTRL_I2C_TRANS_BUSY (1<<4) /* 0=trans done 1=trans busy */ -#define VINO_CTRL_I2C_ACK (1<<5) /* 0=ack received 1=ack not */ -#define VINO_CTRL_I2C_BUS_ERROR (1<<7) /* 0=no bus err 1=bus err */ +#endif diff -urN linux-2.4.24/drivers/message/fusion/isense.c linux-2.4.25/drivers/message/fusion/isense.c --- linux-2.4.24/drivers/message/fusion/isense.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/isense.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,7 @@ * Written By: Steven J. Ralston * (yes I wrote some of the orig. code back in 1991!) * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: isense.c,v 1.34 2003/03/18 22:49:48 pdelaney Exp $ */ diff -urN linux-2.4.24/drivers/message/fusion/linux_compat.h linux-2.4.25/drivers/message/fusion/linux_compat.h --- linux-2.4.24/drivers/message/fusion/linux_compat.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/message/fusion/linux_compat.h 2004-02-18 05:36:31.000000000 -0800 @@ -11,6 +11,11 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +#if (defined(__sparc__) && defined(__sparc_v9__)) || defined(__x86_64__) +#define MPT_CONFIG_COMPAT +#endif + #ifndef rwlock_init #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) #endif @@ -267,9 +272,9 @@ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) -#define mptscsih_sync_irq(_irq) synchronize_irq(_irq) +#define mpt_sync_irq(_irq) synchronize_irq(_irq) #else -#define mptscsih_sync_irq(_irq) synchronize_irq() +#define mpt_sync_irq(_irq) synchronize_irq() #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,58) diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi.h linux-2.4.25/drivers/message/fusion/lsi/mpi.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI.H * Title: MPI Message independent structures and definitions * Creation Date: July 27, 2000 * - * MPI.H Version: 01.02.07 + * MPI.H Version: 01.02.10 * * Version History * --------------- @@ -48,6 +48,10 @@ * 05-31-02 01.02.05 Bumped MPI_HEADER_VERSION_UNIT. * 07-12-02 01.02.06 Added define for MPI_FUNCTION_MAILBOX. * 09-16-02 01.02.07 Bumped value for MPI_HEADER_VERSION_UNIT. + * 11-15-02 01.02.08 Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and + * obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX. + * 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED + * 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value. * -------------------------------------------------------------------------- */ @@ -76,7 +80,7 @@ /* Note: The major versions of 0xe0 through 0xff are reserved */ /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT (0x09) +#define MPI_HEADER_VERSION_UNIT (0x0C) #define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_SHIFT (8) @@ -618,7 +622,8 @@ #define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060) #define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061) -#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) +#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete */ +#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) #define MPI_IOCSTATUS_TARGET_ABORTED (0x0063) #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) #define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) @@ -642,6 +647,7 @@ #define MPI_IOCSTATUS_FC_RX_ID_INVALID (0x0067) #define MPI_IOCSTATUS_FC_DID_INVALID (0x0068) #define MPI_IOCSTATUS_FC_NODE_LOGGED_OUT (0x0069) +#define MPI_IOCSTATUS_FC_EXCHANGE_CANCELED (0x006C) /****************************************************************************/ /* LAN values */ diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_cnfg.h linux-2.4.25/drivers/message/fusion/lsi/mpi_cnfg.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_cnfg.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_cnfg.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_CNFG.H * Title: MPI Config message, structures, and Pages * Creation Date: July 27, 2000 * - * MPI_CNFG.H Version: 01.02.09 + * MPI_CNFG.H Version: 01.02.12 * * Version History * --------------- @@ -127,7 +127,24 @@ * MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE. * Added new config page: CONFIG_PAGE_SCSI_DEVICE_3. * Modified MPI_FCPORTPAGE5_FLAGS_ defines. - * 09-16-02 01.02.09 Added more MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 09-16-02 01.02.09 Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define. + * 11-15-02 01.02.10 Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0. + * 04-01-03 01.02.11 Added RR_TOV field and additional Flags defines for + * CONFIG_PAGE_FC_PORT_1. + * Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable + * an alias. + * Added more device id defines. + * 06-26-03 01.02.12 Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define. + * Added TargetConfig and IDConfig fields to + * CONFIG_PAGE_SCSI_PORT_1. + * Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2 + * to control DV. + * Added more Flags defines for CONFIG_PAGE_FC_PORT_1. + * In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field + * with ADISCHardALPA. + * Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define. * -------------------------------------------------------------------------- */ @@ -281,6 +298,9 @@ /**************************************************************************** * Manufacturing Config pages ****************************************************************************/ +#define MPI_MANUFACTPAGE_VENDORID_LSILOGIC (0x1000) +#define MPI_MANUFACTPAGE_VENDORID_TREBIA (0x1783) + #define MPI_MANUFACTPAGE_DEVICEID_FC909 (0x0621) #define MPI_MANUFACTPAGE_DEVICEID_FC919 (0x0624) #define MPI_MANUFACTPAGE_DEVICEID_FC929 (0x0622) @@ -299,6 +319,10 @@ #define MPI_MANUFACTPAGE_DEVID_SA2020 (0x0806) #define MPI_MANUFACTPAGE_DEVID_SA2020ZC (0x0807) +#define MPI_MANUFACTPAGE_DEVID_SNP1000 (0x0010) +#define MPI_MANUFACTPAGE_DEVID_SNP500 (0x0020) + + typedef struct _CONFIG_PAGE_MANUFACTURING_0 { @@ -422,6 +446,7 @@ #define MPI_IOUNITPAGE1_SINGLE_FUNCTION (0x00000001) #define MPI_IOUNITPAGE1_MULTI_PATHING (0x00000002) #define MPI_IOUNITPAGE1_SINGLE_PATHING (0x00000000) +#define MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) #define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040) #define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) @@ -694,6 +719,10 @@ #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD (0x01) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE (0x02) #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD (0x03) +#define MPI_SCSIPORTPAGE0_PHY_MASK_CONNECTED_ID (0xFF000000) +#define MPI_SCSIPORTPAGE0_PHY_SHIFT_CONNECTED_ID (24) +#define MPI_SCSIPORTPAGE0_PHY_BUS_FREE_CONNECTED_ID (0xFE) +#define MPI_SCSIPORTPAGE0_PHY_UNKNOWN_CONNECTED_ID (0xFF) typedef struct _CONFIG_PAGE_SCSI_PORT_1 @@ -701,14 +730,22 @@ fCONFIG_PAGE_HEADER Header; /* 00h */ U32 Configuration; /* 04h */ U32 OnBusTimerValue; /* 08h */ + U8 TargetConfig; /* 0Ch */ + U8 Reserved1; /* 0Dh */ + U16 IDConfig; /* 0Eh */ } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1, SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t; #define MPI_SCSIPORTPAGE1_PAGEVERSION (0x02) +/* Configuration values */ #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF) #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000) +/* TargetConfig values */ +#define MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY (0x01) +#define MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG (0x02) + typedef struct _MPI_DEVICE_INFO { @@ -727,13 +764,20 @@ } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2, SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t; -#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x01) +#define MPI_SCSIPORTPAGE2_PAGEVERSION (0x02) +/* PortFlags values */ #define MPI_SCSIPORTPAGE2_PORT_FLAGS_SCAN_HIGH_TO_LOW (0x00000001) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET (0x00000004) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_ALTERNATE_CHS (0x00000008) #define MPI_SCSIPORTPAGE2_PORT_FLAGS_TERMINATION_DISABLE (0x00000010) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK (0x00000060) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_FULL_DV (0x00000000) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY (0x00000020) +#define MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV (0x00000060) + +/* PortSettings values */ #define MPI_SCSIPORTPAGE2_PORT_HOST_ID_MASK (0x0000000F) #define MPI_SCSIPORTPAGE2_PORT_MASK_INIT_HBA (0x00000030) #define MPI_SCSIPORTPAGE2_PORT_DISABLE_INIT_HBA (0x00000000) @@ -915,7 +959,7 @@ #define MPI_FCPORTPAGE0_FLAGS_ALIAS_ALPA_SUPPORTED (0x00000010) #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED (0x00000020) -#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000030) +#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000040) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000F00) #define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000000) @@ -974,15 +1018,23 @@ U8 TopologyConfig; /* 1Ah */ U8 AltConnector; /* 1Bh */ U8 NumRequestedAliases; /* 1Ch */ - U8 Reserved1; /* 1Dh */ + U8 RR_TOV; /* 1Dh */ U16 Reserved2; /* 1Eh */ } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1, FCPortPage1_t, MPI_POINTER pFCPortPage1_t; -#define MPI_FCPORTPAGE1_PAGEVERSION (0x04) +#define MPI_FCPORTPAGE1_PAGEVERSION (0x05) #define MPI_FCPORTPAGE1_FLAGS_EXT_FCP_STATUS_EN (0x08000000) #define MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY (0x04000000) +#define MPI_FCPORTPAGE1_FLAGS_FORCE_USE_NOSEEPROM_WWNS (0x02000000) +#define MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS (0x01000000) +#define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID (0x00800000) +#define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE (0x00400000) +#define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS (0x00000070) +#define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG (0x00000008) +#define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO (0x00000004) +#define MPI_FCPORTPAGE1_FLAGS_MAINTAIN_LOGINS (0x00000002) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_DID (0x00000001) #define MPI_FCPORTPAGE1_FLAGS_SORT_BY_WWN (0x00000000) @@ -993,6 +1045,11 @@ #define MPI_FCPORTPAGE1_FLAGS_PROT_LAN ((U32)MPI_PORTFACTS_PROTOCOL_LAN << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) #define MPI_FCPORTPAGE1_FLAGS_PROT_LOGBUSADDR ((U32)MPI_PORTFACTS_PROTOCOL_LOGBUSADDR << MPI_FCPORTPAGE1_FLAGS_PROT_SHIFT) +#define MPI_FCPORTPAGE1_FLAGS_NONE_RR_TOV_UNITS (0x00000000) +#define MPI_FCPORTPAGE1_FLAGS_THOUSANDTH_RR_TOV_UNITS (0x00000010) +#define MPI_FCPORTPAGE1_FLAGS_TENTH_RR_TOV_UNITS (0x00000030) +#define MPI_FCPORTPAGE1_FLAGS_TEN_RR_TOV_UNITS (0x00000050) + #define MPI_FCPORTPAGE1_HARD_ALPA_NOT_USED (0xFF) #define MPI_FCPORTPAGE1_LCONFIG_SPEED_MASK (0x0F) @@ -1108,12 +1165,13 @@ } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5, FCPortPage5_t, MPI_POINTER pFCPortPage5_t; -#define MPI_FCPORTPAGE5_PAGEVERSION (0x01) +#define MPI_FCPORTPAGE5_PAGEVERSION (0x02) #define MPI_FCPORTPAGE5_FLAGS_ALPA_ACQUIRED (0x01) #define MPI_FCPORTPAGE5_FLAGS_HARD_ALPA (0x02) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWNN (0x04) #define MPI_FCPORTPAGE5_FLAGS_HARD_WWPN (0x08) +#define MPI_FCPORTPAGE5_FLAGS_DISABLE (0x10) typedef struct _CONFIG_PAGE_FC_PORT_6 { @@ -1322,7 +1380,7 @@ U8 Flags; /* 19h */ U16 BBCredit; /* 1Ah */ U16 MaxRxFrameSize; /* 1Ch */ - U8 Reserved1; /* 1Eh */ + U8 ADISCHardALPA; /* 1Eh */ U8 PortNumber; /* 1Fh */ U8 FcPhLowestVersion; /* 20h */ U8 FcPhHighestVersion; /* 21h */ @@ -1331,13 +1389,16 @@ } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0, FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t; -#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x02) +#define MPI_FC_DEVICE_PAGE0_PAGEVERSION (0x03) #define MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID (0x01) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID (0x02) +#define MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID (0x04) #define MPI_FC_DEVICE_PAGE0_PROT_IP (0x01) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET (0x02) #define MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR (0x04) +#define MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY (0x08) #define MPI_FC_DEVICE_PAGE0_PGAD_PORT_MASK (MPI_FC_DEVICE_PGAD_PORT_MASK) #define MPI_FC_DEVICE_PAGE0_PGAD_FORM_MASK (MPI_FC_DEVICE_PGAD_FORM_MASK) @@ -1348,6 +1409,7 @@ #define MPI_FC_DEVICE_PAGE0_PGAD_BUS_SHIFT (MPI_FC_DEVICE_PGAD_BT_BUS_SHIFT) #define MPI_FC_DEVICE_PAGE0_PGAD_TID_MASK (MPI_FC_DEVICE_PGAD_BT_TID_MASK) +#define MPI_FC_DEVICE_PAGE0_HARD_ALPA_UNKNOWN (0xFF) /**************************************************************************** * RAID Volume Config Pages diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_init.h linux-2.4.25/drivers/message/fusion/lsi/mpi_init.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_init.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_init.h 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ * Title: MPI initiator mode messages and structures * Creation Date: June 8, 2000 * - * MPI_INIT.H Version: 01.02.05 + * MPI_INIT.H Version: 01.02.07 * * Version History * --------------- @@ -31,6 +31,8 @@ * 10-04-01 01.02.04 Added defines for SEP request Action field. * 05-31-02 01.02.05 Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define * for SCSI IO requests. + * 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP. + * 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define. * -------------------------------------------------------------------------- */ @@ -153,6 +155,10 @@ #define MPI_SCSI_STATUS_TASK_SET_FULL (0x28) #define MPI_SCSI_STATUS_ACA_ACTIVE (0x30) +#define MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT (0x80) +#define MPI_SCSI_STATUS_FCPEXT_NO_LINK (0x81) +#define MPI_SCSI_STATUS_FCPEXT_UNASSIGNED (0x82) + /* SCSI IO Reply SCSIState values */ diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_ioc.h linux-2.4.25/drivers/message/fusion/lsi/mpi_ioc.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_ioc.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_ioc.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_IOC.H * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: August 11, 2000 * - * MPI_IOC.H Version: 01.02.06 + * MPI_IOC.H Version: 01.02.08 * * Version History * --------------- @@ -55,6 +55,8 @@ * 05-31-02 01.02.06 Added define for * MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID. * Added AliasIndex to EVENT_DATA_LOGOUT structure. + * 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_. + * 06-26-03 01.02.08 Added new values to the product family defines. * -------------------------------------------------------------------------- */ @@ -654,6 +656,10 @@ #define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000) #define MPI_FW_HEADER_PID_TYPE_FC (0x1000) +#define MPI_FW_HEADER_SIGNATURE_0 (0x5AEAA55A) +#define MPI_FW_HEADER_SIGNATURE_1 (0xA55AEAA5) +#define MPI_FW_HEADER_SIGNATURE_2 (0x5AA55AEA) + #define MPI_FW_HEADER_PID_PROD_MASK (0x0F00) #define MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI (0x0100) #define MPI_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200) @@ -673,6 +679,8 @@ #define MPI_FW_HEADER_PID_FAMILY_1020C0_SCSI (0x0008) #define MPI_FW_HEADER_PID_FAMILY_1035A0_SCSI (0x0009) #define MPI_FW_HEADER_PID_FAMILY_1035B0_SCSI (0x000A) +#define MPI_FW_HEADER_PID_FAMILY_1030TA0_SCSI (0x000B) +#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI (0x000C) #define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000) #define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001) #define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002) diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_raid.h linux-2.4.25/drivers/message/fusion/lsi/mpi_raid.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_raid.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_raid.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2001-2002 LSI Logic Corporation. + * Copyright (c) 2001-2003 LSI Logic Corporation. * * * Name: MPI_RAID.H * Title: MPI RAID message and structures * Creation Date: February 27, 2001 * - * MPI_RAID.H Version: 01.02.07 + * MPI_RAID.H Version: 01.02.09 * * Version History * --------------- @@ -25,6 +25,9 @@ * MPI_RAID_ACTION_INACTIVATE_VOLUME, and * MPI_RAID_ACTION_ADATA_INACTIVATE_ALL. * 07-12-02 01.02.07 Added structures for Mailbox request and reply. + * 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST. + * 04-01-03 01.02.09 New action data option flag for + * MPI_RAID_ACTION_DELETE_VOLUME. * -------------------------------------------------------------------------- */ @@ -90,6 +93,9 @@ #define MPI_RAID_ACTION_ADATA_KEEP_PHYS_DISKS (0x00000000) #define MPI_RAID_ACTION_ADATA_DEL_PHYS_DISKS (0x00000001) +#define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) +#define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002) + /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */ #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001) @@ -195,6 +201,7 @@ U16 Reserved2; U8 Reserved3; U8 MsgFlags; + U32 MsgContext; U8 Command[10]; U16 Reserved4; SGE_IO_UNION SGL; diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_targ.h linux-2.4.25/drivers/message/fusion/lsi/mpi_targ.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_targ.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_targ.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2002 LSI Logic Corporation. + * Copyright (c) 2000-2003 LSI Logic Corporation. * * * Name: MPI_TARG.H * Title: MPI Target mode messages and structures * Creation Date: June 22, 2000 * - * MPI_TARG.H Version: 01.02.07 + * MPI_TARG.H Version: 01.02.09 * * Version History * --------------- @@ -41,6 +41,8 @@ * Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER. * 09-16-02 01.02.07 Added flags for confirmed completion. * Added PRIORITY_REASON_TARGET_BUSY. + * 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER. + * 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER. * -------------------------------------------------------------------------- */ @@ -171,7 +173,7 @@ U32 FcpDl; /* 1Ch */ U8 AliasIndex; /* 20h */ U8 Reserved1; /* 21h */ - U16 Reserved2; /* 22h */ + U16 OptionalOxid; /* 22h */ } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER, MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer; @@ -190,6 +192,10 @@ U8 TaskManagementFlags; /* 12h */ U8 AdditionalCDBLength; /* 13h */ U8 CDB[16]; /* 14h */ + /* Alias ID */ + U8 AliasID; /* 24h */ + U8 Reserved1; /* 25h */ + U16 Reserved2; /* 26h */ } MPI_TARGET_SCSI_SPI_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER, MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer; diff -urN linux-2.4.24/drivers/message/fusion/lsi/mpi_tool.h linux-2.4.25/drivers/message/fusion/lsi/mpi_tool.h --- linux-2.4.24/drivers/message/fusion/lsi/mpi_tool.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/message/fusion/lsi/mpi_tool.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2001 LSI Logic Corporation. + * + * + * Name: MPI_TOOL.H + * Title: MPI Toolbox structures and definitions + * Creation Date: July 30, 2001 + * + * MPI Version: 01.02.02 + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * 08-08-01 01.02.01 Original release. + * 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI_TOOL_H +#define MPI_TOOL_H + +#define MPI_TOOLBOX_CLEAN_TOOL (0x00) +#define MPI_TOOLBOX_MEMORY_MOVE_TOOL (0x01) +#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) + + +/****************************************************************************/ +/* Toolbox reply */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_REPLY +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U16 Reserved3; /* 0Ch */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ +} MSG_TOOLBOX_REPLY, MPI_POINTER PTR_MSG_TOOLBOX_REPLY, + ToolboxReply_t, MPI_POINTER pToolboxReply_t; + + +/****************************************************************************/ +/* Toolbox Clean Tool request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_CLEAN_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Flags; /* 0Ch */ +} MSG_TOOLBOX_CLEAN_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_CLEAN_REQUEST, + ToolboxCleanRequest_t, MPI_POINTER pToolboxCleanRequest_t; + +#define MPI_TOOLBOX_CLEAN_NVSRAM (0x00000001) +#define MPI_TOOLBOX_CLEAN_SEEPROM (0x00000002) +#define MPI_TOOLBOX_CLEAN_FLASH (0x00000004) + + +/****************************************************************************/ +/* Toolbox Memory Move request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_MEM_MOVE_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + SGE_SIMPLE_UNION SGL; /* 0Ch */ +} MSG_TOOLBOX_MEM_MOVE_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_MEM_MOVE_REQUEST, + ToolboxMemMoveRequest_t, MPI_POINTER pToolboxMemMoveRequest_t; + + +/****************************************************************************/ +/* Toolbox Diagnostic Data Upload request */ +/****************************************************************************/ + +typedef struct _MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST +{ + U8 Tool; /* 00h */ + U8 Reserved; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 Reserved1; /* 04h */ + U8 Reserved2; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 Flags; /* 0Ch */ + U32 Reserved3; /* 10h */ + SGE_SIMPLE_UNION SGL; /* 14h */ +} MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, + ToolboxDiagDataUploadRequest_t, MPI_POINTER pToolboxDiagDataUploadRequest_t; + +typedef struct _DIAG_DATA_UPLOAD_HEADER +{ + U32 DiagDataLength; /* 00h */ + U8 FormatCode; /* 04h */ + U8 Reserved; /* 05h */ + U16 Reserved1; /* 06h */ +} DIAG_DATA_UPLOAD_HEADER, MPI_POINTER PTR_DIAG_DATA_UPLOAD_HEADER, + DiagDataUploadHeader_t, MPI_POINTER pDiagDataUploadHeader_t; + +#define MPI_TB_DIAG_FORMAT_SCSI_PRINTF_1 (0x01) +#define MPI_TB_DIAG_FORMAT_SCSI_2 (0x02) +#define MPI_TB_DIAG_FORMAT_SCSI_3 (0x03) +#define MPI_TB_DIAG_FORMAT_FC_TRACE_1 (0x04) + + +#endif + + diff -urN linux-2.4.24/drivers/message/fusion/mptbase.c linux-2.4.25/drivers/message/fusion/mptbase.c --- linux-2.4.24/drivers/message/fusion/mptbase.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/mptbase.c 2004-02-18 05:36:31.000000000 -0800 @@ -47,7 +47,7 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: mptbase.c,v 1.130 2003/05/07 14:08:30 pdelaney Exp $ */ @@ -211,6 +211,7 @@ static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); static int mpt_findImVolumes(MPT_ADAPTER *ioc); static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); +static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); static void mpt_timer_expired(unsigned long data); static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); @@ -319,14 +320,14 @@ MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mr; u32 pa; - int req_idx = -1; + int req_idx; int cb_idx; int type; int freeme; - int count = 0; ioc = bus_id; +#ifdef MPT_DEBUG_IRQ /* * Verify ioc pointer is ok */ @@ -341,6 +342,7 @@ return; } } +#endif /* * Drain the reply FIFO! @@ -493,17 +495,7 @@ spin_unlock_irqrestore(&ioc->FreeQlock, flags); } - count++; - dirqprintk((MYIOC_s_INFO_FMT "ISR processed frame #%d\n", ioc->name, count)); mb(); - - if (count >= MPT_MAX_REPLIES_PER_ISR) { - dirqprintk((MYIOC_s_INFO_FMT "ISR processed %d replies.", - ioc->name, count)); - dirqprintk((" Giving this ISR a break!\n")); - return; - } - } /* drain reply FIFO */ } @@ -814,7 +806,7 @@ MPT_FRAME_HDR* mpt_get_msg_frame(int handle, int iocid) { - MPT_FRAME_HDR *mf = NULL; + MPT_FRAME_HDR *mf; MPT_ADAPTER *iocp; unsigned long flags; @@ -846,6 +838,8 @@ iocp->mfcnt++; #endif } + else + mf = NULL; spin_unlock_irqrestore(&iocp->FreeQlock, flags); #ifdef MFCNT @@ -1114,10 +1108,12 @@ MPT_ADAPTER * mpt_adapter_find_first(void) { - MPT_ADAPTER *this = NULL; + MPT_ADAPTER *this; if (! Q_IS_EMPTY(&MptAdapters)) this = MptAdapters.head; + else + this = NULL; return this; } @@ -1132,10 +1128,12 @@ MPT_ADAPTER * mpt_adapter_find_next(MPT_ADAPTER *prev) { - MPT_ADAPTER *next = NULL; + MPT_ADAPTER *next; if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head)) next = prev->forw; + else + next = NULL; return next; } @@ -1285,7 +1283,11 @@ if (pci_enable_device(pdev)) return r; - if (!pci_set_dma_mask(pdev, mask)) { + /* For some kernels, broken kernel limits memory allocation for target mode + * driver. Shirron. Fixed in 2.4.20-8 + * if ((sizeof(dma_addr_t) == sizeof(u64)) && (!pci_set_dma_mask(pdev, mask))) { + */ + if ((!pci_set_dma_mask(pdev, mask))) { dprintk((KERN_INFO MYNAM ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); } else { if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) { @@ -1300,10 +1302,10 @@ printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } - memset(ioc, 0, sizeof(*ioc)); + memset(ioc, 0, sizeof(MPT_ADAPTER)); ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->pcidev = pdev; ioc->diagPending = 0; @@ -1419,13 +1421,12 @@ ioc->prod_name = "LSIFC929X"; { /* 929X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. + * for PCIX. Set MOST bits to zero. */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) { @@ -1433,13 +1434,12 @@ ioc->prod_name = "LSIFC919X"; { /* 919X Chip Fix. Set Split transactions level - * for PCIX. Set bits 5 - 6 to zero, turn on bit 4. + * for PCIX. Set MOST bits to zero. */ - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF9F; - pcixcmd |= 0x0010; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { @@ -1449,14 +1449,14 @@ u8 revision; /* 1030 Chip Fix. Disable Split transactions - * for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8) + * for PCIX. Set MOST bits to zero if Rev < C0( = 8). */ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); if (revision < 0x08) { - u16 pcixcmd = 0; - pci_read_config_word(pdev, 0x6a, &pcixcmd); - pcixcmd &= 0xFF8F; - pci_write_config_word(pdev, 0x6a, pcixcmd); + u8 pcixcmd; + pci_read_config_byte(pdev, 0x6a, &pcixcmd); + pcixcmd &= 0x8F; + pci_write_config_byte(pdev, 0x6a, pcixcmd); } } } @@ -1764,6 +1764,8 @@ /* Check, and possibly reset, the coalescing value */ mpt_read_ioc_pg_1(ioc); + + mpt_read_ioc_pg_4(ioc); } GetIoUnitPage2(ioc); @@ -1950,6 +1952,15 @@ kfree(this->spi_data.pIocPg3); this->spi_data.pIocPg3 = NULL; } + + if (freeup && this->spi_data.pIocPg4 != NULL) { + sz = this->spi_data.IocPg4Sz; + pci_free_consistent(this->pcidev, sz, + this->spi_data.pIocPg4, + this->spi_data.IocPg4_dma); + this->spi_data.pIocPg4 = NULL; + this->alloc_total -= sz; + } } } @@ -2346,7 +2357,7 @@ */ ioc->req_sz = MIN(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); ioc->req_depth = MIN(MPT_MAX_REQ_DEPTH, facts->GlobalCredits); - ioc->reply_sz = ioc->req_sz; + ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n", @@ -2609,8 +2620,8 @@ void * mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz) { - fw_image_t **cached_fw = NULL; - u8 *mem = NULL; + fw_image_t **cached_fw; + u8 *mem; dma_addr_t fw_dma; int alloc_total = 0; int bytes_left, bytes, num_frags; @@ -2758,7 +2769,7 @@ u8 reply[sizeof(FWUploadReply_t)]; FWUpload_t *prequest; FWUploadReply_t *preply; - FWUploadTCSGE_t *ptcsge = NULL; + FWUploadTCSGE_t *ptcsge; int sgeoffset; int ii, sz, reply_sz; int cmdStatus, freeMem = 0; @@ -2890,16 +2901,16 @@ static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) { - MpiFwHeader_t *FwHdr = NULL; + MpiFwHeader_t *FwHdr; MpiExtImageHeader_t *ExtHdr; - fw_image_t **pCached = NULL; + fw_image_t **pCached; int fw_sz; u32 diag0val; #ifdef MPT_DEBUG u32 diag1val = 0; #endif int count = 0; - u32 *ptru32 = NULL; + u32 *ptru32; u32 diagRwData; u32 nextImage; u32 ext_offset; @@ -4301,7 +4312,7 @@ static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) { - u8 *pbuf = NULL; + u8 *pbuf; dma_addr_t buf_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4387,7 +4398,6 @@ } if (pbuf) { pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } } @@ -4424,6 +4434,8 @@ /* Save the Port Page 2 data * (reformat into a 32bit quantity) */ + data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; + ioc->spi_data.PortFlags = data; for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { pdevice = &pPP2->DeviceSettings[ii]; data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | @@ -4433,7 +4445,6 @@ } pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); - pbuf = NULL; } } @@ -4509,8 +4520,8 @@ static int mpt_findImVolumes(MPT_ADAPTER *ioc) { - IOCPage2_t *pIoc2 = NULL; - ConfigPageIoc2RaidVol_t *pIocRv = NULL; + IOCPage2_t *pIoc2; + ConfigPageIoc2RaidVol_t *pIocRv; dma_addr_t ioc2_dma; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4587,10 +4598,7 @@ } done_and_free: - if (pIoc2) { - pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); - pIoc2 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); return rc; } @@ -4598,7 +4606,7 @@ int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) { - IOCPage3_t *pIoc3 = NULL; + IOCPage3_t *pIoc3; u8 *mem; CONFIGPARMS cfg; ConfigPageHeader_t header; @@ -4651,18 +4659,66 @@ } } - if (pIoc3) { - pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); - pIoc3 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); return 0; } static void +mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) +{ + IOCPage4_t *pIoc4; + CONFIGPARMS cfg; + ConfigPageHeader_t header; + dma_addr_t ioc4_dma; + int iocpage4sz; + + /* Read and save IOC Page 4 + */ + header.PageVersion = 0; + header.PageLength = 0; + header.PageNumber = 4; + header.PageType = MPI_CONFIG_PAGETYPE_IOC; + cfg.hdr = &header; + cfg.physAddr = -1; + cfg.pageAddr = 0; + cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; + cfg.dir = 0; + cfg.timeout = 0; + if (mpt_config(ioc, &cfg) != 0) + return; + + if (header.PageLength == 0) + return; + + if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { + iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ + pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); + if (!pIoc4) + return; + } else { + ioc4_dma = ioc->spi_data.IocPg4_dma; + iocpage4sz = ioc->spi_data.IocPg4Sz; + } + + /* Read the Page into dma memory. + */ + cfg.physAddr = ioc4_dma; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + if (mpt_config(ioc, &cfg) == 0) { + ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; + ioc->spi_data.IocPg4_dma = ioc4_dma; + ioc->spi_data.IocPg4Sz = iocpage4sz; + } else { + pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); + ioc->spi_data.pIocPg4 = NULL; + } +} + +static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) { - IOCPage1_t *pIoc1 = NULL; + IOCPage1_t *pIoc1; CONFIGPARMS cfg; ConfigPageHeader_t header; dma_addr_t ioc1_dma; @@ -4738,10 +4794,7 @@ } } - if (pIoc1) { - pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); - pIoc1 = NULL; - } + pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); return; } @@ -5428,7 +5481,7 @@ int rc; unsigned long flags; - dprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name)); #ifdef MFCNT printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); printk("MF count 0x%x !\n", ioc->mfcnt); @@ -5460,11 +5513,11 @@ for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { if (MptResetHandlers[ii]) { - dprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", + dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n", ioc->name, ii)); r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET); if (ioc->alt_ioc) { - dprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", + dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n", ioc->name, ioc->alt_ioc->name, ii)); r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET); } @@ -5486,7 +5539,7 @@ ioc->alt_ioc->diagPending = 0; spin_unlock_irqrestore(&ioc->diagLock, flags); - dprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); + dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); return rc; } @@ -5495,7 +5548,7 @@ static char * EventDescriptionStr(u8 event, u32 evData0) { - char *ds = NULL; + char *ds; switch(event) { case MPI_EVENT_NONE: @@ -6001,7 +6054,7 @@ fusion_exit(void) { MPT_ADAPTER *this; - struct pci_dev *pdev = NULL; + struct pci_dev *pdev; dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n")); @@ -6021,7 +6074,7 @@ this->active = 0; pdev = (struct pci_dev *)this->pcidev; - mptscsih_sync_irq(pdev->irq); + mpt_sync_irq(pdev->irq); /* Clear any lingering interrupt */ CHIPREG_WRITE32(&this->chip->IntStatus, 0); diff -urN linux-2.4.24/drivers/message/fusion/mptbase.h linux-2.4.25/drivers/message/fusion/mptbase.h --- linux-2.4.24/drivers/message/fusion/mptbase.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/mptbase.h 2004-02-18 05:36:31.000000000 -0800 @@ -11,7 +11,7 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: mptbase.h,v 1.149 2003/05/07 14:08:31 pdelaney Exp $ */ @@ -77,11 +77,11 @@ #endif #ifndef COPYRIGHT -#define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "2.05.05+" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.05+" +#define MPT_LINUX_VERSION_COMMON "2.05.11.03" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.11.03" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -96,7 +96,7 @@ #define MPT_MAX_BUS 1 /* Do not change */ #define MPT_MAX_FC_DEVICES 255 #define MPT_MAX_SCSI_DEVICES 16 -#define MPT_LAST_LUN 31 +#define MPT_LAST_LUN 255 #define MPT_SENSE_BUFFER_ALLOC 64 /* allow for 256 max sense alloc, but only 255 max request */ #if MPT_SENSE_BUFFER_ALLOC >= 256 @@ -127,6 +127,8 @@ #define MPT_MAX_FRAME_SIZE 128 #define MPT_DEFAULT_FRAME_SIZE 128 +#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ + #define MPT_SG_REQ_128_SCALE 1 #define MPT_SG_REQ_96_SCALE 2 #define MPT_SG_REQ_64_SCALE 4 @@ -245,6 +247,7 @@ MPIHeader_t hdr; SCSIIORequest_t scsireq; SCSIIOReply_t sreply; + ConfigReply_t configreply; MPIDefaultReply_t reply; MPT_FRAME_TRACKER frame; } u; @@ -398,12 +401,9 @@ ScsiCmndTracker SentQ; ScsiCmndTracker DoneQ; u32 num_luns; -//--- LUN split here? - u32 luns; /* Max LUNs is 32 */ - u8 inq_data[SCSI_STD_INQUIRY_BYTES]; /* 36 */ - u8 pad0[4]; - u8 inq00_data[20]; - u8 pad1[4]; + u32 luns[8]; /* Max LUNs is 256 */ + u8 pad[4]; + u8 inq_data[8]; /* IEEE Registered Extended Identifier obtained via INQUIRY VPD page 0x83 */ /* NOTE: Do not separate uniq_prepad and uniq_data @@ -411,11 +411,6 @@ u8 uniq_prepad[8]; u8 uniq_data[20]; u8 pad2[4]; - u8 inqC3_data[12]; - u8 pad3[4]; - u8 inqC9_data[12]; - u8 pad4[4]; - u8 dev_vol_name[64]; } VirtDevice; /* @@ -430,6 +425,7 @@ #define MPT_TARGET_FLAGS_VALID_INQUIRY 0x02 #define MPT_TARGET_FLAGS_Q_YES 0x08 #define MPT_TARGET_FLAGS_VALID_56 0x10 +#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 #endif #define MPT_TARGET_NO_NEGO_WIDE 0x01 @@ -529,8 +525,12 @@ /* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ typedef struct _ScsiCfgData { + u32 PortFlags; int *nvram; /* table of device NVRAM values */ IOCPage3_t *pIocPg3; /* table of physical disks */ + IOCPage4_t *pIocPg4; /* SEP devices addressing */ + dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ + int IocPg4Sz; /* IOCPage4 size */ u8 dvStatus[MPT_MAX_SCSI_DEVICES]; int isRaid; /* bit field, 1 if RAID */ u8 minSyncFactor; /* 0xFF if async */ @@ -544,7 +544,8 @@ u8 dvScheduled; /* 1 if scheduled */ u8 forceDv; /* 1 to force DV scheduling */ u8 noQas; /* Disable QAS for this adapter */ - u8 rsvd[2]; + u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */ + u8 rsvd[1]; } ScsiCfgData; typedef struct _fw_image { diff -urN linux-2.4.24/drivers/message/fusion/mptctl.c linux-2.4.25/drivers/message/fusion/mptctl.c --- linux-2.4.24/drivers/message/fusion/mptctl.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/mptctl.c 2004-02-18 05:36:31.000000000 -0800 @@ -32,7 +32,7 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston, Noah Romer * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: mptctl.c,v 1.66 2003/05/07 14:08:32 pdelaney Exp $ */ @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -208,14 +209,6 @@ return -EBUSY; } -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ - if (!nonblock) { - if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id])) - rc = -ERESTARTSYS; - } else { - rc = -EPERM; - } -#else if (nonblock) { if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id])) rc = -EAGAIN; @@ -223,7 +216,6 @@ if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id])) rc = -ERESTARTSYS; } -#endif dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc)); return rc; } @@ -1275,10 +1267,10 @@ /* Fill in the data and return the structure to the calling * program */ - if (ioc->chip_type == C1030) - karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; - else + if ((int)ioc->chip_type <= (int) FC929) karg.adapterType = MPT_IOCTL_INTERFACE_FC; + else + karg.adapterType = MPT_IOCTL_INTERFACE_SCSI; port = karg.hdr.port; @@ -1329,6 +1321,7 @@ /* Set the Version Strings. */ strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH); + karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0'; karg.busChangeEvent = 0; karg.hostId = ioc->pfacts[port].PortSCSIID; @@ -1369,7 +1362,8 @@ int iocnum; int numDevices = 0; unsigned int max_id; - int ii, jj, lun; + int ii, jj, indexed_lun, lun_index; + u32 lun; int maxWordsLeft; int numBytes; u8 port; @@ -1443,8 +1437,10 @@ while (ii <= max_id) { if (hd->Targets[ii]) { for (jj = 0; jj <= MPT_LAST_LUN; jj++) { - lun = (1 << jj); - if (hd->Targets[ii]->luns & lun) { + lun_index = (jj >> 5); + indexed_lun = (jj % 32); + lun = (1 << indexed_lun); + if (hd->Targets[ii]->luns[lun_index] & lun) { numDevices++; *pdata = (jj << 16) | ii; --maxWordsLeft; @@ -1529,7 +1525,9 @@ karg.chip_type = ioc->chip_type; #endif strncpy (karg.name, ioc->name, MPT_MAX_NAME); + karg.name[MPT_MAX_NAME-1]='\0'; strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH); + karg.product[MPT_PRODUCT_LENGTH-1]='\0'; /* Copy the data from kernel memory to user memory */ @@ -1950,6 +1948,8 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma @@ -2011,6 +2011,8 @@ */ if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; + else + pScsiReq->SenseBufferLength = karg.maxSenseBytes; pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma @@ -2471,8 +2473,10 @@ cfg.physAddr = buf_dma; if (mpt_config(ioc, &cfg) == 0) { ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf; - if (strlen(pdata->BoardTracerNumber) > 1) + if (strlen(pdata->BoardTracerNumber) > 1) { strncpy(karg.serial_number, pdata->BoardTracerNumber, 24); + karg.serial_number[24-1]='\0'; + } } pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); pbuf = NULL; @@ -2705,27 +2709,36 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ - -/* The dynamic ioctl32 compat. registry only exists in >2.3.x sparc64 kernels */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ +#ifdef MPT_CONFIG_COMPAT extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *)); int unregister_ioctl32_conversion(unsigned int cmd); -extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* sparc32_XXX functions are used to provide a conversion between +/* compat_XXX functions are used to provide a conversion between * pointers and u32's. If the arg does not contain any pointers, then - * a specialized function (sparc32_XXX) is not needed. If the arg + * a specialized function (compat_XXX) is not needed. If the arg * does contain pointer(s), then the specialized function is used * to ensure the structure contents is properly processed by mptctl. */ static int -sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, +compat_mptctl_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *filp) +{ + int ret; + + lock_kernel(); + dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n")); + ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + return ret; +} + +static int +compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) { struct mpt_fw_xfer32 kfw32; @@ -2735,7 +2748,7 @@ int nonblock = (filp->f_flags & O_NONBLOCK); int ret; - dctlprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n")); + dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n")); if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32))) return -EFAULT; @@ -2744,7 +2757,7 @@ iocnumX = kfw32.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { - dctlprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n", + dctlprintk((KERN_ERR MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n", __LINE__, iocnumX)); return -ENODEV; } @@ -2764,7 +2777,7 @@ } static int -sparc32_mpt_command(unsigned int fd, unsigned int cmd, +compat_mpt_command(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) { struct mpt_ioctl_command32 karg32; @@ -2775,7 +2788,7 @@ int nonblock = (filp->f_flags & O_NONBLOCK); int ret; - dctlprintk((KERN_INFO MYNAM "::sparc32_mpt_command() called\n")); + dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n")); if (copy_from_user(&karg32, (char *)arg, sizeof(karg32))) return -EFAULT; @@ -2784,7 +2797,7 @@ iocnumX = karg32.hdr.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { - dctlprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n", + dctlprintk((KERN_ERR MYNAM "::compat_mpt_command @%d - ioc%d not found!\n", __LINE__, iocnumX)); return -ENODEV; } @@ -2817,8 +2830,7 @@ return ret; } -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ int __init mptctl_init(void) @@ -2864,35 +2876,34 @@ } } -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ - err = register_ioctl32_conversion(MPTIOCINFO, NULL); +#ifdef MPT_CONFIG_COMPAT + err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTIOCINFO1, NULL); + err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTARGETINFO, NULL); + err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTTEST, NULL); + err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTQUERY, NULL); + err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTENABLE, NULL); + err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTEVENTREPORT, NULL); + err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTHARDRESET, NULL); + err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(MPTCOMMAND32, sparc32_mpt_command); + err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTFWDOWNLOAD32, - sparc32_mptfwxfer_ioctl); + compat_mptfwxfer_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL); + err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl); if (++where && err) goto out_fail; - err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL); + err = register_ioctl32_conversion(HP_GETTARGETINFO, + compat_mptctl_ioctl); if (++where && err) goto out_fail; -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif /* Register this device */ err = misc_register(&mptctl_miscdev); @@ -2925,8 +2936,7 @@ out_fail: -#if defined(__sparc__) && defined(__sparc_v9__) /*{*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ +#ifdef MPT_CONFIG_COMPAT printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!" " (%d:err=%d)\n", where, err); unregister_ioctl32_conversion(MPTIOCINFO); @@ -2941,8 +2951,7 @@ unregister_ioctl32_conversion(MPTFWDOWNLOAD32); unregister_ioctl32_conversion(HP_GETHOSTINFO); unregister_ioctl32_conversion(HP_GETTARGETINFO); -#endif /*} linux >= 2.3.x */ -#endif /*} sparc */ +#endif for (i=0; iioc->FreeQlock, flags); if (!Q_IS_EMPTY(&hd->FreeChainQ)) { @@ -454,6 +455,10 @@ chain_idx = offset / hd->ioc->req_sz; rc = SUCCESS; } + else { + rc = FAILED; + chain_idx = MPT_HOST_NO_CHAIN; + } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -506,12 +511,13 @@ /* Map the data portion, if any. * sges_left = 0 if no data transfer. */ - sges_left = SCpnt->use_sg; - if (SCpnt->use_sg) { - sges_left = pci_map_sg(hd->ioc->pcidev, + if ( (sges_left = SCpnt->use_sg) ) { + if ( (sges_left = pci_map_sg(hd->ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer, SCpnt->use_sg, - scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + scsi_to_pci_dma_dir(SCpnt->sc_data_direction))) + == 0 ) + return FAILED; } else if (SCpnt->request_bufflen) { dma_addr_t buf_dma_addr; scPrivate *my_priv; @@ -730,13 +736,6 @@ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - if ((mf == NULL) || - (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { - printk(MYIOC_s_ERR_FMT "%s req frame ptr! (=%p)!\n", - ioc->name, mf?"BAD":"NULL", (void *) mf); - return 0; - } - req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); sc = hd->ScsiLookup[req_idx]; if (sc == NULL) { @@ -878,7 +877,6 @@ mptscsih_no_negotiate(hd, sc->target); break; - case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ /* * YIKES! I just discovered that SCSI IO which @@ -916,6 +914,9 @@ sc->resid = sc->request_bufflen - xfer_cnt; dprintk((KERN_NOTICE " SET sc->resid=%02xh\n", sc->resid)); #endif + if((xfer_cnt == 0 ) || (sc->underflow > xfer_cnt)) { + sc->result = DID_SOFT_ERROR << 16; + } /* Report Queue Full */ @@ -1036,6 +1037,7 @@ case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ + case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ default: /* @@ -1156,8 +1158,8 @@ static void clean_taskQ(MPT_SCSI_HOST *hd) { - MPT_FRAME_HDR *mf = NULL; - MPT_FRAME_HDR *nextmf = NULL; + MPT_FRAME_HDR *mf; + MPT_FRAME_HDR *nextmf; MPT_ADAPTER *ioc = hd->ioc; unsigned long flags; @@ -1196,7 +1198,7 @@ static void search_taskQ_for_cmd(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd) { - MPT_FRAME_HDR *mf = NULL; + MPT_FRAME_HDR *mf; unsigned long flags; int count = 0; @@ -1320,7 +1322,7 @@ static void mptscsih_reset_timeouts (MPT_SCSI_HOST *hd) { - Scsi_Cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt; int ii; int max = hd->ioc->req_depth; @@ -1346,9 +1348,9 @@ static void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) { - Scsi_Cmnd *SCpnt = NULL; - MPT_FRAME_HDR *mf = NULL; - MPT_DONE_Q *buffer = NULL; + Scsi_Cmnd *SCpnt; + MPT_FRAME_HDR *mf; + MPT_DONE_Q *buffer; int ii; int max = hd->ioc->req_depth; @@ -1457,18 +1459,16 @@ /* ReqToChain size must equal the req_depth * index = req_idx */ - sz = hd->ioc->req_depth * sizeof(int); if (hd->ReqToChain == NULL) { + sz = hd->ioc->req_depth * sizeof(int); mem = kmalloc(sz, GFP_ATOMIC); if (mem == NULL) return -1; hd->ReqToChain = (int *) mem; - } else { - mem = (u8 *) hd->ReqToChain; } - memset(mem, 0xFF, sz); - + for (ii = 0; ii < hd->ioc->req_depth; ii++) + hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN; /* ChainToChain size must equal the total number * of chain buffers to be allocated. @@ -1606,9 +1606,9 @@ int mptscsih_detect(Scsi_Host_Template *tpnt) { - struct Scsi_Host *sh = NULL; - MPT_SCSI_HOST *hd = NULL; - MPT_ADAPTER *this; + struct Scsi_Host *sh; + MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; MPT_DONE_Q *freedoneQ; unsigned long flags; int sz, ii; @@ -1651,20 +1651,19 @@ atomic_set(&mpt_taskQdepth, 0); #endif - this = mpt_adapter_find_first(); - while (this != NULL) { + for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) { /* 20010202 -sralston * Added sanity check on readiness of the MPT adapter. */ - if (this->last_state != MPI_IOC_STATE_OPERATIONAL) { + if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { printk(MYIOC_s_WARN_FMT "Skipping because it's not operational!\n", - this->name); + ioc->name); continue; } - if (!this->active) { + if (!ioc->active) { printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", - this->name); + ioc->name); continue; } @@ -1672,14 +1671,14 @@ /* Sanity check - ensure at least 1 port is INITIATOR capable */ ioc_cap = 0; - for (ii=0; ii < this->facts.NumberOfPorts; ii++) { - if (this->pfacts[ii].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + if (ioc->pfacts[ii].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) ioc_cap ++; } if (!ioc_cap) { - printk(MYIOC_s_WARN_FMT "Skipping because SCSI Initiator mode is NOT enabled!\n", - this->name); + printk(MYIOC_s_WARN_FMT "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", + ioc->name, ioc); continue; } @@ -1690,7 +1689,7 @@ tpnt->proc_info = mptscsih_proc_info; sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST)); if (sh != NULL) { - spin_lock_irqsave(&this->FreeQlock, flags); + spin_lock_irqsave(&ioc->FreeQlock, flags); sh->io_port = 0; sh->n_io_port = 0; sh->irq = 0; @@ -1705,7 +1704,7 @@ * max_lun = 1 + actual last lun, * see hosts.h :o( */ - if ((int)this->chip_type > (int)FC929) + if ((int)ioc->chip_type > (int)FC929) sh->max_id = MPT_MAX_SCSI_DEVICES; else { /* For FC, increase the queue depth @@ -1732,7 +1731,7 @@ * and all access to VirtDev */ sh->max_channel = 0; - sh->this_id = this->pfacts[0].PortSCSIID; + sh->this_id = ioc->pfacts[0].PortSCSIID; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44) /* OS entry to allow host drivers to force @@ -1742,7 +1741,7 @@ #endif /* Required entry. */ - sh->unique_id = this->id; + sh->unique_id = ioc->id; /* Verify that we won't exceed the maximum * number of chain buffers @@ -1753,38 +1752,38 @@ * A slightly different algorithm is required for * 64bit SGEs. */ - scale = this->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); + scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); if (sizeof(dma_addr_t) == sizeof(u64)) { - numSGE = (scale - 1) * (this->facts.MaxChainDepth-1) + scale + - (this->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); + numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); } else { - numSGE = 1 + (scale - 1) * (this->facts.MaxChainDepth-1) + scale + - (this->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); + numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); } if (numSGE < sh->sg_tablesize) { /* Reset this value */ dprintk((MYIOC_s_INFO_FMT "Resetting sg_tablesize to %d from %d\n", - this->name, numSGE, sh->sg_tablesize)); + ioc->name, numSGE, sh->sg_tablesize)); sh->sg_tablesize = numSGE; } /* Set the pci device pointer in Scsi_Host structure. */ - scsi_set_pci_device(sh, this->pcidev); + scsi_set_pci_device(sh, ioc->pcidev); - spin_unlock_irqrestore(&this->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); hd = (MPT_SCSI_HOST *) sh->hostdata; - hd->ioc = this; + hd->ioc = ioc; hd->max_sge = sh->sg_tablesize; - if ((int)this->chip_type > (int)FC929) + if ((int)ioc->chip_type > (int)FC929) hd->is_spi = 1; if (DmpService && - (this->chip_type == FC919 || this->chip_type == FC929)) + (ioc->chip_type == FC919 || ioc->chip_type == FC929)) hd->is_multipath = 1; /* SCSI needs Scsi_Cmnd lookup table! @@ -1799,7 +1798,7 @@ hd->ScsiLookup = (struct scsi_cmnd **) mem; dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", - this->name, hd->ScsiLookup, sz)); + ioc->name, hd->ScsiLookup, sz)); if (mptscsih_initChainBuffers(hd, 1) < 0) goto done; @@ -1870,7 +1869,7 @@ /* Attach the SCSI Host to the IOC structure */ - this->sh = sh; + ioc->sh = sh; /* Initialize this SCSI Hosts' timers * To use, set the timer expires field @@ -1886,7 +1885,7 @@ hd->qtag_tick = jiffies; /* Moved Earlier Pam D */ - /* this->sh = sh; */ + /* ioc->sh = sh; */ #ifdef MPTSCSIH_DBG_TIMEOUT hd->ioc->timeout_hard = 0; @@ -1909,6 +1908,8 @@ if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC) hd->ioc->spi_data.maxSyncOffset = 0; + hd->ioc->spi_data.Saf_Te = driver_setup.saf_te; + hd->negoNvram = 0; #ifdef MPTSCSIH_DISABLE_DOMAIN_VALIDATION hd->negoNvram = MPT_SCSICFG_USE_NVRAM; @@ -1926,16 +1927,15 @@ } ddvprintk((MYIOC_s_INFO_FMT - "dv %x width %x factor %x \n", + "dv %x width %x factor %x saf_te %x\n", hd->ioc->name, driver_setup.dv, driver_setup.max_width, - driver_setup.min_sync_fac)); + driver_setup.min_sync_fac, + driver_setup.saf_te)); } mpt_scsi_hosts++; } - - this = mpt_adapter_find_next(this); } done: @@ -2146,8 +2146,8 @@ static int mptscsih_halt(struct notifier_block *nb, ulong event, void *buf) { - MPT_ADAPTER *ioc = NULL; - MPT_SCSI_HOST *hd = NULL; + MPT_ADAPTER *ioc; + MPT_SCSI_HOST *hd; /* Ignore all messages other than reboot message */ @@ -2182,7 +2182,7 @@ const char * mptscsih_info(struct Scsi_Host *SChost) { - MPT_SCSI_HOST *h = NULL; + MPT_SCSI_HOST *h; int size = 0; if (info_kbuf == NULL) @@ -2398,7 +2398,7 @@ int mptscsih_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int func) { - MPT_ADAPTER *ioc = NULL; + MPT_ADAPTER *ioc; MPT_SCSI_HOST *hd = NULL; int size = 0; @@ -2489,7 +2489,7 @@ MPT_FRAME_HDR *mf; SCSIIORequest_t *pScsiReq; VirtDevice *pTarget; - MPT_DONE_Q *buffer = NULL; + MPT_DONE_Q *buffer; unsigned long flags; int target; int lun; @@ -2774,7 +2774,7 @@ static void mptscsih_freeChainBuffers(MPT_SCSI_HOST *hd, int req_idx) { - MPT_FRAME_HDR *chain = NULL; + MPT_FRAME_HDR *chain; unsigned long flags; int chain_idx; int next; @@ -2839,7 +2839,7 @@ static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, int sleepFlag) { - MPT_ADAPTER *ioc = NULL; + MPT_ADAPTER *ioc; int rc = -1; int doTask = 1; u32 ioc_raw_state; @@ -3088,7 +3088,6 @@ search_doneQ_for_cmd(hd, SCpnt); SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " "Command not in the active list! (sc=%p)\n", hd->ioc->name, SCpnt)); @@ -3345,7 +3344,6 @@ if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) { printk(KERN_WARNING " WARNING - OldAbort, NULL hostdata ptr!!\n"); SCpnt->result = DID_ERROR << 16; - SCpnt->scsi_done(SCpnt); return SCSI_ABORT_NOT_RUNNING; } @@ -3359,18 +3357,19 @@ */ search_doneQ_for_cmd(hd, SCpnt); - SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); + SCpnt->result = DID_ABORT << 16; return SCSI_ABORT_SUCCESS; } else { /* If this command is pended, then timeout/hang occurred * during DV. Force bus reset by posting command to F/W * and then following up with the reset request. */ +#ifndef MPTSCSIH_DBG_TIMEOUT if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); } +#endif } /* @@ -3476,8 +3475,7 @@ printk(KERN_WARNING " IOs outstanding = %d\n", atomic_read(&queue_depth)); if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) { - SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); + SCpnt->result = DID_ERROR << 16; return SCSI_RESET_SUCCESS; } @@ -3492,17 +3490,18 @@ search_doneQ_for_cmd(hd, SCpnt); SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); return SCSI_RESET_SUCCESS; } else { /* If this command is pended, then timeout/hang occurred * during DV. Force bus reset by posting command to F/W * and then following up with the reset request. */ +#ifndef MPTSCSIH_DBG_TIMEOUT if ((mf = mptscsih_search_pendingQ(hd, scpnt_idx)) != NULL) { mptscsih_put_msgframe(ScsiDoneCtx, hd->ioc->id, mf); post_pendingQ_commands(hd); } +#endif } /* @@ -3628,8 +3627,8 @@ #ifdef MPTSCSIH_DBG_TIMEOUT if (ioc->timeout_hard == 1) { - mptscsih_TMHandler(hd, - MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, + mptscsih_TMHandler(hd, + MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 0, 0, 0, 0, CAN_SLEEP); } @@ -3727,6 +3726,9 @@ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf); mf = NULL; +#ifndef MPTSCSIH_DBG_TIMEOUT + post_pendingQ_commands(hd); +#endif if (mptscsih_TMHandler(hd, task_type, SCpnt->channel, SCpnt->target, SCpnt->lun, ctx2abort, CAN_SLEEP) < 0) { @@ -3784,7 +3786,7 @@ { SCSITaskMgmtReply_t *pScsiTmReply; SCSITaskMgmt_t *pScsiTmReq; - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; u8 tmType = 0; @@ -3962,10 +3964,10 @@ } if (pTarget != NULL) { - printk(MYIOC_s_INFO_FMT + dprintk((MYIOC_s_INFO_FMT "scsi%d: Id=%d Lun=%d: Queue depth=%d\n", - hd->ioc->name, sh->host_no, - device->id, device->lun, device->queue_depth); + hd->ioc->name, + device->id, device->lun, device->queue_depth)); dprintk((MYIOC_s_INFO_FMT "Id = %d, sync factor = %x\n", @@ -4041,11 +4043,10 @@ thisIo.SCSIStatus = pScsiReply->SCSIStatus; thisIo.DoDisplay = 1; if (hd->is_multipath) - sprintf(devFoo, "%d:%d:%d \"%s\"", + sprintf(devFoo, "%d:%d:%d", hd->ioc->id, pReq->TargetID, - pReq->LUN[1], - target->dev_vol_name); + pReq->LUN[1]); else sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->target, sc->lun); thisIo.DevIDStr = devFoo; @@ -4102,7 +4103,7 @@ unsigned long flags; MPT_DONE_Q *buffer; MPT_FRAME_HDR *mf = NULL; - MPT_FRAME_HDR *cmdMfPtr = NULL; + MPT_FRAME_HDR *cmdMfPtr; ddvtprintk((MYIOC_s_INFO_FMT ": search_pendingQ ...", hd->ioc->name)); cmdMfPtr = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); @@ -4190,7 +4191,7 @@ static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - MPT_SCSI_HOST *hd = NULL; + MPT_SCSI_HOST *hd; unsigned long flags; dtmprintk((KERN_WARNING MYNAM @@ -4263,7 +4264,7 @@ dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name)); } else { - ScsiCfgData *pSpi = NULL; + ScsiCfgData *pSpi; dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name)); @@ -4971,13 +4972,12 @@ * Allocate and initialize memory for this target. * Save inquiry data. * - * Returns pointer to VirtDevice structure. */ -static VirtDevice * +static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) { + int indexed_lun, lun_index; VirtDevice *vdev; - int sz; dprintk((MYIOC_s_INFO_FMT "initTarget (%d,%d,%d) called, hd=%p\n", hd->ioc->name, bus_id, target_id, lun, hd)); @@ -4986,6 +4986,7 @@ if ((vdev = kmalloc(sizeof(VirtDevice), GFP_ATOMIC)) == NULL) { printk(MYIOC_s_ERR_FMT "initTarget kmalloc(%d) FAILED!\n", hd->ioc->name, (int)sizeof(VirtDevice)); + return; } else { memset(vdev, 0, sizeof(VirtDevice)); rwlock_init(&vdev->VdevLock); @@ -5004,24 +5005,44 @@ } vdev->raidVolume = 0; - if (vdev && hd->is_spi) { + if (hd->is_spi) { if (hd->ioc->spi_data.isRaid & (1 << target_id)) { vdev->raidVolume = 1; ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id)); } } - if (vdev && data) { - if ((!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) || - ((dlen > 56) && (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56)))) { - - /* Copy the inquiry data - if we haven't yet. - */ - sz = MIN(dlen, SCSI_STD_INQUIRY_BYTES); + if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { + /* Copy the inquiry data - if we haven't yet. + */ + + memcpy (vdev->inq_data, data, 8); - memcpy (vdev->inq_data, data, sz); + if ( (data[0] == SCSI_TYPE_PROC) && + !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { + if ( dlen > 49 ) { + vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ( data[44] == 'S' && + data[45] == 'A' && + data[46] == 'F' && + data[47] == '-' && + data[48] == 'T' && + data[49] == 'E' ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } else { + /* Treat all Processors as SAF-TE if + * command line option is set */ + if ( hd->ioc->spi_data.Saf_Te ) { + vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; + mptscsih_writeIOCPage4(hd, target_id, bus_id); + } + } + } else vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; + if ((dlen > 56) && (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { /* Update the target capabilities */ if (dlen > 56) { @@ -5038,17 +5059,19 @@ pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; } } - - /* Is LUN supported? If so, upper 3 bits will be 0 - * in first byte of inquiry data. - */ - if ((*data & 0xe0) == 0) - vdev->luns |= (1 << lun); } + /* Is LUN supported? If so, upper 3 bits will be 0 + * in first byte of inquiry data. + */ + if ((*data & 0xe0) == 0) { + lun_index = (lun >> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + vdev->luns[lun_index] |= (1 << indexed_lun); + } dprintk((KERN_INFO " target = %p\n", vdev)); - return vdev; + return; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -5063,13 +5086,13 @@ int id = (int) target->target_id; int nvram; char canQ = 0; + VirtDevice *vdev; + int ii; u8 width = MPT_NARROW; u8 factor = MPT_ASYNC; u8 offset = 0; u8 version, nfactor; - u8 noQas = 0; - - ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56)); + u8 noQas = 1; if (!hd->is_spi) { if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { @@ -5079,19 +5102,16 @@ return; } + target->negoFlags = pspi_data->noQas; + /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine * support. If available, default QAS to off and allow enabling. * If not available, default QAS to on, turn off for non-disks. */ - if (target->tflags & MPT_TARGET_FLAGS_VALID_56) - noQas = 1; /* Set flags based on Inquiry data */ if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { - if ((target->inq_data[0] & 0x1F) != 0x00) - noQas = 1; - version = target->inq_data[2] & 0x07; if (version < 2) { width = 0; @@ -5111,6 +5131,7 @@ factor = MPT_ULTRA160; else factor = MPT_ULTRA320; + offset = pspi_data->maxSyncOffset; /* If RAID, never disable QAS * else if non RAID, do not disable @@ -5120,8 +5141,6 @@ */ if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0)) noQas = 0; - - offset = pspi_data->maxSyncOffset; } else { factor = MPT_ASYNC; offset = 0; @@ -5180,35 +5199,31 @@ /* Disable unused features. */ - target->negoFlags = pspi_data->noQas; if (!width) target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; if (!offset) target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; - if (noQas) - target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; - /* GEM, processor WORKAROUND */ - if (((target->inq_data[0] & 0x1F) == 0x03) || ((target->inq_data[0] & 0x1F) > 0x08)){ + if (((target->inq_data[0] & 0x1F) == 0x03) || ((target->inq_data[0] & 0x1F) > 0x08)) { target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; - } - - /* Disable QAS if mixed configuration case - */ - if ((noQas) && (!pspi_data->noQas) && ((target->inq_data[0] & 0x1F) != 0x03)){ - VirtDevice *vdev; - int ii; - - ddvtprintk((KERN_INFO "Disabling QAS!\n")); - pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS; - for (ii = 0; ii < id; ii++) { - vdev = hd->Targets[id]; - if (vdev != NULL) - vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + } else { + if (noQas && (pspi_data->noQas == 0)) { + pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; + target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + + /* Disable QAS in a mixed configuration case + */ + +// ddvtprintk((KERN_INFO "Disabling QAS!\n")); + for (ii = 0; ii < id; ii++) { + if ( (vdev = hd->Targets[ii]) ) { + vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; + } + } } } } @@ -5334,9 +5349,9 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) { MPT_ADAPTER *ioc = hd->ioc; - Config_t *pReq = NULL; - SCSIDevicePage1_t *pData = NULL; - VirtDevice *pTarget = NULL; + Config_t *pReq; + SCSIDevicePage1_t *pData; + VirtDevice *pTarget; MPT_FRAME_HDR *mf; dma_addr_t dataDma; u16 req_idx; @@ -5432,7 +5447,6 @@ factor = pTarget->minSyncFactor; offset = pTarget->maxOffset; negoFlags = pTarget->negoFlags; - pTarget = NULL; } if (flags & MPT_SCSICFG_BLK_NEGO) @@ -5515,6 +5529,86 @@ } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* mptscsih_writeIOCPage4 - write IOC Page 4 + * @hd: Pointer to a SCSI Host Structure + * @target_id: write IOC Page4 for this ID & Bus + * + * Return: -EAGAIN if unable to obtain a Message Frame + * or 0 if success. + * + * Remark: We do not wait for a return, write pages sequentially. + */ +static int +mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) +{ + MPT_ADAPTER *ioc = hd->ioc; + Config_t *pReq; + IOCPage4_t *IOCPage4Ptr; + MPT_FRAME_HDR *mf; + dma_addr_t dataDma; + u16 req_idx; + u32 frameOffset; + u32 flagsLength; + int ii; + + /* Get a MF for this command. + */ + if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc->id)) == NULL) { + dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", + ioc->name)); + return -EAGAIN; + } + + ddvprintk((MYIOC_s_INFO_FMT "writeIOCPage4 (mf=%p, id=%d)\n", + ioc->name, mf, target_id)); + + /* Set the request and the data pointers. + * Place data at end of MF. + */ + pReq = (Config_t *)mf; + + req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + frameOffset = ioc->req_sz - sizeof(IOCPage4_t); + + /* Complete the request frame (same for all requests). + */ + pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; + pReq->Reserved = 0; + pReq->ChainOffset = 0; + pReq->Function = MPI_FUNCTION_CONFIG; + pReq->Reserved1[0] = 0; + pReq->Reserved1[1] = 0; + pReq->Reserved1[2] = 0; + pReq->MsgFlags = 0; + for (ii=0; ii < 8; ii++) { + pReq->Reserved2[ii] = 0; + } + + IOCPage4Ptr = ioc->spi_data.pIocPg4; + dataDma = ioc->spi_data.IocPg4_dma; + ii = IOCPage4Ptr->ActiveSEP++; + IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; + IOCPage4Ptr->SEP[ii].SEPBus = bus; + pReq->Header = IOCPage4Ptr->Header; + pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); + + /* Add a SGE to the config request. + */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | + (IOCPage4Ptr->Header.PageLength + ii) * 4; + + mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); + + dsprintk((MYIOC_s_INFO_FMT + "writeIOCPage4: pgaddr 0x%x\n", + ioc->name, (target_id | (bus<<8)))); + + mptscsih_put_msgframe(ScsiDoneCtx, ioc->id, mf); + + return 0; +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* mptscsih_taskmgmt_timeout - Call back for timeout on a * task management request. * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long @@ -6138,7 +6232,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) { MPT_ADAPTER *ioc= hd->ioc; - VirtDevice *pTarget = NULL; + VirtDevice *pTarget; SCSIDevicePage1_t *pcfg1Data = NULL; INTERNAL_CMD iocmd; CONFIGPARMS cfg; @@ -6146,7 +6240,8 @@ ConfigPageHeader_t header1; int bus = 0; int id = 0; - int lun = 0; + int lun; + int indexed_lun, lun_index; int hostId = ioc->pfacts[portnum].PortSCSIID; int max_id; int requested, configuration, data; @@ -6237,12 +6332,13 @@ /* If target Ptr NULL or if this target is NOT a disk, skip. */ - // if (pTarget && ((pTarget->inq_data[0] & 0x1F) == 0)) { if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){ for (lun=0; lun <= MPT_LAST_LUN; lun++) { /* If LUN present, issue the command */ - if (pTarget->luns & (1<> 5); /* 32 luns per lun_index */ + indexed_lun = (lun % 32); + if (pTarget->luns[lun_index] & (1<Targets == NULL) @@ -6495,12 +6591,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) { MPT_ADAPTER *ioc = hd->ioc; - VirtDevice *pTarget = NULL; - SCSIDevicePage1_t *pcfg1Data = NULL; - SCSIDevicePage0_t *pcfg0Data = NULL; - u8 *pbuf1 = NULL; - u8 *pbuf2 = NULL; - u8 *pDvBuf = NULL; + VirtDevice *pTarget; + SCSIDevicePage1_t *pcfg1Data; + SCSIDevicePage0_t *pcfg0Data; + u8 *pbuf1; + u8 *pbuf2; + u8 *pDvBuf; dma_addr_t dvbuf_dma = -1; dma_addr_t buf1_dma = -1; dma_addr_t buf2_dma = -1; @@ -6653,7 +6749,8 @@ if (nfactor < pspi_data->minSyncFactor ) nfactor = pspi_data->minSyncFactor; - if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE)) { + if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) || + (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) { ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", ioc->name, bus, id, lun)); @@ -6921,6 +7018,9 @@ if (inq0 != 0) goto target_done; + if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY ) + goto target_done; + /* Start the Enhanced Test. * 0) issue TUR to clear out check conditions * 1) read capacity of echo (regular) buffer @@ -7377,9 +7477,9 @@ static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) { - VirtDevice *pTarget = NULL; - SCSIDevicePage0_t *pPage0 = NULL; - SCSIDevicePage1_t *pPage1 = NULL; + VirtDevice *pTarget; + SCSIDevicePage0_t *pPage0; + SCSIDevicePage1_t *pPage1; int val = 0, data, configuration; u8 width = 0; u8 offset = 0; @@ -7762,9 +7862,9 @@ /* Commandline Parsing routines and defines. * * insmod format: - * insmod mptscsih mptscsih="width:1 dv:n factor:0x09" + * insmod mptscsih mptscsih="width:1 dv:n factor:0x09 saf-te:1" * boot format: - * mptscsih=width:1,dv:n,factor:0x8 + * mptscsih=width:1,dv:n,factor:0x8,saf-te:1 * */ #ifdef MODULE @@ -7777,11 +7877,13 @@ "dv:" "width:" "factor:" - ; /* DONNOT REMOVE THIS ';' */ + "saf-te:" + ; /* DO NOT REMOVE THIS ';' */ #define OPT_DV 1 #define OPT_MAX_WIDTH 2 #define OPT_MIN_SYNC_FACTOR 3 +#define OPT_SAF_TE 4 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int @@ -7838,6 +7940,10 @@ driver_setup.min_sync_fac = val; break; + case OPT_SAF_TE: + driver_setup.saf_te = val; + break; + default: printk("mptscsih_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); break; diff -urN linux-2.4.24/drivers/message/fusion/mptscsih.h linux-2.4.25/drivers/message/fusion/mptscsih.h --- linux-2.4.24/drivers/message/fusion/mptscsih.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/mptscsih.h 2004-02-18 05:36:31.000000000 -0800 @@ -18,7 +18,7 @@ * Copyright (c) 1999-2002 LSI Logic Corporation * Originally By: Steven J. Ralston * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: mptscsih.h,v 1.1.2.2 2003/05/07 14:08:35 pdelaney Exp $ */ @@ -116,12 +116,14 @@ #define MPTSCSIH_DOMAIN_VALIDATION 1 #define MPTSCSIH_MAX_WIDTH 1 #define MPTSCSIH_MIN_SYNC 0x08 +#define MPTSCSIH_SAF_TE 0 struct mptscsih_driver_setup { u8 dv; u8 max_width; u8 min_sync_fac; + u8 saf_te; }; @@ -130,6 +132,7 @@ MPTSCSIH_DOMAIN_VALIDATION, \ MPTSCSIH_MAX_WIDTH, \ MPTSCSIH_MIN_SYNC, \ + MPTSCSIH_SAF_TE, \ } diff -urN linux-2.4.24/drivers/message/fusion/scsi3.h linux-2.4.25/drivers/message/fusion/scsi3.h --- linux-2.4.24/drivers/message/fusion/scsi3.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/message/fusion/scsi3.h 2004-02-18 05:36:31.000000000 -0800 @@ -7,7 +7,7 @@ * Copyright (c) 1996-2002 Steven J. Ralston * Written By: Steven J. Ralston (19960517) * (mailto:sjralston1@netscape.net) - * (mailto:lstephens@lsil.com) + * (mailto:mpt_linux_developer@lsil.com) * * $Id: scsi3.h,v 1.9 2002/02/27 18:45:02 sralston Exp $ */ diff -urN linux-2.4.24/drivers/net/8139cp.c linux-2.4.25/drivers/net/8139cp.c --- linux-2.4.24/drivers/net/8139cp.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/8139cp.c 2004-02-18 05:36:31.000000000 -0800 @@ -615,8 +615,10 @@ if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; - netif_rx_complete(dev); + local_irq_disable(); cpw16_f(IntrMask, cp_intr_mask); + __netif_rx_complete(dev); + local_irq_enable(); return 0; /* done */ } @@ -643,6 +645,12 @@ spin_lock(&cp->lock); + /* close possible race's with dev_close */ + if (unlikely(!netif_running(dev))) { + cpw16(IntrMask, 0); + goto out; + } + if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) { if (netif_rx_schedule_prep(dev)) { cpw16_f(IntrMask, cp_norx_intr_mask); @@ -664,7 +672,7 @@ /* TODO: reset hardware */ } - +out: spin_unlock(&cp->lock); return IRQ_HANDLED; } diff -urN linux-2.4.24/drivers/net/8139too.c linux-2.4.25/drivers/net/8139too.c --- linux-2.4.24/drivers/net/8139too.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/8139too.c 2004-02-18 05:36:31.000000000 -0800 @@ -116,6 +116,11 @@ #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION #define PFX DRV_NAME ": " +/* Default Message level */ +#define RTL8139_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK) + /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */ #ifdef CONFIG_8139TOO_PIO @@ -559,6 +564,7 @@ int drv_flags; struct pci_dev *pci_dev; u32 pci_state[16]; + u32 msg_enable; struct net_device_stats stats; unsigned char *rx_ring; unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ @@ -984,6 +990,8 @@ /* note: tp->chipset set in rtl8139_init_board */ tp->drv_flags = board_info[ent->driver_data].hw_flags; tp->mmio_addr = ioaddr; + tp->msg_enable = + (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); spin_lock_init (&tp->lock); init_waitqueue_head (&tp->thr_wait); init_completion (&tp->thr_exited); @@ -1286,9 +1294,7 @@ { struct rtl8139_private *tp = dev->priv; int retval; -#ifdef RTL8139_DEBUG void *ioaddr = tp->mmio_addr; -#endif retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); if (retval) @@ -1318,7 +1324,8 @@ rtl8139_init_ring (dev); rtl8139_hw_start (dev); - DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d" + if (netif_msg_ifup(tp)) + printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" " GP Pins %2.2x %s-duplex.\n", dev->name, pci_resource_start (tp->pci_dev, 1), dev->irq, RTL_R8 (MediaStatus), @@ -1335,7 +1342,7 @@ struct rtl8139_private *tp = dev->priv; if (tp->phys[0] >= 0) { - mii_check_media(&tp->mii, 1, init_media); + mii_check_media(&tp->mii, netif_msg_link(tp), init_media); } } @@ -1724,8 +1731,9 @@ netif_stop_queue (dev); spin_unlock_irq(&tp->lock); - DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n", - dev->name, len, entry); + if (netif_msg_tx_queued(tp)) + printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n", + dev->name, len, entry); return 0; } @@ -1755,8 +1763,9 @@ /* Note: TxCarrierLost is always asserted at 100mbps. */ if (txstatus & (TxOutOfWindow | TxAborted)) { /* There was an major error, log it. */ - DPRINTK ("%s: Transmit error, Tx status %8.8x.\n", - dev->name, txstatus); + if (netif_msg_tx_err(tp)) + printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", + dev->name, txstatus); tp->stats.tx_errors++; if (txstatus & TxAborted) { tp->stats.tx_aborted_errors++; @@ -1811,8 +1820,9 @@ int tmp_work; #endif - DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n", - dev->name, rx_status); + if (netif_msg_rx_err (tp)) + printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n", + dev->name, rx_status); tp->stats.rx_errors++; if (!(rx_status & RxStatusOK)) { if (rx_status & RxTooLong) { @@ -1916,8 +1926,9 @@ rx_size = rx_status >> 16; pkt_size = rx_size - 4; - DPRINTK ("%s: rtl8139_rx() status %4.4x, size %4.4x," - " cur %4.4x.\n", dev->name, rx_status, + if (netif_msg_rx_status(tp)) + printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x," + " cur %4.4x.\n", dev->name, rx_status, rx_size, cur_rx); #if RTL8139_DEBUG > 2 { @@ -2078,8 +2089,9 @@ ackstat = status & ~(RxAckBits | TxErr); RTL_W16 (IntrStatus, ackstat); - DPRINTK ("%s: interrupt status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n", - dev->name, status, ackstat, RTL_R16 (IntrStatus)); + if (netif_msg_intr(tp)) + printk (KERN_DEBUG "%s: interrupt status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n", + dev->name, status, ackstat, RTL_R16 (IntrStatus)); if (netif_running (dev) && (status & RxAckBits)) rtl8139_rx_interrupt (dev, tp, ioaddr); @@ -2134,8 +2146,9 @@ } wait_for_completion (&tp->thr_exited); } - - DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n", + + if (netif_msg_ifdown(tp)) + printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus)); spin_lock_irqsave (&tp->lock, flags); @@ -2293,12 +2306,14 @@ static u32 rtl8139_get_msglevel(struct net_device *dev) { - return debug; + struct rtl8139_private *np = dev->priv; + return np->msg_enable; } static void rtl8139_set_msglevel(struct net_device *dev, u32 datum) { - debug = datum; + struct rtl8139_private *np = dev->priv; + np->msg_enable = datum; } /* TODO: we are too slack to do reg dumping for pio, for now */ diff -urN linux-2.4.24/drivers/net/Config.in linux-2.4.25/drivers/net/Config.in --- linux-2.4.24/drivers/net/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -59,21 +59,24 @@ if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then tristate ' MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC fi + if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then + bool ' GT-64240 Ethernet support' CONFIG_GALILEO_64240_ETH + fi if [ "$CONFIG_MIPS_GT96100" = "y" ]; then bool ' MIPS GT96100 Ethernet support' CONFIG_MIPS_GT96100ETH fi - if [ "$CONFIG_MIPS_AU1000" = "y" ]; then - bool ' MIPS AU1000 Ethernet support' CONFIG_MIPS_AU1000_ENET + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + tristate ' MIPS Au1x00 Ethernet support' CONFIG_MIPS_AU1X00_ENET + if [ "$CONFIG_MIPS_AU1X00_ENET" = "y" ]; then + bool ' Broadcom 5222 Dual Phy Support' CONFIG_BCM5222_DUAL_PHY + fi fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then tristate ' SB1250 Ethernet support' CONFIG_NET_SB1250_MAC fi if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi - if [ "$CONFIG_SGI_IP32" = "y" ]; then - tristate ' SGI O2 MACE Fast Ethernet support' CONFIG_SGI_O2MACE_ETH - fi if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi @@ -211,7 +214,7 @@ tristate ' TI ThunderLAN support' CONFIG_TLAN fi if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then - dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI + dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI fi dep_tristate ' VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI dep_mbool ' Use MMIO instead of PIO (EXPERIMENTAL)' CONFIG_VIA_RHINE_MMIO $CONFIG_VIA_RHINE $CONFIG_EXPERIMENTAL @@ -232,7 +235,7 @@ dep_tristate ' D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA fi if [ "$CONFIG_SGI_IP22" = "y" ]; then - bool ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ + tristate ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ fi if [ "$CONFIG_DECSTATION" = "y" ]; then tristate ' DEC LANCE ethernet controller support' CONFIG_DECLANCE diff -urN linux-2.4.24/drivers/net/Makefile linux-2.4.25/drivers/net/Makefile --- linux-2.4.24/drivers/net/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -115,6 +115,7 @@ # end link order section # +obj-$(CONFIG_GALILEO_64240_ETH) += gt64240eth.o obj-$(CONFIG_MV64340_ETH) += mv64340_eth.o obj-$(CONFIG_AIRONET4500) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o @@ -176,7 +177,6 @@ obj-$(CONFIG_SUN3LANCE) += sun3lance.o obj-$(CONFIG_DEFXX) += defxx.o obj-$(CONFIG_SGISEEQ) += sgiseeq.o -obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o obj-$(CONFIG_AT1700) += at1700.o obj-$(CONFIG_FMV18X) += fmv18x.o obj-$(CONFIG_EL1) += 3c501.o @@ -219,7 +219,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o -obj-$(CONFIG_MIPS_AU1000_ENET) += au1000_eth.o +obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_BAGETLANCE) += bagetlance.o obj-$(CONFIG_DECLANCE) += declance.o diff -urN linux-2.4.24/drivers/net/Makefile.lib linux-2.4.25/drivers/net/Makefile.lib --- linux-2.4.24/drivers/net/Makefile.lib 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/Makefile.lib 2004-02-18 05:36:31.000000000 -0800 @@ -34,6 +34,7 @@ obj-$(CONFIG_VIA_RHINE) += crc32.o obj-$(CONFIG_WINBOND_840) += crc32.o obj-$(CONFIG_YELLOWFIN) += crc32.o +obj-$(CONFIG_NATSEMI) += crc32.o # These rely on drivers/net/7990.o which requires crc32.o obj-$(CONFIG_HPLANCE) += crc32.o diff -urN linux-2.4.24/drivers/net/Space.c linux-2.4.25/drivers/net/Space.c --- linux-2.4.24/drivers/net/Space.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/net/Space.c 2004-02-18 05:36:31.000000000 -0800 @@ -83,7 +83,6 @@ extern int SK_init(struct net_device *); extern int seeq8005_probe(struct net_device *); extern int smc_init( struct net_device * ); -extern int sgiseeq_probe(struct net_device *); extern int atarilance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *); extern int sun3_82586_probe(struct net_device *); @@ -366,14 +365,6 @@ {NULL, 0}, }; - -static struct devprobe sgi_probes[] __initdata = { -#ifdef CONFIG_SGISEEQ - {sgiseeq_probe, 0}, -#endif - {NULL, 0}, -}; - static struct devprobe mips_probes[] __initdata = { #ifdef CONFIG_MIPS_JAZZ_SONIC {sonic_probe, 0}, @@ -408,8 +399,6 @@ return 0; if (probe_list(dev, mips_probes) == 0) return 0; - if (probe_list(dev, sgi_probes) == 0) - return 0; if (probe_list(dev, eisa_probes) == 0) return 0; if (probe_list(dev, mca_probes) == 0) diff -urN linux-2.4.24/drivers/net/au1000_eth.c linux-2.4.25/drivers/net/au1000_eth.c --- linux-2.4.24/drivers/net/au1000_eth.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/net/au1000_eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,8 +1,9 @@ /* * - * Alchemy Semi Au1000 ethernet driver + * Alchemy Au1x00 ethernet driver * - * Copyright 2001 MontaVista Software Inc. + * Copyright 2001,2002,2003 MontaVista Software Inc. + * Copyright 2002 TimeSys Corp. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -22,8 +23,15 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * ######################################################################## + * + * */ -#include + +#ifndef __mips__ +#error This driver only works with MIPS architectures! +#endif + + #include #include #include @@ -44,22 +52,27 @@ #include #include #include +#include #include +#include #include "au1000_eth.h" + #ifdef AU1000_ETH_DEBUG -static int au1000_debug = 10; +static int au1000_debug = 5; #else static int au1000_debug = 3; #endif +MODULE_LICENSE("GPL"); + // prototypes static void *dma_alloc(size_t, dma_addr_t *); static void dma_free(void *, size_t); static void hard_stop(struct net_device *); static void enable_rx_tx(struct net_device *dev); -static int __init au1000_probe1(struct net_device *, long, int, int); +static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num); static int au1000_init(struct net_device *); static int au1000_open(struct net_device *); static int au1000_close(struct net_device *); @@ -101,27 +114,8 @@ */ -/* - * Base address and interupt of the Au1xxx ethernet macs - */ -static struct { - unsigned int port; - int irq; -} au1000_iflist[NUM_INTERFACES] = { - {AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, - {AU1000_ETH1_BASE, AU1000_ETH1_IRQ} - }, - au1500_iflist[NUM_INTERFACES] = { - {AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, - {AU1500_ETH1_BASE, AU1000_ETH1_IRQ} - }, - au1100_iflist[NUM_INTERFACES] = { - {AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, - {NULL, NULL} - }; - static char version[] __devinitdata = - "au1000eth.c:1.0 ppopov@mvista.com\n"; + "au1000eth.c:1.4 ppopov@mvista.com\n"; /* These addresses are only used if yamon doesn't tell us what * the mac address is, and the mac address is not passed on the @@ -138,6 +132,7 @@ #define cpu_to_dma32 cpu_to_be32 #define dma32_to_cpu be32_to_cpu +struct au1000_private *au_macs[NUM_ETH_INTERFACES]; /* FIXME * All of the PHY code really should be detached from the MAC @@ -156,7 +151,6 @@ s16 data; /* Stop auto-negotiation */ - //printk("bcm_5201_init\n"); data = mdio_read(dev, phy_addr, MII_CONTROL); mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); @@ -171,12 +165,8 @@ data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; mdio_write(dev, phy_addr, MII_CONTROL, data); - /* Enable TX LED instead of FDX */ - data = mdio_read(dev, phy_addr, MII_INT); - data &= ~MII_FDX_LED; - mdio_write(dev, phy_addr, MII_INT, data); - - if (au1000_debug > 4) dump_mii(dev, phy_addr); + if (au1000_debug > 4) + dump_mii(dev, phy_addr); return 0; } @@ -184,7 +174,6 @@ { s16 mii_control, timeout; - //printk("bcm_5201_reset\n"); mii_control = mdio_read(dev, phy_addr, MII_CONTROL); mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); mdelay(1); @@ -247,8 +236,8 @@ printk("lsi_80227_init\n"); /* restart auto-negotiation */ - mdio_write(dev, phy_addr, 0, 0x3200); - + mdio_write(dev, phy_addr, MII_CONTROL, + MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX); mdelay(1); /* set up LEDs to correct display */ @@ -299,9 +288,9 @@ mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); if (mii_data & MII_STAT_LINK) { *link = 1; - mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_STAT); - if (mii_data & MII_LSI_STAT_SPD) { - if (mii_data & MII_LSI_STAT_FDX) { + mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT); + if (mii_data & MII_LSI_PHY_STAT_SPD) { + if (mii_data & MII_LSI_PHY_STAT_FDX) { *speed = IF_PORT_100BASEFX; dev->if_port = IF_PORT_100BASEFX; } @@ -342,12 +331,303 @@ return 0; } +int am79c874_init(struct net_device *dev, int phy_addr) +{ + s16 data; + + /* 79c874 has quit resembled bit assignments to BCM5201 */ + if (au1000_debug > 4) + printk("am79c847_init\n"); + + /* Stop auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); + + /* Set advertisement to 10/100 and Half/Full duplex + * (full capabilities) */ + data = mdio_read(dev, phy_addr, MII_ANADV); + data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; + mdio_write(dev, phy_addr, MII_ANADV, data); + + /* Restart auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; + + mdio_write(dev, phy_addr, MII_CONTROL, data); + + if (au1000_debug > 4) dump_mii(dev, phy_addr); + return 0; +} + +int am79c874_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + + if (au1000_debug > 4) + printk("am79c874_reset\n"); + + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int +am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + // printk("am79c874_status\n"); + if (!dev) { + printk(KERN_ERR "am79c874_status error: NULL dev\n"); + return -1; + } + + aup = (struct au1000_private *) dev->priv; + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT); + if (mii_data & MII_AMD_PHY_STAT_SPD) { + if (mii_data & MII_AMD_PHY_STAT_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +int lxt971a_init(struct net_device *dev, int phy_addr) +{ + if (au1000_debug > 4) + printk("lxt971a_init\n"); + + /* restart auto-negotiation */ + mdio_write(dev, phy_addr, MII_CONTROL, + MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX); + + /* set up LEDs to correct display */ + mdio_write(dev, phy_addr, 20, 0x0422); + + if (au1000_debug > 4) + dump_mii(dev, phy_addr); + return 0; +} + +int lxt971a_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + + if (au1000_debug > 4) { + printk("lxt971a_reset\n"); + dump_mii(dev, phy_addr); + } + + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int +lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + if (!dev) { + printk(KERN_ERR "lxt971a_status error: NULL dev\n"); + return -1; + } + aup = (struct au1000_private *) dev->priv; + + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT); + if (mii_data & MII_INTEL_PHY_STAT_SPD) { + if (mii_data & MII_INTEL_PHY_STAT_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +int ks8995m_init(struct net_device *dev, int phy_addr) +{ + s16 data; + +// printk("ks8995m_init\n"); + /* Stop auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); + + /* Set advertisement to 10/100 and Half/Full duplex + * (full capabilities) */ + data = mdio_read(dev, phy_addr, MII_ANADV); + data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; + mdio_write(dev, phy_addr, MII_ANADV, data); + + /* Restart auto-negotiation */ + data = mdio_read(dev, phy_addr, MII_CONTROL); + data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; + mdio_write(dev, phy_addr, MII_CONTROL, data); + + if (au1000_debug > 4) dump_mii(dev, phy_addr); + + return 0; +} + +int ks8995m_reset(struct net_device *dev, int phy_addr) +{ + s16 mii_control, timeout; + +// printk("ks8995m_reset\n"); + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); + mdelay(1); + for (timeout = 100; timeout > 0; --timeout) { + mii_control = mdio_read(dev, phy_addr, MII_CONTROL); + if ((mii_control & MII_CNTL_RESET) == 0) + break; + mdelay(1); + } + if (mii_control & MII_CNTL_RESET) { + printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); + return -1; + } + return 0; +} + +int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + u16 mii_data; + struct au1000_private *aup; + + if (!dev) { + printk(KERN_ERR "ks8995m_status error: NULL dev\n"); + return -1; + } + aup = (struct au1000_private *) dev->priv; + + mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); + if (mii_data & MII_STAT_LINK) { + *link = 1; + mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); + if (mii_data & MII_AUX_100) { + if (mii_data & MII_AUX_FDX) { + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + } + else { + *speed = IF_PORT_100BASETX; + dev->if_port = IF_PORT_100BASETX; + } + } + else { + *speed = IF_PORT_10BASET; + dev->if_port = IF_PORT_10BASET; + } + + } + else { + *link = 0; + *speed = 0; + dev->if_port = IF_PORT_UNKNOWN; + } + return 0; +} + +#ifdef CONFIG_MIPS_BOSPORUS +int stub_init(struct net_device *dev, int phy_addr) +{ + //printk("PHY stub_init\n"); + return 0; +} + +int stub_reset(struct net_device *dev, int phy_addr) +{ + //printk("PHY stub_reset\n"); + return 0; +} + +int +stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) +{ + //printk("PHY stub_status\n"); + *link = 1; + /* hmmm, revisit */ + *speed = IF_PORT_100BASEFX; + dev->if_port = IF_PORT_100BASEFX; + return 0; +} +#endif + struct phy_ops bcm_5201_ops = { bcm_5201_init, bcm_5201_reset, bcm_5201_status, }; +struct phy_ops am79c874_ops = { + am79c874_init, + am79c874_reset, + am79c874_status, +}; + struct phy_ops am79c901_ops = { am79c901_init, am79c901_reset, @@ -360,26 +640,82 @@ lsi_80227_status, }; +struct phy_ops lxt971a_ops = { + lxt971a_init, + lxt971a_reset, + lxt971a_status, +}; + +struct phy_ops ks8995m_ops = { + ks8995m_init, + ks8995m_reset, + ks8995m_status, +}; + +#ifdef CONFIG_MIPS_BOSPORUS +struct phy_ops stub_ops = { + stub_init, + stub_reset, + stub_status, +}; +#endif + static struct mii_chip_info { const char * name; u16 phy_id0; u16 phy_id1; struct phy_ops *phy_ops; + int dual_phy; } mii_chip_table[] = { - {"Broadcom BCM5201 10/100 BaseT PHY", 0x0040, 0x6212, &bcm_5201_ops }, - {"AMD 79C901 HomePNA PHY", 0x0000, 0x35c8, &am79c901_ops }, - {"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops }, - {"Broadcom BCM5221 10/100 BaseT PHY", 0x0040, 0x61e4, &bcm_5201_ops }, + {"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0}, + {"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0}, + {"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1}, + {"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0}, + {"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0}, + {"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0}, + {"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0}, + {"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0}, +#ifdef CONFIG_MIPS_BOSPORUS + {"Stub", 0x1234, 0x5678, &stub_ops }, +#endif {0,}, }; static int mdio_read(struct net_device *dev, int phy_id, int reg) { struct au1000_private *aup = (struct au1000_private *) dev->priv; + volatile u32 *mii_control_reg; + volatile u32 *mii_data_reg; u32 timedout = 20; u32 mii_control; - while (aup->mac->mii_control & MAC_MII_BUSY) { + #ifdef CONFIG_BCM5222_DUAL_PHY + /* First time we probe, it's for the mac0 phy. + * Since we haven't determined yet that we have a dual phy, + * aup->mii->mii_control_reg won't be setup and we'll + * default to the else statement. + * By the time we probe for the mac1 phy, the mii_control_reg + * will be setup to be the address of the mac0 phy control since + * both phys are controlled through mac0. + */ + if (aup->mii && aup->mii->mii_control_reg) { + mii_control_reg = aup->mii->mii_control_reg; + mii_data_reg = aup->mii->mii_data_reg; + } + else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + /* assume both phys are controlled through mac0 */ + mii_control_reg = au_macs[0]->mii->mii_control_reg; + mii_data_reg = au_macs[0]->mii->mii_data_reg; + } + else + #endif + { + /* default control and data reg addresses */ + mii_control_reg = &aup->mac->mii_control; + mii_data_reg = &aup->mac->mii_data; + } + + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: read_MII busy timeout!!\n", @@ -391,10 +727,10 @@ mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ; - aup->mac->mii_control = mii_control; + *mii_control_reg = mii_control; timedout = 20; - while (aup->mac->mii_control & MAC_MII_BUSY) { + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: mdio_read busy timeout!!\n", @@ -402,16 +738,36 @@ return -1; } } - return (int)aup->mac->mii_data; + return (int)*mii_data_reg; } static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) { struct au1000_private *aup = (struct au1000_private *) dev->priv; + volatile u32 *mii_control_reg; + volatile u32 *mii_data_reg; u32 timedout = 20; u32 mii_control; - while (aup->mac->mii_control & MAC_MII_BUSY) { + #ifdef CONFIG_BCM5222_DUAL_PHY + if (aup->mii && aup->mii->mii_control_reg) { + mii_control_reg = aup->mii->mii_control_reg; + mii_data_reg = aup->mii->mii_data_reg; + } + else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + /* assume both phys are controlled through mac0 */ + mii_control_reg = au_macs[0]->mii->mii_control_reg; + mii_data_reg = au_macs[0]->mii->mii_data_reg; + } + else + #endif + { + /* default control and data reg addresses */ + mii_control_reg = &aup->mac->mii_control; + mii_data_reg = &aup->mac->mii_data; + } + + while (*mii_control_reg & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { printk(KERN_ERR "%s: mdio_write busy timeout!!\n", @@ -423,8 +779,8 @@ mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE; - aup->mac->mii_data = value; - aup->mac->mii_control = mii_control; + *mii_data_reg = value; + *mii_control_reg = mii_control; } @@ -442,12 +798,13 @@ } } -static int __init mii_probe (struct net_device * dev) +static int mii_probe (struct net_device * dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; int phy_addr; - - aup->mii = NULL; +#ifdef CONFIG_MIPS_BOSPORUS + int phy_found=0; +#endif /* search for total of 32 possible mii phy addresses */ for (phy_addr = 0; phy_addr < 32; phy_addr++) { @@ -455,6 +812,14 @@ u16 phy_id0, phy_id1; int i; + #ifdef CONFIG_BCM5222_DUAL_PHY + /* Mask the already found phy, try next one */ + if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + if (au_macs[0]->phy_addr == phy_addr) + continue; + } + #endif + mii_status = mdio_read(dev, phy_addr, MII_STATUS); if (mii_status == 0xffff || mii_status == 0x0000) /* the mii is not accessable, try next one */ @@ -467,6 +832,65 @@ for (i = 0; mii_chip_table[i].phy_id1; i++) { if (phy_id0 == mii_chip_table[i].phy_id0 && phy_id1 == mii_chip_table[i].phy_id1) { + struct mii_phy * mii_phy = aup->mii; + + printk(KERN_INFO "%s: %s at phy address %d\n", + dev->name, mii_chip_table[i].name, + phy_addr); +#ifdef CONFIG_MIPS_BOSPORUS + phy_found = 1; +#endif + mii_phy->chip_info = mii_chip_table+i; + aup->phy_addr = phy_addr; + aup->phy_ops = mii_chip_table[i].phy_ops; + aup->phy_ops->phy_init(dev,phy_addr); + + // Check for dual-phy and then store required + // values and set indicators. We need to do + // this now since mdio_{read,write} need the + // control and data register addresses. + #ifdef CONFIG_BCM5222_DUAL_PHY + if ( mii_chip_table[i].dual_phy) { + + /* assume both phys are controlled + * through MAC0. Board specific? */ + + /* sanity check */ + if (!au_macs[0] || !au_macs[0]->mii) + return -1; + aup->mii->mii_control_reg = (u32 *) + &au_macs[0]->mac->mii_control; + aup->mii->mii_data_reg = (u32 *) + &au_macs[0]->mac->mii_data; + } + #endif + goto found; + } + } + } +found: + +#ifdef CONFIG_MIPS_BOSPORUS + /* This is a workaround for the Micrel/Kendin 5 port switch + The second MAC doesn't see a PHY connected... so we need to + trick it into thinking we have one. + + If this kernel is run on another Au1500 development board + the stub will be found as well as the actual PHY. However, + the last found PHY will be used... usually at Addr 31 (Db1500). + */ + if ( (!phy_found) ) + { + u16 phy_id0, phy_id1; + int i; + + phy_id0 = 0x1234; + phy_id1 = 0x5678; + + /* search our mii table for the current mii */ + for (i = 0; mii_chip_table[i].phy_id1; i++) { + if (phy_id0 == mii_chip_table[i].phy_id0 && + phy_id1 == mii_chip_table[i].phy_id1) { struct mii_phy * mii_phy; printk(KERN_INFO "%s: %s at phy address %d\n", @@ -476,31 +900,39 @@ GFP_KERNEL); if (mii_phy) { mii_phy->chip_info = mii_chip_table+i; - mii_phy->phy_addr = phy_addr; + aup->phy_addr = phy_addr; mii_phy->next = aup->mii; aup->phy_ops = mii_chip_table[i].phy_ops; aup->mii = mii_phy; aup->phy_ops->phy_init(dev,phy_addr); } else { - printk(KERN_ERR "%s: out of memory\n", + printk(KERN_ERR "%s: out of memory\n", dev->name); return -1; } - /* the current mii is on our mii_info_table, - try next address */ + mii_phy->chip_info = mii_chip_table+i; + aup->phy_addr = phy_addr; + aup->phy_ops = mii_chip_table[i].phy_ops; + aup->phy_ops->phy_init(dev,phy_addr); break; } } } + if (aup->mac_id == 0) { + /* the Bosporus phy responds to addresses 0-5 but + * 5 is the correct one. + */ + aup->phy_addr = 5; + } +#endif if (aup->mii == NULL) { - printk(KERN_ERR "%s: No MII transceivers found!\n", dev->name); + printk(KERN_ERR "%s: Au1x No MII transceivers found!\n", + dev->name); return -1; } - /* use last PHY */ - aup->phy_addr = aup->mii->phy_addr; printk(KERN_INFO "%s: Using %s as default\n", dev->name, aup->mii->chip_info->name); @@ -521,7 +953,6 @@ if (pDB) { aup->pDBfree = pDB->pnext; } - //printk("GetFreeDB: %x\n", pDB); return pDB; } @@ -587,6 +1018,7 @@ static void reset_mac(struct net_device *dev) { + int i; u32 flags; struct au1000_private *aup = (struct au1000_private *) dev->priv; @@ -597,11 +1029,27 @@ spin_lock_irqsave(&aup->lock, flags); del_timer(&aup->timer); hard_stop(dev); - *aup->enable = MAC_EN_CLOCK_ENABLE; - au_sync_delay(2); - *aup->enable = 0; - au_sync_delay(2); + #ifdef CONFIG_BCM5222_DUAL_PHY + if (aup->mac_id != 0) { + #endif + /* If BCM5222, we can't leave MAC0 in reset because then + * we can't access the dual phy for ETH1 */ + *aup->enable = MAC_EN_CLOCK_ENABLE; + au_sync_delay(2); + *aup->enable = 0; + au_sync_delay(2); + #ifdef CONFIG_BCM5222_DUAL_PHY + } + #endif aup->tx_full = 0; + for (i = 0; i < NUM_RX_DMA; i++) { + /* reset control bits */ + aup->rx_dma_ring[i]->buff_stat &= ~0xf; + } + for (i = 0; i < NUM_TX_DMA; i++) { + /* reset control bits */ + aup->tx_dma_ring[i]->buff_stat &= ~0xf; + } spin_unlock_irqrestore(&aup->lock, flags); } @@ -616,95 +1064,110 @@ { int i; - for (i=0; irx_dma_ring[i] = (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i); } - for (i=0; itx_dma_ring[i] = (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i); } } +static struct { + int port; + u32 base_addr; + int irq; + struct net_device *dev; +} iflist[2]; + +static int num_ifs; + +/* + * Setup the base address and interupt of the Au1xxx ethernet macs + * based on cpu type and whether the interface is enabled in sys_pinfunc + * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. + */ static int __init au1000_init_module(void) { - int i; - int prid; - int base_addr, irq; - - prid = read_32bit_cp0_register(CP0_PRID); - for (i=0; i> 4); + struct net_device *dev; + int i, found_one = 0; + + iflist[0].irq = AU1000_ETH0_IRQ; + iflist[1].irq = AU1000_ETH1_IRQ; + switch (c->cputype) { + case CPU_AU1000: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1000_ETH0_BASE; + iflist[1].base_addr = AU1000_ETH1_BASE; + break; + case CPU_AU1100: + num_ifs = 1 - ni; + iflist[0].base_addr = AU1000_ETH0_BASE; + break; + case CPU_AU1500: + num_ifs = 2 - ni; + iflist[0].base_addr = AU1500_ETH0_BASE; + iflist[1].base_addr = AU1500_ETH1_BASE; + break; + default: + num_ifs = 0; } + for(i = 0; i < num_ifs; i++) { + dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i); + iflist[i].dev = dev; + if (dev) + found_one++; } + if (!found_one) + return -ENODEV; return 0; } -static int __init -au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num) +static struct net_device * +au1000_probe(u32 ioaddr, int irq, int port_num) { static unsigned version_printed = 0; struct au1000_private *aup = NULL; - int i, retval = 0; + struct net_device *dev = NULL; db_dest_t *pDB, *pDBfree; char *pmac, *argptr; char ethaddr[6]; + int i, err; - if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) { - return -ENODEV; - } + if (!request_region(ioaddr, MAC_IOSIZE, "Au1x00 ENET")) + return NULL; - if (version_printed++ == 0) printk(version); + if (version_printed++ == 0) + printk(version); + dev = alloc_etherdev(sizeof(struct au1000_private)); if (!dev) { - dev = init_etherdev(0, sizeof(struct au1000_private)); + printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n"); + return NULL; } - if (!dev) { - printk (KERN_ERR "au1000 eth: init_etherdev failed\n"); - return -ENODEV; + + if ((err = register_netdev(dev))) { + printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n", + err); + kfree(dev); + return NULL; } - printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", + printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", dev->name, ioaddr, irq); - /* Initialize our private structure */ - if (dev->priv == NULL) { - aup = (struct au1000_private *) - kmalloc(sizeof(*aup), GFP_KERNEL); - if (aup == NULL) { - retval = -ENOMEM; - goto free_region; - } - dev->priv = aup; - } - aup = dev->priv; - memset(aup, 0, sizeof(*aup)); - /* Allocate the data buffers */ aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr); if (!aup->vaddr) { - retval = -ENOMEM; - goto free_region; + kfree(dev); + release_region(ioaddr, MAC_IOSIZE); + return NULL; } /* aup->mac is the base address of the MAC's registers */ @@ -737,7 +1200,10 @@ ((unsigned long)AU1500_MAC0_ENABLE); memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr)); setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); + aup->mac_id = 0; + au_macs[0] = aup; break; + case AU1000_ETH1_BASE: case AU1500_ETH1_BASE: if (ioaddr == AU1000_ETH1_BASE) @@ -749,15 +1215,16 @@ memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr)); dev->dev_addr[4] += 0x10; setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); + aup->mac_id = 1; + au_macs[1] = aup; break; + default: printk(KERN_ERR "%s: bad ioaddr\n", dev->name); break; } - aup->phy_addr = PHY_ADDRESS; - /* bring the device out of reset, otherwise probing the mii * will hang */ *aup->enable = MAC_EN_CLOCK_ENABLE; @@ -766,14 +1233,22 @@ MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; au_sync_delay(2); + aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); + if (!aup->mii) { + printk(KERN_ERR "%s: out of memory\n", dev->name); + goto err_out; + } + aup->mii->mii_control_reg = 0; + aup->mii->mii_data_reg = 0; + if (mii_probe(dev) != 0) { - goto free_region; + goto err_out; } pDBfree = NULL; /* setup the data buffer descriptors and attach a buffer to each one */ pDB = aup->db; - for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { + for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { pDB->pnext = pDBfree; pDBfree = pDB; pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i); @@ -782,15 +1257,19 @@ } aup->pDBfree = pDBfree; - for (i=0; irx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->rx_db_inuse[i] = pDB; } - for (i=0; itx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->tx_dma_ring[i]->len = 0; aup->tx_db_inuse[i] = pDB; @@ -809,32 +1288,36 @@ dev->tx_timeout = au1000_tx_timeout; dev->watchdog_timeo = ETH_TX_TIMEOUT; - - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(dev); - /* * The boot code uses the ethernet controller, so reset it to start * fresh. au1000_init() expects that the device is in reset state. */ reset_mac(dev); - return 0; -free_region: - release_region(ioaddr, MAC_IOSIZE); + return dev; + +err_out: + /* here we should have a valid dev plus aup-> register addresses + * so we can reset the mac properly.*/ + reset_mac(dev); + if (aup->mii) + kfree(aup->mii); + for (i = 0; i < NUM_RX_DMA; i++) { + if (aup->rx_db_inuse[i]) + ReleaseDB(aup, aup->rx_db_inuse[i]); + } + for (i = 0; i < NUM_TX_DMA; i++) { + if (aup->tx_db_inuse[i]) + ReleaseDB(aup, aup->tx_db_inuse[i]); + } + dma_free((void *)aup->vaddr, MAX_BUF_SIZE * + (NUM_TX_BUFFS+NUM_RX_BUFFS)); unregister_netdev(dev); - if (aup->vaddr) - dma_free((void *)aup->vaddr, - MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS)); - if (dev->priv != NULL) - kfree(dev->priv); - printk(KERN_ERR "%s: au1000_probe1 failed. Returns %d\n", - dev->name, retval); kfree(dev); - return retval; + release_region(ioaddr, MAC_IOSIZE); + return NULL; } - /* * Initialize the interface. * @@ -852,7 +1335,8 @@ u32 control; u16 link, speed; - if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name); + if (au1000_debug > 4) + printk("%s: au1000_init\n", dev->name); spin_lock_irqsave(&aup->lock, flags); @@ -872,7 +1356,7 @@ aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | dev->dev_addr[1]<<8 | dev->dev_addr[0]; - for (i=0; irx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; } au_sync(); @@ -992,24 +1476,48 @@ if (au1000_debug > 4) printk("%s: close: dev=%p\n", dev->name, dev); + reset_mac(dev); + spin_lock_irqsave(&aup->lock, flags); /* stop the device */ - if (netif_device_present(dev)) { - netif_stop_queue(dev); - } + netif_stop_queue(dev); /* disable the interrupt */ free_irq(dev->irq, dev); spin_unlock_irqrestore(&aup->lock, flags); - reset_mac(dev); MOD_DEC_USE_COUNT; return 0; } static void __exit au1000_cleanup_module(void) { + int i, j; + struct net_device *dev; + struct au1000_private *aup; + + for (i = 0; i < num_ifs; i++) { + dev = iflist[i].dev; + if (dev) { + aup = (struct au1000_private *) dev->priv; + unregister_netdev(dev); + if (aup->mii) + kfree(aup->mii); + for (j = 0; j < NUM_RX_DMA; j++) { + if (aup->rx_db_inuse[j]) + ReleaseDB(aup, aup->rx_db_inuse[j]); + } + for (j = 0; j < NUM_TX_DMA; j++) { + if (aup->tx_db_inuse[j]) + ReleaseDB(aup, aup->tx_db_inuse[j]); + } + dma_free((void *)aup->vaddr, MAX_BUF_SIZE * + (NUM_TX_BUFFS+NUM_RX_BUFFS)); + kfree(dev); + release_region(iflist[i].base_addr, MAC_IOSIZE); + } + } } @@ -1081,7 +1589,7 @@ db_dest_t *pDB; int i; - if (au1000_debug > 4) + if (au1000_debug > 5) printk("%s: tx: aup %x len=%d, data=%p, head %d\n", dev->name, (unsigned)aup, skb->len, skb->data, aup->tx_head); @@ -1106,11 +1614,11 @@ pDB = aup->tx_db_inuse[aup->tx_head]; memcpy((void *)pDB->vaddr, skb->data, skb->len); - if (skb->len < MAC_MIN_PKT_SIZE) { - for (i=skb->len; ilen < ETH_ZLEN) { + for (i=skb->len; ivaddr)[i] = 0; } - ptxd->len = MAC_MIN_PKT_SIZE; + ptxd->len = ETH_ZLEN; } else ptxd->len = skb->len; @@ -1159,8 +1667,9 @@ volatile rx_dma_t *prxd; u32 buff_stat, status; db_dest_t *pDB; + u32 frmlen; - if (au1000_debug > 4) + if (au1000_debug > 5) printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head); prxd = aup->rx_dma_ring[aup->rx_head]; @@ -1172,7 +1681,9 @@ if (!(status & RX_ERROR)) { /* good frame */ - skb = dev_alloc_skb((status & RX_FRAME_LEN_MASK) + 2); + frmlen = (status & RX_FRAME_LEN_MASK); + frmlen -= 4; /* Remove FCS */ + skb = dev_alloc_skb(frmlen + 2); if (skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", @@ -1182,9 +1693,9 @@ } skb->dev = dev; skb_reserve(skb, 2); /* 16 byte IP header align */ - eth_copy_and_sum(skb, (unsigned char *)pDB->vaddr, - status & RX_FRAME_LEN_MASK, 0); - skb_put(skb, status & RX_FRAME_LEN_MASK); + eth_copy_and_sum(skb, + (unsigned char *)pDB->vaddr, frmlen, 0); + skb_put(skb, frmlen); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); /* pass the packet to upper layers */ } @@ -1236,8 +1747,11 @@ printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); return; } - au1000_tx_ack(dev); + + /* Handle RX interrupts first to minimize chance of overrun */ + au1000_rx(dev); + au1000_tx_ack(dev); } @@ -1250,6 +1764,8 @@ printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev); reset_mac(dev); au1000_init(dev); + dev->trans_start = jiffies; + netif_wake_queue(dev); } @@ -1305,27 +1821,19 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - u16 *data = (u16 *)&rq->ifr_data; + //u16 *data = (u16 *)&rq->ifr_data; /* fixme */ - switch (cmd) { - case SIOCGMIIPHY: /* Get the address of the PHY in use. */ - case SIOCDEVPRIVATE: /* binary compat, remove in 2.5 */ - data[0] = PHY_ADDRESS; - - case SIOCGMIIREG: /* Read the specified MII register. */ - case SIOCDEVPRIVATE+1: /* binary compat, remove in 2.5 */ + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + //data[0] = PHY_ADDRESS; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ //data[3] = mdio_read(ioaddr, data[0], data[1]); return 0; - - case SIOCSMIIREG: /* Write the specified MII register */ - case SIOCDEVPRIVATE+2: /* binary compat, remove in 2.5 */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ //mdio_write(ioaddr, data[0], data[1], data[2]); return 0; - - default: + default: return -EOPNOTSUPP; } } @@ -1389,7 +1897,6 @@ /* set Speed to 100Mbps, Half Duplex */ /* disable auto negotiation and enable 100MBit Mode */ control = mdio_read(dev, aup->phy_addr, MII_CONTROL); - printk("read control %x\n", control); control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX); control |= MII_CNTL_F100; mdio_write(dev, aup->phy_addr, MII_CONTROL, control); diff -urN linux-2.4.24/drivers/net/au1000_eth.h linux-2.4.25/drivers/net/au1000_eth.h --- linux-2.4.24/drivers/net/au1000_eth.h 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/net/au1000_eth.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,10 +1,13 @@ /* - * Alchemy Semi Au1000 ethernet driver include file + * + * Alchemy Au1x00 ethernet driver include file * * Author: Pete Popov * * Copyright 2001 MontaVista Software Inc. * + * ######################################################################## + * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,14 +20,16 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * */ -#include -#define NUM_INTERFACES 2 #define MAC_IOSIZE 0x10000 -#define NUM_RX_DMA 4 /* Au1000 has 4 rx hardware descriptors */ -#define NUM_TX_DMA 4 /* Au1000 has 4 tx hardware descriptors */ +#define NUM_RX_DMA 4 /* Au1x00 has 4 rx hardware descriptors */ +#define NUM_TX_DMA 4 /* Au1x00 has 4 tx hardware descriptors */ #define NUM_RX_BUFFS 4 #define NUM_TX_BUFFS 4 @@ -33,12 +38,6 @@ #define ETH_TX_TIMEOUT HZ/4 #define MAC_MIN_PKT_SIZE 64 -#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) -#define PHY_ADDRESS 0 -#define PHY_CONTROL_DEFAULT 0x3000 -#define PHY_CONTROL_REG_ADDR 0 -#endif - #define MULTICAST_FILTER_LIMIT 64 /* FIXME @@ -54,11 +53,13 @@ #define MII_ANLPAR 0x0005 #define MII_AEXP 0x0006 #define MII_ANEXT 0x0007 -#define MII_LSI_CONFIG 0x0011 -#define MII_LSI_STAT 0x0012 -#define MII_AUX_CNTRL 0x0018 -#define MII_INT 0x001A +#define MII_LSI_PHY_CONFIG 0x0011 +/* Status register */ +#define MII_LSI_PHY_STAT 0x0012 +#define MII_AMD_PHY_STAT MII_LSI_PHY_STAT +#define MII_INTEL_PHY_STAT 0x0011 +#define MII_AUX_CNTRL 0x0018 /* mii registers specific to AMD 79C901 */ #define MII_STATUS_SUMMARY = 0x0018 @@ -121,23 +122,30 @@ #define MII_STSSUM_AUTO 0x0002 #define MII_STSSUM_SPD 0x0001 -/* lsi status register */ - -#define MII_LSI_STAT_FDX 0x0040 -#define MII_LSI_STAT_SPD 0x0080 +/* lsi phy status register */ +#define MII_LSI_PHY_STAT_FDX 0x0040 +#define MII_LSI_PHY_STAT_SPD 0x0080 + +/* amd phy status register */ +#define MII_AMD_PHY_STAT_FDX 0x0800 +#define MII_AMD_PHY_STAT_SPD 0x0400 + +/* intel phy status register */ +#define MII_INTEL_PHY_STAT_FDX 0x0200 +#define MII_INTEL_PHY_STAT_SPD 0x4000 /* Auxilliary Control/Status Register */ #define MII_AUX_FDX 0x0001 #define MII_AUX_100 0x0002 #define MII_AUX_F100 0x0004 #define MII_AUX_ANEG 0x0008 -#define MII_FDX_LED 0x8000 typedef struct mii_phy { struct mii_phy * next; struct mii_chip_info * chip_info; - int phy_addr; u16 status; + u32 *mii_control_reg; + u32 *mii_data_reg; } mii_phy_t; struct phy_ops { @@ -204,6 +212,7 @@ u32 tx_tail; u32 tx_full; + int mac_id; mii_phy_t *mii; struct phy_ops *phy_ops; @@ -217,7 +226,7 @@ u8 *hash_table; u32 hash_mode; u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ - u32 phy_addr; /* PHY address */ + int phy_addr; /* phy address */ u32 options; /* User-settable misc. driver options. */ u32 drv_flags; struct net_device_stats stats; diff -urN linux-2.4.24/drivers/net/de4x5.c linux-2.4.25/drivers/net/de4x5.c --- linux-2.4.24/drivers/net/de4x5.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/de4x5.c 2004-02-18 05:36:31.000000000 -0800 @@ -999,7 +999,7 @@ static void srom_repair(struct net_device *dev, int card); static int test_bad_enet(struct net_device *dev, int status); static int an_exception(struct de4x5_bus_type *lp); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA static void eisa_probe(struct net_device *dev, u_long iobase); #endif static void pci_probe(struct net_device *dev, u_long iobase); @@ -1053,7 +1053,7 @@ #endif /* MODULE */ static char name[DE4X5_NAME_LENGTH + 1]; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; static int lastEISA; # ifdef DE4X5_FORCE_EISA /* Force an EISA bus probe or not */ @@ -1131,7 +1131,7 @@ u_long iobase = dev->base_addr; pci_probe(dev, iobase); -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) { eisa_probe(dev, iobase); } @@ -2093,7 +2093,7 @@ return; } -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA /* ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. Upto 15 EISA devices are supported. @@ -5363,7 +5363,7 @@ t = *q; *q = '\0'; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1; #endif if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1; @@ -5865,7 +5865,7 @@ u_int class = DE4X5_CLASS_CODE; u_int device; -#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) +#ifdef CONFIG_EISA char name[DE4X5_STRLEN]; u_long iobase = 0x1000; diff -urN linux-2.4.24/drivers/net/declance.c linux-2.4.25/drivers/net/declance.c --- linux-2.4.24/drivers/net/declance.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/declance.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ * * adopted from sunlance.c by Richard van den Berg * - * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2002, 2003 Maciej W. Rozycki * * additional sources: * - PMAD-AA TURBOchannel Ethernet Module Functional Specification, @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -271,7 +272,7 @@ lp->tx_old - lp->tx_new-1) /* The lance control ports are at an absolute address, machine and tc-slot - * dependant. + * dependent. * DECstations do only 32-bit access and the LANCE uses 16 bit addresses, * so we have to give the structure an extra member making rap pointing * at the right address @@ -783,19 +784,29 @@ /* Associate IRQ with lance_interrupt */ if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) { - printk("lance: Can't get IRQ %d\n", dev->irq); + printk("%s: Can't get IRQ %d\n", dev->name, dev->irq); return -EAGAIN; } if (lp->dma_irq >= 0) { + unsigned long flags; + if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0, "lance error", dev)) { free_irq(dev->irq, dev); - printk("lance: Can't get DMA IRQ %d\n", lp->dma_irq); + printk("%s: Can't get DMA IRQ %d\n", dev->name, + lp->dma_irq); return -EAGAIN; } + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); /* Enable I/O ASIC LANCE DMA. */ - fast_wmb(); - ioasic_write(SSR, ioasic_read(SSR) | LANCE_DMA_EN); + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) | IO_SSR_LANCE_DMA_EN); + + fast_mb(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } status = init_restart_lance(lp); @@ -821,9 +832,18 @@ writereg(&ll->rdp, LE_C0_STOP); if (lp->dma_irq >= 0) { + unsigned long flags; + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); /* Disable I/O ASIC LANCE DMA. */ - ioasic_write(SSR, ioasic_read(SSR) & ~LANCE_DMA_EN); + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) & ~IO_SSR_LANCE_DMA_EN); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); + free_irq(lp->dma_irq, dev); } free_irq(dev->irq, dev); @@ -856,8 +876,8 @@ volatile struct lance_regs *ll = lp->ll; printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n", - dev->name, ll->rdp); - lance_reset(dev); + dev->name, ll->rdp); + lance_reset(dev); netif_wake_queue(dev); } @@ -872,10 +892,9 @@ len = skblen; - if(len < ETH_ZLEN) - { + if (len < ETH_ZLEN) { skb = skb_padto(skb, ETH_ZLEN); - if(skb == NULL) + if (skb == NULL) return 0; len = ETH_ZLEN; } @@ -890,7 +909,7 @@ skblen); /* Clear the slack of the packet, do I need this? */ - /* For a firewall its a good idea - AC */ + /* For a firewall it's a good idea - AC */ /* if (len != skblen) memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1); @@ -927,7 +946,7 @@ volatile u16 *mcast_table = (u16 *) & ib->filter; struct dev_mc_list *dmi = dev->mc_list; char *addrs; - int i, j, bit, byte; + int i; u32 crc; /* set all multicast bits */ @@ -1005,6 +1024,8 @@ static int __init dec_lance_init(const int type, const int slot) { static unsigned version_printed; + static const char fmt[] = "declance%d"; + char name[10]; struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; @@ -1019,13 +1040,26 @@ if (dec_lance_debug && version_printed++ == 0) printk(version); - dev = init_etherdev(NULL, sizeof(struct lance_private)); - if (!dev) - return -ENOMEM; + i = 0; + dev = root_lance_dev; + while (dev) { + i++; + lp = (struct lance_private *)dev->priv; + dev = lp->next; + } + snprintf(name, sizeof(name), fmt, i); + + dev = alloc_etherdev(sizeof(struct lance_private)); + if (!dev) { + printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n", + name); + ret = -ENOMEM; + goto err_out; + } SET_MODULE_OWNER(dev); /* - * init_etherdev ensures the data structures used by the LANCE + * alloc_etherdev ensures the data structures used by the LANCE * are aligned. */ lp = (struct lance_private *) dev->priv; @@ -1036,7 +1070,7 @@ switch (type) { #ifdef CONFIG_TC case ASIC_LANCE: - dev->base_addr = system_base + LANCE; + dev->base_addr = system_base + IOASIC_LANCE; /* buffer space for the on-board LANCE shared memory */ /* @@ -1045,7 +1079,7 @@ dev->mem_start = KSEG1ADDR(0x00020000); dev->mem_end = dev->mem_start + 0x00020000; dev->irq = dec_interrupt[DEC_IRQ_LANCE]; - esar_base = system_base + ESAR; + esar_base = system_base + IOASIC_ESAR; /* Workaround crash with booting KN04 2.1k from Disk */ memset((void *)dev->mem_start, 0, @@ -1074,7 +1108,8 @@ /* Setup I/O ASIC LANCE DMA. */ lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR]; - ioasic_write(LANCE_DMA_P, PHYSADDR(dev->mem_start) << 3); + ioasic_write(IO_REG_LANCE_DMA_P, + PHYSADDR(dev->mem_start) << 3); break; @@ -1139,9 +1174,10 @@ break; default: - printk("declance_init called with unknown type\n"); + printk(KERN_ERR "%s: declance_init called with unknown type\n", + name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } ll = (struct lance_regs *) dev->base_addr; @@ -1151,19 +1187,21 @@ /* First, check for test pattern */ if (esar[0x60] != 0xff && esar[0x64] != 0x00 && esar[0x68] != 0x55 && esar[0x6c] != 0xaa) { - printk("Ethernet station address prom not found!\n"); + printk(KERN_ERR + "%s: Ethernet station address prom not found!\n", + name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } /* Check the prom contents */ for (i = 0; i < 8; i++) { if (esar[i * 4] != esar[0x3c - i * 4] && esar[i * 4] != esar[0x40 + i * 4] && esar[0x3c - i * 4] != esar[0x40 + i * 4]) { - printk("Something is wrong with the ethernet " - "station address prom!\n"); + printk(KERN_ERR "%s: Something is wrong with the " + "ethernet station address prom!\n", name); ret = -ENODEV; - goto err_out; + goto err_out_free_dev; } } @@ -1176,13 +1214,13 @@ */ switch (type) { case ASIC_LANCE: - printk("%s: IOASIC onboard LANCE, addr = ", dev->name); + printk("%s: IOASIC onboard LANCE, addr = ", name); break; case PMAD_LANCE: - printk("%s: PMAD-AA, addr = ", dev->name); + printk("%s: PMAD-AA, addr = ", name); break; case PMAX_LANCE: - printk("%s: PMAX onboard LANCE, addr = ", dev->name); + printk("%s: PMAX onboard LANCE, addr = ", name); break; } for (i = 0; i < 6; i++) { @@ -1219,11 +1257,20 @@ lp->multicast_timer.data = (unsigned long) dev; lp->multicast_timer.function = &lance_set_multicast_retry; + ret = register_netdev(dev); + if (ret) { + printk(KERN_ERR + "%s: Unable to register netdev, aborting.\n", name); + goto err_out_free_dev; + } + + printk("%s: registered as %s.\n", name, dev->name); return 0; -err_out: - unregister_netdev(dev); +err_out_free_dev: kfree(dev); + +err_out: return ret; } diff -urN linux-2.4.24/drivers/net/e100/e100.h linux-2.4.25/drivers/net/e100/e100.h --- linux-2.4.24/drivers/net/e100/e100.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/e100/e100_config.c linux-2.4.25/drivers/net/e100/e100_config.c --- linux-2.4.24/drivers/net/e100/e100_config.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/e100/e100_config.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -60,7 +60,7 @@ * All other init functions will only set values that are * different from the 82557 default. */ -void __devinit +void e100_config_init_82557(struct e100_private *bdp) { /* initialize config block */ @@ -104,7 +104,7 @@ e100_config_mulcast_enbl(bdp, false); } -static void __devinit +static void e100_config_init_82558(struct e100_private *bdp) { /* MWI enable. This should be turned on only if the adapter is a 82558/9 @@ -136,7 +136,7 @@ e100_config_long_rx(bdp, true); } -static void __devinit +static void e100_config_init_82550(struct e100_private *bdp) { /* The D102 chip allows for 32 config bytes. This value is @@ -160,7 +160,7 @@ } /* Initialize the adapter's configure block */ -void __devinit +void e100_config_init(struct e100_private *bdp) { e100_config_init_82557(bdp); diff -urN linux-2.4.24/drivers/net/e100/e100_config.h linux-2.4.25/drivers/net/e100/e100_config.h --- linux-2.4.24/drivers/net/e100/e100_config.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/e100/e100_config.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/e100/e100_eeprom.c linux-2.4.25/drivers/net/e100/e100_eeprom.c --- linux-2.4.24/drivers/net/e100/e100_eeprom.c 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100_eeprom.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/e100/e100_main.c linux-2.4.25/drivers/net/e100/e100_main.c --- linux-2.4.24/drivers/net/e100/e100_main.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/e100/e100_main.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -46,20 +46,20 @@ /* Change Log * - * 2.3.30 09/21/03 + * 2.3.38 12/14/03 + * o Added netpoll support. + * o Added ICH6 device ID support + * o Moved to 2.6 APIs: pci_name() and free_netdev(). + * o Removed some __devinit from some functions that shouldn't be marked + * as such (Anton Blanchard [anton@samba.org]). + * + * 2.3.33 10/21/03 * o Bug fix (Bugzilla 97908): Loading e100 was causing crash on Itanium2 * with HP chipset * o Bug fix (Bugzilla 101583): e100 can't pass traffic with ipv6 * o Bug fix (Bugzilla 101360): PRO/10+ can't pass traffic * * 2.3.27 08/08/03 - * o Bug fix: read skb->len after freeing skb - * [Andrew Morton] akpm@zip.com.au - * o Bug fix: 82557 (with National PHY) timeout during init - * [Adam Kropelin] akropel1@rochester.rr.com - * o Feature add: allow to change Wake On LAN when EEPROM disabled - * - * 2.3.13 05/08/03 */ #include @@ -80,7 +80,14 @@ "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", "tx_heartbeat_errors", "tx_window_errors", + /* device-specific stats */ + "tx_late_collision_errors", "tx_deferred", + "tx_single_collisions", "tx_multi_collisions", + "rx_collision_detected_errors", "tx_flow_control_pause", + "rx_flow_control_pause", "rx_flow_control_unsupported", + "tx_tco_packets", "rx_tco_packets", }; +#define E100_NET_STATS_LEN 21 #define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *); @@ -124,8 +131,8 @@ static void e100_non_tx_background(unsigned long); static inline void e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb); /* Global Data structures and variables */ -char e100_copyright[] __devinitdata = "Copyright (c) 2003 Intel Corporation"; -char e100_driver_version[]="2.3.30-k1"; +char e100_copyright[] __devinitdata = "Copyright (c) 2004 Intel Corporation"; +char e100_driver_version[]="2.3.38-k1"; const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver"; char e100_short_driver_name[] = "e100"; static int e100nics = 0; @@ -134,6 +141,11 @@ static void e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); +#ifdef CONFIG_NET_POLL_CONTROLLER +/* for netdump / net console */ +static void e100_netpoll (struct net_device *dev); +#endif + #ifdef CONFIG_PM static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); static int e100_suspend(struct pci_dev *pcid, u32 state); @@ -598,6 +610,8 @@ && (bdp->pdev->device < 0x103F)) || ((bdp->pdev->device >= 0x1050) && (bdp->pdev->device <= 0x1057)) + || ((bdp->pdev->device >= 0x1064) + && (bdp->pdev->device <= 0x106B)) || (bdp->pdev->device == 0x2449) || (bdp->pdev->device == 0x2459) || (bdp->pdev->device == 0x245D)) { @@ -631,6 +645,10 @@ dev->set_mac_address = &e100_set_mac; dev->do_ioctl = &e100_ioctl; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = e100_netpoll; +#endif + if (bdp->flags & USE_IPCB) dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; @@ -695,7 +713,7 @@ pci_disable_device(pcid); err_dev: pci_set_drvdata(pcid, NULL); - kfree(dev); + free_netdev(dev); out: return rc; } @@ -717,7 +735,7 @@ e100_dealloc_space(bdp); pci_set_drvdata(bdp->pdev, NULL); - kfree(dev); + free_netdev(dev); } static void __devexit @@ -746,7 +764,7 @@ --e100nics; } -static struct pci_device_id e100_id_table[] __devinitdata = { +static struct pci_device_id e100_id_table[] = { {0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, @@ -770,6 +788,14 @@ {0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x1069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x106A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + {0x8086, 0x106B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, {0,} /* This has to be the last entry*/ @@ -1317,7 +1343,7 @@ return 1; } -static void __devinit +static void e100_tco_workaround(struct e100_private *bdp) { int i; @@ -2507,7 +2533,7 @@ * true: if successfully cleared stat counters * false: otherwise */ -static unsigned char __devinit +static unsigned char e100_clr_cntrs(struct e100_private *bdp) { volatile u32 *pcmd_complete; @@ -3176,9 +3202,19 @@ void *addr = ifr->ifr_data; int i; - for(i = 0; i < E100_STATS_LEN; i++) + for(i = 0; i < E100_NET_STATS_LEN; i++) stats.data[i] = ((unsigned long *)&bdp->drv_stats.net_stats)[i]; + stats.data[i++] = bdp->drv_stats.tx_late_col; + stats.data[i++] = bdp->drv_stats.tx_ok_defrd; + stats.data[i++] = bdp->drv_stats.tx_one_retry; + stats.data[i++] = bdp->drv_stats.tx_mt_one_retry; + stats.data[i++] = bdp->drv_stats.rcv_cdt_frames; + stats.data[i++] = bdp->drv_stats.xmt_fc_pkts; + stats.data[i++] = bdp->drv_stats.rcv_fc_pkts; + stats.data[i++] = bdp->drv_stats.rcv_fc_unsupported; + stats.data[i++] = bdp->drv_stats.xmt_tco_pkts; + stats.data[i++] = bdp->drv_stats.rcv_tco_pkts; if(copy_to_user(addr, &stats, sizeof(stats))) return -EFAULT; return 0; @@ -3582,7 +3618,7 @@ strncpy(info.version, e100_driver_version, sizeof (info.version) - 1); strncpy(info.fw_version, "N/A", sizeof (info.fw_version) - 1); - strncpy(info.bus_info, bdp->pdev->slot_name, + strncpy(info.bus_info, pci_name(bdp->pdev), sizeof (info.bus_info) - 1); info.n_stats = E100_STATS_LEN; info.regdump_len = E100_REGS_LEN * sizeof(u32); @@ -4340,3 +4376,18 @@ } #endif +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void e100_netpoll (struct net_device *dev) +{ + struct e100_private *adapter = dev->priv; + disable_irq(adapter->pdev->irq); + e100intr (adapter->pdev->irq, dev, NULL); + enable_irq(adapter->pdev->irq); +} +#endif diff -urN linux-2.4.24/drivers/net/e100/e100_phy.c linux-2.4.25/drivers/net/e100/e100_phy.c --- linux-2.4.24/drivers/net/e100/e100_phy.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100_phy.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -132,7 +132,7 @@ } } -static unsigned char __devinit +static unsigned char e100_phy_valid(struct e100_private *bdp, unsigned int phy_address) { u16 ctrl_reg, stat_reg; @@ -150,7 +150,7 @@ return true; } -static void __devinit +static void e100_phy_address_detect(struct e100_private *bdp) { unsigned int addr; @@ -180,7 +180,7 @@ } } -static void __devinit +static void e100_phy_id_detect(struct e100_private *bdp) { u16 low_id_reg, high_id_reg; @@ -204,7 +204,7 @@ ((unsigned int) high_id_reg << 16)); } -static void __devinit +static void e100_phy_isolate(struct e100_private *bdp) { unsigned int phy_address; @@ -227,7 +227,7 @@ } } -static unsigned char __devinit +static unsigned char e100_phy_specific_setup(struct e100_private *bdp) { u16 misc_reg; @@ -380,7 +380,7 @@ * Returns: * NOTHING */ -static void __devinit +static void e100_fix_polarity(struct e100_private *bdp) { u16 status; @@ -916,7 +916,7 @@ schedule_timeout(HZ / 2); } -unsigned char __devinit +unsigned char e100_phy_init(struct e100_private *bdp) { e100_phy_reset(bdp); diff -urN linux-2.4.24/drivers/net/e100/e100_phy.h linux-2.4.25/drivers/net/e100/e100_phy.h --- linux-2.4.24/drivers/net/e100/e100_phy.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100_phy.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/e100/e100_test.c linux-2.4.25/drivers/net/e100/e100_test.c --- linux-2.4.24/drivers/net/e100/e100_test.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100_test.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/e100/e100_ucode.h linux-2.4.25/drivers/net/e100/e100_ucode.h --- linux-2.4.24/drivers/net/e100/e100_ucode.h 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/e100/e100_ucode.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff -urN linux-2.4.24/drivers/net/gt64240eth.c linux-2.4.25/drivers/net/gt64240eth.c --- linux-2.4.24/drivers/net/gt64240eth.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/gt64240eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1854 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 Patton Electronics Company + * Copyright (C) 2002 Momentum Computer + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or support@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Ethernet driver for the MIPS GT96100 Advanced Communication Controller. + * + * Modified for the Gallileo/Marvell GT-64240 Communication Controller. + * + * Support for Rx NAPI, Rx checksum offload, IOCTL and ETHTOOL added + * Manish Lachwani (lachwani@pmc-sierra.com) - 09/16/2003 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DESC_DATA_BE 1 + +#include "gt64240eth.h" + +// enable this port (set hash size to 1/2K) +//- #define PORT_CONFIG pcrHS +#define PORT_CONFIG (pcrHS | pcrHD) +//- #define PORT_CONFIG pcrHS |pcrPM |pcrPBF|pcrHDM +//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS); +//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS | pcrPM); +//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS | pcrPM | 1< 2 some warnings such as queue full, ..... + * > 3 lots of change-of-state messages. + * > 4 EXTENSIVE data/descriptor dumps. + */ +#ifdef GT64240_DEBUG +static int gt64240_debug = GT64240_DEBUG; +#else +static int gt64240_debug = 0; +#endif + +/********************************************************/ + +// prototypes +static void *dmaalloc(size_t size, dma_addr_t * dma_handle); +static void dmafree(size_t size, void *vaddr); +static void gt64240_delay(int msec); +static int gt64240_add_hash_entry(struct net_device *dev, + unsigned char *addr); +static void read_mib_counters(struct gt64240_private *gp); +static int read_MII(struct net_device *dev, u32 reg); +static int write_MII(struct net_device *dev, u32 reg, u16 data); +#if 1 +static void dump_tx_ring(struct net_device *dev); +static void dump_rx_ring(struct net_device *dev); +#endif +static void dump_MII(struct net_device *dev); +static void dump_tx_desc(struct net_device *dev, int i); +static void dump_rx_desc(struct net_device *dev, int i); +static void dump_skb(struct net_device *dev, struct sk_buff *skb); +static void dump_hw_addr(unsigned char *addr_str); +static void update_stats(struct gt64240_private *gp); +static void abort(struct net_device *dev, u32 abort_bits); +static void hard_stop(struct net_device *dev); +static void enable_ether_irq(struct net_device *dev); +static void disable_ether_irq(struct net_device *dev); +static int __init gt64240_probe1(uint32_t ioaddr, int irq, int port_num); +static void reset_tx(struct net_device *dev); +static void reset_rx(struct net_device *dev); +static int gt64240_init(struct net_device *dev); +static int gt64240_open(struct net_device *dev); +static int gt64240_close(struct net_device *dev); +static int gt64240_tx(struct sk_buff *skb, struct net_device *dev); +#ifdef GT64240_NAPI +static int gt64240_poll(struct net_device *dev, int *budget); +static int gt64240_rx(struct net_device *dev, u32 status, int budget); +#else +static int gt64240_rx(struct net_device *dev, u32 status); +#endif +static void gt64240_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void gt64240_tx_timeout(struct net_device *dev); +static void gt64240_set_rx_mode(struct net_device *dev); +static struct net_device_stats *gt64240_get_stats(struct net_device *dev); + +extern char *__init prom_getcmdline(void); +extern int prom_get_mac_addrs(unsigned char + station_addr[NUM_INTERFACES][6]); + +static char version[] __devinitdata = + "gt64240eth.o: version 0.1, \n"; + +// PHY device addresses +static u32 gt64240_phy_addr[NUM_INTERFACES] __devinitdata = { 0x8, 0x1, 0xa }; + +// Need real Ethernet addresses -- in parse_mac_addr_options(), +// these will be replaced by prom_get_mac_addrs() and/or prom_getcmdline(). +static unsigned char gt64240_station_addr[NUM_INTERFACES][6] = { + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, + {0x02, 0x03, 0x04, 0x05, 0x06, 0x07} +}; + +static int max_interrupt_work = 32; + +/* + * Base address and interupt of the GT64240 ethernet controllers + */ +static struct { + unsigned int port; + int irq; +} gt64240_iflist[NUM_INTERFACES] = { + { + GT64240_ETH0_BASE, 8}, { + GT64240_ETH1_BASE, 8}, { + GT64240_ETH2_BASE, 8} +}; + +/* + DMA memory allocation, derived from pci_alloc_consistent. +*/ +static void *dmaalloc(size_t size, dma_addr_t * dma_handle) +{ + void *ret; + + ret = + (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, + get_order(size)); + + if (ret != NULL) { + dma_cache_inv((unsigned long) ret, size); + if (dma_handle != NULL) + *dma_handle = virt_to_phys(ret); + + /* bump virtual address up to non-cached area */ + ret = (void *) KSEG1ADDR(ret); + } + + return ret; +} + +static void dmafree(size_t size, void *vaddr) +{ + vaddr = (void *) KSEG0ADDR(vaddr); + free_pages((unsigned long) vaddr, get_order(size)); +} + +static void gt64240_delay(int ms) +{ + if (in_interrupt()) + return; + else { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(ms * HZ / 1000); + } +} + +unsigned char prom_mac_addr_base[6]; + +int prom_get_mac_addrs(unsigned char station_addr[NUM_INTERFACES][6]) +{ + memcpy(station_addr[0], prom_mac_addr_base, 6); + memcpy(station_addr[1], prom_mac_addr_base, 6); + memcpy(station_addr[2], prom_mac_addr_base, 6); + + station_addr[1][5] += 1; + station_addr[2][5] += 2; + + return 0; +} + +void parse_mac_addr_options(void) +{ + prom_get_mac_addrs(gt64240_station_addr); +} + +static int read_MII(struct net_device *dev, u32 reg) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int timedout = 20; + u32 smir = smirOpCode | (gp->phy_addr << smirPhyAdBit) | + (reg << smirRegAdBit); + + // wait for last operation to complete + while ((GT64240_READ(GT64240_ETH_SMI_REG)) & smirBusy) { + // snooze for 1 msec and check again + gt64240_delay(1); + + if (--timedout == 0) { + printk("%s: read_MII busy timeout!!\n", dev->name); + return -1; + } + } + + GT64240_WRITE(GT64240_ETH_SMI_REG, smir); + + timedout = 20; + // wait for read to complete + while (! + ((smir = + GT64240_READ(GT64240_ETH_SMI_REG)) & smirReadValid)) { + // snooze for 1 msec and check again + gt64240_delay(1); + + if (--timedout == 0) { + printk("%s: read_MII timeout!!\n", dev->name); + return -1; + } + } + + return (int) (smir & smirDataMask); +} + +/* Ethtool support */ +static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + u32 ethcmd; + + if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) + return -EFAULT; + + switch (ethcmd) { + + /* Get driver info */ + case ETHTOOL_GDRVINFO:{ + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strncpy(info.driver, "gt64260", + sizeof(info.driver) - 1); + strncpy(info.version, version, + sizeof(info.version) - 1); + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; + } + /* get settings */ + case ETHTOOL_GSET:{ + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&gp->lock); + mii_ethtool_gset(&gp->mii_if, &ecmd); + spin_unlock_irq(&gp->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET:{ + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&gp->lock); + r = mii_ethtool_sset(&gp->mii_if, &ecmd); + spin_unlock_irq(&gp->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST:{ + return mii_nway_restart(&gp->mii_if); + } + /* get link status */ + case ETHTOOL_GLINK:{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + edata.data = mii_link_ok(&gp->mii_if); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* get message-level */ + case ETHTOOL_GMSGLVL:{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + edata.data = 0; /* XXX */ + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL:{ + struct ethtool_value edata; + if (copy_from_user + (&edata, useraddr, sizeof(edata))) + return -EFAULT; + /* debug = edata.data; *//* XXX */ + return 0; + } + } + return -EOPNOTSUPP; +} + +static int gt64240_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct mii_ioctl_data *data = + (struct mii_ioctl_data *) &rq->ifr_data; + int phy = dev->base_addr & 0x1f; + int retval; + + switch (cmd) { + case SIOCETHTOOL: + retval = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ + case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ + data->phy_id = phy; + /* Fall through */ + + case SIOCGMIIREG: /* Read MII PHY register. */ + case SIOCDEVPRIVATE + 1: /* for binary compat, remove in 2.5 */ + data->val_out = read_MII(dev, data->reg_num & 0x1f); + retval = 0; + break; + + case SIOCSMIIREG: /* Write MII PHY register. */ + case SIOCDEVPRIVATE + 2: /* for binary compat, remove in 2.5 */ + if (!capable(CAP_NET_ADMIN)) { + retval = -EPERM; + } else { + write_MII(dev, data->reg_num & 0x1f, data->val_in); + retval = 0; + } + break; + + default: + retval = -EOPNOTSUPP; + break; + } + return retval; +} + +static void dump_tx_desc(struct net_device *dev, int i) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + gt64240_td_t *td = &gp->tx_ring[i]; + + printk + ("%s:tx[%d]: self=%08x cmd=%08x, cnt=%4d. bufp=%08x, next=%08x\n", + dev->name, i, td, td->cmdstat, td->byte_cnt, td->buff_ptr, + td->next); +} + +static void dump_rx_desc(struct net_device *dev, int i) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + gt64240_rd_t *rd = &gp->rx_ring[i]; + + printk + ("%s:rx_dsc[%d]: self=%08x cst=%08x,size=%4d. cnt=%4d. bufp=%08x, next=%08x\n", + dev->name, i, rd, rd->cmdstat, rd->buff_sz, rd->byte_cnt, + rd->buff_ptr, rd->next); +} + +// These routines work, just disabled to avoid compile warnings +static int write_MII(struct net_device *dev, u32 reg, u16 data) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int timedout = 20; + u32 smir = + (gp->phy_addr << smirPhyAdBit) | (reg << smirRegAdBit) | data; + + // wait for last operation to complete + while (GT64240_READ(GT64240_ETH_SMI_REG) & smirBusy) { + // snooze for 1 msec and check again + gt64240_delay(1); + + if (--timedout == 0) { + printk("%s: write_MII busy timeout!!\n", + dev->name); + return -1; + } + } + + GT64240_WRITE(GT64240_ETH_SMI_REG, smir); + return 0; +} + +static void dump_tx_ring(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int i; + + printk("%s: dump_tx_ring: txno/txni/cnt=%d/%d/%d\n", + dev->name, gp->tx_next_out, gp->tx_next_in, gp->tx_count); + + for (i = 0; i < TX_RING_SIZE; i++) + dump_tx_desc(dev, i); +} + +static void dump_rx_ring(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int i; + + printk("%s: dump_rx_ring: rxno=%d\n", dev->name, gp->rx_next_out); + + for (i = 0; i < RX_RING_SIZE; i++) + dump_rx_desc(dev, i); +} + +static void dump_MII(struct net_device *dev) +{ + int i, val; + + for (i = 0; i < 7; i++) { + if ((val = read_MII(dev, i)) >= 0) + printk("%s: MII Reg %d=%x\n", dev->name, i, val); + } + for (i = 16; i < 21; i++) { + if ((val = read_MII(dev, i)) >= 0) + printk("%s: MII Reg %d=%x\n", dev->name, i, val); + } +} + + +static void dump_hw_addr(unsigned char *addr_str) +{ + int i; + for (i = 0; i < 6; i++) { + printk("%2.2x", addr_str[i]); + printk(i < 5 ? ":" : "\n"); + } +} + + +static void dump_skb(struct net_device *dev, struct sk_buff *skb) +{ + int i; + unsigned char *skbdata; + + printk("%s: dump_skb: skb=%p, skb->data=%p, skb->len=%d.", + dev->name, skb, skb->data, skb->len); + + skbdata = (unsigned char *) KSEG1ADDR(skb->data); + + for (i = 0; i < skb->len; i++) { + if (!(i % 16)) + printk("\r\n %3.3x: %2.2x,", i, skbdata[i]); + else + printk("%2.2x,", skbdata[i]); + } + printk("\r\n"); +} + + +static void dump_data(struct net_device *dev, char *ptr, int len) +{ + int i; + unsigned char *data; + + printk("%s: dump_data: ptr=%p, len=%d.", dev->name, ptr, len); + + data = (unsigned char *) KSEG1ADDR(ptr); + + for (i = 0; i < len; i++) { + if (!(i % 16)) + printk("\n %3.3x: %2.2x,", i, data[i]); + else + printk("%2.2x,", data[i]); + } + printk("\n"); +} + + +/*--------------------------------------------------------------*/ +/* A D D H A S H E N T R Y */ +/*--------------------------------------------------------------*/ +static int gt64240_add_hash_entry(struct net_device *dev, + unsigned char *addr) +{ + struct gt64240_private *gp; + int i; + u32 value1, value0, *entry; + u16 hashResult; + unsigned char hash_ea[6]; + static int flag = 0; + static unsigned char swapped[256]; + + if (flag == 0) { /* Create table to swap bits in a byte */ + flag = 1; + for (i = 0; i < 256; i++) { + swapped[i] = (i & 0x01) << 7; + swapped[i] |= (i & 0x02) << 5; + swapped[i] |= (i & 0x04) << 3; + swapped[i] |= (i & 0x08) << 1; + swapped[i] |= (i & 0x10) >> 1; + swapped[i] |= (i & 0x20) >> 3; + swapped[i] |= (i & 0x40) >> 5; + swapped[i] |= (i & 0x80) >> 7; + } + } + + for (i = 0; i < 6; i++) { /* swap bits from mac to create hash mac */ + hash_ea[i] = swapped[addr[i]]; + } + + gp = (struct gt64240_private *) dev->priv; + + /* create hash entry address */ + hashResult = (((hash_ea[5] >> 2) & 0x3F) << 9) & 0x7E00; + hashResult |= ((hash_ea[4] & 0x7F) << 2) | (hash_ea[5] & 0x03); + hashResult ^= + ((hash_ea[3] & 0xFF) << 1) | ((hash_ea[4] >> 7) & 0x01); + hashResult ^= ((hash_ea[1] & 0x01) << 8) | (hash_ea[2] & 0xFF); + + value0 = hteValid | hteRD; /* Create hash table entry value */ + value0 |= (u32) addr[0] << 3; + value0 |= (u32) addr[1] << 11; + value0 |= (u32) addr[2] << 19; + value0 |= ((u32) addr[3] & 0x1f) << 27; + + value1 = ((u32) addr[3] >> 5) & 0x07; + value1 |= (u32) addr[4] << 3; + value1 |= (u32) addr[5] << 11; + + /* Inset entry value into hash table */ + for (i = 0; i < HASH_HOP_NUMBER; i++) { + entry = (u32 *) ((u32) gp->hash_table + + (((u32) hashResult & 0x07ff) << 3)); + if ((*entry & hteValid) && !(*entry & hteSkip)) { + hashResult += 2; /* oops, occupied, go to next entry */ + } else { +#ifdef __LITTLE_ENDIAN + entry[1] = value1; + entry[0] = value0; +#else + entry[0] = value1; + entry[1] = value0; +#endif + break; + } + } + if (i >= HASH_HOP_NUMBER) { + printk("%s: gt64240_add_hash_entry expired!\n", dev->name); + return (-1); + } + return (0); +} + + +static void read_mib_counters(struct gt64240_private *gp) +{ + u32 *mib_regs = (u32 *) & gp->mib; + int i; + + for (i = 0; i < sizeof(mib_counters_t) / sizeof(u32); i++) + mib_regs[i] = + GT64240ETH_READ(gp, + GT64240_ETH_MIB_COUNT_BASE + + i * sizeof(u32)); +} + + +static void update_stats(struct gt64240_private *gp) +{ + mib_counters_t *mib = &gp->mib; + struct net_device_stats *stats = &gp->stats; + + read_mib_counters(gp); + + stats->rx_packets = mib->totalFramesReceived; + stats->tx_packets = mib->framesSent; + stats->rx_bytes = mib->totalByteReceived; + stats->tx_bytes = mib->byteSent; + stats->rx_errors = mib->totalFramesReceived - mib->framesReceived; + //the tx error counters are incremented by the ISR + //rx_dropped incremented by gt64240_rx + //tx_dropped incremented by gt64240_tx + stats->multicast = mib->multicastFramesReceived; + // collisions incremented by gt64240_tx_complete + stats->rx_length_errors = mib->oversizeFrames + mib->fragments; + // The RxError condition means the Rx DMA encountered a + // CPU owned descriptor, which, if things are working as + // they should, means the Rx ring has overflowed. + stats->rx_over_errors = mib->macRxError; + stats->rx_crc_errors = mib->cRCError; +} + +static void abort(struct net_device *dev, u32 abort_bits) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int timedout = 100; // wait up to 100 msec for hard stop to complete + + if (gt64240_debug > 3) + printk("%s: abort\n", dev->name); + + // Return if neither Rx or Tx abort bits are set + if (!(abort_bits & (sdcmrAR | sdcmrAT))) + return; + + // make sure only the Rx/Tx abort bits are set + abort_bits &= (sdcmrAR | sdcmrAT); + + spin_lock(&gp->lock); + + // abort any Rx/Tx DMA immediately + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, abort_bits); + + if (gt64240_debug > 3) + printk("%s: abort: SDMA cmd = %x/%x\n", + dev->name, abort_bits, GT64240ETH_READ(gp, + GT64240_ETH_SDMA_COMM)); + + // wait for abort to complete + while ((GT64240ETH_READ(gp, GT64240_ETH_SDMA_COMM)) & abort_bits) { + // snooze for 20 msec and check again + gt64240_delay(1); + + if (--timedout == 0) { + printk("%s: abort timeout!!\n", dev->name); + break; + } + } + + spin_unlock(&gp->lock); +} + + +static void hard_stop(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + + if (gt64240_debug > 3) + printk("%s: hard stop\n", dev->name); + + disable_ether_irq(dev); + + abort(dev, sdcmrAR | sdcmrAT); + + // disable port + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, 0); + if (gt64240_debug > 3) + printk("%s: gt64240_hard_stop: Port Config=%x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_PORT_CONFIG)); + +} + + +static void enable_ether_irq(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + u32 intMask; + + intMask = + icrTxBufferLow | icrTxEndLow | icrTxErrorLow | + icrTxBufferHigh | icrTxEndHigh | icrTxErrorHigh | icrTxUdr | + icrRxBuffer | icrRxOVR | icrRxError | icrMIIPhySTC | + icrEtherIntSum; + + +//- GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0); /* CLEAR existing ints */ + // unmask device interrupts: + GT64240ETH_WRITE(gp, GT64240_ETH_INT_MASK, intMask); + + // now route ethernet interrupts to GT PCI1 (eth0 and eth1 will be + // sharing it). + GT_READ(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, &intMask); + intMask |= 1 << gp->port_num; + GT_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, intMask); +} + +static void disable_ether_irq(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + u32 intMask; + + GT_READ(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, &intMask); + intMask &= ~(1 << gp->port_num); + GT_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, intMask); + + // mask all device interrupts: + GT64240ETH_WRITE(gp, GT64240_ETH_INT_MASK, 0); +} + +#ifdef GT64240_NAPI +static inline void __netif_rx_complete(struct net_device *dev) +{ + if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) + BUG(); + list_del(&dev->poll_list); + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} +#endif + + +/* + * Probe for a GT64240 ethernet controller. + */ +static int __init gt64240_probe(void) +{ + unsigned int base_addr = 0; + int i; + int found = 0; + + if (gt64240_debug > 2) + printk("gt64240_probe at 0x%08x\n", base_addr); + + parse_mac_addr_options(); + + for (i = 0; i < NUM_INTERFACES; i++) { + int base_addr = gt64240_iflist[i].port; + + if (check_region(base_addr, GT64240_ETH_IO_SIZE)) { + printk("gt64240_probe: ioaddr 0x%lx taken?\n", + base_addr); + continue; + } + + if (gt64240_probe1(base_addr, gt64240_iflist[i].irq, i) == + 0) { + /* Does not seem to be the "traditional" way folks do this, */ + /* but I want to init both eth ports if at all possible! */ + /* So, until I find out the "correct" way to do this: */ + if (++found == NUM_INTERFACES) /* That's all of them! */ + return 0; + } + } + if (found) + return 0; /* as long as we found at least one! */ + return -ENODEV; +} + +module_init(gt64240_probe); + +static int __init gt64240_probe1(uint32_t ioaddr, int irq, int port_num) +{ + struct net_device *dev = NULL; + static unsigned version_printed = 0; + struct gt64240_private *gp = NULL; + int retval; + u16 vendor_id, device_id; + u32 cpuConfig; + unsigned char chip_rev; + + // probe for GT64240 by reading PCI0 vendor/device ID register + pcibios_read_config_word(0, 0, PCI_VENDOR_ID, &vendor_id); + pcibios_read_config_word(0, 0, PCI_DEVICE_ID, &device_id); + + dev = init_etherdev(NULL, sizeof(struct gt64240_private)); + + if (gt64240_debug > 2) + printk + ("%s: gt64240_probe1 vendId=0x%08x, devId=0x%08x, addr=0x%08lx, irq=%d.,port=%d.\n", + dev->name, vendor_id, device_id, ioaddr, irq, + port_num); + + if (irq < 0) { + printk + ("gt64240_probe1: irq unknown - probing not supported\n"); + return -ENODEV; + } +#if 1 /* KLUDGE Alert: no check on return value: */ + if (!request_region(ioaddr, GT64240_ETH_IO_SIZE, "gt64240eth")) + printk("*** request_region() failed!\n"); +#endif + + cpuConfig = GT64240_READ(CPU_CONFIGURATION); + printk("gt64240_probe1: cpu in %s-endian mode\n", + (cpuConfig & (1 << 12)) ? "little" : "big"); + + printk + ("%s: GT64240 found at ioaddr 0x%lx, irq %d., PCI devID=%x\n", + dev->name, ioaddr, irq, device_id); + + /* Allocate a new 'dev' if needed. */ + if (dev == NULL) + dev = init_etherdev(0, sizeof(struct gt64240_private)); + + if (gt64240_debug && version_printed++ == 0) + printk("%s: %s", dev->name, version); + + /* private struct aligned and zeroed by init_etherdev */ + /* Fill in the 'dev' fields. */ + dev->base_addr = ioaddr; + dev->irq = irq; + memcpy(dev->dev_addr, gt64240_station_addr[port_num], + sizeof(dev->dev_addr)); + + printk("%s: HW Address ", dev->name); + dump_hw_addr(dev->dev_addr); + + /* Initialize our private structure. */ + if (dev->priv == NULL) { + + gp = (struct gt64240_private *) kmalloc(sizeof(*gp), + GFP_KERNEL); + if (gp == NULL) { + retval = -ENOMEM; + goto free_region; + } + + dev->priv = gp; + } + + gp = dev->priv; + + memset(gp, 0, sizeof(*gp)); // clear it + + gp->port_num = port_num; + gp->io_size = GT64240_ETH_IO_SIZE; + gp->port_offset = port_num * GT64240_ETH_IO_SIZE; + gp->phy_addr = gt64240_phy_addr[port_num]; + + pcibios_read_config_byte(0, 0, PCI_REVISION_ID, &chip_rev); + gp->chip_rev = chip_rev; + printk("%s: GT64240 chip revision=%d\n", dev->name, gp->chip_rev); + + printk("%s: GT64240 ethernet port %d\n", dev->name, gp->port_num); + +#ifdef GT64240_NAPI + printk("Rx NAPI supported \n"); +#endif + +/* MII Initialization */ + gp->mii_if.dev = dev; + gp->mii_if.phy_id = dev->base_addr; + gp->mii_if.mdio_read = read_MII; + gp->mii_if.mdio_write = write_MII; + gp->mii_if.advertising = read_MII(dev, MII_ADVERTISE); + + // Allocate Rx and Tx descriptor rings + if (gp->rx_ring == NULL) { + // All descriptors in ring must be 16-byte aligned + gp->rx_ring = dmaalloc(sizeof(gt64240_rd_t) * RX_RING_SIZE + + + sizeof(gt64240_td_t) * TX_RING_SIZE, + &gp->rx_ring_dma); + if (gp->rx_ring == NULL) { + retval = -ENOMEM; + goto free_region; + } + + gp->tx_ring = + (gt64240_td_t *) (gp->rx_ring + RX_RING_SIZE); + gp->tx_ring_dma = + gp->rx_ring_dma + sizeof(gt64240_rd_t) * RX_RING_SIZE; + } + // Allocate the Rx Data Buffers + if (gp->rx_buff == NULL) { + gp->rx_buff = + dmaalloc(PKT_BUF_SZ * RX_RING_SIZE, &gp->rx_buff_dma); + if (gp->rx_buff == NULL) { + dmafree(sizeof(gt64240_rd_t) * RX_RING_SIZE + + sizeof(gt64240_td_t) * TX_RING_SIZE, + gp->rx_ring); + retval = -ENOMEM; + goto free_region; + } + } + + if (gt64240_debug > 3) + printk("%s: gt64240_probe1, rx_ring=%p, tx_ring=%p\n", + dev->name, gp->rx_ring, gp->tx_ring); + + // Allocate Rx Hash Table + if (gp->hash_table == NULL) { + gp->hash_table = (char *) dmaalloc(RX_HASH_TABLE_SIZE, + &gp->hash_table_dma); + if (gp->hash_table == NULL) { + dmafree(sizeof(gt64240_rd_t) * RX_RING_SIZE + + sizeof(gt64240_td_t) * TX_RING_SIZE, + gp->rx_ring); + dmafree(PKT_BUF_SZ * RX_RING_SIZE, gp->rx_buff); + retval = -ENOMEM; + goto free_region; + } + } + + if (gt64240_debug > 3) + printk("%s: gt64240_probe1, hash=%p\n", + dev->name, gp->hash_table); + + spin_lock_init(&gp->lock); + + dev->open = gt64240_open; + dev->hard_start_xmit = gt64240_tx; + dev->stop = gt64240_close; + dev->get_stats = gt64240_get_stats; + dev->do_ioctl = gt64240_ioctl; + dev->set_multicast_list = gt64240_set_rx_mode; + dev->tx_timeout = gt64240_tx_timeout; + dev->watchdog_timeo = GT64240ETH_TX_TIMEOUT; + +#ifdef GT64240_NAPI + dev->poll = gt64240_poll; + dev->weight = 64; +#endif + + /* Fill in the fields of the device structure with ethernet values. */ + ether_setup(dev); + return 0; + + free_region: + release_region(ioaddr, gp->io_size); + unregister_netdev(dev); + if (dev->priv != NULL) + kfree(dev->priv); + kfree(dev); + printk("%s: gt64240_probe1 failed. Returns %d\n", + dev->name, retval); + return retval; +} + + +static void reset_tx(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int i; + + abort(dev, sdcmrAT); + + for (i = 0; i < TX_RING_SIZE; i++) { + if (gp->tx_skbuff[i]) { + if (in_interrupt()) + dev_kfree_skb_irq(gp->tx_skbuff[i]); + else + dev_kfree_skb(gp->tx_skbuff[i]); + gp->tx_skbuff[i] = NULL; + } +//- gp->tx_ring[i].cmdstat = 0; // CPU owns + gp->tx_ring[i].cmdstat = + (u32) (txGenCRC | txEI | txPad | txFirst | txLast); + gp->tx_ring[i].byte_cnt = 0; + gp->tx_ring[i].buff_ptr = 0; + gp->tx_ring[i].next = + gp->tx_ring_dma + sizeof(gt64240_td_t) * (i + 1); + if (gt64240_debug > 4) + dump_tx_desc(dev, i); + } + /* Wrap the ring. */ + gp->tx_ring[i - 1].next = gp->tx_ring_dma; + if (gt64240_debug > 4) + dump_tx_desc(dev, i - 1); + + // setup only the lowest priority TxCDP reg + GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0, + gp->tx_ring_dma); +//- GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0, 0); /* ROLLINS */ +//- GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0,virt_to_phys(&gp->tx_ring[0])); /* ROLLINS */ + + GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR1, 0); + + // init Tx indeces and pkt counter + gp->tx_next_in = gp->tx_next_out = 0; + gp->tx_count = 0; +} + +static void reset_rx(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int i; + + abort(dev, sdcmrAR); + + for (i = 0; i < RX_RING_SIZE; i++) { + gp->rx_ring[i].next = + gp->rx_ring_dma + sizeof(gt64240_rd_t) * (i + 1); + gp->rx_ring[i].buff_ptr = gp->rx_buff_dma + i * PKT_BUF_SZ; + gp->rx_ring[i].buff_sz = PKT_BUF_SZ; + gp->rx_ring[i].byte_cnt = 0; /* just for debug printk's */ + // Give ownership to device, set first and last, enable interrupt + gp->rx_ring[i].cmdstat = + (uint32_t) (rxFirst | rxLast | rxOwn | rxEI); + if (gt64240_debug > 4) + dump_rx_desc(dev, i); + } + /* Wrap the ring. */ + gp->rx_ring[i - 1].next = gp->rx_ring_dma; + if (gt64240_debug > 4) + dump_rx_desc(dev, i - 1); + + // Setup only the lowest priority RxFDP and RxCDP regs + for (i = 0; i < 4; i++) { + if (i == 0) { + GT64240ETH_WRITE(gp, GT64240_ETH_1ST_RX_DESC_PTR0, + gp->rx_ring_dma); + GT64240ETH_WRITE(gp, GT64240_ETH_CURR_RX_DESC_PTR0, + gp->rx_ring_dma); + } else { + GT64240ETH_WRITE(gp, + GT64240_ETH_1ST_RX_DESC_PTR0 + + i * 4, 0); + GT64240ETH_WRITE(gp, + GT64240_ETH_CURR_RX_DESC_PTR0 + + i * 4, 0); + } + } + + // init Rx NextOut index + gp->rx_next_out = 0; +} + + +static int gt64240_init(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + u32 ciu; + + if (gt64240_debug > 3) { + printk("%s: gt64240_init: dev=%p\n", dev->name, dev); + printk("%s: gt64240_init: scs0_lo=%04x, scs0_hi=%04x\n", + dev->name, GT64240_READ(0x008), + GT64240_READ(0x010)); + printk("%s: gt64240_init: scs1_lo=%04x, scs1_hi=%04x\n", + dev->name, GT64240_READ(0x208), + GT64240_READ(0x210)); + printk("%s: gt64240_init: scs2_lo=%04x, scs2_hi=%04x\n", + dev->name, GT64240_READ(0x018), + GT64240_READ(0x020)); + printk("%s: gt64240_init: scs3_lo=%04x, scs3_hi=%04x\n", + dev->name, GT64240_READ(0x218), + GT64240_READ(0x220)); + } + // Stop and disable Port + hard_stop(dev); + + GT64240_WRITE(COMM_UNIT_INTERRUPT_MASK, 0x07070777); /*+prk21aug01 */ + if (gt64240_debug > 2) + printk + ("%s: gt64240_init: CIU Cause=%08x, Mask=%08x, EAddr=%08x\n", + dev->name, GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE), + GT64240_READ(COMM_UNIT_INTERRUPT_MASK), + GT64240_READ(COMM_UNIT_ERROR_ADDRESS)); + + // Set-up hash table + memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE); // clear it + gp->hash_mode = 0; + // Add a single entry to hash table - our ethernet address + gt64240_add_hash_entry(dev, dev->dev_addr); + // Set-up DMA ptr to hash table + GT64240ETH_WRITE(gp, GT64240_ETH_HASH_TBL_PTR, gp->hash_table_dma); + if (gt64240_debug > 3) + printk("%s: gt64240_init: Hash Tbl Ptr=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_HASH_TBL_PTR)); + + // Setup Tx + reset_tx(dev); + + if (gt64240_debug > 3) + printk("%s: gt64240_init: Curr Tx Desc Ptr0=%x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_CURR_TX_DESC_PTR0)); + + // Setup Rx + reset_rx(dev); + + if (gt64240_debug > 3) + printk("%s: gt64240_init: 1st/Curr Rx Desc Ptr0=%x/%x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_1ST_RX_DESC_PTR0), + GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0)); + + if (gt64240_debug > 3) + dump_MII(dev); + write_MII(dev, 0, 0x8000); /* force a PHY reset -- self-clearing! */ + + if (gt64240_debug > 3) + printk("%s: gt64240_init: PhyAD=%x\n", dev->name, + GT64240_READ(GT64240_ETH_PHY_ADDR_REG)); + + // setup DMA + // We want the Rx/Tx DMA to write/read data to/from memory in + // Big Endian mode. Also set DMA Burst Size to 8 64Bit words. +#ifdef DESC_DATA_BE + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_CONFIG, + (0xf << sdcrRCBit) | sdcrRIFB | (3 << + sdcrBSZBit)); +#else + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_CONFIG, sdcrBLMR | sdcrBLMT | +//- (0xf< 3) + printk("%s: gt64240_init: SDMA Config=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_SDMA_CONFIG)); + +#if 0 + // start Rx DMA + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD); +#endif + + if (gt64240_debug > 3) + printk("%s: gt64240_init: SDMA Cmd =%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_SDMA_COMM)); + +#if 1 + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, PORT_CONFIG); +#endif + + if (gt64240_debug > 3) + printk("%s: gt64240_init: Port Config=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG)); + + /* + * Disable all Type-of-Service queueing. All Rx packets will be + * treated normally and will be sent to the lowest priority + * queue. + * + * Disable flow-control for now. FIX! support flow control? + */ + +#if 1 + // clear all the MIB ctr regs + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG_EXT, + EXT_CONFIG_CLEAR); + read_mib_counters(gp); + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG_EXT, + EXT_CONFIG_CLEAR | pcxrMIBclrMode); + +#endif + if (gt64240_debug > 3) + printk("%s: gt64240_init: Port Config Ext=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG_EXT)); + + if (gt64240_debug > 3) + printk("%s: gt64240_init: Port Command=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_PORT_COMMAND)); + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_COMMAND, 0x0); + + netif_start_queue(dev); + + /* enable the port */ + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, + (PORT_CONFIG | pcrEN)); + if (gt64240_debug > 3) + printk("%s: gt64240_init: Port Config=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG)); +#if 1 + // start Rx DMA + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD); +#endif + + + // enable interrupts + enable_ether_irq(dev); + +//--- gp->last_psr |= psrLink; /* KLUDGE ALERT */ + + // we should now be receiving frames + return 0; +} + + +static int gt64240_open(struct net_device *dev) +{ + int retval; + + MOD_INC_USE_COUNT; + + if (gt64240_debug > 3) + printk("%s: gt64240_open: dev=%p\n", dev->name, dev); + + if ((retval = request_irq(dev->irq, >64240_interrupt, + SA_SHIRQ, dev->name, dev))) { + printk("%s: unable to get IRQ %d\n", dev->name, dev->irq); + MOD_DEC_USE_COUNT; + return retval; + } + // Initialize and startup the GT-64240 ethernet port + if ((retval = gt64240_init(dev))) { + printk("%s: error in gt64240_open\n", dev->name); + free_irq(dev->irq, dev); + MOD_DEC_USE_COUNT; + return retval; + } + + if (gt64240_debug > 3) + printk("%s: gt64240_open: Initialization done.\n", + dev->name); + + return 0; +} + +static int gt64240_close(struct net_device *dev) +{ + if (gt64240_debug > 3) + printk("%s: gt64240_close: dev=%p\n", dev->name, dev); + + // stop the device + if (netif_device_present(dev)) { + netif_stop_queue(dev); + hard_stop(dev); + } + + free_irq(dev->irq, dev); + + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef GT64240_NAPI +/* + * Function will release Tx skbs which are now complete + */ +static void gt64240_tx_fill(struct net_device *netdev, u32 status) +{ + struct gt64240_private *gp = + (struct gt64240_private *) netdev->priv; + int nextOut, cdp; + gt64240_td_t *td; + u32 cmdstat; + + cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_TX_DESC_PTR0) + - gp->tx_ring_dma) / sizeof(gt64240_td_t); + + for (nextOut = gp->tx_next_out; nextOut != cdp; + nextOut = (nextOut + 1) % TX_RING_SIZE) { + if (--gp->intr_work_done == 0) + break; + + td = &gp->tx_ring[nextOut]; + cmdstat = td->cmdstat; + + if (cmdstat & (u32) txOwn) + break; + + if (gp->tx_full) { + gp->tx_full = 0; + if (gp->last_psr & psrLink) { + netif_wake_queue(netdev); + } + } + // decrement tx ring buffer count + if (gp->tx_count) + gp->tx_count--; + + // free the skb + if (gp->tx_skbuff[nextOut]) { + dev_kfree_skb_irq(gp->tx_skbuff[nextOut]); + gp->tx_skbuff[nextOut] = NULL; + } + } + + gp->tx_next_out = nextOut; + + if ((status & icrTxEndLow) && gp->tx_count != 0) + // we must restart the DMA + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, + sdcmrERD | sdcmrTXDL); +} + +/* + * Main function for NAPI + */ +static int gt64240_poll(struct net_device *netdev, int *budget) +{ + struct gt64240_private *gp = + (struct gt64240_private *) netdev->priv; + unsigned long flags; + int done = 1, orig_budget, work_done; + u32 intMask, status = GT64240ETH_READ(gp, GT64240_ETH_INT_CAUSE); + + spin_lock_irqsave(&gp->lock, flags); + gt64240_tx_fill(netdev, status); + + if (GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0) != + gp->rx_next_out) { + orig_budget = *budget; + if (orig_budget > netdev->quota) + orig_budget = netdev->quota; + + work_done = gt64240_rx(netdev, status, orig_budget); + *budget -= work_done; + netdev->quota -= work_done; + if (work_done >= orig_budget) + done = 0; + if (done) { + __netif_rx_complete(netdev); + enable_ether_irq(netdev); + } + } + + spin_unlock_irqrestore(&gp->lock, flags); +} +#endif + +static int gt64240_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + unsigned long flags; + int nextIn; + + spin_lock_irqsave(&gp->lock, flags); + + nextIn = gp->tx_next_in; + + if (gt64240_debug > 3) { + printk("%s: gt64240_tx: nextIn=%d.\n", dev->name, nextIn); + } + + if (gp->tx_count >= TX_RING_SIZE) { + printk("%s: Tx Ring full, pkt dropped.\n", dev->name); + gp->stats.tx_dropped++; + spin_unlock_irqrestore(&gp->lock, flags); + return 1; + } + + if (!(gp->last_psr & psrLink)) { + printk("%s: gt64240_tx: Link down, pkt dropped.\n", + dev->name); + gp->stats.tx_dropped++; + spin_unlock_irqrestore(&gp->lock, flags); +//--- dump_MII(dev); /* KLUDGE ALERT !!! */ + return 1; + } + + if (gp->tx_ring[nextIn].cmdstat & txOwn) { + printk + ("%s: gt64240_tx: device owns descriptor, pkt dropped.\n", + dev->name); + gp->stats.tx_dropped++; + // stop the queue, so Tx timeout can fix it + netif_stop_queue(dev); + spin_unlock_irqrestore(&gp->lock, flags); + return 1; + } + // Prepare the Descriptor at tx_next_in + gp->tx_skbuff[nextIn] = skb; + gp->tx_ring[nextIn].byte_cnt = skb->len; + gp->tx_ring[nextIn].buff_ptr = virt_to_phys(skb->data); + + // make sure packet gets written back to memory + dma_cache_wback_inv((unsigned long) (skb->data), skb->len); + mb(); + + // Give ownership to device, set first and last desc, enable interrupt + // Setting of ownership bit must be *last*! + gp->tx_ring[nextIn].cmdstat = + txOwn | txGenCRC | txEI | txPad | txFirst | txLast; + + if (gt64240_debug > 5) { + dump_tx_desc(dev, nextIn); + dump_skb(dev, skb); + } + // increment tx_next_in with wrap + gp->tx_next_in = (nextIn + 1) % TX_RING_SIZE; + +//+prk20aug01: + if (0) { /* ROLLINS */ + GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0, + virt_to_phys(&gp->tx_ring[nextIn])); + } + + if (gt64240_debug > 3) { /*+prk17aug01 */ + printk + ("%s: gt64240_tx: TX_PTR0=0x%08x, EthPortStatus=0x%08x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_CURR_TX_DESC_PTR0), + GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS)); + } + // If DMA is stopped, restart + if (!((GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS)) & psrTxLow)) { + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, + sdcmrERD | sdcmrTXDL); + } + + if (gt64240_debug > 3) { /*+prk17aug01 */ + printk + ("%s: gt64240_tx: TX_PTR0=0x%08x, EthPortStatus=0x%08x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_CURR_TX_DESC_PTR0), + GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS)); + } + // increment count and stop queue if full + if (++gp->tx_count >= TX_RING_SIZE) { + gp->tx_full = 1; + netif_stop_queue(dev); + } + + dev->trans_start = jiffies; + spin_unlock_irqrestore(&gp->lock, flags); + + return 0; +} + + +static int +#ifdef GT64240_NAPI +gt64240_rx(struct net_device *dev, u32 status, int budget) +#else +gt64240_rx(struct net_device *dev, u32 status) +#endif +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + struct sk_buff *skb; + int pkt_len, nextOut, cdp; + gt64240_rd_t *rd; + u32 cmdstat; + + if (gt64240_debug > 3) + printk("%s: gt64240_rx: dev=%p, status=%x\n", + dev->name, dev, status); + + cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0) + - gp->rx_ring_dma) / sizeof(gt64240_rd_t); + + // Continue until we reach the current descriptor pointer + for (nextOut = gp->rx_next_out; nextOut != cdp; + nextOut = (nextOut + 1) % RX_RING_SIZE) { + +#ifdef GT64240_NAPI + if (budget <= 0) + break; + + budget--; +#endif + + if (--gp->intr_work_done == 0) + break; + + if (gt64240_debug > 4) + dump_rx_desc(dev, nextOut); + + rd = &gp->rx_ring[nextOut]; + cmdstat = rd->cmdstat; + + if (gt64240_debug > 3) + printk("%s: isr: Rx desc cmdstat=%x, nextOut=%d\n", + dev->name, cmdstat, nextOut); + + if (cmdstat & (u32) rxOwn) { + if (gt64240_debug > 2) + printk + ("%s: gt64240_rx: device owns descriptor!\n", + dev->name); + // DMA is not finished updating descriptor??? + // Leave and come back later to pick-up where we left off. + break; + } + // must be first and last (ie only) buffer of packet + if (!(cmdstat & (u32) rxFirst) + || !(cmdstat & (u32) rxLast)) { + printk + ("%s: gt64240_rx: desc not first and last!\n", + dev->name); + cmdstat |= (u32) rxOwn; + rd->cmdstat = cmdstat; + continue; + } + // Drop this received pkt if there were any errors + if ((cmdstat & (u32) rxErrorSummary) + || (status & icrRxError)) { + // update the detailed rx error counters that are not covered + // by the MIB counters. + if (cmdstat & (u32) rxOverrun) + gp->stats.rx_fifo_errors++; + cmdstat |= (u32) rxOwn; + rd->cmdstat = cmdstat; + continue; + } + + pkt_len = rd->byte_cnt; + + /* Create new skb. */ +// skb = dev_alloc_skb(pkt_len+2); + skb = dev_alloc_skb(1538); + if (skb == NULL) { + printk("%s: Memory squeeze, dropping packet.\n", + dev->name); + gp->stats.rx_dropped++; + cmdstat |= (u32) rxOwn; + rd->cmdstat = cmdstat; + continue; + } + skb->dev = dev; + skb_reserve(skb, 2); /* 16 byte IP header align */ + memcpy(skb_put(skb, pkt_len), + &gp->rx_buff[nextOut * PKT_BUF_SZ], pkt_len); + skb->protocol = eth_type_trans(skb, dev); + if (gt64240_debug > 4) /* will probably Oops! */ + dump_data(dev, &gp->rx_buff[nextOut * PKT_BUF_SZ], + pkt_len); + if (gt64240_debug > 4) + dump_skb(dev, skb); + + /* NIC performed some checksum computation */ + skb->ip_summed = CHECKSUM_UNNECESSARY; +#ifdef GT64240_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); /* pass the packet to upper layers */ +#endif + + // now we can release ownership of this desc back to device + cmdstat |= (u32) rxOwn; + rd->cmdstat = cmdstat; + + dev->last_rx = jiffies; + } + + if (gt64240_debug > 3 && nextOut == gp->rx_next_out) + printk("%s: gt64240_rx: RxCDP did not increment?\n", + dev->name); + + gp->rx_next_out = nextOut; + return 0; +} + + +static void gt64240_tx_complete(struct net_device *dev, u32 status) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + int nextOut, cdp; + gt64240_td_t *td; + u32 cmdstat; + + cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_TX_DESC_PTR0) + - gp->tx_ring_dma) / sizeof(gt64240_td_t); + + if (gt64240_debug > 3) { /*+prk17aug01 */ + nextOut = gp->tx_next_out; + printk + ("%s: tx_complete: TX_PTR0=0x%08x, cdp=%d. nextOut=%d.\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_CURR_TX_DESC_PTR0), + cdp, nextOut); + td = &gp->tx_ring[nextOut]; + } + +/*** NEED to check and CLEAR these errors every time thru here: ***/ + if (gt64240_debug > 2) { + if (GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE)) + printk + ("%s: gt64240_tx_complete: CIU Cause=%08x, Mask=%08x, EAddr=%08x\n", + dev->name, + GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE), + GT64240_READ(COMM_UNIT_INTERRUPT_MASK), + GT64240_READ(COMM_UNIT_ERROR_ADDRESS)); + GT64240_WRITE(COMM_UNIT_INTERRUPT_CAUSE, 0); + } + // Continue until we reach the current descriptor pointer + for (nextOut = gp->tx_next_out; nextOut != cdp; + nextOut = (nextOut + 1) % TX_RING_SIZE) { + + if (--gp->intr_work_done == 0) + break; + + td = &gp->tx_ring[nextOut]; + cmdstat = td->cmdstat; + + if (cmdstat & (u32) txOwn) { + // DMA is not finished writing descriptor??? + // Leave and come back later to pick-up where we left off. + break; + } + // increment Tx error stats + if (cmdstat & (u32) txErrorSummary) { + if (gt64240_debug > 2) + printk + ("%s: tx_complete: Tx error, cmdstat = %x\n", + dev->name, cmdstat); + gp->stats.tx_errors++; + if (cmdstat & (u32) txReTxLimit) + gp->stats.tx_aborted_errors++; + if (cmdstat & (u32) txUnderrun) + gp->stats.tx_fifo_errors++; + if (cmdstat & (u32) txLateCollision) + gp->stats.tx_window_errors++; + } + + if (cmdstat & (u32) txCollision) + gp->stats.collisions += + (unsigned long) ((cmdstat & txReTxCntMask) >> + txReTxCntBit); + + // Wake the queue if the ring was full + if (gp->tx_full) { + gp->tx_full = 0; + if (gp->last_psr & psrLink) { + netif_wake_queue(dev); + } + } + // decrement tx ring buffer count + if (gp->tx_count) + gp->tx_count--; + + // free the skb + if (gp->tx_skbuff[nextOut]) { + if (gt64240_debug > 3) + printk + ("%s: tx_complete: good Tx, skb=%p\n", + dev->name, gp->tx_skbuff[nextOut]); + dev_kfree_skb_irq(gp->tx_skbuff[nextOut]); + gp->tx_skbuff[nextOut] = NULL; + } else { + printk("%s: tx_complete: no skb!\n", dev->name); + } + } + + gp->tx_next_out = nextOut; + + if ((status & icrTxEndLow) && gp->tx_count != 0) { + // we must restart the DMA + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, + sdcmrERD | sdcmrTXDL); + } +} + + +static void gt64240_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_id; + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + u32 status; + + if (dev == NULL) { + printk("%s: isr: null dev ptr\n", dev->name); + return; + } + + spin_lock(&gp->lock); + + if (gt64240_debug > 3) + printk("%s: isr: entry\n", dev->name); + + gp->intr_work_done = max_interrupt_work; + + while (gp->intr_work_done > 0) { + + status = GT64240ETH_READ(gp, GT64240_ETH_INT_CAUSE); +#ifdef GT64240_NAPI + /* dont ack Rx interrupts */ + if (!(status & icrRxBuffer)) + GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0); +#else + // ACK interrupts + GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0); +#endif + + if (gt64240_debug > 3) + printk("%s: isr: work=%d., icr=%x\n", dev->name, + gp->intr_work_done, status); + + if ((status & icrEtherIntSum) == 0) { + if (!(status & + (icrTxBufferLow | icrTxBufferHigh | + icrRxBuffer))) { + /* exit from the while() loop */ + break; + } + } + + if (status & icrMIIPhySTC) { + u32 psr = + GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS); + if (gp->last_psr != psr) { + printk("%s: port status: 0x%08x\n", + dev->name, psr); + printk + ("%s: %s MBit/s, %s-duplex, flow-control %s, link is %s,\n", + dev->name, + psr & psrSpeed ? "100" : "10", + psr & psrDuplex ? "full" : "half", + psr & psrFctl ? "disabled" : + "enabled", + psr & psrLink ? "up" : "down"); + printk + ("%s: TxLowQ is %s, TxHighQ is %s, Transmitter is %s\n", + dev->name, + psr & psrTxLow ? "running" : + "stopped", + psr & psrTxHigh ? "running" : + "stopped", + psr & psrTxInProg ? "on" : "off"); + + if ((psr & psrLink) && !gp->tx_full && + netif_queue_stopped(dev)) { + printk + ("%s: isr: Link up, waking queue.\n", + dev->name); + netif_wake_queue(dev); + } else if (!(psr & psrLink) + && !netif_queue_stopped(dev)) { + printk + ("%s: isr: Link down, stopping queue.\n", + dev->name); + netif_stop_queue(dev); + } + + gp->last_psr = psr; + } + } + + if (status & (icrTxBufferLow | icrTxEndLow)) + gt64240_tx_complete(dev, status); + + if (status & icrRxBuffer) { +#ifdef GT64240_NAPI + if (netif_rx_schedule_prep(dev)) { + disable_ether_irq(dev); + __netif_rx_schedule(dev); + } +#else + gt64240_rx(dev, status); +#endif + } + // Now check TX errors (RX errors were handled in gt64240_rx) + if (status & icrTxErrorLow) { + printk("%s: isr: Tx resource error\n", dev->name); + } + + if (status & icrTxUdr) { + printk("%s: isr: Tx underrun error\n", dev->name); + } + } + + if (gp->intr_work_done == 0) { + // ACK any remaining pending interrupts + GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0); + if (gt64240_debug > 3) + printk("%s: isr: hit max work\n", dev->name); + } + + if (gt64240_debug > 3) + printk("%s: isr: exit, icr=%x\n", + dev->name, GT64240ETH_READ(gp, + GT64240_ETH_INT_CAUSE)); + + spin_unlock(&gp->lock); +} + + +static void gt64240_tx_timeout(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + unsigned long flags; + + spin_lock_irqsave(&gp->lock, flags); + + + if (!(gp->last_psr & psrLink)) { + spin_unlock_irqrestore(&gp->lock, flags); + } else { + printk("======------> gt64240_tx_timeout: %d jiffies \n", + GT64240ETH_TX_TIMEOUT); + + disable_ether_irq(dev); + spin_unlock_irqrestore(&gp->lock, flags); + reset_tx(dev); + enable_ether_irq(dev); + + netif_wake_queue(dev); + } +} + + +static void gt64240_set_rx_mode(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + unsigned long flags; + struct dev_mc_list *mcptr; + + if (gt64240_debug > 3) + printk("%s: gt64240_set_rx_mode: dev=%p, flags=%x\n", + dev->name, dev, dev->flags); + + // stop the Receiver DMA + abort(dev, sdcmrAR); + + spin_lock_irqsave(&gp->lock, flags); + + if (dev->flags & IFF_PROMISC) + GT64240ETH_SETBIT(gp, GT64240_ETH_PORT_CONFIG, pcrPM); + else + GT64240ETH_CLRBIT(gp, GT64240_ETH_PORT_CONFIG, pcrPM); +/* + GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, + (PORT_CONFIG | pcrPM | pcrEN)); +*/ + + memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE); // clear hash table + // Add our ethernet address + gt64240_add_hash_entry(dev, dev->dev_addr); + if (dev->mc_count) { + for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) { + if (gt64240_debug > 2) { + printk("%s: gt64240_set_rx_mode: addr=\n", + dev->name); + dump_hw_addr(mcptr->dmi_addr); + } + gt64240_add_hash_entry(dev, mcptr->dmi_addr); + } + } + + if (gt64240_debug > 3) + printk("%s: gt64240_set_rx: Port Config=%x\n", dev->name, + GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG)); + + // restart Rx DMA + GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD); + + spin_unlock_irqrestore(&gp->lock, flags); +} + +static struct net_device_stats *gt64240_get_stats(struct net_device *dev) +{ + struct gt64240_private *gp = (struct gt64240_private *) dev->priv; + unsigned long flags; + + if (gt64240_debug > 3) + printk("%s: gt64240_get_stats: dev=%p\n", dev->name, dev); + + if (netif_device_present(dev)) { + spin_lock_irqsave(&gp->lock, flags); + update_stats(gp); + spin_unlock_irqrestore(&gp->lock, flags); + } + + return &gp->stats; +} diff -urN linux-2.4.24/drivers/net/gt64240eth.h linux-2.4.25/drivers/net/gt64240eth.h --- linux-2.4.24/drivers/net/gt64240eth.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/gt64240eth.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,406 @@ +/* $Id: gt64240eth.h.rca 1.1 Tue Mar 11 10:39:26 2003 doucett1 Experimental $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 Patton Electronics Company + * Copyright (C) 2002 Momentum Computer + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or support@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Ethernet driver definitions for the MIPS GT96100 Advanced + * Communication Controller. + * + * Modified for the Marvellous GT64240 Retarded Communication Controller. + * + */ +#ifndef _GT64240ETH_H +#define _GT64240ETH_H + +#include "../../arch/mips/momentum/ocelot_g/gt64240.h" + +#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400 + +/* Translate those weanie names from Galileo/VxWorks header files: */ + +#define GT64240_MRR MAIN_ROUTING_REGISTER +#define GT64240_CIU_ARBITER_CONFIG COMM_UNIT_ARBITER_CONFIGURATION_REGISTER +#define GT64240_CIU_ARBITER_CONTROL COMM_UNIT_ARBITER_CONTROL +#define GT64240_MAIN_LOW_CAUSE LOW_INTERRUPT_CAUSE_REGISTER +#define GT64240_MAIN_HIGH_CAUSE HIGH_INTERRUPT_CAUSE_REGISTER +#define GT64240_CPU_LOW_MASK CPU_INTERRUPT_MASK_REGISTER_LOW +#define GT64240_CPU_HIGH_MASK CPU_INTERRUPT_MASK_REGISTER_HIGH +#define GT64240_CPU_SELECT_CAUSE CPU_SELECT_CAUSE_REGISTER + +#define GT64240_ETH_PHY_ADDR_REG ETHERNET_PHY_ADDRESS_REGISTER +#define GT64240_ETH_PORT_CONFIG ETHERNET0_PORT_CONFIGURATION_REGISTER +#define GT64240_ETH_PORT_CONFIG_EXT ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER +#define GT64240_ETH_PORT_COMMAND ETHERNET0_PORT_COMMAND_REGISTER +#define GT64240_ETH_PORT_STATUS ETHERNET0_PORT_STATUS_REGISTER +#define GT64240_ETH_IO_SIZE ETHERNET_PORTS_DIFFERENCE_OFFSETS +#define GT64240_ETH_SMI_REG ETHERNET_SMI_REGISTER +#define GT64240_ETH_MIB_COUNT_BASE ETHERNET0_MIB_COUNTER_BASE +#define GT64240_ETH_SDMA_CONFIG ETHERNET0_SDMA_CONFIGURATION_REGISTER +#define GT64240_ETH_SDMA_COMM ETHERNET0_SDMA_COMMAND_REGISTER +#define GT64240_ETH_INT_MASK ETHERNET0_INTERRUPT_MASK_REGISTER +#define GT64240_ETH_INT_CAUSE ETHERNET0_INTERRUPT_CAUSE_REGISTER +#define GT64240_ETH_CURR_TX_DESC_PTR0 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 +#define GT64240_ETH_CURR_TX_DESC_PTR1 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 +#define GT64240_ETH_1ST_RX_DESC_PTR0 ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 +#define GT64240_ETH_CURR_RX_DESC_PTR0 ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 +#define GT64240_ETH_HASH_TBL_PTR ETHERNET0_HASH_TABLE_POINTER_REGISTER + +/* Turn on NAPI by default */ + +#define GT64240_NAPI 1 + +/* Some 64240 settings that SHOULD eventually be setup in PROM monitor: */ +/* (Board-specific to the DSL3224 Rev A board ONLY!) */ +#define D3224_MPP_CTRL0_SETTING 0x66669900 +#define D3224_MPP_CTRL1_SETTING 0x00000000 +#define D3224_MPP_CTRL2_SETTING 0x00887700 +#define D3224_MPP_CTRL3_SETTING 0x00000044 +#define D3224_GPP_IO_CTRL_SETTING 0x0000e800 +#define D3224_GPP_LEVEL_CTRL_SETTING 0xf001f703 +#define D3224_GPP_VALUE_SETTING 0x00000000 + +/* Keep the ring sizes a power of two for efficiency. */ +//-#define TX_RING_SIZE 16 +#define TX_RING_SIZE 64 /* TESTING !!! */ +#define RX_RING_SIZE 32 +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ + +#define RX_HASH_TABLE_SIZE 16384 +#define HASH_HOP_NUMBER 12 + +#define NUM_INTERFACES 3 + +#define GT64240ETH_TX_TIMEOUT HZ/4 + +#define MIPS_GT64240_BASE 0xf4000000 +#define GT64240_ETH0_BASE (MIPS_GT64240_BASE + GT64240_ETH_PORT_CONFIG) +#define GT64240_ETH1_BASE (GT64240_ETH0_BASE + GT64240_ETH_IO_SIZE) +#define GT64240_ETH2_BASE (GT64240_ETH1_BASE + GT64240_ETH_IO_SIZE) + +#if defined(CONFIG_MIPS_DSL3224) +#define GT64240_ETHER0_IRQ 4 +#define GT64240_ETHER1_IRQ 4 +#else +#define GT64240_ETHER0_IRQ -1 +#define GT64240_ETHER1_IRQ -1 +#endif + +#define REV_GT64240 0x1 +#define REV_GT64240A 0x10 + +#define GT64240ETH_READ(gp, offset) \ + GT_READ_DATA((gp)->port_offset + (offset)) + +#define GT64240ETH_WRITE(gp, offset, data) \ + GT_WRITE((gp)->port_offset + (offset), (data)) + +#define GT64240ETH_SETBIT(gp, offset, bits) \ + GT64240ETH_WRITE((gp), (offset), GT64240ETH_READ((gp), (offset)) | (bits)) + +#define GT64240ETH_CLRBIT(gp, offset, bits) \ + GT64240ETH_WRITE((gp), (offset), GT64240ETH_READ((gp), (offset)) & ~(bits)) + +#define GT64240_WRITE(ofs, data) GT_WRITE((ofs), (data)) + +#define GT64240_READ(ofs) GT_READ_DATA((ofs)) + +/* Bit definitions of the SMI Reg */ +enum { + smirDataMask = 0xffff, + smirPhyAdMask = 0x1f<<16, + smirPhyAdBit = 16, + smirRegAdMask = 0x1f<<21, + smirRegAdBit = 21, + smirOpCode = 1<<26, + smirReadValid = 1<<27, + smirBusy = 1<<28 +}; + +/* Bit definitions of the Port Config Reg */ +enum pcr_bits { + pcrPM = 1 << 0, + pcrRBM = 1 << 1, + pcrPBF = 1 << 2, + pcrEN = 1 << 7, + pcrLPBKMask = 0x3<<8, + pcrLPBKBit = 1 << 8, + pcrFC = 1<<10, + pcrHS = 1<<12, + pcrHM = 1<<13, + pcrHDM = 1<<14, + pcrHD = 1<<15, + pcrISLMask = 0x7<<28, + pcrISLBit = 28, + pcrACCS = 1<<31 +}; + +/* Bit definitions of the Port Config Extend Reg */ +enum pcxr_bits { + pcxrIGMP = 1, + pcxrSPAN = 2, + pcxrPAR = 4, + pcxrPRIOtxMask = 0x7<<3, + pcxrPRIOtxBit = 3, + pcxrPRIOrxMask = 0x3<<6, + pcxrPRIOrxBit = 6, + pcxrPRIOrxOverride = 1<<8, + pcxrDPLXen = 1<<9, + pcxrFCTLen = 1<<10, + pcxrFLP = 1<<11, + pcxrFCTL = 1<<12, + pcxrMFLMask = 0x3<<14, + pcxrMFLBit = 14, + pcxrMIBclrMode = 1<<16, + pcxrSpeed = 1<<18, + pcxrSpeeden = 1<<19, + pcxrRMIIen = 1<<20, + pcxrDSCPen = 1<<21 +}; + +/* Bit definitions of the Port Command Reg */ +enum pcmr_bits { + pcmrFJ = 1<<15 +}; + + +/* Bit definitions of the Port Status Reg */ +enum psr_bits { + psrSpeed = 1, + psrDuplex = 2, + psrFctl = 4, + psrLink = 8, + psrPause = 1<<4, + psrTxLow = 1<<5, + psrTxHigh = 1<<6, + psrTxInProg = 1<<7 +}; + +/* Bit definitions of the SDMA Config Reg */ +enum sdcr_bits { + sdcrRCMask = 0xf<<2, + sdcrRCBit = 2, + sdcrBLMR = 1<<6, + sdcrBLMT = 1<<7, + sdcrPOVR = 1<<8, + sdcrRIFB = 1<<9, + sdcrBSZMask = 0x3<<12, + sdcrBSZBit = 12 +}; + +/* Bit definitions of the SDMA Command Reg */ +enum sdcmr_bits { + sdcmrERD = 1<<7, + sdcmrAR = 1<<15, + sdcmrSTDH = 1<<16, + sdcmrSTDL = 1<<17, + sdcmrTXDH = 1<<23, + sdcmrTXDL = 1<<24, + sdcmrAT = 1<<31 +}; + +/* Bit definitions of the Interrupt Cause Reg */ +enum icr_bits { + icrRxBuffer = 1, + icrTxBufferHigh = 1<<2, + icrTxBufferLow = 1<<3, + icrTxEndHigh = 1<<6, + icrTxEndLow = 1<<7, + icrRxError = 1<<8, + icrTxErrorHigh = 1<<10, + icrTxErrorLow = 1<<11, + icrRxOVR = 1<<12, + icrTxUdr = 1<<13, + icrRxBufferQ0 = 1<<16, + icrRxBufferQ1 = 1<<17, + icrRxBufferQ2 = 1<<18, + icrRxBufferQ3 = 1<<19, + icrRxErrorQ0 = 1<<20, + icrRxErrorQ1 = 1<<21, + icrRxErrorQ2 = 1<<22, + icrRxErrorQ3 = 1<<23, + icrMIIPhySTC = 1<<28, + icrSMIdone = 1<<29, + icrEtherIntSum = 1<<31 +}; + + +/* The Rx and Tx descriptor lists. */ +#ifdef __LITTLE_ENDIAN +typedef struct { + u32 cmdstat; + u16 reserved; //-prk21aug01 u32 reserved:16; + u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; + u32 buff_ptr; + u32 next; +} gt64240_td_t; + +typedef struct { + u32 cmdstat; + u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; + u16 buff_sz; //-prk21aug01 u32 buff_sz:16; + u32 buff_ptr; + u32 next; +} gt64240_rd_t; +#elif defined(__BIG_ENDIAN) +typedef struct { + u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; + u16 reserved; //-prk21aug01 u32 reserved:16; + u32 cmdstat; + u32 next; + u32 buff_ptr; +} gt64240_td_t; + +typedef struct { + u16 buff_sz; //-prk21aug01 u32 buff_sz:16; + u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; + u32 cmdstat; + u32 next; + u32 buff_ptr; +} gt64240_rd_t; +#else +#error Either __BIG_ENDIAN or __LITTLE_ENDIAN must be defined! +#endif + + +/* Values for the Tx command-status descriptor entry. */ +enum td_cmdstat { + txOwn = 1<<31, + txAutoMode = 1<<30, + txEI = 1<<23, + txGenCRC = 1<<22, + txPad = 1<<18, + txFirst = 1<<17, + txLast = 1<<16, + txErrorSummary = 1<<15, + txReTxCntMask = 0x0f<<10, + txReTxCntBit = 10, + txCollision = 1<<9, + txReTxLimit = 1<<8, + txUnderrun = 1<<6, + txLateCollision = 1<<5 +}; + + +/* Values for the Rx command-status descriptor entry. */ +enum rd_cmdstat { + rxOwn = 1<<31, + rxAutoMode = 1<<30, + rxEI = 1<<23, + rxFirst = 1<<17, + rxLast = 1<<16, + rxErrorSummary = 1<<15, + rxIGMP = 1<<14, + rxHashExpired = 1<<13, + rxMissedFrame = 1<<12, + rxFrameType = 1<<11, + rxShortFrame = 1<<8, + rxMaxFrameLen = 1<<7, + rxOverrun = 1<<6, + rxCollision = 1<<4, + rxCRCError = 1 +}; + +/* Bit fields of a Hash Table Entry */ +enum hash_table_entry { + hteValid = 1, + hteSkip = 2, + hteRD = 4 +}; + +// The MIB counters +typedef struct { + u32 byteReceived; + u32 byteSent; + u32 framesReceived; + u32 framesSent; + u32 totalByteReceived; + u32 totalFramesReceived; + u32 broadcastFramesReceived; + u32 multicastFramesReceived; + u32 cRCError; + u32 oversizeFrames; + u32 fragments; + u32 jabber; + u32 collision; + u32 lateCollision; + u32 frames64; + u32 frames65_127; + u32 frames128_255; + u32 frames256_511; + u32 frames512_1023; + u32 frames1024_MaxSize; + u32 macRxError; + u32 droppedFrames; + u32 outMulticastFrames; + u32 outBroadcastFrames; + u32 undersizeFrames; +} mib_counters_t; + + +struct gt64240_private { + gt64240_rd_t* rx_ring; + gt64240_td_t* tx_ring; + // The Rx and Tx rings must be 16-byte aligned + dma_addr_t rx_ring_dma; + dma_addr_t tx_ring_dma; + char* hash_table; + // The Hash Table must be 8-byte aligned + dma_addr_t hash_table_dma; + int hash_mode; + + // The Rx buffers must be 8-byte aligned + char* rx_buff; + dma_addr_t rx_buff_dma; + // Tx buffers (tx_skbuff[i]->data) with less than 8 bytes + // of payload must be 8-byte aligned + struct sk_buff* tx_skbuff[TX_RING_SIZE]; + int rx_next_out; /* The next free ring entry to receive */ + int tx_next_in; /* The next free ring entry to send */ + int tx_next_out; /* The last ring entry the ISR processed */ + int tx_count; /* current # of pkts waiting to be sent in Tx ring */ + int intr_work_done; /* number of Rx and Tx pkts processed in the isr */ + int tx_full; /* Tx ring is full */ + + mib_counters_t mib; + struct net_device_stats stats; + + int io_size; + int port_num; // 0 or 1 + int chip_rev; + u32 port_offset; + + int phy_addr; // PHY address + u32 last_psr; // last value of the port status register + + int options; /* User-settable misc. driver options. */ + int drv_flags; + spinlock_t lock; /* Serialise access to device */ + struct mii_if_info mii_if; +}; + +#endif /* _GT64240ETH_H */ diff -urN linux-2.4.24/drivers/net/gt96100eth.c linux-2.4.25/drivers/net/gt96100eth.c --- linux-2.4.24/drivers/net/gt96100eth.c 2002-11-28 15:53:13.000000000 -0800 +++ linux-2.4.25/drivers/net/gt96100eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -700,7 +700,8 @@ struct net_device *dev = NULL; if (gtif->irq < 0) { - printk(KERN_ERR "%s: irq unknown - probing not supported\n", __FUNCTION_); + printk(KERN_ERR "%s: irq unknown - probing not supported\n", + __FUNCTION__); return -ENODEV; } @@ -1363,7 +1364,8 @@ gp->tx_full = 0; if (gp->last_psr & psrLink) { netif_wake_queue(dev); - dbg(2, "%s: Tx Ring was full, queue waked\n", __FUNCTION_); + dbg(2, "%s: Tx Ring was full, queue waked\n", + __FUNCTION__); } } @@ -1444,7 +1446,7 @@ if ((psr & psrLink) && !gp->tx_full && netif_queue_stopped(dev)) { dbg(0, ": Link up, waking queue.\n", - __FUNCTION_); + __FUNCTION__); netif_wake_queue(dev); } else if (!(psr & psrLink) && !netif_queue_stopped(dev)) { diff -urN linux-2.4.24/drivers/net/ioc3-eth.c linux-2.4.25/drivers/net/ioc3-eth.c --- linux-2.4.24/drivers/net/ioc3-eth.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/ioc3-eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -377,82 +377,6 @@ ip->dev->dev_addr[i - 2] = nic[i]; } -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) -/* - * Get the ether-address on SN1 nodes - */ -static void ioc3_get_eaddr_sn(struct ioc3_private *ip) -{ - int ibrick_mac_addr_get(nasid_t, char *); - struct ioc3 *ioc3 = ip->regs; - nasid_t nasid_of_ioc3; - char io7eaddr[20]; - long mac; - int err_val; - - /* - * err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr ); - * - * BAD!! The above call uses get_nasid() and assumes that - * the ioc3 pointed to by struct ioc3 is hooked up to the - * cbrick that we're running on. The proper way to make this call - * is to figure out which nasid the ioc3 is connected to - * and use that to call ibrick_mac_addr_get. Below is - * a hack to do just that. - */ - - /* - * Get the nasid of the ioc3 from the ioc3's base addr. - * FIXME: the 8 at the end assumes we're in memory mode, - * not node mode (for that, we'd change it to a 9). - * Is there a call to extract this info from a physical - * addr somewhere in an sn header file already? If so, - * we should probably use that, or restructure this routine - * to use pci_dev and generic numa nodeid getting stuff. - */ - nasid_of_ioc3 = (((unsigned long)ioc3 >> 33) & ~(-1 << 8)); - err_val = ibrick_mac_addr_get(nasid_of_ioc3, io7eaddr ); - - - if (err_val) { - /* Couldn't read the eeprom; try OSLoadOptions. */ - printk("WARNING: ibrick_mac_addr_get failed: %d\n", err_val); - - /* this is where we hardwire the mac address - * 1st ibrick had 08:00:69:11:34:75 - * 2nd ibrick had 08:00:69:11:35:35 - * - * Eagan Machines: - * mankato1 08:00:69:11:BE:95 - * warroad 08:00:69:11:bd:60 - * duron 08:00:69:11:34:60 - * - * an easy way to get the mac address is to hook - * up an ip35, then from L1 do 'cti serial' - * and then look for MAC line XXX THIS DOESN"T QUITE WORK!! - */ - printk("ioc3_get_eaddr: setting ethernet address to:\n -----> "); - ip->dev->dev_addr[0] = 0x8; - ip->dev->dev_addr[1] = 0x0; - ip->dev->dev_addr[2] = 0x69; - ip->dev->dev_addr[3] = 0x11; - ip->dev->dev_addr[4] = 0x34; - ip->dev->dev_addr[5] = 0x60; - } - else { - long simple_strtol(const char *,char **,unsigned int); - - mac = simple_strtol(io7eaddr, (char **)0, 16); - ip->dev->dev_addr[0] = (mac >> 40) & 0xff; - ip->dev->dev_addr[1] = (mac >> 32) & 0xff; - ip->dev->dev_addr[2] = (mac >> 24) & 0xff; - ip->dev->dev_addr[3] = (mac >> 16) & 0xff; - ip->dev->dev_addr[4] = (mac >> 8) & 0xff; - ip->dev->dev_addr[5] = mac & 0xff; - } -} -#endif - /* * Ok, this is hosed by design. It's necessary to know what machine the * NIC is in in order to know how to read the NIC address. We also have @@ -460,30 +384,15 @@ */ static void ioc3_get_eaddr(struct ioc3_private *ip) { - void (*do_get_eaddr)(struct ioc3_private *ip) = NULL; int i; - /* - * We should also use this code for PCI cards, no matter what host - * machine but how to know that we're a PCI card? - */ -#ifdef CONFIG_SGI_IP27 - do_get_eaddr = ioc3_get_eaddr_nic; -#endif -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) - do_get_eaddr = ioc3_get_eaddr_sn; -#endif - if (!do_get_eaddr) { - printk(KERN_ERR "Don't know how to read MAC address of this " - "IOC3 NIC\n"); - return; - } + ioc3_get_eaddr_nic(ip); printk("Ethernet address is "); for (i = 0; i < 6; i++) { printk("%02x", ip->dev->dev_addr[i]); - if (i < 7) + if (i < 5) printk(":"); } printk(".\n"); @@ -588,7 +497,7 @@ ip->stats.rx_frame_errors++; next: ip->rx_skbs[n_entry] = new_skb; - rxr[n_entry] = cpu_to_be32((0xa5UL << 56) | + rxr[n_entry] = cpu_to_be64((0xa5UL << 56) | ((unsigned long) rxb & TO_PHYS_MASK)); rxb->w0 = 0; /* Clear valid flag */ n_entry = (n_entry + 1) & 511; /* Update erpir */ @@ -1552,11 +1461,11 @@ #endif spin_lock_init(&ip->ioc3_lock); + init_timer(&ip->ioc3_timer); ioc3_stop(ip); ioc3_init(ip); - init_timer(&ip->ioc3_timer); ioc3_mii_init(ip); if (ip->phy == -1) { @@ -1610,6 +1519,7 @@ struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; + unregister_netdev(dev); iounmap(ioc3); pci_release_regions(pdev); kfree(dev); @@ -1622,10 +1532,10 @@ MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl); static struct pci_driver ioc3_driver = { - name: "ioc3-eth", - id_table: ioc3_pci_tbl, - probe: ioc3_probe, - remove: __devexit_p(ioc3_remove_one), + .name = "ioc3-eth", + .id_table = ioc3_pci_tbl, + .probe = ioc3_probe, + .remove = __devexit_p(ioc3_remove_one), }; static int __init ioc3_init_module(void) diff -urN linux-2.4.24/drivers/net/irda/Config.in linux-2.4.25/drivers/net/irda/Config.in --- linux-2.4.24/drivers/net/irda/Config.in 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/irda/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -37,6 +37,7 @@ dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA dep_tristate 'ALi M5123 FIR (Experimental)' CONFIG_ALI_FIR $CONFIG_IRDA dep_tristate 'VLSI 82C147 SIR/MIR/FIR (Experimental)' CONFIG_VLSI_FIR $CONFIG_IRDA +dep_tristate 'VIA IrCC (Experimental)' CONFIG_VIA_IRCC_FIR $CONFIG_IRDA fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA diff -urN linux-2.4.24/drivers/net/irda/Makefile linux-2.4.25/drivers/net/irda/Makefile --- linux-2.4.24/drivers/net/irda/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.25/drivers/net/irda/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -22,6 +22,7 @@ obj-$(CONFIG_SMC_IRCC_FIR) += smc-ircc.o irport.o obj-$(CONFIG_ALI_FIR) += ali-ircc.o obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o +obj-$(CONFIG_VIA_IRCC_FIR) += via-ircc.o obj-$(CONFIG_ESI_DONGLE) += esi.o obj-$(CONFIG_TEKRAM_DONGLE) += tekram.o obj-$(CONFIG_ACTISYS_DONGLE) += actisys.o diff -urN linux-2.4.24/drivers/net/irda/act200l.c linux-2.4.25/drivers/net/irda/act200l.c --- linux-2.4.24/drivers/net/irda/act200l.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/act200l.c 2004-02-18 05:36:31.000000000 -0800 @@ -94,12 +94,12 @@ act200l_change_speed, }; -int __init act200l_init(void) +static int __init act200l_init(void) { return irda_device_register_dongle(&dongle); } -void __exit act200l_cleanup(void) +static void __exit act200l_cleanup(void) { irda_device_unregister_dongle(&dongle); } diff -urN linux-2.4.24/drivers/net/irda/au1k_ir.c linux-2.4.25/drivers/net/irda/au1k_ir.c --- linux-2.4.24/drivers/net/irda/au1k_ir.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/net/irda/au1k_ir.c 2004-02-18 05:36:31.000000000 -0800 @@ -46,7 +46,13 @@ #include #include #include +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) #include +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) +#include +#else +#error au1k_ir: unsupported board +#endif #include #include @@ -71,10 +77,16 @@ static int qos_mtt_bits = 0x07; /* 1 ms or more */ static struct net_device *ir_devs[NUM_IR_IFF]; static char version[] __devinitdata = - "au1k_ircc:1.0 ppopov@mvista.com\n"; + "au1k_ircc:1.2 ppopov@mvista.com\n"; #define RUN_AT(x) (jiffies + (x)) +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) +static BCSR * const bcsr = (BCSR *)0xAE000000; +#endif + +static spinlock_t ir_lock = SPIN_LOCK_UNLOCKED; + /* * IrDA peripheral bug. You have to read the register * twice to get the right value. @@ -126,7 +138,7 @@ if (ret != NULL) { memset(ret, 0, size); *dma_handle = virt_to_bus(ret); - ret = KSEG0ADDR(ret); + ret = (void *)KSEG0ADDR(ret); } return ret; } @@ -134,7 +146,7 @@ static void dma_free(void *vaddr, size_t size) { - vaddr = KSEG0ADDR(vaddr); + vaddr = (void *)KSEG0ADDR(vaddr); free_pages((unsigned long) vaddr, get_order(size)); } @@ -211,7 +223,7 @@ struct au1k_private *aup = NULL; int i, retval = 0, err; db_dest_t *pDB, *pDBfree; - unsigned long temp; + dma_addr_t temp; dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL); if (dev->priv == NULL) { @@ -292,6 +304,14 @@ aup->tx_ring[i]->flags = 0; aup->tx_db_inuse[i] = pDB; } + +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + /* power on */ + bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL; + au_sync(); +#endif + return 0; out: @@ -532,13 +552,13 @@ flags = ptxd->flags; if (flags & AU_OWN) { - printk(KERN_INFO "%s: tx_full\n", dev->name); + printk(KERN_DEBUG "%s: tx_full\n", dev->name); netif_stop_queue(dev); aup->tx_full = 1; return 1; } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { - printk(KERN_INFO "%s: tx_full\n", dev->name); + printk(KERN_DEBUG "%s: tx_full\n", dev->name); netif_stop_queue(dev); aup->tx_full = 1; return 1; @@ -558,6 +578,7 @@ memcpy((void *)pDB->vaddr, skb->data, skb->len); ptxd->count_0 = skb->len & 0xff; ptxd->count_1 = (skb->len >> 8) & 0xff; + } else { /* SIR */ @@ -565,6 +586,7 @@ ptxd->count_0 = len & 0xff; ptxd->count_1 = (len >> 8) & 0xff; ptxd->flags |= IR_DIS_CRC; + au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c); } ptxd->flags |= AU_OWN; au_sync(); @@ -699,12 +721,14 @@ u32 control; int ret = 0, timeout = 10, i; volatile ring_dest_t *ptxd; +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + unsigned long irda_resets; +#endif if (speed == aup->speed) return ret; - save_flags(flags); - cli(); + spin_lock_irqsave(&ir_lock, flags); /* disable PHY first */ writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); @@ -745,10 +769,20 @@ ptxd->flags = AU_OWN; } - if (speed == 4000000) + if (speed == 4000000) { +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + bcsr->resets |= BCSR_RESETS_FIR_SEL; +#else /* Pb1000 and Pb1100 */ writel(1<<13, CPLD_AUX1); - else +#endif + } + else { +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) + bcsr->resets &= ~BCSR_RESETS_FIR_SEL; +#else /* Pb1000 and Pb1100 */ writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1); +#endif + } switch (speed) { case 9600: @@ -794,18 +828,18 @@ } else { if (control & (1<<11)) - printk(KERN_INFO "%s Valid SIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); if (control & (1<<12)) - printk(KERN_INFO "%s Valid MIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); if (control & (1<<13)) - printk(KERN_INFO "%s Valid FIR config\n", dev->name); + printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); if (control & (1<<10)) - printk(KERN_INFO "%s TX enabled\n", dev->name); + printk(KERN_DEBUG "%s TX enabled\n", dev->name); if (control & (1<<9)) - printk(KERN_INFO "%s RX enabled\n", dev->name); + printk(KERN_DEBUG "%s RX enabled\n", dev->name); } - restore_flags(flags); + spin_unlock_irqrestore(&ir_lock, flags); return ret; } diff -urN linux-2.4.24/drivers/net/irda/irda-usb.c linux-2.4.25/drivers/net/irda/irda-usb.c --- linux-2.4.24/drivers/net/irda/irda-usb.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/irda-usb.c 2004-02-18 05:36:31.000000000 -0800 @@ -1584,7 +1584,7 @@ /* * Module insertion */ -int __init usb_irda_init(void) +static int __init usb_irda_init(void) { if (usb_register(&irda_driver) < 0) return -1; @@ -1598,7 +1598,7 @@ /* * Module removal */ -void __exit usb_irda_cleanup(void) +static void __exit usb_irda_cleanup(void) { struct irda_usb_cb *irda = NULL; int i; diff -urN linux-2.4.24/drivers/net/irda/ma600.c linux-2.4.25/drivers/net/irda/ma600.c --- linux-2.4.24/drivers/net/irda/ma600.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/ma600.c 2004-02-18 05:36:31.000000000 -0800 @@ -84,13 +84,13 @@ ma600_change_speed, }; -int __init ma600_init(void) +static int __init ma600_init(void) { IRDA_DEBUG(2, "%s()\n", __FUNCTION__); return irda_device_register_dongle(&dongle); } -void __exit ma600_cleanup(void) +static void __exit ma600_cleanup(void) { IRDA_DEBUG(2, "%s()\n", __FUNCTION__); irda_device_unregister_dongle(&dongle); diff -urN linux-2.4.24/drivers/net/irda/nsc-ircc.c linux-2.4.25/drivers/net/irda/nsc-ircc.c --- linux-2.4.24/drivers/net/irda/nsc-ircc.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/nsc-ircc.c 2004-02-18 05:36:31.000000000 -0800 @@ -83,8 +83,10 @@ static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); +static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); +static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); /* These are the known NSC chips */ static nsc_chip_t chips[] = { @@ -93,10 +95,16 @@ nsc_ircc_probe_108, nsc_ircc_init_108 }, { "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8, nsc_ircc_probe_338, nsc_ircc_init_338 }, + /* Contributed by Jan Frey - IBM A30/A31 */ + { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, + nsc_ircc_probe_39x, nsc_ircc_init_39x }, + { NULL } +#if 0 + /* Probably bogus, "PC8739x" should be the real thing. Jean II */ /* Contributed by Kevin Thayer - OmniBook 6100 */ { "PC87338?", { 0x2e, 0x15c, 0x398 }, 0x08, 0x00, 0xf8, nsc_ircc_probe_338, nsc_ircc_init_338 }, - { NULL } +#endif }; /* Max 4 instances for now */ @@ -439,7 +447,7 @@ outb(0x00, cfg_base+1); /* Disable device */ /* Base Address and Interrupt Control Register (BAIC) */ - outb(0, cfg_base); + outb(CFG_108_BAIC, cfg_base); switch (info->fir_base) { case 0x3e8: outb(0x14, cfg_base+1); break; case 0x2e8: outb(0x15, cfg_base+1); break; @@ -459,7 +467,7 @@ case 15: temp = 0x07; break; default: ERROR("%s(), invalid irq", __FUNCTION__); } - outb(1, cfg_base); + outb(CFG_108_CSRT, cfg_base); switch (info->dma) { case 0: outb(0x08+temp, cfg_base+1); break; @@ -468,7 +476,7 @@ default: ERROR("%s(), invalid dma", __FUNCTION__); } - outb(2, cfg_base); /* Mode Control Register (MCTL) */ + outb(CFG_108_MCTL, cfg_base); /* Mode Control Register (MCTL) */ outb(0x03, cfg_base+1); /* Enable device */ return 0; @@ -486,7 +494,7 @@ int reg; /* Read address and interrupt control register (BAIC) */ - outb(CFG_BAIC, cfg_base); + outb(CFG_108_BAIC, cfg_base); reg = inb(cfg_base+1); switch (reg & 0x03) { @@ -508,7 +516,7 @@ __FUNCTION__, info->fir_base); /* Read control signals routing register (CSRT) */ - outb(CFG_CSRT, cfg_base); + outb(CFG_108_CSRT, cfg_base); reg = inb(cfg_base+1); switch (reg & 0x07) { @@ -557,7 +565,7 @@ IRDA_DEBUG(2, "%s(), probing dma=%d\n", __FUNCTION__, info->dma); /* Read mode control register (MCTL) */ - outb(CFG_MCTL, cfg_base); + outb(CFG_108_MCTL, cfg_base); reg = inb(cfg_base+1); info->enabled = reg & 0x01; @@ -594,13 +602,13 @@ int pnp; /* Read funtion enable register (FER) */ - outb(CFG_FER, cfg_base); + outb(CFG_338_FER, cfg_base); reg = inb(cfg_base+1); info->enabled = (reg >> 2) & 0x01; /* Check if we are in Legacy or PnP mode */ - outb(CFG_PNP0, cfg_base); + outb(CFG_338_PNP0, cfg_base); reg = inb(cfg_base+1); pnp = (reg >> 3) & 0x01; @@ -615,7 +623,7 @@ info->fir_base = reg; } else { /* Read function address register (FAR) */ - outb(CFG_FAR, cfg_base); + outb(CFG_338_FAR, cfg_base); reg = inb(cfg_base+1); switch ((reg >> 4) & 0x03) { @@ -665,19 +673,19 @@ info->sir_base = info->fir_base; /* Read PnP register 1 (PNP1) */ - outb(CFG_PNP1, cfg_base); + outb(CFG_338_PNP1, cfg_base); reg = inb(cfg_base+1); info->irq = reg >> 4; /* Read PnP register 3 (PNP3) */ - outb(CFG_PNP3, cfg_base); + outb(CFG_338_PNP3, cfg_base); reg = inb(cfg_base+1); info->dma = (reg & 0x07) - 1; /* Read power and test register (PTR) */ - outb(CFG_PTR, cfg_base); + outb(CFG_338_PTR, cfg_base); reg = inb(cfg_base+1); info->suspended = reg & 0x01; @@ -685,6 +693,130 @@ return 0; } + +/* + * Function nsc_ircc_init_39x (chip, info) + * + * Now that we know it's a '39x (see probe below), we need to + * configure it so we can use it. + * + * The NSC '338 chip is a Super I/O chip with a "bank" architecture, + * the configuration of the different functionality (serial, parallel, + * floppy...) are each in a different bank (Logical Device Number). + * The base address, irq and dma configuration registers are common + * to all functionalities (index 0x30 to 0x7F). + * There is only one configuration register specific to the + * serial port, CFG_39X_SPC. + * JeanII + * + * Note : this code was written by Jan Frey + */ +static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info) +{ + int cfg_base = info->cfg_base; + int enabled; + + /* User is shure about his config... accept it. */ + IRDA_DEBUG(2, "%s(): nsc_ircc_init_39x (user settings): " + "io=0x%04x, irq=%d, dma=%d\n", + __FUNCTION__, info->fir_base, info->irq, info->dma); + + /* Access bank for SP2 */ + outb(CFG_39X_LDN, cfg_base); + outb(0x02, cfg_base+1); + + /* Configure SP2 */ + + /* We want to enable the device if not enabled */ + outb(CFG_39X_ACT, cfg_base); + enabled = inb(cfg_base+1) & 0x01; + + if (!enabled) { + /* Enable the device */ + outb(CFG_39X_SIOCF1, cfg_base); + outb(0x01, cfg_base+1); + /* May want to update info->enabled. Jean II */ + } + + /* Enable UART bank switching (bit 7) ; Sets the chip to normal + * power mode (wake up from sleep mode) (bit 1) */ + outb(CFG_39X_SPC, cfg_base); + outb(0x82, cfg_base+1); + + return 0; +} + +/* + * Function nsc_ircc_probe_39x (chip, info) + * + * Test if we really have a '39x chip at the given address + * + * Note : this code was written by Jan Frey + */ +static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) +{ + int cfg_base = info->cfg_base; + int reg1, reg2, irq, irqt, dma1, dma2; + int enabled, susp; + + IRDA_DEBUG(2, "%s(), nsc_ircc_probe_39x, base=%d\n", + __FUNCTION__, cfg_base); + + /* This function should be executed with irq off to avoid + * another driver messing with the Super I/O bank - Jean II */ + + /* Access bank for SP2 */ + outb(CFG_39X_LDN, cfg_base); + outb(0x02, cfg_base+1); + + /* Read infos about SP2 ; store in info struct */ + outb(CFG_39X_BASEH, cfg_base); + reg1 = inb(cfg_base+1); + outb(CFG_39X_BASEL, cfg_base); + reg2 = inb(cfg_base+1); + info->fir_base = (reg1 << 8) | reg2; + + outb(CFG_39X_IRQNUM, cfg_base); + irq = inb(cfg_base+1); + outb(CFG_39X_IRQSEL, cfg_base); + irqt = inb(cfg_base+1); + info->irq = irq; + + outb(CFG_39X_DMA0, cfg_base); + dma1 = inb(cfg_base+1); + outb(CFG_39X_DMA1, cfg_base); + dma2 = inb(cfg_base+1); + info->dma = dma1 -1; + + outb(CFG_39X_ACT, cfg_base); + info->enabled = enabled = inb(cfg_base+1) & 0x01; + + outb(CFG_39X_SPC, cfg_base); + susp = 1 - ((inb(cfg_base+1) & 0x02) >> 1); + + IRDA_DEBUG(2, "%s(): io=0x%02x%02x, irq=%d (type %d), rxdma=%d, txdma=%d, enabled=%d (suspended=%d)\n", __FUNCTION__, reg1,reg2,irq,irqt,dma1,dma2,enabled,susp); + + /* Configure SP2 */ + + /* We want to enable the device if not enabled */ + outb(CFG_39X_ACT, cfg_base); + enabled = inb(cfg_base+1) & 0x01; + + if (!enabled) { + /* Enable the device */ + outb(CFG_39X_SIOCF1, cfg_base); + outb(0x01, cfg_base+1); + /* May want to update info->enabled. Jean II */ + } + + /* Enable UART bank switching (bit 7) ; Sets the chip to normal + * power mode (wake up from sleep mode) (bit 1) */ + outb(CFG_39X_SPC, cfg_base); + outb(0x82, cfg_base+1); + + return 0; +} + /* * Function nsc_ircc_setup (info) * diff -urN linux-2.4.24/drivers/net/irda/smc-ircc.c linux-2.4.25/drivers/net/irda/smc-ircc.c --- linux-2.4.24/drivers/net/irda/smc-ircc.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/net/irda/smc-ircc.c 2004-02-18 05:36:31.000000000 -0800 @@ -1210,7 +1210,7 @@ return ircc_init(); } -void __exit smc_cleanup(void) +static void __exit smc_cleanup(void) { int i; diff -urN linux-2.4.24/drivers/net/irda/via-ircc.c linux-2.4.25/drivers/net/irda/via-ircc.c --- linux-2.4.24/drivers/net/irda/via-ircc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/via-ircc.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1652 @@ +/******************************************************************** + Filename: via-ircc.c + Version: 1.0 + Description: Driver for the VIA VT8231/VT8233 IrDA chipsets + Author: VIA Technologies,inc + Date : 08/06/2003 + +Copyright (c) 1998-2003 VIA Technologies, Inc. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +F01 Oct/02/02: Modify code for V0.11(move out back to back transfer) +F02 Oct/28/02: Add SB device ID for 3147 and 3177. + Comment : + jul/09/2002 : only implement two kind of dongle currently. + Oct/02/2002 : work on VT8231 and VT8233 . + Aug/06/2003 : change driver format to pci driver . + + ********************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "via-ircc.h" + +//#define DBG_IO 1 +//#define DBGMSG 1 +//#define DBGMSG_96 1 +//#define DBGMSG_76 1 +//static int debug=0; + + +#define DBG(x) {if (debug) x;} + +#define VIA_MODULE_NAME "via-ircc" +#define CHIP_IO_EXTENT 8 +#define BROKEN_DONGLE_ID + +static char *driver_name = "via-ircc"; + +/* Module parameters */ +static int qos_mtt_bits = 0x07; /* 1 ms or more */ +static int dongle_id = 9; //defalut IBM type + +/* Resource is allocate by BIOS user only need to supply dongle_id*/ +MODULE_PARM(dongle_id, "i"); + +/* Max 4 instances for now */ +static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; + +/* Some prototypes */ +static int via_ircc_open(int i, chipio_t * info, unsigned int id); +static int via_ircc_close(struct via_ircc_cb *self); +static int via_ircc_setup(chipio_t * info, unsigned int id); +static int via_ircc_dma_receive(struct via_ircc_cb *self); +static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, + int iobase); +static int via_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev); +static int via_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev); +static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud); +static irqreturn_t via_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +static int via_ircc_is_receiving(struct via_ircc_cb *self); +static int via_ircc_read_dongle_id(int iobase); + +static int via_ircc_net_init(struct net_device *dev); +static int via_ircc_net_open(struct net_device *dev); +static int via_ircc_net_close(struct net_device *dev); +static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, + int cmd); +static struct net_device_stats *via_ircc_net_get_stats(struct net_device + *dev); +static void via_ircc_change_dongle_speed(int iobase, int speed, + int dongle_id); +static int RxTimerHandler(struct via_ircc_cb *self, int iobase); +void hwreset(struct via_ircc_cb *self); +static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase); +static int upload_rxdata(struct via_ircc_cb *self, int iobase); +static int via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id); +static void via_remove_one (struct pci_dev *pdev); + +/* Should use udelay() instead, even if we are x86 only - Jean II */ +void iodelay(int udelay) +{ + u8 data; + int i; + + for (i = 0; i < udelay; i++) { + data = inb(0x80); + } +} + +static struct pci_device_id via_pci_tbl[] = { + { PCI_VENDOR_ID_VIA, DeviceID1, PCI_ANY_ID, PCI_ANY_ID,0,0,0 }, + { PCI_VENDOR_ID_VIA, DeviceID2, PCI_ANY_ID, PCI_ANY_ID,0,0,1 }, + { PCI_VENDOR_ID_VIA, DeviceID3, PCI_ANY_ID, PCI_ANY_ID,0,0,2 }, + { PCI_VENDOR_ID_VIA, DeviceID4, PCI_ANY_ID, PCI_ANY_ID,0,0,3 }, + { PCI_VENDOR_ID_VIA, DeviceID5, PCI_ANY_ID, PCI_ANY_ID,0,0,4 }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci,via_pci_tbl); + + +static struct pci_driver via_driver = { + .name = VIA_MODULE_NAME, + .id_table = via_pci_tbl, + .probe = via_init_one, + .remove = __devexit_p(via_remove_one), +}; + + +/* + * Function via_ircc_init () + * + * Initialize chip. Just find out chip type and resource. + */ +static int __devinit via_ircc_init(void) +{ + int rc; + +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_ircc_init ......\n")); +#endif + rc = pci_register_driver (&via_driver); +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_ircc_init :rc = %d......\n",rc)); +#endif + if (rc < 1) { +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_ircc_init return -ENODEV......\n")); +#endif + if (rc == 0) pci_unregister_driver (&via_driver); + return -ENODEV; + } + return 0; + +} + +static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id) +{ + int rc; + u8 temp,oldPCI_40,oldPCI_44,bTmp,bTmp1; + u16 Chipset,FirDRQ1,FirDRQ0,FirIRQ,FirIOBase; + chipio_t info; + +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one : Device ID=(0X%X)\n",id->device)); +#endif + if(id->device != DeviceID1 && id->device != DeviceID2 && + id->device != DeviceID3 && id->device != DeviceID4 && + id->device != DeviceID5 ){ +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one : Device ID(0X%X) not Supported\n",id->device)); +#endif + return -ENODEV; //South not exist !!!!! + } + rc = pci_enable_device (pcidev); +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one : rc=%d\n",rc)); +#endif + if (rc) + return -ENODEV; + //South Bridge exist + if ( ReadLPCReg(0x20) != 0x3C ) + Chipset=0x3096; + else + Chipset=0x3076; + if (Chipset==0x3076) { +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one : 3076 ......\n")); +#endif + WriteLPCReg(7,0x0c ); + temp=ReadLPCReg(0x30);//check if BIOS Enable Fir + if((temp&0x01)==1) { // BIOS close or no FIR + WriteLPCReg(0x1d, 0x82 ); + WriteLPCReg(0x23,0x18); + temp=ReadLPCReg(0xF0); + if((temp&0x01)==0) { + temp=(ReadLPCReg(0x74)&0x03); //DMA + FirDRQ0=temp + 4; + temp=(ReadLPCReg(0x74)&0x0C) >> 2; + FirDRQ1=temp + 4; + } else { + temp=(ReadLPCReg(0x74)&0x0C) >> 2; //DMA + FirDRQ0=temp + 4; + FirDRQ1=FirDRQ0; + } + FirIRQ=(ReadLPCReg(0x70)&0x0f); //IRQ + FirIOBase=ReadLPCReg(0x60 ) << 8; //IO Space :high byte + FirIOBase=FirIOBase| ReadLPCReg(0x61) ; //low byte + FirIOBase=FirIOBase ; + info.fir_base=FirIOBase; + info.irq=FirIRQ; + info.dma=FirDRQ1; + info.dma2=FirDRQ0; + pci_read_config_byte(pcidev,0x40,&bTmp); + pci_write_config_byte(pcidev,0x40,((bTmp | 0x08) & 0xfe)); + pci_read_config_byte(pcidev,0x42,&bTmp); + pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); + pci_write_config_byte(pcidev,0x5a,0xc0); + WriteLPCReg(0x28, 0x70 ); + if (via_ircc_open(0, &info,0x3076) == 0) + rc=0; + } else + rc = -ENODEV; //IR not turn on + } else { //Not VT1211 +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one : 3096 ......\n")); +#endif + pci_read_config_byte(pcidev,0x67,&bTmp);//check if BIOS Enable Fir + if((bTmp&0x01)==1) { // BIOS enable FIR + //Enable Double DMA clock + pci_read_config_byte(pcidev,0x42,&oldPCI_40); + pci_write_config_byte(pcidev,0x42,oldPCI_40 | 0x80); + pci_read_config_byte(pcidev,0x40,&oldPCI_40); + pci_write_config_byte(pcidev,0x40,oldPCI_40 & 0xf7); + pci_read_config_byte(pcidev,0x44,&oldPCI_44); + pci_write_config_byte(pcidev,0x44,0x4e); + //---------- read configuration from Function0 of south bridge + if((bTmp&0x02)==0) { + pci_read_config_byte(pcidev,0x44,&bTmp1); //DMA + FirDRQ0 = (bTmp1 & 0x30) >> 4; + pci_read_config_byte(pcidev,0x44,&bTmp1); + FirDRQ1 = (bTmp1 & 0xc0) >> 6; + } else { + pci_read_config_byte(pcidev,0x44,&bTmp1); //DMA + FirDRQ0 = (bTmp1 & 0x30) >> 4 ; + FirDRQ1=0; + } + pci_read_config_byte(pcidev,0x47,&bTmp1); //IRQ + FirIRQ = bTmp1 & 0x0f; + + pci_read_config_byte(pcidev,0x69,&bTmp); + FirIOBase = bTmp << 8;//hight byte + pci_read_config_byte(pcidev,0x68,&bTmp); + FirIOBase = (FirIOBase | bTmp ) & 0xfff0; + //------------------------- + info.fir_base=FirIOBase; + info.irq=FirIRQ; + info.dma=FirDRQ1; + info.dma2=FirDRQ0; + if (via_ircc_open(0, &info,0x3096) == 0) + rc=0; + } else + rc = -ENODEV; //IR not turn on !!!!! + }//Not VT1211 +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_init_one End : rc=%d\n",rc)); +#endif + return rc; +} + +/* + * Function via_ircc_clean () + * + * Close all configured chips + * + */ +static void __devexit via_ircc_clean(void) +{ + int i; + +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_ircc_clean\n")); +#endif + for (i=0; i < 4; i++) { + if (dev_self[i]) + via_ircc_close(dev_self[i]); + } +} + +static void __devexit via_remove_one (struct pci_dev *pdev) +{ +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_remove_one : ......\n")); +#endif + via_ircc_clean(); + +} + +static void __devexit via_ircc_cleanup(void) +{ + +#ifdef HEADMSG + DBG(printk(KERN_INFO "via_ircc_cleanup ......\n")); +#endif + via_ircc_clean(); + pci_unregister_driver (&via_driver); +} + +/* + * Function via_ircc_open (iobase, irq) + * + * Open driver instance + * + */ +static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) +{ + struct net_device *dev; + struct via_ircc_cb *self; + int err; + + if ((via_ircc_setup(info, id)) == -1) + return -1; + + /* Allocate new instance of the driver */ + self = kmalloc(sizeof(struct via_ircc_cb), GFP_KERNEL); + if (self == NULL) { + return -ENOMEM; + } + memset(self, 0, sizeof(struct via_ircc_cb)); + spin_lock_init(&self->lock); + + /* Need to store self somewhere */ + dev_self[i] = self; + self->index = i; + /* Initialize Resource */ + self->io.cfg_base = info->cfg_base; + self->io.fir_base = info->fir_base; + self->io.irq = info->irq; + self->io.fir_ext = CHIP_IO_EXTENT; + self->io.dma = info->dma; + self->io.dma2 = info->dma2; + self->io.fifo_size = 32; + self->chip_id = id; + self->st_fifo.len = 0; + self->RxDataReady = 0; + + /* Reserve the ioports that we need */ + if (!request_region(self->io.fir_base, self->io.fir_ext, driver_name)) { +// WARNING(__FUNCTION__ "(), can't get iobase of 0x%03x\n",self->io.fir_base); + err = -ENODEV; + goto err_out1; + } + + /* Initialize QoS for this device */ + irda_init_max_qos_capabilies(&self->qos); + /* The only value we must override it the baudrate */ +// self->qos.baud_rate.bits = IR_9600;// May use this for testing + + self->qos.baud_rate.bits = + IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200 | + IR_576000 | IR_1152000 | (IR_4000000 << 8); + + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); + + self->flags = + IFF_FIR | IFF_MIR | IFF_SIR | IFF_DMA | IFF_PIO | IFF_DONGLE; + + /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ + self->rx_buff.truesize = 14384 + 2048; + self->tx_buff.truesize = 14384 + 2048; + + /* Allocate memory if needed */ + self->rx_buff.head = + (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA); + if (self->rx_buff.head == NULL) { + err = -ENOMEM; + goto err_out2; + } + memset(self->rx_buff.head, 0, self->rx_buff.truesize); + + self->tx_buff.head = + (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA); + if (self->tx_buff.head == NULL) { + err = -ENOMEM; + goto err_out3; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + + /* Reset Tx queue info */ + self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; + self->tx_fifo.tail = self->tx_buff.head; + + if (!(dev = dev_alloc("irda%d", &err))) { + err = -ENOMEM; + goto err_out4; + } + + dev->priv = (void *) self; + self->netdev = dev; + + /* Override the network functions we need to use */ + dev->init = via_ircc_net_init; + dev->hard_start_xmit = via_ircc_hard_xmit_sir; + dev->open = via_ircc_net_open; + dev->stop = via_ircc_net_close; + dev->do_ioctl = via_ircc_net_ioctl; + dev->get_stats = via_ircc_net_get_stats; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) + goto err_out4; + + MESSAGE("IrDA: Registered device %s\n", dev->name); + + /* Check if user has supplied the dongle id or not */ + if (!dongle_id) + dongle_id = via_ircc_read_dongle_id(self->io.fir_base); + self->io.dongle_id = dongle_id; + via_ircc_change_dongle_speed(self->io.fir_base, 9600, + self->io.dongle_id); + + return 0; + err_out4: + kfree(self->tx_buff.head); + err_out3: + kfree(self->rx_buff.head); + err_out2: + release_region(self->io.fir_base, self->io.fir_ext); + err_out1: + kfree(self); + dev_self[i] = NULL; + return err; +} + +/* + * Function via_ircc_close (self) + * + * Close driver instance + * + */ +static int __devexit via_ircc_close(struct via_ircc_cb *self) +{ + int iobase; + + IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + + ASSERT(self != NULL, return -1;); + + iobase = self->io.fir_base; + + ResetChip(iobase, 5); //hardware reset. + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } + + /* Release the PORT that this driver is using */ + IRDA_DEBUG(4, "%s(), Releasing Region %03x\n", + __FUNCTION__, self->io.fir_base); + release_region(self->io.fir_base, self->io.fir_ext); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + if (self->rx_buff.head) + kfree(self->rx_buff.head); + dev_self[self->index] = NULL; + kfree(self); + + return 0; +} + +/* + * Function via_ircc_setup (info) + * + * Returns non-negative on success. + * + */ +static int via_ircc_setup(chipio_t * info, unsigned int chip_id) +{ + int iobase = info->fir_base; + + SetMaxRxPacketSize(iobase, 0x0fff); //set to max:4095 + // FIFO Init + EnRXFIFOReadyInt(iobase, OFF); + EnRXFIFOHalfLevelInt(iobase, OFF); + EnTXFIFOHalfLevelInt(iobase, OFF); + EnTXFIFOUnderrunEOMInt(iobase, ON); + EnTXFIFOReadyInt(iobase, OFF); + InvertTX(iobase, OFF); + InvertRX(iobase, OFF); + if (ReadLPCReg(0x20) == 0x3c) + WriteLPCReg(0xF0, 0); // for VT1211 + if (IsSIROn(iobase)) { + SIRFilter(iobase, ON); + SIRRecvAny(iobase, ON); + } else { + SIRFilter(iobase, OFF); + SIRRecvAny(iobase, OFF); + } + //Int Init + EnRXSpecInt(iobase, ON); + //DMA Init Later.... + WriteReg(iobase, I_ST_CT_0, 0x80); + EnableDMA(iobase, ON); + + return 0; +} + +/* + * Function via_ircc_read_dongle_id (void) + * + */ +static int via_ircc_read_dongle_id(int iobase) +{ + int dongle_id = 9; + + return dongle_id; +} + +/* + * Function via_ircc_change_dongle_speed (iobase, speed, dongle_id) + * Change speed of the attach dongle + * only implement two type of dongle currently. + */ +static void via_ircc_change_dongle_speed(int iobase, int speed, + int dongle_id) +{ + u8 mode = 0; + + WriteReg(iobase, I_ST_CT_0, 0x0); + switch (dongle_id) { //HP1100 + case 0x00: /* same as */ + case 0x01: /* Differential serial interface */ + break; + case 0x02: /* same as */ + case 0x03: /* Reserved */ + break; + case 0x04: /* Sharp RY5HD01 */ + break; + case 0x05: /* Reserved, but this is what the Thinkpad reports */ + break; + case 0x06: /* Single-ended serial interface */ + break; + case 0x07: /* Consumer-IR only */ + break; + + case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ + UseOneRX(iobase, ON); // use one RX pin RX1,RX2 + InvertTX(iobase, OFF); + InvertRX(iobase, OFF); + + EnRX2(iobase, ON); //sir to rx2 + EnGPIOtoRX2(iobase, OFF); + + if (IsSIROn(iobase)) { //sir + // Mode select Off + SlowIRRXLowActive(iobase, ON); + udelay(1000); + SlowIRRXLowActive(iobase, OFF); + } else { + if (IsMIROn(iobase)) { //mir + // Mode select On + SlowIRRXLowActive(iobase, OFF); + udelay(20); + } else { // fir + if (IsFIROn(iobase)) { //fir + // Mode select On + SlowIRRXLowActive(iobase, OFF); + udelay(20); + } + } + } + break; + case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ + UseOneRX(iobase, ON); //use ONE RX....RX1 + InvertTX(iobase, OFF); + InvertRX(iobase, OFF); // invert RX pin + EnRX2(iobase, ON); + EnGPIOtoRX2(iobase, OFF); + if (IsSIROn(iobase)) { //sir + // Mode select On + SlowIRRXLowActive(iobase, ON); + udelay(20); + // Mode select Off + SlowIRRXLowActive(iobase, OFF); + } + if (IsMIROn(iobase)) { //mir + // Mode select On + SlowIRRXLowActive(iobase, OFF); + udelay(20); + // Mode select Off + SlowIRRXLowActive(iobase, ON); + } else { // fir + if (IsFIROn(iobase)) { //fir + // Mode select On + SlowIRRXLowActive(iobase, OFF); + // TX On + WriteTX(iobase, ON); + udelay(20); + // Mode select OFF + SlowIRRXLowActive(iobase, ON); + udelay(20); + // TX Off + WriteTX(iobase, OFF); + } + } + break; + case 0x0d: + UseOneRX(iobase, OFF); // use two RX pin RX1,RX2 + InvertTX(iobase, OFF); + InvertRX(iobase, OFF); + SlowIRRXLowActive(iobase, OFF); + if (IsSIROn(iobase)) { //sir + EnGPIOtoRX2(iobase, OFF); + WriteGIO(iobase, OFF); + EnRX2(iobase, OFF); //sir to rx2 + } else { // fir mir + EnGPIOtoRX2(iobase, OFF); + WriteGIO(iobase, OFF); + EnRX2(iobase, OFF); //fir to rx + } + break; + case 0x0ff: /* Vishay */ + if (IsSIROn(iobase)) + mode = 0; + else if (IsMIROn(iobase)) + mode = 1; + else if (IsFIROn(iobase)) + mode = 2; + else if (IsVFIROn(iobase)) + mode = 5; //VFIR-16 + SI_SetMode(iobase, mode); + } + WriteReg(iobase, I_ST_CT_0, 0x80); + +} + +/* + * Function via_ircc_change_speed (self, baud) + * + * Change the speed of the device + * + */ +static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed) +{ + struct net_device *dev = self->netdev; + u16 iobase; + u8 value = 0, bTmp; + + iobase = self->io.fir_base; + /* Update accounting for new speed */ + self->io.speed = speed; +#ifdef DBGMSG + DBG(printk(KERN_INFO "change_speed =%x......\n", speed)); +#endif + +#ifdef DBG_IO + if (self->io.speed > 0x2580) + outb(0xaa, 0x90); + else + outb(0xbb, 0x90); +#endif + + + /* Controller mode sellection */ + switch (speed) { + case 9600: + value = 11; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 19200: + value = 5; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 38400: + value = 2; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 57600: + value = 1; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 115200: + value = 0; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 576000: + value = 0; + SetSIR(iobase, ON); + CRC16(iobase, ON); + break; + case 1152000: + value = 0; + SetMIR(iobase, ON); + break; + case 4000000: + value = 0; + SetFIR(iobase, ON); + SetPulseWidth(iobase, 0); + SetSendPreambleCount(iobase, 14); + CRC16(iobase, OFF); + EnTXCRC(iobase, ON); + break; + case 16000000: + value = 0; + SetVFIR(iobase, ON); + break; + default: + value = 0; + break; + } + /* Set baudrate to 0x19[2..7] */ + bTmp = (ReadReg(iobase, I_CF_H_1) & 0x03); + bTmp = bTmp | (value << 2); + WriteReg(iobase, I_CF_H_1, bTmp); + via_ircc_change_dongle_speed(iobase, speed, self->io.dongle_id); +// EnTXFIFOHalfLevelInt(iobase,ON); + /* Set FIFO size to 64 */ + SetFIFO(iobase, 64); + /* Enable some interrupts so we can receive frames */ + //EnAllInt(iobase,ON); + + if (IsSIROn(iobase)) { + SIRFilter(iobase, ON); + SIRRecvAny(iobase, ON); + } else { + SIRFilter(iobase, OFF); + SIRRecvAny(iobase, OFF); + } + if (speed > 115200) { + /* Install FIR xmit handler */ + dev->hard_start_xmit = via_ircc_hard_xmit_fir; + via_ircc_dma_receive(self); + } else { + /* Install SIR xmit handler */ + dev->hard_start_xmit = via_ircc_hard_xmit_sir; + } + netif_wake_queue(dev); +} + +/* + * Function via_ircc_hard_xmit (skb, dev) + * + * Transmit the frame! + * + */ +static int via_ircc_hard_xmit_sir(struct sk_buff *skb, + struct net_device *dev) +{ + struct via_ircc_cb *self; + unsigned long flags; + u16 iobase; + __u32 speed; + + self = (struct via_ircc_cb *) dev->priv; + ASSERT(self != NULL, return 0;); + iobase = self->io.fir_base; + + netif_stop_queue(dev); + /* Check if we need to change the speed */ + speed = irda_get_next_speed(skb); + if ((speed != self->io.speed) && (speed != -1)) { + /* Check for empty frame */ + if (!skb->len) { + via_ircc_change_speed(self, speed); + dev->trans_start = jiffies; + dev_kfree_skb(skb); + return 0; + } else + self->new_speed = speed; + } + InitCard(iobase); + CommonInit(iobase); + SIRFilter(iobase, ON); + SetSIR(iobase, ON); + CRC16(iobase, ON); + EnTXCRC(iobase, 0); + WriteReg(iobase, I_ST_CT_0, 0x00); + + spin_lock_irqsave(&self->lock, flags); + self->tx_buff.data = self->tx_buff.head; + self->tx_buff.len = + async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); + + self->stats.tx_bytes += self->tx_buff.len; + SetBaudRate(iobase, speed); + SetPulseWidth(iobase, 12); + SetSendPreambleCount(iobase, 0); + WriteReg(iobase, I_ST_CT_0, 0x80); + + EnableTX(iobase, ON); + EnableRX(iobase, OFF); + + ResetChip(iobase, 0); + ResetChip(iobase, 1); + ResetChip(iobase, 2); + ResetChip(iobase, 3); + ResetChip(iobase, 4); + + EnAllInt(iobase, ON); + EnTXDMA(iobase, ON); + EnRXDMA(iobase, OFF); + + setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, + DMA_TX_MODE); + + SetSendByte(iobase, self->tx_buff.len); + RXStart(iobase, OFF); + TXStart(iobase, ON); + + dev->trans_start = jiffies; + spin_unlock_irqrestore(&self->lock, flags); + dev_kfree_skb(skb); + return 0; +} + +static int via_ircc_hard_xmit_fir(struct sk_buff *skb, + struct net_device *dev) +{ + struct via_ircc_cb *self; + u16 iobase; + __u32 speed; + unsigned long flags; + + self = (struct via_ircc_cb *) dev->priv; + iobase = self->io.fir_base; + + if (self->st_fifo.len) + return 0; + if (self->chip_id == 0x3076) + iodelay(1500); + else + udelay(1500); + netif_stop_queue(dev); + speed = irda_get_next_speed(skb); + if ((speed != self->io.speed) && (speed != -1)) { + if (!skb->len) { + via_ircc_change_speed(self, speed); + dev->trans_start = jiffies; + dev_kfree_skb(skb); + return 0; + } else + self->new_speed = speed; + } + spin_lock_irqsave(&self->lock, flags); + self->tx_fifo.queue[self->tx_fifo.free].start = self->tx_fifo.tail; + self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; + + self->tx_fifo.tail += skb->len; + self->stats.tx_bytes += skb->len; + memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, + skb->len); + self->tx_fifo.len++; + self->tx_fifo.free++; +//F01 if (self->tx_fifo.len == 1) { + via_ircc_dma_xmit(self, iobase); +//F01 } +//F01 if (self->tx_fifo.free < (MAX_TX_WINDOW -1 )) netif_wake_queue(self->netdev); + dev->trans_start = jiffies; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&self->lock, flags); + return 0; + +} + +static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase) +{ +// int i; +// u8 *ch; + + EnTXDMA(iobase, OFF); + self->io.direction = IO_XMIT; + EnPhys(iobase, ON); + EnableTX(iobase, ON); + EnableRX(iobase, OFF); + ResetChip(iobase, 0); + ResetChip(iobase, 1); + ResetChip(iobase, 2); + ResetChip(iobase, 3); + ResetChip(iobase, 4); + EnAllInt(iobase, ON); + EnTXDMA(iobase, ON); + EnRXDMA(iobase, OFF); + setup_dma(self->io.dma, + self->tx_fifo.queue[self->tx_fifo.ptr].start, + self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE); +#ifdef DBGMSG + DBG(printk + (KERN_INFO "dma_xmit:tx_fifo.ptr=%x,len=%x,tx_fifo.len=%x..\n", + self->tx_fifo.ptr, self->tx_fifo.queue[self->tx_fifo.ptr].len, + self->tx_fifo.len)); +/* + ch = self->tx_fifo.queue[self->tx_fifo.ptr].start; + for(i=0 ; i < self->tx_fifo.queue[self->tx_fifo.ptr].len ; i++) { + DBG(printk(KERN_INFO "%x..\n",ch[i])); + } +*/ +#endif + + SetSendByte(iobase, self->tx_fifo.queue[self->tx_fifo.ptr].len); + RXStart(iobase, OFF); + TXStart(iobase, ON); + return 0; + +} + +/* + * Function via_ircc_dma_xmit_complete (self) + * + * The transfer of a frame in finished. This function will only be called + * by the interrupt handler + * + */ +static int via_ircc_dma_xmit_complete(struct via_ircc_cb *self) +{ + int iobase; + int ret = TRUE; + u8 Tx_status; + + IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + iobase = self->io.fir_base; + /* Disable DMA */ +// DisableDmaChannel(self->io.dma); + /* Check for underrrun! */ + /* Clear bit, by writing 1 into it */ + Tx_status = GetTXStatus(iobase); + if (Tx_status & 0x08) { + self->stats.tx_errors++; + self->stats.tx_fifo_errors++; + hwreset(self); +// how to clear underrrun ? + } else { + self->stats.tx_packets++; + ResetChip(iobase, 3); + ResetChip(iobase, 4); + } + /* Check if we need to change the speed */ + if (self->new_speed) { + via_ircc_change_speed(self, self->new_speed); + self->new_speed = 0; + } + + /* Finished with this frame, so prepare for next */ + if (IsFIROn(iobase)) { + if (self->tx_fifo.len) { + self->tx_fifo.len--; + self->tx_fifo.ptr++; + } + } +#ifdef DBGMSG + DBG(printk + (KERN_INFO + "via_ircc_dma_xmit_complete:tx_fifo.len=%x ,tx_fifo.ptr=%x,tx_fifo.free=%x...\n", + self->tx_fifo.len, self->tx_fifo.ptr, self->tx_fifo.free)); +#endif +/* F01_S + // Any frames to be sent back-to-back? + if (self->tx_fifo.len) { + // Not finished yet! + via_ircc_dma_xmit(self, iobase); + ret = FALSE; + } else { +F01_E*/ + // Reset Tx FIFO info + self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; + self->tx_fifo.tail = self->tx_buff.head; +//F01 } + + // Make sure we have room for more frames +//F01 if (self->tx_fifo.free < (MAX_TX_WINDOW -1 )) { + // Not busy transmitting anymore + // Tell the network layer, that we can accept more frames + netif_wake_queue(self->netdev); +//F01 } + return ret; +} + +/* + * Function via_ircc_dma_receive (self) + * + * Set configuration for receive a frame. + * + */ +static int via_ircc_dma_receive(struct via_ircc_cb *self) +{ + int iobase; + + iobase = self->io.fir_base; + + self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; + self->tx_fifo.tail = self->tx_buff.head; + self->RxDataReady = 0; + self->io.direction = IO_RECV; + self->rx_buff.data = self->rx_buff.head; + self->st_fifo.len = self->st_fifo.pending_bytes = 0; + self->st_fifo.tail = self->st_fifo.head = 0; + EnPhys(iobase, ON); + EnableTX(iobase, OFF); + EnableRX(iobase, ON); + + ResetChip(iobase, 0); + ResetChip(iobase, 1); + ResetChip(iobase, 2); + ResetChip(iobase, 3); + ResetChip(iobase, 4); + + EnAllInt(iobase, ON); + EnTXDMA(iobase, OFF); + EnRXDMA(iobase, ON); + setup_dma(self->io.dma2, self->rx_buff.data, + self->rx_buff.truesize, DMA_RX_MODE); + TXStart(iobase, OFF); + RXStart(iobase, ON); + + return 0; +} + +/* + * Function via_ircc_dma_receive_complete (self) + * + * Controller Finished with receiving frames, + * and this routine is call by ISR + * + */ +static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, + int iobase) +{ + struct st_fifo *st_fifo; + struct sk_buff *skb; + int len, i; + u8 status = 0; + + iobase = self->io.fir_base; + st_fifo = &self->st_fifo; + + if (self->io.speed < 4000000) { //Speed below FIR + len = GetRecvByte(iobase, self); + skb = dev_alloc_skb(len + 1); + if (skb == NULL) + return FALSE; + // Make sure IP header gets aligned + skb_reserve(skb, 1); + skb_put(skb, len - 2); + if (self->chip_id == 0x3076) { + for (i = 0; i < len - 2; i++) + skb->data[i] = self->rx_buff.data[i * 2]; + } else { + if (self->chip_id == 0x3096) { + for (i = 0; i < len - 2; i++) + skb->data[i] = + self->rx_buff.data[i]; + } + } + // Move to next frame + self->rx_buff.data += len; + self->stats.rx_bytes += len; + self->stats.rx_packets++; + skb->dev = self->netdev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + return TRUE; + } + + else { //FIR mode + len = GetRecvByte(iobase, self); + if (len == 0) + return TRUE; //interrupt only, data maybe move by RxT + if (((len - 4) < 2) || ((len - 4) > 2048)) { +#ifdef DBGMSG + DBG(printk + (KERN_INFO + "receive_comple:Trouble:len=%x,CurCount=%x,LastCount=%x..\n", + len, RxCurCount(iobase, self), + self->RxLastCount)); +#endif + hwreset(self); + return FALSE; + } +#ifdef DBGMSG + DBG(printk + (KERN_INFO + "recv_comple:fifo.len=%x,len=%x,CurCount=%x..\n", + st_fifo->len, len - 4, RxCurCount(iobase, self))); +#endif + st_fifo->entries[st_fifo->tail].status = status; + st_fifo->entries[st_fifo->tail].len = len; + st_fifo->pending_bytes += len; + st_fifo->tail++; + st_fifo->len++; + if (st_fifo->tail > MAX_RX_WINDOW) + st_fifo->tail = 0; + self->RxDataReady = 0; + + // It maybe have MAX_RX_WINDOW package receive by + // receive_complete before Timer IRQ +/* F01_S + if (st_fifo->len < (MAX_RX_WINDOW+2 )) { + RXStart(iobase,ON); + SetTimer(iobase,4); + } + else { +F01_E */ + EnableRX(iobase, OFF); + EnRXDMA(iobase, OFF); + RXStart(iobase, OFF); +//F01_S + // Put this entry back in fifo + if (st_fifo->head > MAX_RX_WINDOW) + st_fifo->head = 0; + status = st_fifo->entries[st_fifo->head].status; + len = st_fifo->entries[st_fifo->head].len; + st_fifo->head++; + st_fifo->len--; + + skb = dev_alloc_skb(len + 1 - 4); + /* + * if frame size,data ptr,or skb ptr are wrong ,the get next + * entry. + */ + if ((skb == NULL) || (skb->data == NULL) + || (self->rx_buff.data == NULL) || (len < 6)) { + self->stats.rx_dropped++; + return TRUE; + } + skb_reserve(skb, 1); + skb_put(skb, len - 4); + memcpy(skb->data, self->rx_buff.data, len - 4); +#ifdef DBGMSG + DBG(printk + (KERN_INFO "RxT:len=%x.rx_buff=%x\n", len - 4, + self->rx_buff.data)); +/* for(i=0 ; i < (len-4) ; i++) { + DBG(printk(KERN_INFO "%x..\n",self->rx_buff.data[i])); + } +*/ +#endif + // Move to next frame + self->rx_buff.data += len; + self->stats.rx_bytes += len; + self->stats.rx_packets++; + skb->dev = self->netdev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + +//F01_E + } //FIR + return TRUE; + +} + +/* + * if frame is received , but no INT ,then use this routine to upload frame. + */ +static int upload_rxdata(struct via_ircc_cb *self, int iobase) +{ + struct sk_buff *skb; + int len; + struct st_fifo *st_fifo; + st_fifo = &self->st_fifo; + + len = GetRecvByte(iobase, self); + +#ifdef DBGMSG + DBG(printk(KERN_INFO "upload_rxdata: len=%x\n", len)); +#endif + skb = dev_alloc_skb(len + 1); + if ((skb == NULL) || ((len - 4) < 2)) { + self->stats.rx_dropped++; + return FALSE; + } + skb_reserve(skb, 1); + skb_put(skb, len - 4 + 1); + memcpy(skb->data, self->rx_buff.data, len - 4 + 1); + st_fifo->tail++; + st_fifo->len++; + if (st_fifo->tail > MAX_RX_WINDOW) + st_fifo->tail = 0; + // Move to next frame + self->rx_buff.data += len; + self->stats.rx_bytes += len; + self->stats.rx_packets++; + skb->dev = self->netdev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + if (st_fifo->len < (MAX_RX_WINDOW + 2)) { + RXStart(iobase, ON); + } else { + EnableRX(iobase, OFF); + EnRXDMA(iobase, OFF); + RXStart(iobase, OFF); + } + return TRUE; +} + +/* + * Implement back to back receive , use this routine to upload data. + */ + +static int RxTimerHandler(struct via_ircc_cb *self, int iobase) +{ + struct st_fifo *st_fifo; + struct sk_buff *skb; + int len; + u8 status; + + st_fifo = &self->st_fifo; + + if (CkRxRecv(iobase, self)) { + // if still receiving ,then return ,don't upload frame + self->RetryCount = 0; + SetTimer(iobase, 20); + self->RxDataReady++; + return FALSE; + } else + self->RetryCount++; + + if ((self->RetryCount >= 1) || + ((st_fifo->pending_bytes + 2048) > self->rx_buff.truesize) + || (st_fifo->len >= (MAX_RX_WINDOW))) { + while (st_fifo->len > 0) { //upload frame + // Put this entry back in fifo + if (st_fifo->head > MAX_RX_WINDOW) + st_fifo->head = 0; + status = st_fifo->entries[st_fifo->head].status; + len = st_fifo->entries[st_fifo->head].len; + st_fifo->head++; + st_fifo->len--; + + skb = dev_alloc_skb(len + 1 - 4); + /* + * if frame size, data ptr, or skb ptr are wrong, + * then get next entry. + */ + if ((skb == NULL) || (skb->data == NULL) + || (self->rx_buff.data == NULL) || (len < 6)) { + self->stats.rx_dropped++; + continue; + } + skb_reserve(skb, 1); + skb_put(skb, len - 4); + memcpy(skb->data, self->rx_buff.data, len - 4); +#ifdef DBGMSG + DBG(printk + (KERN_INFO "RxT:len=%x.head=%x\n", len - 4, + st_fifo->head)); +#endif + // Move to next frame + self->rx_buff.data += len; + self->stats.rx_bytes += len; + self->stats.rx_packets++; + skb->dev = self->netdev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + } //while + self->RetryCount = 0; +#ifdef DBGMSG + DBG(printk + (KERN_INFO + "RxT:End of upload HostStatus=%x,RxStatus=%x\n", + GetHostStatus(iobase), GetRXStatus(iobase))); +#endif + /* + * if frame is receive complete at this routine ,then upload + * frame. + */ + if ((GetRXStatus(iobase) & 0x10) + && (RxCurCount(iobase, self) != self->RxLastCount)) { + upload_rxdata(self, iobase); + if (irda_device_txqueue_empty(self->netdev)) + via_ircc_dma_receive(self); + } + } // timer detect complete + else + SetTimer(iobase, 4); + return TRUE; + +} + + + +/* + * Function via_ircc_interrupt (irq, dev_id, regs) + * + * An interrupt from the chip has arrived. Time to do some work + * + */ +static irqreturn_t via_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_id; + struct via_ircc_cb *self; + int iobase; + u8 iHostIntType, iRxIntType, iTxIntType; + + if (!dev) { + WARNING("%s: irq %d for unknown device.\n", driver_name, + irq); + return IRQ_NONE; + } + self = (struct via_ircc_cb *) dev->priv; + iobase = self->io.fir_base; + spin_lock(&self->lock); + iHostIntType = GetHostStatus(iobase); + if ((iHostIntType & 0x40) != 0) { //Timer Event + self->EventFlag.TimeOut++; + ClearTimerInt(iobase, 1); + if (self->io.direction == IO_XMIT) { + via_ircc_dma_xmit(self, iobase); + } + if (self->io.direction == IO_RECV) { + /* + * frame ready hold too long, must reset. + */ + if (self->RxDataReady > 30) { + hwreset(self); + if (irda_device_txqueue_empty + (self->netdev)) { + via_ircc_dma_receive(self); + } + } else { // call this to upload frame. + RxTimerHandler(self, iobase); + } + } //RECV + } //Timer Event + if ((iHostIntType & 0x20) != 0) { //Tx Event + iTxIntType = GetTXStatus(iobase); + if (iTxIntType & 0x4) { + self->EventFlag.EOMessage++; // read and will auto clean + if (via_ircc_dma_xmit_complete(self)) { + if (irda_device_txqueue_empty + (self->netdev)) { + via_ircc_dma_receive(self); + } + } else { + self->EventFlag.Unknown++; + } + } //EOP + } //Tx Event + //---------------------------------------- + if ((iHostIntType & 0x10) != 0) { //Rx Event + /* Check if DMA has finished */ + iRxIntType = GetRXStatus(iobase); +#ifdef DBGMSG + if (!iRxIntType) + DBG(printk(KERN_INFO " RxIRQ =0\n")); +#endif + if (iRxIntType & 0x10) { + if (via_ircc_dma_receive_complete(self, iobase)) { +//F01 if(!(IsFIROn(iobase))) via_ircc_dma_receive(self); + via_ircc_dma_receive(self); + } + } // No ERR + else { //ERR +#ifdef DBGMSG + DBG(printk + (KERN_INFO + " RxIRQ ERR:iRxIntType=%x,HostIntType=%x,CurCount=%x,RxLastCount=%x_____\n", + iRxIntType, iHostIntType, RxCurCount(iobase, + self), + self->RxLastCount)); +#endif + if (iRxIntType & 0x20) { //FIFO OverRun ERR + ResetChip(iobase, 0); + ResetChip(iobase, 1); + } else { //PHY,CRC ERR + + if (iRxIntType != 0x08) + hwreset(self); //F01 + } + via_ircc_dma_receive(self); + } //ERR + + } //Rx Event + spin_unlock(&self->lock); + return IRQ_HANDLED; +} + +void hwreset(struct via_ircc_cb *self) +{ + int iobase; + iobase = self->io.fir_base; +#ifdef DBGMSG + DBG(printk(KERN_INFO "hwreset ....\n")); +#endif + ResetChip(iobase, 5); + EnableDMA(iobase, OFF); + EnableTX(iobase, OFF); + EnableRX(iobase, OFF); + EnRXDMA(iobase, OFF); + EnTXDMA(iobase, OFF); + RXStart(iobase, OFF); + TXStart(iobase, OFF); + InitCard(iobase); + CommonInit(iobase); + SIRFilter(iobase, ON); + SetSIR(iobase, ON); + CRC16(iobase, ON); + EnTXCRC(iobase, 0); + WriteReg(iobase, I_ST_CT_0, 0x00); + SetBaudRate(iobase, 9600); + SetPulseWidth(iobase, 12); + SetSendPreambleCount(iobase, 0); + WriteReg(iobase, I_ST_CT_0, 0x80); + via_ircc_change_speed(self, self->io.speed); + self->st_fifo.len = 0; +} + +/* + * Function via_ircc_is_receiving (self) + * + * Return TRUE is we are currently receiving a frame + * + */ +static int via_ircc_is_receiving(struct via_ircc_cb *self) +{ + int status = FALSE; + int iobase; + + ASSERT(self != NULL, return FALSE;); + + iobase = self->io.fir_base; + if (CkRxRecv(iobase, self)) + status = TRUE; +#ifdef DBGMSG + DBG(printk(KERN_INFO "is_receiving status=%x....\n", status)); +#endif + return status; +} + +/* + * Function via_ircc_net_init (dev) + * + * Initialize network device + * + */ +static int via_ircc_net_init(struct net_device *dev) +{ + IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + + /* Keep track of module usage */ + SET_MODULE_OWNER(dev); + + /* Setup to be a normal IrDA network device driver */ + irda_device_setup(dev); + + /* Insert overrides below this line! */ + + return 0; +} + +/* + * Function via_ircc_net_open (dev) + * + * Start the device + * + */ +static int via_ircc_net_open(struct net_device *dev) +{ + struct via_ircc_cb *self; + int iobase; + char hwname[32]; + + IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + + ASSERT(dev != NULL, return -1;); + self = (struct via_ircc_cb *) dev->priv; + self->stats.rx_packets = 0; + ASSERT(self != NULL, return 0;); + iobase = self->io.fir_base; + if (request_irq + (self->io.irq, via_ircc_interrupt, 0, dev->name, dev)) { + WARNING("%s, unable to allocate irq=%d\n", driver_name, + self->io.irq); + return -EAGAIN; + } + /* + * Always allocate the DMA channel after the IRQ, and clean up on + * failure. + */ + if (request_dma(self->io.dma, dev->name)) { + WARNING("%s, unable to allocate dma=%d\n", driver_name, + self->io.dma); + free_irq(self->io.irq, self); + return -EAGAIN; + } + if (self->io.dma2 != self->io.dma) { + if (request_dma(self->io.dma2, dev->name)) { + WARNING("%s, unable to allocate dma2=%d\n", + driver_name, self->io.dma2); + free_irq(self->io.irq, self); + return -EAGAIN; + } + } + + + /* turn on interrupts */ + EnAllInt(iobase, ON); + EnInternalLoop(iobase, OFF); + EnExternalLoop(iobase, OFF); + /* Ready to play! */ + netif_start_queue(dev); + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + sprintf(hwname, "VIA"); + /* + * for different kernel ,irlap_open have different parameter. + */ + self->irlap = irlap_open(dev, &self->qos, hwname); +// self->irlap = irlap_open(dev, &self->qos); + + self->RxLastCount = 0; + + return 0; +} + +/* + * Function via_ircc_net_close (dev) + * + * Stop the device + * + */ +static int via_ircc_net_close(struct net_device *dev) +{ + struct via_ircc_cb *self; + int iobase; + + IRDA_DEBUG(4, "%s()\n", __FUNCTION__); + + ASSERT(dev != NULL, return -1;); + self = (struct via_ircc_cb *) dev->priv; + ASSERT(self != NULL, return 0;); + +#ifdef DBG_IO + outb(0xff, 0x90); + outb(0xff, 0x94); +#endif + /* Stop device */ + netif_stop_queue(dev); + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; + iobase = self->io.fir_base; + EnTXDMA(iobase, OFF); + EnRXDMA(iobase, OFF); + DisableDmaChannel(self->io.dma); + + /* Disable interrupts */ + EnAllInt(iobase, OFF); + free_irq(self->io.irq, dev); + free_dma(self->io.dma); + + return 0; +} + +/* + * Function via_ircc_net_ioctl (dev, rq, cmd) + * + * Process IOCTL commands for this device + * + */ +static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, + int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *) rq; + struct via_ircc_cb *self; + unsigned long flags; + int ret = 0; + + ASSERT(dev != NULL, return -1;); + self = dev->priv; + ASSERT(self != NULL, return -1;); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, + cmd); + /* Disable interrupts & save flags */ + spin_lock_irqsave(&self->lock, flags); + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + goto out; + } + via_ircc_change_speed(self, irq->ifr_baudrate); + break; + case SIOCSMEDIABUSY: /* Set media busy */ + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + goto out; + } + irda_device_set_media_busy(self->netdev, TRUE); + break; + case SIOCGRECEIVING: /* Check if we are receiving right now */ + irq->ifr_receiving = via_ircc_is_receiving(self); + break; + default: + ret = -EOPNOTSUPP; + } + out: + spin_unlock_irqrestore(&self->lock, flags); + return ret; +} + +static struct net_device_stats *via_ircc_net_get_stats(struct net_device + *dev) +{ + struct via_ircc_cb *self = (struct via_ircc_cb *) dev->priv; + + return &self->stats; +} + +MODULE_AUTHOR("VIA Technologies,inc"); +MODULE_DESCRIPTION("VIA IrDA Device Driver"); +MODULE_LICENSE("GPL"); + +module_init(via_ircc_init); +module_exit(via_ircc_cleanup); diff -urN linux-2.4.24/drivers/net/irda/via-ircc.h linux-2.4.25/drivers/net/irda/via-ircc.h --- linux-2.4.24/drivers/net/irda/via-ircc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/irda/via-ircc.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1044 @@ +/********************************************************************* + * + * Filename: via-ircc.h + * Version: 1.0 + * Description: Driver for the VIA VT8231/VT8233 IrDA chipsets + * Author: VIA Technologies, inc + * Date : 08/06/2003 + +Copyright (c) 1998-2003 VIA Technologies, Inc. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + * Comment: + * jul/08/2002 : Rx buffer length should use Rx ring ptr. + * Oct/28/2002 : Add SB id for 3147 and 3177. + * jul/09/2002 : only implement two kind of dongle currently. + * Oct/02/2002 : work on VT8231 and VT8233 . + * Aug/06/2003 : change driver format to pci driver . + ********************************************************************/ +#ifndef via_IRCC_H +#define via_IRCC_H +#include +#include +#include +#include + +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW + 2]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW + 2]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Lenght of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + + +struct eventflag // for keeping track of Interrupt Events +{ + //--------tx part + unsigned char TxFIFOUnderRun; + unsigned char EOMessage; + unsigned char TxFIFOReady; + unsigned char EarlyEOM; + //--------rx part + unsigned char PHYErr; + unsigned char CRCErr; + unsigned char RxFIFOOverRun; + unsigned char EOPacket; + unsigned char RxAvail; + unsigned char TooLargePacket; + unsigned char SIRBad; + //--------unknown + unsigned char Unknown; + //---------- + unsigned char TimeOut; + unsigned char RxDMATC; + unsigned char TxDMATC; +}; + +/* Private data for each instance */ +struct via_ircc_cb { + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u8 ier; /* Interrupt enable register */ + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + int index; /* Instance index */ + + struct eventflag EventFlag; + struct pm_dev *dev; + unsigned int chip_id; /* to remember chip id */ + unsigned int RetryCount; + unsigned int RxDataReady; + unsigned int RxLastCount; +}; + + +//---------I=Infrared, H=Host, M=Misc, T=Tx, R=Rx, ST=Status, +// CF=Config, CT=Control, L=Low, H=High, C=Count +#define I_CF_L_0 0x10 +#define I_CF_H_0 0x11 +#define I_SIR_BOF 0x12 +#define I_SIR_EOF 0x13 +#define I_ST_CT_0 0x15 +#define I_ST_L_1 0x16 +#define I_ST_H_1 0x17 +#define I_CF_L_1 0x18 +#define I_CF_H_1 0x19 +#define I_CF_L_2 0x1a +#define I_CF_H_2 0x1b +#define I_CF_3 0x1e +#define H_CT 0x20 +#define H_ST 0x21 +#define M_CT 0x22 +#define TX_CT_1 0x23 +#define TX_CT_2 0x24 +#define TX_ST 0x25 +#define RX_CT 0x26 +#define RX_ST 0x27 +#define RESET 0x28 +#define P_ADDR 0x29 +#define RX_C_L 0x2a +#define RX_C_H 0x2b +#define RX_P_L 0x2c +#define RX_P_H 0x2d +#define TX_C_L 0x2e +#define TX_C_H 0x2f +#define TIMER 0x32 +#define I_CF_4 0x33 +#define I_T_C_L 0x34 +#define I_T_C_H 0x35 +#define VERSION 0x3f +//------------------------------- +#define StartAddr 0x10 // the first register address +#define EndAddr 0x3f // the last register address +#define GetBit(val,bit) val = (unsigned char) ((val>>bit) & 0x1) + // Returns the bit +#define SetBit(val,bit) val= (unsigned char ) (val | (0x1 << bit)) + // Sets bit to 1 +#define ResetBit(val,bit) val= (unsigned char ) (val & ~(0x1 << bit)) + // Sets bit to 0 +#define PCI_CONFIG_ADDRESS 0xcf8 +#define PCI_CONFIG_DATA 0xcfc + +#define VenderID 0x1106 +#define DeviceID1 0x8231 +#define DeviceID2 0x3109 +#define DeviceID3 0x3074 +//F01_S +#define DeviceID4 0x3147 +#define DeviceID5 0x3177 +//F01_E + +#define OFF 0 +#define ON 1 +#define DMA_TX_MODE 0x08 +#define DMA_RX_MODE 0x04 + +#define DMA1 0 +#define DMA2 0xc0 +#define MASK1 DMA1+0x0a +#define MASK2 DMA2+0x14 + +#define Clk_bit 0x40 +#define Tx_bit 0x01 +#define Rd_Valid 0x08 +#define RxBit 0x08 + +__u8 ReadPCIByte(__u8, __u8, __u8, __u8); +__u32 ReadPCI(__u8, __u8, __u8, __u8); +void WritePCI(__u8, __u8, __u8, __u8, __u32); +void WritePCIByte(__u8, __u8, __u8, __u8, __u8); +int mySearchPCI(__u8 *, __u16, __u16); + + +void DisableDmaChannel(unsigned int channel) +{ + switch (channel) { // 8 Bit DMA channels DMAC1 + case 0: + outb(4, MASK1); //mask channel 0 + break; + case 1: + outb(5, MASK1); //Mask channel 1 + break; + case 2: + outb(6, MASK1); //Mask channel 2 + break; + case 3: + outb(7, MASK1); //Mask channel 3 + break; + case 5: + outb(5, MASK2); //Mask channel 5 + break; + case 6: + outb(6, MASK2); //Mask channel 6 + break; + case 7: + outb(7, MASK2); //Mask channel 7 + break; + default: + break; + }; //Switch +} + +unsigned char ReadLPCReg(int iRegNum) +{ + unsigned char iVal; + + outb(0x87, 0x2e); + outb(0x87, 0x2e); + outb(iRegNum, 0x2e); + iVal = inb(0x2f); + outb(0xaa, 0x2e); + + return iVal; +} + +void WriteLPCReg(int iRegNum, unsigned char iVal) +{ + + outb(0x87, 0x2e); + outb(0x87, 0x2e); + outb(iRegNum, 0x2e); + outb(iVal, 0x2f); + outb(0xAA, 0x2e); +} + +__u8 ReadReg(unsigned int BaseAddr, int iRegNum) +{ + return ((__u8) inb(BaseAddr + iRegNum)); +} + +void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal) +{ + outb(iVal, BaseAddr + iRegNum); +} + +int WriteRegBit(unsigned int BaseAddr, unsigned char RegNum, + unsigned char BitPos, unsigned char value) +{ + __u8 Rtemp, Wtemp; + + if (BitPos > 7) { + return -1; + } + if ((RegNum < StartAddr) || (RegNum > EndAddr)) + return -1; + Rtemp = ReadReg(BaseAddr, RegNum); + if (value == 0) + Wtemp = ResetBit(Rtemp, BitPos); + else { + if (value == 1) + Wtemp = SetBit(Rtemp, BitPos); + else + return -1; + } + WriteReg(BaseAddr, RegNum, Wtemp); + return 0; +} + +__u8 CheckRegBit(unsigned int BaseAddr, unsigned char RegNum, + unsigned char BitPos) +{ + __u8 temp; + + if (BitPos > 7) + return 0xff; + if ((RegNum < StartAddr) || (RegNum > EndAddr)) { +// printf("what is the register %x!\n",RegNum); + } + temp = ReadReg(BaseAddr, RegNum); + return GetBit(temp, BitPos); +} + +__u8 ReadPCIByte(__u8 bus, __u8 device, __u8 fun, __u8 reg) +{ + __u32 dTmp; + __u8 bData, bTmp; + + bTmp = reg & ~0x03; + dTmp = ReadPCI(bus, device, fun, bTmp); + bTmp = reg & 0x03; + bData = (__u8) (dTmp >> bTmp); + return bData; +} + +__u32 ReadPCI(__u8 bus, __u8 device, __u8 fun, __u8 reg) +{ + __u32 CONFIG_ADDR, temp, data; + + if ((bus == 0xff) || (device == 0xff) || (fun == 0xff)) + return 0xffffffff; + CONFIG_ADDR = 0x80000000; + temp = (__u32) reg << 2; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) fun << 8; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) device << 11; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) bus << 16; + CONFIG_ADDR = CONFIG_ADDR | temp; + + outl(PCI_CONFIG_ADDRESS, CONFIG_ADDR); + data = inl(PCI_CONFIG_DATA); + return data; +} + + +void WritePCIByte(__u8 bus, __u8 device, __u8 fun, __u8 reg, + __u8 CONFIG_DATA) +{ + __u32 dTmp, dTmp1 = 0; + __u8 bTmp; + + bTmp = reg & ~0x03; + dTmp = ReadPCI(bus, device, fun, bTmp); + switch (reg & 0x03) { + case 0: + dTmp1 = (dTmp & ~0xff) | CONFIG_DATA; + break; + case 1: + dTmp = (dTmp & ~0x00ff00); + dTmp1 = CONFIG_DATA; + dTmp1 = dTmp1 << 8; + dTmp1 = dTmp1 | dTmp; + break; + case 2: + dTmp = (dTmp & ~0xff0000); + dTmp1 = CONFIG_DATA; + dTmp1 = dTmp1 << 16; + dTmp1 = dTmp1 | dTmp; + break; + case 3: + dTmp = (dTmp & ~0xff000000); + dTmp1 = CONFIG_DATA; + dTmp1 = dTmp1 << 24; + dTmp1 = dTmp1 | dTmp; + break; + } + WritePCI(bus, device, fun, bTmp, dTmp1); +} + +//------------------ +void WritePCI(__u8 bus, __u8 device, __u8 fun, __u8 reg, __u32 CONFIG_DATA) +{ + __u32 CONFIG_ADDR, temp; + + if ((bus == 0xff) || (device == 0xff) || (fun == 0xff)) + return; + CONFIG_ADDR = 0x80000000; + temp = (__u32) reg << 2; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) fun << 8; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) device << 11; + CONFIG_ADDR = CONFIG_ADDR | temp; + temp = (__u32) bus << 16; + CONFIG_ADDR = CONFIG_ADDR | temp; + + outl(PCI_CONFIG_ADDRESS, CONFIG_ADDR); + outl(PCI_CONFIG_DATA, CONFIG_DATA); + +} + + // find device with DeviceID and VenderID // if match return three byte buffer (bus,device,function) // no found, address={99,99,99} +int mySearchPCI(__u8 * SBridpos, __u16 VID, __u16 DID) +{ + __u8 i, j, k; + __u16 FindDeviceID, FindVenderID; + + for (k = 0; k < 8; k++) { //scan function + i = 0; + j = 0x11; + k = 0; + if (ReadPCI(i, j, k, 0) < 0xffffffff) { // not empty + FindDeviceID = (__u16) (ReadPCI(i, j, k, 0) >> 16); + FindVenderID = + (__u16) (ReadPCI(i, j, k, 0) & 0x0000ffff); + if ((VID == FindVenderID) && (DID == FindDeviceID)) { + SBridpos[0] = i; // bus + SBridpos[1] = j; //device + SBridpos[2] = k; //func + return 1; + } + } + } + return 0; +} + +void SetMaxRxPacketSize(__u16 iobase, __u16 size) +{ + __u16 low, high; + if ((size & 0xe000) == 0) { + low = size & 0x00ff; + high = (size & 0x1f00) >> 8; + WriteReg(iobase, I_CF_L_2, low); + WriteReg(iobase, I_CF_H_2, high); + + } + +} + +//for both Rx and Tx + +void SetFIFO(__u16 iobase, __u16 value) +{ + switch (value) { + case 128: + WriteRegBit(iobase, 0x11, 0, 0); + WriteRegBit(iobase, 0x11, 7, 1); + break; + case 64: + WriteRegBit(iobase, 0x11, 0, 0); + WriteRegBit(iobase, 0x11, 7, 0); + break; + case 32: + WriteRegBit(iobase, 0x11, 0, 1); + WriteRegBit(iobase, 0x11, 7, 0); + break; + default: + WriteRegBit(iobase, 0x11, 0, 0); + WriteRegBit(iobase, 0x11, 7, 0); + } + +} + +#define CRC16(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,7,val) //0 for 32 CRC +/* +#define SetVFIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,5,val) +#define SetFIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,6,val) +#define SetMIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,5,val) +#define SetSIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,4,val) +*/ +#define SIRFilter(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,3,val) +#define Filter(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,2,val) +#define InvertTX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,1,val) +#define InvertRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,0,val) +//****************************I_CF_H_0 +#define EnableTX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,4,val) +#define EnableRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,3,val) +#define EnableDMA(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,2,val) +#define SIRRecvAny(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,1,val) +#define DiableTrans(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,0,val) +//***************************I_SIR_BOF,I_SIR_EOF +#define SetSIRBOF(BaseAddr,val) WriteReg(BaseAddr,I_SIR_BOF,val) +#define SetSIREOF(BaseAddr,val) WriteReg(BaseAddr,I_SIR_EOF,val) +#define GetSIRBOF(BaseAddr) ReadReg(BaseAddr,I_SIR_BOF) +#define GetSIREOF(BaseAddr) ReadReg(BaseAddr,I_SIR_EOF) +//*******************I_ST_CT_0 +#define EnPhys(BaseAddr,val) WriteRegBit(BaseAddr,I_ST_CT_0,7,val) +#define IsModeError(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,6) //RO +#define IsVFIROn(BaseAddr) CheckRegBit(BaseAddr,0x14,0) //RO for VT1211 only +#define IsFIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,5) //RO +#define IsMIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,4) //RO +#define IsSIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,3) //RO +#define IsEnableTX(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,2) //RO +#define IsEnableRX(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,1) //RO +#define Is16CRC(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,0) //RO +//***************************I_CF_3 +#define DisableAdjacentPulseWidth(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,5,val) //1 disable +#define DisablePulseWidthAdjust(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,4,val) //1 disable +#define UseOneRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,1,val) //0 use two RX +#define SlowIRRXLowActive(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,0,val) //0 show RX high=1 in SIR +//***************************H_CT +#define EnAllInt(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,7,val) +#define TXStart(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,6,val) +#define RXStart(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,5,val) +#define ClearRXInt(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,4,val) // 1 clear +//*****************H_ST +#define IsRXInt(BaseAddr) CheckRegBit(BaseAddr,H_ST,4) +#define GetIntIndentify(BaseAddr) ((ReadReg(BaseAddr,H_ST)&0xf1) >>1) +#define IsHostBusy(BaseAddr) CheckRegBit(BaseAddr,H_ST,0) +#define GetHostStatus(BaseAddr) ReadReg(BaseAddr,H_ST) //RO +//**************************M_CT +#define EnTXDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,7,val) +#define EnRXDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,6,val) +#define SwapDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,5,val) +#define EnInternalLoop(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,4,val) +#define EnExternalLoop(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,3,val) +//**************************TX_CT_1 +#define EnTXFIFOHalfLevelInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,4,val) //half empty int (1 half) +#define EnTXFIFOUnderrunEOMInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,5,val) +#define EnTXFIFOReadyInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,6,val) //int when reach it threshold (setting by bit 4) +//**************************TX_CT_2 +#define ForceUnderrun(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,7,val) // force an underrun int +#define EnTXCRC(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,6,val) //1 for FIR,MIR...0 (not SIR) +#define ForceBADCRC(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,5,val) //force an bad CRC +#define SendSIP(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,4,val) //send indication pulse for prevent SIR disturb +#define ClearEnTX(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,3,val) // opposite to EnTX +//*****************TX_ST +#define GetTXStatus(BaseAddr) ReadReg(BaseAddr,TX_ST) //RO +//**************************RX_CT +#define EnRXSpecInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,0,val) +#define EnRXFIFOReadyInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,1,val) //enable int when reach it threshold (setting by bit 7) +#define EnRXFIFOHalfLevelInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,7,val) //enable int when (1) half full...or (0) just not full +//*****************RX_ST +#define GetRXStatus(BaseAddr) ReadReg(BaseAddr,RX_ST) //RO +//***********************P_ADDR +#define SetPacketAddr(BaseAddr,addr) WriteReg(BaseAddr,P_ADDR,addr) +//***********************I_CF_4 +#define EnGPIOtoRX2(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,7,val) +#define EnTimerInt(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,1,val) +#define ClearTimerInt(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,0,val) +//***********************I_T_C_L +#define WriteGIO(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_L,7,val) +#define ReadGIO(BaseAddr) CheckRegBit(BaseAddr,I_T_C_L,7) +#define ReadRX(BaseAddr) CheckRegBit(BaseAddr,I_T_C_L,3) //RO +#define WriteTX(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_L,0,val) +//***********************I_T_C_H +#define EnRX2(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_H,7,val) +#define ReadRX2(BaseAddr) CheckRegBit(BaseAddr,I_T_C_H,7) +//**********************Version +#define GetFIRVersion(BaseAddr) ReadReg(BaseAddr,VERSION) + + +void SetTimer(__u16 iobase, __u8 count) +{ + EnTimerInt(iobase, OFF); + WriteReg(iobase, TIMER, count); + EnTimerInt(iobase, ON); +} + + +void SetSendByte(__u16 iobase, __u32 count) +{ + __u32 low, high; + + if ((count & 0xf000) == 0) { + low = count & 0x00ff; + high = (count & 0x0f00) >> 8; + WriteReg(iobase, TX_C_L, low); + WriteReg(iobase, TX_C_H, high); + } +} + +void ResetChip(__u16 iobase, __u8 type) +{ + __u8 value; + + value = (type + 2) << 4; + WriteReg(iobase, RESET, type); +} + +void SetAddrMode(__u16 iobase, __u8 mode) +{ + __u8 bTmp = 0; + if (mode < 3) { + bTmp = (ReadReg(iobase, RX_CT) & 0xcf) | (mode << 4); + WriteReg(iobase, RX_CT, bTmp); + } +} + +int CkRxRecv(__u16 iobase, struct via_ircc_cb *self) +{ + __u8 low, high; + __u16 wTmp = 0, wTmp1 = 0, wTmp_new = 0; + + low = ReadReg(iobase, RX_C_L); + high = ReadReg(iobase, RX_C_H); + wTmp1 = high; + wTmp = (wTmp1 << 8) | low; + udelay(10); + low = ReadReg(iobase, RX_C_L); + high = ReadReg(iobase, RX_C_H); + wTmp1 = high; + wTmp_new = (wTmp1 << 8) | low; + if (wTmp_new != wTmp) + return 1; + else + return 0; + +} + +__u16 RxCurCount(__u16 iobase, struct via_ircc_cb * self) +{ + __u8 low, high; + __u16 wTmp = 0, wTmp1 = 0; + + low = ReadReg(iobase, RX_P_L); + high = ReadReg(iobase, RX_P_H); + wTmp1 = high; + wTmp = (wTmp1 << 8) | low; + return wTmp; +} + +/* This Routine can only use in recevie_complete + * for it will update last count. + */ + +__u16 GetRecvByte(__u16 iobase, struct via_ircc_cb * self) +{ + __u8 low, high; + __u16 wTmp, wTmp1, ret; + + low = ReadReg(iobase, RX_P_L); + high = ReadReg(iobase, RX_P_H); + wTmp1 = high; + wTmp = (wTmp1 << 8) | low; + + + if (wTmp >= self->RxLastCount) + ret = wTmp - self->RxLastCount; + else + ret = (0x8000 - self->RxLastCount) + wTmp; + self->RxLastCount = wTmp; + +/* RX_P is more actually the RX_C + low=ReadReg(iobase,RX_C_L); + high=ReadReg(iobase,RX_C_H); + + if(!(high&0xe000)) { + temp=(high<<8)+low; + return temp; + } + else return 0; +*/ + return ret; +} + + +__u16 GetRecvLen(__u16 iobase) +{ + __u8 low, high; + __u16 temp; + + low = ReadReg(iobase, RX_P_L); + high = ReadReg(iobase, RX_P_H); + + if (!(high & 0xe000)) { + temp = (high << 8) + low; + return temp; + } else + return 0; +} + +void Sdelay(__u16 scale) +{ + __u8 bTmp; + int i, j; + + for (j = 0; j < scale; j++) { + for (i = 0; i < 0x20; i++) { + bTmp = inb(0xeb); + outb(bTmp, 0xeb); + } + } +} + +void Tdelay(__u16 scale) +{ + __u8 bTmp; + int i, j; + + for (j = 0; j < scale; j++) { + for (i = 0; i < 0x50; i++) { + bTmp = inb(0xeb); + outb(bTmp, 0xeb); + } + } +} + + +void ActClk(__u16 iobase, __u8 value) +{ + __u8 bTmp; + bTmp = ReadReg(iobase, 0x34); + if (value) + WriteReg(iobase, 0x34, bTmp | Clk_bit); + else + WriteReg(iobase, 0x34, bTmp & ~Clk_bit); +} + +void ActTx(__u16 iobase, __u8 value) +{ + __u8 bTmp; + + bTmp = ReadReg(iobase, 0x34); + if (value) + WriteReg(iobase, 0x34, bTmp | Tx_bit); + else + WriteReg(iobase, 0x34, bTmp & ~Tx_bit); +} + +void ClkTx(__u16 iobase, __u8 Clk, __u8 Tx) +{ + __u8 bTmp; + + bTmp = ReadReg(iobase, 0x34); + if (Clk == 0) + bTmp &= ~Clk_bit; + else { + if (Clk == 1) + bTmp |= Clk_bit; + } + WriteReg(iobase, 0x34, bTmp); + Sdelay(1); + if (Tx == 0) + bTmp &= ~Tx_bit; + else { + if (Tx == 1) + bTmp |= Tx_bit; + } + WriteReg(iobase, 0x34, bTmp); +} + +void Wr_Byte(__u16 iobase, __u8 data) +{ + __u8 bData = data; +// __u8 btmp; + int i; + + ClkTx(iobase, 0, 1); + + Tdelay(2); + ActClk(iobase, 1); + Tdelay(1); + + for (i = 0; i < 8; i++) { //LDN + + if ((bData >> i) & 0x01) { + ClkTx(iobase, 0, 1); //bit data = 1; + } else { + ClkTx(iobase, 0, 0); //bit data = 1; + } + Tdelay(2); + Sdelay(1); + ActClk(iobase, 1); //clk hi + Tdelay(1); + } +} + +__u8 Rd_Indx(__u16 iobase, __u8 addr, __u8 index) +{ + __u8 data = 0, bTmp, data_bit; + int i; + + bTmp = addr | (index << 1) | 0; + ClkTx(iobase, 0, 0); + Tdelay(2); + ActClk(iobase, 1); + udelay(1); + Wr_Byte(iobase, bTmp); + Sdelay(1); + ClkTx(iobase, 0, 0); + Tdelay(2); + for (i = 0; i < 10; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + Tdelay(1); + ClkTx(iobase, 0, 1); + Tdelay(1); + bTmp = ReadReg(iobase, 0x34); + if (!(bTmp & Rd_Valid)) + break; + } + if (!(bTmp & Rd_Valid)) { + for (i = 0; i < 8; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + bTmp = ReadReg(iobase, 0x34); + data_bit = 1 << i; + if (bTmp & RxBit) + data |= data_bit; + else + data &= ~data_bit; + Tdelay(2); + } + } else { + for (i = 0; i < 2; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + Tdelay(2); + } + bTmp = ReadReg(iobase, 0x34); + } + for (i = 0; i < 1; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + Tdelay(2); + } + ClkTx(iobase, 0, 0); + Tdelay(1); + for (i = 0; i < 3; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + Tdelay(2); + } + return data; +} + +void Wr_Indx(__u16 iobase, __u8 addr, __u8 index, __u8 data) +{ + int i; + __u8 bTmp; + + ClkTx(iobase, 0, 0); + udelay(2); + ActClk(iobase, 1); + udelay(1); + bTmp = addr | (index << 1) | 1; + Wr_Byte(iobase, bTmp); + Wr_Byte(iobase, data); + for (i = 0; i < 2; i++) { + ClkTx(iobase, 0, 0); + Tdelay(2); + ActClk(iobase, 1); + Tdelay(1); + } + ActClk(iobase, 0); +} + +void ResetDongle(__u16 iobase) +{ + int i; + ClkTx(iobase, 0, 0); + Tdelay(1); + for (i = 0; i < 30; i++) { + ActClk(iobase, 1); + Tdelay(1); + ActClk(iobase, 0); + Tdelay(1); + } + ActClk(iobase, 0); +} + +void SetSITmode(__u16 iobase) +{ + + __u8 bTmp; + + bTmp = ReadLPCReg(0x28); + WriteLPCReg(0x28, bTmp | 0x10); //select ITMOFF + bTmp = ReadReg(iobase, 0x35); + WriteReg(iobase, 0x35, bTmp | 0x40); // Driver ITMOFF + WriteReg(iobase, 0x28, bTmp | 0x80); // enable All interrupt +} + +void SI_SetMode(__u16 iobase, int mode) +{ + //__u32 dTmp; + __u8 bTmp; + + WriteLPCReg(0x28, 0x70); // S/W Reset + SetSITmode(iobase); + ResetDongle(iobase); + udelay(10); + Wr_Indx(iobase, 0x40, 0x0, 0x17); //RX ,APEN enable,Normal power + Wr_Indx(iobase, 0x40, 0x1, mode); //Set Mode + Wr_Indx(iobase, 0x40, 0x2, 0xff); //Set power to FIR VFIR > 1m + bTmp = Rd_Indx(iobase, 0x40, 1); +} + +void InitCard(__u16 iobase) +{ + ResetChip(iobase, 5); + WriteReg(iobase, I_ST_CT_0, 0x00); // open CHIP on + SetSIRBOF(iobase, 0xc0); // hardware default value + SetSIREOF(iobase, 0xc1); +} + +void CommonShutDown(__u16 iobase, __u8 TxDMA) +{ + DisableDmaChannel(TxDMA); +} + +void CommonInit(__u16 iobase) +{ +// EnTXCRC(iobase,0); + SwapDMA(iobase, OFF); + SetMaxRxPacketSize(iobase, 0x0fff); //set to max:4095 + EnRXFIFOReadyInt(iobase, OFF); + EnRXFIFOHalfLevelInt(iobase, OFF); + EnTXFIFOHalfLevelInt(iobase, OFF); + EnTXFIFOUnderrunEOMInt(iobase, ON); +// EnTXFIFOReadyInt(iobase,ON); + InvertTX(iobase, OFF); + InvertRX(iobase, OFF); +// WriteLPCReg(0xF0,0); //(if VT1211 then do this) + if (IsSIROn(iobase)) { + SIRFilter(iobase, ON); + SIRRecvAny(iobase, ON); + } else { + SIRFilter(iobase, OFF); + SIRRecvAny(iobase, OFF); + } + EnRXSpecInt(iobase, ON); + WriteReg(iobase, I_ST_CT_0, 0x80); + EnableDMA(iobase, ON); +} + +void SetBaudRate(__u16 iobase, __u32 rate) +{ + __u8 value = 11, temp; + + if (IsSIROn(iobase)) { + switch (rate) { + case (__u32) (2400L): + value = 47; + break; + case (__u32) (9600L): + value = 11; + break; + case (__u32) (19200L): + value = 5; + break; + case (__u32) (38400L): + value = 2; + break; + case (__u32) (57600L): + value = 1; + break; + case (__u32) (115200L): + value = 0; + break; + default: + break; + }; + } else if (IsMIROn(iobase)) { + value = 0; // will automatically be fixed in 1.152M + } else if (IsFIROn(iobase)) { + value = 0; // will automatically be fixed in 4M + } + temp = (ReadReg(iobase, I_CF_H_1) & 0x03); + temp = temp | (value << 2); + WriteReg(iobase, I_CF_H_1, temp); +} + +void SetPulseWidth(__u16 iobase, __u8 width) +{ + __u8 temp, temp1, temp2; + + temp = (ReadReg(iobase, I_CF_L_1) & 0x1f); + temp1 = (ReadReg(iobase, I_CF_H_1) & 0xfc); + temp2 = (width & 0x07) << 5; + temp = temp | temp2; + temp2 = (width & 0x18) >> 3; + temp1 = temp1 | temp2; + WriteReg(iobase, I_CF_L_1, temp); + WriteReg(iobase, I_CF_H_1, temp1); +} + +void SetSendPreambleCount(__u16 iobase, __u8 count) +{ + __u8 temp; + + temp = ReadReg(iobase, I_CF_L_1) & 0xe0; + temp = temp | count; + WriteReg(iobase, I_CF_L_1, temp); + +} + +void SetVFIR(__u16 BaseAddr, __u8 val) +{ + __u8 tmp; + + tmp = ReadReg(BaseAddr, I_CF_L_0); + WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); + WriteRegBit(BaseAddr, I_CF_H_0, 5, val); +} + +void SetFIR(__u16 BaseAddr, __u8 val) +{ + __u8 tmp; + + WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); + tmp = ReadReg(BaseAddr, I_CF_L_0); + WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); + WriteRegBit(BaseAddr, I_CF_L_0, 6, val); +} + +void SetMIR(__u16 BaseAddr, __u8 val) +{ + __u8 tmp; + + WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); + tmp = ReadReg(BaseAddr, I_CF_L_0); + WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); + WriteRegBit(BaseAddr, I_CF_L_0, 5, val); +} + +void SetSIR(__u16 BaseAddr, __u8 val) +{ + __u8 tmp; + + WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); + tmp = ReadReg(BaseAddr, I_CF_L_0); + WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); + WriteRegBit(BaseAddr, I_CF_L_0, 4, val); +} + +void ClrHBusy(__u16 iobase) +{ + + EnableDMA(iobase, OFF); + EnableDMA(iobase, ON); + RXStart(iobase, OFF); + RXStart(iobase, ON); + RXStart(iobase, OFF); + EnableDMA(iobase, OFF); + EnableDMA(iobase, ON); +} + +void SetFifo64(__u16 iobase) +{ + + WriteRegBit(iobase, I_CF_H_0, 0, 0); + WriteRegBit(iobase, I_CF_H_0, 7, 0); +} + + +#endif /* via_IRCC_H */ diff -urN linux-2.4.24/drivers/net/mac89x0.c linux-2.4.25/drivers/net/mac89x0.c --- linux-2.4.24/drivers/net/mac89x0.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/net/mac89x0.c 2004-02-18 05:36:31.000000000 -0800 @@ -128,7 +128,7 @@ extern void reset_chip(struct net_device *dev); #endif static int net_open(struct net_device *dev); -static int net_send_packet(struct sk_buff *skb, struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void set_multicast_list(struct net_device *dev); static void net_rx(struct net_device *dev); @@ -368,57 +368,38 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - if (dev->tbusy) { - /* If we get here, some higher level has decided we are broken. - There should really be a "kick me" function call instead. */ - int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 5) - return 1; - if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name, - tx_done(dev) ? "IRQ conflict" : "network cable problem"); - /* Try to restart the adaptor. */ - dev->tbusy=0; - dev->trans_start = jiffies; - } - - /* Block a timer-based transmit from overlapping. This could better be - done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ - if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) - printk("%s: Transmitter access conflict.\n", dev->name); - else { - struct net_local *lp = (struct net_local *)dev->priv; - unsigned long flags; - - if (net_debug > 3) - printk("%s: sent %d byte packet of type %x\n", - dev->name, skb->len, - (skb->data[ETH_ALEN+ETH_ALEN] << 8) - | skb->data[ETH_ALEN+ETH_ALEN+1]); - - /* keep the upload from being interrupted, since we - ask the chip to start transmitting before the - whole packet has been completely uploaded. */ - save_flags(flags); - cli(); - - /* initiate a transmit sequence */ - writereg(dev, PP_TxCMD, lp->send_cmd); - writereg(dev, PP_TxLength, skb->len); - - /* Test to see if the chip has allocated memory for the packet */ - if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { - /* Gasp! It hasn't. But that shouldn't happen since - we're waiting for TxOk, so return 1 and requeue this packet. */ - restore_flags(flags); - return 1; - } + struct net_local *lp = (struct net_local *)dev->priv; + unsigned long flags; - /* Write the contents of the packet */ - memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1); + if (net_debug > 3) + printk("%s: sent %d byte packet of type %x\n", + dev->name, skb->len, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) + | skb->data[ETH_ALEN+ETH_ALEN+1]); + + /* keep the upload from being interrupted, since we + ask the chip to start transmitting before the + whole packet has been completely uploaded. */ + save_flags(flags); + cli(); + /* initiate a transmit sequence */ + writereg(dev, PP_TxCMD, lp->send_cmd); + writereg(dev, PP_TxLength, skb->len); + + /* Test to see if the chip has allocated memory for the packet */ + if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { + /* Gasp! It hasn't. But that shouldn't happen since + we're waiting for TxOk, so return 1 and requeue this packet. */ restore_flags(flags); - dev->trans_start = jiffies; + return 1; } + + /* Write the contents of the packet */ + memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1); + + restore_flags(flags); + dev->trans_start = jiffies; dev_kfree_skb (skb); return 0; @@ -436,9 +417,6 @@ printk ("net_interrupt(): irq %d for unknown device.\n", irq); return; } - if (dev->interrupt) - printk("%s: Re-entering the interrupt handler.\n", dev->name); - dev->interrupt = 1; ioaddr = dev->base_addr; lp = (struct net_local *)dev->priv; @@ -459,8 +437,7 @@ break; case ISQ_TRANSMITTER_EVENT: lp->stats.tx_packets++; - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ + netif_wake_queue(dev); if ((status & TX_OK) == 0) lp->stats.tx_errors++; if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++; if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++; @@ -474,8 +451,7 @@ That shouldn't happen since we only ever load one packet. Shrug. Do the right thing anyway. */ - dev->tbusy = 0; - mark_bh(NET_BH); /* Inform upper layers. */ + netif_wake_queue(dev); } if (status & TX_UNDERRUN) { if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); @@ -492,7 +468,6 @@ break; } } - dev->interrupt = 0; return; } @@ -527,7 +502,7 @@ skb_put(skb, length); skb->dev = dev; - memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length); + memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length); if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, @@ -607,8 +582,6 @@ static int set_mac_address(struct net_device *dev, void *addr) { int i; - if (dev->start) - return -EBUSY; printk("%s: Setting MAC address to ", dev->name); for (i = 0; i < 6; i++) printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]); diff -urN linux-2.4.24/drivers/net/meth.c linux-2.4.25/drivers/net/meth.c --- linux-2.4.24/drivers/net/meth.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/net/meth.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,863 +0,0 @@ -/* - * meth.c -- O2 Builtin 10/100 Ethernet driver - * - * Copyright (C) 2001 Ilya Volynets - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include - -#include -#include /* printk() */ -#include -#include -#include /* error codes */ -#include /* size_t */ -#include /* mark_bh */ -#include - -#include -#include /* struct device, and other headers */ -#include /* eth_type_trans */ -#include /* struct iphdr */ -#include /* struct tcphdr */ -#include -#include /*MII definitions */ - -#include -#include -#include - -#include "meth.h" - -#include -#include - -#ifndef MFE_DEBUG -#define MFE_DEBUG 0 -#endif - -#if MFE_DEBUG>=1 -#define DPRINTK(str,args...) printk (KERN_DEBUG "meth(%ld): %s: " str, jiffies, __FUNCTION__ , ## args) -#define MFE_RX_DEBUG 2 -#else -#define DPRINTK(str,args...) -#define MFE_RX_DEBUG 0 -#endif - - -static const char *version="meth.c: Ilya Volynets (ilya@theIlya.com)"; -static const char *meth_str="SGI O2 Fast Ethernet"; -MODULE_AUTHOR("Ilya Volynets"); -MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); - -/* This is a load-time options */ -/*static int eth = 0; -MODULE_PARM(eth, "i");*/ - -#define HAVE_TX_TIMEOUT -/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */ -#define TX_TIMEOUT (400*HZ/1000) - -#ifdef HAVE_TX_TIMEOUT -static int timeout = TX_TIMEOUT; -MODULE_PARM(timeout, "i"); -#endif - -int meth_eth; - - -/* - * This structure is private to each device. It is used to pass - * packets in and out, so there is place for a packet - */ - -typedef struct meth_private { - struct net_device_stats stats; - volatile struct meth_regs *regs; - u64 mode; /* in-memory copy of MAC control register */ - int phy_addr; /* address of phy, used by mdio_* functions, initialized in mdio_probe*/ - tx_packet *tx_ring; - dma_addr_t tx_ring_dma; - int free_space; - struct sk_buff *tx_skbs[TX_RING_ENTRIES]; - dma_addr_t tx_skb_dmas[TX_RING_ENTRIES]; - int tx_read,tx_write; - int tx_count; - - rx_packet *rx_ring[RX_RING_ENTRIES]; - dma_addr_t rx_ring_dmas[RX_RING_ENTRIES]; - int rx_write; - - spinlock_t meth_lock; -} meth_private; - -extern struct net_device meth_devs[]; -void meth_tx_timeout (struct net_device *dev); -void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs); - -/* global, initialized in ip32-setup.c */ -char o2meth_eaddr[8]={0,0,0,0,0,0,0,0}; - -static inline void load_eaddr(struct net_device *dev, - volatile struct meth_regs *regs) -{ - int i; - DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF, - (int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF); - //memcpy(dev->dev_addr,o2meth_eaddr+2,6); - for (i=0; i<6; i++) - dev->dev_addr[i]=o2meth_eaddr[i]; - regs->mac_addr= //dev->dev_addr[0]|(dev->dev_addr[1]<<8)| - //dev->dev_addr[2]<<16|(dev->dev_addr[3]<<24)| - //dev->dev_addr[4]<<32|(dev->dev_addr[5]<<40); - (*(u64*)o2meth_eaddr)>>16; - DPRINTK("MAC, finally is %0lx\n",regs->mac_addr); -} - -/* - *Waits for BUSY status of mdio bus to clear - */ -#define WAIT_FOR_PHY(___regs, ___rval) \ - while((___rval=___regs->phy_data)&MDIO_BUSY){ \ - udelay(25); \ - } -/*read phy register, return value read */ -static int mdio_read(meth_private *priv,int phyreg) -{ - volatile meth_regs* regs=priv->regs; - volatile u32 rval; - WAIT_FOR_PHY(regs,rval) - regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f); - udelay(25); - regs->phy_trans_go=1; - udelay(25); - WAIT_FOR_PHY(regs,rval) - return rval&MDIO_DATA_MASK; -} - -/*write phy register */ -static void mdio_write(meth_private* priv,int pfyreg,int val) -{ - volatile meth_regs* regs=priv->regs; - int rval; -/// DPRINTK("Trying to write value %i to reguster %i\n",val, pfyreg); - spin_lock_irq(&priv->meth_lock); - WAIT_FOR_PHY(regs,rval) - regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f); - regs->phy_data=val; - udelay(25); - WAIT_FOR_PHY(regs,rval) - spin_unlock_irq(&priv->meth_lock); -} - -/* Modify phy register using given mask and value */ -static void mdio_update(meth_private* priv,int phyreg, int val, int mask) -{ - int rval; - DPRINTK("RMW value %i to PHY register %i with mask %i\n",val,phyreg,mask); - rval=mdio_read(priv,phyreg); - rval=(rval&~mask)|(val&mask); - mdio_write(priv,phyreg,rval); -} - -/* handle errata data on MDIO bus */ -//static void mdio_errata(meth_private *priv) -//{ - /* Hmmm... what the hell is phyerrata? does it come from sys init parameters in IRIX */ -//} -static int mdio_probe(meth_private *priv) -{ - int i, p2, p3; - DPRINTK("Detecting PHY kind\n"); - /* check if phy is detected already */ - if(priv->phy_addr>=0&&priv->phy_addr<32) - return 0; - spin_lock_irq(&priv->meth_lock); - for (i=0;i<32;++i){ - priv->phy_addr=(char)i; - p2=mdio_read(priv,2); -#ifdef MFE_DEBUG - p3=mdio_read(priv,3); - switch ((p2<<12)|(p3>>4)){ - case PHY_QS6612X: - DPRINTK("PHY is QS6612X\n"); - break; - case PHY_ICS1889: - DPRINTK("PHY is ICS1889\n"); - break; - case PHY_ICS1890: - DPRINTK("PHY is ICS1890\n"); - break; - case PHY_DP83840: - DPRINTK("PHY is DP83840\n"); - break; - } -#endif - if(p2!=0xffff&&p2!=0x0000){ - DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4)); - break; - } - } - spin_unlock_irq(&priv->meth_lock); - if(priv->phy_addr<32) { - return 0; - } - DPRINTK("Oopsie! PHY is not known!\n"); - priv->phy_addr=-1; - return -ENODEV; -} - -static void meth_check_link(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - int mii_partner = mdio_read(priv, 5); - int mii_advertising = mdio_read(priv, 4); - int negotiated = mii_advertising & mii_partner; - int duplex, speed; - - if (mii_partner == 0xffff) - return; - - duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040)?METH_PHY_FDX:0; - speed = (negotiated & 0x0380)?METH_100MBIT:0; - - if ((priv->mode & METH_PHY_FDX) ^ duplex) - { - DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half"); - if (duplex) - priv->mode |= METH_PHY_FDX; - else - priv->mode &= ~METH_PHY_FDX; - priv->regs->mac_ctrl = priv->mode; - } - - if ((priv->mode & METH_100MBIT) ^ speed) - { - DPRINTK("Setting %dMbs mode\n", speed ? 100 : 10); - if (duplex) - priv->mode |= METH_100MBIT; - else - priv->mode &= ~METH_100MBIT; - priv->regs->mac_ctrl = priv->mode; - } -} - - -static int meth_init_tx_ring(meth_private *priv) -{ - /* Init TX ring */ - DPRINTK("Initializing TX ring\n"); - priv->tx_ring = (tx_packet *) pci_alloc_consistent(NULL,TX_RING_BUFFER_SIZE,&(priv->tx_ring_dma)); - if(!priv->tx_ring) - return -ENOMEM; - memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE); - priv->tx_count = priv->tx_read = priv->tx_write = 0; - priv->regs->tx_ring_base = priv->tx_ring_dma; - priv->free_space = TX_RING_ENTRIES; - /* Now init skb save area */ - memset(priv->tx_skbs,0,sizeof(priv->tx_skbs)); - memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas)); - DPRINTK("Done with TX ring init\n"); - return 0; -} - -static int meth_init_rx_ring(meth_private *priv) -{ - int i; - DPRINTK("Initializing RX ring\n"); - for(i=0;irx_ring[i]=get_free_page(GFP_KERNEL))) - return -ENOMEM; - DPRINTK("\t2:\t%i\n",i);*/ - priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i])); - /* I'll need to re-sync it after each RX */ - DPRINTK("\t%p\n",priv->rx_ring[i]); - priv->regs->rx_fifo=priv->rx_ring_dmas[i]; - } - priv->rx_write = 0; - DPRINTK("Done with RX ring\n"); - return 0; -} -static void meth_free_tx_ring(meth_private *priv) -{ - int i; - - /* Remove any pending skb */ - for (i = 0; i < TX_RING_ENTRIES; i++) { - if (priv->tx_skbs[i]) - dev_kfree_skb(priv->tx_skbs[i]); - priv->tx_skbs[i] = NULL; - } - pci_free_consistent(NULL, - TX_RING_BUFFER_SIZE, - priv->tx_ring, - priv->tx_ring_dma); -} -static void meth_free_rx_ring(meth_private *priv) -{ - int i; - - for(i=0;irx_ring[i], - priv->rx_ring_dmas[i]); -} - -int meth_reset(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - /* Reset card */ - priv->regs->mac_ctrl = SGI_MAC_RESET; - priv->regs->mac_ctrl = 0; - udelay(25); - DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl); - - /* Load ethernet address */ - load_eaddr(dev, priv->regs); - /* Should load some "errata", but later */ - - /* Check for device */ - if(mdio_probe(priv) < 0) { - DPRINTK("Unable to find PHY\n"); - return -ENODEV; - } - - /* Initial mode -- 10|Half-duplex|Accept normal packets */ - priv->mode=METH_ACCEPT_MCAST|METH_DEFAULT_IPG; - if(dev->flags | IFF_PROMISC) - priv->mode |= METH_PROMISC; - priv->regs->mac_ctrl = priv->mode; - - /* Autonegociate speed and duplex mode */ - meth_check_link(dev); - - /* Now set dma control, but don't enable DMA, yet */ - priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) | - (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT); - - return(0); -} - -/*============End Helper Routines=====================*/ - -/* - * Open and close - */ - -int meth_open(struct net_device *dev) -{ - meth_private *priv=dev->priv; - volatile meth_regs *regs=priv->regs; - - MOD_INC_USE_COUNT; - - /* Start DMA */ - regs->dma_ctrl|= - METH_DMA_TX_EN|/*METH_DMA_TX_INT_EN|*/ - METH_DMA_RX_EN|METH_DMA_RX_INT_EN; - - if(request_irq(dev->irq,meth_interrupt,SA_SHIRQ,meth_str,dev)){ - printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq); - return -EAGAIN; - } - netif_start_queue(dev); - DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl); - return 0; -} - -int meth_release(struct net_device *dev) -{ - netif_stop_queue(dev); /* can't transmit any more */ - /* shut down dma */ - ((meth_private*)(dev->priv))->regs->dma_ctrl&= - ~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN| - METH_DMA_RX_EN|METH_DMA_RX_INT_EN); - free_irq(dev->irq, dev); - MOD_DEC_USE_COUNT; - return 0; -} - -/* - * Configuration changes (passed on by ifconfig) - */ -int meth_config(struct net_device *dev, struct ifmap *map) -{ - if (dev->flags & IFF_UP) /* can't act on a running interface */ - return -EBUSY; - - /* Don't allow changing the I/O address */ - if (map->base_addr != dev->base_addr) { - printk(KERN_WARNING "meth: Can't change I/O address\n"); - return -EOPNOTSUPP; - } - - /* Allow changing the IRQ */ - if (map->irq != dev->irq) { - printk(KERN_WARNING "meth: Can't change IRQ\n"); - return -EOPNOTSUPP; - } - DPRINTK("Configured\n"); - - /* ignore other fields */ - return 0; -} - -/* - * Receive a packet: retrieve, encapsulate and pass over to upper levels - */ -void meth_rx(struct net_device* dev) -{ - struct sk_buff *skb; - struct meth_private *priv = (struct meth_private *) dev->priv; - rx_packet *rxb; - DPRINTK("RX...\n"); - // TEMP while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ - while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ - int len=rxb->status.parsed.rx_len - 4; /* omit CRC */ - DPRINTK("(%i)\n",priv->rx_write); - /* length sanity check */ - if(len < 60 || len > 1518) { - printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n", - dev->name, priv->rx_write, rxb->status.raw); - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; - } - if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){ - skb=alloc_skb(len+2,GFP_ATOMIC);/* Should be atomic -- we are in interrupt */ - if(!skb){ - /* Ouch! No memory! Drop packet on the floor */ - DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n"); - priv->stats.rx_dropped++; - } else { - skb_reserve(skb, 2); /* align IP on 16B boundary */ - memcpy(skb_put(skb, len), rxb->buf, len); - /* Write metadata, and then pass to the receive level */ - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - //skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ - - DPRINTK("passing packet\n"); - DPRINTK("len = %d rxb->status = %x\n", - len, rxb->status.raw); - netif_rx(skb); - dev->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes+=len; - DPRINTK("There we go... Whew...\n"); - } - } - priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write]; - rxb->status.raw=0; - priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1); - } -} - -static int meth_tx_full(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - return(priv->tx_count >= TX_RING_ENTRIES-1); -} - -void meth_tx_cleanup(struct net_device* dev, int rptr) -{ - meth_private *priv=dev->priv; - tx_packet* status; - struct sk_buff *skb; - - spin_lock(&priv->meth_lock); - - /* Stop DMA */ - priv->regs->dma_ctrl &= ~(METH_DMA_TX_INT_EN); - - while(priv->tx_read != rptr){ - skb = priv->tx_skbs[priv->tx_read]; - status = &priv->tx_ring[priv->tx_read]; - if(!status->header.res.sent) - break; - if(status->header.raw & METH_TX_STATUS_DONE) { - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; - } - dev_kfree_skb_irq(skb); - priv->tx_skbs[priv->tx_read] = NULL; - status->header.raw = 0; - priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1); - priv->tx_count --; - } - - /* wake up queue if it was stopped */ - if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) { - netif_wake_queue(dev); - } - - spin_unlock(priv->meth_lock); -} - -/* - * The typical interrupt entry point - */ -void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs) -{ - struct meth_private *priv; - union { - u32 reg; /*Whole status register */ - struct { - u32 : 2, - rx_seq : 5, - tx_read : 9, - - rx_read : 8, - int_mask: 8; - } parsed; - } status; - /* - * As usual, check the "device" pointer for shared handlers. - * Then assign "struct device *dev" - */ - struct net_device *dev = (struct net_device *)dev_id; - /* ... and check with hw if it's really ours */ - - if (!dev /*paranoid*/ ) return; - - /* Lock the device */ - priv = (struct meth_private *) dev->priv; - - status.reg = priv->regs->int_flags; - - DPRINTK("Interrupt, status %08x...\n",status.reg); - if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) { - /* send it to meth_rx for handling */ - meth_rx(dev); - } - - if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) { - /* a transmission is over: free the skb */ - meth_tx_cleanup(dev, status.parsed.tx_read); - } - /* check for errors too... */ - if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL)) - printk(KERN_WARNING "meth: link failure\n"); - if (status.parsed.int_mask & (METH_INT_MEM_ERROR)) - printk(KERN_WARNING "meth: memory error\n"); - if (status.parsed.int_mask & (METH_INT_TX_ABORT)) - printk(KERN_WARNING "meth: aborted\n"); - DPRINTK("Interrupt handling done...\n"); - - priv->regs->int_flags=status.reg&0xff; /* clear interrupts */ -} - -/* - * Transmits packets that fit into TX descriptor (are <=120B) - */ -static void meth_tx_short_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - int len = (skb->lenlen; - - DPRINTK("preparing short packet\n"); - /* maybe I should set whole thing to 0 first... */ - memcpy(desc->data.dt+(120-len),skb->data,skb->len); - if(skb->len < len) - memset(desc->data.dt+120-len+skb->len,0,len-skb->len); - desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16); - DPRINTK("desc=%016lx\n",desc->header.raw); -} -#define TX_CATBUF1 BIT(25) -static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - void *buffer_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); - int unaligned_len = (int)((u64)buffer_data - (u64)skb->data); - int buffer_len = skb->len - unaligned_len; - dma_addr_t catbuf; - - DPRINTK("preparing 1 page...\n"); - DPRINTK("length=%d data=%p\n", skb->len, skb->data); - DPRINTK("unaligned_len=%d\n", unaligned_len); - DPRINTK("buffer_data=%p buffer_len=%d\n", - buffer_data, - buffer_len); - - desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1); - - /* unaligned part */ - if(unaligned_len){ - memcpy(desc->data.dt+(120-unaligned_len), - skb->data, unaligned_len); - desc->header.raw |= (128-unaligned_len) << 16; - } - - /* first page */ - catbuf = pci_map_single(NULL, - buffer_data, - buffer_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf=%x\n", catbuf); - desc->data.cat_buf[0].form.start_addr = catbuf >> 3; - desc->data.cat_buf[0].form.len = buffer_len-1; - DPRINTK("desc=%016lx\n",desc->header.raw); - DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); -} -#define TX_CATBUF2 BIT(26) -static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb) -{ - tx_packet *desc=&priv->tx_ring[priv->tx_write]; - void *buffer1_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); - void *buffer2_data = (void *)PAGE_ALIGN((u64)skb->data); - int unaligned_len = (int)((u64)buffer1_data - (u64)skb->data); - int buffer1_len = (int)((u64)buffer2_data - (u64)buffer1_data); - int buffer2_len = skb->len - buffer1_len - unaligned_len; - dma_addr_t catbuf1, catbuf2; - - DPRINTK("preparing 2 pages... \n"); - DPRINTK("length=%d data=%p\n", skb->len, skb->data); - DPRINTK("unaligned_len=%d\n", unaligned_len); - DPRINTK("buffer1_data=%p buffer1_len=%d\n", - buffer1_data, - buffer1_len); - DPRINTK("buffer2_data=%p buffer2_len=%d\n", - buffer2_data, - buffer2_len); - - desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1); - /* unaligned part */ - if(unaligned_len){ - memcpy(desc->data.dt+(120-unaligned_len), - skb->data, unaligned_len); - desc->header.raw |= (128-unaligned_len) << 16; - } - - /* first page */ - catbuf1 = pci_map_single(NULL, - buffer1_data, - buffer1_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf1=%x\n", catbuf1); - desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3; - desc->data.cat_buf[0].form.len = buffer1_len-1; - /* second page */ - catbuf2 = pci_map_single(NULL, - buffer2_data, - buffer2_len, - PCI_DMA_TODEVICE); - DPRINTK("catbuf2=%x\n", catbuf2); - desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3; - desc->data.cat_buf[1].form.len = buffer2_len-1; - DPRINTK("desc=%016lx\n",desc->header.raw); - DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); - DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw); -} - - -void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb) -{ - DPRINTK("Transmitting data...\n"); - if(skb->len <= 120) { - /* Whole packet fits into descriptor */ - meth_tx_short_prepare(priv,skb); - } else if(PAGE_ALIGN((u64)skb->data) != - PAGE_ALIGN((u64)skb->data+skb->len-1)) { - /* Packet crosses page boundary */ - meth_tx_2page_prepare(priv,skb); - } else { - /* Packet is in one page */ - meth_tx_1page_prepare(priv,skb); - } - - /* Remember the skb, so we can free it at interrupt time */ - priv->tx_skbs[priv->tx_write] = skb; - priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1); - priv->regs->tx_info.wptr = priv->tx_write; - priv->tx_count ++; - /* Enable DMA transfer */ - priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN; -} - -/* - * Transmit a packet (called by the kernel) - */ -int meth_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - spin_lock_irq(&priv->meth_lock); - - meth_add_to_tx_ring(priv, skb); - dev->trans_start = jiffies; /* save the timestamp */ - - /* If TX ring is full, tell the upper layer to stop sending packets */ - if (meth_tx_full(dev)) { - DPRINTK("TX full: stopping\n"); - netif_stop_queue(dev); - } - - spin_unlock_irq(&priv->meth_lock); - - return 0; -} - -/* - * Deal with a transmit timeout. - */ - -void meth_tx_timeout (struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - - printk(KERN_WARNING "%s: transmit timed out\n", dev->name); - - /* Protect against concurrent rx interrupts */ - spin_lock_irq(&priv->meth_lock); - - /* Try to reset the adaptor. */ - meth_reset(dev); - - priv->stats.tx_errors++; - - /* Clear all rings */ - meth_free_tx_ring(priv); - meth_free_rx_ring(priv); - meth_init_tx_ring(priv); - meth_init_rx_ring(priv); - - /* Restart dma */ - priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN; - - /* Enable interrupt */ - spin_unlock_irq(&priv->meth_lock); - - dev->trans_start = jiffies; - netif_wake_queue(dev); - - return; -} - -/* - * Ioctl commands - */ -int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - - DPRINTK("ioctl\n"); - return 0; -} - -/* - * Return statistics to the caller - */ -struct net_device_stats *meth_stats(struct net_device *dev) -{ - struct meth_private *priv = (struct meth_private *) dev->priv; - return &priv->stats; -} - -/* - * The init function (sometimes called probe). - * It is invoked by register_netdev() - */ -int meth_init(struct net_device *dev) -{ - meth_private *priv; - int ret; - /* - * Then, assign other fields in dev, using ether_setup() and some - * hand assignments - */ - ether_setup(dev); /* assign some of the fields */ - - dev->open = meth_open; - dev->stop = meth_release; - dev->set_config = meth_config; - dev->hard_start_xmit = meth_tx; - dev->do_ioctl = meth_ioctl; - dev->get_stats = meth_stats; -#ifdef HAVE_TX_TIMEOUT - dev->tx_timeout = meth_tx_timeout; - dev->watchdog_timeo = timeout; -#endif - dev->irq = MACE_ETHERNET_IRQ; - SET_MODULE_OWNER(dev); - - /* - * Then, allocate the priv field. This encloses the statistics - * and a few private fields. - */ - priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - dev->priv=priv; - memset(priv, 0, sizeof(struct meth_private)); - spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock); - /* - * Make the usual checks: check_region(), probe irq, ... -ENODEV - * should be returned if no device found. No resource should be - * grabbed: this is done on open(). - */ - priv->regs=(meth_regs*)SGI_MFE; - dev->base_addr=SGI_MFE; - priv->phy_addr = -1; /* No phy is known yet... */ - - /* Initialize the hardware */ - if((ret=meth_reset(dev)) < 0) - return ret; - - /* Allocate the ring buffers */ - if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){ - meth_free_tx_ring(priv); - meth_free_rx_ring(priv); - return ret; - } - - printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29); - - return 0; -} - -/* - * The devices - */ - -struct net_device meth_devs[1] = { - { init: meth_init, } /* init, nothing more */ -}; - -/* - * Finally, the module stuff - */ - -int meth_init_module(void) -{ - int result, device_present = 0; - - strcpy(meth_devs[0].name, "eth%d"); - - if ( (result = register_netdev(meth_devs)) ) - printk("meth: error %i registering device \"%s\"\n", - result, meth_devs->name); - else device_present++; -#ifndef METH_DEBUG - EXPORT_NO_SYMBOLS; -#endif - - return device_present ? 0 : -ENODEV; -} - -void meth_cleanup(void) -{ - kfree(meth_devs->priv); - unregister_netdev(meth_devs); - return; -} - -module_init(meth_init_module); -module_exit(meth_cleanup); diff -urN linux-2.4.24/drivers/net/meth.h linux-2.4.25/drivers/net/meth.h --- linux-2.4.24/drivers/net/meth.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/net/meth.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,273 +0,0 @@ - -/* - * snull.h -- definitions for the network module - * - * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet - * Copyright (C) 2001 O'Reilly & Associates - * - * The source code in this file can be freely used, adapted, - * and redistributed in source or binary form, so long as an - * acknowledgment appears in derived source files. The citation - * should list that the code comes from the book "Linux Device - * Drivers" by Alessandro Rubini and Jonathan Corbet, published - * by O'Reilly & Associates. No warranty is attached; - * we cannot take responsibility for errors or fitness for use. - */ - -/* version dependencies have been confined to a separate file */ - -#define SGI_MFE (MACE_BASE+MACE_ENET) -/* (0xBF280000)*/ - -/* Tunable parameters */ -#define TX_RING_ENTRIES 64 /* 64-512?*/ - -#define RX_RING_ENTRIES 16 /* Do not change */ -/* Internal constants */ -#define TX_RING_BUFFER_SIZE (TX_RING_ENTRIES*sizeof(tx_packet)) -#define RX_BUFFER_SIZE 1546 /* ethenet packet size */ -#define METH_RX_BUFF_SIZE 4096 -#define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */ -#define RX_BUCKET_SIZE 256 - - - -/* For more detailed explanations of what each field menas, - see Nick's great comments to #defines below (or docs, if - you are lucky enough toget hold of them :)*/ - -/* tx status vector is written over tx command header upon - dma completion. */ - -typedef struct tx_status_vector { - u64 sent:1; /* always set to 1...*/ - u64 pad0:34;/* always set to 0 */ - u64 flags:9; /*I'm too lazy to specify each one separately at the moment*/ - u64 col_retry_cnt:4; /*collision retry count*/ - u64 len:16; /*Transmit length in bytes*/ -} tx_status_vector; - -/* - * Each packet is 128 bytes long. - * It consists of header, 0-3 concatination - * buffer pointers and up to 120 data bytes. - */ -typedef struct tx_packet_hdr { - u64 pad1:36; /*should be filled with 0 */ - u64 cat_ptr3_valid:1, /*Concatination pointer valid flags*/ - cat_ptr2_valid:1, - cat_ptr1_valid:1; - u64 tx_int_flag:1; /*Generate TX intrrupt when packet has been sent*/ - u64 term_dma_flag:1; /*Terminate transmit DMA on transmit abort conditions*/ - u64 data_offset:7; /*Starting byte offset in ring data block*/ - u64 data_len:16; /*Length of valid data in bytes-1*/ -} tx_packet_hdr; -typedef union tx_cat_ptr { - struct { - u64 pad2:16; /* should be 0 */ - u64 len:16; /*length of buffer data - 1*/ - u64 start_addr:29; /*Physical starting address*/ - u64 pad1:3; /* should be zero */ - } form; - u64 raw; -} tx_cat_ptr; - -typedef struct tx_packet { - union { - tx_packet_hdr header; - tx_status_vector res; - u64 raw; - }header; - union { - tx_cat_ptr cat_buf[3]; - char dt[120]; - } data; -} tx_packet; - -typedef union rx_status_vector { - struct { - u64 pad1:1;/*fill it with ones*/ - u64 pad2:15;/*fill with 0*/ - u64 ip_chk_sum:16; - u64 seq_num:5; - u64 mac_addr_match:1; - u64 mcast_addr_match:1; - u64 carrier_event_seen:1; - u64 bad_packet:1; - u64 long_event_seen:1; - u64 invalid_preamble:1; - u64 broadcast:1; - u64 multicast:1; - u64 crc_error:1; - u64 huh:1;/*???*/ - u64 rx_code_violation:1; - u64 rx_len:16; - } parsed; - u64 raw; -} rx_status_vector; - -typedef struct rx_packet { - rx_status_vector status; - u64 pad[3]; /* For whatever reason, there needs to be 4 double-word offset */ - u16 pad2; - char buf[METH_RX_BUFF_SIZE-sizeof(rx_status_vector)-3*sizeof(u64)-sizeof(u16)];/* data */ -} rx_packet; - -typedef struct meth_regs { - u64 mac_ctrl; /*0x00,rw,31:0*/ - u64 int_flags; /*0x08,rw,30:0*/ - u64 dma_ctrl; /*0x10,rw,15:0*/ - u64 timer; /*0x18,rw,5:0*/ - u64 int_tx; /*0x20,wo,0:0*/ - u64 int_rx; /*0x28,wo,9:4*/ - struct { - u32 tx_info_pad; - u32 rptr:16,wptr:16; - } tx_info; /*0x30,rw,31:0*/ - u64 tx_info_al; /*0x38,rw,31:0*/ - struct { - u32 rx_buff_pad1; - u32 rx_buff_pad2:8, - wptr:8, - rptr:8, - depth:8; - } rx_buff; /*0x40,ro,23:0*/ - u64 rx_buff_al1; /*0x48,ro,23:0*/ - u64 rx_buff_al2; /*0x50,ro,23:0*/ - u64 int_update; /*0x58,wo,31:0*/ - u32 phy_data_pad; - u32 phy_data; /*0x60,rw,16:0*/ - u32 phy_reg_pad; - u32 phy_registers; /*0x68,rw,9:0*/ - u64 phy_trans_go; /*0x70,wo,0:0*/ - u64 backoff_seed; /*0x78,wo,10:0*/ - u64 imq_reserved[4];/*0x80,ro,64:0(x4)*/ - /*===================================*/ - u64 mac_addr; /*0xA0,rw,47:0, I think it's MAC address, but I'm not sure*/ - u64 mcast_addr; /*0xA8,rw,47:0, This seems like secondary MAC address*/ - u64 mcast_filter; /*0xB0,rw,63:0*/ - u64 tx_ring_base; /*0xB8,rw,31:13*/ - /* Following are read-only debugging info register */ - u64 tx_pkt1_hdr; /*0xC0,ro,63:0*/ - u64 tx_pkt1_ptr[3]; /*0xC8,ro,63:0(x3)*/ - u64 tx_pkt2_hdr; /*0xE0,ro,63:0*/ - u64 tx_pkt2_ptr[3]; /*0xE8,ro,63:0(x3)*/ - /*===================================*/ - u32 rx_pad; - u32 rx_fifo; - u64 reserved[31]; -}meth_regs; - - /* Bits in METH_MAC */ - -#define SGI_MAC_RESET BIT(0) /* 0: MAC110 active in run mode, 1: Global reset signal to MAC110 core is active */ -#define METH_PHY_FDX BIT(1) /* 0: Disable full duplex, 1: Enable full duplex */ -#define METH_PHY_LOOP BIT(2) /* 0: Normal operation, follows 10/100mbit and M10T/MII select, 1: loops internal MII bus */ - /* selects ignored */ -#define METH_100MBIT BIT(3) /* 0: 10meg mode, 1: 100meg mode */ -#define METH_PHY_MII BIT(4) /* 0: MII selected, 1: SIA selected */ - /* Note: when loopback is set this bit becomes collision control. Setting this bit will */ - /* cause a collision to be reported. */ - - /* Bits 5 and 6 are used to determine the the Destination address filter mode */ -#define METH_ACCEPT_MY 0 /* 00: Accept PHY address only */ -#define METH_ACCEPT_MCAST 0x20 /* 01: Accept physical, broadcast, and multicast filter matches only */ -#define METH_ACCEPT_AMCAST 0x40 /* 10: Accept physical, broadcast, and all multicast packets */ -#define METH_PROMISC 0x60 /* 11: Promiscious mode */ - -#define METH_PHY_LINK_FAIL BIT(7) /* 0: Link failure detection disabled, 1: Hardware scans for link failure in PHY */ - -#define METH_MAC_IPG 0x1ffff00 - -#define METH_DEFAULT_IPG ((17<<15) | (11<<22) | (21<<8)) - /* 0x172e5c00 */ /* 23, 23, 23 */ /*0x54A9500 *//*21,21,21*/ - /* Bits 8 through 14 are used to determine Inter-Packet Gap between "Back to Back" packets */ - /* The gap depends on the clock speed of the link, 80ns per increment for 100baseT, 800ns */ - /* per increment for 10BaseT */ - - /* Bits 15 through 21 are used to determine IPGR1 */ - - /* Bits 22 through 28 are used to determine IPGR2 */ - -#define METH_REV_SHIFT 29 /* Bits 29 through 31 are used to determine the revision */ - /* 000: Inital revision */ - /* 001: First revision, Improved TX concatenation */ - - -/* DMA control bits */ -#define METH_RX_OFFSET_SHIFT 12 /* Bits 12:14 of DMA control register indicate starting offset of packet data for RX operation */ -#define METH_RX_DEPTH_SHIFT 4 /* Bits 8:4 define RX fifo depth -- when # of RX fifo entries != depth, interrupt is generted */ - -#define METH_DMA_TX_EN BIT(1) /* enable TX DMA */ -#define METH_DMA_TX_INT_EN BIT(0) /* enable TX Buffer Empty interrupt */ -#define METH_DMA_RX_EN BIT(15) /* Enable RX */ -#define METH_DMA_RX_INT_EN BIT(9) /* Enable interrupt on RX packet */ - - -/* RX status bits */ - -#define METH_RX_ST_RCV_CODE_VIOLATION BIT(16) -#define METH_RX_ST_DRBL_NBL BIT(17) -#define METH_RX_ST_CRC_ERR BIT(18) -#define METH_RX_ST_MCAST_PKT BIT(19) -#define METH_RX_ST_BCAST_PKT BIT(20) -#define METH_RX_ST_INV_PREAMBLE_CTX BIT(21) -#define METH_RX_ST_LONG_EVT_SEEN BIT(22) -#define METH_RX_ST_BAD_PACKET BIT(23) -#define METH_RX_ST_CARRIER_EVT_SEEN BIT(24) -#define METH_RX_ST_MCAST_FILTER_MATCH BIT(25) -#define METH_RX_ST_PHYS_ADDR_MATCH BIT(26) - -#define METH_RX_STATUS_ERRORS \ - ( \ - METH_RX_ST_RCV_CODE_VIOLATION| \ - METH_RX_ST_CRC_ERR| \ - METH_RX_ST_INV_PREAMBLE_CTX| \ - METH_RX_ST_LONG_EVT_SEEN| \ - METH_RX_ST_BAD_PACKET| \ - METH_RX_ST_CARRIER_EVT_SEEN \ - ) - /* Bits in METH_INT */ - /* Write _1_ to corresponding bit to clear */ -#define METH_INT_TX_EMPTY BIT(0) /* 0: No interrupt pending, 1: The TX ring buffer is empty */ -#define METH_INT_TX_PKT BIT(1) /* 0: No interrupt pending */ - /* 1: A TX message had the INT request bit set, the packet has been sent. */ -#define METH_INT_TX_LINK_FAIL BIT(2) /* 0: No interrupt pending, 1: PHY has reported a link failure */ -#define METH_INT_MEM_ERROR BIT(3) /* 0: No interrupt pending */ - /* 1: A memory error occurred durring DMA, DMA stopped, Fatal */ -#define METH_INT_TX_ABORT BIT(4) /* 0: No interrupt pending, 1: The TX aborted operation, DMA stopped, FATAL */ -#define METH_INT_RX_THRESHOLD BIT(5) /* 0: No interrupt pending, 1: Selected receive threshold condition Valid */ -#define METH_INT_RX_UNDERFLOW BIT(6) /* 0: No interrupt pending, 1: FIFO was empty, packet could not be queued */ -#define METH_INT_RX_OVERFLOW BIT(7) /* 0: No interrupt pending, 1: DMA FIFO Overflow, DMA stopped, FATAL */ - -#define METH_INT_RX_RPTR_MASK 0x0001F00 /* Bits 8 through 12 alias of RX read-pointer */ - - /* Bits 13 through 15 are always 0. */ - -#define METH_INT_TX_RPTR_MASK 0x1FF0000 /* Bits 16 through 24 alias of TX read-pointer */ - -#define METH_INT_SEQ_MASK 0x2E000000 /* Bits 25 through 29 are the starting seq number for the message at the */ - /* top of the queue */ - -#define METH_ERRORS ( \ - METH_INT_RX_OVERFLOW| \ - METH_INT_RX_UNDERFLOW| \ - METH_INT_MEM_ERROR| \ - METH_INT_TX_ABORT) - -#define METH_INT_MCAST_HASH BIT(30) /* If RX DMA is enabled the hash select logic output is latched here */ - -/* TX status bits */ -#define METH_TX_STATUS_DONE BIT(23) /* Packet was transmitted successfully */ - -/* Tx command header bits */ -#define METH_TX_CMD_INT_EN BIT(24) /* Generate TX interrupt when packet is sent */ - -/* Phy MDIO interface busy flag */ -#define MDIO_BUSY BIT(16) -#define MDIO_DATA_MASK 0xFFFF -/* PHY defines */ -#define PHY_QS6612X 0x0181441 /* Quality TX */ -#define PHY_ICS1889 0x0015F41 /* ICS FX */ -#define PHY_ICS1890 0x0015F42 /* ICS TX */ -#define PHY_DP83840 0x20005C0 /* National TX */ diff -urN linux-2.4.24/drivers/net/mv64340_eth.c linux-2.4.25/drivers/net/mv64340_eth.c --- linux-2.4.24/drivers/net/mv64340_eth.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/mv64340_eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,6 +5,9 @@ * Based on the 64360 driver from: * Copyright (C) 2002 rabeeh@galileo.co.il * + * Copyright (C) 2003 PMC-Sierra, Inc., + * written by Manish Lachwani (lachwani@pmc-sierra.com) + * * Copyright (C) 2003 Ralf Baechle * * This program is free software; you can redistribute it and/or @@ -20,7 +23,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * */ #include #include @@ -39,10 +41,10 @@ #include #include #include - +#include +#include #include #include -#include #include #include @@ -50,12 +52,6 @@ #include #include #include - -#ifdef CONFIG_NET_FASTROUTE -#include -#include -#endif - #include "mv64340_eth.h" /************************************************************************* @@ -87,13 +83,24 @@ static int mv64340_eth_change_mtu(struct net_device *, int); static struct net_device_stats *mv64340_eth_get_stats(struct net_device *); static void eth_port_init_mac_tables(ETH_PORT eth_port_num); +#ifdef MV64340_NAPI +static int mv64340_poll(struct net_device *dev, int *budget); +#endif -static unsigned char prom_mac_addr_base[6]; +unsigned char prom_mac_addr_base[6]; +unsigned long mv64340_sram_base; /************************************************** * Helper functions - used inside the driver only * **************************************************/ +static inline void __netif_rx_complete(struct net_device *dev) +{ + if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + list_del(&dev->poll_list); + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + static void *mv64340_eth_malloc_ring(unsigned int size) { dma_addr_t dma_handle; @@ -152,7 +159,6 @@ spin_unlock_irqrestore(&port_private->lock, flags); return 0; } - /********************************************************************** * mv64340_eth_rx_task * @@ -181,8 +187,10 @@ while (port_private->rx_ring_skbs < (port_private->rx_ring_size - 5)) { /* The +8 for buffer allignment and another 32 byte extra */ + skb = dev_alloc_skb(BUFFER_MTU + 8 + EXTRA_BYTES); if (!skb) + /* Better luck next time */ break; port_private->rx_ring_skbs++; pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT; @@ -226,7 +234,6 @@ #endif } - /********************************************************************** * mv64340_eth_rx_task_timer_wrapper * @@ -302,37 +309,6 @@ /********************************************************************** - * mv64340_eth_accept_fastpath - * - * Used to authenticate to the kernel that a fast path entry can be - * added to device's routing table cache - * - * Input : pointer to ethernet interface network device structure and - * a pointer to the designated entry to be added to the cache. - * Output : zero upon success, negative upon failure - **********************************************************************/ -#ifdef CONFIG_NET_FASTROUTE -static int mv64340_eth_accept_fastpath(struct net_device *dev, - struct dst_entry *dst) -{ - struct net_device *odev = dst->dev; - - if (dst->ops->protocol != __constant_htons(ETH_P_IP)) { - return -1; - } - - if (odev->type != ARPHRD_ETHER || odev->accept_fastpath == NULL) { - return -1; - } - - printk(KERN_INFO - "Accepted fastpath (destination interface %s)\n", odev->name); - return 0; -} -#endif - - -/********************************************************************** * mv64340_eth_set_mac_address * * Change the interface's mac address. @@ -364,7 +340,27 @@ **********************************************************************/ static void mv64340_eth_tx_timeout(struct net_device *dev) { - printk(KERN_INFO "%s: TX timeout\n", dev->name); + ETH_PORT_INFO *ethernet_private = dev->priv; + printk(KERN_INFO "%s: TX timeout ", dev->name); + printk(KERN_INFO "Resetting card \n"); + + /* Do the reset outside of interrupt context */ + schedule_task(ðernet_private->tx_timeout_task); +} + +/********************************************************************** + * mv64340_eth_tx_timeout_task + * + * Actual routine to reset the adapter when a timeout on Tx has occurred + **********************************************************************/ +static void mv64340_eth_tx_timeout_task(struct net_device *dev) +{ + ETH_PORT_INFO *ethernet_private = dev->priv; + + netif_device_detach(dev); + eth_port_reset(ethernet_private->port_num); + eth_port_start(ethernet_private); + netif_device_attach(dev); } /********************************************************************** @@ -410,7 +406,18 @@ dev_kfree_skb_irq((struct sk_buff *) pkt_info.return_info); released = 0; + if (skb_shinfo(pkt_info.return_info)->nr_frags) + pci_unmap_page(0, pkt_info.buf_ptr, + pkt_info.byte_cnt, + PCI_DMA_TODEVICE); + + if (port_private->tx_ring_skbs != 1) + port_private->tx_ring_skbs--; } + else + pci_unmap_page(0, pkt_info.buf_ptr, + pkt_info.byte_cnt, + PCI_DMA_TODEVICE); /* * Decrement the number of outstanding skbs counter on the @@ -419,7 +426,6 @@ if (port_private->tx_ring_skbs == 0) panic ("ERROR - TX outstanding SKBs counter is corrupted\n"); - port_private->tx_ring_skbs--; } @@ -438,8 +444,12 @@ * * Output : number of served packets **********************************************************************/ - +#ifdef MV64340_NAPI +static int mv64340_eth_receive_queue(struct net_device *dev, unsigned int max, + int budget) +#else static int mv64340_eth_receive_queue(struct net_device *dev, unsigned int max) +#endif { ETH_PORT_INFO *ethernet_private; struct mv64340_eth_priv *port_private; @@ -449,33 +459,29 @@ unsigned int received_packets = 0; struct net_device_stats *stats; -#ifdef CONFIG_NET_FASTROUTE - register int fast_routed = 0; - struct ethhdr *eth; - struct iphdr *iph; - unsigned h, CPU_ID = smp_processor_id(); - struct rtable *rt; - struct net_device *odev; -#endif - ethernet_private = dev->priv; port_private = (struct mv64340_eth_priv *) ethernet_private->port_private; port_num = port_private->port_num; stats = &port_private->stats; +#ifdef MV64340_NAPI + while ((eth_port_receive(ethernet_private, &pkt_info) == ETH_OK) + && + budget > 0) { +#else while ((--max) && (eth_port_receive(ethernet_private, &pkt_info) == ETH_OK)) { +#endif port_private->rx_ring_skbs--; received_packets++; - +#ifdef MV64340_NAPI + budget--; +#endif /* Update statistics. Note byte count includes 4 byte CRC count */ stats->rx_packets++; stats->rx_bytes += pkt_info.byte_cnt; -#ifdef CONFIG_NET_FASTROUTE - fast_routed = 0; -#endif skb = (struct sk_buff *) pkt_info.return_info; /* * In case received a packet without first / last bits on OR the error @@ -502,111 +508,34 @@ } dev_kfree_skb_irq(skb); } else { - /* The -4 is for the CRC in the trailer of the received packet */ + struct ethhdr *eth_h; + struct iphdr *ip_h; + + /* + * The -4 is for the CRC in the trailer of the + * received packet + */ skb_put(skb, pkt_info.byte_cnt - 4); skb->dev = dev; -#ifdef CONFIG_NET_FASTROUTE - eth = (struct ethhdr *) skb->data; - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - iph = - (struct iphdr *) (skb->data + - ETH_HLEN); - h = - (*(u8 *) & iph->daddr ^ *(u8 *) & iph-> - saddr) & NETDEV_FASTROUTE_HMASK; - rt = (struct rtable *) (dev->fastpath[h]); - if (rt != NULL && - ((u16 *) & iph->daddr)[0] == - ((u16 *) & rt->key.dst)[0] - && ((u16 *) & iph->daddr)[1] == - ((u16 *) & rt->key.dst)[1] - && ((u16 *) & iph->saddr)[0] == - ((u16 *) & rt->key.src)[0] - && ((u16 *) & iph->saddr)[1] == - ((u16 *) & rt->key.src)[1] - && !rt->u.dst.obsolete) { - odev = rt->u.dst.dev; - netdev_rx_stat - [CPU_ID].fastroute_hit++; - if (*(u8 *) iph == 0x45 - && (!(eth->h_dest[0] & 0x80)) - && neigh_is_valid(rt->u.dst. - neighbour) - && iph->ttl > 1) { - /* Fast Route Path */ - fast_routed = 1; - if ( - (!netif_queue_stopped - (odev)) - && - (!spin_is_locked - (odev->xmit_lock)) - && (skb->len <= - (odev->mtu + - ETH_HLEN + 2 + - 4))) { - skb->pkt_type = - PACKET_FASTROUTE; - skb->protocol = - __constant_htons - (ETH_P_IP); - ip_decrease_ttl - (iph); - memcpy - (eth->h_source, - odev-> - dev_addr, 6); - memcpy(eth->h_dest, - rt->u.dst. - neighbour-> - ha, 6); - skb->dev = odev; - if - (odev-> - hard_start_xmit - (skb, odev) != 0) { - panic - ("%s: FastRoute path corrupted", - dev-> - name); - } - netdev_rx_stat - [CPU_ID]. - fastroute_success++; - } - /* Semi Fast Route Path */ - else { - skb->pkt_type = - PACKET_FASTROUTE; - skb->nh.raw = - skb->data + - ETH_HLEN; - skb->protocol = - __constant_htons - (ETH_P_IP); - netdev_rx_stat - [CPU_ID]. - fastroute_defer++; - netif_rx(skb); - } - } - } + + eth_h = (struct ethhdr *) skb->data; + ip_h = (struct iphdr *) (skb->data + ETH_HLEN); + if (pkt_info.cmd_sts & ETH_LAYER_4_CHECKSUM_OK) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->csum = htons((pkt_info.cmd_sts + & 0x0007fff8) >> 3); } - if (fast_routed == 0) -#endif - { - struct ethhdr *eth_h; - struct iphdr *ip_h; - eth_h = (struct ethhdr *) skb->data; - ip_h = - (struct iphdr *) (skb->data + - ETH_HLEN); + else skb->ip_summed = CHECKSUM_NONE; - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - } + skb->protocol = eth_type_trans(skb, dev); +#ifdef MV64340_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif } } + return received_packets; } @@ -635,67 +564,52 @@ /* Read interrupt cause registers */ eth_int_cause = - MV_READ_DATA(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num)); - if (eth_int_cause & BIT1) + (MV_READ_DATA(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num)) & + INT_CAUSE_UNMASK_ALL); + + if (eth_int_cause & BIT1) eth_int_cause_ext = - MV_READ_DATA(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG - (port_num)); + (MV_READ_DATA(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) & + INT_CAUSE_UNMASK_ALL_EXT); else eth_int_cause_ext = 0; - /* Mask with shadowed mask registers */ -#ifdef MV64340_RX_QUEUE_FILL_ON_TASK - eth_int_cause &= INT_CAUSE_CHECK_BITS; - eth_int_cause_ext &= INT_CAUSE_CHECK_BITS_EXT; -#else - eth_int_cause &= INT_CAUSE_UNMASK_ALL; - eth_int_cause_ext &= INT_CAUSE_UNMASK_ALL_EXT; +#ifdef MV64340_NAPI + if (!(eth_int_cause & 0x0007fffd)) { + /* Dont ack the Rx interrupt */ #endif - - /* - * If no real interrupt occured, exit. - * This can happen when using gigE interrupt coalescing mechanism. - */ - if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0)) { - return; + /* + * Clear specific ethernet port intrerrupt registers by acknowleding + * relevant bits. + */ + MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num), + ~eth_int_cause); + if (eth_int_cause_ext != 0x0) + MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), + ~eth_int_cause_ext); + + /* UDP change : We may need this */ + if (eth_int_cause_ext & 0x0000ffff) { + if (mv64340_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) { + if (netif_queue_stopped(dev) && + (dev->flags & IFF_RUNNING) && + (MV64340_TX_QUEUE_SIZE > port_private->tx_ring_skbs + 1)) { + netif_wake_queue(dev); + } + } + } +#ifdef MV64340_NAPI } - - /* - * Clear specific ethernet port intrerrupt registers by acknowleding - * relevant bits. - */ - MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num), - ~eth_int_cause); - if (eth_int_cause_ext != 0x0) - MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), - ~eth_int_cause_ext); - - if (eth_int_cause_ext & 0x0000ffff) { - /* - * Check if released more than one packet. - * Otherwise don't wake up queue - */ - if (mv64340_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) { - /* - * If the interface was stopped before, and link is up, - * wakeup TX queue. Note that this might be a problematic - * issue since the multiple TX queues in the system controller, - * and in which few queues are stucked. - * If this is the case, then a TX packet to a stucked queue is - * forwarded to another TX queue of the interface ; BUT in the - * current implementation only one TX / RX queues are used. - */ - if (netif_queue_stopped(dev) - && (dev->flags & IFF_RUNNING) - && - (MV64340_TX_QUEUE_SIZE > port_private->tx_ring_skbs + 1)) { - netif_wake_queue(dev); - } + else { + if (netif_rx_schedule_prep(dev)) { + /* Mask all the interrupts */ + MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num),0); + MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0); + __netif_rx_schedule(dev); } - } - if (eth_int_cause & 0x0007fffd) { /*RxBuffer returned, RxResource Error */ +#else unsigned int total_received = 0; - /* Rx Return Buffer / Resource Error Priority queue 0 */ + if (eth_int_cause & (BIT2 | BIT11)) { total_received += mv64340_eth_receive_queue(dev, 0); @@ -713,7 +627,7 @@ #else port_private->rx_task.routine(dev); #endif - +#endif } /* PHY status changed */ if (eth_int_cause_ext & (BIT16 | BIT20)) { @@ -739,6 +653,15 @@ MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 1); } } + + /* + * If no real interrupt occured, exit. + * This can happen when using gigE interrupt coalescing mechanism. + */ + if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0)) { + return; + } + return; } @@ -800,6 +723,7 @@ unsigned int port_num; u32 phy_reg_data; unsigned int size; + int i; ethernet_private = dev->priv; port_private = @@ -824,6 +748,7 @@ /* Set the MAC Address */ memcpy(ethernet_private->port_mac_addr, dev->dev_addr, 6); + eth_port_init(ethernet_private); /* Set rx_task pointers */ @@ -846,7 +771,7 @@ /* Assumes allocated ring is 16 bytes alligned */ ethernet_private->p_tx_desc_area = - (ETH_TX_DESC *) mv64340_eth_malloc_ring(size); + (ETH_TX_DESC *) mv64340_sram_base; if (!ethernet_private->p_tx_desc_area) { printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", @@ -898,6 +823,22 @@ eth_port_start(ethernet_private); + /* Interrupt Coalescing */ + +#ifdef MV64340_COAL + port_private->rx_int_coal = + eth_port_set_rx_coal (port_num, 133000000, MV64340_RX_COAL); +#endif + + port_private->tx_int_coal = + eth_port_set_tx_coal (port_num, 133000000, MV64340_TX_COAL); + + /* Increase the Rx side buffer size */ + + MV_WRITE (MV64340_ETH_PORT_SERIAL_CONTROL_REG(port_num), (0x5 << 17) | + (MV_READ_DATA (MV64340_ETH_PORT_SERIAL_CONTROL_REG(port_num)) + & 0xfff1ffff)); + /* Check Link status on phy */ eth_port_read_smi_reg(port_num, 1, &phy_reg_data); if (!(phy_reg_data & 0x20)) { @@ -907,10 +848,10 @@ netif_start_queue(dev); dev->flags |= (IFF_RUNNING); } + return 0; } - static void mv64340_eth_free_tx_rings(struct net_device *dev) { ETH_PORT_INFO *ethernet_private; @@ -1022,7 +963,6 @@ ETH_PORT_INFO *ethernet_private; struct mv64340_eth_priv *port_private; unsigned int port_num; - ethernet_private = dev->priv; port_private = (struct mv64340_eth_priv *) ethernet_private->port_private; @@ -1048,6 +988,92 @@ return 0; } +#ifdef MV64340_NAPI +static void mv64340_tx(struct net_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64340_eth_priv *port_private; + unsigned int port_num; + PKT_INFO pkt_info; + + ethernet_private = dev->priv; + port_private = + (struct mv64340_eth_priv *) ethernet_private->port_private; + + port_num = port_private->port_num; + + while (eth_tx_return_desc(ethernet_private, &pkt_info) == ETH_OK) { + if (pkt_info.return_info) { + dev_kfree_skb_irq((struct sk_buff *) + pkt_info.return_info); + if (skb_shinfo(pkt_info.return_info)->nr_frags) + pci_unmap_page(0, pkt_info.buf_ptr, + pkt_info.byte_cnt, + PCI_DMA_TODEVICE); + + if (port_private->tx_ring_skbs != 1) + port_private->tx_ring_skbs--; + } else + pci_unmap_page(0, pkt_info.buf_ptr, + pkt_info.byte_cnt, + PCI_DMA_TODEVICE); + } + + if (netif_queue_stopped(dev) && + (dev->flags & IFF_RUNNING) && + (MV64340_TX_QUEUE_SIZE > port_private->tx_ring_skbs + 1)) { + netif_wake_queue(dev); + } +} + +/********************************************************************** + * mv64340_poll + * + * This function is used in case of NAPI + ***********************************************************************/ +static int mv64340_poll(struct net_device *netdev, int *budget) +{ + ETH_PORT_INFO *ethernet_private = netdev->priv; + struct mv64340_eth_priv *port_private = + (struct mv64340_eth_priv *) ethernet_private->port_private; + int done = 1, orig_budget, work_done; + unsigned long flags; + unsigned int port_num = port_private->port_num; + + spin_lock_irqsave(&port_private->lock, flags); + +#ifdef MV64340_TX_FAST_REFILL + if (++ethernet_private->tx_clean_threshold > 5) { + mv64340_tx(netdev); + ethernet_private->tx_clean_threshold = 0; + } +#endif + if ((u32)(MV_READ_DATA(MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num))) != (u32)ethernet_private->rx_used_desc_q) { + orig_budget = *budget; + if (orig_budget > netdev->quota) + orig_budget = netdev->quota; + work_done = mv64340_eth_receive_queue(netdev, 0, orig_budget); + port_private->rx_task.routine(netdev); + *budget -= work_done; + netdev->quota -= work_done; + if (work_done >= orig_budget) + done = 0; + } + + if (done) { + __netif_rx_complete(netdev); + MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num),0); + MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num),0); + MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL); + MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL_EXT); + } + + spin_unlock_irqrestore(&port_private->lock, flags); + return (done ? 0 : 1); +} +#endif /********************************************************************** * mv64340_eth_start_xmit @@ -1103,19 +1129,91 @@ spin_lock_irqsave(&port_private->lock, flags); /* Update packet info data structure -- DMA owned, first last */ - pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | - ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + if (!skb_shinfo(skb)->nr_frags || (skb_shinfo(skb)->nr_frags > 3)) { +#endif + pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | + ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; - pkt_info.byte_cnt = skb->len; - pkt_info.buf_ptr = pci_map_single - (0, skb->data, skb->len, PCI_DMA_TODEVICE); - - pkt_info.return_info = skb; - status = eth_port_send(ethernet_private, &pkt_info); - if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) - printk(KERN_ERR "%s: Error on transmitting packet\n", - dev->name); - port_private->tx_ring_skbs++; + pkt_info.byte_cnt = skb->len; + pkt_info.buf_ptr = pci_map_single + (0, skb->data, skb->len, PCI_DMA_TODEVICE); + + pkt_info.return_info = skb; + status = eth_port_send(ethernet_private, &pkt_info); + if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) + printk(KERN_ERR "%s: Error on transmitting packet\n", + dev->name); + port_private->tx_ring_skbs++; +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + } + else { + unsigned int frag; + u32 ipheader; + + /* first frag which is skb header */ + pkt_info.byte_cnt = skb_headlen(skb); + pkt_info.buf_ptr = pci_map_single(0, skb->data, + skb_headlen(skb), PCI_DMA_TODEVICE); + pkt_info.return_info = 0; + ipheader = (skb->nh.iph->ihl << 11); + pkt_info.cmd_sts = ETH_TX_FIRST_DESC | + ETH_GEN_TCP_UDP_CHECKSUM | + ETH_GEN_IP_V_4_CHECKSUM | + ipheader; + /* CPU already calculated pseudo header checksum. So, use it */ + pkt_info.l4i_chk = skb->h.th->check; + status = eth_port_send(ethernet_private, &pkt_info); + if (status != ETH_OK) { + if ((status == ETH_ERROR)) + printk(KERN_ERR "%s: Error on transmitting packet\n", dev->name); + if (status == ETH_QUEUE_FULL) + printk("Error on Queue Full \n"); + if (status == ETH_QUEUE_LAST_RESOURCE) + printk("Tx resource error \n"); + } + + /* Check for the remaining frags */ + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + pkt_info.l4i_chk = 0x0000; + pkt_info.cmd_sts = 0x00000000; + + /* Last Frag enables interrupt and frees the skb */ + if (frag == (skb_shinfo(skb)->nr_frags - 1)) { + pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT | + ETH_TX_LAST_DESC; + pkt_info.return_info = skb; + port_private->tx_ring_skbs++; + } + else { + pkt_info.return_info = 0; + } + pkt_info.byte_cnt = this_frag->size; + if (this_frag->size < 8) + printk("%d : \n", skb_shinfo(skb)->nr_frags); + + pkt_info.buf_ptr = pci_map_page(0, + this_frag->page, + this_frag->page_offset, + this_frag->size, + PCI_DMA_TODEVICE); + + status = eth_port_send(ethernet_private, &pkt_info); + + if (status != ETH_OK) { + if ((status == ETH_ERROR)) + printk(KERN_ERR "%s: Error on transmitting packet\n", dev->name); + + if (status == ETH_QUEUE_LAST_RESOURCE) + printk("Tx resource error \n"); + + if (status == ETH_QUEUE_FULL) + printk("Queue is full \n"); + } + } + } +#endif /* Check if TX queue can handle another skb. If not, then * signal higher layers to stop requesting TX @@ -1138,7 +1236,6 @@ return 0; /* success */ } - /********************************************************************** * mv64340_eth_get_stats * @@ -1195,16 +1292,29 @@ /* No need to Tx Timeout */ dev->tx_timeout = mv64340_eth_tx_timeout; +#ifdef MV64340_NAPI + dev->poll = mv64340_poll; + dev->weight = 64; +#endif + dev->watchdog_timeo = 2 * HZ; dev->tx_queue_len = MV64340_TX_QUEUE_SIZE; dev->flags &= ~(IFF_RUNNING); dev->base_addr = 0; dev->change_mtu = &mv64340_eth_change_mtu; -#ifdef CONFIG_NET_FASTROUTE - dev->accept_fastpath = mv64340_eth_accept_fastpath; + +#ifdef MV64340_CHECKSUM_OFFLOAD_TX +#ifdef MAX_SKB_FRAGS +#ifndef CONFIG_JAGUAR_DMALOW + /* + * Zero copy can only work if we use Discovery II memory. Else, we will + * have to map the buffers to ISA memory which is only 16 MB + */ + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM; +#endif +#endif #endif ethernet_private = dev->priv; - /* Allocate memory for stats data structure and spinlock etc... */ ethernet_private->port_private = (void *) kmalloc(sizeof(struct mv64340_eth_priv), GFP_KERNEL); @@ -1223,7 +1333,6 @@ else { printk(KERN_ERR "%s: Invalid port number\n", dev->name); kfree(ethernet_private->port_private); - err = -ENODEV; goto out_free_dev; } @@ -1234,6 +1343,10 @@ memset(&port_private->stats, 0, sizeof(struct net_device_stats)); + /* Configure the timeout task */ + INIT_TQUEUE(ðernet_private->tx_timeout_task, + (void (*)(void *))mv64340_eth_tx_timeout_task, dev); + /* Init spinlock */ spin_lock_init(&port_private->lock); @@ -1250,6 +1363,19 @@ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (dev->features & NETIF_F_SG) + printk("Scatter Gather Enabled "); + + if (dev->features & NETIF_F_IP_CSUM) + printk("TX TCP/IP Checksumming Supported \n"); + + printk("RX TCP/UDP Checksum Offload ON, \n"); + printk("TX and RX Interrupt Coalescing ON \n"); + +#ifdef MV64340_NAPI + printk("RX NAPI Enabled \n"); +#endif + return 0; out_free_dev: @@ -1310,7 +1436,7 @@ module_exit(mv64340_cleanup_module); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Rabeeh Khoury, Assaf Hoffman, and Matthew Dharm"); +MODULE_AUTHOR("Rabeeh Khoury, Assaf Hoffman, Matthew Dharm and Manish Lachwani"); MODULE_DESCRIPTION("Ethernet driver for Marvell MV64340"); /************************************************************************* @@ -1480,33 +1606,6 @@ #define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \ MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue))) -#if 0 -#define CURR_RFD_GET(p_curr_desc) \ - ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q) - -#define CURR_RFD_SET(p_curr_desc) \ - (p_eth_port_ctrl->p_rx_curr_desc_q = (p_curr_desc)) - -#define USED_RFD_GET(p_used_desc) \ - ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q) - -#define USED_RFD_SET(p_used_desc)\ -(p_eth_port_ctrl->p_rx_used_desc_q = (p_used_desc)) - - -#define CURR_TFD_GET(p_curr_desc) \ - ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q) - -#define CURR_TFD_SET(p_curr_desc) \ - (p_eth_port_ctrl->p_tx_curr_desc_q = (p_curr_desc)) - -#define USED_TFD_GET(p_used_desc) \ - ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q) - -#define USED_TFD_SET(p_used_desc) \ - (p_eth_port_ctrl->p_tx_used_desc_q = (p_used_desc)) -#endif - #define LINK_UP_TIMEOUT 100000 #define PHY_BUSY_TIMEOUT 10000000 @@ -1618,7 +1717,7 @@ /* Assignment of Tx CTRP of given queue */ tx_curr_desc = p_eth_port_ctrl->tx_curr_desc_q; MV_WRITE(MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(eth_port_num), - virt_to_bus(&(p_eth_port_ctrl->p_tx_desc_area[tx_curr_desc]))); + (u32)&(p_eth_port_ctrl->p_tx_desc_area[tx_curr_desc])); /* Assignment of Rx CRDP of given queue */ rx_curr_desc = p_eth_port_ctrl->rx_curr_desc_q; @@ -2313,21 +2412,23 @@ p_tx_desc[ix].byte_cnt = 0x0000; p_tx_desc[ix].l4i_chk = 0x0000; p_tx_desc[ix].cmd_sts = 0x00000000; - p_tx_desc[ix].next_desc_ptr = virt_to_bus(&(p_tx_desc[ix+1])); + p_tx_desc[ix].next_desc_ptr = (u32)&(p_tx_desc[ix+1]); p_tx_desc[ix].buf_ptr = 0x00000000; dma_cache_wback_inv((unsigned long)&(p_tx_desc[ix]), sizeof(ETH_TX_DESC)); p_eth_port_ctrl->tx_skb[ix] = NULL; } /* Closing Tx descriptors ring */ - p_tx_desc[tx_desc_num-1].next_desc_ptr = virt_to_bus(&(p_tx_desc[0])); + p_tx_desc[tx_desc_num-1].next_desc_ptr = (u32)&(p_tx_desc[0]); dma_cache_wback_inv((unsigned long)&(p_tx_desc[tx_desc_num-1]), sizeof(ETH_TX_DESC)); /* Set Tx desc pointer in driver struct. */ p_eth_port_ctrl->tx_curr_desc_q = 0; p_eth_port_ctrl->tx_used_desc_q = 0; - +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + p_eth_port_ctrl->tx_first_desc_q = 0; +#endif /* Init Tx ring base and size parameters */ p_eth_port_ctrl->p_tx_desc_area = (ETH_TX_DESC*) tx_desc_base_addr; p_eth_port_ctrl->tx_desc_area_size = tx_desc_num * sizeof(ETH_TX_DESC); @@ -2365,6 +2466,127 @@ * ETH_OK otherwise. * *******************************************************************************/ +#ifdef MV64340_CHECKSUM_OFFLOAD_TX +/* + * Modified to include the first descriptor pointer in case of SG + */ +static ETH_FUNC_RET_STATUS eth_port_send(ETH_PORT_INFO * p_eth_port_ctrl, + PKT_INFO * p_pkt_info) +{ + int tx_desc_curr, tx_desc_used, tx_first_desc, tx_next_desc; + volatile ETH_TX_DESC* current_descriptor; + volatile ETH_TX_DESC* first_descriptor; + u32 command_status, first_chip_ptr; + + /* Do not process Tx ring in case of Tx ring resource error */ + if (p_eth_port_ctrl->tx_resource_err == true) + return ETH_QUEUE_FULL; + + /* Get the Tx Desc ring indexes */ + tx_desc_curr = p_eth_port_ctrl->tx_curr_desc_q; + tx_desc_used = p_eth_port_ctrl->tx_used_desc_q; + + current_descriptor = &(p_eth_port_ctrl->p_tx_desc_area[tx_desc_curr]); + if (current_descriptor == NULL) + return ETH_ERROR; + + tx_next_desc = (tx_desc_curr + 1) % MV64340_TX_QUEUE_SIZE; + command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC; + + if (command_status & ETH_TX_FIRST_DESC) { + tx_first_desc = tx_desc_curr; + p_eth_port_ctrl->tx_first_desc_q = tx_first_desc; + + /* fill first descriptor */ + first_descriptor = &(p_eth_port_ctrl->p_tx_desc_area[tx_desc_curr]); + first_descriptor->l4i_chk = p_pkt_info->l4i_chk; + first_descriptor->cmd_sts = command_status; + first_descriptor->byte_cnt = p_pkt_info->byte_cnt; + first_descriptor->buf_ptr = p_pkt_info->buf_ptr; + first_descriptor->next_desc_ptr = (u32)&(p_eth_port_ctrl->p_tx_desc_area[tx_next_desc]); + dma_cache_wback_inv((unsigned long)first_descriptor, sizeof(ETH_TX_DESC)); + wmb(); + } + else { + tx_first_desc = p_eth_port_ctrl->tx_first_desc_q; + first_descriptor = &(p_eth_port_ctrl->p_tx_desc_area[tx_first_desc]); + if (first_descriptor == NULL) { + printk("First desc is NULL !!\n"); + return ETH_ERROR; + } + if (command_status & ETH_TX_LAST_DESC) + current_descriptor->next_desc_ptr = 0x00000000; + else { + command_status |= ETH_BUFFER_OWNED_BY_DMA; + current_descriptor->next_desc_ptr = (u32)&(p_eth_port_ctrl->p_tx_desc_area[tx_next_desc]); + } + } + + if (p_pkt_info->byte_cnt < 8) { + printk(" < 8 problem \n"); + return ETH_ERROR; + } + + current_descriptor->buf_ptr = p_pkt_info->buf_ptr; + current_descriptor->byte_cnt = p_pkt_info->byte_cnt; + current_descriptor->l4i_chk = p_pkt_info->l4i_chk; + current_descriptor->cmd_sts = command_status; + dma_cache_wback_inv((unsigned long)current_descriptor, sizeof(ETH_TX_DESC)); + + p_eth_port_ctrl->tx_skb[tx_desc_curr] = + (struct sk_buff*)p_pkt_info->return_info; + + dma_cache_wback_inv((unsigned long)p_eth_port_ctrl, sizeof(ETH_PORT_INFO)); + wmb(); + + /* Set last desc with DMA ownership and interrupt enable. */ + if (command_status & ETH_TX_LAST_DESC) { + current_descriptor->cmd_sts = command_status | + ETH_TX_ENABLE_INTERRUPT | + ETH_BUFFER_OWNED_BY_DMA; + + if (!(command_status & ETH_TX_FIRST_DESC) ) { + first_descriptor->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA; + dma_cache_wback_inv((unsigned long)first_descriptor, sizeof(ETH_TX_DESC)); + } + dma_cache_wback_inv((unsigned long)current_descriptor, sizeof(ETH_TX_DESC)); + wmb(); + + first_chip_ptr = MV_READ_DATA(MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(p_eth_port_ctrl->port_num)); + + /* Apply send command */ + if (first_chip_ptr == 0x00000000) { + MV_WRITE(MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(p_eth_port_ctrl->port_num), (u32)&(p_eth_port_ctrl->p_tx_desc_area[tx_first_desc])); + } + + ETH_ENABLE_TX_QUEUE(p_eth_port_ctrl->port_num); + + /* Finish Tx packet. Update first desc in case of Tx resource error */ + tx_first_desc = tx_next_desc; + p_eth_port_ctrl->tx_first_desc_q = tx_first_desc; + } + else { + if (! (command_status & ETH_TX_FIRST_DESC) ) { + current_descriptor->cmd_sts = command_status; + dma_cache_wback_inv((unsigned long)current_descriptor, + sizeof(ETH_TX_DESC)); + wmb(); + } + } + + /* Check for ring index overlap in the Tx desc ring */ + if (tx_next_desc == tx_desc_used) { + p_eth_port_ctrl->tx_resource_err = true; + p_eth_port_ctrl->tx_curr_desc_q = tx_first_desc; + return ETH_QUEUE_LAST_RESOURCE; + } + + p_eth_port_ctrl->tx_curr_desc_q = tx_next_desc; + dma_cache_wback_inv((unsigned long) p_eth_port_ctrl, sizeof(ETH_PORT_INFO)); + wmb(); + return ETH_OK; +} +#else static ETH_FUNC_RET_STATUS eth_port_send(ETH_PORT_INFO * p_eth_port_ctrl, PKT_INFO * p_pkt_info) { @@ -2431,6 +2653,7 @@ return ETH_OK; } +#endif /******************************************************************************* * eth_tx_return_desc - Free all used Tx descriptors @@ -2460,12 +2683,18 @@ PKT_INFO * p_pkt_info) { int tx_desc_used, tx_desc_curr; +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + int tx_first_desc; +#endif volatile ETH_TX_DESC *p_tx_desc_used; unsigned int command_status; /* Get the Tx Desc ring indexes */ tx_desc_curr = p_eth_port_ctrl->tx_curr_desc_q; tx_desc_used = p_eth_port_ctrl->tx_used_desc_q; +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + tx_first_desc = p_eth_port_ctrl->tx_first_desc_q; +#endif p_tx_desc_used = &(p_eth_port_ctrl->p_tx_desc_area[tx_desc_used]); /* XXX Sanity check */ @@ -2475,14 +2704,19 @@ command_status = p_tx_desc_used->cmd_sts; /* Still transmitting... */ +#ifndef MV64340_CHECKSUM_OFFLOAD_TX if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { dma_cache_wback_inv((unsigned long)p_tx_desc_used, sizeof(ETH_TX_DESC)); return ETH_RETRY; } - +#endif /* Stop release. About to overlap the current available Tx descriptor */ +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + if ((tx_desc_used == tx_first_desc) && +#else if ((tx_desc_used == tx_desc_curr) && +#endif (p_eth_port_ctrl->tx_resource_err == false)) { dma_cache_wback_inv((unsigned long)p_tx_desc_used, sizeof(ETH_TX_DESC)); @@ -2640,7 +2874,6 @@ return ETH_OK; } -#ifdef MDD_CUT /******************************************************************************* * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path * @@ -2713,6 +2946,7 @@ return coal; } +#ifdef MDD_CUT /******************************************************************************* * eth_b_copy - Copy bytes from source to destination * diff -urN linux-2.4.24/drivers/net/mv64340_eth.h linux-2.4.25/drivers/net/mv64340_eth.h --- linux-2.4.24/drivers/net/mv64340_eth.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/mv64340_eth.h 2004-02-18 05:36:31.000000000 -0800 @@ -55,6 +55,12 @@ #define ETH_PORT1_IRQ_NUM ETH_PORT0_IRQ_NUM+1 /* main high register, bit1 */ #define ETH_PORT2_IRQ_NUM ETH_PORT0_IRQ_NUM+2 /* main high register, bit1 */ +/* Checksum offload for Tx works */ +#define MV64340_CHECKSUM_OFFLOAD_TX 1 +#define MV64340_NAPI 1 +#define MV64340_TX_FAST_REFILL 1 +#undef MV64340_COAL + /* * Number of RX / TX descriptors on RX / TX rings. * Note that allocating RX descriptors is done by allocating the RX @@ -69,8 +75,10 @@ /* Default RX ring size is 400 descriptors */ #define MV64340_RX_QUEUE_SIZE 400 -#define MV64340_TX_COAL 200 -#define MV64340_RX_COAL 200 +#define MV64340_TX_COAL 100 +#ifdef MV64340_COAL +#define MV64340_RX_COAL 100 +#endif /* Private data structure used for ethernet device */ struct mv64340_eth_priv { @@ -151,9 +159,9 @@ /* Default sdma control value */ #define PORT_SDMA_CONFIG_VALUE \ - ETH_RX_BURST_SIZE_4_64BIT | \ + ETH_RX_BURST_SIZE_16_64BIT | \ GT_ETH_IPG_INT_RX(0) | \ - ETH_TX_BURST_SIZE_4_64BIT; + ETH_TX_BURST_SIZE_16_64BIT; #define GT_ETH_IPG_INT_RX(value) \ ((value & 0x3fff) << 8) @@ -173,7 +181,7 @@ ETH_DTE_ADV_0 | \ ETH_DISABLE_AUTO_NEG_BYPASS | \ ETH_AUTO_NEG_NO_CHANGE | \ - ETH_MAX_RX_PACKET_1552BYTE | \ + ETH_MAX_RX_PACKET_9700BYTE | \ ETH_CLR_EXT_LOOPBACK | \ ETH_SET_FULL_DUPLEX_MODE | \ ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX @@ -554,6 +562,13 @@ /* Next available and first returning Tx resource */ int tx_curr_desc_q, tx_used_desc_q; +#ifdef MV64340_CHECKSUM_OFFLOAD_TX + int tx_first_desc_q; +#endif + +#ifdef MV64340_TX_FAST_REFILL + u32 tx_clean_threshold; +#endif /* Tx/Rx rings size and base variables fields. For driver use */ volatile ETH_RX_DESC *p_rx_desc_area; @@ -563,7 +578,7 @@ volatile ETH_TX_DESC *p_tx_desc_area; unsigned int tx_desc_area_size; struct sk_buff* tx_skb[MV64340_TX_QUEUE_SIZE]; - + struct tq_struct tx_timeout_task; } ETH_PORT_INFO; @@ -578,13 +593,11 @@ unsigned int value); static unsigned int ethernet_get_config_reg(ETH_PORT eth_port_num); -#ifdef MDD_CUT /* Interrupt Coalesting functions */ static unsigned int eth_port_set_rx_coal(ETH_PORT, unsigned int, unsigned int); static unsigned int eth_port_set_tx_coal(ETH_PORT, unsigned int, unsigned int); -#endif /* Port MAC address routines */ static void eth_port_uc_addr_set(ETH_PORT eth_port_num, diff -urN linux-2.4.24/drivers/net/natsemi.c linux-2.4.25/drivers/net/natsemi.c --- linux-2.4.24/drivers/net/natsemi.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/natsemi.c 2004-02-18 05:36:31.000000000 -0800 @@ -164,6 +164,7 @@ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -365,7 +366,7 @@ { "NatSemi DP8381[56]", PCI_IOTYPE }, }; -static struct pci_device_id natsemi_pci_tbl[] __devinitdata = { +static struct pci_device_id natsemi_pci_tbl[] = { { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, }; @@ -695,7 +696,7 @@ static void reinit_ring(struct net_device *dev); static void init_registers(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static void netdev_rx(struct net_device *dev); static void netdev_tx_done(struct net_device *dev); @@ -763,19 +764,13 @@ SET_MODULE_OWNER(dev); i = pci_request_regions(pdev, dev->name); - if (i) { - kfree(dev); - return i; - } + if (i) + goto err_pci_request_regions; - { - void *mmio = ioremap (ioaddr, iosize); - if (!mmio) { - pci_release_regions(pdev); - kfree(dev); - return -ENOMEM; - } - ioaddr = (unsigned long) mmio; + ioaddr = (unsigned long) ioremap (ioaddr, iosize); + if (!ioaddr) { + i = -ENOMEM; + goto err_ioremap; } /* Work around the dropped serial bit. */ @@ -833,13 +828,9 @@ dev->mtu = mtu; i = register_netdev(dev); - if (i) { - pci_release_regions(pdev); - unregister_netdev(dev); - kfree(dev); - pci_set_drvdata(pdev, NULL); - return i; - } + if (i) + goto err_register_netdev; + netif_carrier_off(dev); if (netif_msg_drv(np)) { @@ -876,6 +867,17 @@ return 0; + + err_register_netdev: + iounmap ((void *) dev->base_addr); + + err_ioremap: + pci_release_regions(pdev); + pci_set_drvdata(pdev, NULL); + + err_pci_request_regions: + free_netdev(dev); + return i; } @@ -1679,15 +1681,16 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int boguscnt = max_interrupt_work; + unsigned int handled = 0; if (np->hands_off) - return; + return IRQ_NONE; do { /* Reading automatically acknowledges all int sources. */ u32 intr_status = readl(ioaddr + IntrStatus); @@ -1700,6 +1703,7 @@ if (intr_status == 0) break; + handled = 1; if (intr_status & (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | @@ -1730,6 +1734,8 @@ if (netif_msg_intr(np)) printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name); + + return IRQ_RETVAL(handled); } /* This routine is logically part of the interrupt handler, but separated @@ -1898,44 +1904,6 @@ return &np->stats; } -/** - * dp83815_crc - computer CRC for hash table entries - * - * Note - this is, for some reason, *not* the same function - * as ether_crc_le() or ether_crc(), though it uses the - * same big-endian polynomial. - */ -#define DP_POLYNOMIAL 0x04C11DB7 -static unsigned dp83815_crc(int length, unsigned char *data) -{ - u32 crc; - u8 cur_byte; - u8 msb; - u8 byte, bit; - - crc = ~0; - for (byte=0; byte> 31; - crc <<= 1; - if (msb ^ (cur_byte & 1)) { - crc ^= DP_POLYNOMIAL; - crc |= 1; - } - cur_byte >>= 1; - } - } - crc >>= 23; - - return (crc); -} - - -void set_bit_le(int offset, unsigned char * data) -{ - data[offset >> 3] |= (1 << (offset & 0x07)); -} #define HASH_TABLE 0x200 static void __set_rx_mode(struct net_device *dev) { @@ -1960,9 +1928,8 @@ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit_le( - dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff, - mc_filter); + int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff; + mc_filter[i/8] |= (1 << (i & 0x07)); } rx_mode = RxFilterEnable | AcceptBroadcast | AcceptMulticast | AcceptMyPhys; @@ -2000,7 +1967,7 @@ strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); info.fw_version[0] = '\0'; - strncpy(info.bus_info, np->pci_dev->slot_name, + strncpy(info.bus_info, pci_name(np->pci_dev), ETHTOOL_BUSINFO_LEN); info.eedump_len = NATSEMI_EEPROM_SIZE; info.regdump_len = NATSEMI_REGS_SIZE; @@ -2585,7 +2552,7 @@ unregister_netdev (dev); pci_release_regions (pdev); iounmap ((char *) dev->base_addr); - kfree (dev); + free_netdev (dev); pci_set_drvdata(pdev, NULL); } @@ -2646,7 +2613,7 @@ if (wol) { /* restart the NIC in WOL mode. * The nic must be stopped for this. - * FIXME: use the WOL interupt + * FIXME: use the WOL interrupt */ enable_wol_mode(dev, 0); } else { diff -urN linux-2.4.24/drivers/net/ns83820.c linux-2.4.25/drivers/net/ns83820.c --- linux-2.4.24/drivers/net/ns83820.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/net/ns83820.c 2004-02-18 05:36:31.000000000 -0800 @@ -1790,7 +1790,7 @@ dev->net_dev.owner = THIS_MODULE; dev->net_dev.priv = dev; - PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev); + INIT_TQUEUE(&dev->tq_refill, queue_refill, dev); tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev); err = pci_enable_device(pci_dev); diff -urN linux-2.4.24/drivers/net/pcmcia/pcnet_cs.c linux-2.4.25/drivers/net/pcmcia/pcnet_cs.c --- linux-2.4.24/drivers/net/pcmcia/pcnet_cs.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/pcmcia/pcnet_cs.c 2004-02-18 05:36:31.000000000 -0800 @@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net - pcnet_cs.c 1.149 2002/06/29 06:27:37 + pcnet_cs.c 1.153 2003/11/09 18:53:09 The network driver code is based on Donald Becker's NE2000 code: @@ -75,7 +75,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.149 2002/06/29 06:27:37 (David Hinds)"; +"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -303,7 +303,8 @@ memset(info, 0, sizeof(*info)); link = &info->link; dev = &info->dev; link->priv = info; - + + init_timer(&link->release); link->release.function = &pcnet_release; link->release.data = (u_long)link; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -895,13 +896,15 @@ MII interface support for DL10019 and DL10022 based cards - On the DL10019, the MII IO direction bit is 0x10; on the DL10022 + On the DL10019, the MII IO direction bit is 0x10; on the DL10022 it is 0x20. Setting both bits seems to work on both card types. ======================================================================*/ #define DLINK_GPIO 0x1c #define DLINK_DIAG 0x1d +#define DLINK_EEPROM 0x1e + #define MDIO_SHIFT_CLK 0x80 #define MDIO_DATA_OUT 0x40 #define MDIO_DIR_WRITE 0x30 @@ -964,6 +967,98 @@ outb_p(0x00, addr); } +/*====================================================================== + + EEPROM access routines for DL10019 and DL10022 based cards + +======================================================================*/ + +#define EE_EEP 0x40 +#define EE_ASIC 0x10 +#define EE_CS 0x08 +#define EE_CK 0x04 +#define EE_DO 0x02 +#define EE_DI 0x01 +#define EE_ADOT 0x01 /* DataOut for ASIC */ +#define EE_READ_CMD 0x06 + +#define DL19FDUPLX 0x0400 /* DL10019 Full duplex mode */ + +static int read_eeprom(ioaddr_t ioaddr, int location) +{ + int i, retval = 0; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + int read_cmd = location | (EE_READ_CMD << 8); + + outb(0, ee_addr); + outb(EE_EEP|EE_CS, ee_addr); + + /* Shift the read command bits out. */ + for (i = 10; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_EEP|EE_CS|dataval, ee_addr); + outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr); + } + outb(EE_EEP|EE_CS, ee_addr); + + for (i = 16; i > 0; i--) { + outb_p(EE_EEP|EE_CS | EE_CK, ee_addr); + retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0); + outb_p(EE_EEP|EE_CS, ee_addr); + } + + /* Terminate the EEPROM access. */ + outb(0, ee_addr); + return retval; +} + +/* + The internal ASIC registers can be changed by EEPROM READ access + with EE_ASIC bit set. + In ASIC mode, EE_ADOT is used to output the data to the ASIC. +*/ + +static void write_asic(ioaddr_t ioaddr, int location, short asic_data) +{ + int i; + ioaddr_t ee_addr = ioaddr + DLINK_EEPROM; + short dataval; + int read_cmd = location | (EE_READ_CMD << 8); + + asic_data |= read_eeprom(ioaddr, location); + + outb(0, ee_addr); + outb(EE_ASIC|EE_CS|EE_DI, ee_addr); + + read_cmd = read_cmd >> 1; + + /* Shift the read command bits out. */ + for (i = 9; i >= 0; i--) { + dataval = (read_cmd & (1 << i)) ? EE_DO : 0; + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); + } + // sync + outb(EE_ASIC|EE_CS, ee_addr); + outb(EE_ASIC|EE_CS|EE_CK, ee_addr); + outb(EE_ASIC|EE_CS, ee_addr); + + for (i = 15; i >= 0; i--) { + dataval = (asic_data & (1 << i)) ? EE_ADOT : 0; + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr); + outb_p(EE_ASIC|EE_CS|dataval, ee_addr); + } + + /* Terminate the ASIC access. */ + outb(EE_ASIC|EE_DI, ee_addr); + outb(EE_ASIC|EE_DI| EE_CK, ee_addr); + outb(EE_ASIC|EE_DI, ee_addr); + + outb(0, ee_addr); +} + /*====================================================================*/ static void set_misc_reg(struct net_device *dev) @@ -1178,6 +1273,9 @@ if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); + } else if (link && (info->flags & IS_DL10019)) { + /* Disable collision detection on full duplex links */ + write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); } if (link) { if (info->phy_id == info->eth_phy) { diff -urN linux-2.4.24/drivers/net/pcmcia/xircom_cb.c linux-2.4.25/drivers/net/pcmcia/xircom_cb.c --- linux-2.4.24/drivers/net/pcmcia/xircom_cb.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/pcmcia/xircom_cb.c 2004-02-18 05:36:31.000000000 -0800 @@ -341,6 +341,11 @@ printk("tx status 0x%08x 0x%08x \n",card->tx_buffer[0],card->tx_buffer[4]); printk("rx status 0x%08x 0x%08x \n",card->rx_buffer[0],card->rx_buffer[4]); #endif + /* Handle shared irq and hotplug */ + if (status == 0 || status == 0xffffffff) { + spin_unlock(&card->lock); + return; + } if (link_status_changed(card)) { int newlink; diff -urN linux-2.4.24/drivers/net/pppoe.c linux-2.4.25/drivers/net/pppoe.c --- linux-2.4.24/drivers/net/pppoe.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/pppoe.c 2004-02-18 05:36:31.000000000 -0800 @@ -365,7 +365,8 @@ if (!__pppoe_xmit( relay_po->sk , skb)) goto abort_put; } else { - sock_queue_rcv_skb(sk, skb); + if (sock_queue_rcv_skb(sk, skb)) + goto abort_kfree; } return NET_RX_SUCCESS; diff -urN linux-2.4.24/drivers/net/sb1250-mac.c linux-2.4.25/drivers/net/sb1250-mac.c --- linux-2.4.24/drivers/net/sb1250-mac.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/net/sb1250-mac.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001,2002,2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,10 +17,10 @@ */ /* - This driver is designed for the Broadcom BCM12500 SOC chip's built-in + This driver is designed for the Broadcom SiByte SOC built-in Ethernet controllers. - The author may be reached as mpl@broadcom.com + Written by Mitch Lichtenberg at Broadcom Corp. */ @@ -31,6 +31,7 @@ These may be modified when a driver module is loaded. */ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int noisy_mii = 1; /* mii status msgs */ /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver @@ -44,8 +45,10 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1}; #endif +#ifdef CONFIG_SBMAC_COALESCE static int int_pktcnt = 0; static int int_timeout = 0; +#endif /* Operational parameters that usually are not changed. */ @@ -74,8 +77,7 @@ #include /* Processor type for cache alignment. */ #include #include -#include -#include +#include /* This is only here until the firmware is ready. In that case, the firmware leaves the ethernet address in the register for us. */ @@ -89,26 +91,29 @@ /* These identify the driver base version and may not be removed. */ #if 0 static char version1[] __devinitdata = -"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg (mpl@broadcom.com)\n"; +"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n"; #endif -MODULE_AUTHOR("Mitch Lichtenberg (mpl@broadcom.com)"); -MODULE_DESCRIPTION("Broadcom BCM12500 SOC GB Ethernet driver"); +MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)"); +MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver"); MODULE_PARM(debug, "i"); +MODULE_PARM(noisy_mii, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(int_pktcnt, "i"); MODULE_PARM(int_timeout, "i"); +#include #include #include #include #include #include -#include /* Only to check SOC part number. */ +#include +#include /********************************************************************** @@ -117,8 +122,6 @@ typedef unsigned long sbmac_port_t; -typedef uint64_t sbmac_physaddr_t; -typedef uint64_t sbmac_enetaddr_t; typedef enum { sbmac_speed_auto, sbmac_speed_10, sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t; @@ -142,17 +145,11 @@ (d)->sbdma_dscrtable : (d)->f+1) -#define CACHELINESIZE 32 -#define NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE) -#define KMALLOC(x) kmalloc((x),GFP_KERNEL) -#define KFREE(x) kfree(x) -#define KVTOPHYS(x) virt_to_bus((void *)(x)) +#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES) +#define SBMAC_READCSR(t) in64((unsigned long)t) +#define SBMAC_WRITECSR(t,v) out64(v, (unsigned long)t) -#define SBMAC_READCSR(t) (in64((unsigned long)(t))) -#define SBMAC_WRITECSR(t,v) (out64(v, (unsigned long)(t))) - -#define PKSEG1(x) ((sbmac_port_t) KSEG1ADDR(x)) #define SBMAC_MAX_TXDESCR 32 #define SBMAC_MAX_RXDESCR 32 @@ -172,7 +169,6 @@ } sbdmadscr_t; typedef unsigned long paddr_t; -typedef unsigned long vaddr_t; /********************************************************************** * DMA Controller structure @@ -190,8 +186,8 @@ int sbdma_txdir; /* direction (1=transmit) */ int sbdma_maxdescr; /* total # of descriptors in ring */ #ifdef CONFIG_SBMAC_COALESCE - int sbdma_int_pktcnt; /* # descriptors rx before interrupt*/ - int sbdma_int_timeout; /* # usec rx interrupt */ + int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt*/ + int sbdma_int_timeout; /* # usec rx/tx interrupt */ #endif sbmac_port_t sbdma_config0; /* DMA config register 0 */ @@ -212,7 +208,6 @@ paddr_t sbdma_dscrtable_phys; /* and also the phys addr */ sbdmadscr_t *sbdma_addptr; /* next dscr for sw to add */ sbdmadscr_t *sbdma_remptr; /* next dscr for sw to remove */ - } sbmacdma_t; @@ -232,10 +227,10 @@ struct net_device_stats sbm_stats; int sbm_devflags; /* current device flags */ - int sbm_phy_oldbmsr; - int sbm_phy_oldanlpar; - int sbm_phy_oldk1stsr; - int sbm_phy_oldlinkstat; + int sbm_phy_oldbmsr; + int sbm_phy_oldanlpar; + int sbm_phy_oldk1stsr; + int sbm_phy_oldlinkstat; int sbm_buffersize; unsigned char sbm_phys[2]; @@ -244,7 +239,7 @@ * Controller-specific things */ - sbmac_port_t sbm_base; /* MAC's base address */ + unsigned long sbm_base; /* MAC's base address */ sbmac_state_t sbm_state; /* current state */ sbmac_port_t sbm_macenable; /* MAC Enable Register */ @@ -260,13 +255,12 @@ sbmac_duplex_t sbm_duplex; /* current duplex */ sbmac_fc_t sbm_fc; /* current flow control setting */ - u_char sbm_hwaddr[ETHER_ADDR_LEN]; + unsigned char sbm_hwaddr[ETHER_ADDR_LEN]; sbmacdma_t sbm_txdma; /* for now, only use channel 0 */ sbmacdma_t sbm_rxdma; int rx_hw_checksum; int sbe_idx; - }; @@ -295,12 +289,11 @@ static void sbmac_channel_stop(struct sbmac_softc *s); static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t); static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff); -/*static void sbmac_init_and_start(struct sbmac_softc *sc);*/ static uint64_t sbmac_addr2reg(unsigned char *ptr); static void sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs); static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); static void sbmac_setmulti(struct sbmac_softc *sc); -static int sbmac_init(struct net_device *dev); +static int sbmac_init(struct net_device *dev, int idx); static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed); static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc); @@ -325,7 +318,6 @@ ********************************************************************* */ static uint64_t sbmac_orig_hwaddr[MAX_UNITS]; -static uint64_t chip_revision; /********************************************************************** @@ -347,8 +339,8 @@ #define BMCR_DUPLEX 0x0100 #define BMCR_COLTEST 0x0080 #define BMCR_SPEED1 0x0040 -#define BMCR_SPEED1000 (BMCR_SPEED1) -#define BMCR_SPEED100 (BMCR_SPEED0) +#define BMCR_SPEED1000 BMCR_SPEED1 +#define BMCR_SPEED100 BMCR_SPEED0 #define BMCR_SPEED10 0 #define BMSR_100BT4 0x8000 @@ -511,7 +503,8 @@ curmask = 1 << (bitcnt - 1); for (i = 0; i < bitcnt; i++) { - if (data & curmask) bits |= M_MAC_MDIO_OUT; + if (data & curmask) + bits |= M_MAC_MDIO_OUT; else bits &= ~M_MAC_MDIO_OUT; SBMAC_WRITECSR(s->sbm_mdio,bits); SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC); @@ -533,7 +526,7 @@ * regidx = index of register to read * * Return value: - * value read, or 0 if an error occured. + * value read, or 0 if an error occurred. ********************************************************************* */ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx) @@ -575,7 +568,7 @@ SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT); /* - * If an error occured, the PHY will signal '1' back + * If an error occurred, the PHY will signal '1' back */ error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN; @@ -592,7 +585,8 @@ regval <<= 1; if (error == 0) { - if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) regval |= 1; + if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) + regval |= 1; } SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC); @@ -602,7 +596,8 @@ /* Switch back to output */ SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT); - if (error == 0) return regval; + if (error == 0) + return regval; return 0; } @@ -672,66 +667,68 @@ d->sbdma_channel = chan; d->sbdma_txdir = txrx; +#if 0 /* RMON clearing */ s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; +#endif - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0); - SBMAC_WRITECSR(PKSEG1( - A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0); /* * initialize register pointers */ d->sbdma_config0 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); d->sbdma_config1 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); d->sbdma_dscrbase = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); d->sbdma_dscrcnt = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); d->sbdma_curdscr = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); /* * Allocate memory for the ring @@ -740,47 +737,39 @@ d->sbdma_maxdescr = maxdescr; d->sbdma_dscrtable = (sbdmadscr_t *) - KMALLOC(d->sbdma_maxdescr*sizeof(sbdmadscr_t)); + kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL); memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t)); d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; - d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable); + d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable); /* * And context table */ d->sbdma_ctxtable = (struct sk_buff **) - KMALLOC(d->sbdma_maxdescr*sizeof(struct sk_buff *)); + kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL); memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *)); #ifdef CONFIG_SBMAC_COALESCE - /* - * Setup Rx DMA coalescing defaults - */ - - if ( txrx == DMA_RX ) { - if ( int_pktcnt ) { - d->sbdma_int_pktcnt = int_pktcnt; - } - else { - d->sbdma_int_pktcnt = 1; - } + /* + * Setup Rx/Tx DMA coalescing defaults + */ - if ( int_timeout ) { - d->sbdma_int_timeout = int_timeout; - } - else { - d->sbdma_int_timeout = 0; - } - } - else { - d->sbdma_int_pktcnt = 0; - d->sbdma_int_timeout = 0; - } + if ( int_pktcnt ) { + d->sbdma_int_pktcnt = int_pktcnt; + } else { + d->sbdma_int_pktcnt = 1; + } + + if ( int_timeout ) { + d->sbdma_int_timeout = int_timeout; + } else { + d->sbdma_int_timeout = 0; + } #endif } @@ -800,43 +789,34 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx ) { - /* - * Turn on the DMA channel - */ + /* + * Turn on the DMA channel + */ #ifdef CONFIG_SBMAC_COALESCE - if (rxtx == DMA_RX) { - SBMAC_WRITECSR(d->sbdma_config1, + SBMAC_WRITECSR(d->sbdma_config1, V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | 0); - SBMAC_WRITECSR(d->sbdma_config0, - M_DMA_EOP_INT_EN | - V_DMA_RINGSZ(d->sbdma_maxdescr) | - V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | - 0); - } - else { - SBMAC_WRITECSR(d->sbdma_config1,0); SBMAC_WRITECSR(d->sbdma_config0, + M_DMA_EOP_INT_EN | V_DMA_RINGSZ(d->sbdma_maxdescr) | + V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | 0); - } #else - SBMAC_WRITECSR(d->sbdma_config1,0); - SBMAC_WRITECSR(d->sbdma_config0, - V_DMA_RINGSZ(d->sbdma_maxdescr) | - 0); + SBMAC_WRITECSR(d->sbdma_config1,0); + SBMAC_WRITECSR(d->sbdma_config0, + V_DMA_RINGSZ(d->sbdma_maxdescr) | + 0); #endif - - SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); - - /* - * Initialize ring pointers - */ - - d->sbdma_addptr = d->sbdma_dscrtable; - d->sbdma_remptr = d->sbdma_dscrtable; + SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); + + /* + * Initialize ring pointers + */ + + d->sbdma_addptr = d->sbdma_dscrtable; + d->sbdma_remptr = d->sbdma_dscrtable; } /********************************************************************** @@ -921,7 +901,7 @@ if (nextdsc == d->sbdma_remptr) { return -ENOSPC; } - + /* * Allocate a sk_buff if we don't already have one. * If we do have an sk_buff, reset it so that it's empty. @@ -935,22 +915,22 @@ * 3. The buffer can be aligned such that the IP addresses are * naturally aligned. * - * Remember, the SB1250's MAC writes whole cache lines at a time, + * Remember, the SOCs MAC writes whole cache lines at a time, * without reading the old contents first. So, if the sk_buff's - * data portion starts in the middle of a cache line, the SB1250 + * data portion starts in the middle of a cache line, the SOC * DMA will trash the beginning (and ending) portions. */ if (sb == NULL) { - sb_new = dev_alloc_skb(ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN); + sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN); if (sb_new == NULL) { printk(KERN_INFO "%s: sk_buff allocation failed\n", d->sbdma_eth->sbm_dev->name); return -ENOBUFS; } - - sbdma_align_skb(sb_new,CACHELINESIZE,ETHER_ALIGN); - + + sbdma_align_skb(sb_new, SMP_CACHE_BYTES, ETHER_ALIGN); + /* mark skbuff owned by our device */ sb_new->dev = d->sbdma_eth->sbm_dev; } @@ -958,7 +938,7 @@ sb_new = sb; /* * nothing special to reinit buffer, it's already aligned - * and sb->tail already points to a good place. + * and sb->data already points to a good place. */ } @@ -967,18 +947,18 @@ */ #ifdef CONFIG_SBMAC_COALESCE - /* - * Do not interrupt per DMA transfer. - */ - dsc->dscr_a = KVTOPHYS(sb_new->tail) | - V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | - 0; + /* + * Do not interrupt per DMA transfer. + */ + dsc->dscr_a = virt_to_phys(sb_new->tail) | + V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | + 0; #else - dsc->dscr_a = KVTOPHYS(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->tail) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | M_DMA_DSCRA_INTERRUPT; #endif - + /* receiving: no options */ dsc->dscr_b = 0; @@ -1057,12 +1037,14 @@ * while doing the calculation. */ - phys = KVTOPHYS(sb->data); - ncb = NUMCACHEBLKS(length+(phys & (CACHELINESIZE-1))); - + phys = virt_to_phys(sb->data); + ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); + dsc->dscr_a = phys | V_DMA_DSCRA_A_SIZE(ncb) | +#ifndef CONFIG_SBMAC_COALESCE M_DMA_DSCRA_INTERRUPT | +#endif M_DMA_ETHTX_SOP; /* transmitting: set outbound options and length */ @@ -1139,7 +1121,8 @@ int idx; for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) { - if (sbdma_add_rcvbuffer(d,NULL) != 0) break; + if (sbdma_add_rcvbuffer(d,NULL) != 0) + break; } } @@ -1190,7 +1173,8 @@ * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1211,49 +1195,47 @@ if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) { /* - * Set length into the packet - */ - skb_put(sb,len); - - /* * Add a new buffer to replace the old one. If we fail * to allocate a buffer, we're going to drop this * packet and put it right back on the receive ring. */ if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) { - sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ - } - else { - /* - * Buffer has been replaced on the receive ring. - * Pass the buffer to the kernel - */ - sc->sbm_stats.rx_bytes += len; - sc->sbm_stats.rx_packets++; - sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); - if (sc->rx_hw_checksum == ENABLE) { - /* if the ip checksum is good indicate in skb. - else set CHECKSUM_NONE as device failed to - checksum the packet */ - - if (((dsc->dscr_b) |M_DMA_ETHRX_BADTCPCS) || - ((dsc->dscr_a)| M_DMA_ETHRX_BADIP4CS)){ - sb->ip_summed = CHECKSUM_NONE; - } else { - printk(KERN_DEBUG "hw checksum fail .\n"); - sb->ip_summed = CHECKSUM_UNNECESSARY; - } - } /*rx_hw_checksum */ - - netif_rx(sb); - } - } - else { + sc->sbm_stats.rx_dropped++; + sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ + } else { + /* + * Set length into the packet + */ + skb_put(sb,len); + + /* + * Buffer has been replaced on the + * receive ring. Pass the buffer to + * the kernel + */ + sc->sbm_stats.rx_bytes += len; + sc->sbm_stats.rx_packets++; + sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); + /* Check hw IPv4/TCP checksum if supported */ + if (sc->rx_hw_checksum == ENABLE) { + if (!((dsc->dscr_a) & M_DMA_ETHRX_BADIP4CS) && + !((dsc->dscr_a) & M_DMA_ETHRX_BADTCPCS)) { + sb->ip_summed = CHECKSUM_UNNECESSARY; + /* don't need to set sb->csum */ + } else { + sb->ip_summed = CHECKSUM_NONE; + } + } + + netif_rx(sb); + } + } else { /* * Packet was mangled somehow. Just drop it and * put it back on the receive ring. */ + sc->sbm_stats.rx_errors++; sbdma_add_rcvbuffer(d,sb); } @@ -1309,36 +1291,17 @@ */ curidx = d->sbdma_remptr - d->sbdma_dscrtable; - { - /* XXX This is gross, ugly, and only here because justin hacked it - in to fix a problem without really understanding it. - - It seems that, for whatever reason, this routine is invoked immediately upon the enabling of interrupts. - So then the Read below returns zero, making hwidx a negative number, and anti-hilarity - ensues. - - I'm guessing there's a proper fix involving clearing out interrupt state from old packets - before enabling interrupts, but I'm not sure. - - Anyways, this hack seems to work, and is Good Enough for 11 PM. :) - - -Justin - */ - - uint64_t tmp = SBMAC_READCSR(d->sbdma_curdscr); - if (!tmp) { - break; - } - hwidx = (int) (((tmp & M_DMA_CURDSCR_ADDR) - - d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); - } + hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - + d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); + /* * If they're the same, that means we've processed all * of the descriptors up to (but not including) the one that * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1405,14 +1368,14 @@ * figure out the addresses of some ports */ - s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE); - s->sbm_maccfg = PKSEG1(s->sbm_base + R_MAC_CFG); - s->sbm_fifocfg = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG); - s->sbm_framecfg = PKSEG1(s->sbm_base + R_MAC_FRAMECFG); - s->sbm_rxfilter = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG); - s->sbm_isr = PKSEG1(s->sbm_base + R_MAC_STATUS); - s->sbm_imr = PKSEG1(s->sbm_base + R_MAC_INT_MASK); - s->sbm_mdio = PKSEG1(s->sbm_base + R_MAC_MDIO); + s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; + s->sbm_maccfg = s->sbm_base + R_MAC_CFG; + s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; + s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; + s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; + s->sbm_isr = s->sbm_base + R_MAC_STATUS; + s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; + s->sbm_mdio = s->sbm_base + R_MAC_MDIO; s->sbm_phys[0] = 1; s->sbm_phys[1] = 0; @@ -1451,12 +1414,12 @@ static void sbdma_uninitctx(struct sbmacdma_s *d) { if (d->sbdma_dscrtable) { - KFREE(d->sbdma_dscrtable); + kfree(d->sbdma_dscrtable); d->sbdma_dscrtable = NULL; } if (d->sbdma_ctxtable) { - KFREE(d->sbdma_ctxtable); + kfree(d->sbdma_ctxtable); d->sbdma_ctxtable = NULL; } } @@ -1486,13 +1449,14 @@ uint64_t reg; sbmac_port_t port; uint64_t cfg,fifo,framecfg; - int idx; + int idx, th_value; /* * Don't do this if running */ - if (s->sbm_state == sbmac_state_on) return; + if (s->sbm_state == sbmac_state_on) + return; /* * Bring the controller out of reset, but leave it off. @@ -1519,31 +1483,35 @@ 0; /* - * Be sure that RD_THRSH+WR_THRSH <= 32 + * Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars + * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above * Use a larger RD_THRSH for gigabit */ + if (periph_rev >= 2) + th_value = 64; + else + th_value = 28; fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ ((s->sbm_speed == sbmac_speed_1000) - ? V_MAC_TX_RD_THRSH(28) : V_MAC_TX_RD_THRSH(4)) | + ? V_MAC_TX_RD_THRSH(th_value) : V_MAC_TX_RD_THRSH(4)) | V_MAC_TX_RL_THRSH(4) | V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RL_THRSH(8) | 0; - + framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | V_MAC_MAX_FRAMESZ_DEFAULT | V_MAC_BACKOFF_SEL(1); - - + /* * Clear out the hash address map */ - port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE); - for (idx = 0; idx < MAC_HASH_COUNT; idx++) { + port = s->sbm_base + R_MAC_HASH_BASE; + for (idx = 0; idx < MAC_HASH_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } @@ -1552,7 +1520,7 @@ * Clear out the exact-match table */ - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1562,14 +1530,14 @@ * Clear out the DMA Channel mapping table registers */ - port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE); + port = s->sbm_base + R_MAC_CHUP0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } - port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE); + port = s->sbm_base + R_MAC_CHLO0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1582,13 +1550,13 @@ reg = sbmac_addr2reg(s->sbm_hwaddr); - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; SBMAC_WRITECSR(port,reg); - port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR); + port = s->sbm_base + R_MAC_ETHERNET_ADDR; #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* - * Pass1 SB1250s do not receive packets addressed to the + * Pass1 SOCs do not receive packets addressed to the * destination address in the R_MAC_ETHERNET_ADDR register. * Set the value to zero. */ @@ -1646,7 +1614,7 @@ * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0 */ SBMAC_WRITECSR(s->sbm_imr, - (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | + ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0)); #else /* @@ -1702,7 +1670,8 @@ { /* don't do this if already stopped */ - if (s->sbm_state == sbmac_state_off) return; + if (s->sbm_state == sbmac_state_off) + return; /* don't accept any packets, disable all interrupts */ @@ -1795,7 +1764,8 @@ { uint64_t reg; - if (sc->sbm_state != sbmac_state_on) return; + if (sc->sbm_state != sbmac_state_on) + return; if (onoff) { reg = SBMAC_READCSR(sc->sbm_rxfilter); @@ -1825,15 +1795,15 @@ { uint64_t reg; - reg = SBMAC_READCSR(sc->sbm_rxfilter); - reg &= ~M_MAC_IPHDR_OFFSET; /* Hard code the off set to 15 for now */ - reg |= 15 << S_MAC_IPHDR_OFFSET; + reg = SBMAC_READCSR(sc->sbm_rxfilter); + reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); SBMAC_WRITECSR(sc->sbm_rxfilter,reg); /* read system identification to determine revision */ - if (sb1250_pass >= K_SYS_REVISION_PASS2) { - printk(KERN_INFO "pass2 - enabling Rx rcv tcp checksum\n"); + if (periph_rev >= 2) { + printk(KERN_INFO "%s: enabling TCP rcv checksum\n", + sc->sbm_dev->name); sc->rx_hw_checksum = ENABLE; } else { sc->rx_hw_checksum = DISABLE; @@ -1841,31 +1811,6 @@ } -#if 0 -/********************************************************************** - * SBMAC_INIT_AND_START(sc) - * - * Stop the channel and restart it. This is generally used - * when we have to do something to the channel that requires - * a swift kick. - * - * Input parameters: - * sc - softc - ********************************************************************* */ - -static void sbmac_init_and_start(struct sbmac_softc *sc) -{ - unsigned long flags; - - spin_lock_irqsave(&(sc->sbm_lock),flags); - - sbmac_set_channel_state(sc,sbmac_state_on); - - spin_unlock_irqrestore(&(sc->sbm_lock),flags); -} -#endif - - /********************************************************************** * SBMAC_ADDR2REG(ptr) * @@ -1927,7 +1872,8 @@ s->sbm_speed = speed; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -1987,7 +1933,6 @@ SBMAC_WRITECSR(s->sbm_maccfg,cfg); return 1; - } /********************************************************************** @@ -2017,7 +1962,8 @@ s->sbm_duplex = duplex; s->sbm_fc = fc; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -2116,7 +2062,8 @@ isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; - if (isr == 0) break; + if (isr == 0) + break; /* * Transmits on channel 0 @@ -2151,7 +2098,6 @@ sbdma_rx_process(sc,&(sc->sbm_rxdma)); } } - } @@ -2224,12 +2170,12 @@ */ for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } for (idx = 0; idx < MAC_HASH_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } @@ -2266,8 +2212,7 @@ mclist = dev->mc_list; while (mclist && (idx < MAC_ADDR_COUNT)) { reg = sbmac_addr2reg(mclist->dmi_addr); - port = PKSEG1(sc->sbm_base + - R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); SBMAC_WRITECSR(port,reg); idx++; mclist = mclist->next; @@ -2304,10 +2249,14 @@ { int digit; - if ((str >= '0') && (str <= '9')) digit = str - '0'; - else if ((str >= 'a') && (str <= 'f')) digit = str - 'a' + 10; - else if ((str >= 'A') && (str <= 'F')) digit = str - 'A' + 10; - else return -1; + if ((str >= '0') && (str <= '9')) + digit = str - '0'; + else if ((str >= 'a') && (str <= 'f')) + digit = str - 'a' + 10; + else if ((str >= 'A') && (str <= 'F')) + digit = str - 'A' + 10; + else + return -1; return digit; } @@ -2326,16 +2275,18 @@ * 0 if ok, else -1 ********************************************************************* */ -static int sbmac_parse_hwaddr(char *str,u_char *hwaddr) +static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr) { int digit1,digit2; int idx = 6; while (*str && (idx > 0)) { digit1 = sbmac_parse_xdigit(*str); - if (digit1 < 0) return -1; + if (digit1 < 0) + return -1; str++; - if (!*str) return -1; + if (!*str) + return -1; if ((*str == ':') || (*str == '-')) { digit2 = digit1; @@ -2343,15 +2294,18 @@ } else { digit2 = sbmac_parse_xdigit(*str); - if (digit2 < 0) return -1; + if (digit2 < 0) + return -1; str++; } *hwaddr++ = (digit1 << 4) | digit2; idx--; - if (*str == '-') str++; - if (*str == ':') str++; + if (*str == '-') + str++; + if (*str == ':') + str++; } return 0; } @@ -2359,11 +2313,11 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) { - if (new_mtu > ENET_PACKET_SIZE) - return -EINVAL; - _dev->mtu = new_mtu; + if (new_mtu > ENET_PACKET_SIZE) + return -EINVAL; + _dev->mtu = new_mtu; printk(KERN_INFO "changing the mtu to %d\n", new_mtu); - return 0; + return 0; } /********************************************************************** @@ -2378,19 +2332,20 @@ * status ********************************************************************* */ -static int sbmac_init(struct net_device *dev) +static int sbmac_init(struct net_device *dev, int idx) { struct sbmac_softc *sc; - u_char *eaddr; + unsigned char *eaddr; uint64_t ea_reg; - int idx; + int i; sc = (struct sbmac_softc *)dev->priv; /* Determine controller base address */ - sc->sbm_base = (sbmac_port_t) dev->base_addr; + sc->sbm_base = KSEG1ADDR(dev->base_addr); sc->sbm_dev = dev; + sc->sbe_idx = idx; eaddr = sc->sbm_hwaddr; @@ -2399,16 +2354,15 @@ * for us in the ethernet address register for each mac. */ - ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR)); - SBMAC_WRITECSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR), 0); - for (idx = 0; idx < 6; idx++) { - eaddr[idx] = (uint8_t) (ea_reg & 0xFF); + ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR); + SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0); + for (i = 0; i < 6; i++) { + eaddr[i] = (uint8_t) (ea_reg & 0xFF); ea_reg >>= 8; } - - for (idx = 0; idx < 6; idx++) { - dev->dev_addr[idx] = eaddr[idx]; + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = eaddr[i]; } @@ -2416,8 +2370,8 @@ * Init packet size */ - sc->sbm_buffersize = ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN; - + sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN; + /* * Initialize context (get pointers to registers and stuff), then * allocate the memory for the descriptor tables. @@ -2427,13 +2381,13 @@ /* - * Display Ethernet address (this is called during the config process - * so we need to finish off the config message that was being displayed) + * Display Ethernet address (this is called during the config + * process so we need to finish off the config message that + * was being displayed) */ printk(KERN_INFO - "%s: SB1250 Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", - dev->name, - (unsigned long) sc->sbm_base, + "%s: SiByte Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", + dev->name, dev->base_addr, eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]); /* @@ -2454,16 +2408,10 @@ dev->change_mtu = sb1250_change_mtu; - if (sb1250_pass >= K_SYS_REVISION_PASS3) { - /* In pass3 we do dumb checksum in TX */ - dev->features |= NETIF_F_IP_CSUM; - } - - /* This is needed for PASS2 for Rx H/W checksum feature */ - sbmac_set_iphdr_offset( sc); + /* This is needed for PASS2 for Rx H/W checksum feature */ + sbmac_set_iphdr_offset(sc); return 0; - } @@ -2478,9 +2426,12 @@ } /* - * map/route interrupt + * map/route interrupt (clear status first, in case something + * weird is pending; we haven't initialized the mac registers + * yet) */ - + + SBMAC_READCSR(sc->sbm_isr); if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev)) { MOD_DEC_USE_COUNT; return -EBUSY; @@ -2490,7 +2441,7 @@ * Configure default speed */ - sbmac_mii_poll(sc,1); + sbmac_mii_poll(sc,noisy_mii); /* * Turn on the channel @@ -2572,7 +2523,8 @@ chg = 1; } - if (chg == 0) return 0; + if (chg == 0) + return 0; p += sprintf(p,"Link speed: "); @@ -2616,9 +2568,6 @@ p += sprintf(p,"Unknown"); } -#ifdef CONFIG_NET_SB1250_MAC_QUIET - noisy = 0; -#endif if (noisy) { printk(KERN_INFO "%s: %s\n",s->sbm_dev->name,buffer); } @@ -2627,8 +2576,6 @@ } - - static void sbmac_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; @@ -2655,19 +2602,19 @@ * Poll the PHY to see what speed we should be running at */ - if (sbmac_mii_poll(sc,1)) { - if (sc->sbm_state != sbmac_state_off) { - /* - * something changed, restart the channel - */ - if (debug > 1) { - printk("%s: restarting channel because speed changed\n", - sc->sbm_dev->name); - } - sbmac_channel_stop(sc); - sbmac_channel_start(sc); + if (sbmac_mii_poll(sc,noisy_mii)) { + if (sc->sbm_state != sbmac_state_off) { + /* + * something changed, restart the channel + */ + if (debug > 1) { + printk("%s: restarting channel because speed changed\n", + sc->sbm_dev->name); + } + sbmac_channel_stop(sc); + sbmac_channel_start(sc); } - } + } spin_unlock_irq (&sc->sbm_lock); @@ -2735,7 +2682,8 @@ spin_unlock_irqrestore(&sc->sbm_lock, flags); if (msg_flag) { - printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", dev->name,(msg_flag==1)?"en":"dis"); + printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", + dev->name,(msg_flag==1)?"en":"dis"); } /* @@ -2786,31 +2734,29 @@ { struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; unsigned long flags; - + sbmac_set_channel_state(sc,sbmac_state_off); - + del_timer_sync(&sc->sbm_timer); - + spin_lock_irqsave(&sc->sbm_lock, flags); - + netif_stop_queue(dev); - + if (debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard\n",dev->name); } - + spin_unlock_irqrestore(&sc->sbm_lock, flags); - - /* Make sure there is no irq-handler running on a different CPU. */ + synchronize_irq(); - free_irq(dev->irq, dev); - + sbdma_emptyring(&(sc->sbm_txdma)); sbdma_emptyring(&(sc->sbm_rxdma)); MOD_DEC_USE_COUNT; - + return 0; } @@ -2827,8 +2773,8 @@ port = A_MAC_CHANNEL_BASE(chan); sbmac_parse_hwaddr(addr,eaddr); val = sbmac_addr2reg(eaddr); - SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR),val); - val = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),val); + val = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); } #endif @@ -2862,15 +2808,15 @@ * Walk through the Ethernet controllers and find * those who have their MAC addresses set. */ - chip_revision = SBMAC_READCSR(PKSEG1(A_SCD_SYSTEM_REVISION)); - switch ((int)G_SYS_PART(chip_revision)) { - case 0x1150: - case 0x1250: + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: chip_max_units = 3; break; - case 0x1120: - case 0x1125: - case 0x1126: + case K_SYS_SOC_TYPE_BCM1120: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ chip_max_units = 2; break; default: @@ -2894,9 +2840,10 @@ * If we find a zero, skip this MAC. */ - sbmac_orig_hwaddr[idx] = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)); + sbmac_orig_hwaddr[idx] = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); if (sbmac_orig_hwaddr[idx] == 0) { - printk( KERN_DEBUG "sbmac: not configuring MAC at %x\n",(uint32_t)port); + printk(KERN_DEBUG "sbmac: not configuring MAC at " + "%lx\n", port); continue; } @@ -2908,15 +2855,16 @@ if (!dev) return -ENOMEM; /* return ENOMEM */ + printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); + dev->irq = K_INT_MAC_0 + idx; dev->base_addr = port; dev->mem_end = 0; /*dev->init = sbmac_init;*/ - sbmac_init(dev); + sbmac_init(dev, macidx); dev_sbmac[macidx] = dev; macidx++; - } /* @@ -2935,7 +2883,8 @@ sbmac_port_t port; for (idx = 0; idx < MAX_UNITS; idx++) { dev = dev_sbmac[idx]; - if (dev == NULL) continue; + if (dev == NULL) + continue; if (dev->priv != NULL) { struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv; @@ -2946,8 +2895,8 @@ } port = A_MAC_CHANNEL_BASE(idx); - SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] ); - KFREE(dev); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] ); + kfree(dev); dev_sbmac[idx] = NULL; } } diff -urN linux-2.4.24/drivers/net/sgiseeq.c linux-2.4.25/drivers/net/sgiseeq.c --- linux-2.4.24/drivers/net/sgiseeq.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/net/sgiseeq.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,51 +5,45 @@ */ #include #include -#include +#include +#include #include #include -#include #include +#include #include +#include #include #include #include +#include +#include +#include +#include #include -#include #include #include #include #include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include +#include +#include #include #include "sgiseeq.h" -static char *version = - "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n"; +static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n"; static char *sgiseeqstr = "SGI Seeq8003"; -/* If you want speed, you do something silly, it always has worked - * for me. So, with that in mind, I've decided to make this driver - * look completely like a stupid Lance from a driver architecture - * perspective. Only difference is that here our "ring buffer" looks - * and acts like a real Lance one does but is layed out like how the - * HPC DMA and the Seeq want it to. You'd be surprised how a stupid - * idea like this can pay off in performance, not to mention making - * this driver 2,000 times easier to write. ;-) +/* + * If you want speed, you do something silly, it always has worked for me. So, + * with that in mind, I've decided to make this driver look completely like a + * stupid Lance from a driver architecture perspective. Only difference is that + * here our "ring buffer" looks and acts like a real Lance one does but is + * layed out like how the HPC DMA and the Seeq want it to. You'd be surprised + * how a stupid idea like this can pay off in performance, not to mention + * making this driver 2,000 times easier to write. ;-) */ /* Tune these if we tend to run out often etc. */ @@ -79,9 +73,10 @@ signed int buf_vaddr; }; -/* Warning: This structure is layed out in a certain way because - * HPC dma descriptors must be 8-byte aligned. So don't - * touch this without some care. +/* + * Warning: This structure is layed out in a certain way because HPC dma + * descriptors must be 8-byte aligned. So don't touch this without + * some care. */ struct sgiseeq_init_block { /* Note the name ;-) */ /* Ptrs to the descriptors in KSEG1 uncached space. */ @@ -96,8 +91,8 @@ struct sgiseeq_private { volatile struct sgiseeq_init_block srings; char *name; - volatile struct hpc3_ethregs *hregs; - volatile struct sgiseeq_regs *sregs; + struct hpc3_ethregs *hregs; + struct sgiseeq_regs *sregs; /* Ring entry counters. */ unsigned int rx_new, tx_new; @@ -108,17 +103,23 @@ unsigned char mode; struct net_device_stats stats; + + struct net_device *next_module; + spinlock_t tx_lock; }; -static inline void hpc3_eth_reset(volatile struct hpc3_ethregs *hregs) +/* A list of all installed seeq devices, for removing the driver module. */ +static struct net_device *root_sgiseeq_dev; + +static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) { - hregs->rx_reset = (HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ); + hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ; udelay(20); hregs->rx_reset = 0; } -static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) +static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { hregs->rx_ctrl = hregs->tx_ctrl = 0; hpc3_eth_reset(hregs); @@ -128,15 +129,15 @@ SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC) static inline void seeq_go(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { sregs->rstat = sp->mode | RSTAT_GO_BITS; hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; } static inline void seeq_load_eaddr(struct net_device *dev, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { int i; @@ -169,7 +170,7 @@ /* Setup tx ring. */ for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - if(!ib->tx_desc[i].tdma.pbuf) { + if (!ib->tx_desc[i].tdma.pbuf) { unsigned long buffer; buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); @@ -177,9 +178,8 @@ return -ENOMEM; ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } - ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT); + ib->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; } /* And now the rx ring. */ @@ -192,11 +192,10 @@ return -ENOMEM; ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } - ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT); + ib->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; } - ib->rx_desc[i - 1].rdma.cntinfo |= (HPCDMA_EOR); + ib->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; return 0; } @@ -209,10 +208,10 @@ static int once; struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc; struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc; - volatile struct hpc3_ethregs *hregs = gpriv->hregs; + struct hpc3_ethregs *hregs = gpriv->hregs; int i; - if(once) + if (once) return; once++; printk("RING DUMP:\n"); @@ -248,9 +247,9 @@ #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; int err; reset_hpc3_and_seeq(hregs, sregs); @@ -260,11 +259,11 @@ /* Setup to field the proper interrupt types. */ if (sp->is_edlc) { - sregs->tstat = (TSTAT_INIT_EDLC); + sregs->tstat = TSTAT_INIT_EDLC; sregs->rw.wregs.control = sp->control; sregs->rw.wregs.frame_gap = 0; } else { - sregs->tstat = (TSTAT_INIT_SEEQ); + sregs->tstat = TSTAT_INIT_SEEQ; } hregs->rx_dconfig |= RDMACFG_INIT; @@ -291,8 +290,8 @@ } static inline void rx_maybe_restart(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]); @@ -305,8 +304,8 @@ (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; struct sk_buff *skb = 0; @@ -317,7 +316,7 @@ /* Service every received packet. */ for_each_rx(rd, sp) { - len = (PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3); + len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3; pkt_pointer = (unsigned char *)(long)rd->buf_vaddr; pkt_status = pkt_pointer[len + 2]; @@ -338,7 +337,7 @@ sp->stats.rx_packets++; sp->stats.rx_bytes += len; } else { - printk ("%s: Memory squeeze, deferring packet.\n", + printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", dev->name); sp->stats.rx_dropped++; } @@ -347,7 +346,7 @@ } /* Return the entry to the ring pool. */ - rd->rdma.cntinfo = (RCNTINFO_INIT); + rd->rdma.cntinfo = RCNTINFO_INIT; sp->rx_new = NEXT_RX(sp->rx_new); } sp->srings.rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); @@ -356,7 +355,7 @@ } static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { if (sp->is_edlc) { sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT); @@ -365,7 +364,7 @@ } static inline void kick_tx(struct sgiseeq_tx_desc *td, - volatile struct hpc3_ethregs *hregs) + struct hpc3_ethregs *hregs) { /* If the HPC aint doin nothin, and there are more packets * with ETXD cleared and XIU set we must make very certain @@ -383,8 +382,8 @@ } static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_tx_desc *td; unsigned long status = hregs->tx_ctrl; @@ -409,7 +408,7 @@ if (!(td->tdma.cntinfo & (HPCDMA_XIU))) break; if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) { - if(!(status & HPC3_ETXCTRL_ACTIVE)) { + if (!(status & HPC3_ETXCTRL_ACTIVE)) { hregs->tx_ndptr = PHYSADDR(td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } @@ -426,8 +425,10 @@ { struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct hpc3_ethregs *hregs = sp->hregs; + struct sgiseeq_regs *sregs = sp->sregs; + + spin_lock(&sp->tx_lock); /* Ack the IRQ and set software state. */ hregs->rx_reset = HPC3_ERXRST_CLRIRQ; @@ -435,59 +436,47 @@ /* Always check for received packets. */ sgiseeq_rx(dev, sp, hregs, sregs); - /* Only check for tx acks iff we have something queued. */ + /* Only check for tx acks if we have something queued. */ if (sp->tx_old != sp->tx_new) sgiseeq_tx(dev, sp, hregs, sregs); if ((TX_BUFFS_AVAIL(sp) > 0) && netif_queue_stopped(dev)) { netif_wake_queue(dev); } + spin_unlock(&sp->tx_lock); } static int sgiseeq_open(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; - unsigned long flags; - int err; - - __save_and_cli(flags); + struct sgiseeq_regs *sregs = sp->sregs; - err = -EAGAIN; - if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { - printk("Seeq8003: Can't get irq %d\n", dev->irq); - goto out; - } - err = init_seeq(dev, sp, sregs); + int err = init_seeq(dev, sp, sregs); if (err) - goto out; + return err; netif_start_queue(dev); -out: - __restore_flags(flags); - return err; + return 0; } static int sgiseeq_close(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; netif_stop_queue(dev); /* Shutdown the Seeq. */ reset_hpc3_and_seeq(sp->hregs, sregs); - free_irq(dev->irq, dev); - return 0; } static inline int sgiseeq_reset(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; int err; err = init_seeq(dev, sp, sregs); @@ -509,12 +498,12 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; int skblen, len, entry; - save_and_cli(flags); + spin_lock_irqsave(&sp->tx_lock, flags); /* Setup... */ skblen = skb->len; @@ -530,22 +519,22 @@ * 2) Do no allow the HPC to look at a new descriptor until * we have completely set up it's state. This means, do * not clear HPCDMA_EOX in the current last descritptor - * until the one we are adding looks consistant and could + * until the one we are adding looks consistent and could * be processes right now. * 3) The tx interrupt code must notice when we've added a new * entry and the HPC got to the end of the chain before we * added this new entry and restarted it. */ memcpy((char *)(long)td->buf_vaddr, skb->data, skblen); - if(len != skblen) + if (len != skblen) memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen); td->tdma.cntinfo = (len & HPCDMA_BCNT) | - (HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX); + HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX; if (sp->tx_old != sp->tx_new) { struct sgiseeq_tx_desc *backend; backend = &sp->srings.tx_desc[PREV_TX(sp->tx_new)]; - backend->tdma.cntinfo &= ~(HPCDMA_EOX); + backend->tdma.cntinfo &= ~HPCDMA_EOX; } sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */ @@ -558,14 +547,14 @@ if (!TX_BUFFS_AVAIL(sp)) netif_stop_queue(dev); - restore_flags(flags); + spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; } static void timeout(struct net_device *dev) { - printk("%s: transmit timed out, resetting\n", dev->name); + printk(KERN_NOTICE "%s: transmit timed out, resetting\n", dev->name); sgiseeq_reset(dev); dev->trans_start = jiffies; @@ -608,49 +597,56 @@ buf[i].rdma.pnext = PHYSADDR(&buf[0]); } -static char onboard_eth_addr[6]; - #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, - struct hpc3_ethregs *hregs, int irq) +int sgiseeq_init(struct hpc3_regs* regs, int irq) { - static unsigned version_printed; - int i; + struct net_device *dev; struct sgiseeq_private *sp; + int err, i; - dev->priv = (struct sgiseeq_private *) get_free_page(GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - - if (!version_printed++) - printk(version); - - printk("%s: SGI Seeq8003 ", dev->name); + dev = alloc_etherdev(0); + if (!dev) { + printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); + err = -ENOMEM; + goto err_out; + } + /* Make private data page aligned */ + sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); + if (!sp) { + printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n"); + err = -ENOMEM; + goto err_out_free_dev; + } + + if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { + printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq); + err = -EAGAIN; + goto err_out_free_page; + } + +#define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { + unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); - for (i = 0; i < 6; i++) - printk("%2.2x%c", - dev->dev_addr[i] = onboard_eth_addr[i], - i == 5 ? ' ': ':'); - - printk("\n"); + dev->dev_addr[2 * i] = tmp >> 8; + dev->dev_addr[2 * i + 1] = tmp & 0xff; + } - sp = (struct sgiseeq_private *) dev->priv; #ifdef DEBUG gpriv = sp; gdev = dev; #endif - memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private)); - sp->sregs = sregs; - sp->hregs = hregs; + sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0]; + sp->hregs = &hpc3c0->ethregs; sp->name = sgiseeqstr; sp->srings.rx_desc = (struct sgiseeq_rx_desc *) - (KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0]))); + KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])); dma_cache_wback_inv((unsigned long)&sp->srings.rxvector, sizeof(sp->srings.rxvector)); sp->srings.tx_desc = (struct sgiseeq_tx_desc *) - (KSEG1ADDR(ALIGNED(&sp->srings.txvector[0]))); + KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])); dma_cache_wback_inv((unsigned long)&sp->srings.txvector, sizeof(sp->srings.txvector)); @@ -659,71 +655,78 @@ setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); /* Reset the chip. */ - hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs); + hpc3_eth_reset(sp->hregs); - sp->is_edlc = !(sregs->rw.rregs.collision_tx[0] & 0xff); - if (sp->is_edlc) { - sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | - SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | - SEEQ_CTRL_ENCARR); + sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff); + if (sp->is_edlc) + sp->control = SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | + SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | + SEEQ_CTRL_ENCARR; + + dev->open = sgiseeq_open; + dev->stop = sgiseeq_close; + dev->hard_start_xmit = sgiseeq_start_xmit; + dev->tx_timeout = timeout; + dev->watchdog_timeo = (200 * HZ) / 1000; + dev->get_stats = sgiseeq_get_stats; + dev->set_multicast_list = sgiseeq_set_multicast; + dev->irq = irq; + dev->dma = 0; + dev->priv = sp; + + if (register_netdev(dev)) { + printk(KERN_ERR "Sgiseeq: Cannot register net device, " + "aborting.\n"); + err = -ENODEV; + goto err_out_free_irq; } - dev->open = sgiseeq_open; - dev->stop = sgiseeq_close; - dev->hard_start_xmit = sgiseeq_start_xmit; - dev->tx_timeout = timeout; - dev->watchdog_timeo = (200 * HZ) / 1000; - dev->get_stats = sgiseeq_get_stats; - dev->set_multicast_list = sgiseeq_set_multicast; - dev->irq = irq; - dev->dma = 0; - ether_setup(dev); + printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name); + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + + sp->next_module = root_sgiseeq_dev; + root_sgiseeq_dev = dev; return 0; -} -static inline unsigned char str2hexnum(unsigned char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ +err_out_free_irq: + free_irq(irq, dev); +err_out_free_page: + free_page((unsigned long) sp); +err_out_free_dev: + kfree(dev); + +err_out: + return err; } -static inline void str2eaddr(unsigned char *ea, unsigned char *str) +static int __init sgiseeq_probe(void) { - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; + printk(version); - if(*str == ':') - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } + /* On board adapter on 1st HPC is always present */ + return sgiseeq_init(hpc3c0, SGI_ENET_IRQ); } -int sgiseeq_probe(struct net_device *dev) +static void __exit sgiseeq_exit(void) { - static int initialized; - char *ep; - - if (initialized) /* Already initialized? */ - return 1; - initialized++; + struct net_device *next, *dev; + struct sgiseeq_private *sp; + int irq; - /* First get the ethernet address of the onboard interface from ARCS. - * This is fragile; PROM doesn't like running from cache. - * On MIPS64 it crashes for some other, yet unknown reason ... - */ - ep = ArcGetEnvironmentVariable("eaddr"); - str2eaddr(onboard_eth_addr, ep); - return sgiseeq_init(dev, - (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)), - &hpc3c0->ethregs, SGI_ENET_IRQ); + for (dev = root_sgiseeq_dev; dev; dev = next) { + sp = (struct sgiseeq_private *) dev->priv; + next = sp->next_module; + irq = dev->irq; + unregister_netdev(dev); + free_irq(irq, dev); + free_page((unsigned long) dev->priv); + kfree(dev); + } } +module_init(sgiseeq_probe); +module_exit(sgiseeq_exit); + MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/net/sk98lin/Makefile linux-2.4.25/drivers/net/sk98lin/Makefile --- linux-2.4.24/drivers/net/sk98lin/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -78,7 +78,7 @@ # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources # SK_DBGCAT_DRV_EVENT 0x08000000 driver events -EXTRA_CFLAGS += -I. -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) +EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/drivers/net/sk98lin/h/skcsum.h linux-2.4.25/drivers/net/sk98lin/h/skcsum.h --- linux-2.4.24/drivers/net/sk98lin/h/skcsum.h 2001-07-04 11:50:39.000000000 -0700 +++ linux-2.4.25/drivers/net/sk98lin/h/skcsum.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skcsum.h * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) - * Version: $Revision: 1.9 $ - * Date: $Date: 2001/02/06 11:21:39 $ + * Version: $Revision: 1.10 $ + * Date: $Date: 2003/08/20 13:59:57 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -26,6 +26,10 @@ * History: * * $Log: skcsum.h,v $ + * Revision 1.10 2003/08/20 13:59:57 mschmid + * Changed notation of #ifndef SkCsCalculateChecksum to + * #ifndef SK_CS_CALCULATE_CHECKSUM + * * Revision 1.9 2001/02/06 11:21:39 rassmann * Editorial changes. * @@ -226,11 +230,11 @@ /* function prototypes ********************************************************/ -#ifndef SkCsCalculateChecksum +#ifndef SK_CS_CALCULATE_CHECKSUM extern unsigned SkCsCalculateChecksum( void *pData, unsigned Length); -#endif +#endif /* SK_CS_CALCULATE_CHECKSUM */ extern int SkCsEvent( SK_AC *pAc, diff -urN linux-2.4.24/drivers/net/sk98lin/h/skdrv1st.h linux-2.4.25/drivers/net/sk98lin/h/skdrv1st.h --- linux-2.4.24/drivers/net/sk98lin/h/skdrv1st.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skdrv1st.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,15 +2,16 @@ * * Name: skdrv1st.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2003/07/21 07:22:43 $ + * Version: $Revision: 1.4 $ + * Date: $Date: 2003/11/12 14:28:14 $ * Purpose: First header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,15 @@ * History: * * $Log: skdrv1st.h,v $ + * Revision 1.4 2003/11/12 14:28:14 rroesler + * Fix: use dedicated ip_fast_csum() on X86_64 systems + * + * Revision 1.3 2003/10/07 08:16:52 mlindner + * Fix: Copyright changes + * + * Revision 1.2 2003/09/29 12:05:59 mlindner + * Fix: Added define SK_CS_CALCULSTE_CHECKSUM + * * Revision 1.1 2003/07/21 07:22:43 rroesler * Fix: Re-Enter after CVS crash * @@ -127,11 +137,8 @@ #define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4) #define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8) -#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) - #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) - #if !defined(__OPTIMIZE__) || !defined(__KERNEL__) #warning You must compile this file with the correct options! #warning See the last lines of the source file. @@ -158,6 +165,13 @@ #include #include +#define SK_CS_CALCULATE_CHECKSUM +#ifndef CONFIG_X86_64 +#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) +#else +#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff) +#endif + #include "h/sktypes.h" #include "h/skerror.h" #include "h/skdebug.h" diff -urN linux-2.4.24/drivers/net/sk98lin/h/skdrv2nd.h linux-2.4.25/drivers/net/sk98lin/h/skdrv2nd.h --- linux-2.4.24/drivers/net/sk98lin/h/skdrv2nd.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skdrv2nd.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,15 +2,16 @@ * * Name: skdrv2nd.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.3 $ - * Date: $Date: 2003/08/12 16:51:18 $ + * Version: $Revision: 1.10 $ + * Date: $Date: 2003/12/11 16:04:45 $ * Purpose: Second header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,27 @@ * History: * * $Log: skdrv2nd.h,v $ + * Revision 1.10 2003/12/11 16:04:45 mlindner + * Add: New pnmi data backup structure + * + * Revision 1.9 2003/11/10 09:31:37 rroesler + * Add: pnmiBackup structure for DIAG backup restore + * + * Revision 1.8 2003/10/22 14:18:32 rroesler + * Fix: DIAG handling for DualNet cards + * + * Revision 1.7 2003/10/07 09:34:59 mlindner + * Add: New defines for lower and upper range values (interrupt moderation) + * + * Revision 1.6 2003/10/07 08:16:51 mlindner + * Fix: Copyright changes + * + * Revision 1.5 2003/09/01 13:10:39 rroesler + * Add: Prototypes for DIAG Attach/Detach functions + * + * Revision 1.4 2003/09/01 12:33:38 rroesler + * Add: Defines for optimized DIAG interaction + * * Revision 1.3 2003/08/12 16:51:18 mlindner * Fix: UDP and TCP Proto checks * Fix: UDP header offset @@ -206,6 +228,11 @@ extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); +#ifdef SK_DIAG_SUPPORT +extern int SkDrvEnterDiagMode(SK_AC *pAc); +extern int SkDrvLeaveDiagMode(SK_AC *pAc); +#endif + struct s_DrvRlmtMbuf { SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ SK_U8 *pData; /* Data buffer (virtually contig.). */ @@ -247,6 +274,7 @@ #define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) #define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) #define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) +#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) typedef struct s_IOCTL SK_GE_IOCTL; @@ -462,6 +490,9 @@ #define C_INTS_PER_SEC_DEFAULT 2000 #define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */ #define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */ +#define C_INT_MOD_IPS_LOWER_RANGE 30 +#define C_INT_MOD_IPS_UPPER_RANGE 40000 + typedef struct s_DynIrqModInfo DIM_INFO; struct s_DynIrqModInfo { @@ -493,6 +524,11 @@ #define SK_ALLOC_IRQ 0x00000001 +#ifdef SK_DIAG_SUPPORT +#define DIAG_ACTIVE 1 +#define DIAG_NOTACTIVE 0 +#endif + /**************************************************************************** * Per board structure / Adapter Context structure: * Allocated within attach(9e) and freed within detach(9e). @@ -563,9 +599,18 @@ int PortUp; int PortDown; int ChipsetType; /* Chipset family type - * 0 == Genesis family support - * 1 == Yukon family support - */ + * 0 == Genesis family support + * 1 == Yukon family support + */ +#ifdef SK_DIAG_SUPPORT + SK_U32 DiagModeActive; /* is diag active? */ + SK_BOOL DiagFlowCtrl; /* for control purposes */ + SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */ + SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while + * DIAG is busy with NIC + */ +#endif + }; diff -urN linux-2.4.24/drivers/net/sk98lin/h/skgehw.h linux-2.4.25/drivers/net/sk98lin/h/skgehw.h --- linux-2.4.24/drivers/net/sk98lin/h/skgehw.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skgehw.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgehw.h * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.53 $ - * Date: $Date: 2003/07/04 12:39:01 $ + * Version: $Revision: 1.56 $ + * Date: $Date: 2003/09/23 09:01:00 $ * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family * ******************************************************************************/ @@ -26,6 +26,17 @@ * * History: * $Log: skgehw.h,v $ + * Revision 1.56 2003/09/23 09:01:00 malthoff + * Minor change: Define I2C device size constants as long. + * + * Revision 1.55 2003/09/16 14:03:34 rschmidt + * Added define for YUKON-Lite Rev. A1,A2 Chip Revision + * Moved defines for PHY power down modes to skgeinit.h + * Editorial changes + * + * Revision 1.54 2003/09/16 07:37:58 mschmid + * Added defines for Marvell PHY low power modes + * * Revision 1.53 2003/07/04 12:39:01 rschmidt * Added SK_FAR to pointers in XM_IN32() and GM_IN32() macros (for PXE) * Editorial changes @@ -84,7 +95,7 @@ * Editorial changes * * Revision 1.39 2002/06/10 09:37:07 rschmidt - * Added macros for the ADDR-Modul + * Added macros for the ADDR-Module * * Revision 1.38 2002/06/05 08:15:19 rschmidt * Added defines for WOL Registers @@ -628,12 +639,12 @@ #define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ #define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */ /* 0x0125 - 0x0127: reserved */ -#define B2_LD_CRTL 0x0128 /* 8 bit EPROM loader control register */ +#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */ #define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */ /* 0x012a - 0x012f: reserved */ #define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */ #define B2_TI_VAL 0x0134 /* 32 bit Timer Value */ -#define B2_TI_CRTL 0x0138 /* 8 bit Timer Control */ +#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */ #define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */ /* 0x013a - 0x013f: reserved */ #define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/ @@ -1021,7 +1032,7 @@ /* Bit 7: reserved */ #define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ -/* B0_CTST 16 bit Control/Status register */ +/* B0_CTST 16 bit Control/Status register */ /* Bit 15..14: reserved */ #define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */ #define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */ @@ -1038,7 +1049,7 @@ #define CS_RST_CLR BIT_1S /* Clear Software reset */ #define CS_RST_SET BIT_0S /* Set Software reset */ -/* B0_LED 8 Bit LED register */ +/* B0_LED 8 Bit LED register */ /* Bit 7.. 2: reserved */ #define LED_STAT_ON BIT_1S /* Status LED on */ #define LED_STAT_OFF BIT_0S /* Status LED off */ @@ -1053,9 +1064,9 @@ #define PC_VCC_ON BIT_1 /* Switch VCC On */ #define PC_VCC_OFF BIT_0 /* Switch VCC Off */ -/* B0_ISRC 32 bit Interrupt Source Register */ -/* B0_IMSK 32 bit Interrupt Mask Register */ -/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ +/* B0_ISRC 32 bit Interrupt Source Register */ +/* B0_IMSK 32 bit Interrupt Mask Register */ +/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ /* B2_IRQM_MSK 32 bit IRQ Moderation Mask */ #define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */ #define IS_HW_ERR BIT_31 /* Interrupt HW Error */ @@ -1099,9 +1110,9 @@ #define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ -/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ -/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ -/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ +/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ +/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ +/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ #define IS_ERR_MSK 0x00000fffL /* All Error bits */ /* Bit 31..14: reserved */ #define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */ @@ -1119,29 +1130,32 @@ #define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ #define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ -/* B2_CONN_TYP 8 bit Connector type */ -/* B2_PMD_TYP 8 bit PMD type */ +/* B2_CONN_TYP 8 bit Connector type */ +/* B2_PMD_TYP 8 bit PMD type */ /* Values of connector and PMD type comply to SysKonnect internal std */ -/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ +/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ #define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */ /* Bit 3.. 2: reserved */ #define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */ #define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/ -/* B2_CHIP_ID 8 bit Chip Identification Number */ +/* B2_CHIP_ID 8 bit Chip Identification Number */ #define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ #define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ -#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1) */ +#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */ #define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */ -/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ +#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */ +#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */ + +/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ #define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ -/* B2_LD_CRTL 8 bit EPROM loader control register */ +/* B2_LD_CTRL 8 bit EPROM loader control register */ /* Bits are currently reserved */ -/* B2_LD_TEST 8 bit EPROM loader test register */ +/* B2_LD_TEST 8 bit EPROM loader test register */ /* Bit 7.. 4: reserved */ #define LD_T_ON BIT_3S /* Loader Test mode on */ #define LD_T_OFF BIT_2S /* Loader Test mode off */ @@ -1151,16 +1165,16 @@ /* * Timer Section */ -/* B2_TI_CRTL 8 bit Timer control */ +/* B2_TI_CTRL 8 bit Timer control */ /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ /* Bit 7.. 3: reserved */ #define TIM_START BIT_2S /* Start Timer */ #define TIM_STOP BIT_1S /* Stop Timer */ #define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */ -/* B2_TI_TEST 8 Bit Timer Test */ +/* B2_TI_TEST 8 Bit Timer Test */ /* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */ -/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ +/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ /* Bit 7.. 3: reserved */ #define TIM_T_ON BIT_2S /* Test mode on */ #define TIM_T_OFF BIT_1S /* Test mode off */ @@ -1197,7 +1211,7 @@ #define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */ #define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */ -/* B2_GP_IO 32 bit General Purpose I/O Register */ +/* B2_GP_IO 32 bit General Purpose I/O Register */ /* Bit 31..26: reserved */ #define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */ #define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */ @@ -1221,28 +1235,28 @@ #define GP_IO_1 BIT_1 /* IO_1 pin */ #define GP_IO_0 BIT_0 /* IO_0 pin */ -/* B2_I2C_CTRL 32 bit I2C HW Control Register */ +/* B2_I2C_CTRL 32 bit I2C HW Control Register */ #define I2C_FLAG BIT_31 /* Start read/write if WR */ #define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ #define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ /* Bit 8.. 5: reserved */ #define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */ -#define I2C_DEV_SIZE (7L<<1) /* Bit 3.. 1: I2C Device Size */ -#define I2C_025K_DEV (0L<<1) /* 0: 256 Bytes or smal. */ -#define I2C_05K_DEV (1L<<1) /* 1: 512 Bytes */ -#define I2C_1K_DEV (2L<<1) /* 2: 1024 Bytes */ -#define I2C_2K_DEV (3L<<1) /* 3: 2048 Bytes */ -#define I2C_4K_DEV (4L<<1) /* 4: 4096 Bytes */ -#define I2C_8K_DEV (5L<<1) /* 5: 8192 Bytes */ -#define I2C_16K_DEV (6L<<1) /* 6: 16384 Bytes */ -#define I2C_32K_DEV (7L<<1) /* 7: 32768 Bytes */ +#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ +#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */ +#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */ +#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */ +#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */ +#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */ +#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */ +#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */ +#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */ #define I2C_STOP BIT_0 /* Interrupt I2C transfer */ -/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ +/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ /* Bit 31.. 1 reserved */ #define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */ -/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ +/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ /* Bit 7.. 3: reserved */ #define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */ #define I2C_DATA BIT_1S /* I2C Data Port */ @@ -1254,27 +1268,27 @@ #define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ -/* B2_BSC_CTRL 8 bit Blink Source Counter Control */ +/* B2_BSC_CTRL 8 bit Blink Source Counter Control */ /* Bit 7.. 2: reserved */ #define BSC_START BIT_1S /* Start Blink Source Counter */ #define BSC_STOP BIT_0S /* Stop Blink Source Counter */ -/* B2_BSC_STAT 8 bit Blink Source Counter Status */ +/* B2_BSC_STAT 8 bit Blink Source Counter Status */ /* Bit 7.. 1: reserved */ #define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */ -/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ +/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ #define BSC_T_ON BIT_2S /* Test mode on */ #define BSC_T_OFF BIT_1S /* Test mode off */ #define BSC_T_STEP BIT_0S /* Test step */ -/* B3_RAM_ADDR 32 bit RAM Address, to read or write */ +/* B3_RAM_ADDR 32 bit RAM Address, to read or write */ /* Bit 31..19: reserved */ #define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */ /* RAM Interface Registers */ -/* B3_RI_CTRL 16 bit RAM Iface Control Register */ +/* B3_RI_CTRL 16 bit RAM Iface Control Register */ /* Bit 15..10: reserved */ #define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ #define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/ @@ -1282,7 +1296,7 @@ #define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */ #define RI_RST_SET BIT_0S /* Set RAM Interface Reset */ -/* B3_RI_TEST 8 bit RAM Iface Test Register */ +/* B3_RI_TEST 8 bit RAM Iface Test Register */ /* Bit 15.. 4: reserved */ #define RI_T_EV BIT_3S /* Timeout Event occured */ #define RI_T_ON BIT_2S /* Timeout Timer Test On */ @@ -1309,7 +1323,7 @@ #define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */ /* Packet Arbiter Registers */ -/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ +/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ /* Bit 15..14: reserved */ #define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */ #define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */ @@ -1332,7 +1346,7 @@ /* Rx/Tx Path related Arbiter Test Registers */ /* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ /* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ -/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ +/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ /* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ #define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */ #define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */ @@ -1353,14 +1367,14 @@ /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ -/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ -/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ -/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ -/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ +/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ +/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ +/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ +/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ /* Bit 31..24: reserved */ #define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */ -/* TXA_CTRL 8 bit Tx Arbiter Control Register */ +/* TXA_CTRL 8 bit Tx Arbiter Control Register */ #define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */ #define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */ #define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */ @@ -1370,7 +1384,7 @@ #define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */ #define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */ -/* TXA_TEST 8 bit Tx Arbiter Test Register */ +/* TXA_TEST 8 bit Tx Arbiter Test Register */ /* Bit 7.. 6: reserved */ #define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */ #define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */ @@ -1379,22 +1393,22 @@ #define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */ #define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */ -/* TXA_STAT 8 bit Tx Arbiter Status Register */ +/* TXA_STAT 8 bit Tx Arbiter Status Register */ /* Bit 7.. 1: reserved */ #define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */ -/* Q_BC 32 bit Current Byte Counter */ +/* Q_BC 32 bit Current Byte Counter */ /* Bit 31..16: reserved */ #define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ /* BMU Control Status Registers */ -/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ -/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ -/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ -/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ -/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ -/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ -/* Q_CSR 32 bit BMU Control/Status Register */ +/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ +/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ +/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ +/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ +/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ +/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ +/* Q_CSR 32 bit BMU Control/Status Register */ /* Bit 31..25: reserved */ #define CSR_SV_IDLE BIT_24 /* BMU SM Idle */ /* Bit 23..22: reserved */ @@ -1428,7 +1442,7 @@ CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ CSR_TRANS_RUN) -/* Q_F 32 bit Flag Register */ +/* Q_F 32 bit Flag Register */ /* Bit 31..28: reserved */ #define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */ #define F_EMPTY BIT_27 /* Tx FIFO: empty flag */ @@ -1439,17 +1453,17 @@ /* Bit 15..11: reserved */ #define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */ -/* Q_T1 32 bit Test Register 1 */ +/* Q_T1 32 bit Test Register 1 */ /* Holds four State Machine control Bytes */ -#define SM_CRTL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ -#define SM_CRTL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ -#define SM_CRTL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ -#define SM_CRTL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ - -/* Q_T1_TR 8 bit Test Register 1 Transfer SM */ -/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ -/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ -/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ +#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ +#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ +#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ +#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ + +/* Q_T1_TR 8 bit Test Register 1 Transfer SM */ +/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ +/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ +/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ /* The control status byte of each machine looks like ... */ #define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */ @@ -1459,7 +1473,7 @@ #define SM_STEP BIT_0S /* Step the State Machine */ /* The encoding of the states is not supported by the Diagnostics Tool */ -/* Q_T2 32 bit Test Register 2 */ +/* Q_T2 32 bit Test Register 2 */ /* Bit 31.. 8: reserved */ #define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */ #define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */ @@ -1470,23 +1484,23 @@ #define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */ #define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */ -/* Q_T3 32 bit Test Register 3 */ +/* Q_T3 32 bit Test Register 3 */ /* Bit 31.. 7: reserved */ #define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */ /* Bit 3: reserved */ #define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */ /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */ -/* RB_START 32 bit RAM Buffer Start Address */ -/* RB_END 32 bit RAM Buffer End Address */ -/* RB_WP 32 bit RAM Buffer Write Pointer */ -/* RB_RP 32 bit RAM Buffer Read Pointer */ -/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ -/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ -/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ -/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ -/* RB_PC 32 bit RAM Buffer Packet Counter */ -/* RB_LEV 32 bit RAM Buffer Level Register */ +/* RB_START 32 bit RAM Buffer Start Address */ +/* RB_END 32 bit RAM Buffer End Address */ +/* RB_WP 32 bit RAM Buffer Write Pointer */ +/* RB_RP 32 bit RAM Buffer Read Pointer */ +/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ +/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ +/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ +/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ +/* RB_PC 32 bit RAM Buffer Packet Counter */ +/* RB_LEV 32 bit RAM Buffer Level Register */ /* Bit 31..19: reserved */ #define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */ @@ -1519,17 +1533,17 @@ /* Receive and Transmit MAC FIFO Registers (GENESIS only) */ -/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ -/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ -/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ -/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ -/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ -/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ -/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ -/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ -/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ -/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ -/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ +/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ +/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ +/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ +/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ +/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ +/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ +/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ +/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ +/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ +/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ +/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ /* Bit 31.. 6: reserved */ #define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */ @@ -1682,7 +1696,7 @@ #define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */ -/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ +/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ /* Bit 7.. 3: reserved */ #define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ #define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ @@ -1766,13 +1780,13 @@ #define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ GM_IS_TX_FF_UR) -/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ +/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ /* Bits 15.. 2: reserved */ #define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */ #define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */ -/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ +/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ #define WOL_CTL_LINK_CHG_OCC BIT_15S #define WOL_CTL_MAGIC_PKT_OCC BIT_14S #define WOL_CTL_PATTERN_OCC BIT_13S @@ -1801,7 +1815,7 @@ WOL_CTL_DIS_PATTERN_UNIT | \ WOL_CTL_DIS_MAGIC_PKT_UNIT) -/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ +/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ #define WOL_CTL_PATT_ENA(x) (BIT_0 << (x)) #define SK_NUM_WOL_PATTERN 7 diff -urN linux-2.4.24/drivers/net/sk98lin/h/skgehwt.h linux-2.4.25/drivers/net/sk98lin/h/skgehwt.h --- linux-2.4.24/drivers/net/sk98lin/h/skgehwt.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skgehwt.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,9 +1,9 @@ /****************************************************************************** * * Name: skhwt.h - * Project: Gigabit Ethernet Adapters, Schedule-Modul - * Version: $Revision: 1.6 $ - * Date: $Date: 2003/05/13 17:57:48 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.7 $ + * Date: $Date: 2003/09/16 12:55:08 $ * Purpose: Defines for the hardware timer functions * ******************************************************************************/ @@ -27,6 +27,9 @@ * History: * * $Log: skgehwt.h,v $ + * Revision 1.7 2003/09/16 12:55:08 rschmidt + * Editorial changes + * * Revision 1.6 2003/05/13 17:57:48 mkarl * Editorial changes. * @@ -34,7 +37,7 @@ * Changed license header to GPL. * * Revision 1.4 1998/08/19 09:50:58 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs + * fix: remove struct keyword from C-code (see CCC) add typedefs * * Revision 1.3 1998/08/14 07:09:29 gklug * fix: chg pAc -> pAC @@ -44,10 +47,6 @@ * * Revision 1.1 1998/08/07 09:32:58 gklug * first version - * - * - * - * * ******************************************************************************/ @@ -64,14 +63,14 @@ * - use in Adapters context name pAC->Hwt */ typedef struct s_Hwt { - SK_U32 TStart ; /* HWT start */ - SK_U32 TStop ; /* HWT stop */ - int TActive ; /* HWT: flag : active/inactive */ + SK_U32 TStart; /* HWT start */ + SK_U32 TStop; /* HWT stop */ + int TActive; /* HWT: flag : active/inactive */ } SK_HWT; extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc); extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time); extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc); -extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc); +extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc); extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc); #endif /* _SKGEHWT_H_ */ diff -urN linux-2.4.24/drivers/net/sk98lin/h/skgei2c.h linux-2.4.25/drivers/net/sk98lin/h/skgei2c.h --- linux-2.4.24/drivers/net/sk98lin/h/skgei2c.h 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/net/sk98lin/h/skgei2c.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,16 +1,17 @@ /****************************************************************************** * * Name: skgei2c.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.23 $ - * Date: $Date: 2002/12/19 14:34:27 $ - * Purpose: Special GEnesis defines for TWSI + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.25 $ + * Date: $Date: 2003/10/20 09:06:05 $ + * Purpose: Special defines for TWSI * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,12 @@ * History: * * $Log: skgei2c.h,v $ + * Revision 1.25 2003/10/20 09:06:05 rschmidt + * Editorial changes. + * + * Revision 1.24 2003/09/23 09:31:15 malthoff + * Parameter dev_size added to macro definition of SK_I2C_CTL. + * * Revision 1.23 2002/12/19 14:34:27 rschmidt * Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT() * Editorial changes (TWSI) @@ -107,8 +114,6 @@ * Revision 1.1 1998/07/17 11:27:56 gklug * Created. * - * - * ******************************************************************************/ /* @@ -121,12 +126,13 @@ /* * Macros to access the B2_I2C_CTRL */ -#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \ +#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \ SK_OUT32(IoC, B2_I2C_CTRL,\ (flag ? 0x80000000UL : 0x0L) | \ - (((SK_U32) reg << 16) & I2C_ADDR) | \ - (((SK_U32) dev << 9) & I2C_DEV_SEL) | \ - (( burst << 4) & I2C_BURST_LEN)) + (((SK_U32)reg << 16) & I2C_ADDR) | \ + (((SK_U32)dev << 9) & I2C_DEV_SEL) | \ + (dev_size & I2C_DEV_SIZE) | \ + ((burst << 4) & I2C_BURST_LEN)) #define SK_I2C_STOP(IoC) { \ SK_U32 I2cCtrl; \ @@ -166,42 +172,42 @@ */ #define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ #define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ -#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for the - * extension value - */ -#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) -/* formula: counter = (22500*60)/(rpm * divisor * pulses/2) +#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */ + +/* + * formula: counter = (22500*60)/(rpm * divisor * pulses/2) * assuming: 6500rpm, 4 pulses, divisor 1 */ +#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) /* * Define sensor management data - * Maximum is reached on copperfield with dual Broadcom. + * Maximum is reached on Genesis copper dual port and Yukon-64 * Board specific maximum is in pAC->I2c.MaxSens */ #define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */ #define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ /* - * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto + * To watch the state machine (SM) use the timer in two ways + * instead of one as hitherto */ -#define SK_TIMER_WATCH_STATEMACHINE 0 /* Watch the statemachine to finish in a specific time */ -#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ - +#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */ +#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ /* - * Defines for the individual Thresholds + * Defines for the individual thresholds */ /* Temperature sensor */ -#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ +#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ #define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ #define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ -#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ +#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ /* VCC which should be 5 V */ -#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ -#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ +#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ +#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ #define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ #define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ @@ -229,17 +235,16 @@ #define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ #define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ /* 3300 mVolt */ -#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ - +#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ /* * VDD voltage */ -#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ -#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ -#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ -#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ +#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ +#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ +#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ +#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ /* * PHY PLL 3V3 voltage @@ -255,8 +260,8 @@ #define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */ #define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */ #define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ -#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ +#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ +#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ #define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ /* @@ -270,7 +275,7 @@ /* * ASIC Core 1V5 voltage (YUKON only) */ -#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ +#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ #define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */ #define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */ #define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */ @@ -285,8 +290,8 @@ */ #define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ #define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ -#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ -#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ +#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ +#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ /* * Some Voltages need dynamic thresholds diff -urN linux-2.4.24/drivers/net/sk98lin/h/skgeinit.h linux-2.4.25/drivers/net/sk98lin/h/skgeinit.h --- linux-2.4.24/drivers/net/sk98lin/h/skgeinit.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skgeinit.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgeinit.h * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.81 $ - * Date: $Date: 2003/07/04 12:30:38 $ + * Version: $Revision: 1.83 $ + * Date: $Date: 2003/09/16 14:07:37 $ * Purpose: Structures and prototypes for the GE Init Module * ******************************************************************************/ @@ -27,6 +27,23 @@ * History: * * $Log: skgeinit.h,v $ + * Revision 1.83 2003/09/16 14:07:37 rschmidt + * Moved defines for PHY power down modes from skgehw.h + * Added prototypes for SkMacClearRst() + * Editorial changes + * + * Revision 1.82 2003/09/16 07:18:36 mschmid + * Added members to port structure for MAC control + * - PMacColThres + * - PMacJamLen + * - PMacJamIpgVal + * - PMacJamIpgData + * - PMacIpgData + * - PMacLimit4 + * Added PHY power state to port structure + * - PPhyPowerState + * Added function prototypes to enter and leave low power modes + * * Revision 1.81 2003/07/04 12:30:38 rschmidt * Added SK_FAR to pointers in MAC statistic functions (for PXE) * Editorial changes @@ -594,6 +611,13 @@ #define SK_PRT_INIT 2 /* the port is initialized */ #define SK_PRT_RUN 3 /* the port has an active link */ +/* PHY power down modes */ +#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */ +#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */ +#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */ +#define PHY_PM_ENERGY_DETECT 3 /* energy detect */ +#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */ + /* Default receive frame limit for Workaround of XMAC Errata */ #define SK_DEF_RX_WA_LIM SK_CONSTU64(100) @@ -685,6 +709,13 @@ SK_U8 PCableLen; /* Cable Length */ SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */ SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */ + SK_U8 PPhyPowerState; /* PHY current power state */ + int PMacColThres; /* MAC Collision Threshold */ + int PMacJamLen; /* MAC Jam length */ + int PMacJamIpgVal; /* MAC Jam IPG */ + int PMacJamIpgData; /* MAC IPG Jam to Data */ + int PMacIpgData; /* MAC Data IPG */ + SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */ } SK_GEPORT; /* @@ -865,6 +896,11 @@ SK_IOC IoC, int Port); +extern void SkMacClearRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmInitMac( SK_AC *pAC, SK_IOC IoC, @@ -1040,6 +1076,17 @@ int Port, SK_BOOL StartTest); +extern int SkGmEnterLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_U8 Mode); + +extern int SkGmLeaveLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port); + #ifdef SK_DIAG extern void SkGePhyRead( SK_AC *pAC, @@ -1101,6 +1148,7 @@ extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); +extern void SkMacClearRst(); extern void SkMacInitPhy(); extern int SkMacRxTxEnable(); extern void SkMacPromiscMode(); @@ -1131,6 +1179,8 @@ extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); +extern int SkGmEnterLowPowerMode(); +extern int SkGmLeaveLowPowerMode(); #ifdef SK_DIAG extern void SkGePhyRead(); diff -urN linux-2.4.24/drivers/net/sk98lin/h/skgepnmi.h linux-2.4.25/drivers/net/sk98lin/h/skgepnmi.h --- linux-2.4.24/drivers/net/sk98lin/h/skgepnmi.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skgepnmi.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgepnmi.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.61 $ - * Date: $Date: 2003/05/23 12:53:52 $ + * Version: $Revision: 1.62 $ + * Date: $Date: 2003/08/15 12:31:52 $ * Purpose: Defines for Private Network Management Interface * ****************************************************************************/ @@ -27,6 +27,18 @@ * History: * * $Log: skgepnmi.h,v $ + * Revision 1.62 2003/08/15 12:31:52 tschilli + * Added new OIDs: + * OID_SKGE_DRIVER_RELDATE + * OID_SKGE_DRIVER_FILENAME + * OID_SKGE_CHIPID + * OID_SKGE_RAMSIZE + * OID_SKGE_VAUXAVAIL + * OID_SKGE_PHY_TYPE + * OID_SKGE_PHY_LP_MODE + * + * Added new define SK_DIAG_ATTACHED for OID_SKGE_DIAG_MODE handling. + * * Revision 1.61 2003/05/23 12:53:52 tschilli * Generic PNMI IOCTL subcommands added. * Function prototype SkPnmiGenIoctl() added. @@ -568,15 +580,23 @@ #define OID_SKGE_ALL_DATA 0xFF020190 /* Defines for VCT. */ -#define OID_SKGE_VCT_GET 0xFF020200 -#define OID_SKGE_VCT_SET 0xFF020201 -#define OID_SKGE_VCT_STATUS 0xFF020202 +#define OID_SKGE_VCT_GET 0xFF020200 +#define OID_SKGE_VCT_SET 0xFF020201 +#define OID_SKGE_VCT_STATUS 0xFF020202 #ifdef SK_DIAG_SUPPORT /* Defines for driver DIAG mode. */ -#define OID_SKGE_DIAG_MODE 0xFF020204 +#define OID_SKGE_DIAG_MODE 0xFF020204 #endif /* SK_DIAG_SUPPORT */ +/* New OIDs */ +#define OID_SKGE_DRIVER_RELDATE 0xFF020210 +#define OID_SKGE_DRIVER_FILENAME 0xFF020211 +#define OID_SKGE_CHIPID 0xFF020212 +#define OID_SKGE_RAMSIZE 0xFF020213 +#define OID_SKGE_VAUXAVAIL 0xFF020214 +#define OID_SKGE_PHY_TYPE 0xFF020215 +#define OID_SKGE_PHY_LP_MODE 0xFF020216 /* VCT struct to store a backup copy of VCT data after a port reset. */ typedef struct s_PnmiVct { @@ -613,6 +633,12 @@ #define OID_SKGE_TRAP_RLMT_PORT_UP 523 #define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 +#ifdef SK_DIAG_SUPPORT +/* Defines for driver DIAG mode. */ +#define SK_DIAG_ATTACHED 2 +#define SK_DIAG_RUNNING 1 +#define SK_DIAG_IDLE 0 +#endif /* SK_DIAG_SUPPORT */ /* * Generic PNMI IOCTL subcommand definitions. @@ -730,6 +756,14 @@ #define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" #define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) #define SK_PNMI_ERR052MSG "" +#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53) +#define SK_PNMI_ERR053MSG "General: Driver release date not initialized" +#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54) +#define SK_PNMI_ERR054MSG "General: Driver release date string too long" +#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55) +#define SK_PNMI_ERR055MSG "General: Driver file name not initialized" +#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56) +#define SK_PNMI_ERR056MSG "General: Driver file name string too long" /* * Management counter macros called by the driver @@ -740,6 +774,11 @@ #define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \ (char *)(v)) +#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \ + (char *)(v)) + +#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \ + (char *)(v)) #define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \ { \ @@ -916,6 +955,8 @@ char ConfMacFactoryAddr[6]; SK_U8 ConfPMD; SK_U8 ConfConnector; + SK_U32 ConfPhyType; + SK_U32 ConfPhyMode; SK_U8 ConfLinkCapability; SK_U8 ConfLinkMode; SK_U8 ConfLinkModeStatus; @@ -964,9 +1005,14 @@ SK_U32 DeviceType; char DriverDescr[SK_PNMI_STRINGLEN1]; char DriverVersion[SK_PNMI_STRINGLEN2]; + char DriverReleaseDate[SK_PNMI_STRINGLEN1]; + char DriverFileName[SK_PNMI_STRINGLEN1]; char HwDescr[SK_PNMI_STRINGLEN1]; char HwVersion[SK_PNMI_STRINGLEN2]; SK_U16 Chipset; + SK_U32 ChipId; + SK_U8 VauxAvail; + SK_U32 RamSize; SK_U32 MtuSize; SK_U32 Action; SK_U32 TestResult; @@ -1090,6 +1136,8 @@ char *pDriverDescription; char *pDriverVersion; + char *pDriverReleaseDate; + char *pDriverFileName; int MacUpdatedFlag; int RlmtUpdatedFlag; @@ -1119,6 +1167,9 @@ SK_U8 VctStatus[SK_MAX_MACS]; SK_PNMI_VCT VctBackup[SK_MAX_MACS]; SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS]; +#ifdef SK_DIAG_SUPPORT + SK_U32 DiagAttached; +#endif /* SK_DIAG_SUPPORT */ } SK_PNMI; diff -urN linux-2.4.24/drivers/net/sk98lin/h/ski2c.h linux-2.4.25/drivers/net/sk98lin/h/ski2c.h --- linux-2.4.24/drivers/net/sk98lin/h/ski2c.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/ski2c.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,16 +1,17 @@ /****************************************************************************** * * Name: ski2c.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.34 $ - * Date: $Date: 2003/01/28 09:11:21 $ + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.35 $ + * Date: $Date: 2003/10/20 09:06:30 $ * Purpose: Defines to access Voltage and Temperature Sensor * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,10 @@ * History: * * $Log: ski2c.h,v $ + * Revision 1.35 2003/10/20 09:06:30 rschmidt + * Added prototypes for SkI2cRead() and SkI2cWrite(). + * Editorial changes. + * * Revision 1.34 2003/01/28 09:11:21 rschmidt * Editorial changes * @@ -137,7 +142,6 @@ * Revision 1.1 1998/06/19 14:30:10 malthoff * Created. Sources taken from ML Project. * - * ******************************************************************************/ /* @@ -252,7 +256,7 @@ SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ int SenErrFlag; /* Sensor indicated an error */ SK_BOOL SenInit; /* Is sensor initialized ? */ - SK_U64 SenErrCts; /* Error trap counter */ + SK_U64 SenErrCts; /* Error trap counter */ SK_U64 SenWarnCts; /* Warning trap counter */ SK_U64 SenBegErrTS; /* Begin error timestamp */ SK_U64 SenBegWarnTS; /* Begin warning timestamp */ @@ -279,13 +283,17 @@ #endif /* !SK_DIAG */ } SK_I2C; +extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, + int Reg, int Burst); extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); -#ifndef SK_DIAG +#ifdef SK_DIAG +extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, + int Burst); +#else /* !SK_DIAG */ extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); - -#endif +#endif /* !SK_DIAG */ #endif /* n_SKI2C_H */ diff -urN linux-2.4.24/drivers/net/sk98lin/h/skqueue.h linux-2.4.25/drivers/net/sk98lin/h/skqueue.h --- linux-2.4.24/drivers/net/sk98lin/h/skqueue.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skqueue.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,9 +1,9 @@ /****************************************************************************** * * Name: skqueue.h - * Project: Gigabit Ethernet Adapters, Schedule-Modul - * Version: $Revision: 1.15 $ - * Date: $Date: 2003/05/13 17:54:57 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.16 $ + * Date: $Date: 2003/09/16 12:50:32 $ * Purpose: Defines for the Event queue * ******************************************************************************/ @@ -27,6 +27,9 @@ * History: * * $Log: skqueue.h,v $ + * Revision 1.16 2003/09/16 12:50:32 rschmidt + * Editorial changes + * * Revision 1.15 2003/05/13 17:54:57 mkarl * Editorial changes. * @@ -47,7 +50,7 @@ * add: typedef SK_QUEUE * * Revision 1.9 1998/08/19 09:50:59 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs + * fix: remove struct keyword from C-code (see CCC) add typedefs * * Revision 1.8 1998/08/18 07:00:01 gklug * fix: SK_PTR not defined use void * instead. @@ -74,8 +77,6 @@ * Revision 1.1 1998/07/30 14:52:12 gklug * Initial version. * Defines Event Classes, Event structs and queue management variables. - * - * * ******************************************************************************/ @@ -92,7 +93,7 @@ */ #define SKGE_DRV 1 /* Driver Event Class */ #define SKGE_RLMT 2 /* RLMT Event Class */ -#define SKGE_I2C 3 /* i2C Event Class */ +#define SKGE_I2C 3 /* I2C Event Class */ #define SKGE_PNMI 4 /* PNMI Event Class */ #define SKGE_CSUM 5 /* Checksum Event Class */ #define SKGE_HWAC 6 /* Hardware Access Event Class */ @@ -121,25 +122,25 @@ * Event Queue * skqueue.c * events are class/value pairs - * class is addressee, e.g. RMT, PCM etc. + * class is addressee, e.g. RLMT, PNMI etc. * value is command, e.g. line state change, ring op change etc. */ typedef struct s_EventElem { - SK_U32 Class ; /* Event class */ - SK_U32 Event ; /* Event value */ - SK_EVPARA Para ; /* Event parameter */ + SK_U32 Class; /* Event class */ + SK_U32 Event; /* Event value */ + SK_EVPARA Para; /* Event parameter */ } SK_EVENTELEM; typedef struct s_Queue { SK_EVENTELEM EvQueue[SK_MAX_EVENT]; - SK_EVENTELEM *EvPut ; - SK_EVENTELEM *EvGet ; + SK_EVENTELEM *EvPut; + SK_EVENTELEM *EvGet; } SK_QUEUE; extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level); extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); -extern int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc); +extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc); /* Define Error Numbers and messages */ diff -urN linux-2.4.24/drivers/net/sk98lin/h/sktimer.h linux-2.4.25/drivers/net/sk98lin/h/sktimer.h --- linux-2.4.24/drivers/net/sk98lin/h/sktimer.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/sktimer.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,9 +1,9 @@ /****************************************************************************** * * Name: sktimer.h - * Project: Gigabit Ethernet Adapters, Schedule-Modul - * Version: $Revision: 1.10 $ - * Date: $Date: 2003/05/13 17:56:44 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.11 $ + * Date: $Date: 2003/09/16 12:58:18 $ * Purpose: Defines for the timer functions * ******************************************************************************/ @@ -27,6 +27,9 @@ * History: * * $Log: sktimer.h,v $ + * Revision 1.11 2003/09/16 12:58:18 rschmidt + * Editorial changes + * * Revision 1.10 2003/05/13 17:56:44 mkarl * Editorial changes. * @@ -40,7 +43,7 @@ * fix: SK_TIMCTRL needs to be defined * * Revision 1.6 1998/08/19 09:51:00 gklug - * fix: remove struct keyword from c-code (see CCC) add typedefs + * fix: remove struct keyword from C-code (see CCC) add typedefs * * Revision 1.5 1998/08/17 13:43:21 gklug * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR @@ -78,25 +81,25 @@ typedef struct s_Timer SK_TIMER; struct s_Timer { - SK_TIMER *TmNext ; /* linked list */ - SK_U32 TmClass ; /* Timer Event class */ - SK_U32 TmEvent ; /* Timer Event value */ - SK_EVPARA TmPara ; /* Timer Event parameter */ - SK_U32 TmDelta ; /* delta time */ - int TmActive ; /* flag : active/inactive */ -} ; + SK_TIMER *TmNext; /* linked list */ + SK_U32 TmClass; /* Timer Event class */ + SK_U32 TmEvent; /* Timer Event value */ + SK_EVPARA TmPara; /* Timer Event parameter */ + SK_U32 TmDelta; /* delta time */ + int TmActive; /* flag: active/inactive */ +}; /* * Timer control struct. * - use in Adapters context name pAC->Tim */ typedef struct s_TimCtrl { - SK_TIMER *StQueue ; /* Head of Timer queue */ -} SK_TIMCTRL ; + SK_TIMER *StQueue; /* Head of Timer queue */ +} SK_TIMCTRL; -extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level); -extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer); -extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer, - SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para); -extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc); +extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level); +extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer); +extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer, + SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); +extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc); #endif /* _SKTIMER_H_ */ diff -urN linux-2.4.24/drivers/net/sk98lin/h/sktypes.h linux-2.4.25/drivers/net/sk98lin/h/sktypes.h --- linux-2.4.24/drivers/net/sk98lin/h/sktypes.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/sktypes.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,15 +2,16 @@ * * Name: sktypes.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.1 $ - * Date: $Date: 2003/07/21 07:26:01 $ + * Version: $Revision: 1.2 $ + * Date: $Date: 2003/10/07 08:16:51 $ * Purpose: Define data types for Linux * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,9 @@ * History: * * $Log: sktypes.h,v $ + * Revision 1.2 2003/10/07 08:16:51 mlindner + * Fix: Copyright changes + * * Revision 1.1 2003/07/21 07:26:01 rroesler * Fix: Re-Enter after CVS crash * diff -urN linux-2.4.24/drivers/net/sk98lin/h/skversion.h linux-2.4.25/drivers/net/sk98lin/h/skversion.h --- linux-2.4.24/drivers/net/sk98lin/h/skversion.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/skversion.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,15 +2,16 @@ * * Name: version.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.3 $ - * Date: $Date: 2003/08/25 13:34:48 $ + * Version: $Revision: 1.5 $ + * Date: $Date: 2003/10/07 08:16:51 $ * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +26,12 @@ * * History: * $Log: skversion.h,v $ + * Revision 1.5 2003/10/07 08:16:51 mlindner + * Fix: Copyright changes + * + * Revision 1.4 2003/09/22 08:40:10 mlindner + * Add: Added DRIVER_FILE_NAME and DRIVER_REL_DATE + * * Revision 1.3 2003/08/25 13:34:48 mlindner * Fix: Lint changes * @@ -54,12 +61,14 @@ #ifdef lint static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.18 PL: 01"; + "@(#)SK-BUILD: 6.22 PL: 01"; #endif /* !defined(lint) */ -#define BOOT_STRING "sk98lin: Network Device Driver v6.18\n" \ - "(C)Copyright 1999-2003 Marvell(R)." +#define BOOT_STRING "sk98lin: Network Device Driver v6.22\n" \ + "(C)Copyright 1999-2004 Marvell(R)." -#define VER_STRING "6.18" +#define VER_STRING "6.22" +#define DRIVER_FILE_NAME "sk98lin" +#define DRIVER_REL_DATE "Jan-30-2004" diff -urN linux-2.4.24/drivers/net/sk98lin/h/xmac_ii.h linux-2.4.25/drivers/net/sk98lin/h/xmac_ii.h --- linux-2.4.24/drivers/net/sk98lin/h/xmac_ii.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/h/xmac_ii.h 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: xmac_ii.h * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.48 $ - * Date: $Date: 2003/05/13 17:17:55 $ + * Version: $Revision: 1.52 $ + * Date: $Date: 2003/10/02 16:35:50 $ * Purpose: Defines and Macros for Gigabit Ethernet Controller * ******************************************************************************/ @@ -27,6 +27,22 @@ * History: * * $Log: xmac_ii.h,v $ + * Revision 1.52 2003/10/02 16:35:50 rschmidt + * Added defines for default values of GMAC parameters + * Changed defines for setting GMAC parameters + * Editorial changes + * + * Revision 1.51 2003/09/23 09:04:27 malthoff + * Add bit definitions for PHY_MARV_EXT_P_STAT. + * + * Revision 1.50 2003/09/16 14:15:07 rschmidt + * Added defines for Extended PHY Specific Control + * Editorial changes + * + * Revision 1.49 2003/09/16 07:22:46 mschmid + * Added defines for Marvell PHY energy detect modes + * Added macros for MAC parameter setting in port structure + * * Revision 1.48 2003/05/13 17:17:55 mkarl * Editorial changes. * @@ -676,7 +692,7 @@ #define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */ #define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* 0x09 - 0x0e: reserved */ #define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */ #define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */ @@ -693,7 +709,7 @@ #define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Broadcom-specific registers */ #define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ #define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -702,7 +718,7 @@ #define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */ #define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */ #define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */ -#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carr Sense Cnt */ +#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */ #define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */ /* 0x15 - 0x17: reserved */ #define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */ @@ -724,7 +740,7 @@ #define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link P Reg */ +#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Marvel-specific registers */ #define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ #define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -757,7 +773,7 @@ #define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ #define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner*/ +#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Level One-specific registers */ #define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ #define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ @@ -804,12 +820,13 @@ /* * PHY bit definitions * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are - * Xmac/Broadcom/LevelOne/National-specific. + * XMAC/Broadcom/LevelOne/National/Marvell-specific. * All other are general. */ /***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/ /***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/ +/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/ /***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ #define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */ #define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */ @@ -909,27 +926,20 @@ /***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ /* Bit 15..4: reserved */ -#define PHY_AN_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ -#define PHY_AN_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ -#define PHY_AN_RX_PG (1<<1) /* Bit 1: Page Received */ +#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ +#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ +#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */ /* Bit 0: reserved */ /***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ - /* Bit 15..5: reserved */ -#define PHY_B_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ - /***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ -#define PHY_L_AN_BP (1<<5) /* Bit 5: Base Page Indication */ -#define PHY_L_AN_PDF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_AN_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_AN_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_AN_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_B_AN_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ - +/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ + /* Bit 15..5: reserved */ +#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */ +/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ +/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ +/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */ +#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ /***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ /***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ @@ -958,7 +968,7 @@ #define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */ #define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */ #define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */ -#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability missmatch */ +#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */ /* Bit 2..0: reserved */ /* * Remote Fault Bits (PHY_X_AN_RFB) encoding @@ -990,6 +1000,7 @@ /* Bit 7..0: reserved */ /***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ +/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ #define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ #define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ #define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ @@ -1309,7 +1320,6 @@ /* Bit 7..0: reserved */ /***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/ - #define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ #define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ #define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */ @@ -1323,6 +1333,9 @@ #define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */ #define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */ +#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */ +#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */ + #define PHY_M_PC_MDI_XMODE(x) SHIFT5(x) #define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */ #define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */ @@ -1373,6 +1386,7 @@ #define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */ #define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */ #define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */ +#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */ #define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */ #define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */ @@ -1434,6 +1448,18 @@ #define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */ #define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */ +/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ +#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */ +#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */ +#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */ +#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */ +#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */ +#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */ + /* Bit 9..4: reserved */ +#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */ +#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */ + + /***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/ #define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */ #define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */ @@ -1531,7 +1557,7 @@ #define GM_RXF_SHT \ (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */ #define GM_RXE_FRAG \ - (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Receeived with FCS Err */ + (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */ #define GM_RXF_64B \ (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */ #define GM_RXF_127B \ @@ -1606,7 +1632,6 @@ */ /* GM_GP_STAT 16 bit r/o General Purpose Status Register */ - #define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */ #define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */ #define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */ @@ -1646,11 +1671,14 @@ GM_GPCR_AU_SPD_DIS) /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ - #define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */ #define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */ #define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */ -#define GM_TXCR_COL_THR (4<<10) /* Bit 12..10: Collision Threshold */ +#define GM_TXCR_COL_THR_MSK (1<<10) /* Bit 12..10: Collision Threshold */ + +#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK) + +#define TX_COL_DEF 0x04 /* GM_RX_CTRL 16 bit r/w Receive Control Register */ #define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */ @@ -1663,35 +1691,41 @@ #define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */ #define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */ /* Bit 3..0: reserved */ -#define JAM_LEN_VAL(x) SHIFT14(x) -#define JAM_IPG_VAL(x) SHIFT9(x) -#define IPG_JAM_DATA(x) SHIFT4(x) + +#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK) +#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK) +#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK) + +#define TX_JAM_LEN_DEF 0x03 +#define TX_JAM_IPG_DEF 0x0b +#define TX_IPG_JAM_DEF 0x1c /* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */ -#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder */ +#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */ #define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */ #define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */ #define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */ /* Bit 7..5: reserved */ #define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ -#define DATA_BLIND_VAL(x) SHIFT11(x) -#define DATA_BLIND_FAST_ETH 0x1c -#define DATA_BLIND_GIGABIT 4 +#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK) +#define DATA_BLIND_DEF 0x04 -#define IPG_VAL_FAST_ETH 0x1e -#define IPG_VAL_GIGABIT 6 +#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK) +#define IPG_DATA_DEF 0x1e /* GM_SMI_CTRL 16 bit r/w SMI Control Register */ - -#define GM_SMI_CT_PHY_AD(x) SHIFT11(x) -#define GM_SMI_CT_REG_AD(x) SHIFT6(x) +#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */ +#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */ #define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/ #define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */ #define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */ /* Bit 2..0: reserved */ -/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ +#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK) +#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK) + + /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ /* Bit 15..6: reserved */ #define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */ #define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */ diff -urN linux-2.4.24/drivers/net/sk98lin/skcsum.c linux-2.4.25/drivers/net/sk98lin/skcsum.c --- linux-2.4.24/drivers/net/sk98lin/skcsum.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skcsum.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skcsum.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.11 $ - * Date: $Date: 2003/03/11 14:05:55 $ + * Version: $Revision: 1.12 $ + * Date: $Date: 2003/08/20 13:55:53 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -26,6 +26,10 @@ * History: * * $Log: skcsum.c,v $ + * Revision 1.12 2003/08/20 13:55:53 mschmid + * Changed notation of #ifndef SkCsCalculateChecksum to + * #ifndef SK_CS_CALCULATE_CHECKSUM + * * Revision 1.11 2003/03/11 14:05:55 rschmidt * Replaced memset() by macro SK_MEMSET() * Editorial changes @@ -78,7 +82,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skcsum.c,v 1.11 2003/03/11 14:05:55 rschmidt Exp $ (C) SysKonnect."; + "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect."; #endif /* !lint */ /****************************************************************************** @@ -791,7 +795,7 @@ *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE; } /* SkCsSetReceiveFlags */ -#ifndef SkCsCalculateChecksum +#ifndef SK_CS_CALCULATE_CHECKSUM /****************************************************************************** * @@ -856,7 +860,7 @@ return ((unsigned) Checksum); } /* SkCsCalculateChecksum */ -#endif /* SkCsCalculateChecksum */ +#endif /* SK_CS_CALCULATE_CHECKSUM */ /****************************************************************************** * diff -urN linux-2.4.24/drivers/net/sk98lin/skdim.c linux-2.4.25/drivers/net/sk98lin/skdim.c --- linux-2.4.24/drivers/net/sk98lin/skdim.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skdim.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skdim.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.2 $ - * Date: $Date: 2003/08/21 12:35:05 $ + * Version: $Revision: 1.5 $ + * Date: $Date: 2003/11/28 12:55:40 $ * Purpose: All functions to maintain interrupt moderation * ******************************************************************************/ @@ -11,6 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,15 @@ * History: * * $Log: skdim.c,v $ + * Revision 1.5 2003/11/28 12:55:40 rroesler + * Fix: support for new process timing interface added + * + * Revision 1.4 2003/10/10 10:58:56 mlindner + * Fix: CPU detection under the kernel 2.6 + * + * Revision 1.3 2003/10/07 08:17:08 mlindner + * Fix: Copyright changes + * * Revision 1.2 2003/08/21 12:35:05 mlindner * Fix: Corrected CPU detection and compile errors on single CPU machines * @@ -62,7 +72,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skdim.c,v 1.2 2003/08/21 12:35:05 mlindner Exp $ (C) SysKonnect."; + "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect."; #endif #define __SKADDR_C @@ -318,6 +328,7 @@ unsigned int TotalTime = 0; unsigned int UsedTime = 0; unsigned int SystemLoad = 0; + #ifdef CONFIG_SMP unsigned int SKNumCpus = smp_num_cpus; #else @@ -327,9 +338,23 @@ unsigned int NbrCpu = 0; for (NbrCpu = 0; NbrCpu < SKNumCpus; NbrCpu++) { +#ifdef _LINUX_PROCESS_TIMING_H + /* + ** all seconds and usec values being obtained from the + ** process_timing entries need to be adapted to jiffies + ** (in case we have a system supporting process times) + */ + UserTime = UserTime + (kstat_percpu[NbrCpu].user.tv_sec * 10) + + (kstat_percpu[NbrCpu].user.tv_usec/100000); + NiceTime = NiceTime + (kstat_percpu[NbrCpu].nice.tv_sec * 10) + + (kstat_percpu[NbrCpu].nice.tv_usec/100000); + SystemTime = SystemTime + (kstat_percpu[NbrCpu].system.tv_sec * 10) + + (kstat_percpu[NbrCpu].system.tv_usec/100000); +#else UserTime = UserTime + kstat.per_cpu_user[NbrCpu]; NiceTime = NiceTime + kstat.per_cpu_nice[NbrCpu]; SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu]; +#endif } UsedTime = UserTime + NiceTime + SystemTime; diff -urN linux-2.4.24/drivers/net/sk98lin/skge.c linux-2.4.25/drivers/net/sk98lin/skge.c --- linux-2.4.24/drivers/net/sk98lin/skge.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skge.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,35 +1,20 @@ /****************************************************************************** * - * Name: skge.c + * Name: skge.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.11 $ - * Date: $Date: 2003/08/26 16:05:19 $ + * Version: $Revision: 1.43 $ + * Date: $Date: 2004/01/29 15:47:07 $ * Purpose: The main driver source module * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * - * Driver for SysKonnect Gigabit Ethernet Server Adapters: - * - * SK-9871 (single link 1000Base-ZX) - * SK-9872 (dual link 1000Base-ZX) - * SK-9861 (single link 1000Base-SX, VF45 Volition Plug) - * SK-9862 (dual link 1000Base-SX, VF45 Volition Plug) - * SK-9841 (single link 1000Base-LX) - * SK-9842 (dual link 1000Base-LX) - * SK-9843 (single link 1000Base-SX) - * SK-9844 (dual link 1000Base-SX) - * SK-9821 (single link 1000Base-T) - * SK-9822 (dual link 1000Base-T) - * SK-9881 (single link 1000Base-SX V2 LC) - * SK-9871 (single link 1000Base-ZX V2) - * SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug) - * SK-9841 (single link 1000Base-LX V2) - * SK-9843 (single link 1000Base-SX V2) - * SK-9821 (single link 1000Base-T V2) + * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet + * Server Adapters. * * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and * SysKonnects GEnesis Solaris driver @@ -56,6 +41,90 @@ * History: * * $Log: skge.c,v $ + * Revision 1.43 2004/01/29 15:47:07 mlindner + * Fix: Reset Xmac when stopping the port + * + * Revision 1.42 2003/12/12 10:05:43 mlindner + * Fix: Format of error message corrected + * + * Revision 1.41 2003/12/11 16:03:57 mlindner + * Fix: Create backup from pnmi data structure + * + * Revision 1.40 2003/12/11 12:14:48 mlindner + * Fix: Initalize Board before network configuration + * Fix: Change device names to driver name + * + * Revision 1.39 2003/12/10 08:57:38 rroesler + * Fix: Modifications regarding try_module_get() and capable() + * + * Revision 1.38 2003/12/01 17:16:50 mlindner + * Fix: Remove useless register_netdev + * + * Revision 1.37 2003/12/01 17:11:30 mlindner + * Fix: Register net device before SkGeBoardInit + * + * Revision 1.36 2003/11/28 13:04:27 rroesler + * Fix: do not print interface status in case DIAG is used + * + * Revision 1.35 2003/11/17 14:41:06 mlindner + * Fix: Endif command + * + * Revision 1.34 2003/11/17 13:29:05 mlindner + * Fix: Editorial changes + * + * Revision 1.33 2003/11/14 14:56:54 rroesler + * Fix: corrected compilation warnings kernel 2.2 + * + * Revision 1.32 2003/11/13 14:18:47 rroesler + * Fix: added latest changes regarding the use of the proc system + * + * Revision 1.31 2003/11/13 09:28:35 rroesler + * Fix: removed kernel warning 'driver changed get_stats after register' + * + * Revision 1.30 2003/11/11 13:15:27 rroesler + * Fix: use suitables kernel usage count macros when using the diag + * + * Revision 1.29 2003/11/10 09:38:26 rroesler + * Fix: restore PNMI structure backup for DIAG actions + * + * Revision 1.28 2003/11/07 17:28:45 rroesler + * Fix: Additions for the LeaveDiagMode + * + * Revision 1.27 2003/11/03 13:21:14 mlindner + * Add: SkGeBuffPad function for padding to ensure the trailing bytes exist + * + * Revision 1.26 2003/10/30 09:20:40 mlindner + * Fix: Control bit check + * + * Revision 1.25 2003/10/29 07:43:37 rroesler + * Fix: Implemented full None values handling for parameter Moderation + * + * Revision 1.24 2003/10/22 14:18:12 rroesler + * Fix: DIAG handling for DualNet cards + * + * Revision 1.23 2003/10/17 10:05:13 mlindner + * Add: New blinkmode for Morvell cards + * + * Revision 1.22 2003/10/15 12:31:25 rroesler + * Fix: Corrected bugreport #10954 (Linux System crash when using vlans) + * + * Revision 1.21 2003/10/07 12:32:28 mlindner + * Fix: Editorial changes + * + * Revision 1.20 2003/10/07 12:22:40 mlindner + * Fix: Compiler warnings + * + * Revision 1.19 2003/10/07 09:33:40 mlindner + * Fix: No warnings for illegal values of Mod and IntsPerSec + * Fix: Speed 100 in Half Duplex not allowed for Yukon + * Fix: PrefPort=B not allowed on single NICs + * + * Revision 1.18 2003/10/07 08:17:08 mlindner + * Fix: Copyright changes + * + * Revision 1.17 2003/09/29 12:06:59 mlindner + * *** empty log message *** + * * Revision 1.16 2003/09/23 11:07:35 mlindner * Fix: IO-control return race condition * Fix: Interrupt moderation value check @@ -68,6 +137,12 @@ * Add: Yukon Plus changes (ChipID, PCI...) * Fix: TCP and UDP Checksum calculation * + * Revision 1.13 2003/09/01 13:30:08 rroesler + * Fix: Corrected missing defines + * + * Revision 1.12 2003/09/01 13:12:02 rroesler + * Add: Code for improved DIAG Attach/Detach interface + * * Revision 1.11 2003/08/26 16:05:19 mlindner * Fix: Compiler warnings (void *) * @@ -406,7 +481,6 @@ * * * "h/skdrv1st.h" - * * * * @@ -568,6 +642,12 @@ static void StopDrvCleanupTimer(SK_AC *pAC); static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); +#ifdef SK_DIAG_SUPPORT +static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); +static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); +static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); +#endif + /******************************************************************************* * * Extern Function Prototypes @@ -576,14 +656,13 @@ #ifdef CONFIG_PROC_FS static const char SK_Root_Dir_entry[] = "sk98lin"; -static struct proc_dir_entry *pSkRootDir; - -extern int sk_proc_read( char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data); +static struct proc_dir_entry *pSkRootDir = NULL; +extern int sk_proc_read( char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data); #endif extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); @@ -601,6 +680,7 @@ static const char *BootString = BOOT_STRING; struct SK_NET_DEVICE *SkGeRootDev = NULL; static int probed __initdata = 0; +static SK_BOOL DoPrintInterfaceChange = SK_TRUE; /* local variables **********************************************************/ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; @@ -672,17 +752,11 @@ break; } - if (dev->priv == NULL) { - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } - pNet = dev->priv; pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); if (pNet->pAC == NULL){ - dev->get_stats = NULL; unregister_netdev(dev); + dev->get_stats = NULL; kfree(dev->priv); printk(KERN_ERR "Unable to allocate adapter " "structure!\n"); @@ -712,8 +786,8 @@ retval = SkGeInitPCI(pAC); if (retval) { printk("SKGE: PCI setup failed: %i\n", retval); - dev->get_stats = NULL; unregister_netdev(dev); + dev->get_stats = NULL; kfree(dev); continue; } @@ -740,12 +814,30 @@ #endif pAC->Index = boards_found; + if (SkGeBoardInit(dev, pAC)) { - FreeResources(dev); + unregister_netdev(dev); kfree(dev); continue; } + + /* Print adapter specific string from vpd */ + ProductStr(pAC); + printk("%s: %s\n", dev->name, pAC->DeviceStr); + + /* Print configuration settings */ + printk(" PrefPort:%c RlmtMode:%s\n", + 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, + (pAC->RlmtMode==0) ? "Check Link State" : + ((pAC->RlmtMode==1) ? "Check Link State" : + ((pAC->RlmtMode==3) ? "Check Local Port" : + ((pAC->RlmtMode==7) ? "Check Segmentation" : + ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); + + SkGeYellowLED(pAC, pAC->IoBase, 1); + + memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); @@ -770,27 +862,16 @@ S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); - - pProcFile->read_proc = sk_proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #endif pNet->PortNr = 0; - pNet->NetNr = 0; - - -#ifdef SK_ZEROCOPY -#ifdef USE_SK_TX_CHECKSUM - if (pAC->ChipsetType) { - /* SG and ZEROCOPY - fly baby... */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - } -#endif -#endif + pNet->NetNr = 0; boards_found++; @@ -802,23 +883,23 @@ break; } - pAC->dev[1] = dev; - pNet = dev->priv; - pNet->PortNr = 1; - pNet->NetNr = 1; - pNet->pAC = pAC; - pNet->Mtu = 1500; - pNet->Up = 0; - - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; + pAC->dev[1] = dev; + pNet = dev->priv; + pNet->PortNr = 1; + pNet->NetNr = 1; + pNet->pAC = pAC; + pNet->Mtu = 1500; + pNet->Up = 0; + + dev->open = &SkGeOpen; + dev->stop = &SkGeClose; + dev->hard_start_xmit = &SkGeXmit; + dev->get_stats = &SkGeStats; dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - dev->flags &= ~IFF_RUNNING; + dev->set_mac_address = &SkGeSetMacAddr; + dev->do_ioctl = &SkGeIoctl; + dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; #ifdef SK_ZEROCOPY #ifdef USE_SK_TX_CHECKSUM @@ -833,14 +914,12 @@ pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); - - - pProcFile->read_proc = sk_proc_read; + pProcFile->read_proc = sk_proc_read; pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #endif memcpy((caddr_t) &dev->dev_addr, @@ -848,14 +927,20 @@ printk("%s: %s\n", dev->name, pAC->DeviceStr); printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - } - /* Save the hardware revision */ pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + (pAC->GIni.GIPciHwRev & 0x0F); + /* Set driver globals */ + pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; + pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; + + SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); + SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + /* * This is bollocks, but we need to tell the net-init * code that it shall go for the next device. @@ -875,7 +960,6 @@ } /* skge_probe */ - /***************************************************************************** * * SkGeInitPCI - Init the PCI resources @@ -1249,7 +1333,7 @@ SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); - + pAC->BoardLevel = SK_INIT_DATA; pAC->RxBufSize = ETH_BUF_SIZE; @@ -1261,7 +1345,7 @@ /* level 1 init common modules here (HW init) */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { - printk("HWInit (1) failed.\n"); + printk("sk98lin: HWInit (1) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); return(-EAGAIN); } @@ -1293,14 +1377,14 @@ Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev); } else { - printk(KERN_WARNING "%s: Illegal number of ports: %d\n", - dev->name, pAC->GIni.GIMacsFound); + printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", + pAC->GIni.GIMacsFound); return -EAGAIN; } if (Ret) { - printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n", - dev->name, dev->irq); + printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", + dev->irq); return -EAGAIN; } pAC->AllocFlag |= SK_ALLOC_IRQ; @@ -1328,25 +1412,10 @@ pAC->ActivePort, DualNet)) { BoardFreeMem(pAC); - printk("SkGeInitAssignRamToQueues failed.\n"); + printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); return(-EAGAIN); } - /* Print adapter specific string from vpd */ - ProductStr(pAC); - printk("%s: %s\n", dev->name, pAC->DeviceStr); - - /* Print configuration settings */ - printk(" PrefPort:%c RlmtMode:%s\n", - 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, - (pAC->RlmtMode==0) ? "Check Link State" : - ((pAC->RlmtMode==1) ? "Check Link State" : - ((pAC->RlmtMode==3) ? "Check Local Port" : - ((pAC->RlmtMode==7) ? "Check Segmentation" : - ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); - - SkGeYellowLED(pAC, pAC->IoBase, 1); - /* * Register the device here */ @@ -1904,9 +1973,17 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC)); +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + return (-1); /* still in use by diag; deny actions */ + } + } +#endif + /* Set blink mode */ - if (pAC->PciDev->vendor == 0x1186) + if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE; if (pAC->BoardLevel == SK_INIT_DATA) { @@ -2001,26 +2078,50 @@ static int SkGeClose( struct SK_NET_DEVICE *dev) { - DEV_NET *pNet; - SK_AC *pAC; + DEV_NET *pNet; + DEV_NET *newPtrNet; + SK_AC *pAC; unsigned long Flags; /* for spin lock */ - int i; - int PortIdx; - SK_EVPARA EvPara; + int i; + int PortIdx; + SK_EVPARA EvPara; + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); - netif_stop_queue(dev); pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { + MOD_DEC_USE_COUNT; + /* + ** notify that the interface which has been closed + ** by operator interaction must not be started up + ** again when the DIAG has finished. + */ + newPtrNet = (DEV_NET *) pAC->dev[0]->priv; + if (newPtrNet == pNet) { + pAC->WasIfUp[0] = SK_FALSE; + } else { + pAC->WasIfUp[1] = SK_FALSE; + } + return 0; /* return to system everything is fine... */ + } else { + pAC->DiagFlowCtrl = SK_FALSE; + } + } +#endif + + netif_stop_queue(dev); + if (pAC->RlmtNets == 1) PortIdx = pAC->ActivePort; else PortIdx = pNet->NetNr; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); - StopDrvCleanupTimer(pAC); /* @@ -2049,6 +2150,7 @@ EvPara.Para32[0] = pNet->NetNr; EvPara.Para32[1] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara); SkEventDispatcher(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); @@ -2078,6 +2180,10 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeClose: done ")); + SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); + SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + pAC->MaxPorts--; pNet->Up = 0; @@ -2224,9 +2330,10 @@ ** This is to resolve faulty padding by the HW with 0xaa bytes. */ if (BytesSend < C_LEN_ETHERNET_MINSIZE) { - skb_put(pMessage, (C_LEN_ETHERNET_MINSIZE-BytesSend)); - SK_MEMSET( ((char *)(pMessage->data))+BytesSend, - 0, C_LEN_ETHERNET_MINSIZE-BytesSend); + if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { + return 0; + } + pMessage->len = C_LEN_ETHERNET_MINSIZE; } /* @@ -3343,6 +3450,16 @@ return -EINVAL; } +#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { + return -1; /* still in use, deny any actions of MTU */ + } else { + pAC->DiagFlowCtrl = SK_FALSE; + } + } +#endif + pNet->Mtu = NewMtu; pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv; if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) { @@ -3562,11 +3679,20 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeStats starts now...\n")); pPnmiStruct = &pAC->PnmiStruct; - memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); + +#ifdef SK_DIAG_SUPPORT + if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && + (pAC->BoardLevel == SK_INIT_RUN)) { +#endif + SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +#ifdef SK_DIAG_SUPPORT + } +#endif + pPnmiStat = &pPnmiStruct->Stat[0]; pPnmiConf = &pPnmiStruct->Conf[0]; @@ -3629,7 +3755,7 @@ DEV_NET *pNet; SK_AC *pAC; void *pMemBuf; - +struct pci_dev *pdev = NULL; SK_GE_IOCTL Ioctl; unsigned int Err = 0; int Size = 0; @@ -3696,6 +3822,45 @@ fault_gen: kfree(pMemBuf); /* cleanup everything */ break; +#ifdef SK_DIAG_SUPPORT + case SK_IOCTL_DIAG: + if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { + Length = Ioctl.Len; + } else { + Length = sizeof(pAC->PnmiStruct) + HeaderLength; + } + if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { + return -ENOMEM; + } + if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { + Err = -EFAULT; + goto fault_diag; + } + pdev = pAC->PciDev; + Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */ + /* + ** While coding this new IOCTL interface, only a few lines of code + ** are to to be added. Therefore no dedicated function has been + ** added. If more functionality is added, a separate function + ** should be used... + */ + * ((SK_U32 *)pMemBuf) = 0; + * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number; + * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pdev->slot_name); + if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { + Err = -EFAULT; + goto fault_diag; + } + Ioctl.Len = Length; + if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { + Err = -EFAULT; + goto fault_diag; + } +fault_diag: + kfree(pMemBuf); /* cleanup everything */ + break; +#endif default: Err = -EOPNOTSUPP; } @@ -3851,10 +4016,9 @@ (strcmp(ConType[pAC->Index],"Auto")!=0) && (strcmp(ConType[pAC->Index],"")!=0)) { /* Set the speed parameter back */ - printk("%s: Illegal value \"%s\" " + printk("sk98lin: Illegal value \"%s\" " "for ConType." " Using Auto.\n", - pAC->dev[0]->name, ConType[pAC->Index]); sprintf(ConType[pAC->Index], "Auto"); @@ -3898,8 +4062,8 @@ M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; } } else { - printk("%s: Illegal value \"%s\" for ConType\n", - pAC->dev[0]->name, ConType[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for ConType\n", + ConType[pAC->Index]); IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ } } else { @@ -3923,8 +4087,8 @@ } else if (strcmp(Speed_A[pAC->Index],"1000")==0) { LinkSpeed = SK_LSPEED_1000MBPS; } else { - printk("%s: Illegal value \"%s\" for Speed_A\n", - pAC->dev[0]->name, Speed_A[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for Speed_A\n", + Speed_A[pAC->Index]); IsLinkSpeedDefined = SK_FALSE; } } else { @@ -3938,9 +4102,9 @@ if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && ((LinkSpeed != SK_LSPEED_AUTO) && (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("%s: Illegal value for Speed_A. " + printk("sk98lin: Illegal value for Speed_A. " "Not a copper card or GE V2 card\n Using " - "speed 1000\n", pAC->dev[0]->name); + "speed 1000\n"); LinkSpeed = SK_LSPEED_1000MBPS; } @@ -3970,8 +4134,8 @@ } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) { AutoNeg = AN_SENS; } else { - printk("%s: Illegal value \"%s\" for AutoNeg_A\n", - pAC->dev[0]->name, AutoNeg_A[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n", + AutoNeg_A[pAC->Index]); } } @@ -3989,33 +4153,32 @@ } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) { DuplexCap = DC_HALF; } else { - printk("%s: Illegal value \"%s\" for DupCap_A\n", - pAC->dev[0]->name, DupCap_A[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for DupCap_A\n", + DupCap_A[pAC->Index]); } } - + /* ** Check for illegal combinations */ - if ((LinkSpeed = SK_LSPEED_1000MBPS) && + if ((LinkSpeed == SK_LSPEED_1000MBPS) && ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || (DuplexCap == SK_LMODE_STAT_HALF)) && (pAC->ChipsetType)) { - printk("%s: Half Duplex not possible with Gigabit speed!\n" - " Using Full Duplex.\n", - pAC->dev[0]->name); + printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" + " Using Full Duplex.\n"); DuplexCap = DC_FULL; } if ( AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("%s, Port A: DuplexCapabilities" - " ignored using Sense mode\n", pAC->dev[0]->name); + printk("sk98lin, Port A: DuplexCapabilities" + " ignored using Sense mode\n"); } if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("%s, Port A: Illegal combination" + printk("sk98lin: Port A: Illegal combination" " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n", pAC->dev[0]->name); + "Full Duplex\n"); DuplexCap = DC_FULL; } @@ -4024,10 +4187,9 @@ } if (!AutoSet && DupSet) { - printk("%s, Port A: Duplex setting not" + printk("sk98lin: Port A: Duplex setting not" " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n", - pAC->dev[0]->name); + " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } @@ -4054,8 +4216,8 @@ } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) { FlowCtrl = SK_FLOW_MODE_NONE; } else { - printk("%s: Illegal value \"%s\" for FlowCtrl_A\n", - pAC->dev[0]->name, FlowCtrl_A[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", + FlowCtrl_A[pAC->Index]); IsFlowCtrlDefined = SK_FALSE; } } else { @@ -4064,9 +4226,9 @@ if (IsFlowCtrlDefined) { if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { - printk("%s, Port A: FlowControl" + printk("sk98lin: Port A: FlowControl" " impossible without AutoNegotiation," - " disabled\n", pAC->dev[0]->name); + " disabled\n"); FlowCtrl = SK_FLOW_MODE_NONE; } pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl; @@ -4086,8 +4248,8 @@ } else if (strcmp(Role_A[pAC->Index],"Slave")==0) { MSMode = SK_MS_MODE_SLAVE; } else { - printk("%s: Illegal value \"%s\" for Role_A\n", - pAC->dev[0]->name, Role_A[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for Role_A\n", + Role_A[pAC->Index]); IsRoleDefined = SK_FALSE; } } else { @@ -4122,8 +4284,8 @@ } else if (strcmp(Speed_B[pAC->Index],"1000")==0) { LinkSpeed = SK_LSPEED_1000MBPS; } else { - printk("%s: Illegal value \"%s\" for Speed_B\n", - pAC->dev[1]->name, Speed_B[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for Speed_B\n", + Speed_B[pAC->Index]); IsLinkSpeedDefined = SK_FALSE; } } else { @@ -4137,9 +4299,9 @@ if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && ((LinkSpeed != SK_LSPEED_AUTO) && (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("%s: Illegal value for Speed_B. " + printk("sk98lin: Illegal value for Speed_B. " "Not a copper card or GE V2 card\n Using " - "speed 1000\n", pAC->dev[1]->name); + "speed 1000\n"); LinkSpeed = SK_LSPEED_1000MBPS; } @@ -4169,8 +4331,8 @@ } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) { AutoNeg = AN_SENS; } else { - printk("%s: Illegal value \"%s\" for AutoNeg_B\n", - pAC->dev[0]->name, AutoNeg_B[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n", + AutoNeg_B[pAC->Index]); } } @@ -4188,8 +4350,8 @@ } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) { DuplexCap = DC_HALF; } else { - printk("%s: Illegal value \"%s\" for DupCap_B\n", - pAC->dev[0]->name, DupCap_B[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for DupCap_B\n", + DupCap_B[pAC->Index]); } } @@ -4197,25 +4359,24 @@ /* ** Check for illegal combinations */ - if ((LinkSpeed = SK_LSPEED_1000MBPS) && + if ((LinkSpeed == SK_LSPEED_1000MBPS) && ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || (DuplexCap == SK_LMODE_STAT_HALF)) && (pAC->ChipsetType)) { - printk("%s: Half Duplex not possible with Gigabit speed!\n" - " Using Full Duplex.\n", - pAC->dev[1]->name); + printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" + " Using Full Duplex.\n"); DuplexCap = DC_FULL; } if (AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("%s, Port B: DuplexCapabilities" - " ignored using Sense mode\n", pAC->dev[1]->name); + printk("sk98lin, Port B: DuplexCapabilities" + " ignored using Sense mode\n"); } if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("%s, Port B: Illegal combination" + printk("sk98lin: Port B: Illegal combination" " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n", pAC->dev[1]->name); + "Full Duplex\n"); DuplexCap = DC_FULL; } @@ -4224,10 +4385,9 @@ } if (!AutoSet && DupSet) { - printk("%s, Port B: Duplex setting not" + printk("sk98lin: Port B: Duplex setting not" " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n", - pAC->dev[1]->name); + " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } @@ -4254,8 +4414,8 @@ } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) { FlowCtrl = SK_FLOW_MODE_NONE; } else { - printk("%s: Illegal value \"%s\" for FlowCtrl_B\n", - pAC->dev[0]->name, FlowCtrl_B[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n", + FlowCtrl_B[pAC->Index]); IsFlowCtrlDefined = SK_FALSE; } } else { @@ -4264,9 +4424,9 @@ if (IsFlowCtrlDefined) { if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { - printk("%s, Port B: FlowControl" + printk("sk98lin: Port B: FlowControl" " impossible without AutoNegotiation," - " disabled\n", pAC->dev[1]->name); + " disabled\n"); FlowCtrl = SK_FLOW_MODE_NONE; } pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl; @@ -4286,8 +4446,8 @@ } else if (strcmp(Role_B[pAC->Index],"Slave")==0) { MSMode = SK_MS_MODE_SLAVE; } else { - printk("%s: Illegal value \"%s\" for Role_B\n", - pAC->dev[1]->name, Role_B[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for Role_B\n", + Role_B[pAC->Index]); IsRoleDefined = SK_FALSE; } } else { @@ -4305,28 +4465,37 @@ if (PrefPort != NULL && pAC->IndexIndex] != NULL) { if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */ - pAC->ActivePort = 0; - pAC->Rlmt.Net[0].Preference = -1; /* auto */ - pAC->Rlmt.Net[0].PrefPort = 0; + pAC->ActivePort = 0; + pAC->Rlmt.Net[0].Preference = -1; /* auto */ + pAC->Rlmt.Net[0].PrefPort = 0; } else if (strcmp(PrefPort[pAC->Index],"A") == 0) { - /* - ** do not set ActivePort here, thus a port - ** switch is issued after net up. - */ - Port = 0; - pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; + /* + ** do not set ActivePort here, thus a port + ** switch is issued after net up. + */ + Port = 0; + pAC->Rlmt.Net[0].Preference = Port; + pAC->Rlmt.Net[0].PrefPort = Port; } else if (strcmp(PrefPort[pAC->Index],"B") == 0) { - /* - ** do not set ActivePort here, thus a port - ** switch is issued after net up. - */ - Port = 1; - pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; + /* + ** do not set ActivePort here, thus a port + ** switch is issued after net up. + */ + if (pAC->GIni.GIMacsFound == 1) { + printk("sk98lin: Illegal value \"B\" for PrefPort.\n" + " Port B not available on single port adapters.\n"); + + pAC->ActivePort = 0; + pAC->Rlmt.Net[0].Preference = -1; /* auto */ + pAC->Rlmt.Net[0].PrefPort = 0; + } else { + Port = 1; + pAC->Rlmt.Net[0].Preference = Port; + pAC->Rlmt.Net[0].PrefPort = Port; + } } else { - printk("%s: Illegal value \"%s\" for PrefPort\n", - pAC->dev[0]->name, PrefPort[pAC->Index]); + printk("sk98lin: Illegal value \"%s\" for PrefPort\n", + PrefPort[pAC->Index]); } } @@ -4350,9 +4519,9 @@ pAC->RlmtMode = SK_RLMT_CHECK_LINK; pAC->RlmtNets = 2; } else { - printk("%s: Illegal value \"%s\" for" + printk("sk98lin: Illegal value \"%s\" for" " RlmtMode, using default\n", - pAC->dev[0]->name, RlmtMode[pAC->Index]); + RlmtMode[pAC->Index]); pAC->RlmtMode = 0; } } else { @@ -4363,97 +4532,111 @@ ** Check the interrupt moderation parameters */ if (Moderation[pAC->Index] != NULL) { - if (strcmp(Moderation[pAC->Index], "Static") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; - } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC; - } else { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } + if (strcmp(Moderation[pAC->Index], "") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } else if (strcmp(Moderation[pAC->Index], "Static") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; + } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC; + } else if (strcmp(Moderation[pAC->Index], "None") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } else { + printk("sk98lin: Illegal value \"%s\" for Moderation.\n" + " Disable interrupt moderation.\n", + Moderation[pAC->Index]); + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + } } else { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; } if (Stats[pAC->Index] != NULL) { - if (strcmp(Stats[pAC->Index], "Yes") == 0) { - pAC->DynIrqModInfo.DisplayStats = SK_TRUE; - } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; - } + if (strcmp(Stats[pAC->Index], "Yes") == 0) { + pAC->DynIrqModInfo.DisplayStats = SK_TRUE; + } else { + pAC->DynIrqModInfo.DisplayStats = SK_FALSE; + } } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; + pAC->DynIrqModInfo.DisplayStats = SK_FALSE; } - if (ModerationMask[pAC->Index] != NULL) { - if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; - } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; - } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; - } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; - } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else { /* some rubbish */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; - } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } - - if (AutoSizing[pAC->Index] != NULL) { - if (strcmp(AutoSizing[pAC->Index], "On") == 0) { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } else { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } + if (ModerationMask[pAC->Index] != NULL) { + if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; + } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; + } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; + } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } else { /* some rubbish */ + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; + } + } else { /* operator has stated nothing */ + pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + } + + if (AutoSizing[pAC->Index] != NULL) { + if (strcmp(AutoSizing[pAC->Index], "On") == 0) { + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + } else { + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + } + } else { /* operator has stated nothing */ + pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + } - if (IntsPerSec[pAC->Index] != 0) { - if ((IntsPerSec[pAC->Index]< 30) || (IntsPerSec[pAC->Index]> 40000)) { - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; - } else { - pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; - } - } else { - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; - } + if (IntsPerSec[pAC->Index] != 0) { + if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || + (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { + printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n" + " Using default value of %i.\n", + IntsPerSec[pAC->Index], + C_INT_MOD_IPS_LOWER_RANGE, + C_INT_MOD_IPS_UPPER_RANGE, + C_INTS_PER_SEC_DEFAULT); + pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; + } else { + pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; + } + } else { + pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; + } - /* + /* ** Evaluate upper and lower moderation threshold */ - pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = - pAC->DynIrqModInfo.MaxModIntsPerSec + - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); - - pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = - pAC->DynIrqModInfo.MaxModIntsPerSec - - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); + pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = + pAC->DynIrqModInfo.MaxModIntsPerSec + + (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); + + pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = + pAC->DynIrqModInfo.MaxModIntsPerSec - + (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); - pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ + pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ } /* GetConfiguration */ @@ -4816,6 +4999,7 @@ spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); + SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; spin_unlock_irqrestore( @@ -4851,6 +5035,10 @@ FromPort = Param.Para32[0]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET UP EVENT, Port: %d ", Param.Para32[0])); + /* Mac update */ + SkAddrMcUpdate(pAC,IoC, FromPort); + + if (DoPrintInterfaceChange) { printk("%s: network connection up using" " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); @@ -4866,8 +5054,6 @@ printk(" speed: unknown\n"); } - /* Mac update */ - SkAddrMcUpdate(pAC,IoC, FromPort); Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; if (Stat == SK_LMODE_STAT_AUTOHALF || @@ -4945,6 +5131,9 @@ printk(" rx-checksum: disabled\n"); #endif + } else { + DoPrintInterfaceChange = SK_TRUE; + } if ((Param.Para32[0] != pAC->ActivePort) && (pAC->RlmtNets == 1)) { @@ -4962,7 +5151,12 @@ /* action list 7 */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET DOWN EVENT ")); - printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name); + if (DoPrintInterfaceChange) { + printk("%s: network connection down\n", + pAC->dev[Param.Para32[1]]->name); + } else { + DoPrintInterfaceChange = SK_TRUE; + } pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING; break; case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ @@ -5147,6 +5341,229 @@ } /* SkErrorLog */ +#ifdef SK_DIAG_SUPPORT + +/***************************************************************************** + * + * SkDrvEnterDiagMode - handles DIAG attach request + * + * Description: + * Notify the kernel to NOT access the card any longer due to DIAG + * Deinitialize the Card + * + * Returns: + * int + */ +int SkDrvEnterDiagMode( +SK_AC *pAc) /* pointer to adapter context */ +{ + SK_AC *pAC = NULL; + DEV_NET *pNet = NULL; + + pNet = (DEV_NET *) pAc->dev[0]->priv; + pAC = pNet->pAC; + + SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); + + pAC->DiagModeActive = DIAG_ACTIVE; + if (pAC->BoardLevel > SK_INIT_DATA) { + if (pNet->Up) { + pAC->WasIfUp[0] = SK_TRUE; + pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ + } else { + pAC->WasIfUp[0] = SK_FALSE; + } + if (pNet != (DEV_NET *) pAc->dev[1]->priv) { + pNet = (DEV_NET *) pAc->dev[1]->priv; + if (pNet->Up) { + pAC->WasIfUp[1] = SK_TRUE; + pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */ + } else { + pAC->WasIfUp[1] = SK_FALSE; + } + } + pAC->BoardLevel = SK_INIT_DATA; + } + return(0); +} + +/***************************************************************************** + * + * SkDrvLeaveDiagMode - handles DIAG detach request + * + * Description: + * Notify the kernel to may access the card again after use by DIAG + * Initialize the Card + * + * Returns: + * int + */ +int SkDrvLeaveDiagMode( +SK_AC *pAc) /* pointer to adapter control context */ +{ + SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), + sizeof(SK_PNMI_STRUCT_DATA)); + pAc->DiagModeActive = DIAG_NOTACTIVE; + pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; + if (pAc->WasIfUp[0] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvInitAdapter(pAc, 0); /* first device */ + } + if (pAc->WasIfUp[1] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; + SkDrvInitAdapter(pAc, 1); /* second device */ + } + return(0); +} + +/***************************************************************************** + * + * ParseDeviceNbrFromSlotName - Evaluate PCI device number + * + * Description: + * This function parses the PCI slot name information string and will + * retrieve the devcie number out of it. The slot_name maintianed by + * linux is in the form of '02:0a.0', whereas the first two characters + * represent the bus number in hex (in the sample above this is + * pci bus 0x02) and the next two characters the device number (0x0a). + * + * Returns: + * SK_U32: The device number from the PCI slot name + */ + +static SK_U32 ParseDeviceNbrFromSlotName( +const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */ +{ + char *CurrCharPos = (char *) SlotName; + int FirstNibble = -1; + int SecondNibble = -1; + SK_U32 Result = 0; + + while (*CurrCharPos != '\0') { + if (*CurrCharPos == ':') { + while (*CurrCharPos != '.') { + CurrCharPos++; + if ( (*CurrCharPos >= '0') && + (*CurrCharPos <= '9')) { + if (FirstNibble == -1) { + /* dec. value for '0' */ + FirstNibble = *CurrCharPos - 48; + } else { + SecondNibble = *CurrCharPos - 48; + } + } else if ( (*CurrCharPos >= 'a') && + (*CurrCharPos <= 'f') ) { + if (FirstNibble == -1) { + FirstNibble = *CurrCharPos - 87; + } else { + SecondNibble = *CurrCharPos - 87; + } + } else { + Result = 0; + } + } + + Result = FirstNibble; + Result = Result << 4; /* first nibble is higher one */ + Result = Result | SecondNibble; + } + CurrCharPos++; /* next character */ + } + return (Result); +} + +/**************************************************************************** + * + * SkDrvDeInitAdapter - deinitialize adapter (this function is only + * called if Diag attaches to that card) + * + * Description: + * Close initialized adapter. + * + * Returns: + * 0 - on success + * error code - on error + */ +static int SkDrvDeInitAdapter( +SK_AC *pAC, /* pointer to adapter context */ +int devNbr) /* what device is to be handled */ +{ + struct SK_NET_DEVICE *dev; + + dev = pAC->dev[devNbr]; + + /* + ** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4) + ** or module_put() (2.6) to decrease the number of users for + ** a device, but if a device is to be put under control of + ** the DIAG, that count is OK already and does not need to + ** be adapted! Hence the opposite MOD_INC_USE_COUNT or + ** try_module_get() needs to be used again to correct that. + */ + MOD_INC_USE_COUNT; + + if (SkGeClose(dev) != 0) { + MOD_DEC_USE_COUNT; + return (-1); + } + return (0); + +} /* SkDrvDeInitAdapter() */ + +/**************************************************************************** + * + * SkDrvInitAdapter - Initialize adapter (this function is only + * called if Diag deattaches from that card) + * + * Description: + * Close initialized adapter. + * + * Returns: + * 0 - on success + * error code - on error + */ +static int SkDrvInitAdapter( +SK_AC *pAC, /* pointer to adapter context */ +int devNbr) /* what device is to be handled */ +{ + struct SK_NET_DEVICE *dev; + + dev = pAC->dev[devNbr]; + + if (SkGeOpen(dev) != 0) { + return (-1); + } else { + /* + ** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) + ** or try_module_get() (2.6) to increase the number of + ** users for a device, but if a device was just under + ** control of the DIAG, that count is OK already and + ** does not need to be adapted! Hence the opposite + ** MOD_DEC_USE_COUNT or module_put() needs to be used + ** again to correct that. + */ + MOD_DEC_USE_COUNT; + } + + /* + ** Use correct MTU size and indicate to kernel TX queue can be started + */ + if (SkGeChangeMtu(dev, dev->mtu) != 0) { + return (-1); + } + return (0); + +} /* SkDrvInitAdapter */ + +#endif + #ifdef DEBUG /****************************************************************************/ /* "debug only" section *****************************************************/ diff -urN linux-2.4.24/drivers/net/sk98lin/skgehwt.c linux-2.4.25/drivers/net/sk98lin/skgehwt.c --- linux-2.4.24/drivers/net/sk98lin/skgehwt.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skgehwt.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,10 +1,10 @@ /****************************************************************************** * * Name: skgehwt.c - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.14 $ - * Date: $Date: 2003/05/13 18:01:58 $ - * Purpose: Hardware Timer. + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.15 $ + * Date: $Date: 2003/09/16 13:41:23 $ + * Purpose: Hardware Timer * ******************************************************************************/ @@ -27,6 +27,10 @@ * History: * * $Log: skgehwt.c,v $ + * Revision 1.15 2003/09/16 13:41:23 rschmidt + * Added (C) Marvell to SysKonnectFileId + * Editorial changes + * * Revision 1.14 2003/05/13 18:01:58 mkarl * Editorial changes. * @@ -69,19 +73,15 @@ * * Revision 1.1 1998/08/05 11:28:36 gklug * first version: adapted from SMT/FDDI - * - * - * * ******************************************************************************/ - /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.14 2003/05/13 18:01:58 mkarl Exp $" ; + "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -89,10 +89,7 @@ #ifdef __C2MAN__ /* - Hardware Timer function queue management. - - General Description: - + * Hardware Timer function queue management. */ intro() {} @@ -117,9 +114,9 @@ { pAC->Hwt.TStart = 0 ; pAC->Hwt.TStop = 0 ; - pAC->Hwt.TActive = SK_FALSE ; + pAC->Hwt.TActive = SK_FALSE; - SkHwtStop(pAC,Ioc) ; + SkHwtStop(pAC, Ioc); } /* @@ -132,28 +129,29 @@ SK_IOC Ioc, /* IoContext */ SK_U32 Time) /* Time in units of 16us to load the timer with. */ { - SK_U32 Cnt ; + SK_U32 Cnt; if (Time > SK_HWT_MAX) - Time = SK_HWT_MAX ; + Time = SK_HWT_MAX; - pAC->Hwt.TStart = Time ; - pAC->Hwt.TStop = 0L ; + pAC->Hwt.TStart = Time; + pAC->Hwt.TStop = 0L; - Cnt = Time ; + Cnt = Time; /* * if time < 16 us * time = 16 us */ if (!Cnt) { - Cnt++ ; + Cnt++; } - SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ; - SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ; /* Start timer. */ + SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC); + + SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */ - pAC->Hwt.TActive = SK_TRUE ; + pAC->Hwt.TActive = SK_TRUE; } /* @@ -164,10 +162,11 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ; - SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ; + SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP); + + SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ); - pAC->Hwt.TActive = SK_FALSE ; + pAC->Hwt.TActive = SK_FALSE; } @@ -182,26 +181,31 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SK_U32 TRead ; - SK_U32 IStatus ; + SK_U32 TRead; + SK_U32 IStatus; if (pAC->Hwt.TActive) { - SkHwtStop(pAC,Ioc) ; + + SkHwtStop(pAC, Ioc); SK_IN32(Ioc, B2_TI_VAL, &TRead); TRead /= SK_HWT_FAC; SK_IN32(Ioc, B0_ISRC, &IStatus); - /* Check if timer expired (or wraparound). */ + /* Check if timer expired (or wraped around) */ if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { - SkHwtStop(pAC,Ioc) ; - pAC->Hwt.TStop = pAC->Hwt.TStart ; - } else { - pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ; + + SkHwtStop(pAC, Ioc); + + pAC->Hwt.TStop = pAC->Hwt.TStart; + } + else { + + pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; } } - return (pAC->Hwt.TStop) ; + return(pAC->Hwt.TStop); } /* @@ -211,9 +215,11 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - SkHwtStop(pAC,Ioc); + SkHwtStop(pAC, Ioc); + pAC->Hwt.TStop = pAC->Hwt.TStart; - SkTimerDone(pAC,Ioc) ; + + SkTimerDone(pAC, Ioc); } /* End of file */ diff -urN linux-2.4.24/drivers/net/sk98lin/skgeinit.c linux-2.4.25/drivers/net/sk98lin/skgeinit.c --- linux-2.4.24/drivers/net/sk98lin/skgeinit.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skgeinit.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgeinit.c * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.93 $ - * Date: $Date: 2003/05/28 15:44:43 $ + * Version: $Revision: 1.97 $ + * Date: $Date: 2003/10/02 16:45:31 $ * Purpose: Contains functions to initialize the adapter * ******************************************************************************/ @@ -27,6 +27,32 @@ * History: * * $Log: skgeinit.c,v $ + * Revision 1.97 2003/10/02 16:45:31 rschmidt + * Replaced default values of GMAC parameters with defines. + * Removed hard reset of MACs in SkGeDeInit(). + * Added define SK_PHY_LP_MODE around power saving mode in SkGeDeInit(). + * Added check for VAUX available before switch power to VAUX. + * + * Revision 1.96 2003/09/18 14:02:41 rroesler + * Add: Perform a hardreset of MACs in GeDeInit() + * + * Revision 1.95 2003/09/16 14:26:59 rschmidt + * Added switch power to VCC (WA for VAUX problem) in SkGeInit1(). + * Fixed setting PHY to coma mode and D3 power state in SkGeDeInit(). + * Editorial changes. + * + * Revision 1.94 2003/09/16 07:17:10 mschmid + * Added init for new members in port structure for MAC control + * - PMacColThres + * - PMacJamLen + * - PMacJamIpgVal + * - PMacJamIpgData + * - PMacIpgData + * - PMacLimit4 + * Added init for PHY power state in port structure + * - PPhyPowerState + * Added shutdown handling for Yukon Plus in SkGeDeInit() + * * Revision 1.93 2003/05/28 15:44:43 rschmidt * Added check for chip Id on WOL WA for chip Rev. A. * Added setting of GILevel in SkGeDeInit(). @@ -446,7 +472,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skgeinit.c,v 1.93 2003/05/28 15:44:43 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell."; #endif struct s_QOffTab { @@ -1013,8 +1039,6 @@ * - enable the FIFO */ - Word = (SK_U16)GMF_RX_CTRL_DEF; - #ifdef GENESIS if (pAC->GIni.GIGenesis) { /* Configure Rx MAC FIFO */ @@ -1039,6 +1063,8 @@ /* set Rx GMAC FIFO Flush Mask */ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); + Word = (SK_U16)GMF_RX_CTRL_DEF; + /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { @@ -1809,6 +1835,13 @@ pPrt->PAutoNegFail = SK_FALSE; pPrt->PHWLinkUp = SK_FALSE; pPrt->PLinkBroken = SK_TRUE; /* See WA code */ + pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + pPrt->PMacColThres = TX_COL_DEF; + pPrt->PMacJamLen = TX_JAM_LEN_DEF; + pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; + pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; + pPrt->PMacIpgData = IPG_DATA_DEF; + pPrt->PMacLimit4 = SK_FALSE; } pAC->GIni.GIPortUsage = SK_RED_LINK; @@ -1963,7 +1996,7 @@ /* restore CLK_RUN bits */ SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); - + /* read Chip Identification Number */ SK_IN8(IoC, B2_CHIP_ID, &Byte); pAC->GIni.GIChipId = Byte; @@ -2053,6 +2086,10 @@ } } + /* switch power to VCC (WA for VAUX problem) */ + SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | + PC_VAUX_OFF | PC_VCC_ON)); + /* read the Interrupt source */ SK_IN32(IoC, B0_ISRC, &DWord); @@ -2395,6 +2432,11 @@ int i; SK_U16 Word; +#ifdef SK_PHY_LP_MODE + SK_U8 Byte; + SK_U16 PmCtlSts; +#endif /* SK_PHY_LP_MODE */ + #if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); @@ -2409,6 +2451,38 @@ } } +#ifdef SK_PHY_LP_MODE + /* + * for power saving purposes within mobile environments + * we set the PHY to coma mode and switch to D3 power state. + */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* for all ports switch PHY to coma mode */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); + } + + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; + + SK_OUT8(IoC, B0_POWER_CTRL, Byte); + } + + /* switch to D3 state */ + SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); + + PmCtlSts |= PCI_PM_STATE_D3; + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); + } +#endif /* SK_PHY_LP_MODE */ + /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not diff -urN linux-2.4.24/drivers/net/sk98lin/skgemib.c linux-2.4.25/drivers/net/sk98lin/skgemib.c --- linux-2.4.24/drivers/net/sk98lin/skgemib.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skgemib.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgemib.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.9 $ - * Date: $Date: 2003/05/23 12:55:20 $ + * Version: $Revision: 1.11 $ + * Date: $Date: 2003/09/15 13:38:12 $ * Purpose: Private Network Management Interface Management Database * ****************************************************************************/ @@ -27,6 +27,19 @@ * History: * * $Log: skgemib.c,v $ + * Revision 1.11 2003/09/15 13:38:12 tschilli + * OID_SKGE_PHY_LP_MODE included only after using #define SK_PHY_LP_MODE. + * + * Revision 1.10 2003/08/15 12:28:59 tschilli + * Added new OIDs: + * OID_SKGE_DRIVER_RELDATE + * OID_SKGE_DRIVER_FILENAME + * OID_SKGE_CHIPID + * OID_SKGE_RAMSIZE + * OID_SKGE_VAUXAVAIL + * OID_SKGE_PHY_TYPE + * OID_SKGE_PHY_LP_MODE + * * Revision 1.9 2003/05/23 12:55:20 tschilli * OID_SKGE_BOARDLEVEL added. * @@ -356,6 +369,16 @@ 0, SK_PNMI_MAI_OFF(DriverVersion), SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_RELDATE, + 1, + 0, + SK_PNMI_MAI_OFF(DriverReleaseDate), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_FILENAME, + 1, + 0, + SK_PNMI_MAI_OFF(DriverFileName), + SK_PNMI_RO, General, 0}, {OID_SKGE_HW_DESCR, 1, 0, @@ -371,6 +394,21 @@ 0, SK_PNMI_MAI_OFF(Chipset), SK_PNMI_RO, General, 0}, + {OID_SKGE_CHIPID, + 1, + 0, + SK_PNMI_MAI_OFF(ChipId), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RAMSIZE, + 1, + 0, + SK_PNMI_MAI_OFF(RamSize), + SK_PNMI_RO, General, 0}, + {OID_SKGE_VAUXAVAIL, + 1, + 0, + SK_PNMI_MAI_OFF(VauxAvail), + SK_PNMI_RO, General, 0}, {OID_SKGE_ACTION, 1, 0, @@ -876,6 +914,18 @@ sizeof(SK_PNMI_CONF), SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_TYPE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), + SK_PNMI_RO, MacPrivateConf, 0}, +#ifdef SK_PHY_LP_MODE + {OID_SKGE_PHY_LP_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), + SK_PNMI_RW, MacPrivateConf, 0}, +#endif {OID_SKGE_LINK_CAP, SK_PNMI_MAC_ENTRIES, sizeof(SK_PNMI_CONF), diff -urN linux-2.4.24/drivers/net/sk98lin/skgepnmi.c linux-2.4.25/drivers/net/sk98lin/skgepnmi.c --- linux-2.4.24/drivers/net/sk98lin/skgepnmi.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skgepnmi.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgepnmi.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.109 $ - * Date: $Date: 2003/07/17 14:15:24 $ + * Version: $Revision: 1.111 $ + * Date: $Date: 2003/09/15 13:35:35 $ * Purpose: Private Network Management Interface * ****************************************************************************/ @@ -27,6 +27,22 @@ * History: * * $Log: skgepnmi.c,v $ + * Revision 1.111 2003/09/15 13:35:35 tschilli + * Code for OID_SKGE_PHY_LP_MODE completed (using #define SK_PHY_LP_MODE). + * SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions() changed. + * + * Revision 1.110 2003/08/15 12:28:04 tschilli + * Added new OIDs: + * OID_SKGE_DRIVER_RELDATE + * OID_SKGE_DRIVER_FILENAME + * OID_SKGE_CHIPID + * OID_SKGE_RAMSIZE + * OID_SKGE_VAUXAVAIL + * OID_SKGE_PHY_TYPE + * OID_SKGE_PHY_LP_MODE + * + * Added SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions(). + * * Revision 1.109 2003/07/17 14:15:24 tschilli * Bug in SkPnmiGenIoctl() fixed. * @@ -471,7 +487,7 @@ #ifndef _lint static const char SysKonnectFileId[] = - "@(#) $Id: skgepnmi.c,v 1.109 2003/07/17 14:15:24 tschilli Exp $ (C) Marvell."; + "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell."; #endif /* !_lint */ #include "h/skdrv1st.h" @@ -4008,14 +4024,6 @@ #endif /* SK_NDIS_64BIT_CTR */ break; - case OID_SKGE_BOARDLEVEL: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - case OID_SKGE_PORT_NUMBER: case OID_SKGE_DEVICE_TYPE: case OID_SKGE_RESULT: @@ -4023,6 +4031,9 @@ case OID_GEN_TRANSMIT_QUEUE_LENGTH: case OID_SKGE_TRAP_NUMBER: case OID_SKGE_MDB_VERSION: + case OID_SKGE_BOARDLEVEL: + case OID_SKGE_CHIPID: + case OID_SKGE_RAMSIZE: if (*pLen < sizeof(SK_U32)) { *pLen = sizeof(SK_U32); @@ -4043,6 +4054,7 @@ case OID_SKGE_BUS_WIDTH: case OID_SKGE_SENSOR_NUMBER: case OID_SKGE_CHKSM_NUMBER: + case OID_SKGE_VAUXAVAIL: if (*pLen < sizeof(SK_U8)) { *pLen = sizeof(SK_U8); @@ -4234,6 +4246,66 @@ *pLen = Len; break; + case OID_SKGE_DRIVER_RELDATE: + if (pAC->Pnmi.pDriverReleaseDate == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, + SK_PNMI_ERR053MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, + SK_PNMI_ERR054MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_DRIVER_FILENAME: + if (pAC->Pnmi.pDriverFileName == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, + SK_PNMI_ERR055MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, + SK_PNMI_ERR056MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); + *pLen = Len; + break; + case OID_SKGE_HW_DESCR: /* * The hardware description is located in the VPD. This @@ -4291,8 +4363,25 @@ *pLen = sizeof(SK_U16); break; + case OID_SKGE_CHIPID: + Val32 = pAC->GIni.GIChipId; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_RAMSIZE: + Val32 = pAC->GIni.GIRamSize; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VAUXAVAIL: + *pBuf = (char) pAC->GIni.GIVauxAvail; + *pLen = sizeof(char); + break; + case OID_SKGE_BUS_TYPE: - *pBuf = (char)SK_PNMI_BUS_PCI; + *pBuf = (char) SK_PNMI_BUS_PCI; *pLen = sizeof(char); break; @@ -5435,6 +5524,9 @@ case OID_SKGE_SPEED_CAP: case OID_SKGE_SPEED_MODE: case OID_SKGE_SPEED_STATUS: +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: +#endif if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); @@ -5443,6 +5535,7 @@ break; case OID_SKGE_MTU: + case OID_SKGE_PHY_TYPE: if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); @@ -5488,6 +5581,49 @@ Offset += sizeof(char); break; + case OID_SKGE_PHY_TYPE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; + SK_PNMI_STORE_U32(pBufPtr, Val32); + } + } + else { /* DualNetMode */ + + Val32 = pAC->GIni.GP[NetIndex].PhyType; + SK_PNMI_STORE_U32(pBufPtr, Val32); + } + Offset += sizeof(SK_U32); + break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + } + else { /* DualNetMode */ + + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + Offset += sizeof(SK_U8); + break; +#endif + case OID_SKGE_LINK_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { @@ -5804,6 +5940,16 @@ } break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +#endif + case OID_SKGE_MTU: if (*pLen < sizeof(SK_U32)) { @@ -6160,6 +6306,116 @@ Offset += sizeof(SK_U32); break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + /* The preset ends here */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + Offset = 0; + continue; + } + else { + /* Set value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + switch (*(pBuf + Offset)) { + case 0: + /* If LowPowerMode is active, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + case 1: + case 2: + case 3: + case 4: + /* If no LowPowerMode is active, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + } + else { /* DualNetMode */ + + switch (*(pBuf + Offset)) { + case 0: + /* If we are in a LowPowerMode, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + case 1: + case 2: + case 3: + case 4: + /* If we are not already in LowPowerMode, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + else { + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + Offset += sizeof(SK_U8); + break; +#endif default: SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, @@ -6318,6 +6574,7 @@ unsigned int PhysPortMax; unsigned int PhysPortIndex; SK_U8 Val8; + SK_U32 Val32; SK_BOOL PortActiveFlag; SK_GEPORT *pPrt; @@ -6340,6 +6597,14 @@ switch (Id) { + case OID_SKGE_PHY_TYPE: + /* Check if it is the first active port */ + if (*pBuf == 0) { + Val32 = pPrt->PhyType; + SK_PNMI_STORE_U32(pBuf, Val32); + continue; + } + case OID_SKGE_LINK_CAP: /* @@ -7974,6 +8239,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ { + SK_U32 DiagStatus; SK_U32 RetCode = SK_PNMI_ERR_GENERAL; /* @@ -8012,7 +8278,8 @@ switch (Id) { case OID_SKGE_DIAG_MODE: - SK_PNMI_STORE_U32(pBuf, pAC->DiagModeActive); + DiagStatus = pAC->Pnmi.DiagAttached; + SK_PNMI_STORE_U32(pBuf, DiagStatus); *pLen = sizeof(SK_U32); RetCode = SK_PNMI_ERR_OK; break; @@ -8022,7 +8289,6 @@ RetCode = SK_PNMI_ERR_GENERAL; break; } - return (RetCode); } @@ -8039,23 +8305,84 @@ /* Handle the SET. */ switch (*pBuf) { - + + /* Attach the DIAG to this adapter. */ + case SK_DIAG_ATTACHED: + /* Check if we come from running */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; + } + break; + /* Enter the DIAG mode in the driver. */ - case 1: - /* If DiagMode is not active, we can enter it. */ - if (!pAC->DiagModeActive) { + case SK_DIAG_RUNNING: + RetCode = SK_PNMI_ERR_OK; + + /* + * If DiagAttached is set, we can tell the driver + * to enter the DIAG mode. + */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + /* If DiagMode is not active, we can enter it. */ + if (!pAC->DiagModeActive) { - RetCode = SkDrvEnterDiagMode(pAC); + RetCode = SkDrvEnterDiagMode(pAC); + } + else { + + RetCode = SK_PNMI_ERR_GENERAL; + } } else { RetCode = SK_PNMI_ERR_GENERAL; } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; + } break; - /* Leave the DIAG mode in the driver. */ - case 0: - RetCode = SkDrvLeaveDiagMode(pAC); + case SK_DIAG_IDLE: + /* Check if we come from running */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; + } break; default: diff -urN linux-2.4.24/drivers/net/sk98lin/skgesirq.c linux-2.4.25/drivers/net/sk98lin/skgesirq.c --- linux-2.4.24/drivers/net/sk98lin/skgesirq.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skgesirq.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skgesirq.c * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.91 $ - * Date: $Date: 2003/07/04 12:46:22 $ + * Version: $Revision: 1.92 $ + * Date: $Date: 2003/09/16 14:37:07 $ * Purpose: Special IRQ module * ******************************************************************************/ @@ -27,6 +27,12 @@ * History: * * $Log: skgesirq.c,v $ + * Revision 1.92 2003/09/16 14:37:07 rschmidt + * Added debug messages in some SkGePortCheckUp...() routines. + * Fixed compiler warnings for different types. + * Avoided port check up in reset state (eg. coma mode). + * Editorial changes. + * * Revision 1.91 2003/07/04 12:46:22 rschmidt * Added debug messages in SkGePortCheckUpGmac(). * Added error log message and new driver event SK_DRV_DOWNSHIFT_DET @@ -410,7 +416,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skgesirq.c,v 1.91 2003/07/04 12:46:22 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -490,7 +496,7 @@ ("AutoSensing: First mode %d on Port %d\n", (int)SK_LMODE_AUTOFULL, Port)); - pPrt->PLinkMode = SK_LMODE_AUTOFULL; + pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; return; } /* SkHWInitDefSense */ @@ -606,7 +612,7 @@ /* Reset Port stati */ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED; /* Re-init Phy especially when the AutoSense default is set now */ SkMacInitPhy(pAC, IoC, Port, SK_FALSE); @@ -655,19 +661,19 @@ case SK_LSPEED_AUTO: /* default is 1000 Mbps */ case SK_LSPEED_1000MBPS: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; break; case SK_LSPEED_100MBPS: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; break; case SK_LSPEED_10MBPS: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; break; } /* Set Link Mode Status */ if (pPrt->PLinkMode == SK_LMODE_FULL) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL; } else { pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; @@ -1598,8 +1604,7 @@ * (clear Page Received bit if set) */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); + return(SK_HW_PS_LINK); } @@ -1870,7 +1875,7 @@ SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat)); + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); @@ -1897,8 +1902,11 @@ if (AutoNeg) { if ((PhyStat & PHY_ST_AN_OVER) != 0) { + SkHWLinkUp(pAC, IoC, Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); + if (Done != SK_AND_OK) { #ifdef DEBUG /* Get PHY parameters, for debugging only */ @@ -1924,9 +1932,6 @@ (void *)NULL); } #endif /* DEBUG */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -1989,9 +1994,22 @@ SK_U16 PhySpecStat;/* PHY Specific Status */ SK_U16 ResAb; /* Master/Slave resolution */ SK_EVPARA Para; +#ifdef DEBUG + SK_U16 Word; /* I/O helper */ +#endif /* DEBUG */ pPrt = &pAC->GIni.GP[Port]; + if (pPrt->PHWLinkUp) { + return(SK_HW_PS_NONE); + } + + /* Read PHY Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); + /* Read PHY Interrupt Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); @@ -2005,16 +2023,6 @@ ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); } - if (pPrt->PHWLinkUp) { - return(SK_HW_PS_NONE); - } - - /* Read PHY Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat)); - SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); @@ -2034,7 +2042,20 @@ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg: %d, PhySpecStat: 0x%04X\n", AutoNeg, PhySpecStat)); + ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); + +#ifdef DEBUG + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); + + if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || + (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { + /* Read PHY Next Page Link Partner */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Page Received, NextPage: 0x%04X\n", Word)); + } +#endif /* DEBUG */ if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { return(SK_HW_PS_NONE); @@ -2069,8 +2090,6 @@ return(SK_HW_PS_RESTART); } - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -2179,8 +2198,6 @@ * extra link down/ups */ SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); return(SK_HW_PS_LINK); } } @@ -2278,8 +2295,14 @@ switch (Event) { case SK_HWEV_WATIM: - /* Check whether port came up */ - PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); + if (pPrt->PState == SK_PRT_RESET) { + + PortStat = SK_HW_PS_NONE; + } + else { + /* Check whether port came up */ + PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); + } switch (PortStat) { case SK_HW_PS_RESTART: diff -urN linux-2.4.24/drivers/net/sk98lin/ski2c.c linux-2.4.25/drivers/net/sk98lin/ski2c.c --- linux-2.4.24/drivers/net/sk98lin/ski2c.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/ski2c.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,16 +1,17 @@ /****************************************************************************** * * Name: ski2c.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.57 $ - * Date: $Date: 2003/01/28 09:17:38 $ + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.59 $ + * Date: $Date: 2003/10/20 09:07:25 $ * Purpose: Functions to access Voltage and Temperature Sensor * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,14 @@ * History: * * $Log: ski2c.c,v $ + * Revision 1.59 2003/10/20 09:07:25 rschmidt + * Added cast SK_U32 in SkI2cWrite() to avoid compiler warning. + * Editorial changes. + * + * Revision 1.58 2003/09/23 09:22:53 malthoff + * Parameter I2cDevSize added in SkI2cRead and SkI2cWrite to + * support larger devices on the TWSI bus. + * * Revision 1.57 2003/01/28 09:17:38 rschmidt * Fixed handling for sensors on YUKON Fiber. * Editorial changes. @@ -224,15 +233,15 @@ * Created. Sources taken from ML Projekt. * Sources have to be reworked for GE. * - * ******************************************************************************/ - /* * I2C Protocol */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $"; + "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. "; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -312,7 +321,7 @@ {} #endif -#ifdef SK_DIAG +#ifdef SK_DIAG /* * I2C Fast Mode timing values used by the LM80. * If new devices are added to the I2C bus the timing values have to be checked. @@ -516,7 +525,6 @@ { /* * Received bit must be zero. - * */ SkI2cSndBit(IoC, 0); } /* SkI2cSndAck */ @@ -590,7 +598,7 @@ return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); } /* SkI2cSndDev */ -#endif /* SK_DIAG */ +#endif /* SK_DIAG */ /*----------------- I2C CTRL Register Functions ----------*/ @@ -620,7 +628,7 @@ SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ return(1); } @@ -661,15 +669,19 @@ } StartTime = SkOsGetTime(pAC); + do { if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { + SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ return; } + SK_IN32(IoC, B0_ISRC, &IrqSrc); + } while ((IrqSrc & IS_I2C_READY) == 0); pSen->SenState = SK_SEN_IDLE; @@ -687,18 +699,19 @@ SK_IOC IoC, /* I/O Context */ SK_U32 I2cData, /* I2C Data to write */ int I2cDev, /* I2C Device Address */ +int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag */ { SK_OUT32(IoC, B2_I2C_DATA, I2cData); - SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst); + + SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); return(SkI2cWait(pAC, IoC, I2C_WRITE)); } /* SkI2cWrite*/ #ifdef SK_DIAG - /* * reads a single byte or 4 bytes from the I2C device * @@ -708,23 +721,24 @@ SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int I2cDev, /* I2C Device Address */ +int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag */ { SK_U32 Data; SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst); + SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { w_print("%s\n", SKERR_I2C_E002MSG); } SK_IN32(IoC, B2_I2C_DATA, &Data); + return(Data); } /* SkI2cRead */ - -#endif /* SK_DIAG */ +#endif /* SK_DIAG */ /* @@ -745,9 +759,10 @@ if (pSen->SenRead != NULL) { return((*pSen->SenRead)(pAC, IoC, pSen)); } - else + else { return(0); /* no success */ -} /* SkI2cReadSensor*/ + } +} /* SkI2cReadSensor */ /* * Do the Init state 0 initialization @@ -761,12 +776,12 @@ pAC->I2c.CurrSens = 0; /* Begin with timeout control for state machine */ - pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; /* Set sensor number to zero */ pAC->I2c.MaxSens = 0; -#ifndef SK_DIAG +#ifndef SK_DIAG /* Initialize Number of Dummy Reads */ pAC->I2c.DummyReads = SK_MAX_SENSORS; #endif @@ -840,19 +855,20 @@ } /* Check for 64 Bit Yukon without sensors */ - if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) { + if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { return(0); } - (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0); + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); - (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0); + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0); + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0); + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); - (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0); + (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, + LM80_CFG, 0); /* * MaxSens has to be updated here, because PhyType is not @@ -957,7 +973,7 @@ pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; } else { - pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5"; + pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5"; pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; @@ -1015,9 +1031,9 @@ pAC->I2c.SenTable[i].SenDev = LM80_ADDR; } -#ifndef SK_DIAG +#ifndef SK_DIAG pAC->I2c.DummyReads = pAC->I2c.MaxSens; -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ /* Clear I2C IRQ */ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); @@ -1208,15 +1224,13 @@ pSen->SenLastErrLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, - SKERR_I2C_E011MSG); - } else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, - SKERR_I2C_E012MSG); - } else - { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, - SKERR_I2C_E015MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); } } } @@ -1235,8 +1249,7 @@ /* This state is the former one */ /* So check first whether we have to send a trap */ - if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > - CurrTime) { + if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { /* * Do NOT send the Trap. The hold back time * has to run out first. @@ -1245,8 +1258,7 @@ } /* Check now whether we have to log an Error */ - if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > - CurrTime) { + if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { /* * Do NOT log the error. The hold back time * has to run out first. @@ -1277,15 +1289,13 @@ pSen->SenLastWarnLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, - SKERR_I2C_E009MSG); - } else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, - SKERR_I2C_E010MSG); - } else - { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, - SKERR_I2C_E014MSG); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); } } } @@ -1317,7 +1327,7 @@ } } -#if 0 +#ifdef TEST_ONLY /* Dynamic thresholds also for VAUX of LM80 sensor */ if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { @@ -1359,7 +1369,7 @@ if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); } -} /* SkI2cCheckSensor*/ +} /* SkI2cCheckSensor */ /* @@ -1390,7 +1400,7 @@ if (ReadComplete) { /* Check sensor against defined thresholds */ - SkI2cCheckSensor (pAC, pSen); + SkI2cCheckSensor(pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; @@ -1414,7 +1424,7 @@ /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; - pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); @@ -1431,7 +1441,7 @@ if (ReadComplete) { /* Check sensor against defined thresholds */ - SkI2cCheckSensor (pAC, pSen); + SkI2cCheckSensor(pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; @@ -1496,4 +1506,4 @@ return(0); } /* SkI2cEvent*/ -#endif /* !SK_DIAG */ +#endif /* !SK_DIAG */ diff -urN linux-2.4.24/drivers/net/sk98lin/sklm80.c linux-2.4.25/drivers/net/sk98lin/sklm80.c --- linux-2.4.24/drivers/net/sk98lin/sklm80.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/net/sk98lin/sklm80.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,16 +1,17 @@ /****************************************************************************** * * Name: sklm80.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.20 $ - * Date: $Date: 2002/08/13 09:16:27 $ - * Purpose: Funktions to access Voltage and Temperature Sensor (LM80) + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.22 $ + * Date: $Date: 2003/10/20 09:08:21 $ + * Purpose: Functions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,15 +27,21 @@ * History: * * $Log: sklm80.c,v $ + * Revision 1.22 2003/10/20 09:08:21 rschmidt + * Editorial changes. + * + * Revision 1.21 2003/09/23 09:29:04 malthoff + * Parameter Dev_Size added to macro SK_I2C_CTL. + * * Revision 1.20 2002/08/13 09:16:27 rschmidt * Changed return value for SkLm80ReadSensor() back to 'int' - * Editorial changes + * Editorial changes. * * Revision 1.19 2002/08/06 09:43:31 jschmalz - * Extensions and changes for Yukon + * Extensions and changes for Yukon. * * Revision 1.18 2002/08/02 12:26:57 rschmidt - * Editorial changes + * Editorial changes. * * Revision 1.17 1999/11/22 13:35:51 cgoos * Changed license header to GPL. @@ -93,16 +100,15 @@ * Revision 1.1 1998/07/17 09:57:12 gklug * initial version * - * - * ******************************************************************************/ - /* LM80 functions */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ; + "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. "; +#endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ #include "h/lm80.h" @@ -202,7 +208,7 @@ switch (pSen->SenState) { case SK_SEN_IDLE: /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0); + SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); pSen->SenState = SK_SEN_VALUE ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); @@ -250,7 +256,7 @@ (pSen->SenValue % SK_LM80_TEMP_LSB); /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0); + SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); pSen->SenState = SK_SEN_VALEXT ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); @@ -284,3 +290,4 @@ /* Not completed */ return(0); } + diff -urN linux-2.4.24/drivers/net/sk98lin/skproc.c linux-2.4.25/drivers/net/sk98lin/skproc.c --- linux-2.4.24/drivers/net/sk98lin/skproc.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skproc.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,16 +1,17 @@ /****************************************************************************** * - * Name: skproc.c + * Name: skproc.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.2 $ - * Date: $Date: 2003/08/12 16:45:29 $ + * Version: $Revision: 1.11 $ + * Date: $Date: 2003/12/11 16:03:57 $ * Purpose: Funktions to display statictic data * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,33 @@ * History: * * $Log: skproc.c,v $ + * Revision 1.11 2003/12/11 16:03:57 mlindner + * Fix: Create backup from pnmi data structure + * + * Revision 1.10 2003/11/19 16:25:36 mlindner + * Fix: Print output as 64-bit digit + * + * Revision 1.9 2003/11/17 13:29:05 mlindner + * Fix: Editorial changes + * + * Revision 1.8 2003/11/13 14:18:48 rroesler + * Fix: added latest changes regarding the use of the proc system + * + * Revision 1.7 2003/11/10 09:35:07 rroesler + * Fix: diag backup restore of PNMI structure + * + * Revision 1.6 2003/11/07 17:31:39 rroesler + * Add: security counter for the proc file system + * + * Revision 1.5 2003/10/07 08:17:08 mlindner + * Fix: Copyright changes + * + * Revision 1.4 2003/09/01 15:29:24 mlindner + * Fix: Editorial changes + * + * Revision 1.3 2003/08/29 12:30:58 mlindner + * Add: Version entry in the proc file system + * * Revision 1.2 2003/08/12 16:45:29 mlindner * Add: Removed SkNumber and SkDoDiv * Add: Counter output as (unsigned long long) @@ -93,54 +121,83 @@ #include "h/skdrv1st.h" #include "h/skdrv2nd.h" +#include "h/skversion.h" - extern struct net_device *SkGeRootDev; +extern struct SK_NET_DEVICE *SkGeRootDev; +static int sk_proc_print(void *writePtr, char *format, ...); +static void sk_gen_browse(void *buffer); +int len; +struct proc_dir_entry *file = NULL; -int sk_proc_read(char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data); +/***************************************************************************** + * + * sk_proc_read - show proc information of a particular adapter + * + * Description: + * This function fills the proc entry with statistic data about + * the ethernet device. It invokes the generic sk_gen_browse() to + * print out all items one per one. + * + * Returns: number of bytes written + * + */ +int sk_proc_read(char *buffer, + char **buffer_location, + off_t offset, + int buffer_length, + int *eof, + void *data) +{ + void *castedBuffer = (void *) buffer; + file = (struct proc_dir_entry*) data; + len = 0; /* initial value */ + sk_gen_browse(castedBuffer); + if (offset >= len) { + *eof = 1; + return 0; + } + *buffer_location = buffer + offset; + if (buffer_length >= len - offset) { + *eof = 1; + } + return (min_t(int, buffer_length, len - offset)); +} /***************************************************************************** * - * sk_proc_read - print "summaries" entry + * sk_gen_browse -generic print "summaries" entry * * Description: * This function fills the proc entry with statistic data about * the ethernet device. * - * - * Returns: buffer with statistic data + * Returns: - * */ -int sk_proc_read(char *buffer, -char **buffer_location, -off_t offset, -int buffer_length, -int *eof, -void *data) +static void sk_gen_browse(void *buffer) { - int len = 0; - int t; - int i; - DEV_NET *pNet; - SK_AC *pAC; - char sens_msg[50]; - unsigned long Flags; - unsigned int Size; - struct SK_NET_DEVICE *next; - struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; - + struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; + struct SK_NET_DEVICE *next; SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_PNMI_STAT *pPnmiStat; - struct proc_dir_entry *file = (struct proc_dir_entry*) data; + unsigned long Flags; + unsigned int Size; + DEV_NET *pNet; + SK_AC *pAC; + char sens_msg[50]; + int MaxSecurityCount = 0; + int t; + int i; while (SkgeProcDev) { + MaxSecurityCount++; + if (MaxSecurityCount > 100) { + printk("Max limit for sk_proc_read security counter!\n"); + return; + } pNet = (DEV_NET*) SkgeProcDev->priv; pAC = pNet->pAC; next = pAC->Next; @@ -153,38 +210,52 @@ spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; +#ifdef SK_DIAG_SUPPORT + if (pAC->BoardLevel == SK_INIT_DATA) { + SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA)); + if (pAC->DiagModeActive == DIAG_NOTACTIVE) { + pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; + } + } else { + SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); + } +#else SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); +#endif spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); if (strcmp(pAC->dev[t-1]->name, file->name) == 0) { pPnmiStat = &pPnmiStruct->Stat[0]; - len = sprintf(buffer, + len = sk_proc_print(buffer, "\nDetailed statistic for device %s\n", pAC->dev[t-1]->name); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "=======================================\n"); /* Board statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nBoard statistics\n\n"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Active Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Preferred Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Bus speed (MHz) %d\n", pPnmiStruct->BusSpeed); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Bus width (Bit) %d\n", pPnmiStruct->BusWidth); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, + "Driver version %s\n", + VER_STRING); + len += sk_proc_print(buffer, "Hardware revision v%d.%d\n", (pAC->GIni.GIPciHwRev >> 4) & 0x0F, pAC->GIni.GIPciHwRev & 0x0F); @@ -196,7 +267,7 @@ case 1: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (C)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%02d\n", sens_msg, pAC->I2c.SenTable[i].SenValue / 10, @@ -204,7 +275,7 @@ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (F)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%02d\n", sens_msg, ((((pAC->I2c.SenTable[i].SenValue) @@ -215,7 +286,7 @@ case 2: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (V)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d.%03d\n", sens_msg, pAC->I2c.SenTable[i].SenValue / 1000, @@ -224,7 +295,7 @@ case 3: strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); strcat(sens_msg, " (rpm)"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "%-25s %d\n", sens_msg, pAC->I2c.SenTable[i].SenValue); @@ -235,14 +306,14 @@ } /*Receive statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nReceive statistics\n\n"); - len += sprintf(buffer + len, - "Received bytes %Ld\n", + len += sk_proc_print(buffer, + "Received bytes %Lu\n", (unsigned long long) pPnmiStat->StatRxOctetsOkCts); - len += sprintf(buffer + len, - "Received packets %Ld\n", + len += sk_proc_print(buffer, + "Received packets %Lu\n", (unsigned long long) pPnmiStat->StatRxOkCts); #if 0 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && @@ -256,110 +327,138 @@ pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - pPnmiStat->StatRxTooLongCts; - len += sprintf(buffer + len, - "Receive errors %Ld\n", + len += sk_proc_print(buffer, + "Receive errors %Lu\n", (unsigned long long) pPnmiStruct->InErrorsCts); - len += sprintf(buffer + len, - "Receive dropped %Ld\n", + len += sk_proc_print(buffer, + "Receive dropped %Lu\n", (unsigned long long) pPnmiStruct->RxNoBufCts); - len += sprintf(buffer + len, - "Received multicast %Ld\n", + len += sk_proc_print(buffer, + "Received multicast %Lu\n", (unsigned long long) pPnmiStat->StatRxMulticastOkCts); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Receive error types\n"); - len += sprintf(buffer + len, - " length %Ld\n", + len += sk_proc_print(buffer, + " length %Lu\n", (unsigned long long) pPnmiStat->StatRxRuntCts); - len += sprintf(buffer + len, - " buffer overflow %Ld\n", + len += sk_proc_print(buffer, + " buffer overflow %Lu\n", (unsigned long long) pPnmiStat->StatRxFifoOverflowCts); - len += sprintf(buffer + len, - " bad crc %Ld\n", + len += sk_proc_print(buffer, + " bad crc %Lu\n", (unsigned long long) pPnmiStat->StatRxFcsCts); - len += sprintf(buffer + len, - " framing %Ld\n", + len += sk_proc_print(buffer, + " framing %Lu\n", (unsigned long long) pPnmiStat->StatRxFramingCts); - len += sprintf(buffer + len, - " missed frames %Ld\n", + len += sk_proc_print(buffer, + " missed frames %Lu\n", (unsigned long long) pPnmiStat->StatRxMissedCts); if (pNet->Mtu > 1500) pPnmiStat->StatRxTooLongCts = 0; - len += sprintf(buffer + len, - " too long %Ld\n", + len += sk_proc_print(buffer, + " too long %Lu\n", (unsigned long long) pPnmiStat->StatRxTooLongCts); - len += sprintf(buffer + len, - " carrier extension %Ld\n", + len += sk_proc_print(buffer, + " carrier extension %Lu\n", (unsigned long long) pPnmiStat->StatRxCextCts); - len += sprintf(buffer + len, - " too short %Ld\n", + len += sk_proc_print(buffer, + " too short %Lu\n", (unsigned long long) pPnmiStat->StatRxShortsCts); - len += sprintf(buffer + len, - " symbol %Ld\n", + len += sk_proc_print(buffer, + " symbol %Lu\n", (unsigned long long) pPnmiStat->StatRxSymbolCts); - len += sprintf(buffer + len, - " LLC MAC size %Ld\n", + len += sk_proc_print(buffer, + " LLC MAC size %Lu\n", (unsigned long long) pPnmiStat->StatRxIRLengthCts); - len += sprintf(buffer + len, - " carrier event %Ld\n", + len += sk_proc_print(buffer, + " carrier event %Lu\n", (unsigned long long) pPnmiStat->StatRxCarrierCts); - len += sprintf(buffer + len, - " jabber %Ld\n", + len += sk_proc_print(buffer, + " jabber %Lu\n", (unsigned long long) pPnmiStat->StatRxJabberCts); /*Transmit statistics */ - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "\nTransmit statistics\n\n"); - len += sprintf(buffer + len, - "Transmited bytes %Ld\n", + len += sk_proc_print(buffer, + "Transmited bytes %Lu\n", (unsigned long long) pPnmiStat->StatTxOctetsOkCts); - len += sprintf(buffer + len, - "Transmited packets %Ld\n", + len += sk_proc_print(buffer, + "Transmited packets %Lu\n", (unsigned long long) pPnmiStat->StatTxOkCts); - len += sprintf(buffer + len, - "Transmit errors %Ld\n", + len += sk_proc_print(buffer, + "Transmit errors %Lu\n", (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); - len += sprintf(buffer + len, - "Transmit dropped %Ld\n", + len += sk_proc_print(buffer, + "Transmit dropped %Lu\n", (unsigned long long) pPnmiStruct->TxNoBufCts); - len += sprintf(buffer + len, - "Transmit collisions %Ld\n", + len += sk_proc_print(buffer, + "Transmit collisions %Lu\n", (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, "Transmit error types\n"); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, " excessive collision %ld\n", pAC->stats.tx_aborted_errors); - len += sprintf(buffer + len, - " carrier %Ld\n", + len += sk_proc_print(buffer, + " carrier %Lu\n", (unsigned long long) pPnmiStat->StatTxCarrierCts); - len += sprintf(buffer + len, - " fifo underrun %Ld\n", + len += sk_proc_print(buffer, + " fifo underrun %Lu\n", (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts); - len += sprintf(buffer + len, - " heartbeat %Ld\n", + len += sk_proc_print(buffer, + " heartbeat %Lu\n", (unsigned long long) pPnmiStat->StatTxCarrierCts); - len += sprintf(buffer + len, + len += sk_proc_print(buffer, " window %ld\n", pAC->stats.tx_window_errors); - } + } /* if (strcmp(pACname, currDeviceName) == 0) */ } SkgeProcDev = next; } - if (offset >= len) { - *eof = 1; - return 0; - } +} - *buffer_location = buffer + offset; - if (buffer_length >= len - offset) { - *eof = 1; - } - return (min_t(int, buffer_length, len - offset)); +/***************************************************************************** + * + * sk_proc_print -generic line print + * + * Description: + * This function fills the proc entry with statistic data about + * the ethernet device. + * + * Returns: number of bytes written + * + */ +static int sk_proc_print(void *writePtr, char *format, ...) +{ +#define MAX_LEN_SINGLE_LINE 256 + char str[MAX_LEN_SINGLE_LINE]; + va_list a_start; + int lenght = 0; + + char *buffer = (char *) writePtr; + buffer = buffer + len; /* plus global variable len for current location */ + + SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE); + + va_start(a_start, format); + vsprintf(str, format, a_start); + va_end(a_start); + + lenght = strlen(str); + + sprintf(buffer, str); + return lenght; } +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.24/drivers/net/sk98lin/skqueue.c linux-2.4.25/drivers/net/sk98lin/skqueue.c --- linux-2.4.24/drivers/net/sk98lin/skqueue.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skqueue.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,9 +1,9 @@ /****************************************************************************** * * Name: skqueue.c - * Project: Gigabit Ethernet Adapters, Schedule-Modul - * Version: $Revision: 1.19 $ - * Date: $Date: 2003/05/13 18:00:07 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.20 $ + * Date: $Date: 2003/09/16 13:44:00 $ * Purpose: Management of an event queue. * ******************************************************************************/ @@ -27,6 +27,10 @@ * History: * * $Log: skqueue.c,v $ + * Revision 1.20 2003/09/16 13:44:00 rschmidt + * Added (C) Marvell to SysKonnectFileId + * Editorial changes + * * Revision 1.19 2003/05/13 18:00:07 mkarl * Removed calls to RLMT, TWSI, and PNMI for SLIM driver (SK_SLIM). * Editorial changes. @@ -85,18 +89,16 @@ * * Revision 1.1 1998/07/30 15:14:01 gklug * Initial version. Adapted from SMT - * - * * ******************************************************************************/ /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.19 2003/05/13 18:00:07 mkarl Exp $" ; + "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -124,11 +126,11 @@ void SkEventInit( SK_AC *pAC, /* Adapter context */ SK_IOC Ioc, /* IO context */ -int Level) /* Init level */ +int Level) /* Init level */ { switch (Level) { case SK_INIT_DATA: - pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ; + pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue; break; default: break; @@ -144,14 +146,15 @@ SK_U32 Event, /* Event to be queued */ SK_EVPARA Para) /* Event parameter */ { - pAC->Event.EvPut->Class = Class ; - pAC->Event.EvPut->Event = Event ; - pAC->Event.EvPut->Para = Para ; + pAC->Event.EvPut->Class = Class; + pAC->Event.EvPut->Event = Event; + pAC->Event.EvPut->Para = Para; + if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pAC->Event.EvPut = pAC->Event.EvQueue ; + pAC->Event.EvPut = pAC->Event.EvQueue; if (pAC->Event.EvPut == pAC->Event.EvGet) { - SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ; + SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); } } @@ -168,77 +171,79 @@ SK_AC *pAC, /* Adapters Context */ SK_IOC Ioc) /* Io context */ { - SK_EVENTELEM *pEv ; /* pointer into queue */ - SK_U32 Class ; - int Rtv ; - - pEv = pAC->Event.EvGet ; - PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ; + SK_EVENTELEM *pEv; /* pointer into queue */ + SK_U32 Class; + int Rtv; + + pEv = pAC->Event.EvGet; + + PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put); + while (pEv != pAC->Event.EvPut) { - PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ; - switch(Class = pEv->Class) { + PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event); + + switch (Class = pEv->Class) { #ifndef SK_USE_LAC_EV #ifndef SK_SLIM - case SKGE_RLMT : /* RLMT Event */ - Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; - case SKGE_I2C : /* I2C Event */ - Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; - case SKGE_PNMI : - Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + case SKGE_RLMT: /* RLMT Event */ + Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + case SKGE_I2C: /* I2C Event */ + Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + case SKGE_PNMI: /* PNMI Event */ + Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* not SK_SLIM */ #endif /* not SK_USE_LAC_EV */ - case SKGE_DRV : /* Driver Event */ - Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; -#ifndef SK_USE_SW_TIMER - case SKGE_HWAC : - Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + case SKGE_DRV: /* Driver Event */ + Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; +#ifndef SK_USE_SW_TIMER + case SKGE_HWAC: + Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #else /* !SK_USE_SW_TIMER */ - case SKGE_SWT : - Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + case SKGE_SWT : + Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* !SK_USE_SW_TIMER */ -#ifdef SK_USE_LAC_EV +#ifdef SK_USE_LAC_EV case SKGE_LACP : - Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_RSF : - Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_MARKER : - Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; case SKGE_FD : - Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* SK_USE_LAC_EV */ #ifdef SK_USE_CSUM case SKGE_CSUM : - Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para); - break ; + Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; #endif /* SK_USE_CSUM */ default : - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, - SKERR_Q_E002MSG) ; + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG); Rtv = 0; } if (Rtv != 0) { - return(Rtv) ; + return(Rtv); } if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pEv = pAC->Event.EvQueue ; + pEv = pAC->Event.EvQueue; /* Renew get: it is used in queue_events to detect overruns */ pAC->Event.EvGet = pEv; } - return(0) ; + return(0); } /* End of file */ diff -urN linux-2.4.24/drivers/net/sk98lin/sktimer.c linux-2.4.25/drivers/net/sk98lin/sktimer.c --- linux-2.4.24/drivers/net/sk98lin/sktimer.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/sktimer.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,9 +1,9 @@ /****************************************************************************** * * Name: sktimer.c - * Project: Gigabit Ethernet Adapters, Schedule-Modul - * Version: $Revision: 1.13 $ - * Date: $Date: 2003/05/13 18:01:01 $ + * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 1.14 $ + * Date: $Date: 2003/09/16 13:46:51 $ * Purpose: High level timer functions. * ******************************************************************************/ @@ -27,6 +27,10 @@ * History: * * $Log: sktimer.c,v $ + * Revision 1.14 2003/09/16 13:46:51 rschmidt + * Added (C) Marvell to SysKonnectFileId + * Editorial changes + * * Revision 1.13 2003/05/13 18:01:01 mkarl * Editorial changes. * @@ -68,19 +72,16 @@ * * Revision 1.1 1998/08/05 11:27:55 gklug * first version: adapted from SMT - * - * - * * ******************************************************************************/ /* - Event queue and dispatcher -*/ + * Event queue and dispatcher + */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.13 2003/05/13 18:01:01 mkarl Exp $" ; + "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -110,14 +111,14 @@ void SkTimerInit( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ -int Level) /* Init Level */ +int Level) /* Init Level */ { switch (Level) { case SK_INIT_DATA: - pAC->Tim.StQueue = 0 ; + pAC->Tim.StQueue = 0; break; case SK_INIT_IO: - SkHwtInit(pAC,Ioc) ; + SkHwtInit(pAC, Ioc); SkTimerDone(pAC, Ioc); break; default: @@ -134,31 +135,34 @@ SK_IOC Ioc, /* IoContext */ SK_TIMER *pTimer) /* Timer Pointer to be started */ { - SK_TIMER **ppTimPrev ; - SK_TIMER *pTm ; + SK_TIMER **ppTimPrev; + SK_TIMER *pTm; /* * remove timer from queue */ - pTimer->TmActive = SK_FALSE ; + pTimer->TmActive = SK_FALSE; + if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) { - SkHwtStop(pAC,Ioc) ; + SkHwtStop(pAC, Ioc); } - for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ; + + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { + if (pTm == pTimer) { /* * Timer found in queue * - dequeue it and * - correct delta of the next timer */ - *ppTimPrev = pTm->TmNext ; + *ppTimPrev = pTm->TmNext; if (pTm->TmNext) { /* correct delta of next timer in queue */ - pTm->TmNext->TmDelta += pTm->TmDelta ; + pTm->TmNext->TmDelta += pTm->TmDelta; } - return ; + return; } } } @@ -175,65 +179,67 @@ SK_U32 Event, /* Event Value for this timer */ SK_EVPARA Para) /* Event Parameter for this timer */ { - SK_TIMER **ppTimPrev ; - SK_TIMER *pTm ; - SK_U32 Delta ; + SK_TIMER **ppTimPrev; + SK_TIMER *pTm; + SK_U32 Delta; - Time /= 16 ; /* input is uS, clock ticks are 16uS */ + Time /= 16; /* input is uS, clock ticks are 16uS */ + if (!Time) - Time = 1 ; + Time = 1; - SkTimerStop(pAC,Ioc,pTimer) ; + SkTimerStop(pAC, Ioc, pTimer); - pTimer->TmClass = Class ; - pTimer->TmEvent = Event ; - pTimer->TmPara = Para ; - pTimer->TmActive = SK_TRUE ; + pTimer->TmClass = Class; + pTimer->TmEvent = Event; + pTimer->TmPara = Para; + pTimer->TmActive = SK_TRUE; if (!pAC->Tim.StQueue) { /* First Timer to be started */ - pAC->Tim.StQueue = pTimer ; - pTimer->TmNext = 0 ; - pTimer->TmDelta = Time ; - SkHwtStart(pAC,Ioc,Time) ; - return ; + pAC->Tim.StQueue = pTimer; + pTimer->TmNext = 0; + pTimer->TmDelta = Time; + + SkHwtStart(pAC, Ioc, Time); + + return; } /* * timer correction */ - timer_done(pAC,Ioc,0) ; + timer_done(pAC, Ioc, 0); /* * find position in queue */ - Delta = 0 ; - for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ; + Delta = 0; + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { + if (Delta + pTm->TmDelta > Time) { /* Position found */ /* Here the timer needs to be inserted. */ - break ; + break; } - Delta += pTm->TmDelta ; + Delta += pTm->TmDelta; } /* insert in queue */ - *ppTimPrev = pTimer ; - pTimer->TmNext = pTm ; - pTimer->TmDelta = Time - Delta ; + *ppTimPrev = pTimer; + pTimer->TmNext = pTm; + pTimer->TmDelta = Time - Delta; if (pTm) { /* There is a next timer * -> correct its Delta value. */ - pTm->TmDelta -= pTimer->TmDelta ; + pTm->TmDelta -= pTimer->TmDelta; } - /* - * start new with first - */ - SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ; + /* restart with first */ + SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); } @@ -241,55 +247,56 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { - timer_done(pAC,Ioc,1) ; + timer_done(pAC, Ioc, 1); } static void timer_done( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ -int Restart) /* Do we need to restart the Hardware timer ? */ +int Restart) /* Do we need to restart the Hardware timer ? */ { - SK_U32 Delta ; - SK_TIMER *pTm ; - SK_TIMER *pTComp ; /* Timer completed now now */ - SK_TIMER **ppLast ; /* Next field of Last timer to be deq */ - int Done = 0 ; - - Delta = SkHwtRead(pAC,Ioc) ; - ppLast = &pAC->Tim.StQueue ; - pTm = pAC->Tim.StQueue ; + SK_U32 Delta; + SK_TIMER *pTm; + SK_TIMER *pTComp; /* Timer completed now now */ + SK_TIMER **ppLast; /* Next field of Last timer to be deq */ + int Done = 0; + + Delta = SkHwtRead(pAC, Ioc); + + ppLast = &pAC->Tim.StQueue; + pTm = pAC->Tim.StQueue; while (pTm && !Done) { if (Delta >= pTm->TmDelta) { /* Timer ran out */ - pTm->TmActive = SK_FALSE ; - Delta -= pTm->TmDelta ; - ppLast = &pTm->TmNext ; - pTm = pTm->TmNext ; - } else { + pTm->TmActive = SK_FALSE; + Delta -= pTm->TmDelta; + ppLast = &pTm->TmNext; + pTm = pTm->TmNext; + } + else { /* We found the first timer that did not run out */ - pTm->TmDelta -= Delta ; - Delta = 0 ; - Done = 1 ; + pTm->TmDelta -= Delta; + Delta = 0; + Done = 1; } } - *ppLast = 0 ; + *ppLast = 0; /* * pTm points to the first Timer that did not run out. * StQueue points to the first Timer that run out. */ - for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) { - SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, - pTComp->TmPara) ; + for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { + SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara); } /* Set head of timer queue to the first timer that did not run out */ - pAC->Tim.StQueue = pTm ; + pAC->Tim.StQueue = pTm; if (Restart && pAC->Tim.StQueue) { /* Restart HW timer */ - SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ; + SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); } } diff -urN linux-2.4.24/drivers/net/sk98lin/skxmac2.c linux-2.4.25/drivers/net/sk98lin/skxmac2.c --- linux-2.4.24/drivers/net/sk98lin/skxmac2.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/sk98lin/skxmac2.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,8 +2,8 @@ * * Name: skxmac2.c * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.99 $ - * Date: $Date: 2003/07/11 12:19:33 $ + * Version: $Revision: 1.102 $ + * Date: $Date: 2003/10/02 16:53:58 $ * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************/ @@ -27,6 +27,23 @@ * History: * * $Log: skxmac2.c,v $ + * Revision 1.102 2003/10/02 16:53:58 rschmidt + * Changed setting of GMAC parameters with new macros. + * Added define SLIM around SkGm...LowPowerMode(). + * Editorial changes. + * + * Revision 1.101 2003/09/16 14:49:07 rschmidt + * Added routines SkGmClearRst(), SkXmClearRst, SkMacClearRst(). + * Added WA code for Yukon-Lite's COMA mode in SkGmHardRst(). + * Replaced PCI-Config R/W through internal access. + * Fixed return from coma mode in SkGmLeaveLowPowerMode(). + * Fixed compiler warnings for different types. + * Editorial changes. + * + * Revision 1.100 2003/09/16 07:09:11 mschmid + * Added functions SkGmEnterLowPowerMode() and + * SkGmLeaveLowPowerMode() + * * Revision 1.99 2003/07/11 12:19:33 rschmidt * Reduced init values for Master & Slave downshift counters to * minimum values. @@ -164,7 +181,7 @@ * Revision 1.74 2002/08/12 14:00:17 rschmidt * Replaced usage of Broadcom PHY Ids with defines. * Corrected error messages in SkGmMacStatistic(). - * Made SkMacPromiscMode() public for ADDR-Modul. + * Made SkMacPromiscMode() public for ADDR-Module. * Editorial changes. * * Revision 1.73 2002/08/08 16:26:24 rschmidt @@ -475,7 +492,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skxmac2.c,v 1.99 2003/07/11 12:19:33 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell."; #endif #ifdef GENESIS @@ -1343,7 +1360,7 @@ * Description: * The XMAC of the specified 'Port' and all connected devices * (PHY and SERDES) will receive a reset signal on its *Reset pins. - * External PHYs must be reset be clearing a bit in the GPIO register + * External PHYs must be reset by clearing a bit in the GPIO register * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns). * * ATTENTION: @@ -1386,23 +1403,62 @@ /* For external PHYs there must be special handling */ if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { - /* reset external PHY */ + SK_IN32(IoC, B2_GP_IO, &Reg); + if (Port == 0) { - Reg |= GP_DIR_0; /* set to output */ - Reg &= ~GP_IO_0; + Reg |= GP_DIR_0; /* set to output */ + Reg &= ~GP_IO_0; /* set PHY reset (active low) */ } else { - Reg |= GP_DIR_2; /* set to output */ - Reg &= ~GP_IO_2; + Reg |= GP_DIR_2; /* set to output */ + Reg &= ~GP_IO_2; /* set PHY reset (active low) */ } + /* reset external PHY */ SK_OUT32(IoC, B2_GP_IO, Reg); /* short delay */ SK_IN32(IoC, B2_GP_IO, &Reg); } - } /* SkXmHardRst */ + + +/****************************************************************************** + * + * SkXmClearRst() - Release the PHY & XMAC reset + * + * Description: + * + * Returns: + * nothing + */ +static void SkXmClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 DWord; + + /* clear HW reset */ + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); + + if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + if (Port == 0) { + DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */ + } + else { + DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */ + } + /* Clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + /* Enable GMII interface */ + XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); + } +} /* SkXmClearRst */ #endif /* GENESIS */ @@ -1452,10 +1508,6 @@ * * Description: * - * ATTENTION: - * It is absolutely necessary to reset the SW_RST Bit first - * before calling this function. - * * Returns: * nothing */ @@ -1464,6 +1516,20 @@ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ { + SK_U32 DWord; + + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + /* set GPHY Control reset */ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); @@ -1471,6 +1537,73 @@ SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); } /* SkGmHardRst */ + + +/****************************************************************************** + * + * SkGmClearRst() - Release the GPHY & GMAC reset + * + * Description: + * + * Returns: + * nothing + */ +static void SkGmClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U32 DWord; + +#ifdef XXX + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); + + /* set GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); +#endif /* XXX */ + + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= GP_DIR_9; /* set to output */ + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + + /* set HWCFG_MODE */ + DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | + GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | + (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : + GPC_HWCFG_GMII_FIB); + + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + + /* release GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); + +#ifdef VCPU + VCpuWait(9000); +#endif /* VCPU */ + + /* clear GMAC Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + +#ifdef VCPU + VCpuWait(2000); + + SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord); + + SK_IN32(IoC, B0_ISRC, &DWord); +#endif /* VCPU */ + +} /* SkGmClearRst */ #endif /* YUKON */ @@ -1553,6 +1686,38 @@ } /* SkMacHardRst */ +/****************************************************************************** + * + * SkMacClearRst() - Clear the MAC reset + * + * Description: calls a clear MAC reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmClearRst(pAC, IoC, Port); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmClearRst(pAC, IoC, Port); + } +#endif /* YUKON */ + +} /* SkMacClearRst */ + + #ifdef GENESIS /****************************************************************************** * @@ -1574,7 +1739,6 @@ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U32 Reg; int i; SK_U16 SWord; @@ -1594,32 +1758,10 @@ } if (pPrt->PState == SK_PRT_RESET) { - /* - * clear HW reset - * Note: The SW reset is self clearing, therefore there is - * nothing to do here. - */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); - /* Ensure that XMAC reset release is done (errata from LReinbold?) */ - SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); + SkXmClearRst(pAC, IoC, Port); - /* Clear PHY reset */ if (pPrt->PhyType != SK_PHY_XMAC) { - - SK_IN32(IoC, B2_GP_IO, &Reg); - - if (Port == 0) { - Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */ - } - else { - Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */ - } - SK_OUT32(IoC, B2_GP_IO, Reg); - - /* Enable GMII interface */ - XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); - /* read Id from external PHY (all have the same address) */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1); @@ -1831,43 +1973,11 @@ } if (pPrt->PState == SK_PRT_RESET) { - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); - - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); - -#ifdef XXX - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); - - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); -#endif /* XXX */ - - /* set HWCFG_MODE */ - DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | - GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | - (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : - GPC_HWCFG_GMII_FIB); - - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); - - /* release GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); - -#ifdef VCPU - VCpuWait(9000); -#endif /* VCPU */ - - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); - -#ifdef VCPU - VCpuWait(2000); -#endif /* VCPU */ + + SkGmHardRst(pAC, IoC, Port); + SkGmClearRst(pAC, IoC, Port); + /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* Auto-negotiation disabled */ @@ -1906,6 +2016,7 @@ SWord |= GM_GPCR_DUP_FULL; } + /* flow-control settings */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* set Pause Off */ @@ -1940,7 +2051,7 @@ (void)SkGmResetCounter(pAC, IoC, Port); /* setup Transmit Control Register */ - GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR); + GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); /* setup Receive Control Register */ GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | @@ -1954,7 +2065,9 @@ GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); #endif /* VCPU */ - SWord = (SK_U16)(JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26)); + SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | + TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | + TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); @@ -1963,7 +2076,12 @@ GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); #endif /* VCPU */ - SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH; + SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); + + if (pPrt->PMacLimit4) { + /* reset of collision counter after 4 consecutive collisions */ + SWord |= GM_SMOD_LIMIT_4; + } if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { /* enable jumbo mode (Max. Frame Length = 9018) */ @@ -2021,11 +2139,13 @@ GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); +#if defined(SK_DIAG) || defined(DEBUG) /* read General Purpose Status */ GM_IN16(IoC, Port, GM_GP_STAT, &SWord); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("MAC Stat Reg=0x%04X\n", SWord)); + ("MAC Stat Reg.=0x%04X\n", SWord)); +#endif /* SK_DIAG || DEBUG */ #ifdef SK_DIAG c_print("MAC Stat Reg=0x%04X\n", SWord); @@ -2226,6 +2346,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl |= PHY_X_P_NO_PAUSE; @@ -2306,7 +2427,9 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ - Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { @@ -2346,6 +2469,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_B_P_NO_PAUSE; @@ -2375,12 +2499,12 @@ /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); + ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); + ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); if (DoLoop) { /* Set the Phy Loopback bit, too */ @@ -2409,6 +2533,281 @@ #ifdef YUKON +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGmEnterLowPowerMode() + * + * Description: + * This function sets the Marvell Alaska PHY to the low power mode + * given by parameter mode. + * The following low power modes are available: + * + * - Coma Mode (Deep Sleep): + * Power consumption: ~15 - 30 mW + * The PHY cannot wake up on its own. + * + * - IEEE 22.2.4.1.5 compatible power down mode + * Power consumption: ~240 mW + * The PHY cannot wake up on its own. + * + * - energy detect mode + * Power consumption: ~160 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * + * - energy detect plus mode + * Power consumption: ~150 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * Connected devices can be woken up by sending normal link + * pulses every one second. + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmEnterLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (e.g. MAC_1) */ +SK_U8 Mode) /* low power mode */ +{ + SK_U16 Word; + SK_U32 DWord; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = Mode; + + switch (Mode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + /* setup General Purpose Control Register */ + GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | + GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); + + /* apply COMA mode workaround */ + SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); + + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Set PHY to Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - disable MAC 125 MHz clock + * - allow MAC power down + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + Word &= ~PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode on */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - disable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* activate energy detect mode 1 */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + /* energy detect mode */ + if (Mode == PHY_PM_ENERGY_DETECT) { + Word |= PHY_M_PC_EN_DET; + } + /* energy detect plus mode */ + else { + Word |= PHY_M_PC_EN_DET_PLUS; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmEnterLowPowerMode */ + +/****************************************************************************** + * + * SkGmLeaveLowPowerMode() + * + * Description: + * Leave the current low power mode and switch to normal mode + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmLeaveLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (e.g. MAC_1) */ +{ + SK_U32 DWord; + SK_U16 Word; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + + switch (LastMode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Release PHY from Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + SK_IN32(IoC, B2_GP_IO, &DWord); + + /* set to output */ + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - enable MAC 125 MHz clock + * - set MAC power up + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + Word |= PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode off */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word &= ~PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - enable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* disable energy detect mode */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_EN_DET_MSK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmLeaveLowPowerMode */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkGmInitPhyMarv() - Initialize the Marvell Phy registers @@ -2457,7 +2856,6 @@ VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", Port, DoLoop); #else /* VCPU */ - if (DoLoop) { /* Set 'MAC Power up'-bit, set Manual MDI configuration */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, @@ -2475,16 +2873,20 @@ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); + ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); } /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + if (!AutoNeg) { + /* Disable Auto-negotiation */ + PhyCtrl &= ~PHY_CT_ANE; + } + PhyCtrl |= PHY_CT_RESET; /* Assert software reset */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); - #endif /* VCPU */ PhyCtrl = 0 /* PHY_CT_COL_TST */; @@ -2533,13 +2935,9 @@ if (!DoLoop) { PhyCtrl |= PHY_CT_RESET; } - /* - * Do NOT enable Auto-negotiation here. This would hold - * the link down because no IDLES are transmitted - */ } else { - PhyCtrl |= PHY_CT_ANE; + /* Set Auto-negotiation advertisement */ if (pAC->GIni.GICopperType) { /* Set Speed capabilities */ @@ -2554,6 +2952,7 @@ break; case SK_LSPEED_100MBPS: AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + /* advertise 10Base-T also */ PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; case SK_LSPEED_10MBPS: @@ -2581,7 +2980,7 @@ SKERR_HWI_E015MSG); } - /* Set Auto-negotiation advertisement */ + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_B_P_NO_PAUSE; @@ -2618,7 +3017,7 @@ SKERR_HWI_E015MSG); } - /* Set Auto-negotiation advertisement */ + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_M_P_NO_PAUSE_X; @@ -2640,7 +3039,7 @@ if (!DoLoop) { /* Restart Auto-negotiation */ - PhyCtrl |= PHY_CT_RE_CFG; + PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } } @@ -2659,12 +3058,12 @@ /* Write 1000Base-T Control Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl=0x%04X\n", C1000BaseT)); + ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); /* Write AutoNeg Advertisement Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv)); + ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); #endif /* VCPU */ if (DoLoop) { @@ -2694,6 +3093,8 @@ /* Write to the PHY Control register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); #ifdef VCPU VCpuWait(2000); @@ -2712,7 +3113,7 @@ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { - /* only in forced 100Mbps mode */ + /* only in forced 100 Mbps mode */ if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, @@ -2741,7 +3142,7 @@ /* Read AutoNeg Advertisement Register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv)); + ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); /* Read Ext. PHY Specific Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); @@ -2818,13 +3219,15 @@ /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* - * level one spec say: "1000Mbps: manual mode not allowed" + * level one spec say: "1000 Mbps: manual mode not allowed" * but lets see what happens... */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: no auto-negotiation Port %d\n", Port)); /* Set DuplexMode in Config register */ - Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0); + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } /* Determine Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { @@ -2857,6 +3260,7 @@ SKERR_HWI_E015MSG); } + /* Set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_L_P_NO_PAUSE; @@ -2877,7 +3281,6 @@ /* Restart Auto-negotiation */ Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; - } /* Write 1000Base-T Control Register */ @@ -3019,10 +3422,10 @@ /* Check Duplex mismatch */ if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } else { /* Error */ @@ -3055,7 +3458,7 @@ /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; return(SK_AND_OK); } /* SkXmAutoNegDoneXmac */ @@ -3110,10 +3513,10 @@ /* Check Duplex mismatch */ if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } else { /* Error */ @@ -3156,7 +3559,7 @@ /* PAUSE mismatch -> no PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; } - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; return(SK_AND_OK); } /* SkXmAutoNegDoneBcom */ @@ -3192,6 +3595,8 @@ /* Get PHY parameters */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link P.Abil.=0x%04X\n", LPAb)); if ((LPAb & PHY_M_AN_RF) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, @@ -3222,15 +3627,15 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; - pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; return(SK_AND_DUP_CAP); } if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } /* Check PAUSE mismatch ??? */ @@ -3255,13 +3660,13 @@ /* set used link speed */ switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { case (unsigned)PHY_M_PS_SPEED_1000: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; break; case PHY_M_PS_SPEED_100: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; break; default: - pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; } return(SK_AND_OK); @@ -3312,10 +3717,10 @@ /* Check Duplex mismatch */ if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; } else { - pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } /* Check Master/Slave resolution */ @@ -3338,6 +3743,7 @@ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ /* we must manually resolve the abilities here */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* default */ @@ -3457,6 +3863,9 @@ return(Rtv); } + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg done Port %d\n", Port)); + /* We checked everything and may now enable the link */ pPrt->PAutoNegFail = SK_FALSE; diff -urN linux-2.4.24/drivers/net/starfire.c linux-2.4.25/drivers/net/starfire.c --- linux-2.4.24/drivers/net/starfire.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/starfire.c 2004-02-18 05:36:31.000000000 -0800 @@ -130,7 +130,6 @@ #include #include #include -#include #include #include #include diff -urN linux-2.4.24/drivers/net/tg3.c linux-2.4.25/drivers/net/tg3.c --- linux-2.4.24/drivers/net/tg3.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/tg3.c 2004-02-18 05:36:31.000000000 -0800 @@ -55,8 +55,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "2.3" -#define DRV_MODULE_RELDATE "November 5, 2003" +#define DRV_MODULE_VERSION "2.6" +#define DRV_MODULE_RELDATE "February 3, 2004" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -175,6 +175,10 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, @@ -2687,7 +2691,13 @@ mss |= (tsflags << 11); } } else { - mss += tcp_opt_len; + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } } } #else @@ -2894,7 +2904,13 @@ mss |= (tsflags << 11); } } else { - mss += tcp_opt_len; + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } } } #else @@ -3859,180 +3875,181 @@ #if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO_FW_RELASE_MINOR 0x3 +#define TG3_TSO_FW_RELASE_MINOR 0x4 #define TG3_TSO_FW_RELEASE_FIX 0x0 #define TG3_TSO_FW_START_ADDR 0x08000000 #define TG3_TSO_FW_TEXT_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_LEN 0x1ac0 -#define TG3_TSO_FW_RODATA_ADDR 0x08001650 +#define TG3_TSO_FW_TEXT_LEN 0x1a90 +#define TG3_TSO_FW_RODATA_ADDR 0x08001a900 #define TG3_TSO_FW_RODATA_LEN 0x60 -#define TG3_TSO_FW_DATA_ADDR 0x080016a0 +#define TG3_TSO_FW_DATA_ADDR 0x08001b20 #define TG3_TSO_FW_DATA_LEN 0x20 -#define TG3_TSO_FW_SBSS_ADDR 0x080016c0 +#define TG3_TSO_FW_SBSS_ADDR 0x08001b40 #define TG3_TSO_FW_SBSS_LEN 0x2c -#define TG3_TSO_FW_BSS_ADDR 0x080016e0 -#define TG3_TSO_FW_BSS_LEN 0x890 +#define TG3_TSO_FW_BSS_ADDR 0x08001b70 +#define TG3_TSO_FW_BSS_LEN 0x894 static u32 tg3TsoFwText[] = { 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c04fefe, - 0xafbf0018, 0x0e0005e0, 0x34840002, 0x0e000670, 0x00000000, 0x3c030800, - 0x90631b78, 0x24020002, 0x3c040800, 0x24841acc, 0x14620003, 0x24050001, - 0x3c040800, 0x24841ac0, 0x24060002, 0x00003821, 0xafa00010, 0x0e000684, + 0xafbf0018, 0x0e0005d4, 0x34840002, 0x0e000664, 0x00000000, 0x3c030800, + 0x90631b58, 0x24020002, 0x3c040800, 0x24841a9c, 0x14620003, 0x24050001, + 0x3c040800, 0x24841a90, 0x24060003, 0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, 0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, - 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018, - 0xafb10014, 0x0e000052, 0xafb00010, 0x24110001, 0x8f706820, 0x32020100, - 0x10400003, 0x00000000, 0x0e0000b2, 0x00000000, 0x8f706820, 0x32022000, - 0x10400004, 0x32020001, 0x0e0001e3, 0x24040001, 0x32020001, 0x10400003, - 0x00000000, 0x0e00009a, 0x00000000, 0x0a00003a, 0xaf715028, 0x8fbf0018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, - 0x24841ae0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x3c040800, 0x248423e8, 0xa4800000, 0x3c010800, - 0xa0201ba8, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, - 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, - 0xac201bcc, 0x8f624434, 0x3c010800, 0xac221b98, 0x8f624438, 0x3c010800, - 0xac221b9c, 0x8f624410, 0xac80f7a8, 0x3c010800, 0xac201b94, 0x3c010800, - 0xac2023f0, 0x3c010800, 0xac2023d8, 0x3c010800, 0xac2023dc, 0x3c010800, - 0xac202410, 0x3c010800, 0xac221ba0, 0x8f620068, 0x24030007, 0x00021702, - 0x10430005, 0x00000000, 0x8f620068, 0x00021702, 0x14400004, 0x24020001, - 0x3c010800, 0x0a00008e, 0xac20241c, 0xac820034, 0x3c040800, 0x24841aec, - 0x3c050800, 0x8ca5241c, 0x00003021, 0x00003821, 0xafa00010, 0x0e000684, - 0xafa00014, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, - 0x24841af8, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x0e000052, 0x00000000, 0x0e0000ab, 0x00002021, - 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, 0x8f636820, 0x00821004, - 0x00021027, 0x00621824, 0x03e00008, 0xaf636820, 0x27bdffd0, 0xafbf002c, - 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, - 0xafb00010, 0x8f665c5c, 0x3c030800, 0x24631bcc, 0x8c620000, 0x14460005, - 0x3c0200ff, 0x3c020800, 0x90421ba8, 0x14400115, 0x3c0200ff, 0x3442fff8, - 0x00c28824, 0xac660000, 0x00111902, 0x306300ff, 0x30c20003, 0x000211c0, - 0x00623825, 0x00e02821, 0x00061602, 0x3c030800, 0x90631ba8, 0x3044000f, - 0x1460002b, 0x00804021, 0x24020001, 0x3c010800, 0xa0221ba8, 0x00071100, - 0x00821025, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, - 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, - 0xac201bc0, 0x3c010800, 0xac201bc4, 0x3c010800, 0xa42223e8, 0x9623000c, - 0x30628000, 0x10400008, 0x30627fff, 0x2442003e, 0x3c010800, 0xa4221ba6, - 0x24020001, 0x3c010800, 0x0a0000f9, 0xac222404, 0x24620036, 0x3c010800, - 0xa4221ba6, 0x3c010800, 0xac202404, 0x3c010800, 0xac202400, 0x3c010800, - 0x0a000101, 0xac202408, 0x9622000c, 0x3c010800, 0xa42223fc, 0x3c040800, - 0x24841bac, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac311bd8, - 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac261bdc, 0x8c820000, - 0x24a30001, 0x306701ff, 0x00021100, 0x3c010800, 0x00220821, 0xac271be0, - 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac281be4, 0x96230008, - 0x3c020800, 0x8c421bbc, 0x00432821, 0x3c010800, 0xac251bbc, 0x9622000a, - 0x30420004, 0x14400018, 0x00071100, 0x8f630c14, 0x3063000f, 0x2c620002, - 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, 0x8c421b50, 0x3063000f, - 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, 0x1040fff7, 0x3c02c000, - 0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x10400014, 0x00000000, - 0x0a000133, 0x00000000, 0x3c030800, 0x8c631b90, 0x3c040800, 0x94841ba4, - 0x01021025, 0x3c010800, 0xa42223ea, 0x24020001, 0x3c010800, 0xac221bc8, - 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, 0xac231b90, 0x3c010800, - 0xa4251ba4, 0x3c060800, 0x24c61bac, 0x8cc20000, 0x24420001, 0xacc20000, - 0x28420080, 0x14400005, 0x00000000, 0x0e00065e, 0x24040002, 0x0a0001d9, - 0x00000000, 0x3c020800, 0x8c421bc8, 0x1040007f, 0x24020001, 0x3c040800, - 0x90841ba8, 0x14820077, 0x24020003, 0x3c150800, 0x96b51ba6, 0x3c050800, - 0x8ca51bbc, 0x32a3ffff, 0x00a3102a, 0x14400073, 0x00000000, 0x14a30003, - 0x00000000, 0x3c010800, 0xac242400, 0x10600061, 0x00009021, 0x24d60004, - 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, 0x3c110800, 0x02308821, - 0x0e00062d, 0x8e311bd8, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a, - 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018, - 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, - 0x3c030800, 0x00701821, 0x8c631be0, 0x3c020800, 0x00501021, 0x8c421be4, - 0x00031d00, 0x00021400, 0x00621825, 0xacc30014, 0x8ec30004, 0x96220008, - 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002, - 0x02b22823, 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, - 0x8e220000, 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004, - 0xa4c5000e, 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a, - 0x14400005, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0, - 0xacc00008, 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001, - 0x34e70010, 0x24020905, 0xa4c2000c, 0x0a0001bc, 0x34e70020, 0xa4c2000c, - 0x3c020800, 0x8c422400, 0x10400003, 0x3c024b65, 0x0a0001c4, 0x34427654, - 0x3c02b49a, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, - 0x00c02021, 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002, - 0x3c010800, 0x0a0001d9, 0xa0221ba8, 0x8ec2083c, 0x24420001, 0x0a0001d9, - 0xaec2083c, 0x14820003, 0x00000000, 0x0e0004b9, 0x00000000, 0x8fbf002c, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, + 0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001, + 0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000, + 0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001ef, 0x24040001, + 0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800, + 0x90421b88, 0x14520003, 0x00000000, 0x0e0004bf, 0x00000000, 0x0a00003c, + 0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ab0, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x3c040800, + 0x248423c8, 0xa4800000, 0x3c010800, 0xa0201b88, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201bac, 0x8f624434, 0x3c010800, + 0xac221b78, 0x8f624438, 0x3c010800, 0xac221b7c, 0x8f624410, 0xac80f7a8, + 0x3c010800, 0xac201b74, 0x3c010800, 0xac2023d0, 0x3c010800, 0xac2023b8, + 0x3c010800, 0xac2023bc, 0x3c010800, 0xac2023f0, 0x3c010800, 0xac221b80, + 0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068, + 0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac2023fc, + 0xac820034, 0x3c040800, 0x24841abc, 0x3c050800, 0x8ca523fc, 0x00003021, + 0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac8, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x0e00005b, + 0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, + 0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, + 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800, + 0x24631bac, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b88, + 0x14400118, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902, + 0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602, + 0x3c030800, 0x90631b88, 0x3044000f, 0x14600036, 0x00804821, 0x24020001, + 0x3c010800, 0xa0221b88, 0x00051100, 0x00821025, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, + 0x3c010800, 0xa42223c8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222400, + 0x30428000, 0x3c010800, 0xa4231bb6, 0x10400005, 0x24020001, 0x3c010800, + 0xac2223e4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023e4, + 0x9622000a, 0x3c030800, 0x94631bb6, 0x3c010800, 0xac2023e0, 0x3c010800, + 0xac2023e8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800, + 0xa42223c0, 0x3c010800, 0x0a000115, 0xa4231b86, 0x9622000c, 0x3c010800, + 0xa42223dc, 0x3c040800, 0x24841b8c, 0x8c820000, 0x00021100, 0x3c010800, + 0x00220821, 0xac311bb8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac271bbc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800, + 0x00220821, 0xac261bc0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac291bc4, 0x96230008, 0x3c020800, 0x8c421b9c, 0x00432821, 0x3c010800, + 0xac251b9c, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14, + 0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, + 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002, + 0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002, + 0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b70, + 0x3c040800, 0x94841b84, 0x01221025, 0x3c010800, 0xa42223ca, 0x24020001, + 0x3c010800, 0xac221ba8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, + 0xac231b70, 0x3c010800, 0xa4251b84, 0x3c060800, 0x24c61b8c, 0x8cc20000, + 0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000652, + 0x24040002, 0x0a0001e5, 0x00000000, 0x3c020800, 0x8c421ba8, 0x10400077, + 0x24020001, 0x3c050800, 0x90a51b88, 0x14a20071, 0x00000000, 0x3c150800, + 0x96b51b86, 0x3c040800, 0x8c841b9c, 0x32a3ffff, 0x0083102a, 0x1440006b, + 0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523e0, 0x1060005b, + 0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, + 0x3c110800, 0x02308821, 0x0e000621, 0x8e311bb8, 0x00402821, 0x10a00053, + 0x00000000, 0x9628000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, + 0x2407188c, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bc0, 0x3c020800, + 0x00501021, 0x8c421bc4, 0x00031d00, 0x00021400, 0x00621825, 0xaca30014, + 0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000, 0x30c4ffff, + 0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, 0x8e63fff4, + 0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021, 0xae62fff4, + 0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008, 0x24020305, + 0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, 0x0a0001ca, + 0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223e0, 0x10400003, 0x3c024b65, + 0x0a0001d2, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, 0x30e2ffff, + 0xaca20010, 0x0e00059f, 0x00a02021, 0x3242ffff, 0x0054102b, 0x1440ffaa, + 0x00000000, 0x24020002, 0x3c010800, 0x0a0001e5, 0xa0221b88, 0x8ec2083c, + 0x24420001, 0x0a0001e5, 0xaec2083c, 0x0e0004bf, 0x00000000, 0x8fbf002c, 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, 0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, - 0x3c060800, 0x24c61bc4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, - 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000643, + 0x3c060800, 0x24c61ba4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, + 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000637, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x10400121, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011c, - 0x00000000, 0x0a000200, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, + 0x00000000, 0x0a00020c, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, 0x000241c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, 0x00031942, 0x30637800, 0x00021100, 0x24424000, 0x00625021, 0x9542000a, 0x3084ffff, - 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c422410, 0x1440002d, - 0x25050008, 0x95020014, 0x3c010800, 0xa42223e0, 0x8d070010, 0x00071402, - 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, 0x9502000e, 0x30e3ffff, - 0x00431023, 0x3c010800, 0xac222418, 0x8f626800, 0x3c030010, 0x00431024, - 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000235, 0x00431021, - 0x9502001a, 0x3c010800, 0xac22240c, 0x3c02c000, 0x02421825, 0x3c010800, - 0xac282410, 0x3c010800, 0xac322414, 0xaf635c9c, 0x8f625c90, 0x30420002, + 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c4223f0, 0x1440002d, + 0x25050008, 0x95020014, 0x3c010800, 0xa42223c0, 0x8d070010, 0x00071402, + 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, 0x9502000e, 0x30e3ffff, + 0x00431023, 0x3c010800, 0xac2223f8, 0x8f626800, 0x3c030010, 0x00431024, + 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000241, 0x00431021, + 0x9502001a, 0x3c010800, 0xac2223ec, 0x3c02c000, 0x02421825, 0x3c010800, + 0xac2823f0, 0x3c010800, 0xac3223f4, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000df, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000da, - 0x00000000, 0x0a000242, 0x00000000, 0x9502000e, 0x3c030800, 0x946323e4, + 0x00000000, 0x0a00024e, 0x00000000, 0x9502000e, 0x3c030800, 0x946323c4, 0x00434823, 0x3123ffff, 0x2c620008, 0x1040001c, 0x00000000, 0x95020014, 0x24420028, 0x00a22821, 0x00031042, 0x1840000b, 0x00002021, 0x24c60848, 0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, 0x0087102a, 0x1440fff9, 0x24a50002, 0x31220001, 0x1040001f, 0x3c024000, - 0x3c040800, 0x2484240c, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, - 0x0a000281, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, - 0x00000000, 0x9502001a, 0x3c030800, 0x8c63240c, 0x00431021, 0x3c010800, - 0xac22240c, 0x0a000282, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, - 0x8c63240c, 0x00441023, 0x00621821, 0x3c010800, 0xac23240c, 0x3c024000, + 0x3c040800, 0x248423ec, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, + 0x0a00028d, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, + 0x00000000, 0x9502001a, 0x3c030800, 0x8c6323ec, 0x00431021, 0x3c010800, + 0xac2223ec, 0x0a00028e, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, + 0x8c6323ec, 0x00441023, 0x00621821, 0x3c010800, 0xac2323ec, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, - 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c62410, - 0x3c020800, 0x944223e4, 0x8cc50000, 0x3c040800, 0x8c842418, 0x24420030, - 0x00a22821, 0x94a20004, 0x3c030800, 0x8c63240c, 0x00441023, 0x00621821, + 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c623f0, + 0x3c020800, 0x944223c4, 0x8cc50000, 0x3c040800, 0x8c8423f8, 0x24420030, + 0x00a22821, 0x94a20004, 0x3c030800, 0x8c6323ec, 0x00441023, 0x00621821, 0x00603821, 0x00032402, 0x30e2ffff, 0x00823821, 0x00071402, 0x00e23821, - 0x00071027, 0x3c010800, 0xac23240c, 0xa4a20006, 0x3c030800, 0x8c632414, + 0x00071027, 0x3c010800, 0xac2323ec, 0xa4a20006, 0x3c030800, 0x8c6323f4, 0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, 0x24040001, 0x24034000, 0x000241c0, 0x00e01021, 0xa502001a, 0xa500001c, 0xacc00000, 0x3c010800, - 0xac241b70, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, - 0x3c010800, 0xac201b70, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, - 0x10400003, 0x00000000, 0x3c010800, 0xac201b70, 0x3c020800, 0x8c421b70, - 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000643, 0x8c842414, 0x0a000320, - 0x00000000, 0x3c030800, 0x90631ba8, 0x24020002, 0x14620003, 0x3c034b65, - 0x0a0002d7, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, - 0x24100001, 0x01002021, 0x0e000346, 0x02003021, 0x24020003, 0x3c010800, - 0xa0221ba8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c632400, - 0x10620006, 0x00000000, 0x3c020800, 0x944223e8, 0x00021400, 0x0a000315, - 0xae220014, 0x3c040800, 0x248423ea, 0x94820000, 0x00021400, 0xae220014, - 0x3c020800, 0x8c421bcc, 0x3c03c000, 0x3c010800, 0xa0201ba8, 0x00431025, + 0xac241b50, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, + 0x3c010800, 0xac201b50, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, + 0x10400003, 0x00000000, 0x3c010800, 0xac201b50, 0x3c020800, 0x8c421b50, + 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000637, 0x8c8423f4, 0x0a00032c, + 0x00000000, 0x3c030800, 0x90631b88, 0x24020002, 0x14620003, 0x3c034b65, + 0x0a0002e3, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, + 0x24100001, 0x01002021, 0x0e000352, 0x02003021, 0x24020003, 0x3c010800, + 0xa0221b88, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c6323e0, + 0x10620006, 0x00000000, 0x3c020800, 0x944223c8, 0x00021400, 0x0a000321, + 0xae220014, 0x3c040800, 0x248423ca, 0x94820000, 0x00021400, 0xae220014, + 0x3c020800, 0x8c421bac, 0x3c03c000, 0x3c010800, 0xa0201b88, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, - 0x00000000, 0x3c020800, 0x24421b94, 0x8c430000, 0x24630001, 0xac430000, + 0x00000000, 0x3c020800, 0x24421b74, 0x8c430000, 0x24630001, 0xac430000, 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, - 0x3c020800, 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x12600003, 0x00000000, - 0x0e0004b9, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, - 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b98, + 0x0e0004bf, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, + 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b78, 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, - 0x14c00017, 0x256e0008, 0x3c020800, 0x8c422404, 0x1040000a, 0x2402003e, - 0x3c010800, 0xa42223e0, 0x24020016, 0x3c010800, 0xa42223e2, 0x2402002a, - 0x3c010800, 0x0a000360, 0xa42223e4, 0x95620014, 0x3c010800, 0xa42223e0, - 0x8d670010, 0x00071402, 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, - 0x3c040800, 0x948423e4, 0x3c030800, 0x946323e2, 0x95cf0006, 0x3c020800, - 0x944223e0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, + 0x14c00011, 0x256e0008, 0x3c020800, 0x8c4223e4, 0x10400007, 0x24020016, + 0x3c010800, 0xa42223c2, 0x2402002a, 0x3c010800, 0x0a000366, 0xa42223c4, + 0x8d670010, 0x00071402, 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, + 0x3c040800, 0x948423c4, 0x3c030800, 0x946323c2, 0x95cf0006, 0x3c020800, + 0x944223c0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, 0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, - 0xa42223e6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023f4, 0x3c010800, - 0xac2023f8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bd0, 0x95220004, - 0x3c010800, 0xa4221bd4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, - 0x24020001, 0x3c010800, 0x0a000394, 0xac222408, 0x3c030800, 0x8c6323f8, - 0x3c020800, 0x94421bd4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bd0, - 0xa5820004, 0x3c020800, 0x8c421bd0, 0xa5820006, 0x3c020800, 0x8c422400, - 0x3c0d0800, 0x8dad23f4, 0x3c0a0800, 0x144000e5, 0x8d4a23f8, 0x3c020800, - 0x94421bd4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, - 0x01435023, 0x3c020800, 0x944223e6, 0x30420009, 0x10400008, 0x00000000, - 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223e6, 0x30420009, - 0x01a26823, 0x3c020800, 0x8c422408, 0x1040004a, 0x01203821, 0x3c020800, - 0x944223e2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, + 0xa42223c6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023d4, 0x3c010800, + 0xac2023d8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bb0, 0x95220004, + 0x3c010800, 0xa4221bb4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, + 0x24020001, 0x3c010800, 0x0a00039a, 0xac2223e8, 0x3c030800, 0x8c6323d8, + 0x3c020800, 0x94421bb4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bb0, + 0xa5820004, 0x3c020800, 0x8c421bb0, 0xa5820006, 0x3c020800, 0x8c4223e0, + 0x3c0d0800, 0x8dad23d4, 0x3c0a0800, 0x144000e5, 0x8d4a23d8, 0x3c020800, + 0x94421bb4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, + 0x01435023, 0x3c020800, 0x944223c6, 0x30420009, 0x10400008, 0x00000000, + 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223c6, 0x30420009, + 0x01a26823, 0x3c020800, 0x8c4223e8, 0x1040004a, 0x01203821, 0x3c020800, + 0x944223c2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, @@ -4043,131 +4060,127 @@ 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, - 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a000479, 0x30c6ffff, - 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c42241c, 0x14400007, - 0x00000000, 0x3c020800, 0x944223e2, 0x95230002, 0x01e21023, 0x10620077, - 0x00000000, 0x3c020800, 0x944223e2, 0x01e21023, 0xa5220002, 0x3c020800, - 0x8c42241c, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421ba6, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a00047f, 0x30c6ffff, + 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c4223fc, 0x14400007, + 0x00000000, 0x3c020800, 0x944223c2, 0x95230002, 0x01e21023, 0x10620077, + 0x00000000, 0x3c020800, 0x944223c2, 0x01e21023, 0xa5220002, 0x3c020800, + 0x8c4223fc, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b86, 0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, 0x00823823, 0x00072402, 0x30e2ffff, 0x00823821, 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, - 0x948423e4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, - 0x00061c02, 0x30c2ffff, 0x0a000479, 0x00623021, 0x01203821, 0x00004021, + 0x948423c4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, + 0x00061c02, 0x30c2ffff, 0x0a00047f, 0x00623021, 0x01203821, 0x00004021, 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, - 0x948423e4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, - 0x00061c02, 0x3c020800, 0x944223e0, 0x00c34821, 0x00441023, 0x00021fc2, + 0x948423c4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, + 0x00061c02, 0x3c020800, 0x944223c0, 0x00c34821, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043, 0x18400010, 0x00003021, 0x00402021, 0x94e20000, 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, - 0x00000000, 0x3c020800, 0x944223fc, 0x00c23021, 0x3122ffff, 0x00c23021, + 0x00000000, 0x3c020800, 0x944223dc, 0x00c23021, 0x3122ffff, 0x00c23021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, - 0x00061027, 0xa5820010, 0xadc00014, 0x0a000499, 0xadc00000, 0x8dc70010, + 0x00061027, 0xa5820010, 0xadc00014, 0x0a00049f, 0xadc00000, 0x8dc70010, 0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, 0x00433021, 0x00061402, 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, - 0x946323e4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, + 0x946323c4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, - 0x8c422404, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223f8, - 0x3c040800, 0x8c8423f4, 0x24420001, 0x3c010800, 0xac2223f8, 0x3c020800, - 0x8c421bd0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423f4, 0x00431821, - 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223f4, 0x3c010800, - 0xac231bd0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51ba8, + 0x8c4223e4, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223d8, + 0x3c040800, 0x8c8423d4, 0x24420001, 0x3c010800, 0xac2223d8, 0x3c020800, + 0x8c421bb0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423d4, 0x00431821, + 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223d4, 0x3c010800, + 0xac231bb0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51b86, 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, 0xafb40030, - 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90a30000, 0x24020003, - 0x146200d5, 0x00000000, 0x3c090800, 0x95291ba6, 0x3c020800, 0x944223e0, - 0x3c030800, 0x8c631bc0, 0x3c040800, 0x8c841bbc, 0x01221023, 0x0064182a, - 0xa7a9001e, 0x106000c8, 0xa7a20016, 0x24be0020, 0x97b6001e, 0x24b30018, - 0x24b70014, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, 0x97a30016, - 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ba, 0x00000000, 0x97d50818, - 0x32a2ffff, 0x104000ad, 0x00009021, 0x0040a021, 0x00008821, 0x0e00062d, - 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, 0x8c4223ec, - 0x24420001, 0x3c010800, 0x0a00059e, 0xac2223ec, 0x3c100800, 0x02118021, - 0x8e101bd8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, - 0x2407188c, 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, - 0x3042c000, 0x00623825, 0x31020080, 0x54400001, 0x34e70010, 0x3c020800, - 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, 0x8c631be4, 0x00021500, - 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, 0x00821021, - 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, 0x02459021, - 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff, - 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e0005aa, 0xa482000c, - 0x3242ffff, 0x0054102b, 0x1440ffc0, 0x3242ffff, 0x0a000596, 0x00000000, - 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1040006c, 0x00000000, 0x8e62fff0, - 0x00028900, 0x3c100800, 0x02118021, 0x0e00062d, 0x8e101bd8, 0x00403021, - 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a00059e, 0xae62082c, - 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, 0x2407188c, - 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, - 0x00623825, 0x3c020800, 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, - 0x8c631be4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, - 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a, - 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, - 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004, - 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, - 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, - 0x0a000579, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, - 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, - 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, - 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, 0x0a000590, - 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, - 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff96, 0x00000000, 0x8e620000, - 0x8e63fffc, 0x0043102a, 0x1440ff3e, 0x00000000, 0x8fbf0044, 0x8fbe0040, - 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028, - 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, - 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005b9, 0x00808021, 0x8f626820, - 0x30422000, 0x10400003, 0x00000000, 0x0e0001e3, 0x00002021, 0x8f624450, - 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, - 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, - 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, - 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, - 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, 0x0e0001e3, - 0x00002021, 0x0a0005cc, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, + 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000, 0x3c020800, + 0x944223c0, 0x3c030800, 0x8c631ba0, 0x3c040800, 0x8c841b9c, 0x01221023, + 0x0064182a, 0xa7a9001e, 0x106000bc, 0xa7a20016, 0x24be0022, 0x97b6001e, + 0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, + 0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ae, 0x00000000, + 0x97d50818, 0x32a2ffff, 0x104000a1, 0x00009021, 0x0040a021, 0x00008821, + 0x0e000621, 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, + 0x8c4223cc, 0x24420001, 0x3c010800, 0x0a000593, 0xac2223cc, 0x3c100800, + 0x02118021, 0x8e101bb8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, + 0x8e02000c, 0x2407188c, 0xacc20018, 0x31020080, 0x54400001, 0x34e70010, + 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, 0x00711821, 0x8c631bc4, + 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, + 0x00821021, 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, + 0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, + 0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e00059f, + 0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc6, 0x3242ffff, 0x0a00058b, + 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, 0x10400066, 0x00000000, + 0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, 0x0e000621, 0x8e101bb8, + 0x00403021, 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a000593, + 0xae62082c, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, + 0x2407188c, 0xacc20018, 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, + 0x00711821, 0x8c631bc4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, + 0x8e63fff4, 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x02c2102a, 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, + 0x30a4ffff, 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, + 0x8e020004, 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, + 0x00641821, 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0x0a00056e, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, + 0x10560003, 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, + 0x34e70010, 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, + 0x14620007, 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, + 0x0a000585, 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, + 0x0e00059f, 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff9c, 0x00000000, + 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1440ff4a, 0x00000000, 0x8fbf0044, + 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, + 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, + 0xafbf0014, 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005ae, 0x00808021, + 0x8f626820, 0x30422000, 0x10400003, 0x00000000, 0x0e0001ef, 0x00002021, + 0x8f624450, 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, + 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, + 0x2c620002, 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, + 0x10400009, 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, + 0x0e0001ef, 0x00002021, 0x0a0005c1, 0x00000000, 0x8fbf0014, 0x8fb00010, + 0x03e00008, 0x27bd0018, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, - 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b64, 0x24020b78, 0x3c010800, - 0xac221b74, 0x34630002, 0xaf634000, 0x0e00060d, 0x00808021, 0x3c010800, - 0xa0221b78, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, - 0x8c421b64, 0x0a000600, 0xac5000c0, 0x3c020800, 0x8c421b64, 0xac5000bc, - 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b6c, 0x3c010800, - 0xac231b7c, 0x3c010800, 0xac241b68, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b44, 0x24020b78, 0x3c010800, + 0xac221b54, 0x34630002, 0xaf634000, 0x0e000601, 0x00808021, 0x3c010800, + 0xa0221b58, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, + 0x8c421b44, 0x0a0005f4, 0xac5000c0, 0x3c020800, 0x8c421b44, 0xac5000bc, + 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b4c, 0x3c010800, + 0xac231b5c, 0x3c010800, 0xac241b48, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, 0xac830000, 0x8cc20000, 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, 0xac830000, 0x8cc20000, 0x50430001, 0x24050001, 0x3c020800, 0xac470000, 0x03e00008, 0x00a01021, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, - 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b6c, - 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b7c, + 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b4c, + 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b5c, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, - 0x0a000650, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x0a000644, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, - 0x8c631b68, 0x0a000659, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, + 0x8c631b48, 0x0a00064d, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, - 0x3c040800, 0x24841b10, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x0a000668, 0x00000000, 0x8fbf0018, 0x03e00008, + 0x3c040800, 0x24841ae0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000678, 0xafa00014, 0x0a00065c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x3c020800, 0x34423000, - 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b84, - 0x24020040, 0x3c010800, 0xac221b88, 0x3c010800, 0xac201b80, 0xac600000, + 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b64, + 0x24020040, 0x3c010800, 0xac221b68, 0x3c010800, 0xac201b60, 0xac600000, 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b80, 0x3c040800, 0x8c841b88, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b80, 0x14400003, - 0x00004021, 0x3c010800, 0xac201b80, 0x3c020800, 0x8c421b80, 0x3c030800, - 0x8c631b84, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b80, - 0x3c030800, 0x8c631b84, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, + 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b60, 0x3c040800, 0x8c841b68, + 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b60, 0x14400003, + 0x00004021, 0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x3c030800, + 0x8c631b64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, + 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b60, + 0x3c030800, 0x8c631b64, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, }; u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, - 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, - 0x496e0000, 0x73746b6f, 0x66662a2a, 0x00000000, 0x53774576, - 0x656e7430, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x66617461, 0x6c457272, 0x00000000, 0x00000000, 0x00000000 + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, + 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, + 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000, }; #if 0 /* All zeros, don't eat up space with it. */ @@ -4540,7 +4553,10 @@ tg3_chip_reset(tp); - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, NIC_SRAM_FIRMWARE_MBOX_MAGIC1); @@ -4596,17 +4612,6 @@ */ tg3_init_rings(tp); - /* Clear statistics/status block in chip, and status block in ram. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { - for (i = NIC_SRAM_STATS_BLK; - i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; - i += sizeof(u32)) { - tg3_write_mem(tp, i, 0); - udelay(40); - } - } - memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); - /* This value is determined during the probe time DMA * engine test, tg3_test_dma. */ @@ -4705,6 +4710,17 @@ return -ENODEV; } + /* Clear statistics/status block in chip, and status block in ram. */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_STATS_BLK; + i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; + i += sizeof(u32)) { + tg3_write_mem(tp, i, 0); + udelay(40); + } + } + memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + /* Setup replenish threshold. */ tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); @@ -5759,14 +5775,20 @@ rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | RX_MODE_KEEP_VLAN_TAG); + + /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG + * flag clear. + */ #if TG3_VLAN_TAG_USED - if (!tp->vlgrp) + if (!tp->vlgrp && + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) rx_mode |= RX_MODE_KEEP_VLAN_TAG; #else /* By definition, VLAN is disabled always in this * case. */ - rx_mode |= RX_MODE_KEEP_VLAN_TAG; + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + rx_mode |= RX_MODE_KEEP_VLAN_TAG; #endif if (dev->flags & IFF_PROMISC) { @@ -5881,7 +5903,8 @@ GET_REG32_LOOP(MSGINT_MODE, 0x0c); GET_REG32_1(DMAC_MODE); GET_REG32_LOOP(GRC_MODE, 0x4c); - GET_REG32_LOOP(NVRAM_CMD, 0x24); + if (tp->tg3_flags & TG3_FLAG_NVRAM) + GET_REG32_LOOP(NVRAM_CMD, 0x24); #undef __GET_REG32 #undef GET_REG32_LOOP @@ -6401,25 +6424,22 @@ static struct subsys_tbl_ent subsys_id_to_phy_id[] = { /* Broadcom boards. */ - { 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ - { 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ - { 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ - { 0x14e4, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ - { 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ - { 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ - { 0x14e4, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ - { 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ - { 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ - { 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ - { 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ + { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ + { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ + { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ + { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ + { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ + { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ + { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ + { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ + { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ /* 3com boards. */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */ - /* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX }, 3C996CT */ - /* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX }, 3C997T */ { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */ - /* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX }, 3C997SZ */ { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */ { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */ @@ -6434,7 +6454,10 @@ { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */ { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */ { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */ - { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 } /* NC7780_2 */ + { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */ + + /* IBM boards. */ + { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */ }; static int __devinit tg3_phy_probe(struct tg3 *tp) @@ -6715,6 +6738,7 @@ u32 misc_ctrl_reg; u32 cacheline_sz_reg; u32 pci_state_reg, grc_misc_cfg; + u32 val; u16 pci_cmd; int err; @@ -6911,7 +6935,9 @@ udelay(40); /* Initialize data/descriptor byte/word swapping. */ - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); tg3_switch_clocks(tp); @@ -6974,7 +7000,8 @@ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2))) + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F))) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -7164,26 +7191,33 @@ test_desc.addr_lo = buf_dma & 0xffffffff; test_desc.nic_mbuf = 0x00002100; test_desc.len = size; + + /* + * HP ZX1 was seeing test failures for 5701 cards running at 33Mhz + * the *second* time the tg3 driver was getting loaded after an + * initial scan. + * + * Broadcom tells me: + * ...the DMA engine is connected to the GRC block and a DMA + * reset may affect the GRC block in some unpredictable way... + * The behavior of resets to individual blocks has not been tested. + * + * Broadcom noted the GRC reset will also reset all sub-components. + */ if (to_device) { test_desc.cqid_sqid = (13 << 8) | 2; - tw32(RDMAC_MODE, RDMAC_MODE_RESET); - tr32(RDMAC_MODE); - udelay(40); tw32(RDMAC_MODE, RDMAC_MODE_ENABLE); tr32(RDMAC_MODE); udelay(40); } else { test_desc.cqid_sqid = (16 << 8) | 7; - tw32(WDMAC_MODE, WDMAC_MODE_RESET); - tr32(WDMAC_MODE); - udelay(40); tw32(WDMAC_MODE, WDMAC_MODE_ENABLE); tr32(WDMAC_MODE); udelay(40); } - test_desc.flags = 0x00000004; + test_desc.flags = 0x00000005; for (i = 0; i < (sizeof(test_desc) / sizeof(u32)); i++) { u32 val; @@ -7342,9 +7376,19 @@ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { /* Remove this if it causes problems for some boards. */ tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; - } - tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE; + /* On 5700/5701 chips, we need to set this bit. + * Otherwise the chip will issue cacheline transactions + * to streamable DMA memory with not all the byte + * enables turned on. This is an error on several + * RISC PCI controllers, in particular sparc64. + * + * On 5703/5704 chips, this bit has been reassigned + * a different meaning. In particular, it is used + * on those chips to enable a PCI-X workaround. + */ + tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE; + } tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); @@ -7359,28 +7403,38 @@ goto out; while (1) { - u32 *p, i; + u32 *p = buf, i; - p = buf; for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) p[i] = i; /* Send the buffer to the chip. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 1); - if (ret) + if (ret) { + printk(KERN_ERR "tg3_test_dma() Write the buffer failed %d\n", ret); break; + } - p = buf; - for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) + /* validate data reached card RAM correctly. */ + for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { + u32 val; + tg3_read_mem(tp, 0x2100 + (i*4), &val); + if (val != p[i]) { + printk( KERN_ERR " tg3_test_dma() Card buffer currupted on write! (%d != %d)\n", val, i); + /* ret = -ENODEV here? */ + } p[i] = 0; + } /* Now read it back. */ ret = tg3_do_test_dma(tp, buf, buf_dma, TEST_BUFFER_SIZE, 0); - if (ret) + if (ret) { + printk(KERN_ERR "tg3_test_dma() Read the buffer failed %d\n", ret); + break; + } /* Verify it. */ - p = buf; for (i = 0; i < TEST_BUFFER_SIZE / sizeof(u32); i++) { if (p[i] == i) continue; @@ -7391,6 +7445,7 @@ tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); break; } else { + printk(KERN_ERR "tg3_test_dma() buffer corrupted on read back! (%d != %d)\n", p[i], i); ret = -ENODEV; goto out; } @@ -7526,11 +7581,13 @@ if (pm_cap == 0) { printk(KERN_ERR PFX "Cannot find PowerManagement capability, " "aborting.\n"); + err = -EIO; goto err_out_free_res; } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + if (!err) { pci_using_dac = 1; } else { err = pci_set_dma_mask(pdev, 0xffffffffULL); diff -urN linux-2.4.24/drivers/net/tokenring/Config.in linux-2.4.25/drivers/net/tokenring/Config.in --- linux-2.4.24/drivers/net/tokenring/Config.in 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/net/tokenring/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -20,12 +20,12 @@ dep_tristate ' IBM Lanstreamer chipset PCI adapter support' CONFIG_IBMLS $CONFIG_TR $CONFIG_PCI dep_tristate ' 3Com 3C359 Token Link Velocity XL adapter support' CONFIG_3C359 $CONFIG_TR $CONFIG_PCI tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR - if [ "$CONFIG_TMS380TR" != "n" ]; then - dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI - dep_tristate ' Generic TMS380 ISA support' CONFIG_TMSISA $CONFIG_ISA - dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_PCI - dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_MCA - fi + + dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_PCI $CONFIG_TMS380TR + dep_tristate ' Generic TMS380 ISA support' CONFIG_TMSISA $CONFIG_ISA $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_PCI $CONFIG_TMS380TR + dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_MCA $CONFIG_TMS380TR + if [ "$CONFIG_ISA" = "y" -o "$CONFIG_MCA" = "y" ]; then tristate ' SMC ISA/MCA adapter support' CONFIG_SMCTR fi diff -urN linux-2.4.24/drivers/net/tokenring/olympic.c linux-2.4.25/drivers/net/tokenring/olympic.c --- linux-2.4.24/drivers/net/tokenring/olympic.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/net/tokenring/olympic.c 2004-02-18 05:36:31.000000000 -0800 @@ -457,14 +457,7 @@ printk("Before the open command \n"); #endif do { - int i; - - for(i=0;i"); +MODULE_AUTHOR("David Dillow "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); MODULE_PARM(rx_copybreak, "i"); @@ -146,11 +146,12 @@ int capabilities; }; -#define TYPHOON_CRYPTO_NONE 0 -#define TYPHOON_CRYPTO_DES 1 -#define TYPHOON_CRYPTO_3DES 2 -#define TYPHOON_CRYPTO_VARIABLE 4 -#define TYPHOON_FIBER 8 +#define TYPHOON_CRYPTO_NONE 0x00 +#define TYPHOON_CRYPTO_DES 0x01 +#define TYPHOON_CRYPTO_3DES 0x02 +#define TYPHOON_CRYPTO_VARIABLE 0x04 +#define TYPHOON_FIBER 0x08 +#define TYPHOON_WAKEUP_NEEDS_RESET 0x10 enum typhoon_cards { TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR, @@ -307,7 +308,8 @@ /* We'll wait up to six seconds for a reset, and half a second normally. */ #define TYPHOON_UDELAY 50 -#define TYPHOON_RESET_TIMEOUT (6 * HZ) +#define TYPHOON_RESET_TIMEOUT_SLEEP (6 * HZ) +#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY) #define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28) @@ -375,10 +377,12 @@ typhoon_reset(unsigned long ioaddr, int wait_type) { int i, err = 0; - int timeout = TYPHOON_RESET_TIMEOUT; + int timeout; if(wait_type == WaitNoSleep) - timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY); + timeout = TYPHOON_RESET_TIMEOUT_NOSLEEP; + else + timeout = TYPHOON_RESET_TIMEOUT_SLEEP; writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); @@ -1857,6 +1861,11 @@ if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0) return -ETIMEDOUT; + /* Since we cannot monitor the status of the link while sleeping, + * tell the world it went away. + */ + netif_carrier_off(tp->dev); + pci_enable_wake(tp->pdev, state, 1); pci_disable_device(pdev); return pci_set_power_state(pdev, state); @@ -1871,8 +1880,13 @@ pci_set_power_state(pdev, 0); pci_restore_state(pdev, tp->pci_state); + /* Post 2.x.x versions of the Sleep Image require a reset before + * we can download the Runtime Image. But let's not make users of + * the old firmware pay for the reset. + */ writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND); - if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) + if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 || + (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET)) return typhoon_reset(ioaddr, wait_type); return 0; @@ -2250,7 +2264,7 @@ void *shared; dma_addr_t shared_dma; struct cmd_desc xp_cmd; - struct resp_desc xp_resp; + struct resp_desc xp_resp[3]; int i; int err = 0; @@ -2378,15 +2392,15 @@ } INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS); - if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) { + if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) { printk(ERR_PFX "%s: cannot read MAC address\n", pdev->slot_name); err = -EIO; goto error_out_reset; } - *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1)); - *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2)); + *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); + *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); if(!is_valid_ether_addr(dev->dev_addr)) { printk(ERR_PFX "%s: Could not obtain valid ethernet address, " @@ -2394,6 +2408,28 @@ goto error_out_reset; } + /* Read the Sleep Image version last, so the response is valid + * later when we print out the version reported. + */ + INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); + if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { + printk(ERR_PFX "%s: Could not get Sleep Image version\n", + pdev->slot_name); + goto error_out_reset; + } + + tp->capabilities = typhoon_card_info[card_id].capabilities; + tp->xcvr_select = TYPHOON_XCVR_AUTONEG; + + /* Typhoon 1.0 Sleep Images return one response descriptor to the + * READ_VERSIONS command. Those versions are OK after waking up + * from sleep without needing a reset. Typhoon 1.1+ Sleep Images + * seem to need a little extra help to get started. Since we don't + * know how to nudge it along, just kick it. + */ + if(xp_resp[0].numDesc != 0) + tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; + if(typhoon_sleep(tp, 3, 0) < 0) { printk(ERR_PFX "%s: cannot put adapter to sleep\n", pdev->slot_name); @@ -2401,9 +2437,6 @@ goto error_out_reset; } - tp->capabilities = typhoon_card_info[card_id].capabilities; - tp->xcvr_select = TYPHOON_XCVR_AUTONEG; - /* The chip-specific entries in the device structure. */ dev->open = typhoon_open; dev->hard_start_xmit = typhoon_start_tx; @@ -2440,6 +2473,32 @@ printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x\n", dev->dev_addr[i]); + /* xp_resp still contains the response to the READ_VERSIONS command. + * For debugging, let the user know what version he has. + */ + if(xp_resp[0].numDesc == 0) { + /* This is the Typhoon 1.0 type Sleep Image, last 16 bits + * of version is Month/Day of build. + */ + u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff; + printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built " + "%02u/%02u/2000\n", dev->name, monthday >> 8, + monthday & 0xff); + } else if(xp_resp[0].numDesc == 2) { + /* This is the Typhoon 1.1+ type Sleep Image + */ + u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); + u8 *ver_string = (u8 *) &xp_resp[1]; + ver_string[25] = 0; + printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version " + "%u.%u.%u.%u %s\n", dev->name, HIPQUAD(sleep_ver), + ver_string); + } else { + printk(KERN_WARNING "%s: Unknown Sleep Image version " + "(%u:%04x)\n", dev->name, xp_resp[0].numDesc, + le32_to_cpu(xp_resp[0].parm2)); + } + return 0; error_out_reset: diff -urN linux-2.4.24/drivers/net/wan/8253x/crc32dcl.h linux-2.4.25/drivers/net/wan/8253x/crc32dcl.h --- linux-2.4.24/drivers/net/wan/8253x/crc32dcl.h 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/net/wan/8253x/crc32dcl.h 2004-02-18 05:36:31.000000000 -0800 @@ -29,7 +29,6 @@ /****************************************************/ extern void fn_init_crc_table(void); -extern unsigned int fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc); extern unsigned int fn_calc_memory_crc32(void *p, unsigned int n_bytes); extern unsigned int fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc); diff -urN linux-2.4.24/drivers/net/wan/Config.in linux-2.4.25/drivers/net/wan/Config.in --- linux-2.4.24/drivers/net/wan/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -23,7 +23,7 @@ # COMX drivers # - tristate ' MultiGate (COMX) synchronous serial boards support' CONFIG_COMX + bool ' MultiGate (COMX) synchronous serial boards support' CONFIG_COMX if [ "$CONFIG_COMX" != "n" ]; then dep_tristate ' Support for COMX/CMX/HiCOMX boards' CONFIG_COMX_HW_COMX $CONFIG_COMX dep_tristate ' Support for LoCOMX board' CONFIG_COMX_HW_LOCOMX $CONFIG_COMX @@ -77,13 +77,23 @@ else comment ' X.25/LAPB support is disabled' fi - dep_tristate ' SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC - dep_tristate ' Moxa C101 support' CONFIG_C101 $CONFIG_HDLC - dep_tristate ' FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC - bool ' Debug received/transmitted packets' CONFIG_HDLC_DEBUG_PKT - bool ' Debug hard_header routines' CONFIG_HDLC_DEBUG_HARD_HEADER - bool ' Debug FECN/BECN conditions' CONFIG_HDLC_DEBUG_ECN - bool ' Debug RX/TX packet rings' CONFIG_HDLC_DEBUG_RINGS + if [ "$CONFIG_PCI" != "n" ]; then + dep_tristate ' Goramo PCI200SYN support' CONFIG_PCI200SYN $CONFIG_HDLC + dep_tristate ' Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)' CONFIG_PC300 $CONFIG_HDLC + if [ "$CONFIG_PC300" != "n" ]; then + if [ "$CONFIG_PPP" != "n" -a "$CONFIG_PPP_MULTLINK" != "n" -a "$CONFIG_PPP_SYNCTTY" != "n" -a "$CONFIG_HDLC_PPP" = "y" ]; then + bool ' Cyclades-PC300 MLPPP support' CONFIG_PC300_MLPPP + else + comment ' Cyclades-PC300 MLPPP support is disabled.' + comment ' Refer to the file README.mlppp, provided by PC300 package.' + fi + fi + dep_tristate ' FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC + fi + if [ "$CONFIG_ISA" != "n" ]; then + dep_tristate ' SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC + dep_tristate ' Moxa C101 support' CONFIG_C101 $CONFIG_HDLC + fi fi tristate ' Frame relay DLCI support' CONFIG_DLCI diff -urN linux-2.4.24/drivers/net/wan/Makefile linux-2.4.25/drivers/net/wan/Makefile --- linux-2.4.24/drivers/net/wan/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,7 @@ O_TARGET := wan.o -export-objs = z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o +export-objs = z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o pc300_drv.o list-multi = wanpipe.o cyclomx.o wanpipe-objs = sdlamain.o sdla_ft1.o $(wanpipe-y) @@ -31,6 +31,8 @@ hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o hdlc-objs := $(hdlc-y) +pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o + obj-$(CONFIG_HOSTESS_SV11) += z85230.o syncppp.o hostess_sv11.o obj-$(CONFIG_SEALEVEL_4021) += z85230.o syncppp.o sealevel.o obj-$(CONFIG_COMX) += comx.o @@ -71,15 +73,20 @@ obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o obj-$(CONFIG_LAPBETHER) += lapbether.o obj-$(CONFIG_SBNI) += sbni.o +obj-$(CONFIG_PC300) += pc300.o obj-$(CONFIG_HDLC) += hdlc.o ifeq ($(CONFIG_HDLC_PPP),y) obj-$(CONFIG_HDLC) += syncppp.o endif obj-$(CONFIG_N2) += n2.o obj-$(CONFIG_C101) += c101.o +obj-$(CONFIG_PCI200SYN) += pci200syn.o include $(TOPDIR)/Rules.make +pc300.o: pc300_drv.o $(pc300-y) + $(LD) -r -o $@ pc300_drv.o $(pc300-y) + hdlc.o: $(hdlc-objs) $(LD) -r -o $@ $(hdlc-objs) diff -urN linux-2.4.24/drivers/net/wan/c101.c linux-2.4.25/drivers/net/wan/c101.c --- linux-2.4.24/drivers/net/wan/c101.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/c101.c 2004-02-18 05:36:31.000000000 -0800 @@ -14,7 +14,6 @@ * Moxa C101 User's Manual */ -#include #include #include #include @@ -33,6 +32,9 @@ static const char* version = "Moxa C101 driver version: 1.14"; static const char* devname = "C101"; +#undef DEBUG_PKT +#define DEBUG_RINGS + #define C101_PAGE 0x1D00 #define C101_DTR 0x1E00 #define C101_SCA 0x1F00 @@ -188,7 +190,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); port_t *port = hdlc_to_port(hdlc); -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS if (cmd == SIOCDEVPRIVATE) { sca_dump_rings(hdlc); return 0; @@ -297,9 +299,6 @@ card->tx_ring_buffers = TX_RING_BUFFERS; card->rx_ring_buffers = RX_RING_BUFFERS; - printk(KERN_DEBUG "c101: using %u TX + %u RX packets rings\n", - card->tx_ring_buffers, card->rx_ring_buffers); - card->buff_offset = C101_WINDOW_SIZE; /* Bytes 1D00-1FFF reserved */ readb(card->win0base + C101_PAGE); /* Resets SCA? */ @@ -332,6 +331,11 @@ sca_init_sync_port(card); /* Set up C101 memory */ + printk(KERN_INFO "%s: Moxa C101 on IRQ%u," + " using %u TX + %u RX packets rings\n", + hdlc_to_name(&card->hdlc), card->irq, + card->tx_ring_buffers, card->rx_ring_buffers); + *new_card = card; new_card = &card->next_card; return 0; diff -urN linux-2.4.24/drivers/net/wan/hd64572.h linux-2.4.25/drivers/net/wan/hd64572.h --- linux-2.4.24/drivers/net/wan/hd64572.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hd64572.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,516 @@ +/* + * hd64572.h Description of the Hitachi HD64572 (SCA-II), valid for + * CPU modes 0 & 2. + * + * Author: Ivan Passos + * + * Copyright: (c) 2000-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef __HD64572_H +#define __HD64572_H + +/* Illegal Access Register */ +#define ILAR 0x00 + +/* Wait Controller Registers */ +#define PABR0L 0x20 /* Physical Addr Boundary Register 0 L */ +#define PABR0H 0x21 /* Physical Addr Boundary Register 0 H */ +#define PABR1L 0x22 /* Physical Addr Boundary Register 1 L */ +#define PABR1H 0x23 /* Physical Addr Boundary Register 1 H */ +#define WCRL 0x24 /* Wait Control Register L */ +#define WCRM 0x25 /* Wait Control Register M */ +#define WCRH 0x26 /* Wait Control Register H */ + +/* Interrupt Registers */ +#define IVR 0x60 /* Interrupt Vector Register */ +#define IMVR 0x64 /* Interrupt Modified Vector Register */ +#define ITCR 0x68 /* Interrupt Control Register */ +#define ISR0 0x6c /* Interrupt Status Register 0 */ +#define ISR1 0x70 /* Interrupt Status Register 1 */ +#define IER0 0x74 /* Interrupt Enable Register 0 */ +#define IER1 0x78 /* Interrupt Enable Register 1 */ + +/* Register Access Macros (chan is 0 or 1 in _any_ case) */ +#define M_REG(reg, chan) (reg + 0x80*chan) /* MSCI */ +#define DRX_REG(reg, chan) (reg + 0x40*chan) /* DMA Rx */ +#define DTX_REG(reg, chan) (reg + 0x20*(2*chan + 1)) /* DMA Tx */ +#define TRX_REG(reg, chan) (reg + 0x20*chan) /* Timer Rx */ +#define TTX_REG(reg, chan) (reg + 0x10*(2*chan + 1)) /* Timer Tx */ +#define ST_REG(reg, chan) (reg + 0x80*chan) /* Status Cnt */ +#define IR0_DRX(val, chan) ((val)<<(8*(chan))) /* Int DMA Rx */ +#define IR0_DTX(val, chan) ((val)<<(4*(2*chan + 1))) /* Int DMA Tx */ +#define IR0_M(val, chan) ((val)<<(8*(chan))) /* Int MSCI */ + +/* MSCI Channel Registers */ +#define MSCI0_OFFSET 0x00 +#define MSCI1_OFFSET 0x80 + +#define MD0 0x138 /* Mode reg 0 */ +#define MD1 0x139 /* Mode reg 1 */ +#define MD2 0x13a /* Mode reg 2 */ +#define MD3 0x13b /* Mode reg 3 */ +#define CTL 0x130 /* Control reg */ +#define RXS 0x13c /* RX clock source */ +#define TXS 0x13d /* TX clock source */ +#define EXS 0x13e /* External clock input selection */ +#define TMCT 0x144 /* Time constant (Tx) */ +#define TMCR 0x145 /* Time constant (Rx) */ +#define CMD 0x128 /* Command reg */ +#define ST0 0x118 /* Status reg 0 */ +#define ST1 0x119 /* Status reg 1 */ +#define ST2 0x11a /* Status reg 2 */ +#define ST3 0x11b /* Status reg 3 */ +#define ST4 0x11c /* Status reg 4 */ +#define FST 0x11d /* frame Status reg */ +#define IE0 0x120 /* Interrupt enable reg 0 */ +#define IE1 0x121 /* Interrupt enable reg 1 */ +#define IE2 0x122 /* Interrupt enable reg 2 */ +#define IE4 0x124 /* Interrupt enable reg 4 */ +#define FIE 0x125 /* Frame Interrupt enable reg */ +#define SA0 0x140 /* Syn Address reg 0 */ +#define SA1 0x141 /* Syn Address reg 1 */ +#define IDL 0x142 /* Idle register */ +#define TRBL 0x100 /* TX/RX buffer reg L */ +#define TRBK 0x101 /* TX/RX buffer reg K */ +#define TRBJ 0x102 /* TX/RX buffer reg J */ +#define TRBH 0x103 /* TX/RX buffer reg H */ +#define TRC0 0x148 /* TX Ready control reg 0 */ +#define TRC1 0x149 /* TX Ready control reg 1 */ +#define RRC 0x14a /* RX Ready control reg */ +#define CST0 0x108 /* Current Status Register 0 */ +#define CST1 0x109 /* Current Status Register 1 */ +#define CST2 0x10a /* Current Status Register 2 */ +#define CST3 0x10b /* Current Status Register 3 */ +#define GPO 0x131 /* General Purpose Output Pin Ctl Reg */ +#define TFS 0x14b /* Tx Start Threshold Ctl Reg */ +#define TFN 0x143 /* Inter-transmit-frame Time Fill Ctl Reg */ +#define TBN 0x110 /* Tx Buffer Number Reg */ +#define RBN 0x111 /* Rx Buffer Number Reg */ +#define TNR0 0x150 /* Tx DMA Request Ctl Reg 0 */ +#define TNR1 0x151 /* Tx DMA Request Ctl Reg 1 */ +#define TCR 0x152 /* Tx DMA Critical Request Reg */ +#define RNR 0x154 /* Rx DMA Request Ctl Reg */ +#define RCR 0x156 /* Rx DMA Critical Request Reg */ + +/* Timer Registers */ +#define TIMER0RX_OFFSET 0x00 +#define TIMER0TX_OFFSET 0x10 +#define TIMER1RX_OFFSET 0x20 +#define TIMER1TX_OFFSET 0x30 + +#define TCNTL 0x200 /* Timer Upcounter L */ +#define TCNTH 0x201 /* Timer Upcounter H */ +#define TCONRL 0x204 /* Timer Constant Register L */ +#define TCONRH 0x205 /* Timer Constant Register H */ +#define TCSR 0x206 /* Timer Control/Status Register */ +#define TEPR 0x207 /* Timer Expand Prescale Register */ + +/* DMA registers */ +#define PCR 0x40 /* DMA priority control reg */ +#define DRR 0x44 /* DMA reset reg */ +#define DMER 0x07 /* DMA Master Enable reg */ +#define BTCR 0x08 /* Burst Tx Ctl Reg */ +#define BOLR 0x0c /* Back-off Length Reg */ +#define DSR_RX(chan) (0x48 + 2*chan) /* DMA Status Reg (Rx) */ +#define DSR_TX(chan) (0x49 + 2*chan) /* DMA Status Reg (Tx) */ +#define DIR_RX(chan) (0x4c + 2*chan) /* DMA Interrupt Enable Reg (Rx) */ +#define DIR_TX(chan) (0x4d + 2*chan) /* DMA Interrupt Enable Reg (Tx) */ +#define FCT_RX(chan) (0x50 + 2*chan) /* Frame End Interrupt Counter (Rx) */ +#define FCT_TX(chan) (0x51 + 2*chan) /* Frame End Interrupt Counter (Tx) */ +#define DMR_RX(chan) (0x54 + 2*chan) /* DMA Mode Reg (Rx) */ +#define DMR_TX(chan) (0x55 + 2*chan) /* DMA Mode Reg (Tx) */ +#define DCR_RX(chan) (0x58 + 2*chan) /* DMA Command Reg (Rx) */ +#define DCR_TX(chan) (0x59 + 2*chan) /* DMA Command Reg (Tx) */ + +/* DMA Channel Registers */ +#define DMAC0RX_OFFSET 0x00 +#define DMAC0TX_OFFSET 0x20 +#define DMAC1RX_OFFSET 0x40 +#define DMAC1TX_OFFSET 0x60 + +#define DARL 0x80 /* Dest Addr Register L (single-block, RX only) */ +#define DARH 0x81 /* Dest Addr Register H (single-block, RX only) */ +#define DARB 0x82 /* Dest Addr Register B (single-block, RX only) */ +#define DARBH 0x83 /* Dest Addr Register BH (single-block, RX only) */ +#define SARL 0x80 /* Source Addr Register L (single-block, TX only) */ +#define SARH 0x81 /* Source Addr Register H (single-block, TX only) */ +#define SARB 0x82 /* Source Addr Register B (single-block, TX only) */ +#define DARBH 0x83 /* Source Addr Register BH (single-block, TX only) */ +#define BARL 0x80 /* Buffer Addr Register L (chained-block) */ +#define BARH 0x81 /* Buffer Addr Register H (chained-block) */ +#define BARB 0x82 /* Buffer Addr Register B (chained-block) */ +#define BARBH 0x83 /* Buffer Addr Register BH (chained-block) */ +#define CDAL 0x84 /* Current Descriptor Addr Register L */ +#define CDAH 0x85 /* Current Descriptor Addr Register H */ +#define CDAB 0x86 /* Current Descriptor Addr Register B */ +#define CDABH 0x87 /* Current Descriptor Addr Register BH */ +#define EDAL 0x88 /* Error Descriptor Addr Register L */ +#define EDAH 0x89 /* Error Descriptor Addr Register H */ +#define EDAB 0x8a /* Error Descriptor Addr Register B */ +#define EDABH 0x8b /* Error Descriptor Addr Register BH */ +#define BFLL 0x90 /* RX Buffer Length L (only RX) */ +#define BFLH 0x91 /* RX Buffer Length H (only RX) */ +#define BCRL 0x8c /* Byte Count Register L */ +#define BCRH 0x8d /* Byte Count Register H */ + +/* Block Descriptor Structure */ +typedef struct { + unsigned long next; /* pointer to next block descriptor */ + unsigned long ptbuf; /* buffer pointer */ + unsigned short len; /* data length */ + unsigned char status; /* status */ + unsigned char filler[5]; /* alignment filler (16 bytes) */ +} pcsca_bd_t; + +typedef struct { + u32 cp; /* pointer to next block descriptor */ + u32 bp; /* buffer pointer */ + u16 len; /* data length */ + u8 stat; /* status */ + u8 unused; /* pads to 4-byte boundary */ +}pkt_desc; + + +/* + Descriptor Status definitions: + + Bit Transmission Reception + + 7 EOM EOM + 6 - Short Frame + 5 - Abort + 4 - Residual bit + 3 Underrun Overrun + 2 - CRC + 1 Ownership Ownership + 0 EOT - +*/ +#define DST_EOT 0x01 /* End of transmit command */ +#define DST_OSB 0x02 /* Ownership bit */ +#define DST_CRC 0x04 /* CRC Error */ +#define DST_OVR 0x08 /* Overrun */ +#define DST_UDR 0x08 /* Underrun */ +#define DST_RBIT 0x10 /* Residual bit */ +#define DST_ABT 0x20 /* Abort */ +#define DST_SHRT 0x40 /* Short Frame */ +#define DST_EOM 0x80 /* End of Message */ + +/* Packet Descriptor Status bits */ + +#define ST_TX_EOM 0x80 /* End of frame */ +#define ST_TX_UNDRRUN 0x08 +#define ST_TX_OWNRSHP 0x02 +#define ST_TX_EOT 0x01 /* End of transmition */ + +#define ST_RX_EOM 0x80 /* End of frame */ +#define ST_RX_SHORT 0x40 /* Short frame */ +#define ST_RX_ABORT 0x20 /* Abort */ +#define ST_RX_RESBIT 0x10 /* Residual bit */ +#define ST_RX_OVERRUN 0x08 /* Overrun */ +#define ST_RX_CRC 0x04 /* CRC */ +#define ST_RX_OWNRSHP 0x02 + +#define ST_ERROR_MASK 0x7C + +/* Status Counter Registers */ +#define CMCR 0x158 /* Counter Master Ctl Reg */ +#define TECNTL 0x160 /* Tx EOM Counter L */ +#define TECNTM 0x161 /* Tx EOM Counter M */ +#define TECNTH 0x162 /* Tx EOM Counter H */ +#define TECCR 0x163 /* Tx EOM Counter Ctl Reg */ +#define URCNTL 0x164 /* Underrun Counter L */ +#define URCNTH 0x165 /* Underrun Counter H */ +#define URCCR 0x167 /* Underrun Counter Ctl Reg */ +#define RECNTL 0x168 /* Rx EOM Counter L */ +#define RECNTM 0x169 /* Rx EOM Counter M */ +#define RECNTH 0x16a /* Rx EOM Counter H */ +#define RECCR 0x16b /* Rx EOM Counter Ctl Reg */ +#define ORCNTL 0x16c /* Overrun Counter L */ +#define ORCNTH 0x16d /* Overrun Counter H */ +#define ORCCR 0x16f /* Overrun Counter Ctl Reg */ +#define CECNTL 0x170 /* CRC Counter L */ +#define CECNTH 0x171 /* CRC Counter H */ +#define CECCR 0x173 /* CRC Counter Ctl Reg */ +#define ABCNTL 0x174 /* Abort frame Counter L */ +#define ABCNTH 0x175 /* Abort frame Counter H */ +#define ABCCR 0x177 /* Abort frame Counter Ctl Reg */ +#define SHCNTL 0x178 /* Short frame Counter L */ +#define SHCNTH 0x179 /* Short frame Counter H */ +#define SHCCR 0x17b /* Short frame Counter Ctl Reg */ +#define RSCNTL 0x17c /* Residual bit Counter L */ +#define RSCNTH 0x17d /* Residual bit Counter H */ +#define RSCCR 0x17f /* Residual bit Counter Ctl Reg */ + +/* Register Programming Constants */ + +#define IR0_DMIC 0x00000001 +#define IR0_DMIB 0x00000002 +#define IR0_DMIA 0x00000004 +#define IR0_EFT 0x00000008 +#define IR0_DMAREQ 0x00010000 +#define IR0_TXINT 0x00020000 +#define IR0_RXINTB 0x00040000 +#define IR0_RXINTA 0x00080000 +#define IR0_TXRDY 0x00100000 +#define IR0_RXRDY 0x00200000 + +#define MD0_CRC16_0 0x00 +#define MD0_CRC16_1 0x01 +#define MD0_CRC32 0x02 +#define MD0_CRC_CCITT 0x03 +#define MD0_CRCC0 0x04 +#define MD0_CRCC1 0x08 +#define MD0_AUTO_ENA 0x10 +#define MD0_ASYNC 0x00 +#define MD0_BY_MSYNC 0x20 +#define MD0_BY_BISYNC 0x40 +#define MD0_BY_EXT 0x60 +#define MD0_BIT_SYNC 0x80 +#define MD0_TRANSP 0xc0 + +#define MD0_HDLC 0x80 /* Bit-sync HDLC mode */ + +#define MD0_CRC_NONE 0x00 +#define MD0_CRC_16_0 0x04 +#define MD0_CRC_16 0x05 +#define MD0_CRC_ITU32 0x06 +#define MD0_CRC_ITU 0x07 + +#define MD1_NOADDR 0x00 +#define MD1_SADDR1 0x40 +#define MD1_SADDR2 0x80 +#define MD1_DADDR 0xc0 + +#define MD2_NRZI_IEEE 0x40 +#define MD2_MANCHESTER 0x80 +#define MD2_FM_MARK 0xA0 +#define MD2_FM_SPACE 0xC0 +#define MD2_LOOPBACK 0x03 /* Local data Loopback */ + +#define MD2_F_DUPLEX 0x00 +#define MD2_AUTO_ECHO 0x01 +#define MD2_LOOP_HI_Z 0x02 +#define MD2_LOOP_MIR 0x03 +#define MD2_ADPLL_X8 0x00 +#define MD2_ADPLL_X16 0x08 +#define MD2_ADPLL_X32 0x10 +#define MD2_NRZ 0x00 +#define MD2_NRZI 0x20 +#define MD2_NRZ_IEEE 0x40 +#define MD2_MANCH 0x00 +#define MD2_FM1 0x20 +#define MD2_FM0 0x40 +#define MD2_FM 0x80 + +#define CTL_RTS 0x01 +#define CTL_DTR 0x02 +#define CTL_SYN 0x04 +#define CTL_IDLC 0x10 +#define CTL_UDRNC 0x20 +#define CTL_URSKP 0x40 +#define CTL_URCT 0x80 + +#define CTL_NORTS 0x01 +#define CTL_NODTR 0x02 +#define CTL_IDLE 0x10 + +#define RXS_BR0 0x01 +#define RXS_BR1 0x02 +#define RXS_BR2 0x04 +#define RXS_BR3 0x08 +#define RXS_ECLK 0x00 +#define RXS_ECLK_NS 0x20 +#define RXS_IBRG 0x40 +#define RXS_PLL1 0x50 +#define RXS_PLL2 0x60 +#define RXS_PLL3 0x70 +#define RXS_DRTXC 0x80 + +#define TXS_BR0 0x01 +#define TXS_BR1 0x02 +#define TXS_BR2 0x04 +#define TXS_BR3 0x08 +#define TXS_ECLK 0x00 +#define TXS_IBRG 0x40 +#define TXS_RCLK 0x60 +#define TXS_DTRXC 0x80 + +#define EXS_RES0 0x01 +#define EXS_RES1 0x02 +#define EXS_RES2 0x04 +#define EXS_TES0 0x10 +#define EXS_TES1 0x20 +#define EXS_TES2 0x40 + +#define CLK_BRG_MASK 0x0F +#define CLK_PIN_OUT 0x80 +#define CLK_LINE 0x00 /* clock line input */ +#define CLK_BRG 0x40 /* internal baud rate generator */ +#define CLK_TX_RXCLK 0x60 /* TX clock from RX clock */ + +#define CMD_RX_RST 0x11 +#define CMD_RX_ENA 0x12 +#define CMD_RX_DIS 0x13 +#define CMD_RX_CRC_INIT 0x14 +#define CMD_RX_MSG_REJ 0x15 +#define CMD_RX_MP_SRCH 0x16 +#define CMD_RX_CRC_EXC 0x17 +#define CMD_RX_CRC_FRC 0x18 +#define CMD_TX_RST 0x01 +#define CMD_TX_ENA 0x02 +#define CMD_TX_DISA 0x03 +#define CMD_TX_CRC_INIT 0x04 +#define CMD_TX_CRC_EXC 0x05 +#define CMD_TX_EOM 0x06 +#define CMD_TX_ABORT 0x07 +#define CMD_TX_MP_ON 0x08 +#define CMD_TX_BUF_CLR 0x09 +#define CMD_TX_DISB 0x0b +#define CMD_CH_RST 0x21 +#define CMD_SRCH_MODE 0x31 +#define CMD_NOP 0x00 + +#define CMD_RESET 0x21 +#define CMD_TX_ENABLE 0x02 +#define CMD_RX_ENABLE 0x12 + +#define ST0_RXRDY 0x01 +#define ST0_TXRDY 0x02 +#define ST0_RXINTB 0x20 +#define ST0_RXINTA 0x40 +#define ST0_TXINT 0x80 + +#define ST1_IDLE 0x01 +#define ST1_ABORT 0x02 +#define ST1_CDCD 0x04 +#define ST1_CCTS 0x08 +#define ST1_SYN_FLAG 0x10 +#define ST1_CLMD 0x20 +#define ST1_TXIDLE 0x40 +#define ST1_UDRN 0x80 + +#define ST2_CRCE 0x04 +#define ST2_ONRN 0x08 +#define ST2_RBIT 0x10 +#define ST2_ABORT 0x20 +#define ST2_SHORT 0x40 +#define ST2_EOM 0x80 + +#define ST3_RX_ENA 0x01 +#define ST3_TX_ENA 0x02 +#define ST3_DCD 0x04 +#define ST3_CTS 0x08 +#define ST3_SRCH_MODE 0x10 +#define ST3_SLOOP 0x20 +#define ST3_GPI 0x80 + +#define ST4_RDNR 0x01 +#define ST4_RDCR 0x02 +#define ST4_TDNR 0x04 +#define ST4_TDCR 0x08 +#define ST4_OCLM 0x20 +#define ST4_CFT 0x40 +#define ST4_CGPI 0x80 + +#define FST_CRCEF 0x04 +#define FST_OVRNF 0x08 +#define FST_RBIF 0x10 +#define FST_ABTF 0x20 +#define FST_SHRTF 0x40 +#define FST_EOMF 0x80 + +#define IE0_RXRDY 0x01 +#define IE0_TXRDY 0x02 +#define IE0_RXINTB 0x20 +#define IE0_RXINTA 0x40 +#define IE0_TXINT 0x80 +#define IE0_UDRN 0x00008000 /* TX underrun MSCI interrupt enable */ +#define IE0_CDCD 0x00000400 /* CD level change interrupt enable */ + +#define IE1_IDLD 0x01 +#define IE1_ABTD 0x02 +#define IE1_CDCD 0x04 +#define IE1_CCTS 0x08 +#define IE1_SYNCD 0x10 +#define IE1_CLMD 0x20 +#define IE1_IDL 0x40 +#define IE1_UDRN 0x80 + +#define IE2_CRCE 0x04 +#define IE2_OVRN 0x08 +#define IE2_RBIT 0x10 +#define IE2_ABT 0x20 +#define IE2_SHRT 0x40 +#define IE2_EOM 0x80 + +#define IE4_RDNR 0x01 +#define IE4_RDCR 0x02 +#define IE4_TDNR 0x04 +#define IE4_TDCR 0x08 +#define IE4_OCLM 0x20 +#define IE4_CFT 0x40 +#define IE4_CGPI 0x80 + +#define FIE_CRCEF 0x04 +#define FIE_OVRNF 0x08 +#define FIE_RBIF 0x10 +#define FIE_ABTF 0x20 +#define FIE_SHRTF 0x40 +#define FIE_EOMF 0x80 + +#define DSR_DWE 0x01 +#define DSR_DE 0x02 +#define DSR_REF 0x04 +#define DSR_UDRF 0x04 +#define DSR_COA 0x08 +#define DSR_COF 0x10 +#define DSR_BOF 0x20 +#define DSR_EOM 0x40 +#define DSR_EOT 0x80 + +#define DIR_REF 0x04 +#define DIR_UDRF 0x04 +#define DIR_COA 0x08 +#define DIR_COF 0x10 +#define DIR_BOF 0x20 +#define DIR_EOM 0x40 +#define DIR_EOT 0x80 + +#define DIR_REFE 0x04 +#define DIR_UDRFE 0x04 +#define DIR_COAE 0x08 +#define DIR_COFE 0x10 +#define DIR_BOFE 0x20 +#define DIR_EOME 0x40 +#define DIR_EOTE 0x80 + +#define DMR_CNTE 0x02 +#define DMR_NF 0x04 +#define DMR_SEOME 0x08 +#define DMR_TMOD 0x10 + +#define DMER_DME 0x80 /* DMA Master Enable */ + +#define DCR_SW_ABT 0x01 +#define DCR_FCT_CLR 0x02 + +#define DCR_ABORT 0x01 +#define DCR_CLEAR_EOF 0x02 + +#define PCR_COTE 0x80 +#define PCR_PR0 0x01 +#define PCR_PR1 0x02 +#define PCR_PR2 0x04 +#define PCR_CCC 0x08 +#define PCR_BRC 0x10 +#define PCR_OSB 0x40 +#define PCR_BURST 0x80 + +#endif /* (__HD64572_H) */ diff -urN linux-2.4.24/drivers/net/wan/hd6457x.c linux-2.4.25/drivers/net/wan/hd6457x.c --- linux-2.4.24/drivers/net/wan/hd6457x.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hd6457x.c 2004-02-18 05:36:31.000000000 -0800 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -255,9 +254,6 @@ card_t* card = port_to_card(port); u8 stat = sca_in(msci + ST1, card); /* read MSCI ST1 status */ - /* printk(KERN_DEBUG "MSCI INT: ST1=%02X ILAR=%02X\n", - stat, sca_in(ILAR, card)); */ - /* Reset MSCI TX underrun status bit */ sca_out(stat & ST1_UDRN, msci + ST1, card); @@ -307,7 +303,7 @@ openwin(card, 0); #endif skb_put(skb, len); -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s RX(%i):", hdlc_to_name(&port->hdlc), skb->len); debug_frame(skb); #endif @@ -557,7 +553,7 @@ #endif /* We're using the following interrupts: - - TXINT (DMAC completed all transmisions, underflow or CTS change) + - TXINT (DMAC completed all transmisions, underrun or DCD change) - all DMA interrupts */ @@ -633,7 +629,7 @@ -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS static void sca_dump_rings(hdlc_device *hdlc) { port_t *port = hdlc_to_port(hdlc); @@ -648,30 +644,26 @@ openwin(card, 0); #endif - printk(KERN_ERR "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive", + printk(KERN_DEBUG "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive", sca_ina(get_dmac_rx(port) + CDAL, card), sca_ina(get_dmac_rx(port) + EDAL, card), - sca_in(DSR_RX(phy_node(port)), card), - port->rxin, + sca_in(DSR_RX(phy_node(port)), card), port->rxin, sca_in(DSR_RX(phy_node(port)), card) & DSR_DE?"":"in"); for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) - printk(" %02X", - readb(&(desc_address(port, cnt, 0)->stat))); + printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); - printk("\n" KERN_ERR "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " + printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " "last=%u %sactive", sca_ina(get_dmac_tx(port) + CDAL, card), sca_ina(get_dmac_tx(port) + EDAL, card), - sca_in(DSR_TX(phy_node(port)), card), port->txin, - port->txlast, + sca_in(DSR_TX(phy_node(port)), card), port->txin, port->txlast, sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in"); for (cnt = 0; cnt < port_to_card(port)->tx_ring_buffers; cnt++) - printk(" %02X", - readb(&(desc_address(port, cnt, 1)->stat))); + printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); printk("\n"); - printk(KERN_ERR "MSCI: MD: %02x %02x %02x, " + printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, " "ST: %02x %02x %02x %02x" #ifdef __HD64572_H " %02x" @@ -692,14 +684,14 @@ sca_in(get_msci(port) + CST1, card)); #ifdef __HD64572_H - printk(KERN_ERR "ILAR: %02x\n", sca_in(ILAR, card)); + printk(KERN_DEBUG "ILAR: %02x\n", sca_in(ILAR, card)); #endif #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) openwin(card, page); /* Restore original page */ #endif } -#endif /* CONFIG_HDLC_DEBUG_RINGS */ +#endif /* DEBUG_RINGS */ @@ -720,7 +712,7 @@ desc = desc_address(port, port->txin + 1, 1); if (readb(&desc->stat)) { /* allow 1 packet gap */ /* should never happen - previous xmit should stop queue */ -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); #endif netif_stop_queue(dev); @@ -728,7 +720,7 @@ return 1; /* request packet to be queued */ } -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_DEBUG "%s TX(%i):", hdlc_to_name(hdlc), skb->len); debug_frame(skb); #endif diff -urN linux-2.4.24/drivers/net/wan/hdlc_cisco.c linux-2.4.25/drivers/net/wan/hdlc_cisco.c --- linux-2.4.24/drivers/net/wan/hdlc_cisco.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_cisco.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include @@ -24,6 +23,7 @@ #include #include +#undef DEBUG_HARD_HEADER #define CISCO_MULTICAST 0x8F /* Cisco multicast address */ #define CISCO_UNICAST 0x0F /* Cisco unicast address */ @@ -39,7 +39,7 @@ unsigned int len) { hdlc_header *data; -#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER +#ifdef DEBUG_HARD_HEADER printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); #endif @@ -182,7 +182,7 @@ case CISCO_KEEPALIVE_REQ: hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); - if (ntohl(cisco_data->par2) == hdlc->state.cisco.txseq) { + if (ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { hdlc->state.cisco.last_poll = jiffies; if (!hdlc->state.cisco.up) { u32 sec, min, hrs, days; @@ -219,8 +219,7 @@ { hdlc_device *hdlc = (hdlc_device*)arg; - if (hdlc->state.cisco.up && - jiffies - hdlc->state.cisco.last_poll >= + if (hdlc->state.cisco.up && jiffies - hdlc->state.cisco.last_poll >= hdlc->state.cisco.settings.timeout * HZ) { hdlc->state.cisco.up = 0; printk(KERN_INFO "%s: Link down\n", hdlc_to_name(hdlc)); @@ -281,10 +280,10 @@ return 0; case IF_PROTO_CISCO: - if(!capable(CAP_NET_ADMIN)) + if (!capable(CAP_NET_ADMIN)) return -EPERM; - if(dev->flags & IFF_UP) + if (dev->flags & IFF_UP) return -EBUSY; if (copy_from_user(&new_settings, cisco_s, size)) diff -urN linux-2.4.24/drivers/net/wan/hdlc_fr.c linux-2.4.25/drivers/net/wan/hdlc_fr.c --- linux-2.4.24/drivers/net/wan/hdlc_fr.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_fr.c 2004-02-18 05:36:31.000000000 -0800 @@ -19,7 +19,6 @@ -> 1 when "PVC up" and (exist,new) = 1,0 */ -#include #include #include #include @@ -36,12 +35,95 @@ #include #include +#undef DEBUG_PKT +#undef DEBUG_ECN -__inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) +#define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ + +#define PVC_STATE_NEW 0x01 +#define PVC_STATE_ACTIVE 0x02 +#define PVC_STATE_FECN 0x08 /* FECN condition */ +#define PVC_STATE_BECN 0x10 /* BECN condition */ + + +#define FR_UI 0x03 +#define FR_PAD 0x00 + +#define NLPID_IP 0xCC +#define NLPID_IPV6 0x8E +#define NLPID_SNAP 0x80 +#define NLPID_PAD 0x00 +#define NLPID_Q933 0x08 + + +#define LMI_DLCI 0 /* LMI DLCI */ +#define LMI_PROTO 0x08 +#define LMI_CALLREF 0x00 /* Call Reference */ +#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */ +#define LMI_REPTYPE 1 /* report type */ +#define LMI_CCITT_REPTYPE 0x51 +#define LMI_ALIVE 3 /* keep alive */ +#define LMI_CCITT_ALIVE 0x53 +#define LMI_PVCSTAT 7 /* pvc status */ +#define LMI_CCITT_PVCSTAT 0x57 +#define LMI_FULLREP 0 /* full report */ +#define LMI_INTEGRITY 1 /* link integrity report */ +#define LMI_SINGLE 2 /* single pvc report */ +#define LMI_STATUS_ENQUIRY 0x75 +#define LMI_STATUS 0x7D /* reply */ + +#define LMI_REPT_LEN 1 /* report type element length */ +#define LMI_INTEG_LEN 2 /* link integrity element length */ + +#define LMI_LENGTH 13 /* standard LMI frame length */ +#define LMI_ANSI_LENGTH 14 + + +typedef struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ea1: 1; + unsigned cr: 1; + unsigned dlcih: 6; + + unsigned ea2: 1; + unsigned de: 1; + unsigned becn: 1; + unsigned fecn: 1; + unsigned dlcil: 4; +#else + unsigned dlcih: 6; + unsigned cr: 1; + unsigned ea1: 1; + + unsigned dlcil: 4; + unsigned fecn: 1; + unsigned becn: 1; + unsigned de: 1; + unsigned ea2: 1; +#endif +}__attribute__ ((packed)) fr_hdr; + + +static inline u16 q922_to_dlci(u8 *hdr) +{ + return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); +} + + + +static inline void dlci_to_q922(u8 *hdr, u16 dlci) +{ + hdr[0] = (dlci >> 2) & 0xFC; + hdr[1] = ((dlci << 4) & 0xF0) | 0x01; +} + + + +static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) { pvc_device *pvc = hdlc->state.fr.first_pvc; - while(pvc) { + while (pvc) { if (pvc->dlci == dlci) return pvc; if (pvc->dlci > dlci) @@ -53,15 +135,15 @@ } -__inline__ pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci) +static inline pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci) { pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; - while(*pvc_p) { + while (*pvc_p) { if ((*pvc_p)->dlci == dlci) return *pvc_p; if ((*pvc_p)->dlci > dlci) - break; /* the listed is sorted */ + break; /* the list is sorted */ pvc_p = &(*pvc_p)->next; } @@ -78,17 +160,17 @@ } -__inline__ int pvc_is_used(pvc_device *pvc) +static inline int pvc_is_used(pvc_device *pvc) { return pvc->main != NULL || pvc->ether != NULL; } -__inline__ void delete_unused_pvcs(hdlc_device *hdlc) +static inline void delete_unused_pvcs(hdlc_device *hdlc) { pvc_device **pvc_p = &hdlc->state.fr.first_pvc; - while(*pvc_p) { + while (*pvc_p) { if (!pvc_is_used(*pvc_p)) { pvc_device *pvc = *pvc_p; *pvc_p = pvc->next; @@ -100,7 +182,7 @@ } -__inline__ struct net_device** get_dev_p(pvc_device *pvc, int type) +static inline struct net_device** get_dev_p(pvc_device *pvc, int type) { if (type == ARPHRD_ETHER) return &pvc->ether; @@ -109,20 +191,19 @@ } -__inline__ u16 status_to_dlci(u8 *status, int *active, int *new) +static inline u16 status_to_dlci(u8 *status, int *active, int *new) { *new = (status[2] & 0x08) ? 1 : 0; *active = (status[2] & 0x02) ? 1 : 0; - return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3); + return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3); } -__inline__ void dlci_to_status(u16 dlci, u8 *status, - int active, int new) +static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new) { - status[0] = (dlci>>4) & 0x3F; - status[1] = ((dlci<<3) & 0x78) | 0x80; + status[0] = (dlci >> 4) & 0x3F; + status[1] = ((dlci << 3) & 0x78) | 0x80; status[2] = 0x80; if (new) @@ -138,7 +219,7 @@ u16 head_len; struct sk_buff *skb = *skb_p; - switch(skb->protocol) { + switch (skb->protocol) { case __constant_ntohs(ETH_P_IP): head_len = 4; skb_push(skb, head_len); @@ -260,7 +341,7 @@ } -__inline__ struct net_device_stats *pvc_get_stats(struct net_device *dev) +static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) { return (struct net_device_stats *) ((char *)dev + sizeof(struct net_device)); @@ -632,8 +713,7 @@ pvc->state.exist = 1; pvc->state.deleted = 0; if (active != pvc->state.active || - new != pvc->state.new || - !pvc->state.exist) { + new != pvc->state.new) { pvc->state.new = new; pvc->state.active = active; fr_log_dlci_active(pvc); @@ -699,7 +779,7 @@ pvc = find_pvc(hdlc, dlci); if (!pvc) { -#ifdef CONFIG_HDLC_DEBUG_PKT +#ifdef DEBUG_PKT printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", hdlc_to_name(hdlc), dlci); #endif @@ -708,7 +788,7 @@ } if (pvc->state.fecn != fh->fecn) { -#ifdef CONFIG_HDLC_DEBUG_ECN +#ifdef DEBUG_ECN printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", hdlc_to_name(pvc), dlci, fh->fecn ? "N" : "FF"); #endif @@ -716,7 +796,7 @@ } if (pvc->state.becn != fh->becn) { -#ifdef CONFIG_HDLC_DEBUG_ECN +#ifdef DEBUG_ECN printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", hdlc_to_name(pvc), dlci, fh->becn ? "N" : "FF"); #endif @@ -820,7 +900,7 @@ if (hdlc->state.fr.settings.lmi != LMI_NONE) del_timer_sync(&hdlc->state.fr.timer); - while(pvc) { /* Shutdown all PVCs for this FRAD */ + while (pvc) { /* Shutdown all PVCs for this FRAD */ if (pvc->main) dev_close(pvc->main); if (pvc->ether) @@ -941,7 +1021,7 @@ static void fr_destroy(hdlc_device *hdlc) { pvc_device *pvc = hdlc->state.fr.first_pvc; - while(pvc) { + while (pvc) { pvc_device *next = pvc->next; if (pvc->main) { unregister_netdevice(pvc->main); diff -urN linux-2.4.24/drivers/net/wan/hdlc_generic.c linux-2.4.25/drivers/net/wan/hdlc_generic.c --- linux-2.4.24/drivers/net/wan/hdlc_generic.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_generic.c 2004-02-18 05:36:31.000000000 -0800 @@ -33,7 +33,7 @@ #include -static const char* version = "HDLC support module revision 1.14"; +static const char* version = "HDLC support module revision 1.14b"; static int hdlc_change_mtu(struct net_device *dev, int new_mtu) @@ -145,7 +145,7 @@ hdlc->proto_detach = NULL; result = dev_alloc_name(dev, "hdlc%d"); - if (result<0) + if (result < 0) return result; result = register_netdev(dev); @@ -177,8 +177,7 @@ EXPORT_SYMBOL(register_hdlc_device); EXPORT_SYMBOL(unregister_hdlc_device); -struct packet_type hdlc_packet_type= -{ +static struct packet_type hdlc_packet_type = { __constant_htons(ETH_P_HDLC), NULL, hdlc_rcv, diff -urN linux-2.4.24/drivers/net/wan/hdlc_ppp.c linux-2.4.25/drivers/net/wan/hdlc_ppp.c --- linux-2.4.24/drivers/net/wan/hdlc_ppp.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_ppp.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include diff -urN linux-2.4.24/drivers/net/wan/hdlc_raw.c linux-2.4.25/drivers/net/wan/hdlc_raw.c --- linux-2.4.24/drivers/net/wan/hdlc_raw.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_raw.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include diff -urN linux-2.4.24/drivers/net/wan/hdlc_raw_eth.c linux-2.4.25/drivers/net/wan/hdlc_raw_eth.c --- linux-2.4.24/drivers/net/wan/hdlc_raw_eth.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_raw_eth.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include diff -urN linux-2.4.24/drivers/net/wan/hdlc_x25.c linux-2.4.25/drivers/net/wan/hdlc_x25.c --- linux-2.4.24/drivers/net/wan/hdlc_x25.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/hdlc_x25.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,7 +9,6 @@ * as published by the Free Software Foundation. */ -#include #include #include #include diff -urN linux-2.4.24/drivers/net/wan/n2.c linux-2.4.25/drivers/net/wan/n2.c --- linux-2.4.24/drivers/net/wan/n2.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/n2.c 2004-02-18 05:36:31.000000000 -0800 @@ -16,7 +16,6 @@ * SDL Inc. PPP/HDLC/CISCO driver */ -#include #include #include #include @@ -36,6 +35,9 @@ static const char* version = "SDL RISCom/N2 driver version: 1.14"; static const char* devname = "RISCom/N2"; +#undef DEBUG_PKT +#define DEBUG_RINGS + #define USE_WINDOWSIZE 16384 #define USE_BUS16BITS 1 #define CLOCK_BASE 9830400 /* 9.8304 MHz */ @@ -257,7 +259,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); port_t *port = hdlc_to_port(hdlc); -#ifdef CONFIG_HDLC_DEBUG_RINGS +#ifdef DEBUG_RINGS if (cmd == SIOCDEVPRIVATE) { sca_dump_rings(hdlc); return 0; @@ -415,7 +417,7 @@ card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) * (card->tx_ring_buffers + card->rx_ring_buffers); - printk(KERN_DEBUG "n2: RISCom/N2 %u KB RAM, IRQ%u, " + printk(KERN_INFO "n2: RISCom/N2 %u KB RAM, IRQ%u, " "using %u TX + %u RX packets rings\n", card->ram_size / 1024, card->irq, card->tx_ring_buffers, card->rx_ring_buffers); @@ -446,7 +448,7 @@ spin_lock_init(&port->lock); dev->irq = irq; dev->mem_start = winbase; - dev->mem_end = winbase + USE_WINDOWSIZE-1; + dev->mem_end = winbase + USE_WINDOWSIZE - 1; dev->tx_queue_len = 50; dev->do_ioctl = n2_ioctl; dev->open = n2_open; diff -urN linux-2.4.24/drivers/net/wan/pc300.h linux-2.4.25/drivers/net/wan/pc300.h --- linux-2.4.24/drivers/net/wan/pc300.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/pc300.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,424 @@ +/* + * pc300.h Cyclades-PC300(tm) Kernel API Definitions. + * + * Author: Ivan Passos + * + * Copyright: (c) 1999-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef _PC300_H +#define _PC300_H + +#ifndef __HDLC_H +#include +#endif + +#ifndef _HD64572_H +#include "hd64572.h" +#endif +#ifndef _FALC_LH_H +#include "pc300_falc-lh.h" +#endif + +#ifndef CY_TYPES +#define CY_TYPES +#if defined(__alpha__) +typedef unsigned long ucdouble; /* 64 bits, unsigned */ +typedef unsigned int uclong; /* 32 bits, unsigned */ +#else +typedef unsigned long uclong; /* 32 bits, unsigned */ +#endif +typedef unsigned short ucshort; /* 16 bits, unsigned */ +typedef unsigned char ucchar; /* 8 bits, unsigned */ +#endif /* CY_TYPES */ + +#define PC300_PROTO_MLPPP 1 + +#define PC300_KERNEL "2.4.x" /* Kernel supported by this driver */ + +#define PC300_DEVNAME "hdlc" /* Dev. name base (for hdlc0, hdlc1, etc.) */ +#define PC300_MAXINDEX 100 /* Max dev. name index (the '0' in hdlc0) */ + +#define PC300_MAXCARDS 4 /* Max number of cards per system */ +#define PC300_MAXCHAN 2 /* Number of channels per card */ + +#define PC300_PLX_WIN 0x80 /* PLX control window size (128b) */ +#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */ +#define PC300_SCASIZE 0x400 /* SCA window size (1Kb) */ +#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */ + +#define PC300_OSC_CLOCK 24576000 +#define PC300_PCI_CLOCK 33000000 + +#define BD_DEF_LEN 0x0800 /* DMA buffer length (2KB) */ +#define DMA_TX_MEMSZ 0x8000 /* Total DMA Tx memory size (32KB/ch) */ +#define DMA_RX_MEMSZ 0x10000 /* Total DMA Rx memory size (64KB/ch) */ + +#define N_DMA_TX_BUF (DMA_TX_MEMSZ / BD_DEF_LEN) /* DMA Tx buffers */ +#define N_DMA_RX_BUF (DMA_RX_MEMSZ / BD_DEF_LEN) /* DMA Rx buffers */ + +/* DMA Buffer Offsets */ +#define DMA_TX_BASE ((N_DMA_TX_BUF + N_DMA_RX_BUF) * \ + PC300_MAXCHAN * sizeof(pcsca_bd_t)) +#define DMA_RX_BASE (DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ) + +/* DMA Descriptor Offsets */ +#define DMA_TX_BD_BASE 0x0000 +#define DMA_RX_BD_BASE (DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \ + BD_DEF_LEN) * sizeof(pcsca_bd_t))) + +/* DMA Descriptor Macros */ +#define TX_BD_ADDR(chan, n) (DMA_TX_BD_BASE + \ + ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t)) +#define RX_BD_ADDR(chan, n) (DMA_RX_BD_BASE + \ + ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t)) + +/* Macro to access the FALC registers (TE only) */ +#define F_REG(reg, chan) (0x200*(chan) + ((reg)<<2)) + +/*************************************** + * Memory access functions/macros * + * (required to support Alpha systems) * + ***************************************/ +#ifdef __KERNEL__ +#define cpc_writeb(port,val) {writeb((ucchar)(val),(ulong)(port)); mb();} +#define cpc_writew(port,val) {writew((ushort)(val),(ulong)(port)); mb();} +#define cpc_writel(port,val) {writel((uclong)(val),(ulong)(port)); mb();} + +#define cpc_readb(port) readb(port) +#define cpc_readw(port) readw(port) +#define cpc_readl(port) readl(port) + +#else /* __KERNEL__ */ +#define cpc_writeb(port,val) (*(volatile ucchar *)(port) = (ucchar)(val)) +#define cpc_writew(port,val) (*(volatile ucshort *)(port) = (ucshort)(val)) +#define cpc_writel(port,val) (*(volatile uclong *)(port) = (uclong)(val)) + +#define cpc_readb(port) (*(volatile ucchar *)(port)) +#define cpc_readw(port) (*(volatile ucshort *)(port)) +#define cpc_readl(port) (*(volatile uclong *)(port)) + +#endif /* __KERNEL__ */ + +/****** Data Structures *****************************************************/ + +/* + * RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime + * registers. This structure can be used to access the 9050 registers + * (memory mapped). + */ +struct RUNTIME_9050 { + uclong loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ + uclong loc_rom_range; /* 10h : Local ROM Range */ + uclong loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ + uclong loc_rom_base; /* 24h : Local ROM Base */ + uclong loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ + uclong rom_bus_descr; /* 38h : ROM Bus Descriptor */ + uclong cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ + uclong intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ + uclong init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ +}; + +#define PLX_9050_LINT1_ENABLE 0x01 +#define PLX_9050_LINT1_POL 0x02 +#define PLX_9050_LINT1_STATUS 0x04 +#define PLX_9050_LINT2_ENABLE 0x08 +#define PLX_9050_LINT2_POL 0x10 +#define PLX_9050_LINT2_STATUS 0x20 +#define PLX_9050_INTR_ENABLE 0x40 +#define PLX_9050_SW_INTR 0x80 + +/* Masks to access the init_ctrl PLX register */ +#define PC300_CLKSEL_MASK (0x00000004UL) +#define PC300_CHMEDIA_MASK(chan) (0x00000020UL<<(chan*3)) +#define PC300_CTYPE_MASK (0x00000800UL) + +/* CPLD Registers (base addr = falcbase, TE only) */ +/* CPLD v. 0 */ +#define CPLD_REG1 0x140 /* Chip resets, DCD/CTS status */ +#define CPLD_REG2 0x144 /* Clock enable , LED control */ +/* CPLD v. 2 or higher */ +#define CPLD_V2_REG1 0x100 /* Chip resets, DCD/CTS status */ +#define CPLD_V2_REG2 0x104 /* Clock enable , LED control */ +#define CPLD_ID_REG 0x108 /* CPLD version */ + +/* CPLD Register bit description: for the FALC bits, they should always be + set based on the channel (use (bit<<(2*ch)) to access the correct bit for + that channel) */ +#define CPLD_REG1_FALC_RESET 0x01 +#define CPLD_REG1_SCA_RESET 0x02 +#define CPLD_REG1_GLOBAL_CLK 0x08 +#define CPLD_REG1_FALC_DCD 0x10 +#define CPLD_REG1_FALC_CTS 0x20 + +#define CPLD_REG2_FALC_TX_CLK 0x01 +#define CPLD_REG2_FALC_RX_CLK 0x02 +#define CPLD_REG2_FALC_LED1 0x10 +#define CPLD_REG2_FALC_LED2 0x20 + +/* Structure with FALC-related fields (TE only) */ +#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */ + +typedef struct falc { + ucchar sync; /* If true FALC is synchronized */ + ucchar active; /* if TRUE then already active */ + ucchar loop_active; /* if TRUE a line loopback UP was received */ + ucchar loop_gen; /* if TRUE a line loopback UP was issued */ + + ucchar num_channels; + ucchar offset; /* 1 for T1, 0 for E1 */ + ucchar full_bandwidth; + + ucchar xmb_cause; + ucchar multiframe_mode; + + /* Statistics */ + ucshort pden; /* Pulse Density violation count */ + ucshort los; /* Loss of Signal count */ + ucshort losr; /* Loss of Signal recovery count */ + ucshort lfa; /* Loss of frame alignment count */ + ucshort farec; /* Frame Alignment Recovery count */ + ucshort lmfa; /* Loss of multiframe alignment count */ + ucshort ais; /* Remote Alarm indication Signal count */ + ucshort sec; /* One-second timer */ + ucshort es; /* Errored second */ + ucshort rai; /* remote alarm received */ + ucshort bec; + ucshort fec; + ucshort cvc; + ucshort cec; + ucshort ebc; + + /* Status */ + ucchar red_alarm; + ucchar blue_alarm; + ucchar loss_fa; + ucchar yellow_alarm; + ucchar loss_mfa; + ucchar prbs; +} falc_t; + +typedef struct falc_status { + ucchar sync; /* If true FALC is synchronized */ + ucchar red_alarm; + ucchar blue_alarm; + ucchar loss_fa; + ucchar yellow_alarm; + ucchar loss_mfa; + ucchar prbs; +} falc_status_t; + +typedef struct rsv_x21_status { + ucchar dcd; + ucchar dsr; + ucchar cts; + ucchar rts; + ucchar dtr; +} rsv_x21_status_t; + +typedef struct pc300stats { + int hw_type; + uclong line_on; + uclong line_off; + struct net_device_stats gen_stats; + falc_t te_stats; +} pc300stats_t; + +typedef struct pc300status { + int hw_type; + rsv_x21_status_t gen_status; + falc_status_t te_status; +} pc300status_t; + +typedef struct pc300loopback { + char loop_type; + char loop_on; +} pc300loopback_t; + +typedef struct pc300patterntst { + char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */ + ucshort num_errors; +} pc300patterntst_t; + +typedef struct pc300dev { + void *if_ptr; /* General purpose pointer */ + struct pc300ch *chan; + ucchar trace_on; + uclong line_on; /* DCD(X.21, RSV) / sync(TE) change counters */ + uclong line_off; +#ifdef __KERNEL__ + char name[16]; + hdlc_device *hdlc; + + void *private; + struct sk_buff *tx_skb; + union { /* This union has all the protocol-specific structures */ + struct ppp_device pppdev; + }ifu; +#ifdef CONFIG_PC300_MLPPP + void *cpc_tty; /* information to PC300 TTY driver */ +#endif +#endif /* __KERNEL__ */ +}pc300dev_t; + +typedef struct pc300hw { + int type; /* RSV, X21, etc. */ + int bus; /* Bus (PCI, PMC, etc.) */ + int nchan; /* number of channels */ + int irq; /* interrupt request level */ + uclong clock; /* Board clock */ + ucchar cpld_id; /* CPLD ID (TE only) */ + ucshort cpld_reg1; /* CPLD reg 1 (TE only) */ + ucshort cpld_reg2; /* CPLD reg 2 (TE only) */ + ucshort gpioc_reg; /* PLX GPIOC reg */ + ucshort intctl_reg; /* PLX Int Ctrl/Status reg */ + uclong iophys; /* PLX registers I/O base */ + uclong iosize; /* PLX registers I/O size */ + uclong plxphys; /* PLX registers MMIO base (physical) */ + uclong plxbase; /* PLX registers MMIO base (virtual) */ + uclong plxsize; /* PLX registers MMIO size */ + uclong scaphys; /* SCA registers MMIO base (physical) */ + uclong scabase; /* SCA registers MMIO base (virtual) */ + uclong scasize; /* SCA registers MMIO size */ + uclong ramphys; /* On-board RAM MMIO base (physical) */ + uclong rambase; /* On-board RAM MMIO base (virtual) */ + uclong alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */ + uclong ramsize; /* On-board RAM MMIO size */ + uclong falcphys; /* FALC registers MMIO base (physical) */ + uclong falcbase; /* FALC registers MMIO base (virtual) */ + uclong falcsize; /* FALC registers MMIO size */ +} pc300hw_t; + +typedef struct pc300chconf { + sync_serial_settings phys_settings; /* Clock type/rate (in bps), + loopback mode */ + raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */ + uclong media; /* HW media (RS232, V.35, etc.) */ + uclong proto; /* Protocol (PPP, X.25, etc.) */ + ucchar monitor; /* Monitor mode (0 = off, !0 = on) */ + + /* TE-specific parameters */ + ucchar lcode; /* Line Code (AMI, B8ZS, etc.) */ + ucchar fr_mode; /* Frame Mode (ESF, D4, etc.) */ + ucchar lbo; /* Line Build Out */ + ucchar rx_sens; /* Rx Sensitivity (long- or short-haul) */ + uclong tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */ +} pc300chconf_t; + +typedef struct pc300ch { + struct pc300 *card; + int channel; + pc300dev_t d; + pc300chconf_t conf; + ucchar tx_first_bd; /* First TX DMA block descr. w/ data */ + ucchar tx_next_bd; /* Next free TX DMA block descriptor */ + ucchar rx_first_bd; /* First free RX DMA block descriptor */ + ucchar rx_last_bd; /* Last free RX DMA block descriptor */ + ucchar nfree_tx_bd; /* Number of free TX DMA block descriptors */ + falc_t falc; /* FALC structure (TE only) */ +} pc300ch_t; + +typedef struct pc300 { + pc300hw_t hw; /* hardware config. */ + pc300ch_t chan[PC300_MAXCHAN]; +#ifdef __KERNEL__ + spinlock_t card_lock; +#endif /* __KERNEL__ */ +} pc300_t; + +typedef struct pc300conf { + pc300hw_t hw; + pc300chconf_t conf; +} pc300conf_t; + +/* DEV ioctl() commands */ +#define N_SPPP_IOCTLS 2 + +enum pc300_ioctl_cmds { + SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS), + SIOCGPC300CONF, + SIOCSPC300CONF, + SIOCGPC300STATUS, + SIOCGPC300FALCSTATUS, + SIOCGPC300UTILSTATS, + SIOCGPC300UTILSTATUS, + SIOCSPC300TRACE, + SIOCSPC300LOOPBACK, + SIOCSPC300PATTERNTEST, +}; + +/* Loopback types - PC300/TE boards */ +enum pc300_loopback_cmds { + PC300LOCLOOP = 1, + PC300REMLOOP, + PC300PAYLOADLOOP, + PC300GENLOOPUP, + PC300GENLOOPDOWN, +}; + +/* Control Constant Definitions */ +#define PC300_RSV 0x01 +#define PC300_X21 0x02 +#define PC300_TE 0x03 + +#define PC300_PCI 0x00 +#define PC300_PMC 0x01 + +#define PC300_LC_AMI 0x01 +#define PC300_LC_B8ZS 0x02 +#define PC300_LC_NRZ 0x03 +#define PC300_LC_HDB3 0x04 + +/* Framing (T1) */ +#define PC300_FR_ESF 0x01 +#define PC300_FR_D4 0x02 +#define PC300_FR_ESF_JAPAN 0x03 + +/* Framing (E1) */ +#define PC300_FR_MF_CRC4 0x04 +#define PC300_FR_MF_NON_CRC4 0x05 +#define PC300_FR_UNFRAMED 0x06 + +#define PC300_LBO_0_DB 0x00 +#define PC300_LBO_7_5_DB 0x01 +#define PC300_LBO_15_DB 0x02 +#define PC300_LBO_22_5_DB 0x03 + +#define PC300_RX_SENS_SH 0x01 +#define PC300_RX_SENS_LH 0x02 + +#define PC300_TX_TIMEOUT (2*HZ) +#define PC300_TX_QUEUE_LEN 100 +#define PC300_DEF_MTU 1600 + +#ifdef __KERNEL__ +/* Function Prototypes */ +int dma_buf_write(pc300_t *, int, ucchar *, int); +int dma_buf_read(pc300_t *, int, struct sk_buff *); +void tx_dma_start(pc300_t *, int); +void rx_dma_start(pc300_t *, int); +void tx_dma_stop(pc300_t *, int); +void rx_dma_stop(pc300_t *, int); +int cpc_queue_xmit(struct sk_buff *, struct net_device *); +void cpc_net_rx(hdlc_device *); +void cpc_sca_status(pc300_t *, int); +int cpc_change_mtu(struct net_device *, int); +int cpc_ioctl(struct net_device *, struct ifreq *, int); +int ch_config(pc300dev_t *); +int rx_config(pc300dev_t *); +int tx_config(pc300dev_t *); +void cpc_opench(pc300dev_t *); +void cpc_closech(pc300dev_t *); +int cpc_open(struct net_device *dev); +int cpc_close(struct net_device *dev); +int cpc_set_media(hdlc_device *, int); +#endif /* __KERNEL__ */ + +#endif /* _PC300_H */ + diff -urN linux-2.4.24/drivers/net/wan/pc300_drv.c linux-2.4.25/drivers/net/wan/pc300_drv.c --- linux-2.4.24/drivers/net/wan/pc300_drv.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/pc300_drv.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,3486 @@ +#define USE_PCI_CLOCK +static char rcsid[] = +// Important note: +// This string must have this exact format, including the space on its end +"Revision: 4.1.0 Date: 2003/11/19 "; + +/* + * pc300.c Cyclades-PC300(tm) Driver. + * + * Author: Ivan Passos + * Maintainer: PC300 Maintainer + * + * Copyright: (c) 1999-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pc300.h" + +#define CPC_LOCK(card,flags) \ + do { \ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_UNLOCK(card,flags) \ + do { \ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +#undef PC300_DEBUG_PCI +#undef PC300_DEBUG_INTR +#undef PC300_DEBUG_TX +#undef PC300_DEBUG_RX +#undef PC300_DEBUG_OTHER + +static struct pci_device_id cpc_pci_dev_id[] __devinitdata = { + /* PC300/RSV or PC300/X21, 2 chan */ + {0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300}, + /* PC300/RSV or PC300/X21, 1 chan */ + {0x120e, 0x301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x301}, + /* PC300/TE, 2 chan */ + {0x120e, 0x310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x310}, + /* PC300/TE, 1 chan */ + {0x120e, 0x311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x311}, + /* PC300/TE-M, 2 chan */ + {0x120e, 0x320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x320}, + /* PC300/TE-M, 1 chan */ + {0x120e, 0x321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x321}, + /* End of table */ + {0,}, +}; +MODULE_DEVICE_TABLE(pci, cpc_pci_dev_id); + +#ifndef cpc_min +#define cpc_min(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef cpc_max +#define cpc_max(a,b) (((a)>(b))?(a):(b)) +#endif + +/* prototypes */ +static void tx_dma_buf_pt_init(pc300_t *, int); +static void tx_dma_buf_init(pc300_t *, int); +static void rx_dma_buf_pt_init(pc300_t *, int); +static void rx_dma_buf_init(pc300_t *, int); +static void tx_dma_buf_check(pc300_t *, int); +static void rx_dma_buf_check(pc300_t *, int); +static void cpc_intr(int, void *, struct pt_regs *); +static struct net_device_stats *cpc_get_stats(struct net_device *); +static int clock_rate_calc(uclong, uclong, int *); +static uclong detect_ram(pc300_t *); +static void plx_init(pc300_t *); +static void cpc_trace(struct net_device *, struct sk_buff *, char); +static int cpc_attach(hdlc_device *, unsigned short, unsigned short); + +#ifdef CONFIG_PC300_MLPPP +void cpc_tty_init(pc300dev_t * dev); +void cpc_tty_unregister_service(pc300dev_t * pc300dev); +void cpc_tty_receive(pc300dev_t * pc300dev); +void cpc_tty_trigger_poll(pc300dev_t * pc300dev); +void cpc_tty_reset_var(void); +#endif + +/************************/ +/*** DMA Routines ***/ +/************************/ +static void tx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (uclong) (DMA_TX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (uclong) (DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void tx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, DST_OSB); + } + tx_dma_buf_pt_init(card, ch); +} + +static void rx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (uclong) (DMA_RX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (uclong) (DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void rx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, 0); + } + rx_dma_buf_pt_init(card, ch); +} + +static void tx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t *ptdescr; + int i; + ucshort first_bd = card->chan[ch].tx_first_bd; + ucshort next_bd = card->chan[ch].tx_next_bd; + + printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + for (i = first_bd, + ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, first_bd)); + i != ((next_bd + 1) & (N_DMA_TX_BUF - 1)); + i = (i + 1) & (N_DMA_TX_BUF - 1), + ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, i))) { + printk("\n CH%d TX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d", + ch, i, (uclong) cpc_readl(&ptdescr->next), + (uclong) cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +#ifdef PC300_DEBUG_OTHER +/* Show all TX buffer descriptors */ +static void tx1_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t *ptdescr; + int i; + ucshort first_bd = card->chan[ch].tx_first_bd; + ucshort next_bd = card->chan[ch].tx_next_bd; + uclong scabase = card->hw.scabase; + + printk ("\nnfree_tx_bd = %d \n", card->chan[ch].nfree_tx_bd); + printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + printk("TX_CDA=0x%08lx, TX_EDA=0x%08lx\n", + (uclong) cpc_readl(scabase + DTX_REG(CDAL, ch)), + (uclong) cpc_readl(scabase + DTX_REG(EDAL, ch))); + for (i = 0; i < N_DMA_TX_BUF; i++) { + ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, i)); + printk("\n CH%d TX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d", + ch, i, (uclong) cpc_readl(&ptdescr->next), + (uclong) cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} +#endif + +static void rx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t *ptdescr; + int i; + ucshort first_bd = card->chan[ch].rx_first_bd; + ucshort last_bd = card->chan[ch].rx_last_bd; + int ch_factor; + + ch_factor = ch * N_DMA_RX_BUF; + printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd); + for (i = 0, ptdescr = (pcsca_bd_t *) (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + i < N_DMA_RX_BUF; i++, ptdescr++) { + if (cpc_readb(&ptdescr->status) & DST_OSB) + printk ("\n CH%d RX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d", + ch, i, (uclong) cpc_readl(&ptdescr->next), + (uclong) cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), + cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +int dma_get_rx_frame_size(pc300_t * card, int ch) +{ + volatile pcsca_bd_t *ptdescr; + ucshort first_bd = card->chan[ch].rx_first_bd; + int rcvd = 0; + volatile ucchar status; + + ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rcvd += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { + /* Return the size of a good frame or incomplete bad frame + * (dma_buf_read will clean the buffer descriptors in this case). */ + return (rcvd); + } + ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next)); + } + return (-1); +} + +/* + * dma_buf_write: writes a frame to the Tx DMA buffers + * NOTE: this function writes one frame at a time. + */ +int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len) +{ + int i, nchar; + volatile pcsca_bd_t *ptdescr; + int tosend = len; + ucchar nbuf = ((len - 1) / BD_DEF_LEN) + 1; + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return -ENOMEM; + } + + for (i = 0; i < nbuf; i++) { + ptdescr = (pcsca_bd_t *) (card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = cpc_min(BD_DEF_LEN, tosend); + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((void *)(card->hw.rambase + cpc_readl(&ptdescr->ptbuf)), + &ptdata[len - tosend], nchar); + cpc_writew(&ptdescr->len, nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + } else { + return -ENOMEM; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + /* If it gets to here, it means we have sent the whole frame */ + return 0; +} + +/* + * dma_buf_read: reads a frame from the Rx DMA buffers + * NOTE: this function reads one frame at a time. + */ +int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) +{ + int nchar; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + volatile pcsca_bd_t *ptdescr; + int rcvd = 0; + volatile ucchar status; + + ptdescr = (pcsca_bd_t *) (card->hw.rambase + + RX_BD_ADDR(ch, chan->rx_first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + nchar = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) + || (nchar > BD_DEF_LEN)) { + + if (nchar > BD_DEF_LEN) + status |= DST_RBIT; + rcvd = -status; + /* Discard remaining descriptors used by the bad frame */ + while (chan->rx_first_bd != chan->rx_last_bd) { + cpc_writeb(&ptdescr->status, 0); + chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1); + if (status & DST_EOM) + break; + ptdescr = (pcsca_bd_t *) (card->hw.rambase + + cpc_readl(&ptdescr->next)); + status = cpc_readb(&ptdescr->status); + } + break; + } + if (nchar != 0) { + if (skb) { + memcpy_fromio(skb_put(skb, nchar), + (void *)(card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar); + } + rcvd += nchar; + } + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1); + + if (status & DST_EOM) + break; + + ptdescr = (pcsca_bd_t *) (card->hw.rambase + cpc_readl(&ptdescr->next)); + } + + if (rcvd != 0) { + /* Update pointer */ + chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1); + /* Update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + } + return (rcvd); +} + +void tx_dma_stop(pc300_t * card, int ch) +{ + uclong scabase = card->hw.scabase; + ucchar drr_ena_bit = 1 << (5 + 2 * ch); + ucchar drr_rst_bit = 1 << (1 + 2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +void rx_dma_stop(pc300_t * card, int ch) +{ + uclong scabase = card->hw.scabase; + ucchar drr_ena_bit = 1 << (4 + 2 * ch); + ucchar drr_rst_bit = 1 << (2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +void rx_dma_start(pc300_t * card, int ch) +{ + uclong scabase = card->hw.scabase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + + /* Start DMA */ + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + if (cpc_readl(scabase + DRX_REG(CDAL,ch)) != + RX_BD_ADDR(ch, chan->rx_first_bd)) { + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + } + cpc_writel(scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN); + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + if (!(cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + } +} + +/*************************/ +/*** FALC Routines ***/ +/*************************/ +void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd) +{ + uclong falcbase = card->hw.falcbase; + unsigned long i = 0; + + while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) { + if (i++ >= PC300_FALC_MAXLOOP) { + printk("%s: FALC command locked(cmd=0x%x).\n", + card->chan[ch].d.name, cmd); + break; + } + } + cpc_writeb(falcbase + F_REG(CMDR, ch), cmd); +} + +void falc_intr_enable(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + /* Interrupt pins are open-drain */ + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0); + /* Conters updated each second */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM); + /* Enable SEC and ES interrupts */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES)); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & + ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP)); + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS)); + if (pfalc->multiframe_mode) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_T400MS | IMR2_MFAR)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) | + IMR2_T400MS | IMR2_MFAR); + } + } + } +} + +void falc_open_timeslot(pc300_t * card, int ch, int timeslot) +{ + uclong falcbase = card->hw.falcbase; + ucchar tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & + ~(0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); +} + +void falc_close_timeslot(pc300_t * card, int ch, int timeslot) +{ + uclong falcbase = card->hw.falcbase; + ucchar tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | + (0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); +} + +void falc_close_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + uclong falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR1, ch), 0); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0); + cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0); + } +} + +void falc_open_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + uclong falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff); + } else { + /* Timeslot 0 is never enabled */ + cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f); + } + cpc_writeb(falcbase + F_REG(ICB2, ch), 0); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff); + } else { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80); + } +} + +void falc_init_timeslot(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + int tslot; + + for (tslot = 0; tslot < pfalc->num_channels; tslot++) { + if (conf->tslot_bitmap & (1 << tslot)) { + // Channel enabled + falc_open_timeslot(card, ch, tslot + 1); + } else { + // Channel disabled + falc_close_timeslot(card, ch, tslot + 1); + } + } +} + +void falc_enable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->full_bandwidth) { + falc_open_all_timeslots(card, ch); + } else { + falc_init_timeslot(card, ch); + } + // CTS/DCD ON + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +void falc_disable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->loop_active != 2) { + falc_close_all_timeslots(card, ch); + } + // CTS/DCD OFF + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +void falc_init_t1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to T1 mode (PCM 24) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); + + /* Wait 20 us for setup */ + udelay(20); + + /* Transmit Buffer Size (1 frame) */ + cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); + } + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + /* Clear Channel register to ON for all channels */ + cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff); + break; + + case PC300_LC_B8ZS: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00); + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + switch (conf->fr_mode) { + case PC300_FR_ESF: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | + FMR1_CRC | FMR1_EDL); + cpc_writeb(falcbase + F_REG(XDL1, ch), 0); + cpc_writeb(falcbase + F_REG(XDL2, ch), 0); + cpc_writeb(falcbase + F_REG(XDL3, ch), 0); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP); + break; + + case PC300_FR_D4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & + ~(FMR4_FM1 | FMR4_FM0)); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP); + break; + } + + /* Enable Automatic Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Channel translation mode 1 : one to one */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM); + + /* No signaling */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM); + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & + ~(FMR5_EIBR | FMR5_SRS)); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + + switch (conf->lbo) { + /* Provides proper Line Build Out */ + case PC300_LBO_0_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_7_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_15_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_22_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + } + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + if (conf->fr_mode == PC300_FR_ESF_JAPAN) { + cpc_writeb(falcbase + F_REG(RC1, ch), + cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80); + } + + falc_close_all_timeslots(card, ch); +} + +void falc_init_e1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to E1 mode (PCM 30) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + } + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM); + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + break; + + case PC300_LC_HDB3: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00); + + switch (conf->fr_mode) { + case PC300_FR_MF_CRC4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0); + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW); + + /* MultiFrame Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS); + + /* Automatic Loss of Multiframe > 914 CRC errors */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF); + + /* S1 and SI1/SI2 spare Bits set to 1 */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XS13 | XSP_XS15); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_MF_NON_CRC4: + case PC300_FR_D4: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_UNFRAMED: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_TT0); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & + ~(XSW_XTM|XSW_XY0|XSW_XY1|XSW_XY2|XSW_XY3|XSW_XY4)); + cpc_writeb(falcbase + F_REG(TSWM, ch), 0xff); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | + (FMR2_RTM | FMR2_DAIS)); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_AXRA); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_AFR); + pfalc->sync = 1; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + break; + } + + /* No signaling */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + falc_close_all_timeslots(card, ch); +} + +void falc_init_hdlc(pc300_t * card, int ch) +{ + uclong falcbase = card->hw.falcbase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + /* Enable transparent data transfer */ + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(MODE, ch), 0); + } else { + cpc_writeb(falcbase + F_REG(MODE, ch), + cpc_readb(falcbase + F_REG(MODE, ch)) | + (MODE_HRAC | MODE_MDS2)); + cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff); + } + + /* Tx/Rx reset */ + falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES); + + /* Enable interrupt sources */ + falc_intr_enable(card, ch); +} + +void te_config(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucchar dummy; + unsigned long flags; + + memset(pfalc, 0, sizeof(falc_t)); + switch (conf->media) { + case IF_IFACE_T1: + pfalc->num_channels = NUM_OF_T1_CHANNELS; + pfalc->offset = 1; + break; + case IF_IFACE_E1: + pfalc->num_channels = NUM_OF_E1_CHANNELS; + pfalc->offset = 0; + break; + } + if (conf->tslot_bitmap == 0xffffffffUL) + pfalc->full_bandwidth = 1; + else + pfalc->full_bandwidth = 0; + + CPC_LOCK(card, flags); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + + if (conf->media == IF_IFACE_T1) { + falc_init_t1(card, ch); + } else { + falc_init_e1(card, ch); + } + falc_init_hdlc(card, ch); + if (conf->rx_sens == PC300_RX_SENS_SH) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON); + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON); + } + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2 * ch))); + + /* Clear all interrupt registers */ + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) + + cpc_readb(falcbase + F_REG(FISR1, ch)) + + cpc_readb(falcbase + F_REG(FISR2, ch)) + + cpc_readb(falcbase + F_REG(FISR3, ch)); + CPC_UNLOCK(card, flags); +} + +void falc_check_status(pc300_t * card, int ch, unsigned char frs0) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + /* Verify LOS */ + if (frs0 & FRS0_LOS) { + if (!pfalc->red_alarm) { + pfalc->red_alarm = 1; + pfalc->los++; + if (!pfalc->blue_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere + * with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->red_alarm) { + pfalc->red_alarm = 0; + pfalc->losr++; + } + } + + if (conf->fr_mode != PC300_FR_UNFRAMED) { + /* Verify AIS alarm */ + if (frs0 & FRS0_AIS) { + if (!pfalc->blue_alarm) { + pfalc->blue_alarm = 1; + pfalc->ais++; + // EVENT_AIS + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_AIS + } + } else { + pfalc->blue_alarm = 0; + } + + /* Verify LFA */ + if (frs0 & FRS0_LFA) { + if (!pfalc->loss_fa) { + pfalc->loss_fa = 1; + pfalc->lfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->loss_fa) { + pfalc->loss_fa = 0; + pfalc->farec++; + } + } + + /* Verify LMFA */ + if (pfalc->multiframe_mode && (frs0 & FRS0_LMFA)) { + /* D4 or CRC4 frame mode */ + if (!pfalc->loss_mfa) { + pfalc->loss_mfa = 1; + pfalc->lmfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm && + !pfalc->loss_fa) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + pfalc->loss_mfa = 0; + } + + /* Verify Remote Alarm */ + if (frs0 & FRS0_RRA) { + if (!pfalc->yellow_alarm) { + pfalc->yellow_alarm = 1; + pfalc->rai++; + if (pfalc->sync) { + // EVENT_RAI + falc_disable_comm(card, ch); + // EVENT_RAI + } + } + } else { + pfalc->yellow_alarm = 0; + } + } /* if !PC300_UNFRAMED */ + + if (pfalc->red_alarm || pfalc->loss_fa || + pfalc->loss_mfa || pfalc->blue_alarm) { + if (pfalc->sync) { + pfalc->sync = 0; + chan->d.line_off++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } else { + if (!pfalc->sync) { + pfalc->sync = 1; + chan->d.line_on++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } + + if (pfalc->sync && !pfalc->yellow_alarm) { + if (!pfalc->active) { + // EVENT_FALC_NORMAL + if (pfalc->loop_active) { + return; + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN); + } + falc_enable_comm(card, ch); + // EVENT_FALC_NORMAL + pfalc->active = 1; + } + } else { + if (pfalc->active) { + pfalc->active = 0; + } + } +} + +void falc_update_stats(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucshort counter; + + counter = cpc_readb(falcbase + F_REG(FECL, ch)); + counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8; + pfalc->fec += counter; + + counter = cpc_readb(falcbase + F_REG(CVCL, ch)); + counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8; + pfalc->cvc += counter; + + counter = cpc_readb(falcbase + F_REG(CECL, ch)); + counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8; + pfalc->cec += counter; + + counter = cpc_readb(falcbase + F_REG(EBCL, ch)); + counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8; + pfalc->ebc += counter; + + if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) { + mdelay(10); + counter = cpc_readb(falcbase + F_REG(BECL, ch)); + counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8; + pfalc->bec += counter; + + if (((conf->media == IF_IFACE_T1) && + (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) && + (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) + || + ((conf->media == IF_IFACE_E1) && + (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) { + pfalc->prbs = 2; + } else { + pfalc->prbs = 1; + } + } +} + +/*---------------------------------------------------------------------------- + * falc_remote_loop + *---------------------------------------------------------------------------- + * Description: In the remote loopback mode the clock and data recovered + * from the line inputs RL1/2 or RDIP/RDIN are routed back + * to the line outputs XL1/2 or XDOP/XDON via the analog + * transmitter. As in normal mode they are processsed by + * the synchronizer and then sent to the system interface. + *---------------------------------------------------------------------------- + */ +void falc_remote_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL); + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_local_loop + *---------------------------------------------------------------------------- + * Description: The local loopback mode disconnects the receive lines + * RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the + * signals coming from the line the data provided by system + * interface are routed through the analog receiver back to + * the system interface. The unipolar bit stream will be + * undisturbed transmitted on the line. Receiver and transmitter + * coding must be identical. + *---------------------------------------------------------------------------- + */ +void falc_local_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (loop_on) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_payload_loop + *---------------------------------------------------------------------------- + * Description: This routine allows to enable/disable payload loopback. + * When the payload loop is activated, the received 192 bits + * of payload data will be looped back to the transmit + * direction. The framing bits, CRC6 and DL bits are not + * looped. They are originated by the FALC-LH transmitter. + *---------------------------------------------------------------------------- + */ +void falc_payload_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0); + } + falc_open_all_timeslots(card, ch); + pfalc->loop_active = 2; + } else { + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xlu + *---------------------------------------------------------------------------- + * Description: Turns XLU bit off in the proper register + *---------------------------------------------------------------------------- + */ +void turn_off_xlu(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + uclong falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU); + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xld + *---------------------------------------------------------------------------- + * Description: Turns XLD bit off in the proper register + *---------------------------------------------------------------------------- + */ +void turn_off_xld(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + uclong falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD); + } +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_up_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP activation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +void falc_generate_loop_up_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU); + } + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + pfalc->loop_gen = 1; +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_down_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP deactivation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +void falc_generate_loop_down_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; +// falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_gen = 0; +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test + *---------------------------------------------------------------------------- + * Description: This routine generates a pattern code and checks + * it on the reception side. + *---------------------------------------------------------------------------- + */ +void falc_pattern_test(pc300_t * card, int ch, unsigned int activate) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (activate) { + pfalc->prbs = 1; + pfalc->bec = 0; + if (conf->media == IF_IFACE_T1) { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC); + } else { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC); + } + /* Activates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS); + } else { + pfalc->prbs = 0; + /* Deactivates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS)); + if (conf->media == IF_IFACE_T1) { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC); + } + } +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test_error + *---------------------------------------------------------------------------- + * Description: This routine returns the bit error counter value + *---------------------------------------------------------------------------- + */ +ucshort falc_pattern_test_error(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + return (pfalc->bec); +} + +/**********************************/ +/*** Net Interface Routines ***/ +/**********************************/ + +static void +cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) { + printk("%s: out of memory\n", dev->name); + return; + } + skb_put(skb, 10 + skb_main->len); + + skb->dev = dev; + skb->protocol = htons(ETH_P_CUST); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_HOST; + skb->len = 10 + skb_main->len; + + memcpy(skb->data, dev->name, 5); + skb->data[5] = '['; + skb->data[6] = rx_tx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + memcpy(&skb->data[10], skb_main->data, skb_main->len); + + netif_rx(skb); +} + +void cpc_tx_timeout(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + struct net_device_stats *stats = &d->hdlc->stats; + int ch = chan->channel; + uclong flags; + ucchar ilar; + + stats->tx_errors++; + stats->tx_aborted_errors++; + CPC_LOCK(card, flags); + if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) { + printk("%s: ILAR=0x%x\n", dev->name, ilar); + cpc_writeb(card->hw.scabase + ILAR, ilar); + cpc_writeb(card->hw.scabase + DMER, 0x80); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + dev->trans_start = jiffies; + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); +} + +int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + struct net_device_stats *stats = &d->hdlc->stats; + int ch = chan->channel; + uclong flags; +#ifdef PC300_DEBUG_TX + int i; +#endif + + if (chan->conf.monitor) { + /* In monitor mode no Tx is done: ignore packet */ + dev_kfree_skb(skb); + return 0; + } else if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + dev_kfree_skb(skb); + stats->tx_errors++; + stats->tx_carrier_errors++; + return 0; + } else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk("%s: DCD is OFF. Going administrative down.\n", dev->name); + stats->tx_errors++; + stats->tx_carrier_errors++; + dev_kfree_skb(skb); + netif_carrier_off(dev); + CPC_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); + return 0; + } + + /* Write buffer to DMA buffers */ + if (dma_buf_write(card, ch, (ucchar *) skb->data, skb->len) != 0) { +// printk("%s: write error. Dropping TX packet.\n", dev->name); + netif_stop_queue(dev); + dev_kfree_skb(skb); + stats->tx_errors++; + stats->tx_dropped++; + return 0; + } +#ifdef PC300_DEBUG_TX + printk("%s T:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + + if (d->trace_on) { + cpc_trace(dev, skb, 'T'); + } + dev->trans_start = jiffies; + + /* Start transmission */ + CPC_LOCK(card, flags); + /* verify if it has more than one free descriptor */ + if (card->chan[ch].nfree_tx_bd <= 1) { + /* don't have so stop the queue */ + netif_stop_queue(dev); + } + cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + dev_kfree_skb(skb); + + return 0; +} + +void cpc_net_rx(hdlc_device * hdlc) +{ + struct net_device *dev = hdlc_to_dev(hdlc); + pc300dev_t *d = (pc300dev_t *) dev->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + struct net_device_stats *stats = &d->hdlc->stats; + int ch = chan->channel; +#ifdef PC300_DEBUG_RX + int i; +#endif + int rxb; + struct sk_buff *skb; + + while (1) { + if ((rxb = dma_get_rx_frame_size(card, ch)) == -1) + return; + + if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + printk("%s : DCD is OFF - drop %d rx bytes\n", dev->name, rxb); + skb = NULL; + } else { + if (rxb > (dev->mtu + 40)) { /* add headers */ + printk("%s : MTU exceeded %d\n", dev->name, rxb); + skb = NULL; + } else { + skb = dev_alloc_skb(rxb); + if (skb == NULL) { + printk("%s: Memory squeeze!!\n", dev->name); + return; + } + skb->dev = dev; + } + } + + if (((rxb = dma_buf_read(card, ch, skb)) <= 0) || (skb == NULL)) { +#ifdef PC300_DEBUG_RX + printk("%s: rxb = %x\n", dev->name, rxb); +#endif + if ((skb == NULL) && (rxb > 0)) { + /* rxb > dev->mtu */ + stats->rx_errors++; + stats->rx_length_errors++; + continue; + } + + if (rxb < 0) { /* Invalid frame */ + rxb = -rxb; + if (rxb & DST_OVR) { + stats->rx_errors++; + stats->rx_fifo_errors++; + } + if (rxb & DST_CRC) { + stats->rx_errors++; + stats->rx_crc_errors++; + } + if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) { + stats->rx_errors++; + stats->rx_frame_errors++; + } + } + if (skb) { + dev_kfree_skb_irq(skb); + } + continue; + } + + stats->rx_bytes += rxb; + +#ifdef PC300_DEBUG_RX + printk("%s R:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + if (d->trace_on) { + cpc_trace(dev, skb, 'R'); + } + stats->rx_packets++; + skb->mac.raw = skb->data; + skb->protocol = hdlc_type_trans(skb, dev); + netif_rx(skb); + } +} + +/************************************/ +/*** PC300 Interrupt Routines ***/ +/************************************/ +static void sca_tx_intr(pc300dev_t *dev) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + volatile pcsca_bd_t * ptdescr; + struct net_device_stats *stats = &dev->hdlc->stats; + + /* Clean up descriptors from previous transmission */ + ptdescr = (pcsca_bd_t *)(card->hw.rambase + + TX_BD_ADDR(ch,chan->tx_first_bd)); + while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) != + TX_BD_ADDR(ch,chan->tx_first_bd)) && + (cpc_readb(&ptdescr->status) & DST_OSB)) { + stats->tx_packets++; + stats->tx_bytes += cpc_readw(&ptdescr->len); + cpc_writeb(&ptdescr->status, DST_OSB); + cpc_writew(&ptdescr->len, 0); + chan->nfree_tx_bd++; + chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1); + ptdescr = (pcsca_bd_t *)(card->hw.rambase + + TX_BD_ADDR(ch,chan->tx_first_bd)); + } + +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_trigger_poll(dev); + } else { +#endif + /* Tell the upper layer we are ready to transmit more packets */ + netif_wake_queue((struct net_device*)dev->hdlc); +#ifdef CONFIG_PC300_MLPPP + } +#endif +} + +static void sca_intr(pc300_t * card) +{ + uclong scabase = card->hw.scabase; + volatile uclong status; + int ch; + int intr_count = 0; + unsigned char dsr_rx; + + while ((status = cpc_readl(scabase + ISR0)) != 0) { + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300dev_t *d = &chan->d; + hdlc_device *hdlc = d->hdlc; + struct net_device *dev = hdlc_to_dev(hdlc); + + spin_lock(&card->card_lock); + + /**** Reception ****/ + if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) { + ucchar drx_stat = cpc_readb(scabase + DSR_RX(ch)); + + /* Clear RX interrupts */ + cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, drx_stat); +#endif + if (status & IR0_DRX(IR0_DMIA, ch)) { + if (drx_stat & DSR_BOF) { +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_tty_receive(d); + rx_dma_start(card, ch); + } else +#endif + { + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_net_rx(hdlc); + /* Discard invalid frames */ + hdlc->stats.rx_errors++; + hdlc->stats.rx_over_errors++; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_start(card, ch); + } + } + } + if (status & IR0_DRX(IR0_DMIB, ch)) { + if (drx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + cpc_tty_receive(d); + } else { + cpc_net_rx(hdlc); + } +#else + cpc_net_rx(hdlc); +#endif + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + } + } + if (!(dsr_rx = cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { +#ifdef PC300_DEBUG_INTR + printk("%s: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x, dsr2=0x%02x)\n", + dev->name, ch, status, drx_stat, dsr_rx); +#endif + cpc_writeb(scabase + DSR_RX(ch), (dsr_rx | DSR_DE) & 0xfe); + } + } + + /**** Transmission ****/ + if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) { + ucchar dtx_stat = cpc_readb(scabase + DSR_TX(ch)); + + /* Clear TX interrupts */ + cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: TX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, dtx_stat); +#endif + if (status & IR0_DTX(IR0_EFT, ch)) { + if (dtx_stat & DSR_UDRF) { + if (cpc_readb (scabase + M_REG(TBN, ch)) != 0) { + cpc_writeb(scabase + M_REG(CMD,ch), CMD_TX_BUF_CLR); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + hdlc->stats.tx_errors++; + hdlc->stats.tx_fifo_errors++; + sca_tx_intr(d); + } + } + if (status & IR0_DTX(IR0_DMIA, ch)) { + if (dtx_stat & DSR_BOF) { + } + } + if (status & IR0_DTX(IR0_DMIB, ch)) { + if (dtx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + sca_tx_intr(d); + } + } + } + + /**** MSCI ****/ + if (status & IR0_M(IR0_RXINTA, ch)) { + ucchar st1 = cpc_readb(scabase + M_REG(ST1, ch)); + + /* Clear MSCI interrupts */ + cpc_writeb(scabase + M_REG(ST1, ch), st1); + +#ifdef PC300_DEBUG_INTR + printk("sca_intr: MSCI intr chan[%d] (st=0x%08lx, st1=0x%02x)\n", + ch, status, st1); +#endif + if (st1 & ST1_CDCD) { /* DCD changed */ + if (cpc_readb(scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk ("%s: DCD is OFF. Going administrative down.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) { + netif_carrier_off(dev); + } +#else + netif_carrier_off(dev); + +#endif + card->chan[ch].d.line_off++; + } else { /* DCD = 1 */ + printk ("%s: DCD is ON. Going administrative up.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) + /* verify if driver is not TTY */ +#endif + netif_carrier_on(dev); + card->chan[ch].d.line_on++; + } + } + } + spin_unlock(&card->card_lock); + } + if (++intr_count == 10) + /* Too much work at this board. Force exit */ + break; + } +} + +static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (frs1 & FRS1_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((frs1 & FRS1_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_e1_loop_detection(pc300_t * card, int ch, ucchar rsp) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (rsp & RSP_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((rsp & RSP_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_t1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucchar isr0, isr3, gis; + ucchar dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + if (gis & GIS_ISR0) { + isr0 = cpc_readb(falcbase + F_REG(FISR0, ch)); + if (isr0 & FISR0_PDEN) { + /* Read the bit to clear the situation */ + if (cpc_readb(falcbase + F_REG(FRS1, ch)) & + FRS1_PDEN) { + pfalc->pden++; + } + } + } + + if (gis & GIS_ISR1) { + dummy = cpc_readb(falcbase + F_REG(FISR1, ch)); + } + + if (gis & GIS_ISR2) { + dummy = cpc_readb(falcbase + F_REG(FISR2, ch)); + } + + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + if (isr3 & FISR3_LLBSC) { + falc_t1_loop_detection(card, ch, + cpc_readb(falcbase + F_REG(FRS1, ch))); + } + } + } +} + +static void falc_e1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong falcbase = card->hw.falcbase; + ucchar isr1, isr2, isr3, gis, rsp; + ucchar dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + rsp = cpc_readb(falcbase + F_REG(RSP, ch)); + + if (gis & GIS_ISR0) { + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)); + } + if (gis & GIS_ISR1) { + isr1 = cpc_readb(falcbase + F_REG(FISR1, ch)); + if (isr1 & FISR1_XMB) { + if ((pfalc->xmb_cause & 2) + && pfalc->multiframe_mode) { + if (cpc_readb (falcbase + F_REG(FRS0, ch)) & + (FRS0_LOS | FRS0_AIS | FRS0_LFA)) { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + & ~XSP_AXS); + } else { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + | XSP_AXS); + } + } + pfalc->xmb_cause = 0; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB); + } + if (isr1 & FISR1_LLBSC) { + falc_e1_loop_detection(card, ch, rsp); + } + } + if (gis & GIS_ISR2) { + isr2 = cpc_readb(falcbase + F_REG(FISR2, ch)); + if (isr2 & FISR2_T400MS) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA); + } + if (isr2 & FISR2_MFAR) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA); + } + if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) { + pfalc->xmb_cause |= 2; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB); + } + } + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + } + } +} + +static void falc_intr(pc300_t * card) +{ + int ch; + + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + if (conf->media == IF_IFACE_T1) { + falc_t1_intr(card, ch); + } else { + falc_e1_intr(card, ch); + } + } +} + +static void cpc_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + pc300_t *card; + volatile ucchar plx_status; + + if ((card = (pc300_t *) dev_id) == 0) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr %d\n", irq); +#endif + return; /* spurious intr */ + } + + if (card->hw.rambase == 0) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr2 %d\n", irq); +#endif + return; /* spurious intr */ + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + sca_intr(card); + break; + + case PC300_TE: + while ( (plx_status = (cpc_readb(card->hw.plxbase + card->hw.intctl_reg) & + (PLX_9050_LINT1_STATUS | PLX_9050_LINT2_STATUS))) != 0) { + if (plx_status & PLX_9050_LINT1_STATUS) { /* SCA Interrupt */ + sca_intr(card); + } + if (plx_status & PLX_9050_LINT2_STATUS) { /* FALC Interrupt */ + falc_intr(card); + } + } + break; + } +} + +void cpc_sca_status(pc300_t * card, int ch) +{ + ucchar ilar; + uclong scabase = card->hw.scabase; + uclong flags; + + tx_dma_buf_check(card, ch); + rx_dma_buf_check(card, ch); + ilar = cpc_readb(scabase + ILAR); + printk ("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n", + ilar, cpc_readb(scabase + WCRL), cpc_readb(scabase + PCR), + cpc_readb(scabase + BTCR), cpc_readb(scabase + BOLR)); + printk("TX_CDA=0x%08lx, TX_EDA=0x%08lx\n", + (uclong) cpc_readl(scabase + DTX_REG(CDAL, ch)), + (uclong) cpc_readl(scabase + DTX_REG(EDAL, ch))); + printk("RX_CDA=0x%08lx, RX_EDA=0x%08lx, BFL=0x%04x\n", + (uclong) cpc_readl(scabase + DRX_REG(CDAL, ch)), + (uclong) cpc_readl(scabase + DRX_REG(EDAL, ch)), + cpc_readw(scabase + DRX_REG(BFLL, ch))); + printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n", + cpc_readb(scabase + DMER), cpc_readb(scabase + DSR_TX(ch)), + cpc_readb(scabase + DSR_RX(ch))); + printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n", + cpc_readb(scabase + DMR_TX(ch)), cpc_readb(scabase + DMR_RX(ch)), + cpc_readb(scabase + DIR_TX(ch)), + cpc_readb(scabase + DIR_RX(ch))); + printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n", + cpc_readb(scabase + DCR_TX(ch)), cpc_readb(scabase + DCR_RX(ch)), + cpc_readb(scabase + FCT_TX(ch)), + cpc_readb(scabase + FCT_RX(ch))); + printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n", + cpc_readb(scabase + M_REG(MD0, ch)), + cpc_readb(scabase + M_REG(MD1, ch)), + cpc_readb(scabase + M_REG(MD2, ch)), + cpc_readb(scabase + M_REG(MD3, ch)), + cpc_readb(scabase + M_REG(IDL, ch))); + printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n", + cpc_readb(scabase + M_REG(CMD, ch)), + cpc_readb(scabase + M_REG(SA0, ch)), + cpc_readb(scabase + M_REG(SA1, ch)), + cpc_readb(scabase + M_REG(TFN, ch)), + cpc_readb(scabase + M_REG(CTL, ch))); + printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n", + cpc_readb(scabase + M_REG(ST0, ch)), + cpc_readb(scabase + M_REG(ST1, ch)), + cpc_readb(scabase + M_REG(ST2, ch)), + cpc_readb(scabase + M_REG(ST3, ch)), + cpc_readb(scabase + M_REG(ST4, ch))); + printk ("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n", + cpc_readb(scabase + M_REG(CST0, ch)), + cpc_readb(scabase + M_REG(CST1, ch)), + cpc_readb(scabase + M_REG(CST2, ch)), + cpc_readb(scabase + M_REG(CST3, ch)), + cpc_readb(scabase + M_REG(FST, ch))); + printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n", + cpc_readb(scabase + M_REG(TRC0, ch)), + cpc_readb(scabase + M_REG(TRC1, ch)), + cpc_readb(scabase + M_REG(RRC, ch)), + cpc_readb(scabase + M_REG(TBN, ch)), + cpc_readb(scabase + M_REG(RBN, ch))); + printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TFS, ch)), + cpc_readb(scabase + M_REG(TNR0, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TCR, ch)), + cpc_readb(scabase + M_REG(RCR, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n", + cpc_readb(scabase + M_REG(TXS, ch)), + cpc_readb(scabase + M_REG(RXS, ch)), + cpc_readb(scabase + M_REG(EXS, ch)), + cpc_readb(scabase + M_REG(TMCT, ch)), + cpc_readb(scabase + M_REG(TMCR, ch))); + printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n", + cpc_readb(scabase + M_REG(IE0, ch)), + cpc_readb(scabase + M_REG(IE1, ch)), + cpc_readb(scabase + M_REG(IE2, ch)), + cpc_readb(scabase + M_REG(IE4, ch)), + cpc_readb(scabase + M_REG(FIE, ch))); + printk("IER0=0x%08lx\n", (uclong) cpc_readl(scabase + IER0)); + + if (ilar != 0) { + CPC_LOCK(card, flags); + cpc_writeb(scabase + ILAR, ilar); + cpc_writeb(scabase + DMER, 0x80); + CPC_UNLOCK(card, flags); + } +} + +void cpc_falc_status(pc300_t * card, int ch) +{ + pc300ch_t *chan = &card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + uclong flags; + + CPC_LOCK(card, flags); + printk("CH%d: %s %s %d channels\n", + ch, (pfalc->sync ? "SYNC" : ""), (pfalc->active ? "ACTIVE" : ""), + pfalc->num_channels); + + printk(" pden=%d, los=%d, losr=%d, lfa=%d, farec=%d\n", + pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec); + printk(" lmfa=%d, ais=%d, sec=%d, es=%d, rai=%d\n", + pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai); + printk(" bec=%d, fec=%d, cvc=%d, cec=%d, ebc=%d\n", + pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc); + + printk("\n"); + printk(" STATUS: %s %s %s %s %s %s\n", + (pfalc->red_alarm ? "RED" : ""), + (pfalc->blue_alarm ? "BLU" : ""), + (pfalc->yellow_alarm ? "YEL" : ""), + (pfalc->loss_fa ? "LFA" : ""), + (pfalc->loss_mfa ? "LMF" : ""), (pfalc->prbs ? "PRB" : "")); + CPC_UNLOCK(card, flags); +} + +int cpc_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pc300dev_t *d = (pc300dev_t *) dev->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + pc300conf_t conf_aux; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + int ch = chan->channel; + void *arg = (void *) ifr->ifr_data; + uclong scabase = card->hw.scabase; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + switch (cmd) { + case SIOCGPC300CONF: +#ifdef CONFIG_PC300_MLPPP + if (conf->proto != PC300_PROTO_MLPPP) { + conf->proto = hdlc->proto; + } +#else + conf->proto = hdlc->proto; +#endif + memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); + memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); + if (!arg || + copy_to_user(arg, &conf_aux, sizeof(pc300conf_t))) + return -EINVAL; + return 0; + case SIOCSPC300CONF: + if (!suser()) + return -EPERM; + if (!arg || + copy_from_user(&conf_aux.conf, arg, sizeof(pc300chconf_t))) + return -EINVAL; + if (card->hw.cpld_id < 0x02 && + conf_aux.conf.fr_mode == PC300_FR_UNFRAMED) { + /* CPLD_ID < 0x02 doesn't support Unframed E1 */ + return -EINVAL; + } +#ifdef CONFIG_PC300_MLPPP + if (conf_aux.conf.proto == PC300_PROTO_MLPPP) { + if (conf->proto != PC300_PROTO_MLPPP) { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + cpc_tty_init(d); /* init TTY driver */ + } + } else { + if (conf_aux.conf.proto == 0xffff) { + if (conf->proto == PC300_PROTO_MLPPP){ + /* ifdown interface */ + cpc_close(dev); + } + } else { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + hdlc->proto = conf->proto; + } + } +#else + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + hdlc->proto = conf->proto; +#endif + return 0; + case SIOCGPC300STATUS: + cpc_sca_status(card, ch); + return 0; + case SIOCGPC300FALCSTATUS: + cpc_falc_status(card, ch); + return 0; + + case SIOCGPC300UTILSTATS: + { + if (!arg) { /* clear statistics */ + memset(&hdlc->stats, 0, sizeof(struct net_device_stats)); + if (card->hw.type == PC300_TE) { + memset(&chan->falc, 0, sizeof(falc_t)); + } + } else { + pc300stats_t pc300stats; + + memset(&pc300stats, 0, sizeof(pc300stats_t)); + pc300stats.hw_type = card->hw.type; + pc300stats.line_on = card->chan[ch].d.line_on; + pc300stats.line_off = card->chan[ch].d.line_off; + memcpy(&pc300stats.gen_stats, &hdlc->stats, + sizeof(struct net_device_stats)); + if (card->hw.type == PC300_TE) + memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); + if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t))) + return -EFAULT; + } + return 0; + } + + case SIOCGPC300UTILSTATUS: + { + struct pc300status pc300status; + + pc300status.hw_type = card->hw.type; + if (card->hw.type == PC300_TE) { + pc300status.te_status.sync = chan->falc.sync; + pc300status.te_status.red_alarm = chan->falc.red_alarm; + pc300status.te_status.blue_alarm = chan->falc.blue_alarm; + pc300status.te_status.loss_fa = chan->falc.loss_fa; + pc300status.te_status.yellow_alarm =chan->falc.yellow_alarm; + pc300status.te_status.loss_mfa = chan->falc.loss_mfa; + pc300status.te_status.prbs = chan->falc.prbs; + } else { + pc300status.gen_status.dcd = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_DCD); + pc300status.gen_status.cts = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_CTS); + pc300status.gen_status.rts = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_RTS); + pc300status.gen_status.dtr = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR); + /* There is no DSR in HD64572 */ + } + if (!arg + || copy_to_user(arg, &pc300status, sizeof(pc300status_t))) + return -EINVAL; + return 0; + } + + case SIOCSPC300TRACE: + /* Sets/resets a trace_flag for the respective device */ + if (!arg || copy_from_user(&d->trace_on, arg,sizeof(unsigned char))) + return -EINVAL; + return 0; + + case SIOCSPC300LOOPBACK: + { + struct pc300loopback pc300loop; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (!arg || + copy_from_user(&pc300loop, arg, sizeof(pc300loopback_t))) + return -EINVAL; + switch (pc300loop.loop_type) { + case PC300LOCLOOP: /* Turn the local loop on/off */ + falc_local_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300REMLOOP: /* Turn the remote loop on/off */ + falc_remote_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300PAYLOADLOOP: /* Turn the payload loop on/off */ + falc_payload_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300GENLOOPUP: /* Generate loop UP */ + if (pc300loop.loop_on) { + falc_generate_loop_up_code (card, ch); + } else { + turn_off_xlu(card, ch); + } + return 0; + + case PC300GENLOOPDOWN: /* Generate loop DOWN */ + if (pc300loop.loop_on) { + falc_generate_loop_down_code (card, ch); + } else { + turn_off_xld(card, ch); + } + return 0; + + default: + return -EINVAL; + } + } + + case SIOCSPC300PATTERNTEST: + /* Turn the pattern test on/off and show the errors counter */ + { + struct pc300patterntst pc300patrntst; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (card->hw.cpld_id < 0x02) { + /* CPLD_ID < 0x02 doesn't support pattern test */ + return -EINVAL; + } + + if (!arg || + copy_from_user(&pc300patrntst,arg,sizeof(pc300patterntst_t))) + return -EINVAL; + if (pc300patrntst.patrntst_on == 2) { + if (chan->falc.prbs == 0) { + falc_pattern_test(card, ch, 1); + } + pc300patrntst.num_errors = + falc_pattern_test_error(card, ch); + if (!arg + || copy_to_user(arg, &pc300patrntst, + sizeof (pc300patterntst_t))) + return -EINVAL; + } else { + falc_pattern_test(card, ch, pc300patrntst.patrntst_on); + } + return 0; + } + + case SIOCWANDEV: + switch (ifr->ifr_settings.type) { + case IF_GET_IFACE: + { + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync; + + ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(line, &conf->phys_settings, size)) + return -EFAULT; + return 0; + } + + case IF_IFACE_V35: + case IF_IFACE_V24: + case IF_IFACE_X21: + { + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync; + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + if (ifr->ifr_settings.size != size) { + return -ENOMEM; //incorrect data len + } + if (copy_from_user(&conf->phys_settings, line, size)) { + return -EFAULT; + } + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + + case IF_IFACE_T1: + case IF_IFACE_E1: + { + const size_t te_size = sizeof(te1_settings); + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync; + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + if (ifr->ifr_settings.size != te_size) { + return -ENOMEM; //incorrect data len + } + if (copy_from_user(&conf->phys_settings, line, size)) { + return -EFAULT; + }/* Ignoring HDLC slot_map for a while */ + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + + default: + return hdlc_ioctl(dev, ifr, cmd); + } + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +static struct net_device_stats *cpc_get_stats(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev->priv; + + if (d) + return &d->hdlc->stats; + else + return NULL; +} + +static int clock_rate_calc(uclong rate, uclong clock, int *br_io) +{ + int br, tc; + int br_pwr, error; + + if (rate == 0) + return (0); + + for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { + if ((tc = clock / br_pwr / rate) <= 0xff) { + *br_io = br; + break; + } + } + + if (tc <= 0xff) { + error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; + /* Errors bigger than +/- 1% won't be tolerated */ + if (error < -10 || error > 10) + return (-1); + else + return (tc); + } else { + return (-1); + } +} + +int ch_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + pc300_t *card = (pc300_t *) chan->card; + uclong scabase = card->hw.scabase; + uclong plxbase = card->hw.plxbase; + int ch = chan->channel; + uclong clkrate = chan->conf.phys_settings.clock_rate; + uclong clktype = chan->conf.phys_settings.clock_type; + ucshort encoding = chan->conf.proto_settings.encoding; + ucshort parity = chan->conf.proto_settings.parity; + int tmc, br; + ucchar md0, md2; + + /* Reset the channel */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST); + + /* Configure the SCA registers */ + switch (parity) { + case PARITY_NONE: + md0 = MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR0: + md0 = MD0_CRC16_0|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1: + md0 = MD0_CRC16_1|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC32_PR1_CCITT: + md0 = MD0_CRC32|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1_CCITT: + default: + md0 = MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC; + break; + } + switch (encoding) { + case ENCODING_NRZI: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZI; + break; + case ENCODING_FM_MARK: /* FM1 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM1; + break; + case ENCODING_FM_SPACE: /* FM0 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM0; + break; + case ENCODING_MANCHESTER: /* It's not working... */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_MANCH; + break; + case ENCODING_NRZ: + default: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZ; + break; + } + cpc_writeb(scabase + M_REG(MD0, ch), md0); + cpc_writeb(scabase + M_REG(MD1, ch), 0); + cpc_writeb(scabase + M_REG(MD2, ch), md2); + cpc_writeb(scabase + M_REG(IDL, ch), 0x7e); + cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP | CTL_IDLC); + + /* Configure HW media */ + switch (card->hw.type) { + case PC300_RSV: + if (conf->media == IF_IFACE_V35) { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) | PC300_CHMEDIA_MASK(ch)); + } else { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) & ~PC300_CHMEDIA_MASK(ch)); + } + break; + + case PC300_X21: + break; + + case PC300_TE: + te_config(card, ch); + break; + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { + /* Calculate the clkrate parameters */ + tmc = clock_rate_calc(clkrate, card->hw.clock, &br); + cpc_writeb(scabase + M_REG(TMCT, ch), tmc); + cpc_writeb(scabase + M_REG(TXS, ch), + (TXS_DTRXC | TXS_IBRG | br)); + if (clktype == CLOCK_INT) { + cpc_writeb(scabase + M_REG(TMCR, ch), tmc); + cpc_writeb(scabase + M_REG(RXS, ch), + (RXS_IBRG | br)); + } else { + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + } + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 1); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } else { + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + if (clktype == CLOCK_EXT) { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC); + } else { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC|TXS_RCLK); + } + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } + break; + + case PC300_TE: + /* SCA always receives clock from the FALC chip */ + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + cpc_writeb(scabase + M_REG(TXS, ch), 0); + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), 0); + break; + } + + /* Enable Interrupts */ + cpc_writel(scabase + IER0, + cpc_readl(scabase + IER0) | + IR0_M(IR0_RXINTA, ch) | + IR0_DRX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch) | + IR0_DTX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch)); + cpc_writeb(scabase + M_REG(IE0, ch), + cpc_readl(scabase + M_REG(IE0, ch)) | IE0_RXINTA); + cpc_writeb(scabase + M_REG(IE1, ch), + cpc_readl(scabase + M_REG(IE1, ch)) | IE1_CDCD); + + return 0; +} + +int rx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + uclong scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_RX(ch), 0); + + /* General RX settings */ + cpc_writeb(scabase + M_REG(RRC, ch), 0); + cpc_writeb(scabase + M_REG(RNR, ch), 16); + + /* Enable reception */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT); + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA); + + /* Initialize DMA stuff */ + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF)); + + /* Start DMA */ + rx_dma_start(card, ch); + + return 0; +} + +int tx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + uclong scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_TX(ch), 0); + + /* General TX settings */ + cpc_writeb(scabase + M_REG(TRC0, ch), 0); + cpc_writeb(scabase + M_REG(TFS, ch), 32); + cpc_writeb(scabase + M_REG(TNR0, ch), 20); + cpc_writeb(scabase + M_REG(TNR1, ch), 48); + cpc_writeb(scabase + M_REG(TCR, ch), 8); + + /* Enable transmission */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT); + + /* Initialize DMA stuff */ + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + tx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF)); + cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd)); + cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd)); + + return 0; +} + +static int cpc_attach(hdlc_device * hdlc, unsigned short encoding, + unsigned short parity) +{ + struct net_device * dev = hdlc_to_dev(hdlc); + pc300dev_t *d = (pc300dev_t *)dev->priv; + pc300ch_t *chan = (pc300ch_t *)d->chan; + pc300_t *card = (pc300_t *)chan->card; + pc300chconf_t *conf = (pc300chconf_t *)&chan->conf; + + if (card->hw.type == PC300_TE) { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI) { + return -EINVAL; + } + } else { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI && + encoding != ENCODING_FM_MARK && encoding != ENCODING_FM_SPACE) { + /* Driver doesn't support ENCODING_MANCHESTER yet */ + return -EINVAL; + } + } + + if (parity != PARITY_NONE && parity != PARITY_CRC16_PR0 && + parity != PARITY_CRC16_PR1 && parity != PARITY_CRC32_PR1_CCITT && + parity != PARITY_CRC16_PR1_CCITT) { + return -EINVAL; + } + + conf->proto_settings.encoding = encoding; + conf->proto_settings.parity = parity; + return 0; +} + +void cpc_opench(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; + uclong scabase = card->hw.scabase; + + ch_config(d); + + rx_config(d); + + tx_config(d); + + /* Assert RTS and DTR */ + cpc_writeb(scabase + M_REG(CTL, ch), + cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); +} + +void cpc_closech(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + falc_t *pfalc = (falc_t *) & chan->falc; + int ch = chan->channel; + + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST); + rx_dma_stop(card, ch); + tx_dma_stop(card, ch); + + if (card->hw.type == PC300_TE) { + memset(pfalc, 0, sizeof(falc_t)); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK | + CPLD_REG2_FALC_LED2) << (2 * ch))); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + } +} + +int cpc_open(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pc300dev_t *d = (pc300dev_t *) dev->priv; + struct ifreq ifr; + int result; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_open"); +#endif + + if (hdlc->proto == IF_PROTO_PPP) { + d->if_ptr = &hdlc->state.ppp.pppdev; + } + + result = hdlc_open(hdlc); + if (hdlc->proto == IF_PROTO_PPP) { + dev->priv = d; + } + if (result) { + return result; + } + + MOD_INC_USE_COUNT; + sprintf(ifr.ifr_name, "%s", dev->name); + cpc_opench(d); + netif_start_queue(dev); + return 0; +} + +int cpc_close(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + pc300dev_t *d = (pc300dev_t *) dev->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + uclong flags; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_close"); +#endif + + netif_stop_queue(dev); + + CPC_LOCK(card, flags); + cpc_closech(d); + CPC_UNLOCK(card, flags); + + hdlc_close(hdlc); + if (hdlc->proto == IF_PROTO_PPP) { + d->if_ptr = NULL; + } +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_unregister_service(d); + chan->conf.proto = 0xffff; + } +#endif + + MOD_DEC_USE_COUNT; + return 0; +} + +static uclong detect_ram(pc300_t * card) +{ + uclong i; + ucchar data; + uclong rambase = card->hw.rambase; + + card->hw.ramsize = PC300_RAMSIZE; + /* Let's find out how much RAM is present on this board */ + for (i = 0; i < card->hw.ramsize; i++) { + data = (ucchar) (i & 0xff); + cpc_writeb(rambase + i, data); + if (cpc_readb(rambase + i) != data) { + break; + } + } + return (i); +} + +static void plx_init(pc300_t * card) +{ + struct RUNTIME_9050 *plx_ctl = (struct RUNTIME_9050 *) card->hw.plxbase; + + /* Reset PLX */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x40000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x40000000); + + /* Reload Config. Registers from EEPROM */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x20000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x20000000); + +} + +static inline void show_version(void) +{ + char *rcsvers, *rcsdate, *tmp; + + rcsvers = strchr(rcsid, ' '); + rcsvers++; + tmp = strchr(rcsvers, ' '); + *tmp++ = '\0'; + rcsdate = strchr(tmp, ' '); + rcsdate++; + tmp = strrchr(rcsdate, ' '); + *tmp = '\0'; + printk(KERN_INFO "Cyclades-PC300 driver %s %s (built %s %s)\n", + rcsvers, rcsdate, __DATE__, __TIME__); +} /* show_version */ + +static void cpc_init_card(pc300_t * card) +{ + int i, devcount = 0; + static int board_nbr = 1; + + /* Enable interrupts on the PCI bridge */ + plx_init(card); + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) | 0x0040); + +#ifdef USE_PCI_CLOCK + /* Set board clock to PCI clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) | 0x00000004UL); + card->hw.clock = PC300_PCI_CLOCK; +#else + /* Set board clock to internal oscillator clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & ~0x00000004UL); + card->hw.clock = PC300_OSC_CLOCK; +#endif + + /* Detect actual on-board RAM size */ + card->hw.ramsize = detect_ram(card); + + /* Set Global SCA-II registers */ + cpc_writeb(card->hw.scabase + PCR, PCR_PR2); + cpc_writeb(card->hw.scabase + BTCR, 0x10); + cpc_writeb(card->hw.scabase + WCRL, 0); + cpc_writeb(card->hw.scabase + DMER, 0x80); + + if (card->hw.type == PC300_TE) { + ucchar reg1; + + /* Check CPLD version */ + reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1); + cpc_writeb(card->hw.falcbase + CPLD_REG1, (reg1 + 0x5a)); + if (cpc_readb(card->hw.falcbase + CPLD_REG1) == reg1) { + /* New CPLD */ + card->hw.cpld_id = cpc_readb(card->hw.falcbase + CPLD_ID_REG); + card->hw.cpld_reg1 = CPLD_V2_REG1; + card->hw.cpld_reg2 = CPLD_V2_REG2; + } else { + /* old CPLD */ + card->hw.cpld_id = 0; + card->hw.cpld_reg1 = CPLD_REG1; + card->hw.cpld_reg2 = CPLD_REG2; + cpc_writeb(card->hw.falcbase + CPLD_REG1, reg1); + } + + /* Enable the board's global clock */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + CPLD_REG1_GLOBAL_CLK); + + } + + for (i = 0; i < card->hw.nchan; i++) { + pc300ch_t *chan = &card->chan[i]; + pc300dev_t *d = &chan->d; + hdlc_device *hdlc; + struct net_device *dev; + + chan->card = card; + chan->channel = i; + chan->conf.phys_settings.clock_rate = 0; + chan->conf.phys_settings.clock_type = CLOCK_EXT; + chan->conf.proto_settings.encoding = ENCODING_NRZ; + chan->conf.proto_settings.parity = PARITY_CRC16_PR1_CCITT; + switch (card->hw.type) { + case PC300_TE: + chan->conf.media = IF_IFACE_T1; + chan->conf.lcode = PC300_LC_B8ZS; + chan->conf.fr_mode = PC300_FR_ESF; + chan->conf.lbo = PC300_LBO_0_DB; + chan->conf.rx_sens = PC300_RX_SENS_SH; + chan->conf.tslot_bitmap = 0xffffffffUL; + break; + + case PC300_X21: + chan->conf.media = IF_IFACE_X21; + break; + + case PC300_RSV: + default: + chan->conf.media = IF_IFACE_V35; + break; + } + chan->conf.proto = IF_PROTO_PPP; + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + chan->nfree_tx_bd = N_DMA_TX_BUF; + + d->chan = chan; + d->tx_skb = NULL; + d->trace_on = 0; + d->line_on = 0; + d->line_off = 0; + + d->hdlc = (hdlc_device *) kmalloc(sizeof(hdlc_device), GFP_KERNEL); + if (d->hdlc == NULL) + continue; + memset(d->hdlc, 0, sizeof(hdlc_device)); + + hdlc = d->hdlc; + hdlc->xmit = cpc_queue_xmit; + hdlc->attach = cpc_attach; + + dev = hdlc_to_dev(hdlc); + + dev->mem_start = card->hw.ramphys; + dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1; + dev->irq = card->hw.irq; + dev->init = NULL; + dev->tx_queue_len = PC300_TX_QUEUE_LEN; + dev->mtu = PC300_DEF_MTU; + + dev->open = cpc_open; + dev->stop = cpc_close; + dev->tx_timeout = cpc_tx_timeout; + dev->watchdog_timeo = PC300_TX_TIMEOUT; + dev->get_stats = cpc_get_stats; + dev->set_multicast_list = NULL; + dev->set_mac_address = NULL; + dev->change_mtu = cpc_change_mtu; + dev->do_ioctl = cpc_ioctl; + + if (register_hdlc_device(hdlc) == 0) { + dev->priv = d; /* We need 'priv', hdlc doesn't */ + printk("%s: Cyclades-PC300/", dev->name); + switch (card->hw.type) { + case PC300_TE: + if (card->hw.bus == PC300_PMC) { + printk("TE-M"); + } else { + printk("TE "); + } + break; + + case PC300_X21: + printk("X21 "); + break; + + case PC300_RSV: + default: + printk("RSV "); + break; + } + printk (" #%d, %ldKB of RAM at 0x%08lx, IRQ%d, channel %d.\n", + board_nbr, card->hw.ramsize / 1024, + card->hw.ramphys, card->hw.irq, i + 1); + devcount++; + } else { + printk ("Dev%d on card(0x%08lx): unable to allocate i/f name.\n", + i + 1, card->hw.ramphys); + *(dev->name) = 0; + kfree(d->hdlc); + continue; + } + } + spin_lock_init(&card->card_lock); + + board_nbr++; +} + +static int __devinit +cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int first_time = 1; + ucchar cpc_rev_id; + int err = 0, eeprom_outdated = 0; + ucshort device_id; + pc300_t *card; + + if (first_time) { + first_time = 0; + show_version(); +#ifdef CONFIG_PC300_MLPPP + cpc_tty_reset_var(); +#endif + } + + card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); + if (card == NULL) { + printk("PC300 found at RAM 0x%08lx, " + "but could not allocate card structure.\n", + pci_resource_start(pdev, 3)); + return -ENOMEM; + } + memset(card, 0, sizeof(pc300_t)); + + /* read PCI configuration area */ + device_id = ent->device; + card->hw.irq = pdev->irq; + card->hw.iophys = pci_resource_start(pdev, 1); + card->hw.iosize = pci_resource_len(pdev, 1); + card->hw.scaphys = pci_resource_start(pdev, 2); + card->hw.scasize = pci_resource_len(pdev, 2); + card->hw.ramphys = pci_resource_start(pdev, 3); + card->hw.alloc_ramsize = pci_resource_len(pdev, 3); + card->hw.falcphys = pci_resource_start(pdev, 4); + card->hw.falcsize = pci_resource_len(pdev, 4); + card->hw.plxphys = pci_resource_start(pdev, 5); + card->hw.plxsize = pci_resource_len(pdev, 5); + pci_read_config_byte(pdev, PCI_REVISION_ID, &cpc_rev_id); + + switch (device_id) { + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_TE_1: + card->hw.nchan = 1; + break; + + case PCI_DEVICE_ID_PC300_RX_2: + case PCI_DEVICE_ID_PC300_TE_2: + default: + card->hw.nchan = PC300_MAXCHAN; + break; + } +#ifdef PC300_DEBUG_PCI + printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", cpc_rev_id, card->hw.irq); + printk("cpc:found ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.ramphys, card->hw.plxphys, card->hw.scaphys, + card->hw.falcphys); +#endif + /* Although we don't use this I/O region, we should + * request it from the kernel anyway, to avoid problems + * with other drivers accessing it. */ + if (!request_region(card->hw.iophys, card->hw.iosize, "PLX Registers")) { + /* In case we can't allocate it, warn user */ + printk("WARNING: couldn't allocate I/O region for PC300 board " + "at 0x%08lx!\n", card->hw.ramphys); + } + + if (card->hw.plxphys) { + pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, card->hw.plxphys); + } else { + eeprom_outdated = 1; + card->hw.plxphys = pci_resource_start(pdev, 0); + card->hw.plxsize = pci_resource_len(pdev, 0); + } + + if (!request_mem_region(card->hw.plxphys, card->hw.plxsize, + "PLX Registers")) { + printk("PC300 found at RAM 0x%08lx, " + "but could not allocate PLX mem region.\n", + card->hw.ramphys); + err = -ENODEV; + goto err_release_io; + } + if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, + "On-board RAM")) { + printk("PC300 found at RAM 0x%08lx, " + "but could not allocate RAM mem region.\n", + card->hw.ramphys); + err = -ENODEV; + goto err_release_plx; + } + if (!request_mem_region(card->hw.scaphys, card->hw.scasize, + "SCA-II Registers")) { + printk("PC300 found at RAM 0x%08lx, " + "but could not allocate SCA mem region.\n", + card->hw.ramphys); + err = -ENODEV; + goto err_release_ram; + } + + if ((err = pci_enable_device(pdev)) != 0) + goto err_release_sca; + + card->hw.plxbase = (uclong) ioremap(card->hw.plxphys, card->hw.plxsize); + card->hw.rambase = (uclong) ioremap(card->hw.ramphys, + card->hw.alloc_ramsize); + card->hw.scabase = (uclong) ioremap(card->hw.scaphys, card->hw.scasize); + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + request_mem_region(card->hw.falcphys, card->hw.falcsize, + "FALC Registers"); + card->hw.falcbase = (uclong) ioremap(card->hw.falcphys, + card->hw.falcsize); + break; + + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.falcbase = 0; + break; + } + +#ifdef PC300_DEBUG_PCI + printk("cpc: relocate ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.rambase, card->hw.plxbase, card->hw.scabase, + card->hw.falcbase); +#endif + + /* Set PCI drv pointer to the card structure */ + pdev->driver_data = card; + + /* Set board type */ + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + card->hw.type = PC300_TE; + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + break; + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + + if ((cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & PC300_CTYPE_MASK)) { + card->hw.type = PC300_X21; + } else { + card->hw.type = PC300_RSV; + } + break; + } + + /* Allocate IRQ */ + if (request_irq(card->hw.irq, cpc_intr, SA_SHIRQ, "Cyclades-PC300", card)) { + printk ("PC300 found at RAM 0x%08lx, but could not allocate IRQ%d.\n", + card->hw.ramphys, card->hw.irq); + goto err_io_unmap; + } + + cpc_init_card(card); + + if (eeprom_outdated) + printk("WARNING: PC300 with outdated EEPROM.\n"); + return 0; + +err_io_unmap: + iounmap((void *) card->hw.plxbase); + iounmap((void *) card->hw.scabase); + iounmap((void *) card->hw.rambase); + if (card->hw.type == PC300_TE) { + iounmap((void *) card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } +err_release_sca: + release_mem_region(card->hw.scaphys, card->hw.scasize); +err_release_ram: + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); +err_release_plx: + release_mem_region(card->hw.plxphys, card->hw.plxsize); +err_release_io: + release_region(card->hw.iophys, card->hw.iosize); + kfree(card); + return -ENODEV; +} + +static void __devexit cpc_remove_one(struct pci_dev *pdev) +{ + pc300_t *card = (pc300_t *) pdev->driver_data; + + if (card->hw.rambase != 0) { + int i; + + /* Disable interrupts on the PCI bridge */ + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) & ~(0x0040)); + + for (i = 0; i < card->hw.nchan; i++) { + unregister_hdlc_device(card->chan[i].d.hdlc); + } + iounmap((void *) card->hw.plxbase); + iounmap((void *) card->hw.scabase); + iounmap((void *) card->hw.rambase); + release_mem_region(card->hw.plxphys, card->hw.plxsize); + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); + release_mem_region(card->hw.scaphys, card->hw.scasize); + release_region(card->hw.iophys, card->hw.iosize); + if (card->hw.type == PC300_TE) { + iounmap((void *) card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } + if (card->hw.irq) + free_irq(card->hw.irq, card); + kfree(card); + } +} + +static struct pci_driver cpc_driver = { + .name = "pc300", + .id_table = cpc_pci_dev_id, + .probe = cpc_init_one, + .remove = __devexit_p(cpc_remove_one), +}; + +static int __init cpc_init(void) +{ + return pci_module_init(&cpc_driver); +} + +static void __exit cpc_cleanup_module(void) +{ + pci_unregister_driver(&cpc_driver); +} + +module_init(cpc_init); +module_exit(cpc_cleanup_module); + +MODULE_DESCRIPTION("Cyclades-PC300 cards driver"); +MODULE_AUTHOR( "Author: Ivan Passos \r\n" + "Maintainer: PC300 Maintainer + * + * Copyright: (c) 2000-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef _FALC_LH_H +#define _FALC_LH_H + +#define NUM_OF_T1_CHANNELS 24 +#define NUM_OF_E1_CHANNELS 32 + +/*>>>>>>>>>>>>>>>>> FALC Register Bits (Transmit Mode) <<<<<<<<<<<<<<<<<<< */ + +/* CMDR (Command Register) + ---------------- E1 & T1 ------------------------------ */ +#define CMDR_RMC 0x80 +#define CMDR_RRES 0x40 +#define CMDR_XREP 0x20 +#define CMDR_XRES 0x10 +#define CMDR_XHF 0x08 +#define CMDR_XTF 0x04 +#define CMDR_XME 0x02 +#define CMDR_SRES 0x01 + +/* MODE (Mode Register) + ----------------- E1 & T1 ----------------------------- */ +#define MODE_MDS2 0x80 +#define MODE_MDS1 0x40 +#define MODE_MDS0 0x20 +#define MODE_BRAC 0x10 +#define MODE_HRAC 0x08 + +/* IPC (Interrupt Port Configuration) + ----------------- E1 & T1 ----------------------------- */ +#define IPC_VIS 0x80 +#define IPC_SCI 0x04 +#define IPC_IC1 0x02 +#define IPC_IC0 0x01 + +/* CCR1 (Common Configuration Register 1) + ----------------- E1 & T1 ----------------------------- */ +#define CCR1_SFLG 0x80 +#define CCR1_XTS16RA 0x40 +#define CCR1_BRM 0x40 +#define CCR1_CASSYM 0x20 +#define CCR1_EDLX 0x20 +#define CCR1_EITS 0x10 +#define CCR1_ITF 0x08 +#define CCR1_RFT1 0x02 +#define CCR1_RFT0 0x01 + +/* CCR3 (Common Configuration Register 3) + ---------------- E1 & T1 ------------------------------ */ + +#define CCR3_PRE1 0x80 +#define CCR3_PRE0 0x40 +#define CCR3_EPT 0x20 +#define CCR3_RADD 0x10 +#define CCR3_RCRC 0x04 +#define CCR3_XCRC 0x02 + + +/* RTR1-4 (Receive Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define RTR1_TS0 0x80 +#define RTR1_TS1 0x40 +#define RTR1_TS2 0x20 +#define RTR1_TS3 0x10 +#define RTR1_TS4 0x08 +#define RTR1_TS5 0x04 +#define RTR1_TS6 0x02 +#define RTR1_TS7 0x01 + +#define RTR2_TS8 0x80 +#define RTR2_TS9 0x40 +#define RTR2_TS10 0x20 +#define RTR2_TS11 0x10 +#define RTR2_TS12 0x08 +#define RTR2_TS13 0x04 +#define RTR2_TS14 0x02 +#define RTR2_TS15 0x01 + +#define RTR3_TS16 0x80 +#define RTR3_TS17 0x40 +#define RTR3_TS18 0x20 +#define RTR3_TS19 0x10 +#define RTR3_TS20 0x08 +#define RTR3_TS21 0x04 +#define RTR3_TS22 0x02 +#define RTR3_TS23 0x01 + +#define RTR4_TS24 0x80 +#define RTR4_TS25 0x40 +#define RTR4_TS26 0x20 +#define RTR4_TS27 0x10 +#define RTR4_TS28 0x08 +#define RTR4_TS29 0x04 +#define RTR4_TS30 0x02 +#define RTR4_TS31 0x01 + + +/* TTR1-4 (Transmit Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define TTR1_TS0 0x80 +#define TTR1_TS1 0x40 +#define TTR1_TS2 0x20 +#define TTR1_TS3 0x10 +#define TTR1_TS4 0x08 +#define TTR1_TS5 0x04 +#define TTR1_TS6 0x02 +#define TTR1_TS7 0x01 + +#define TTR2_TS8 0x80 +#define TTR2_TS9 0x40 +#define TTR2_TS10 0x20 +#define TTR2_TS11 0x10 +#define TTR2_TS12 0x08 +#define TTR2_TS13 0x04 +#define TTR2_TS14 0x02 +#define TTR2_TS15 0x01 + +#define TTR3_TS16 0x80 +#define TTR3_TS17 0x40 +#define TTR3_TS18 0x20 +#define TTR3_TS19 0x10 +#define TTR3_TS20 0x08 +#define TTR3_TS21 0x04 +#define TTR3_TS22 0x02 +#define TTR3_TS23 0x01 + +#define TTR4_TS24 0x80 +#define TTR4_TS25 0x40 +#define TTR4_TS26 0x20 +#define TTR4_TS27 0x10 +#define TTR4_TS28 0x08 +#define TTR4_TS29 0x04 +#define TTR4_TS30 0x02 +#define TTR4_TS31 0x01 + + + +/* IMR0-4 (Interrupt Mask Register 0-4) + + ----------------- E1 & T1 ----------------------------- */ + +#define IMR0_RME 0x80 +#define IMR0_RFS 0x40 +#define IMR0_T8MS 0x20 +#define IMR0_ISF 0x20 +#define IMR0_RMB 0x10 +#define IMR0_CASC 0x08 +#define IMR0_RSC 0x08 +#define IMR0_CRC6 0x04 +#define IMR0_CRC4 0x04 +#define IMR0_PDEN 0x02 +#define IMR0_RPF 0x01 + +#define IMR1_CASE 0x80 +#define IMR1_RDO 0x40 +#define IMR1_ALLS 0x20 +#define IMR1_XDU 0x10 +#define IMR1_XMB 0x08 +#define IMR1_XLSC 0x02 +#define IMR1_XPR 0x01 +#define IMR1_LLBSC 0x80 + +#define IMR2_FAR 0x80 +#define IMR2_LFA 0x40 +#define IMR2_MFAR 0x20 +#define IMR2_T400MS 0x10 +#define IMR2_LMFA 0x10 +#define IMR2_AIS 0x08 +#define IMR2_LOS 0x04 +#define IMR2_RAR 0x02 +#define IMR2_RA 0x01 + +#define IMR3_ES 0x80 +#define IMR3_SEC 0x40 +#define IMR3_LMFA16 0x20 +#define IMR3_AIS16 0x10 +#define IMR3_RA16 0x08 +#define IMR3_API 0x04 +#define IMR3_XSLP 0x20 +#define IMR3_XSLN 0x10 +#define IMR3_LLBSC 0x08 +#define IMR3_XRS 0x04 +#define IMR3_SLN 0x02 +#define IMR3_SLP 0x01 + +#define IMR4_LFA 0x80 +#define IMR4_FER 0x40 +#define IMR4_CER 0x20 +#define IMR4_AIS 0x10 +#define IMR4_LOS 0x08 +#define IMR4_CVE 0x04 +#define IMR4_SLIP 0x02 +#define IMR4_EBE 0x01 + +/* FMR0-5 for E1 and T1 (Framer Mode Register ) */ + +#define FMR0_XC1 0x80 +#define FMR0_XC0 0x40 +#define FMR0_RC1 0x20 +#define FMR0_RC0 0x10 +#define FMR0_EXTD 0x08 +#define FMR0_ALM 0x04 +#define E1_FMR0_FRS 0x02 +#define T1_FMR0_FRS 0x08 +#define FMR0_SRAF 0x04 +#define FMR0_EXLS 0x02 +#define FMR0_SIM 0x01 + +#define FMR1_MFCS 0x80 +#define FMR1_AFR 0x40 +#define FMR1_ENSA 0x20 +#define FMR1_CTM 0x80 +#define FMR1_SIGM 0x40 +#define FMR1_EDL 0x20 +#define FMR1_PMOD 0x10 +#define FMR1_XFS 0x08 +#define FMR1_CRC 0x08 +#define FMR1_ECM 0x04 +#define FMR1_IMOD 0x02 +#define FMR1_XAIS 0x01 + +#define FMR2_RFS1 0x80 +#define FMR2_RFS0 0x40 +#define FMR2_MCSP 0x40 +#define FMR2_RTM 0x20 +#define FMR2_SSP 0x20 +#define FMR2_DAIS 0x10 +#define FMR2_SAIS 0x08 +#define FMR2_PLB 0x04 +#define FMR2_AXRA 0x02 +#define FMR2_ALMF 0x01 +#define FMR2_EXZE 0x01 + +#define LOOP_RTM 0x40 +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA 0x1f + +/*--------------------- E1 ----------------------------*/ +#define FMR3_XLD 0x20 +#define FMR3_XLU 0x10 + +/*--------------------- T1 ----------------------------*/ +#define FMR4_AIS3 0x80 +#define FMR4_TM 0x40 +#define FMR4_XRA 0x20 +#define FMR4_SSC1 0x10 +#define FMR4_SSC0 0x08 +#define FMR4_AUTO 0x04 +#define FMR4_FM1 0x02 +#define FMR4_FM0 0x01 + +#define FMR5_SRS 0x80 +#define FMR5_EIBR 0x40 +#define FMR5_XLD 0x20 +#define FMR5_XLU 0x10 + + +/* LOOP (Channel Loop Back) + + ------------------ E1 & T1 ---------------------------- */ + +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA4 0x10 +#define LOOP_CLA3 0x08 +#define LOOP_CLA2 0x04 +#define LOOP_CLA1 0x02 +#define LOOP_CLA0 0x01 + + + +/* XSW (Transmit Service Word Pulseframe) + + ------------------- E1 --------------------------- */ + +#define XSW_XSIS 0x80 +#define XSW_XTM 0x40 +#define XSW_XRA 0x20 +#define XSW_XY0 0x10 +#define XSW_XY1 0x08 +#define XSW_XY2 0x04 +#define XSW_XY3 0x02 +#define XSW_XY4 0x01 + + +/* XSP (Transmit Spare Bits) + + ------------------- E1 --------------------------- */ + +#define XSP_XAP 0x80 +#define XSP_CASEN 0x40 +#define XSP_TT0 0x20 +#define XSP_EBP 0x10 +#define XSP_AXS 0x08 +#define XSP_XSIF 0x04 +#define XSP_XS13 0x02 +#define XSP_XS15 0x01 + + +/* XC0/1 (Transmit Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define XC0_SA8E 0x80 +#define XC0_SA7E 0x40 +#define XC0_SA6E 0x20 +#define XC0_SA5E 0x10 +#define XC0_SA4E 0x08 +#define XC0_BRM 0x80 +#define XC0_MFBS 0x40 +#define XC0_SFRZ 0x10 +#define XC0_XCO2 0x04 +#define XC0_XCO1 0x02 +#define XC0_XCO0 0x01 + +#define XC1_XTO5 0x20 +#define XC1_XTO4 0x10 +#define XC1_XTO3 0x08 +#define XC1_XTO2 0x04 +#define XC1_XTO1 0x02 +#define XC1_XTO0 0x01 + + +/* RC0/1 (Receive Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define RC0_SICS 0x40 +#define RC0_CRCI 0x20 +#define RC0_XCRCI 0x10 +#define RC0_RDIS 0x08 +#define RC0_RCO2 0x04 +#define RC0_RCO1 0x02 +#define RC0_RCO0 0x01 + +#define RC1_SWD 0x80 +#define RC1_ASY4 0x40 +#define RC1_RRAM 0x40 +#define RC1_RTO5 0x20 +#define RC1_RTO4 0x10 +#define RC1_RTO3 0x08 +#define RC1_RTO2 0x04 +#define RC1_RTO1 0x02 +#define RC1_RTO0 0x01 + + + +/* XPM0-2 (Transmit Pulse Mask 0-2) + --------------------- E1 & T1 ------------------------- */ + +#define XPM0_XP12 0x80 +#define XPM0_XP11 0x40 +#define XPM0_XP10 0x20 +#define XPM0_XP04 0x10 +#define XPM0_XP03 0x08 +#define XPM0_XP02 0x04 +#define XPM0_XP01 0x02 +#define XPM0_XP00 0x01 + +#define XPM1_XP30 0x80 +#define XPM1_XP24 0x40 +#define XPM1_XP23 0x20 +#define XPM1_XP22 0x10 +#define XPM1_XP21 0x08 +#define XPM1_XP20 0x04 +#define XPM1_XP14 0x02 +#define XPM1_XP13 0x01 + +#define XPM2_XLHP 0x80 +#define XPM2_XLT 0x40 +#define XPM2_DAXLT 0x20 +#define XPM2_XP34 0x08 +#define XPM2_XP33 0x04 +#define XPM2_XP32 0x02 +#define XPM2_XP31 0x01 + + +/* TSWM (Transparent Service Word Mask) + ------------------ E1 ---------------------------- */ + +#define TSWM_TSIS 0x80 +#define TSWM_TSIF 0x40 +#define TSWM_TRA 0x20 +#define TSWM_TSA4 0x10 +#define TSWM_TSA5 0x08 +#define TSWM_TSA6 0x04 +#define TSWM_TSA7 0x02 +#define TSWM_TSA8 0x01 + +/* IDLE + + ------------------ E1 & T1 ----------------------- */ + +#define IDLE_IDL7 0x80 +#define IDLE_IDL6 0x40 +#define IDLE_IDL5 0x20 +#define IDLE_IDL4 0x10 +#define IDLE_IDL3 0x08 +#define IDLE_IDL2 0x04 +#define IDLE_IDL1 0x02 +#define IDLE_IDL0 0x01 + + +/* XSA4-8 + -------------------E1 ----------------------------- */ + +#define XSA4_XS47 0x80 +#define XSA4_XS46 0x40 +#define XSA4_XS45 0x20 +#define XSA4_XS44 0x10 +#define XSA4_XS43 0x08 +#define XSA4_XS42 0x04 +#define XSA4_XS41 0x02 +#define XSA4_XS40 0x01 + +#define XSA5_XS57 0x80 +#define XSA5_XS56 0x40 +#define XSA5_XS55 0x20 +#define XSA5_XS54 0x10 +#define XSA5_XS53 0x08 +#define XSA5_XS52 0x04 +#define XSA5_XS51 0x02 +#define XSA5_XS50 0x01 + +#define XSA6_XS67 0x80 +#define XSA6_XS66 0x40 +#define XSA6_XS65 0x20 +#define XSA6_XS64 0x10 +#define XSA6_XS63 0x08 +#define XSA6_XS62 0x04 +#define XSA6_XS61 0x02 +#define XSA6_XS60 0x01 + +#define XSA7_XS77 0x80 +#define XSA7_XS76 0x40 +#define XSA7_XS75 0x20 +#define XSA7_XS74 0x10 +#define XSA7_XS73 0x08 +#define XSA7_XS72 0x04 +#define XSA7_XS71 0x02 +#define XSA7_XS70 0x01 + +#define XSA8_XS87 0x80 +#define XSA8_XS86 0x40 +#define XSA8_XS85 0x20 +#define XSA8_XS84 0x10 +#define XSA8_XS83 0x08 +#define XSA8_XS82 0x04 +#define XSA8_XS81 0x02 +#define XSA8_XS80 0x01 + + +/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write)) + ----------------------- T1 --------------------- */ + +#define XDL1_XDL17 0x80 +#define XDL1_XDL16 0x40 +#define XDL1_XDL15 0x20 +#define XDL1_XDL14 0x10 +#define XDL1_XDL13 0x08 +#define XDL1_XDL12 0x04 +#define XDL1_XDL11 0x02 +#define XDL1_XDL10 0x01 + +#define XDL2_XDL27 0x80 +#define XDL2_XDL26 0x40 +#define XDL2_XDL25 0x20 +#define XDL2_XDL24 0x10 +#define XDL2_XDL23 0x08 +#define XDL2_XDL22 0x04 +#define XDL2_XDL21 0x02 +#define XDL2_XDL20 0x01 + +#define XDL3_XDL37 0x80 +#define XDL3_XDL36 0x40 +#define XDL3_XDL35 0x20 +#define XDL3_XDL34 0x10 +#define XDL3_XDL33 0x08 +#define XDL3_XDL32 0x04 +#define XDL3_XDL31 0x02 +#define XDL3_XDL30 0x01 + + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ E1 ---------------------------- */ + +#define E1_ICB1_IC0 0x80 +#define E1_ICB1_IC1 0x40 +#define E1_ICB1_IC2 0x20 +#define E1_ICB1_IC3 0x10 +#define E1_ICB1_IC4 0x08 +#define E1_ICB1_IC5 0x04 +#define E1_ICB1_IC6 0x02 +#define E1_ICB1_IC7 0x01 + +#define E1_ICB2_IC8 0x80 +#define E1_ICB2_IC9 0x40 +#define E1_ICB2_IC10 0x20 +#define E1_ICB2_IC11 0x10 +#define E1_ICB2_IC12 0x08 +#define E1_ICB2_IC13 0x04 +#define E1_ICB2_IC14 0x02 +#define E1_ICB2_IC15 0x01 + +#define E1_ICB3_IC16 0x80 +#define E1_ICB3_IC17 0x40 +#define E1_ICB3_IC18 0x20 +#define E1_ICB3_IC19 0x10 +#define E1_ICB3_IC20 0x08 +#define E1_ICB3_IC21 0x04 +#define E1_ICB3_IC22 0x02 +#define E1_ICB3_IC23 0x01 + +#define E1_ICB4_IC24 0x80 +#define E1_ICB4_IC25 0x40 +#define E1_ICB4_IC26 0x20 +#define E1_ICB4_IC27 0x10 +#define E1_ICB4_IC28 0x08 +#define E1_ICB4_IC29 0x04 +#define E1_ICB4_IC30 0x02 +#define E1_ICB4_IC31 0x01 + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ T1 ---------------------------- */ + +#define T1_ICB1_IC1 0x80 +#define T1_ICB1_IC2 0x40 +#define T1_ICB1_IC3 0x20 +#define T1_ICB1_IC4 0x10 +#define T1_ICB1_IC5 0x08 +#define T1_ICB1_IC6 0x04 +#define T1_ICB1_IC7 0x02 +#define T1_ICB1_IC8 0x01 + +#define T1_ICB2_IC9 0x80 +#define T1_ICB2_IC10 0x40 +#define T1_ICB2_IC11 0x20 +#define T1_ICB2_IC12 0x10 +#define T1_ICB2_IC13 0x08 +#define T1_ICB2_IC14 0x04 +#define T1_ICB2_IC15 0x02 +#define T1_ICB2_IC16 0x01 + +#define T1_ICB3_IC17 0x80 +#define T1_ICB3_IC18 0x40 +#define T1_ICB3_IC19 0x20 +#define T1_ICB3_IC20 0x10 +#define T1_ICB3_IC21 0x08 +#define T1_ICB3_IC22 0x04 +#define T1_ICB3_IC23 0x02 +#define T1_ICB3_IC24 0x01 + +/* FMR3 (Framer Mode Register 3) + --------------------E1------------------------ */ + +#define FMR3_CMI 0x08 +#define FMR3_SYNSA 0x04 +#define FMR3_CFRZ 0x02 +#define FMR3_EXTIW 0x01 + + + +/* CCB1-3 (Clear Channel Register) + ------------------- T1 ----------------------- */ + +#define CCB1_CH1 0x80 +#define CCB1_CH2 0x40 +#define CCB1_CH3 0x20 +#define CCB1_CH4 0x10 +#define CCB1_CH5 0x08 +#define CCB1_CH6 0x04 +#define CCB1_CH7 0x02 +#define CCB1_CH8 0x01 + +#define CCB2_CH9 0x80 +#define CCB2_CH10 0x40 +#define CCB2_CH11 0x20 +#define CCB2_CH12 0x10 +#define CCB2_CH13 0x08 +#define CCB2_CH14 0x04 +#define CCB2_CH15 0x02 +#define CCB2_CH16 0x01 + +#define CCB3_CH17 0x80 +#define CCB3_CH18 0x40 +#define CCB3_CH19 0x20 +#define CCB3_CH20 0x10 +#define CCB3_CH21 0x08 +#define CCB3_CH22 0x04 +#define CCB3_CH23 0x02 +#define CCB3_CH24 0x01 + + +/* LIM0/1 (Line Interface Mode 0/1) + ------------------- E1 & T1 --------------------------- */ + +#define LIM0_XFB 0x80 +#define LIM0_XDOS 0x40 +#define LIM0_SCL1 0x20 +#define LIM0_SCL0 0x10 +#define LIM0_EQON 0x08 +#define LIM0_ELOS 0x04 +#define LIM0_LL 0x02 +#define LIM0_MAS 0x01 + +#define LIM1_EFSC 0x80 +#define LIM1_RIL2 0x40 +#define LIM1_RIL1 0x20 +#define LIM1_RIL0 0x10 +#define LIM1_DCOC 0x08 +#define LIM1_JATT 0x04 +#define LIM1_RL 0x02 +#define LIM1_DRS 0x01 + + +/* PCDR (Pulse Count Detection Register(Read/Write)) + ------------------ E1 & T1 ------------------------- */ + +#define PCDR_PCD7 0x80 +#define PCDR_PCD6 0x40 +#define PCDR_PCD5 0x20 +#define PCDR_PCD4 0x10 +#define PCDR_PCD3 0x08 +#define PCDR_PCD2 0x04 +#define PCDR_PCD1 0x02 +#define PCDR_PCD0 0x01 + +#define PCRR_PCR7 0x80 +#define PCRR_PCR6 0x40 +#define PCRR_PCR5 0x20 +#define PCRR_PCR4 0x10 +#define PCRR_PCR3 0x08 +#define PCRR_PCR2 0x04 +#define PCRR_PCR1 0x02 +#define PCRR_PCR0 0x01 + + +/* LIM2 (Line Interface Mode 2) + + ------------------ E1 & T1 ---------------------------- */ + +#define LIM2_DJA2 0x20 +#define LIM2_DJA1 0x10 +#define LIM2_LOS2 0x02 +#define LIM2_LOS1 0x01 + +/* LCR1 (Loop Code Register 1) */ + +#define LCR1_EPRM 0x80 +#define LCR1_XPRBS 0x40 + +/* SIC1 (System Interface Control 1) */ +#define SIC1_SRSC 0x80 +#define SIC1_RBS1 0x20 +#define SIC1_RBS0 0x10 +#define SIC1_SXSC 0x08 +#define SIC1_XBS1 0x02 +#define SIC1_XBS0 0x01 + +/* DEC (Disable Error Counter) + ------------------ E1 & T1 ---------------------------- */ + +#define DEC_DCEC3 0x20 +#define DEC_DBEC 0x10 +#define DEC_DCEC1 0x08 +#define DEC_DCEC 0x08 +#define DEC_DEBC 0x04 +#define DEC_DCVC 0x02 +#define DEC_DFEC 0x01 + + +/* FALC Register Bits (Receive Mode) + ---------------------------------------------------------------------------- */ + + +/* FRS0/1 (Framer Receive Status Register 0/1) + ----------------- E1 & T1 ---------------------------------- */ + +#define FRS0_LOS 0x80 +#define FRS0_AIS 0x40 +#define FRS0_LFA 0x20 +#define FRS0_RRA 0x10 +#define FRS0_API 0x08 +#define FRS0_NMF 0x04 +#define FRS0_LMFA 0x02 +#define FRS0_FSRF 0x01 + +#define FRS1_TS16RA 0x40 +#define FRS1_TS16LOS 0x20 +#define FRS1_TS16AIS 0x10 +#define FRS1_TS16LFA 0x08 +#define FRS1_EXZD 0x80 +#define FRS1_LLBDD 0x10 +#define FRS1_LLBAD 0x08 +#define FRS1_XLS 0x02 +#define FRS1_XLO 0x01 +#define FRS1_PDEN 0x40 + +/* FRS2/3 (Framer Receive Status Register 2/3) + ----------------- T1 ---------------------------------- */ + +#define FRS2_ESC2 0x80 +#define FRS2_ESC1 0x40 +#define FRS2_ESC0 0x20 + +#define FRS3_FEH5 0x20 +#define FRS3_FEH4 0x10 +#define FRS3_FEH3 0x08 +#define FRS3_FEH2 0x04 +#define FRS3_FEH1 0x02 +#define FRS3_FEH0 0x01 + + +/* RSW (Receive Service Word Pulseframe) + ----------------- E1 ------------------------------ */ + +#define RSW_RSI 0x80 +#define RSW_RRA 0x20 +#define RSW_RYO 0x10 +#define RSW_RY1 0x08 +#define RSW_RY2 0x04 +#define RSW_RY3 0x02 +#define RSW_RY4 0x01 + + +/* RSP (Receive Spare Bits / Additional Status) + ---------------- E1 ------------------------------- */ + +#define RSP_SI1 0x80 +#define RSP_SI2 0x40 +#define RSP_LLBDD 0x10 +#define RSP_LLBAD 0x08 +#define RSP_RSIF 0x04 +#define RSP_RS13 0x02 +#define RSP_RS15 0x01 + + +/* FECL (Framing Error Counter) + ---------------- E1 & T1 -------------------------- */ + +#define FECL_FE7 0x80 +#define FECL_FE6 0x40 +#define FECL_FE5 0x20 +#define FECL_FE4 0x10 +#define FECL_FE3 0x08 +#define FECL_FE2 0x04 +#define FECL_FE1 0x02 +#define FECL_FE0 0x01 + +#define FECH_FE15 0x80 +#define FECH_FE14 0x40 +#define FECH_FE13 0x20 +#define FECH_FE12 0x10 +#define FECH_FE11 0x08 +#define FECH_FE10 0x04 +#define FECH_FE9 0x02 +#define FECH_FE8 0x01 + + +/* CVCl (Code Violation Counter) + ----------------- E1 ------------------------- */ + +#define CVCL_CV7 0x80 +#define CVCL_CV6 0x40 +#define CVCL_CV5 0x20 +#define CVCL_CV4 0x10 +#define CVCL_CV3 0x08 +#define CVCL_CV2 0x04 +#define CVCL_CV1 0x02 +#define CVCL_CV0 0x01 + +#define CVCH_CV15 0x80 +#define CVCH_CV14 0x40 +#define CVCH_CV13 0x20 +#define CVCH_CV12 0x10 +#define CVCH_CV11 0x08 +#define CVCH_CV10 0x04 +#define CVCH_CV9 0x02 +#define CVCH_CV8 0x01 + + +/* CEC1-3L (CRC Error Counter) + ------------------ E1 ----------------------------- */ + +#define CEC1L_CR7 0x80 +#define CEC1L_CR6 0x40 +#define CEC1L_CR5 0x20 +#define CEC1L_CR4 0x10 +#define CEC1L_CR3 0x08 +#define CEC1L_CR2 0x04 +#define CEC1L_CR1 0x02 +#define CEC1L_CR0 0x01 + +#define CEC1H_CR15 0x80 +#define CEC1H_CR14 0x40 +#define CEC1H_CR13 0x20 +#define CEC1H_CR12 0x10 +#define CEC1H_CR11 0x08 +#define CEC1H_CR10 0x04 +#define CEC1H_CR9 0x02 +#define CEC1H_CR8 0x01 + +#define CEC2L_CR7 0x80 +#define CEC2L_CR6 0x40 +#define CEC2L_CR5 0x20 +#define CEC2L_CR4 0x10 +#define CEC2L_CR3 0x08 +#define CEC2L_CR2 0x04 +#define CEC2L_CR1 0x02 +#define CEC2L_CR0 0x01 + +#define CEC2H_CR15 0x80 +#define CEC2H_CR14 0x40 +#define CEC2H_CR13 0x20 +#define CEC2H_CR12 0x10 +#define CEC2H_CR11 0x08 +#define CEC2H_CR10 0x04 +#define CEC2H_CR9 0x02 +#define CEC2H_CR8 0x01 + +#define CEC3L_CR7 0x80 +#define CEC3L_CR6 0x40 +#define CEC3L_CR5 0x20 +#define CEC3L_CR4 0x10 +#define CEC3L_CR3 0x08 +#define CEC3L_CR2 0x04 +#define CEC3L_CR1 0x02 +#define CEC3L_CR0 0x01 + +#define CEC3H_CR15 0x80 +#define CEC3H_CR14 0x40 +#define CEC3H_CR13 0x20 +#define CEC3H_CR12 0x10 +#define CEC3H_CR11 0x08 +#define CEC3H_CR10 0x04 +#define CEC3H_CR9 0x02 +#define CEC3H_CR8 0x01 + + +/* CECL (CRC Error Counter) + + ------------------ T1 ----------------------------- */ + +#define CECL_CR7 0x80 +#define CECL_CR6 0x40 +#define CECL_CR5 0x20 +#define CECL_CR4 0x10 +#define CECL_CR3 0x08 +#define CECL_CR2 0x04 +#define CECL_CR1 0x02 +#define CECL_CR0 0x01 + +#define CECH_CR15 0x80 +#define CECH_CR14 0x40 +#define CECH_CR13 0x20 +#define CECH_CR12 0x10 +#define CECH_CR11 0x08 +#define CECH_CR10 0x04 +#define CECH_CR9 0x02 +#define CECH_CR8 0x01 + +/* EBCL (E Bit Error Counter) + ------------------- E1 & T1 ------------------------- */ + +#define EBCL_EB7 0x80 +#define EBCL_EB6 0x40 +#define EBCL_EB5 0x20 +#define EBCL_EB4 0x10 +#define EBCL_EB3 0x08 +#define EBCL_EB2 0x04 +#define EBCL_EB1 0x02 +#define EBCL_EB0 0x01 + +#define EBCH_EB15 0x80 +#define EBCH_EB14 0x40 +#define EBCH_EB13 0x20 +#define EBCH_EB12 0x10 +#define EBCH_EB11 0x08 +#define EBCH_EB10 0x04 +#define EBCH_EB9 0x02 +#define EBCH_EB8 0x01 + + +/* RSA4-8 (Receive Sa4-8-Bit Register) + -------------------- E1 --------------------------- */ + +#define RSA4_RS47 0x80 +#define RSA4_RS46 0x40 +#define RSA4_RS45 0x20 +#define RSA4_RS44 0x10 +#define RSA4_RS43 0x08 +#define RSA4_RS42 0x04 +#define RSA4_RS41 0x02 +#define RSA4_RS40 0x01 + +#define RSA5_RS57 0x80 +#define RSA5_RS56 0x40 +#define RSA5_RS55 0x20 +#define RSA5_RS54 0x10 +#define RSA5_RS53 0x08 +#define RSA5_RS52 0x04 +#define RSA5_RS51 0x02 +#define RSA5_RS50 0x01 + +#define RSA6_RS67 0x80 +#define RSA6_RS66 0x40 +#define RSA6_RS65 0x20 +#define RSA6_RS64 0x10 +#define RSA6_RS63 0x08 +#define RSA6_RS62 0x04 +#define RSA6_RS61 0x02 +#define RSA6_RS60 0x01 + +#define RSA7_RS77 0x80 +#define RSA7_RS76 0x40 +#define RSA7_RS75 0x20 +#define RSA7_RS74 0x10 +#define RSA7_RS73 0x08 +#define RSA7_RS72 0x04 +#define RSA7_RS71 0x02 +#define RSA7_RS70 0x01 + +#define RSA8_RS87 0x80 +#define RSA8_RS86 0x40 +#define RSA8_RS85 0x20 +#define RSA8_RS84 0x10 +#define RSA8_RS83 0x08 +#define RSA8_RS82 0x04 +#define RSA8_RS81 0x02 +#define RSA8_RS80 0x01 + +/* RSA6S (Receive Sa6 Bit Status Register) + ------------------------ T1 ------------------------- */ + +#define RSA6S_SX 0x20 +#define RSA6S_SF 0x10 +#define RSA6S_SE 0x08 +#define RSA6S_SC 0x04 +#define RSA6S_SA 0x02 +#define RSA6S_S8 0x01 + + +/* RDL1-3 Receive DL-Bit Register1-3) + ------------------------ T1 ------------------------- */ + +#define RDL1_RDL17 0x80 +#define RDL1_RDL16 0x40 +#define RDL1_RDL15 0x20 +#define RDL1_RDL14 0x10 +#define RDL1_RDL13 0x08 +#define RDL1_RDL12 0x04 +#define RDL1_RDL11 0x02 +#define RDL1_RDL10 0x01 + +#define RDL2_RDL27 0x80 +#define RDL2_RDL26 0x40 +#define RDL2_RDL25 0x20 +#define RDL2_RDL24 0x10 +#define RDL2_RDL23 0x08 +#define RDL2_RDL22 0x04 +#define RDL2_RDL21 0x02 +#define RDL2_RDL20 0x01 + +#define RDL3_RDL37 0x80 +#define RDL3_RDL36 0x40 +#define RDL3_RDL35 0x20 +#define RDL3_RDL34 0x10 +#define RDL3_RDL33 0x08 +#define RDL3_RDL32 0x04 +#define RDL3_RDL31 0x02 +#define RDL3_RDL30 0x01 + + +/* SIS (Signaling Status Register) + + -------------------- E1 & T1 -------------------------- */ + +#define SIS_XDOV 0x80 +#define SIS_XFW 0x40 +#define SIS_XREP 0x20 +#define SIS_RLI 0x08 +#define SIS_CEC 0x04 +#define SIS_BOM 0x01 + + +/* RSIS (Receive Signaling Status Register) + + -------------------- E1 & T1 --------------------------- */ + +#define RSIS_VFR 0x80 +#define RSIS_RDO 0x40 +#define RSIS_CRC16 0x20 +#define RSIS_RAB 0x10 +#define RSIS_HA1 0x08 +#define RSIS_HA0 0x04 +#define RSIS_HFR 0x02 +#define RSIS_LA 0x01 + + +/* RBCL/H (Receive Byte Count Low/High) + + ------------------- E1 & T1 ----------------------- */ + +#define RBCL_RBC7 0x80 +#define RBCL_RBC6 0x40 +#define RBCL_RBC5 0x20 +#define RBCL_RBC4 0x10 +#define RBCL_RBC3 0x08 +#define RBCL_RBC2 0x04 +#define RBCL_RBC1 0x02 +#define RBCL_RBC0 0x01 + +#define RBCH_OV 0x10 +#define RBCH_RBC11 0x08 +#define RBCH_RBC10 0x04 +#define RBCH_RBC9 0x02 +#define RBCH_RBC8 0x01 + + +/* ISR1-3 (Interrupt Status Register 1-3) + + ------------------ E1 & T1 ------------------------------ */ + +#define FISR0_RME 0x80 +#define FISR0_RFS 0x40 +#define FISR0_T8MS 0x20 +#define FISR0_ISF 0x20 +#define FISR0_RMB 0x10 +#define FISR0_CASC 0x08 +#define FISR0_RSC 0x08 +#define FISR0_CRC6 0x04 +#define FISR0_CRC4 0x04 +#define FISR0_PDEN 0x02 +#define FISR0_RPF 0x01 + +#define FISR1_CASE 0x80 +#define FISR1_LLBSC 0x80 +#define FISR1_RDO 0x40 +#define FISR1_ALLS 0x20 +#define FISR1_XDU 0x10 +#define FISR1_XMB 0x08 +#define FISR1_XLSC 0x02 +#define FISR1_XPR 0x01 + +#define FISR2_FAR 0x80 +#define FISR2_LFA 0x40 +#define FISR2_MFAR 0x20 +#define FISR2_T400MS 0x10 +#define FISR2_LMFA 0x10 +#define FISR2_AIS 0x08 +#define FISR2_LOS 0x04 +#define FISR2_RAR 0x02 +#define FISR2_RA 0x01 + +#define FISR3_ES 0x80 +#define FISR3_SEC 0x40 +#define FISR3_LMFA16 0x20 +#define FISR3_AIS16 0x10 +#define FISR3_RA16 0x08 +#define FISR3_API 0x04 +#define FISR3_XSLP 0x20 +#define FISR3_XSLN 0x10 +#define FISR3_LLBSC 0x08 +#define FISR3_XRS 0x04 +#define FISR3_SLN 0x02 +#define FISR3_SLP 0x01 + + +/* GIS (Global Interrupt Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define GIS_ISR3 0x08 +#define GIS_ISR2 0x04 +#define GIS_ISR1 0x02 +#define GIS_ISR0 0x01 + + +/* VSTR (Version Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define VSTR_VN3 0x08 +#define VSTR_VN2 0x04 +#define VSTR_VN1 0x02 +#define VSTR_VN0 0x01 + + +/*>>>>>>>>>>>>>>>>>>>>> Local Control Structures <<<<<<<<<<<<<<<<<<<<<<<<< */ + +/* Write-only Registers (E1/T1 control mode write registers) */ +#define XFIFOH 0x00 /* Tx FIFO High Byte */ +#define XFIFOL 0x01 /* Tx FIFO Low Byte */ +#define CMDR 0x02 /* Command Reg */ +#define DEC 0x60 /* Disable Error Counter */ +#define TEST2 0x62 /* Manuf. Test Reg 2 */ +#define XS(nbr) (0x70 + (nbr)) /* Tx CAS Reg (0 to 15) */ + +/* Read-write Registers (E1/T1 status mode read registers) */ +#define MODE 0x03 /* Mode Reg */ +#define RAH1 0x04 /* Receive Address High 1 */ +#define RAH2 0x05 /* Receive Address High 2 */ +#define RAL1 0x06 /* Receive Address Low 1 */ +#define RAL2 0x07 /* Receive Address Low 2 */ +#define IPC 0x08 /* Interrupt Port Configuration */ +#define CCR1 0x09 /* Common Configuration Reg 1 */ +#define CCR3 0x0A /* Common Configuration Reg 3 */ +#define PRE 0x0B /* Preamble Reg */ +#define RTR1 0x0C /* Receive Timeslot Reg 1 */ +#define RTR2 0x0D /* Receive Timeslot Reg 2 */ +#define RTR3 0x0E /* Receive Timeslot Reg 3 */ +#define RTR4 0x0F /* Receive Timeslot Reg 4 */ +#define TTR1 0x10 /* Transmit Timeslot Reg 1 */ +#define TTR2 0x11 /* Transmit Timeslot Reg 2 */ +#define TTR3 0x12 /* Transmit Timeslot Reg 3 */ +#define TTR4 0x13 /* Transmit Timeslot Reg 4 */ +#define IMR0 0x14 /* Interrupt Mask Reg 0 */ +#define IMR1 0x15 /* Interrupt Mask Reg 1 */ +#define IMR2 0x16 /* Interrupt Mask Reg 2 */ +#define IMR3 0x17 /* Interrupt Mask Reg 3 */ +#define IMR4 0x18 /* Interrupt Mask Reg 4 */ +#define IMR5 0x19 /* Interrupt Mask Reg 5 */ +#define FMR0 0x1A /* Framer Mode Reigster 0 */ +#define FMR1 0x1B /* Framer Mode Reigster 1 */ +#define FMR2 0x1C /* Framer Mode Reigster 2 */ +#define LOOP 0x1D /* Channel Loop Back */ +#define XSW 0x1E /* Transmit Service Word */ +#define FMR4 0x1E /* Framer Mode Reg 4 */ +#define XSP 0x1F /* Transmit Spare Bits */ +#define FMR5 0x1F /* Framer Mode Reg 5 */ +#define XC0 0x20 /* Transmit Control 0 */ +#define XC1 0x21 /* Transmit Control 1 */ +#define RC0 0x22 /* Receive Control 0 */ +#define RC1 0x23 /* Receive Control 1 */ +#define XPM0 0x24 /* Transmit Pulse Mask 0 */ +#define XPM1 0x25 /* Transmit Pulse Mask 1 */ +#define XPM2 0x26 /* Transmit Pulse Mask 2 */ +#define TSWM 0x27 /* Transparent Service Word Mask */ +#define TEST1 0x28 /* Manuf. Test Reg 1 */ +#define IDLE 0x29 /* Idle Channel Code */ +#define XSA4 0x2A /* Transmit SA4 Bit Reg */ +#define XDL1 0x2A /* Transmit DL-Bit Reg 2 */ +#define XSA5 0x2B /* Transmit SA4 Bit Reg */ +#define XDL2 0x2B /* Transmit DL-Bit Reg 2 */ +#define XSA6 0x2C /* Transmit SA4 Bit Reg */ +#define XDL3 0x2C /* Transmit DL-Bit Reg 2 */ +#define XSA7 0x2D /* Transmit SA4 Bit Reg */ +#define CCB1 0x2D /* Clear Channel Reg 1 */ +#define XSA8 0x2E /* Transmit SA4 Bit Reg */ +#define CCB2 0x2E /* Clear Channel Reg 2 */ +#define FMR3 0x2F /* Framer Mode Reg. 3 */ +#define CCB3 0x2F /* Clear Channel Reg 3 */ +#define ICB1 0x30 /* Idle Channel Reg 1 */ +#define ICB2 0x31 /* Idle Channel Reg 2 */ +#define ICB3 0x32 /* Idle Channel Reg 3 */ +#define ICB4 0x33 /* Idle Channel Reg 4 */ +#define LIM0 0x34 /* Line Interface Mode 0 */ +#define LIM1 0x35 /* Line Interface Mode 1 */ +#define PCDR 0x36 /* Pulse Count Detection */ +#define PCRR 0x37 /* Pulse Count Recovery */ +#define LIM2 0x38 /* Line Interface Mode Reg 2 */ +#define LCR1 0x39 /* Loop Code Reg 1 */ +#define LCR2 0x3A /* Loop Code Reg 2 */ +#define LCR3 0x3B /* Loop Code Reg 3 */ +#define SIC1 0x3C /* System Interface Control 1 */ + +/* Read-only Registers (E1/T1 control mode read registers) */ +#define RFIFOH 0x00 /* Receive FIFO */ +#define RFIFOL 0x01 /* Receive FIFO */ +#define FRS0 0x4C /* Framer Receive Status 0 */ +#define FRS1 0x4D /* Framer Receive Status 1 */ +#define RSW 0x4E /* Receive Service Word */ +#define FRS2 0x4E /* Framer Receive Status 2 */ +#define RSP 0x4F /* Receive Spare Bits */ +#define FRS3 0x4F /* Framer Receive Status 3 */ +#define FECL 0x50 /* Framing Error Counter */ +#define FECH 0x51 /* Framing Error Counter */ +#define CVCL 0x52 /* Code Violation Counter */ +#define CVCH 0x53 /* Code Violation Counter */ +#define CECL 0x54 /* CRC Error Counter 1 */ +#define CECH 0x55 /* CRC Error Counter 1 */ +#define EBCL 0x56 /* E-Bit Error Counter */ +#define EBCH 0x57 /* E-Bit Error Counter */ +#define BECL 0x58 /* Bit Error Counter Low */ +#define BECH 0x59 /* Bit Error Counter Low */ +#define CEC3 0x5A /* CRC Error Counter 3 (16-bit) */ +#define RSA4 0x5C /* Receive SA4 Bit Reg */ +#define RDL1 0x5C /* Receive DL-Bit Reg 1 */ +#define RSA5 0x5D /* Receive SA5 Bit Reg */ +#define RDL2 0x5D /* Receive DL-Bit Reg 2 */ +#define RSA6 0x5E /* Receive SA6 Bit Reg */ +#define RDL3 0x5E /* Receive DL-Bit Reg 3 */ +#define RSA7 0x5F /* Receive SA7 Bit Reg */ +#define RSA8 0x60 /* Receive SA8 Bit Reg */ +#define RSA6S 0x61 /* Receive SA6 Bit Status Reg */ +#define TSR0 0x62 /* Manuf. Test Reg 0 */ +#define TSR1 0x63 /* Manuf. Test Reg 1 */ +#define SIS 0x64 /* Signaling Status Reg */ +#define RSIS 0x65 /* Receive Signaling Status Reg */ +#define RBCL 0x66 /* Receive Byte Control */ +#define RBCH 0x67 /* Receive Byte Control */ +#define FISR0 0x68 /* Interrupt Status Reg 0 */ +#define FISR1 0x69 /* Interrupt Status Reg 1 */ +#define FISR2 0x6A /* Interrupt Status Reg 2 */ +#define FISR3 0x6B /* Interrupt Status Reg 3 */ +#define GIS 0x6E /* Global Interrupt Status */ +#define VSTR 0x6F /* Version Status */ +#define RS(nbr) (0x70 + (nbr)) /* Rx CAS Reg (0 to 15) */ + +#endif /* _FALC_LH_H */ + diff -urN linux-2.4.24/drivers/net/wan/pc300_tty.c linux-2.4.25/drivers/net/wan/pc300_tty.c --- linux-2.4.24/drivers/net/wan/pc300_tty.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/pc300_tty.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1117 @@ +/* + * pc300_tty.c Cyclades-PC300(tm) TTY Driver. + * + * Author: Regina Kodato + * Maintainer: PC300 Maintainer + * + * Copyright: (c) 1999-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* TTY includes */ +#include +#include +#include + +#include "pc300.h" + +/* defines and macros */ +/* TTY Global definitions */ +#define CPC_TTY_NPORTS 8 /* maximum number of the sync tty connections */ +#define CPC_TTY_MAJOR CYCLADES_MAJOR +#define CPC_TTY_MINOR_START 240 /* minor of the first PC300 interface */ + +#define CPC_TTY_MAX_MTU 2000 + +/* tty interface state */ +#define CPC_TTY_ST_IDLE 0 +#define CPC_TTY_ST_INIT 1 /* configured with MLPPP and up */ +#define CPC_TTY_ST_OPEN 2 /* opened by application */ + +#define CPC_TTY_LOCK(card,flags)\ + do {\ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_TTY_UNLOCK(card,flags) \ + do {\ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +//#define CPC_TTY_DBG(format,a...) printk(format,##a) +#define CPC_TTY_DBG(format,a...) + +/* data structures */ +typedef struct _st_cpc_rx_buf { + struct _st_cpc_rx_buf *next; + int size; + unsigned char data[1]; +} st_cpc_rx_buf; + +struct st_cpc_rx_list { + st_cpc_rx_buf *first; + st_cpc_rx_buf *last; +}; + +typedef struct _st_cpc_tty_area { + int state; /* state of the TTY interface */ + int num_open; + unsigned int tty_minor; /* minor this interface */ + volatile struct st_cpc_rx_list buf_rx; /* ptr. to reception buffer */ + unsigned char* buf_tx; /* ptr. to transmission buffer */ + pc300dev_t* pc300dev; /* ptr. to info struct in PC300 driver */ + unsigned char name[20]; /* interf. name + "-tty" */ + struct tty_struct *tty; + struct tq_struct tty_tx_task_queue; /* tx task - tx interrupt */ + struct tq_struct tty_rx_task_queue; /* rx task - rx interrupt */ + } st_cpc_tty_area; + +/* TTY data structures */ +static struct tty_struct *cpc_tty_serial_table[CPC_TTY_NPORTS]; +static struct termios *cpc_tty_serial_termios[CPC_TTY_NPORTS]; +static struct termios *cpc_tty_serial_termios_locked[CPC_TTY_NPORTS]; +static struct tty_driver serial_drv, callout_drv; + +/* local variables */ +st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS]; + +int cpc_tty_cnt=0; /* number of intrfaces configured with MLPPP */ +int cpc_tty_refcount; +int cpc_tty_unreg_flag = 0; + +/* TTY functions prototype */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip); +static void cpc_tty_close(struct tty_struct *tty, struct file *flip); +static int cpc_tty_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count); +static int cpc_tty_write_room(struct tty_struct *tty); +static int cpc_tty_chars_in_buffer(struct tty_struct *tty); +static int cpc_tty_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +static void cpc_tty_flush_buffer(struct tty_struct *tty); +static void cpc_tty_hangup(struct tty_struct *tty); +static void cpc_tty_rx_task(void *data); +static void cpc_tty_tx_task(void *data); +static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); +static void cpc_tty_dtr_off(pc300dev_t *pc300dev); +static void cpc_tty_dtr_on(pc300dev_t *pc300dev); + +/* functions called by PC300 driver */ +void cpc_tty_init(pc300dev_t *dev); +void cpc_tty_unregister_service(pc300dev_t *pc300dev); +void cpc_tty_receive(pc300dev_t *pc300dev); +void cpc_tty_trigger_poll(pc300dev_t *pc300dev); +void cpc_tty_reset_var(void); + +/* + * PC300 TTY clear DTR signal + */ +static void cpc_tty_dtr_off(pc300dev_t *pc300dev) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Clear signal DTR\n", + ((struct net_device*)(pc300dev->hdlc))->name); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& CTL_DTR); + CPC_TTY_UNLOCK(card,flags); +} + +/* + * PC300 TTY set DTR signal to ON + */ +static void cpc_tty_dtr_on(pc300dev_t *pc300dev) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Set signal DTR\n", + ((struct net_device*)(pc300dev->hdlc))->name); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~CTL_DTR); + CPC_TTY_UNLOCK(card,flags); +} + +/* + * PC300 TTY initialization routine + * + * This routine is called by the PC300 driver during board configuration + * (ioctl=SIOCSP300CONF). At this point the adapter is completely + * initialized. + * o verify kernel version (only 2.4.x) + * o register TTY driver + * o init cpc_tty_area struct + */ +void cpc_tty_init(pc300dev_t *pc300dev) +{ + int port, aux; + st_cpc_tty_area * cpc_tty; + + /* hdlcX - X=interface number */ + port = ((struct net_device*)(pc300dev->hdlc))->name[4] - '0'; + if (port >= CPC_TTY_NPORTS) { + printk("%s-tty: invalid interface selected (0-%i): %i", + ((struct net_device*)(pc300dev->hdlc))->name, + CPC_TTY_NPORTS-1,port); + return; + } + + if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */ + CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n", + ((struct net_device*)(pc300dev->hdlc))->name, + CPC_TTY_MAJOR, CPC_TTY_MINOR_START, + CPC_TTY_MINOR_START+CPC_TTY_NPORTS); + /* initialize tty driver struct */ + memset(&serial_drv,0,sizeof(struct tty_driver)); + serial_drv.magic = TTY_DRIVER_MAGIC; + serial_drv.driver_name = "pc300_tty"; + serial_drv.name = "ttyCP"; + serial_drv.major = CPC_TTY_MAJOR; + serial_drv.minor_start = CPC_TTY_MINOR_START; + serial_drv.num = CPC_TTY_NPORTS; + serial_drv.type = TTY_DRIVER_TYPE_SERIAL; + serial_drv.subtype = SERIAL_TYPE_NORMAL; + + serial_drv.init_termios = tty_std_termios; + serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + serial_drv.flags = TTY_DRIVER_REAL_RAW; + serial_drv.refcount = &cpc_tty_refcount; + + /* tty data structures */ + serial_drv.table = cpc_tty_serial_table; + serial_drv.termios = cpc_tty_serial_termios; + serial_drv.termios_locked = cpc_tty_serial_termios_locked; + + /* interface routines from the upper tty layer to the tty driver */ + serial_drv.open = cpc_tty_open; + serial_drv.close = cpc_tty_close; + serial_drv.write = cpc_tty_write; + serial_drv.write_room = cpc_tty_write_room; + serial_drv.chars_in_buffer = cpc_tty_chars_in_buffer; + serial_drv.ioctl = cpc_tty_ioctl; + serial_drv.flush_buffer = cpc_tty_flush_buffer; + serial_drv.hangup = cpc_tty_hangup; + + /* the callout device is just like normal device except for major */ + /* number and the subtype code */ + callout_drv = serial_drv; + callout_drv.name = "cucp"; + callout_drv.major = CPC_TTY_MAJOR + 1; + callout_drv.subtype = SERIAL_TYPE_CALLOUT; + callout_drv.read_proc = 0; + callout_drv.proc_entry = 0; + + /* register the TTY driver */ + if (tty_register_driver(&serial_drv)) { + printk("%s-tty: Failed to register serial driver! ", + ((struct net_device*)(pc300dev->hdlc))->name); + return; + } + + if (tty_register_driver(&callout_drv)) { + CPC_TTY_DBG("%s-tty: Failed to register callout driver! ", + ((struct net_device*)(pc300dev->hdlc))->name); + return; + } + memset((void *)cpc_tty_area, 0, + sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS); + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state != CPC_TTY_ST_IDLE) { + CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n", + ((struct net_device*)(pc300dev->hdlc))->name,port); + return; + } + + cpc_tty_cnt++; + cpc_tty->state = CPC_TTY_ST_INIT; + cpc_tty->num_open= 0; + cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; + cpc_tty->pc300dev = pc300dev; + + cpc_tty->tty_tx_task_queue.routine = cpc_tty_tx_task; + cpc_tty->tty_tx_task_queue.data = (void *)cpc_tty; + + cpc_tty->tty_rx_task_queue.routine = cpc_tty_rx_task; + cpc_tty->tty_rx_task_queue.data = (void *) port; + + cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = 0; + + pc300dev->cpc_tty = (void *)cpc_tty; + + aux = strlen(((struct net_device*)(pc300dev->hdlc))->name); + memcpy(cpc_tty->name,((struct net_device*)(pc300dev->hdlc))->name,aux); + memcpy(&cpc_tty->name[aux], "-tty", 5); + + cpc_open((struct net_device *)pc300dev->hdlc); + cpc_tty_dtr_off(pc300dev); + + CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n", + cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); + return; +} + +/* + * PC300 TTY OPEN routine + * + * This routine is called by the tty driver to open the interface + * o verify minor + * o allocate buffer to Rx and Tx + */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip) +{ + int port ; + st_cpc_tty_area *cpc_tty; + + if (!tty) { + return -ENODEV; + } + + port = MINOR(tty->device) - tty->driver.minor_start; + + if ((port < 0) || (port >= CPC_TTY_NPORTS)){ + CPC_TTY_DBG("pc300_tty: open invalid minor %i\n",MINOR(tty->device)); + return -ENODEV; + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state == CPC_TTY_ST_IDLE){ + CPC_TTY_DBG("%s: open - invalid interface, minor=%i\n", + cpc_tty->name, MINOR(tty->device)); + return -ENODEV; + } + + if (cpc_tty->num_open == 0) { /* first open of this tty */ + if (!cpc_tty_area[port].buf_tx){ + cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL); + if (cpc_tty_area[port].buf_tx == 0){ + CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name); + return -ENOMEM; + } + } + + if (cpc_tty_area[port].buf_rx.first) { + unsigned char * aux; + while (cpc_tty_area[port].buf_rx.first) { + aux = (unsigned char *)cpc_tty_area[port].buf_rx.first; + cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next; + kfree(aux); + } + cpc_tty_area[port].buf_rx.first = NULL; + cpc_tty_area[port].buf_rx.last = NULL; + } + + cpc_tty_area[port].state = CPC_TTY_ST_OPEN; + cpc_tty_area[port].tty = tty; + tty->driver_data = &cpc_tty_area[port]; + + cpc_tty_dtr_on(cpc_tty->pc300dev); + } + + cpc_tty->num_open++; + + CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name); + + /* avisar driver PC300 */ + return 0; +} + +/* + * PC300 TTY CLOSE routine + * + * This routine is called by the tty driver to close the interface + * o call close channel in PC300 driver (cpc_closech) + * o free Rx and Tx buffers + */ + +static void cpc_tty_close(struct tty_struct *tty, struct file *flip) +{ + st_cpc_tty_area *cpc_tty; + unsigned long flags; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlx-tty: no TTY in close \n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + if (!cpc_tty->num_open) { + CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name); + return; + } + + if (--cpc_tty->num_open > 0) { + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + return; + } + + cpc_tty_dtr_off(cpc_tty->pc300dev); + + CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags); /* lock irq */ + cpc_tty->tty = NULL; + cpc_tty->state = CPC_TTY_ST_INIT; + CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ + + if (cpc_tty->buf_rx.first) { + unsigned char * aux; + while (cpc_tty->buf_rx.first) { + aux = (unsigned char *)cpc_tty->buf_rx.first; + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree(aux); + } + cpc_tty->buf_rx.first = NULL; + cpc_tty->buf_rx.last = NULL; + } + + if (cpc_tty->buf_tx) { + kfree(cpc_tty->buf_tx); + cpc_tty->buf_tx = NULL; + } + + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + + if (!cpc_tty_refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + if ((res=tty_unregister_driver(&callout_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + return; +} + +/* + * PC300 TTY WRITE routine + * + * This routine is called by the tty driver to write a series of characters + * to the tty device. The characters may come from user or kernel space. + * o verify the DCD signal + * o send characters to board and start the transmission + */ +static int cpc_tty_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan; + pc300_t *card; + int ch; + unsigned long flags; + struct net_device_stats *stats; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY in write\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name); + return -ENODEV; + } + + if (count > CPC_TTY_MAX_MTU) { + CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name); + return -EINVAL; /* frame too big */ + } + + CPC_TTY_DBG("%s: cpc_tty_write %s data len=%i\n",cpc_tty->name, + (from_user)?"from user" : "from kernel",count); + + pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; + stats = &((pc300dev_t*)cpc_tty->pc300dev)->hdlc->stats; + card = (pc300_t *) pc300chan->card; + ch = pc300chan->channel; + + /* verify DCD signal*/ + if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { + /* DCD is OFF */ + CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name); + stats->tx_errors++; + stats->tx_carrier_errors++; + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 *ch))); + } + + CPC_TTY_UNLOCK(card, flags); + + return -EINVAL; + } + + if (from_user) { + unsigned char *buf_tmp; + + buf_tmp = cpc_tty->buf_tx; + if (copy_from_user(buf_tmp, buf, count)) { + /* failed to copy from user */ + CPC_TTY_DBG("%s: error in copy from user\n",cpc_tty->name); + return -EINVAL; + } + + if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*) buf_tmp,count)) { + /* failed to send */ + CPC_TTY_DBG("%s: transmission error\n",cpc_tty->name); + return 0; + } + } else { + if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { + /* failed to send */ + CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name); + return 0; + } + } + return count; +} + +/* + * PC300 TTY Write Room routine + * + * This routine returns the numbers of characteres the tty driver will accept + * for queuing to be written. + * o return MTU + */ +static int cpc_tty_write_room(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + CPC_TTY_DBG("%s: write room\n",cpc_tty->name); + + return CPC_TTY_MAX_MTU; +} + +/* + * PC300 TTY chars in buffer routine + * + * This routine returns the chars number in the transmission buffer + * o returns 0 + */ +static int cpc_tty_chars_in_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + return(0); +} + +/* + * PC300 TTY IOCTL routine + * + * This routine treats TIOCMBIS (set DTR signal) and TIOCMBIC (clear DTR + * signal)IOCTL commands. + */ +static int cpc_tty_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) + +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + CPC_TTY_DBG("%s: IOCTL cmd %x\n",cpc_tty->name,cmd); + + switch (cmd) { + case TIOCMBIS : /* set DTR */ + cpc_tty_dtr_on(cpc_tty->pc300dev); + break; + + case TIOCMBIC: /* clear DTR */ + cpc_tty_dtr_off(cpc_tty->pc300dev); + break; + default : + return -ENOIOCTLCMD; + } + return 0; +} + +/* + * PC300 TTY Flush Buffer routine + * + * This routine resets the transmission buffer + */ +static void cpc_tty_flush_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); + + wake_up_interruptible(&tty->write_wait); + + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ + CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name); + tty->ldisc.write_wakeup(tty); + } + + return; +} + +/* + * PC300 TTY Hangup routine + * + * This routine is called by the tty driver to hangup the interface + * o clear DTR signal + */ + +static void cpc_tty_hangup(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n"); + return ; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return ; + } + if (!cpc_tty_refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + if ((res=tty_unregister_driver(&callout_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + cpc_tty_dtr_off(cpc_tty->pc300dev); +} + +/* + * PC300 TTY RX task routine + * This routine treats RX task + * o verify read buffer + * o call the line disc. read + * o free memory + */ +static void cpc_tty_rx_task(void * data) +{ + int port, i, j; + st_cpc_tty_area *cpc_tty; + volatile st_cpc_rx_buf * buf; + char flags=0,flg_rx=1; + + if (cpc_tty_cnt == 0) return; + + for (i=0; (i < 4) && flg_rx ; i++) { + flg_rx = 0; + port = (int) data; + for (j=0; j < CPC_TTY_NPORTS; j++) { + cpc_tty = &cpc_tty_area[port]; + + if ((buf=cpc_tty->buf_rx.first) != 0) { + + if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { + CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); + cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, buf->data, + &flags, buf->size); + } + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree((unsigned char *)buf); + buf = cpc_tty->buf_rx.first; + flg_rx = 1; + } + if (++port == CPC_TTY_NPORTS) port = 0; + } + } +} + +/* + * PC300 TTY RX task routine + * + * This routine treats RX interrupt. + * o read all frames in card + * o verify the frame size + * o read the frame in rx buffer + */ +static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan) +{ + volatile pcsca_bd_t * ptdescr; + volatile unsigned char status; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + + /* dma buf read */ + ptdescr = (pcsca_bd_t *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { + status = cpc_readb(&ptdescr->status); + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; /* end of message */ + } + ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next)); + } +} + +void cpc_tty_receive(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + volatile pcsca_bd_t * ptdescr; + struct net_device_stats *stats = &pc300dev->hdlc->stats; + int rx_len, rx_aux; + volatile unsigned char status; + unsigned short first_bd = pc300chan->rx_first_bd; + st_cpc_rx_buf *new; + unsigned char dsr_rx; + + if (pc300dev->cpc_tty == NULL) { + return; + } + + dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch)); + + cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; + + while (1) { + rx_len = 0; + ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_len += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; + } + ptdescr=(pcsca_bd_t*)(card->hw.rambase+cpc_readl(&ptdescr->next)); + } + + if (!rx_len) { + if (dsr_rx & DSR_BOF) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + return; + } + + if (rx_len > CPC_TTY_MAX_MTU) { + /* Free RX descriptors */ + CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name); + stats->rx_errors++; + stats->rx_frame_errors++; + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + new = (st_cpc_rx_buf *) kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); + if (new == 0) { + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + /* dma buf read */ + ptdescr = (pcsca_bd_t *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + + rx_len = 0; /* counter frame size */ + + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_aux = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) + || (rx_aux > BD_DEF_LEN)) { + CPC_TTY_DBG("%s: reception error\n", cpc_tty->name); + stats->rx_errors++; + if (status & DST_OVR) { + stats->rx_fifo_errors++; + } + if (status & DST_CRC) { + stats->rx_crc_errors++; + } + if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) || + (rx_aux > BD_DEF_LEN)) { + stats->rx_frame_errors++; + } + /* discard remainig descriptors used by the bad frame */ + CPC_TTY_DBG("%s: reception error - discard descriptors", + cpc_tty->name); + cpc_tty_rx_disc_frame(pc300chan); + rx_len = 0; + kfree((unsigned char *)new); + break; /* read next frame - while(1) */ + } + + if (cpc_tty->state != CPC_TTY_ST_OPEN) { + /* Free RX descriptors */ + cpc_tty_rx_disc_frame(pc300chan); + stats->rx_dropped++; + rx_len = 0; + kfree((unsigned char *)new); + break; /* read next frame - while(1) */ + } + + /* read the segment of the frame */ + if (rx_aux != 0) { + memcpy_fromio((new->data + rx_len), + (void *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), rx_aux); + rx_len += rx_aux; + } + cpc_writeb(&ptdescr->status,0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF -1); + if (status & DST_EOM)break; + + ptdescr = (pcsca_bd_t *) (card->hw.rambase + + cpc_readl(&ptdescr->next)); + } + /* update pointer */ + pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & + (N_DMA_RX_BUF - 1) ; + if (!(dsr_rx & DSR_BOF)) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + if (rx_len != 0) { + stats->rx_bytes += rx_len; + + if (pc300dev->trace_on) { + cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); + } + new->size = rx_len; + new->next = 0; + if (cpc_tty->buf_rx.first == 0) { + cpc_tty->buf_rx.first = new; + cpc_tty->buf_rx.last = new; + } else { + cpc_tty->buf_rx.last->next = new; + cpc_tty->buf_rx.last = new; + } + schedule_task(&(cpc_tty->tty_rx_task_queue)); + stats->rx_packets++; + } + } +} + +/* + * PC300 TTY TX task routine + * + * This routine treats TX interrupt. + * o if need call line discipline wakeup + * o call wake_up_interruptible + */ +static void cpc_tty_tx_task(void *data) +{ + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data; + struct tty_struct *tty; + + CPC_TTY_DBG("%s: cpc_tty_tx_task init\n",cpc_tty->name); + + if ((tty = cpc_tty->tty) == 0) { + CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); + return; + } + + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ + CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name); + tty->ldisc.write_wakeup (tty); + } + + wake_up_interruptible(&tty->write_wait); +} + +/* + * PC300 TTY send to card routine + * + * This routine send data to card. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ +static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + struct net_device_stats *stats = &dev->hdlc->stats; + unsigned long flags; + volatile pcsca_bd_t * ptdescr; + int i, nchar; + int tosend = len; + int nbuf = ((len - 1)/BD_DEF_LEN) + 1; + unsigned char *pdata=buf; + + CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", + (st_cpc_tty_area *)dev->cpc_tty->name,len); + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return 1; + } + + /* write buffer to DMA buffers */ + CPC_TTY_DBG("%s: call dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + for (i = 0 ; i < nbuf ; i++) { + ptdescr = (pcsca_bd_t *)(card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN; + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((void *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), + &pdata[len - tosend], + nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + cpc_writew(&ptdescr->len, nchar); + } else { + CPC_TTY_DBG("%s: error in dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + stats->tx_dropped++; + return 1; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + + if (dev->trace_on) { + cpc_tty_trace(dev, buf, len,'T'); + } + + /* start transmission */ + CPC_TTY_DBG("%s: start transmission\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_TTY_UNLOCK(card, flags); + return 0; +} + +/* + * PC300 TTY trace routine + * + * This routine send trace of connection to application. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ + +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + len)) == NULL) { + /* out of memory */ + CPC_TTY_DBG("%s: tty_trace - out of memory\n", + ((struct net_device *)(dev->hdlc))->name); + return; + } + + skb_put (skb, 10 + len); + skb->dev = (struct net_device *) dev->hdlc; + skb->protocol = htons(ETH_P_CUST); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_HOST; + skb->len = 10 + len; + + memcpy(skb->data,((struct net_device *)(dev->hdlc))->name,5); + skb->data[5] = '['; + skb->data[6] = rxtx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + memcpy(&skb->data[10], buf, len); + netif_rx(skb); +} + +/* + * PC300 TTY unregister service routine + * + * This routine unregister one interface. + */ +void cpc_tty_unregister_service(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + ulong flags; + int res; + + if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == 0) { + CPC_TTY_DBG("%s: interface is not TTY\n", + ((struct net_device *)(pc300dev->hdlc))->name); + return; + } + CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name); + + if (cpc_tty->pc300dev != pc300dev) { + CPC_TTY_DBG("%s: invalid tty ptr=%s\n", + ((struct net_device *)(pc300dev->hdlc))->name, cpc_tty->name); + return; + } + + if (--cpc_tty_cnt == 0) { + if (cpc_tty_refcount) { + CPC_TTY_DBG("%s: unregister is not possible, refcount=%d", + cpc_tty->name, cpc_tty_refcount); + cpc_tty_cnt++; + cpc_tty_unreg_flag = 1; + return; + } else { + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + if ((res=tty_unregister_driver(&callout_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + } + CPC_TTY_LOCK(pc300dev->chan->card,flags); + cpc_tty->tty = NULL; + CPC_TTY_UNLOCK(pc300dev->chan->card, flags); + cpc_tty->tty_minor = 0; + cpc_tty->state = CPC_TTY_ST_IDLE; +} + +/* + * PC300 TTY trigger poll routine + * This routine is called by pc300driver to treats Tx interrupt. + */ +void cpc_tty_trigger_poll(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; + if (!cpc_tty) { + return; + } + schedule_task(&(cpc_tty->tty_tx_task_queue)); +} + +/* + * PC300 TTY reset var routine + * This routine is called by pc300driver to init the TTY area. + */ + +void cpc_tty_reset_var(void) +{ + int i ; + + CPC_TTY_DBG("hdlcX-tty: reset variables\n"); + /* reset the tty_driver structure - serial_drv */ + memset(&serial_drv, 0, sizeof(struct tty_driver)); + memset(&callout_drv, 0, sizeof(struct tty_driver)); + for (i=0; i < CPC_TTY_NPORTS; i++){ + memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); + } +} diff -urN linux-2.4.24/drivers/net/wan/pci200syn.c linux-2.4.25/drivers/net/wan/pci200syn.c --- linux-2.4.24/drivers/net/wan/pci200syn.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/net/wan/pci200syn.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,476 @@ +/* + * Goramo PCI200SYN synchronous serial card driver for Linux + * + * Copyright (C) 2002-2003 Krzysztof Halasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * For information see http://hq.pm.waw.pl/hdlc/ + * + * Sources of information: + * Hitachi HD64572 SCA-II User's Manual + * PLX Technology Inc. PCI9052 Data Book + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hd64572.h" + +static const char* version = "Goramo PCI200SYN driver version: 1.14c"; +static const char* devname = "PCI200SYN"; + +#undef DEBUG_PKT +#define DEBUG_RINGS + +#define PCI200SYN_PLX_SIZE 0x80 /* PLX control window size (128b) */ +#define PCI200SYN_SCA_SIZE 0x400 /* SCA window size (1Kb) */ +#define ALL_PAGES_ALWAYS_MAPPED +#define NEED_DETECT_RAM +#define MAX_TX_BUFFERS 10 + +static int pci_clock_freq = 33000000; +#define CLOCK_BASE pci_clock_freq + +#define PCI_VENDOR_ID_GORAMO 0x10B5 /* uses PLX:9050 ID - this card */ +#define PCI_DEVICE_ID_PCI200SYN 0x9050 /* doesn't have its own ID */ + + +/* + * PLX PCI9052 local configuration and shared runtime registers. + * This structure can be used to access 9052 registers (memory mapped). + */ +typedef struct { + u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ + u32 loc_rom_range; /* 10h : Local ROM Range */ + u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ + u32 loc_rom_base; /* 24h : Local ROM Base */ + u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ + u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */ + u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ + u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ + u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ +}plx9052; + + + +typedef struct port_s { + hdlc_device hdlc; /* HDLC device struct - must be first */ + struct card_s *card; + spinlock_t lock; /* TX lock */ + sync_serial_settings settings; + int rxpart; /* partial frame received, next frame invalid*/ + unsigned short encoding; + unsigned short parity; + u16 rxin; /* rx ring buffer 'in' pointer */ + u16 txin; /* tx ring buffer 'in' and 'last' pointers */ + u16 txlast; + u8 rxs, txs, tmc; /* SCA registers */ + u8 phy_node; /* physical port # - 0 or 1 */ +}port_t; + + + +typedef struct card_s { + u8* rambase; /* buffer memory base (virtual) */ + u8* scabase; /* SCA memory base (virtual) */ + plx9052* plxbase; /* PLX registers memory base (virtual) */ + u16 rx_ring_buffers; /* number of buffers in a ring */ + u16 tx_ring_buffers; + u16 buff_offset; /* offset of first buffer of first channel */ + u8 irq; /* interrupt request level */ + + port_t ports[2]; +}card_t; + + +#define sca_in(reg, card) readb(card->scabase + (reg)) +#define sca_out(value, reg, card) writeb(value, card->scabase + (reg)) +#define sca_inw(reg, card) readw(card->scabase + (reg)) +#define sca_outw(value, reg, card) writew(value, card->scabase + (reg)) +#define sca_inl(reg, card) readl(card->scabase + (reg)) +#define sca_outl(value, reg, card) writel(value, card->scabase + (reg)) + +#define port_to_card(port) (port->card) +#define log_node(port) (port->phy_node) +#define phy_node(port) (port->phy_node) +#define winbase(card) (card->rambase) +#define get_port(card, port) (&card->ports[port]) +#define sca_flush(card) (sca_in(IER0, card)); + +static inline void new_memcpy_toio(char *dest, char *src, int length) +{ + int len; + do { + len = length > 256 ? 256 : length; + memcpy_toio(dest, src, len); + dest += len; + src += len; + length -= len; + readb(dest); + } while (len); +} + +#undef memcpy_toio +#define memcpy_toio new_memcpy_toio + +#include "hd6457x.c" + + +static void pci200_set_iface(port_t *port) +{ + card_t *card = port->card; + u16 msci = get_msci(port); + u8 rxs = port->rxs & CLK_BRG_MASK; + u8 txs = port->txs & CLK_BRG_MASK; + + sca_out(EXS_TES1, (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS, + port_to_card(port)); + switch(port->settings.clock_type) { + case CLOCK_INT: + rxs |= CLK_BRG; /* BRG output */ + txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */ + break; + + case CLOCK_TXINT: + rxs |= CLK_LINE; /* RXC input */ + txs |= CLK_PIN_OUT | CLK_BRG; /* BRG output */ + break; + + case CLOCK_TXFROMRX: + rxs |= CLK_LINE; /* RXC input */ + txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */ + break; + + default: /* EXTernal clock */ + rxs |= CLK_LINE; /* RXC input */ + txs |= CLK_PIN_OUT | CLK_LINE; /* TXC input */ + break; + } + + port->rxs = rxs; + port->txs = txs; + sca_out(rxs, msci + RXS, card); + sca_out(txs, msci + TXS, card); + sca_set_port(port); +} + + + +static int pci200_open(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + port_t *port = hdlc_to_port(hdlc); + + int result = hdlc_open(hdlc); + if (result) + return result; + + MOD_INC_USE_COUNT; + sca_open(hdlc); + pci200_set_iface(port); + sca_flush(port_to_card(port)); + return 0; +} + + + +static int pci200_close(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + sca_close(hdlc); + sca_flush(port_to_card(dev_to_port(dev))); + hdlc_close(hdlc); + MOD_DEC_USE_COUNT; + return 0; +} + + + +static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync; + hdlc_device *hdlc = dev_to_hdlc(dev); + port_t *port = hdlc_to_port(hdlc); + +#ifdef DEBUG_RINGS + if (cmd == SIOCDEVPRIVATE) { + sca_dump_rings(hdlc); + return 0; + } +#endif + if (cmd != SIOCWANDEV) + return hdlc_ioctl(dev, ifr, cmd); + + switch(ifr->ifr_settings.type) { + case IF_GET_IFACE: + ifr->ifr_settings.type = IF_IFACE_V35; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + if (copy_to_user(line, &port->settings, size)) + return -EFAULT; + return 0; + + case IF_IFACE_V35: + case IF_IFACE_SYNC_SERIAL: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (copy_from_user(&new_line, line, size)) + return -EFAULT; + + if (new_line.clock_type != CLOCK_EXT && + new_line.clock_type != CLOCK_TXFROMRX && + new_line.clock_type != CLOCK_INT && + new_line.clock_type != CLOCK_TXINT) + return -EINVAL; /* No such clock setting */ + + if (new_line.loopback != 0 && new_line.loopback != 1) + return -EINVAL; + + memcpy(&port->settings, &new_line, size); /* Update settings */ + pci200_set_iface(port); + sca_flush(port_to_card(port)); + return 0; + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + + + +static void pci200_pci_remove_one(struct pci_dev *pdev) +{ + int i; + card_t *card = pci_get_drvdata(pdev); + + for(i = 0; i < 2; i++) + if (card->ports[i].card) + unregister_hdlc_device(&card->ports[i].hdlc); + + if (card->irq) + free_irq(card->irq, card); + + if (card->rambase) + iounmap(card->rambase); + if (card->scabase) + iounmap(card->scabase); + if (card->plxbase) + iounmap(card->plxbase); + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + kfree(card); +} + + + +static int __devinit pci200_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + card_t *card; + u8 rev_id; + u32 *p; + int i; + u32 ramsize; + u32 ramphys; /* buffer memory base */ + u32 scaphys; /* SCA memory base */ + u32 plxphys; /* PLX registers memory base */ + +#ifndef MODULE + static int printed_version; + if (!printed_version++) + printk(KERN_INFO "%s\n", version); +#endif + + i = pci_enable_device(pdev); + if (i) + return i; + + i = pci_request_regions(pdev, "PCI200SYN"); + if (i) { + pci_disable_device(pdev); + return i; + } + + card = kmalloc(sizeof(card_t), GFP_KERNEL); + if (card == NULL) { + printk(KERN_ERR "pci200syn: unable to allocate memory\n"); + pci_release_regions(pdev); + pci_disable_device(pdev); + return -ENOBUFS; + } + memset(card, 0, sizeof(card_t)); + pci_set_drvdata(pdev, card); + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + if (pci_resource_len(pdev, 0) != PCI200SYN_PLX_SIZE || + pci_resource_len(pdev, 2) != PCI200SYN_SCA_SIZE || + pci_resource_len(pdev, 3) < 16384) { + printk(KERN_ERR "pci200syn: invalid card EEPROM parameters\n"); + pci200_pci_remove_one(pdev); + return -EFAULT; + } + + plxphys = pci_resource_start(pdev,0) & PCI_BASE_ADDRESS_MEM_MASK; + card->plxbase = ioremap(plxphys, PCI200SYN_PLX_SIZE); + + scaphys = pci_resource_start(pdev,2) & PCI_BASE_ADDRESS_MEM_MASK; + card->scabase = ioremap(scaphys, PCI200SYN_SCA_SIZE); + + ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK; + card->rambase = ioremap(ramphys, pci_resource_len(pdev,3)); + + if (card->plxbase == NULL || + card->scabase == NULL || + card->rambase == NULL) { + printk(KERN_ERR "pci200syn: ioremap() failed\n"); + pci200_pci_remove_one(pdev); + } + + /* Reset PLX */ + p = &card->plxbase->init_ctrl; + writel(readl(p) | 0x40000000, p); + readl(p); /* Flush the write - do not use sca_flush */ + udelay(1); + + writel(readl(p) & ~0x40000000, p); + readl(p); /* Flush the write - do not use sca_flush */ + udelay(1); + + ramsize = sca_detect_ram(card, card->rambase, + pci_resource_len(pdev, 3)); + + /* number of TX + RX buffers for one port - this is dual port card */ + i = ramsize / (2 * (sizeof(pkt_desc) + HDLC_MAX_MRU)); + card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS); + card->rx_ring_buffers = i - card->tx_ring_buffers; + + card->buff_offset = 2 * sizeof(pkt_desc) * (card->tx_ring_buffers + + card->rx_ring_buffers); + + printk(KERN_INFO "pci200syn: %u KB RAM at 0x%x, IRQ%u, using %u TX +" + " %u RX packets rings\n", ramsize / 1024, ramphys, + pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers); + + if (card->tx_ring_buffers < 1) { + printk(KERN_ERR "pci200syn: RAM test failed\n"); + pci200_pci_remove_one(pdev); + return -EFAULT; + } + + /* Enable interrupts on the PCI bridge */ + p = &card->plxbase->intr_ctrl_stat; + writew(readw(p) | 0x0040, p); + + /* Allocate IRQ */ + if (request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { + printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n", + pdev->irq); + pci200_pci_remove_one(pdev); + return -EBUSY; + } + card->irq = pdev->irq; + + sca_init(card, 0); + + for(i = 0; i < 2; i++) { + port_t *port = &card->ports[i]; + struct net_device *dev = hdlc_to_dev(&port->hdlc); + port->phy_node = i; + + spin_lock_init(&port->lock); + SET_MODULE_OWNER(dev); + dev->irq = card->irq; + dev->mem_start = ramphys; + dev->mem_end = ramphys + ramsize - 1; + dev->tx_queue_len = 50; + dev->do_ioctl = pci200_ioctl; + dev->open = pci200_open; + dev->stop = pci200_close; + port->hdlc.attach = sca_attach; + port->hdlc.xmit = sca_xmit; + port->settings.clock_type = CLOCK_EXT; + if (register_hdlc_device(&port->hdlc)) { + printk(KERN_ERR "pci200syn: unable to register hdlc " + "device\n"); + pci200_pci_remove_one(pdev); + return -ENOBUFS; + } + port->card = card; + sca_init_sync_port(port); /* Set up SCA memory */ + + printk(KERN_INFO "%s: PCI200SYN node %d\n", + hdlc_to_name(&port->hdlc), port->phy_node); + } + + sca_flush(card); + return 0; +} + + + +static struct pci_device_id pci200_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_GORAMO, PCI_DEVICE_ID_PCI200SYN, PCI_ANY_ID, + PCI_ANY_ID, 0, 0, 0 }, + { 0, } +}; + + +static struct pci_driver pci200_pci_driver = { + name: "PCI200SYN", + id_table: pci200_pci_tbl, + probe: pci200_pci_init_one, + remove: pci200_pci_remove_one, +}; + + +static int __init pci200_init_module(void) +{ +#ifdef MODULE + printk(KERN_INFO "%s\n", version); +#endif + if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) { + printk(KERN_ERR "pci200syn: Invalid PCI clock frequency\n"); + return -EINVAL; + } + return pci_module_init(&pci200_pci_driver); +} + + + +static void __exit pci200_cleanup_module(void) +{ + pci_unregister_driver(&pci200_pci_driver); +} + +MODULE_AUTHOR("Krzysztof Halasa "); +MODULE_DESCRIPTION("Goramo PCI200SYN serial port driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(pci, pci200_pci_tbl); +MODULE_PARM(pci_clock_freq, "i"); +MODULE_PARM_DESC(pci_clock_freq, "System PCI clock frequency in Hz"); +EXPORT_NO_SYMBOLS; +module_init(pci200_init_module); +module_exit(pci200_cleanup_module); diff -urN linux-2.4.24/drivers/net/wireless/airo.c linux-2.4.25/drivers/net/wireless/airo.c --- linux-2.4.24/drivers/net/wireless/airo.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/net/wireless/airo.c 2004-02-18 05:36:31.000000000 -0800 @@ -1034,7 +1034,6 @@ #define FLAG_802_11 7 #define FLAG_PENDING_XMIT 9 #define FLAG_PENDING_XMIT11 10 -#define FLAG_PCI 11 #define JOB_MASK 0x1ff0000 #define JOB_DIE 16 #define JOB_XMIT 17 @@ -2476,11 +2475,8 @@ OUT4500( apriv, EVACK, EV_MIC ); #ifdef MICSUPPORT if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { - if (down_trylock(&apriv->sem) != 0) { - set_bit(JOB_MIC, &apriv->flags); - wake_up_interruptible(&apriv->thr_wait); - } else - micinit (apriv); + set_bit(JOB_MIC, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); } #endif } @@ -4642,7 +4638,6 @@ return -ENODEV; pci_set_drvdata(pdev, dev); - set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags); return 0; } @@ -4672,7 +4667,7 @@ #ifdef CONFIG_PCI printk( KERN_INFO "airo: Probing for PCI adapters\n" ); - pci_module_init(&airo_driver); + pci_register_driver(&airo_driver); printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); #endif @@ -4684,22 +4679,15 @@ static void __exit airo_cleanup_module( void ) { - int is_pci = 0; while( airo_devices ) { printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); -#ifdef CONFIG_PCI - if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags)) - is_pci = 1; -#endif stop_airo_card( airo_devices->dev, 1 ); } remove_proc_entry("aironet", proc_root_driver); - if (is_pci) { #ifdef CONFIG_PCI - pci_unregister_driver(&airo_driver); + pci_unregister_driver(&airo_driver); #endif - } } #ifdef WIRELESS_EXT diff -urN linux-2.4.24/drivers/parport/Config.in linux-2.4.25/drivers/parport/Config.in --- linux-2.4.24/drivers/parport/Config.in 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.25/drivers/parport/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -24,13 +24,7 @@ bool ' Use FIFO/DMA if available (EXPERIMENTAL)' CONFIG_PARPORT_PC_FIFO bool ' SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO fi - if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then - if [ "$CONFIG_PARPORT_PC" = "y" ]; then - dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA - else - dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PARPORT_PC - fi - fi + dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA $CONFIG_PARPORT_PC $CONFIG_HOTPLUG fi if [ "$CONFIG_ARM" = "y" ]; then dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT @@ -61,6 +55,12 @@ define_tristate CONFIG_PARPORT_SUNBPP n fi + if [ "$CONFIG_SGI_IP22" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' SGI Indy/Indigo2 hardware (EXPERIMENTAL)' CONFIG_PARPORT_IP22 $CONFIG_PARPORT + else + define_tristate CONFIG_PARPORT_IP22 n + fi + # If exactly one hardware type is selected then parport will optimise away # support for loading any others. Defeat this if the user is keen. bool ' Support foreign hardware' CONFIG_PARPORT_OTHER diff -urN linux-2.4.24/drivers/parport/Makefile linux-2.4.25/drivers/parport/Makefile --- linux-2.4.24/drivers/parport/Makefile 2001-09-13 16:04:43.000000000 -0700 +++ linux-2.4.25/drivers/parport/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -23,12 +23,13 @@ obj-$(CONFIG_PARPORT) += parport.o obj-$(CONFIG_PARPORT_PC) += parport_pc.o obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o -obj-$(CONFIG_PARPORT_PC_PCMCIA)+= parport_cs.o +obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o +obj-$(CONFIG_PARPORT_IP22) += parport_ip22.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.24/drivers/parport/parport_ip22.c linux-2.4.25/drivers/parport/parport_ip22.c --- linux-2.4.24/drivers/parport/parport_ip22.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/parport/parport_ip22.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,313 @@ +/* + * Low-level parallel port routines for the SGI Indy/Indigo2 builtin port + * + * Copyright (c) 2002 Vincent Stehlé + * (shamelessly based on other parport_xxx.c) + * See the "COPYING" license file at the top-level. + * + * PI1 registers have the same bits as the PC parallel port registers, but + * all PI1 bits are "direct"; i.e. no invertion: A 1 is TTL "high" (5 V), + * a 0 is TTL "low" (0 V). There are also some bits on the PI1, which have + * no equivalents on the PC. They are for non-SPP modes. + * + * Here follows a little summary of the signals and their meanings: + * + * A "/" in front of a signal means that the _bit_ is inverted: i.e. a "1" + * bit value means a TTL "low" (0 V) signal. + * + * A "-" in front of a signal means that it is low active: i.e. a TTL "low" + * (0 V) value means that the signal is active. + * + * Internal only signals are between ()'s. + * + * Control + * ------- + * PC SGI + * + * 7 6 5 4 3 2 1 0 + * \ \ \ \ \ \ \ `- /-STROBE -STROBE + * \ \ \ \ \ \ `-- /-AUTO FEED -AFD + * \ \ \ \ \ `--- -INIT -INIT + * \ \ \ \ `---- /-SELECT -SLIN + * \ \ \ `----- (IRQ 1=enabled) + * \ \ `------ (DIRECTION 0=forward) + * \ `------- (SEL ?) + * `-------- + * + * Status + * ------ + * PC SGI + * + * 7 6 5 4 3 2 1 0 + * \ \ \ \ \ \ \ `- DEVID + * \ \ \ \ \ \ `-- " " + * \ \ \ \ \ `--- NOINK + * \ \ \ \ `---- -ERROR -ERROR + * \ \ \ `----- SELECT IN ONLINE + * \ \ `------ PAPER END PE + * \ `------- -ACK -ACK + * `-------- / BUSY BUSY + * + * Note that some of those information have been "guessed" with a multimeter + * and some spare nights :) + * + * Reminder: all functions await PC-style values, i.e. one should convert + * status and control. + */ + +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DPRINTK printk +#else +#define DPRINTK(x...) do { } while (0) +#endif + +const unsigned char control_invert = PARPORT_CONTROL_STROBE + | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT; +const unsigned char status_invert = PARPORT_STATUS_BUSY; + +static struct parport *this_port = NULL; + +static inline void debug_dump_registers(void) +{ +#ifdef DEBUG + printk(KERN_DEBUG + "PI1 registers:\n" + " data= %02x\n" + " control= %02x\n" + " status= %02x\n" + " dma control= %02x\n" + " interrupt status= %02x\n" + " interrupt mask= %02x\n" + " timer 1= %02x\n" + " timer 2= %02x\n" + " timer 3= %02x\n" + " timer 4= %02x\n" + , + sgioc->pport.data, + sgioc->pport.ctrl, + sgioc->pport.status, + sgioc->pport.dmactrl, + sgioc->pport.intstat, + sgioc->pport.intmask, + sgioc->pport.timer1, + sgioc->pport.timer2, + sgioc->pport.timer3, + sgioc->pport.timer4 + ); +#endif +} + +static unsigned char pi1_read_data(struct parport *p) +{ + unsigned char data = sgioc->pport.data; + DPRINTK("pi1_read_data: %#x\n", data); + return data; +} + +static void pi1_write_data(struct parport *p, unsigned char data) +{ + DPRINTK("pi1_write_data: %#x\n", data); + sgioc->pport.data = data; +} + +static unsigned char pi1_read_control(struct parport *p) +{ + const unsigned char mask = PARPORT_CONTROL_STROBE + | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_INIT + | PARPORT_CONTROL_SELECT; + unsigned char pctrl = sgioc->pport.ctrl, + control = ((pctrl & mask) ^ control_invert); + DPRINTK("pi1_read_control: %#x, %#x\n", pctrl, control); + return control; +} + +static void pi1_write_control(struct parport *p, unsigned char control) +{ + const unsigned char mask = PARPORT_CONTROL_STROBE + | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_INIT + | PARPORT_CONTROL_SELECT, + /* we enforce some necessary bits */ + force = 0x30; + unsigned char pctrl = ((control & mask) ^ control_invert) | force; + DPRINTK("pi1_write_control: %#x, %#x\n", control, pctrl); + sgioc->pport.ctrl = pctrl; +} + +static unsigned char pi1_frob_control(struct parport *p, + unsigned char mask, unsigned char val) +{ + unsigned char old; + DPRINTK(KERN_DEBUG "pi1_frob_control mask %02x, value %02x\n",mask,val); + old = pi1_read_control(p); + pi1_write_control(p, (old & ~mask) ^ val); + return old; +} + +static unsigned char pi1_read_status(struct parport *p) +{ + const unsigned mask = PARPORT_STATUS_ERROR | PARPORT_STATUS_SELECT + | PARPORT_STATUS_PAPEROUT | PARPORT_STATUS_ACK + | PARPORT_STATUS_BUSY; + unsigned char pstat = sgioc->pport.status, + status = ((pstat & mask) ^ status_invert); + DPRINTK("pi1_read_status: %#x, %#x\n", pstat, status); + return status; +} + +static void pi1_init_state(struct pardevice *d, struct parport_state *s) +{ + DPRINTK("pi1_init_state\n"); +} + +static void pi1_save_state(struct parport *p, struct parport_state *s) +{ + DPRINTK("pi1_save_state\n"); +} + +static void pi1_restore_state(struct parport *p, struct parport_state *s) +{ + DPRINTK("pi1_restore_state\n"); +} + +static void pi1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + DPRINTK("pi1_interrupt\n"); + parport_generic_irq(irq, (struct parport *) dev_id, regs); +} + +static void pi1_enable_irq(struct parport *p) +{ + DPRINTK("pi1_enable_irq\n"); +} + +static void pi1_disable_irq(struct parport *p) +{ + DPRINTK("pi1_disable_irq\n"); +} + +static void pi1_data_forward(struct parport *p) +{ + DPRINTK("pi1_data_forward\n"); + sgioc->pport.ctrl &= ~PI1_CTRL_DIR; +} + +static void pi1_data_reverse(struct parport *p) +{ + DPRINTK("pi1_data_reverse\n"); + sgioc->pport.ctrl |= PI1_CTRL_DIR; +} + +static void pi1_inc_use_count(void) +{ + DPRINTK("pi1_inc_use_count\n"); + MOD_INC_USE_COUNT; +} + +static void pi1_dec_use_count(void) +{ + DPRINTK("pi1_dec_use_count\n"); + MOD_DEC_USE_COUNT; +} + +static struct parport_operations pi1_ops = { + pi1_write_data, + pi1_read_data, + pi1_write_control, + pi1_read_control, + pi1_frob_control, + pi1_read_status, + pi1_enable_irq, + pi1_disable_irq, + pi1_data_forward, + pi1_data_reverse, + pi1_init_state, + pi1_save_state, + pi1_restore_state, + pi1_inc_use_count, + pi1_dec_use_count, + parport_ieee1284_epp_write_data, + parport_ieee1284_epp_read_data, + parport_ieee1284_epp_write_addr, + parport_ieee1284_epp_read_addr, + parport_ieee1284_ecp_write_data, + parport_ieee1284_ecp_read_data, + parport_ieee1284_ecp_write_addr, + parport_ieee1284_write_compat, + parport_ieee1284_read_nibble, + parport_ieee1284_read_byte +}; + +static void init_hardware(void) +{ + sgioc->pport.intmask = 0xfc; + sgioc->pport.dmactrl = 1; + sgioc->pport.ctrl = 0x3f; + sgioc->pport.timer1 = 0; + sgioc->pport.timer2 = 0; + sgioc->pport.timer3 = 0; + sgioc->pport.timer4 = 0; + sgioc->pport.data = 0; +} + +static int __init pi1_init(void) +{ + struct parport *p; + + DPRINTK("pi1_init\n"); + p = parport_register_port((unsigned long) &sgioc->pport.data, + PARPORT_IRQ_NONE, PARPORT_DMA_NONE, + &pi1_ops); + if (!p) + return -EBUSY; + +/* TODO + err = request_irq(IRQ_AMIGA_CIAA_FLG, amiga_interrupt, 0, p->name, p); + if (err) + goto out_irq; +*/ + + /* tell what we are capable of */ + p->modes = PARPORT_MODE_PCSPP; + +/* TODO + | PARPORT_MODE_TRISTATE;*/ + + /* remember for exit */ + this_port = p; + + /* put hardware into known initial state */ + init_hardware(); + + printk(KERN_INFO "%s: SGI PI1\n", p->name); + parport_proc_register(p); + parport_announce_port(p); + + return 0; +} + +static void __exit pi1_exit(void) +{ + DPRINTK("pi1_exit\n"); + if (this_port->irq != PARPORT_IRQ_NONE) + free_irq(this_port->irq, this_port); + + parport_proc_unregister(this_port); + parport_unregister_port(this_port); +} + +MODULE_AUTHOR("Vincent Stehle "); +MODULE_DESCRIPTION("Driver for SGI Indy/Indigo2 parallel port"); +MODULE_SUPPORTED_DEVICE("SGI PI1 parallel port"); +MODULE_LICENSE("GPL"); + +module_init(pi1_init); +module_exit(pi1_exit); diff -urN linux-2.4.24/drivers/pci/pci.ids linux-2.4.25/drivers/pci/pci.ids --- linux-2.4.24/drivers/pci/pci.ids 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/pci/pci.ids 2004-02-18 05:36:31.000000000 -0800 @@ -3428,8 +3428,6 @@ 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 1148 9521 SK-9521 10/100/1000Base-T Adapter - 4400 SK-9Dxx Gigabit Ethernet Adapter - 4500 SK-9Mxx Gigabit Ethernet Adapter 1149 Win System Corporation 114a VMIC 5579 VMIPCI-5579 (Reflective Memory Card) @@ -3725,8 +3723,24 @@ 11aa Actel 11ab Galileo Technology Ltd. 0146 GT-64010/64010A System Controller + 4146 GT-64011/GT-64111 System Controller 4320 Gigabit Ethernet Adapter - 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter + 1019 0f38 Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) + 1019 8001 Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) + 1043 173c Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) + 1043 811a Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) + 105b 0c19 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) + 10b8 b452 SMC EZ Card 1000 (SMC9452TXV.2) + 11ab 0121 Marvell RDK-8001 Adapter + 11ab 0321 Marvell RDK-8003 Adapter + 11ab 1021 Marvell RDK-8010 Adapter + 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) + 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) + 1458 e000 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) + 147b 1406 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) + 15d4 0047 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) + 1695 9025 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) + 17f2 1c03 Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) 4611 GT-64115 System Controller 4620 GT-64120/64120A/64121A System Controller 4801 GT-48001 @@ -4497,6 +4511,7 @@ 9132 Ethernet 100/10 MBit 1283 Integrated Technology Express, Inc. 673a IT8330G + 8181 IT8181E/F LCD/VGA Controller 8330 IT8330G 8888 IT8888F PCI to ISA Bridge with SMB 8889 IT8889F PCI to ISA Bridge @@ -5524,11 +5539,13 @@ 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X 1166 1648 NetXtreme CIOB-E 1000Base-T + 1649 NetXtreme BCM5704S Gigabit Ethernet 164d NetXtreme BCM5702FE Gigabit Ethernet 1653 NetXtreme BCM5705 Gigabit Ethernet 1654 NetXtreme BCM5705 Gigabit Ethernet 165d NetXtreme BCM5705M Gigabit Ethernet 165e NetXtreme BCM5705M Gigabit Ethernet + 166e NetXtreme BCM5705F Gigabit Ethernet 1696 NetXtreme BCM5782 Gigabit Ethernet 14e4 000d NetXtreme BCM5782 1000Base-T 169c NetXtreme BCM5788 Gigabit Ethernet diff -urN linux-2.4.24/drivers/pcmcia/Config.in linux-2.4.25/drivers/pcmcia/Config.in --- linux-2.4.24/drivers/pcmcia/Config.in 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -29,5 +29,20 @@ if [ "$CONFIG_8xx" = "y" ]; then dep_tristate ' M8xx support' CONFIG_PCMCIA_M8XX $CONFIG_PCMCIA fi + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + dep_tristate ' Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA + if [ "$CONFIG_PCMCIA_AU1X00" != "n" ]; then + bool ' Pb1x00 board support' CONFIG_PCMCIA_PB1X00 + bool ' Db1x00 board support' CONFIG_PCMCIA_DB1X00 + bool ' XXS1500 board support' CONFIG_PCMCIA_XXS1500 + fi + fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_bool ' SiByte PCMCIA support' CONFIG_PCMCIA_SIBYTE $CONFIG_PCMCIA $CONFIG_BLK_DEV_IDE_SIBYTE + fi + if [ "$CONFIG_VRC4173" = "y" -o "$CONFIG_VRC4173" = "m" ]; then + dep_tristate ' NEC VRC4173 CARDU support' CONFIG_PCMCIA_VRC4173 $CONFIG_PCMCIA + fi fi + endmenu diff -urN linux-2.4.24/drivers/pcmcia/Makefile linux-2.4.25/drivers/pcmcia/Makefile --- linux-2.4.24/drivers/pcmcia/Makefile 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -59,8 +59,15 @@ endif endif +obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o +au1000_ss-objs-y := au1000_generic.o +au1000_ss-objs-$(CONFIG_PCMCIA_PB1X00) += au1000_pb1x00.o +au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o +au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o + obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o +obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o sa1100_cs-objs-y := sa1100_generic.o sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o sa1111_generic.o @@ -82,6 +89,8 @@ sa1100_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o sa1111_generic.o sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o +obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o + include $(TOPDIR)/Rules.make pcmcia_core.o: $(pcmcia_core-objs) @@ -90,5 +99,8 @@ sa1100_cs.o: $(sa1100_cs-objs-y) $(LD) -r -o $@ $(sa1100_cs-objs-y) +au1x00_ss.o: $(au1000_ss-objs-y) + $(LD) -r -o $@ $(au1000_ss-objs-y) + yenta_socket.o: $(yenta_socket-objs) $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) diff -urN linux-2.4.24/drivers/pcmcia/au1000_pb1x00.c linux-2.4.25/drivers/pcmcia/au1000_pb1x00.c --- linux-2.4.24/drivers/pcmcia/au1000_pb1x00.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/au1000_pb1x00.c 2004-02-18 05:36:31.000000000 -0800 @@ -124,7 +124,7 @@ #else vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3; #ifdef CONFIG_MIPS_PB1500 - inserted0 = !((au_readl(GPIO2_PIN_STATE) >> 1) & 0x1); /* gpio 201 */ + inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */ #else /* Pb1100 */ inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */ #endif diff -urN linux-2.4.24/drivers/pcmcia/cardbus.c linux-2.4.25/drivers/pcmcia/cardbus.c --- linux-2.4.24/drivers/pcmcia/cardbus.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/cardbus.c 2004-02-18 05:36:31.000000000 -0800 @@ -223,7 +223,6 @@ struct pci_dev *cb_scan_slot(struct pci_dev *temp, struct list_head *list) { - struct pci_bus *bus = temp->bus; struct pci_dev *dev; struct pci_dev *first_dev = NULL; int func = 0; @@ -369,7 +368,7 @@ return max; } -static int program_bridge(struct pci_dev *bridge) +static void program_bridge(struct pci_dev *bridge) { u32 l; diff -urN linux-2.4.24/drivers/pcmcia/cistpl.c linux-2.4.25/drivers/pcmcia/cistpl.c --- linux-2.4.24/drivers/pcmcia/cistpl.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/cistpl.c 2004-02-18 05:36:31.000000000 -0800 @@ -351,9 +351,12 @@ int verify_cis_cache(socket_info_t *s) { - char buf[256], *caddr; + char *buf, *caddr; int i; - + + buf = kmalloc(256, GFP_KERNEL); + if (buf == NULL) + return -1; caddr = s->cis_cache; for (i = 0; i < s->cis_used; i++) { #ifdef CONFIG_CARDBUS @@ -368,6 +371,7 @@ break; caddr += s->cis_table[i].len; } + kfree(buf); return (i < s->cis_used); } @@ -1410,20 +1414,31 @@ int read_tuple(client_handle_t handle, cisdata_t code, void *parse) { - tuple_t tuple; - cisdata_t buf[255]; + tuple_t *tuple; + cisdata_t *buf; int ret; - - tuple.DesiredTuple = code; - tuple.Attributes = TUPLE_RETURN_COMMON; - ret = pcmcia_get_first_tuple(handle, &tuple); - if (ret != CS_SUCCESS) return ret; - tuple.TupleData = buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = sizeof(buf); - ret = pcmcia_get_tuple_data(handle, &tuple); - if (ret != CS_SUCCESS) return ret; - ret = pcmcia_parse_tuple(handle, &tuple, parse); + + buf = kmalloc(256, GFP_KERNEL); + if (buf == NULL) + return CS_OUT_OF_RESOURCE; + tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); + if (tuple == NULL) { + kfree(buf); + return CS_OUT_OF_RESOURCE; + } + tuple->DesiredTuple = code; + tuple->Attributes = TUPLE_RETURN_COMMON; + ret = pcmcia_get_first_tuple(handle, tuple); + if (ret != CS_SUCCESS) goto done; + tuple->TupleData = buf; + tuple->TupleOffset = 0; + tuple->TupleDataMax = 255; + ret = pcmcia_get_tuple_data(handle, tuple); + if (ret != CS_SUCCESS) goto done; + ret = pcmcia_parse_tuple(handle, tuple, parse); +done: + kfree(tuple); + kfree(buf); return ret; } @@ -1439,50 +1454,61 @@ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info) { - tuple_t tuple; - cisparse_t p; + tuple_t *tuple; + cisparse_t *p; int ret, reserved, dev_ok = 0, ident_ok = 0; if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; + tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); + if (tuple == NULL) + return CS_OUT_OF_RESOURCE; + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { + kfree(tuple); + return CS_OUT_OF_RESOURCE; + } info->Chains = reserved = 0; - tuple.DesiredTuple = RETURN_FIRST_TUPLE; - tuple.Attributes = TUPLE_RETURN_COMMON; - ret = pcmcia_get_first_tuple(handle, &tuple); + tuple->DesiredTuple = RETURN_FIRST_TUPLE; + tuple->Attributes = TUPLE_RETURN_COMMON; + ret = pcmcia_get_first_tuple(handle, tuple); if (ret != CS_SUCCESS) - return CS_SUCCESS; + goto done; /* First tuple should be DEVICE; we should really have either that or a CFTABLE_ENTRY of some sort */ - if ((tuple.TupleCode == CISTPL_DEVICE) || - (read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) == CS_SUCCESS)) + if ((tuple->TupleCode == CISTPL_DEVICE) || + (read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS)) dev_ok++; /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 tuple, for card identification. Certain old D-Link and Linksys cards have only a broken VERS_2 tuple; hence the bogus test. */ - if ((read_tuple(handle, CISTPL_MANFID, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_VERS_1, &p) == CS_SUCCESS) || - (read_tuple(handle, CISTPL_VERS_2, &p) != CS_NO_MORE_ITEMS)) + if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) || + (read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS)) ident_ok++; if (!dev_ok && !ident_ok) - return CS_SUCCESS; + goto done; for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) { - ret = pcmcia_get_next_tuple(handle, &tuple); + ret = pcmcia_get_next_tuple(handle, tuple); if (ret != CS_SUCCESS) break; - if (((tuple.TupleCode > 0x23) && (tuple.TupleCode < 0x40)) || - ((tuple.TupleCode > 0x47) && (tuple.TupleCode < 0x80)) || - ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff))) + if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || + ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || + ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) reserved++; } if ((info->Chains == MAX_TUPLES) || (reserved > 5) || ((!dev_ok || !ident_ok) && (info->Chains > 10))) info->Chains = 0; +done: + kfree(tuple); + kfree(p); return CS_SUCCESS; } diff -urN linux-2.4.24/drivers/pcmcia/cs.c linux-2.4.25/drivers/pcmcia/cs.c --- linux-2.4.24/drivers/pcmcia/cs.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/cs.c 2004-02-18 05:36:31.000000000 -0800 @@ -1862,7 +1862,7 @@ { socket_info_t *s; config_t *c; - int ret = 0, irq = 0; + int ret = CS_IN_USE, irq = 0; if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; @@ -1874,13 +1874,9 @@ return CS_CONFIGURATION_LOCKED; if (c->state & CONFIG_IRQ_REQ) return CS_IN_USE; - - /* Short cut: if there are no ISA interrupts, then it is PCI */ - if (!s->cap.irq_mask) { - irq = s->cap.pci_irq; - ret = (irq) ? 0 : CS_IN_USE; + #ifdef CONFIG_ISA - } else if (s->irq.AssignedIRQ != 0) { + if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must match */ irq = s->irq.AssignedIRQ; if (req->IRQInfo1 & IRQ_INFO2_VALID) { @@ -1889,7 +1885,6 @@ } else ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS; } else { - ret = CS_IN_USE; if (req->IRQInfo1 & IRQ_INFO2_VALID) { u_int try, mask = req->IRQInfo2 & s->cap.irq_mask; for (try = 0; try < 2; try++) { @@ -1904,9 +1899,13 @@ irq = req->IRQInfo1 & IRQ_MASK; ret = try_irq(req->Attributes, irq, 1); } + } #endif + if (ret != 0) { + if (!s->cap.pci_irq) + return ret; + irq = s->cap.pci_irq; } - if (ret != 0) return ret; if (req->Attributes & IRQ_HANDLE_PRESENT) { if (bus_request_irq(s->cap.bus, irq, req->Handler, diff -urN linux-2.4.24/drivers/pcmcia/rsrc_mgr.c linux-2.4.25/drivers/pcmcia/rsrc_mgr.c --- linux-2.4.24/drivers/pcmcia/rsrc_mgr.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/rsrc_mgr.c 2004-02-18 05:36:31.000000000 -0800 @@ -379,7 +379,7 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), int force_low, socket_info_t *s) { - resource_map_t *m, *n; + resource_map_t *m, mm; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; static int hi = 0, lo = 0; u_long b, i, ok = 0; @@ -393,18 +393,18 @@ "available!\n"); } if (lo++) return; - for (m = mem_db.next; m != &mem_db; m = n) { - n = m->next; + for (m = mem_db.next; m != &mem_db; m = mm.next) { + mm = *m; /* Only probe < 1 MB */ - if (m->base >= 0x100000) continue; - if ((m->base | m->num) & 0xffff) { - ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s); + if (mm.base >= 0x100000) continue; + if ((mm.base | mm.num) & 0xffff) { + ok += do_mem_probe(mm.base, mm.num, is_valid, do_cksum, s); continue; } /* Special probe for 64K-aligned block */ for (i = 0; i < 4; i++) { b = order[i] << 12; - if ((b >= m->base) && (b+0x10000 <= m->base+m->num)) { + if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { if (ok >= mem_limit) sub_interval(&mem_db, b, 0x10000); else diff -urN linux-2.4.24/drivers/pcmcia/sa1100_stork.c linux-2.4.25/drivers/pcmcia/sa1100_stork.c --- linux-2.4.24/drivers/pcmcia/sa1100_stork.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/sa1100_stork.c 2004-02-18 05:36:31.000000000 -0800 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff -urN linux-2.4.24/drivers/pcmcia/sibyte_generic.c linux-2.4.25/drivers/pcmcia/sibyte_generic.c --- linux-2.4.24/drivers/pcmcia/sibyte_generic.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/pcmcia/sibyte_generic.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,688 @@ +/* + * Copyright (C) 2003 Broadcom Corporation + * originally contributed to SiByte, Inc as + * "sb1250pc.c 0.10 (Stanley Chen & James Liao)" + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Notes / Apologies: + * - only ATA cards tested so far + * - requires hack in cs.c to avoid poking the CISCOR register + * - ack_intr routine might be improved to avoid error msgs. + * - remove and re-insert doesn't work (crash or fail to probe drive) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#include + +#include +#include +#include +#include +#include +#include + +#define PFX "sibyte-pcmcia: " + +MODULE_AUTHOR("Kip Walker, Stanley Chen & James Liao"); +MODULE_DESCRIPTION("SiByte PCMCIA socket driver"); + +#undef PCMCIA_DEBUG +#ifdef PCMCIA_DEBUG +#define DPRINTK(args...) do { printk(KERN_DEBUG args); } while (0) +#else +#define DPRINTK(n, args...) do { } while (0) +#endif + +static unsigned long sb_pcmcia_base = PCMCIA_PHYS; +static unsigned long sb_pcmcia_size; +#define SIBYTE_CS_REG(pcaddr) (IO_SPACE_BASE + sb_pcmcia_base - mips_io_port_base + pcaddr) +#define SB_PC_PORT 0xff00 +extern void sibyte_set_ideops(ide_hwif_t *hwif); + +/* The card status change interrupt */ +static int cs_irq = K_INT_PCMCIA; + +/* Memory map windows */ +static struct pccard_mem_map sibyte_memmap[MAX_WIN]; +static struct pccard_io_map sibyte_iomap[MAX_IO_WIN]; + +/*====================================================================*/ +/* Socket structures */ +/*====================================================================*/ + + +static void sb1250pc_interrupt(int irq, void *dev, struct pt_regs *regs); +static struct pccard_operations sb1250pc_operations; + +typedef struct socket_handler_t { + void (*handler)(void *info, u_int events); + void *info; +} socket_handler_t; + +static socket_handler_t socket_handler; + +/* + * cap features: + * full 32-bit addressing for 16-bit PCcard memory windows + * 16-bit card memory and IO accesses need bus_ops + * only 16-bit PCcards + * align memory windows + * statically mapped memory windows + */ +static socket_cap_t sb1250pc_cap = { + features: (SS_CAP_PAGE_REGS | +// SS_CAP_VIRTUAL_BUS | + SS_CAP_PCCARD | + SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP), + irq_mask: 0, /* tell ide layer to take PCI irq */ + map_size: 0x4000000, /* 64MB minimum window size (What *should* this be?)*/ + io_offset: SB_PC_PORT, /* This is ide5 -- just a special token for ide-sibyte */ + pci_irq: K_INT_PC_READY, /* XXXKW This serves as IREQ# for CompactFlash */ + cb_dev: NULL, + bus: NULL +}; + +/*====================================================================*/ +/* Useful macros */ +/*====================================================================*/ + +#define READ_PHYSADDR(addr) (*(volatile u32 *)(KSEG1ADDR(addr))) +#define WRITE_PHYSADDR(addr, data) (*(volatile u32 *)(KSEG1ADDR(addr))) = (data) + +#define READ_CSR32(reg) csr_in32(IO_SPACE_BASE + (reg)) +#define WRITE_CSR32(data, reg) csr_out32(data, IO_SPACE_BASE + (reg)) + +#define sb1250pc_write_config(data) WRITE_CSR32(data, A_IO_PCMCIA_CFG) +#define sb1250pc_read_config() READ_CSR32(A_IO_PCMCIA_CFG) +#define sb1250pc_read_status() READ_CSR32(A_IO_PCMCIA_STATUS) + +#define CARDPRESENT(s) (((s) & (M_PCMCIA_STATUS_CD1 | M_PCMCIA_STATUS_CD2)) == 0) + +int sb_pcmcia_ack_intr(struct hwif_s *hwif) +{ + /* + * XXXKW verify interrupt and return appropriate value? + * Simple check of the bit in A_GPIO_READ didn't DTRT + */ + + /* Clear out the GPIO edge detector */ + WRITE_CSR32(1 << K_GPIO_PC_READY, A_GPIO_CLR_EDGE); + return 1; +} + +/*====================================================================*/ +/* Interrupt handling */ +/*====================================================================*/ + +static unsigned int pending_events; +static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED; + +static void sb1250pc_bh(void *dummy) +{ + unsigned int events; + + spin_lock_irq(&pending_event_lock); + events = pending_events; + pending_events = 0; + spin_unlock_irq(&pending_event_lock); + + if (socket_handler.handler) + socket_handler.handler(socket_handler.info, events); +} + +static struct tq_struct sb1250pc_task = +{ + routine: sb1250pc_bh +}; + +static void sb1250pc_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + unsigned int events = 0; + uint32_t status; + + status = sb1250pc_read_status(); + + if (status & M_PCMCIA_STATUS_CDCHG) { + events = SS_DETECT; + if (CARDPRESENT(status)) { + events |= SS_INSERTION; + } else { + events |= SS_EJECTION; + } + } +#if 0 + /* XXXKW ignore everything but CD? */ + if (status & M_PCMCIA_STATUS_RDYCHG) { + if (status & M_PCMCIA_STATUS_RDY) { + /* XXXKW if ide, ack the interrupt? */ + events |= SS_READY; + } + } +#endif + + if (events) { + DPRINTK(PFX " passing %x to bh\n", events); + + /* Pass the events off to the bottom-half */ + spin_lock(&pending_event_lock); + pending_events |= events; + spin_unlock(&pending_event_lock); + schedule_task(&sb1250pc_task); + } +} + +/*====================================================================*/ +/* PC Card Operations */ +/*====================================================================*/ + +static int sb1250pc_register_callback(unsigned int lsock, + void (*handler)(void *, unsigned int), + void * info) +{ + DPRINTK(PFX "sb1250pc_register_callback(%d)\n", lsock); + + socket_handler.handler = handler; + socket_handler.info = info; + if (handler == NULL) { + MOD_DEC_USE_COUNT; + } else { + MOD_INC_USE_COUNT; + } + return 0; +} + +/*====================================================================*/ + +static int sb1250pc_get_status(unsigned int lsock, u_int *value) +{ + u_int val; + uint32_t status; +#if PCMCIA_DEBUG + u32 config; +#endif + + status = sb1250pc_read_status(); +#if PCMCIA_DEBUG + config = sb1250pc_read_config(); +#endif + + val = CARDPRESENT(status) ? SS_DETECT : 0; + val |= (status & M_PCMCIA_CFG_RESET) ? SS_RESET : 0; + val |= (status & (M_PCMCIA_STATUS_3VEN | M_PCMCIA_STATUS_5VEN)) ? + SS_POWERON : 0; + val |= (status & M_PCMCIA_STATUS_RDY) ? SS_READY : 0; + val |= (status & M_PCMCIA_STATUS_WP) ? SS_WRPROT : 0; + val |= ((status & M_PCMCIA_STATUS_VS2) && + (~status & M_PCMCIA_STATUS_VS1)) ? SS_3VCARD : 0; + val |= (status & (M_PCMCIA_STATUS_CDCHG | M_PCMCIA_STATUS_WPCHG + | M_PCMCIA_STATUS_RDYCHG)) ? SS_STSCHG : 0; + /* XXXKW SS_INSERTION on cdchange? */ + + DPRINTK(PFX "GetStatus(%d) = %x", lsock, val); +#if PCMCIA_DEBUG + DPRINTK(" [config(0x%4.4x) status(0x%4.4x)]", config, status); +#endif + DPRINTK("\n"); + + *value = val; + return 0; +} + +/*====================================================================*/ + +static int sb1250pc_inquire_socket(unsigned int lsock, socket_cap_t *cap) +{ + *cap = sb1250pc_cap; + + DPRINTK(PFX "InquireSocket(%d) = features 0x%4.4x, irq_mask " + "0x%4.4x, map_size 0x%4.4x\n", lsock, cap->features, + cap->irq_mask, cap->map_size); + + return 0; +} + +/*====================================================================*/ + +// This garbage function never seems to get called... +static int sb1250pc_get_socket(unsigned int lsock, socket_state_t *state) +{ + DPRINTK(PFX "Does GetSocket(%d) ever get called???", lsock); + return -1; +} /* sb1250pc_get_socket */ + +/*====================================================================*/ + +static uint32_t sibyte_set_power(uint32_t config, int vcc) +{ + config &= ~(M_PCMCIA_CFG_3VEN | M_PCMCIA_CFG_5VEN); + if (vcc == 33) { + config |= M_PCMCIA_CFG_3VEN; + } else if (vcc == 50) { + config |= M_PCMCIA_CFG_5VEN; + } + + sb1250pc_write_config(config); + return config; +} + +static int sb1250pc_set_socket(unsigned int lsock, socket_state_t *state) +{ + uint32_t config; + + DPRINTK(PFX "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, + state->Vcc, state->Vpp, state->io_irq, state->csc_mask); + + config = sb1250pc_read_config(); + + config = sibyte_set_power(config, state->Vcc); + + if (state->flags & SS_DEBOUNCED) + state->flags &= ~SS_DEBOUNCED; /* SS_DEBOUNCED is oneshot */ + /* XXXKW SS_OUTPUT_ENA? */ + /* XXXKW SS_PWR_AUTO? */ + /* XXXKW SS_IOCARD? */ + + if (state->csc_mask & SS_DETECT) + config &= ~M_PCMCIA_CFG_CDMASK; + else + config |= M_PCMCIA_CFG_CDMASK; + + config &= ~M_PCMCIA_CFG_RESET; + if (state->flags & SS_RESET) { + DPRINTK(PFX " resetting PCMCIA\n"); + config |= M_PCMCIA_CFG_RESET; + } + sb1250pc_write_config(config); + + DPRINTK(PFX " new config: %x\n", sb1250pc_read_config()); + + return 0; +} + +/*====================================================================*/ + +static int sb1250pc_get_io_map(unsigned int lsock, struct pccard_io_map *io) +{ + *io = sibyte_iomap[io->map]; + + DPRINTK(PFX "GetIOMap(%d, %d) = %#2.2x, %d ns, " + "%#4.4x-%#4.4x\n", lsock, io->map, io->flags, + io->speed, io->start, io->stop); + return 0; +} /* sb1250pc_get_io_map */ + +static int sb1250pc_set_io_map(unsigned int lsock, struct pccard_io_map *io) +{ + unsigned int speed; + unsigned long start; + u32 config; + + /* SB1250 uses direct mapping */ + DPRINTK(PFX "SetIOMap(%d, %d, %#2.2x, %d ns, " + "%#4.4x-%#4.4x) called\n", lsock, io->map, io->flags, + io->speed, io->start, io->stop); + + if (io->map >= MAX_IO_WIN) { + DPRINTK(KERN_ERR PFX "map (%d) out of range\n", io->map); + return -1; + } + + if (io->flags & MAP_ACTIVE) { + speed = (io->speed > 0) ? io->speed : 255; + } + + config = sb1250pc_read_config(); + + if (io->flags & MAP_ATTRIB) { + DPRINTK(PFX " Setting pcmcia_cfg_reg to 1 (Attribute Mode)\n"); + config |= M_PCMCIA_CFG_ATTRMEM; + } else { + DPRINTK(PFX " Setting pcmcia_cfg_reg to 0 (Data Mode)\n"); + config &= ~M_PCMCIA_CFG_ATTRMEM; + } + sb1250pc_write_config(config); + + start = io->start; + + if (io->stop == 1) { + io->stop = PAGE_SIZE - 1; + } + + if (io->start == 0) + io->start = sb_pcmcia_base; + + io->stop = io->start + (io->stop - start); + + sibyte_iomap[io->map] = *io; + + DPRINTK(PFX "SetIOMap(%d, %d, %#2.2x, %d ns, " + "%#4.4x-%#4.4x) returns\n", lsock, io->map, io->flags, + io->speed, io->start, io->stop); + return 0; +} /* sb1250pc_set_io_map */ + +/*====================================================================*/ + +static int sb1250pc_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem) +{ + if(mem->map >= MAX_WIN) + return -EINVAL; + + *mem = sibyte_memmap[mem->map]; + + DPRINTK(PFX "GetMemMap(%d, mem[%d, %#2.2x, %d ns, " + "%#5.5lx-%#5.5lx, %#5.5x) called\n", lsock, mem->map, mem->flags, + mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); + + return 0; +} + +static int sb1250pc_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem) +{ + u32 old_config, new_config; + + if (mem->map >= MAX_WIN) { + DPRINTK(KERN_ERR PFX "map (%d) out of range\n", mem->map); + return -1; + } + + if (mem->sys_start == 0) + mem->sys_start = mem->card_start + sb_pcmcia_base; + + if (mem->sys_stop == 0) + mem->sys_stop = mem->sys_start + sb_pcmcia_size - 1; + + old_config = sb1250pc_read_config(); + + DPRINTK(PFX " Setting mem_map %p\n", mem); + if (mem->flags & MAP_ATTRIB) { + DPRINTK(PFX " Setting pcmcia_cfg_reg to 1 (Attribute Mode)\n"); + new_config = old_config | M_PCMCIA_CFG_ATTRMEM; + } else { + DPRINTK(PFX " Setting pcmcia_cfg_reg to 0 (Data Mode)\n"); + new_config = old_config & ~M_PCMCIA_CFG_ATTRMEM; + } + if (new_config != old_config) + sb1250pc_write_config(new_config); + + sibyte_memmap[mem->map] = *mem; + + DPRINTK(PFX "SetMemMap(%d, mem[%d, %#2.2x, %d ns], " + "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, + mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); + + return 0; +} + +/*====================================================================*/ + +#ifdef CONFIG_PROC_FS +/* sb1250pc_proc_status() + * Implements the /proc/bus/pccard/??/status file. + * + * Returns: the number of characters added to the buffer + * + * Be aware that reading status clears the "change" bits; this seems + * unlikely to bite us by making us miss interrupts. + */ +static int sb1250pc_proc_status(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + char *p = buf; + u32 addr, temp; + u32 status, config; + //unsigned int sock = (unsigned int) data; + + config = sb1250pc_read_config(); + status = sb1250pc_read_status(); + p += sprintf(p, "config(0x%4.4x) status(0x%4.4x)\n", config, status); + + for (addr = sb_pcmcia_base; addr < sb_pcmcia_base + 8; addr+=4) { + temp = READ_PHYSADDR(addr); + p += sprintf(p, " Looking up addr 0x%x: 0x%8.8x\n", addr, temp); + } + + return p - buf; +} + +static void sb1250pc_proc_setup(unsigned int sock, struct proc_dir_entry *base) +{ + struct proc_dir_entry *entry; + + if ((entry = create_proc_entry("sb1250pc", 0, base)) == NULL) { + printk(KERN_ERR PFX "Unable to install \"sb1250pc\" procfs entry\n"); + return; + } else + printk(KERN_INFO PFX "Setting up \"sb1250pc\" procfs entry\n"); + + entry->read_proc = sb1250pc_proc_status; + entry->data = (void *) sock; +} + +#endif + +/*====================================================================*/ + +static int sibyte_pcmcia_initted = 0; + +static int sb1250pc_init(unsigned int s) +{ + u32 config, status; + + DPRINTK(PFX "Initializing SB1250 PCMCIA:\n"); + + /* Read status to clear interrupt sources */ + status = sb1250pc_read_status(); + + /* + * Before getting setting up the IRQ, set the config: + * reset off, auto-power off + * interrupt mask: WP, CD, Ready off + */ + config = sb1250pc_read_config(); + config = M_PCMCIA_CFG_CDMASK | M_PCMCIA_CFG_WPMASK | M_PCMCIA_CFG_RDYMASK; + sb1250pc_write_config(config); + + if (!sibyte_pcmcia_initted) { + uint32_t gpio_ctrl; + /* Set up the GPIO for PC_READY for use in ide-cs */ + gpio_ctrl = READ_CSR32(A_GPIO_INT_TYPE); + gpio_ctrl &= ~M_GPIO_INTR_TYPEX(K_GPIO_PC_READY); + gpio_ctrl |= V_GPIO_INTR_TYPEX(K_GPIO_PC_READY, K_GPIO_INTR_EDGE); + WRITE_CSR32(gpio_ctrl, A_GPIO_INT_TYPE); + WRITE_CSR32(1 << K_GPIO_PC_READY, A_GPIO_CLR_EDGE); + + /* Invert to get busy->ready transition */ + gpio_ctrl = READ_CSR32(A_GPIO_INPUT_INVERT); + gpio_ctrl |= 1 << K_GPIO_PC_READY; + WRITE_CSR32(gpio_ctrl, A_GPIO_INPUT_INVERT); + + /* Should not be any pending since we masked all sources */ + if (request_irq(cs_irq, sb1250pc_interrupt, 0, "pcmcia", NULL)) + return -ENODEV; + DPRINTK(PFX " IRQ %d registered\n", cs_irq); + + sibyte_pcmcia_initted = 1; + } + + status = sb1250pc_read_status(); + DPRINTK(PFX " config(0x%4.4x) status(0x%4.4x)\n", config, status); + + sb1250pc_set_socket(s, &dead_socket); + + return 0; +} + +static int sb1250pc_suspend(unsigned int sock) +{ + free_irq(cs_irq, NULL); + DPRINTK(KERN_INFO PFX " IRQ %d freed\n", cs_irq); + return sb1250pc_set_socket(sock, &dead_socket); +} + +static struct pccard_operations sb1250pc_operations = { + sb1250pc_init, + sb1250pc_suspend, + sb1250pc_register_callback, + sb1250pc_inquire_socket, + sb1250pc_get_status, + sb1250pc_get_socket, + sb1250pc_set_socket, + sb1250pc_get_io_map, + sb1250pc_set_io_map, + sb1250pc_get_mem_map, + sb1250pc_set_mem_map, +#ifdef CONFIG_PROC_FS + sb1250pc_proc_setup +#endif +}; + +/* + * XXXKW This is a hack. The ide-cs stuff seems to leave us in + * Attribute mode. Since I know that a SELECT_DRIVE will happen as + * the first I/O access, use this opportunity to enter data mode. + */ +static void sibyte_pcmcia_selectproc(ide_drive_t *drive) +{ + sb1250pc_write_config(sb1250pc_read_config() & ~M_PCMCIA_CFG_ATTRMEM); +} + +static int sibyte_pc_prep_ide(void) +{ + int i; + ide_hwif_t *hwif = NULL; + + /* Stake early claim on an ide_hwif */ + for (i = 0; i < MAX_HWIFS; i++) { + if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) { + hwif = &ide_hwifs[i]; + break; + } + } + if (hwif == NULL) { + printk("No space for SiByte onboard PCMCIA driver in ide_hwifs[]. Not enabled.\n"); + return 1; + } + + /* + * Prime the hwif with port values, so when a card is + * detected, the 'io_offset' from the capabilities will lead + * it here + */ + hwif->hw.io_ports[IDE_DATA_OFFSET] = SIBYTE_CS_REG(0); + hwif->hw.io_ports[IDE_ERROR_OFFSET] = SIBYTE_CS_REG(1); + hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SIBYTE_CS_REG(2); + hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SIBYTE_CS_REG(3); + hwif->hw.io_ports[IDE_LCYL_OFFSET] = SIBYTE_CS_REG(4); + hwif->hw.io_ports[IDE_HCYL_OFFSET] = SIBYTE_CS_REG(5); + hwif->hw.io_ports[IDE_SELECT_OFFSET] = SIBYTE_CS_REG(6); + hwif->hw.io_ports[IDE_STATUS_OFFSET] = SIBYTE_CS_REG(7); + hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SIBYTE_CS_REG(6); /* XXXKW ? */ + hwif->hw.ack_intr = sb_pcmcia_ack_intr; + hwif->selectproc = sibyte_pcmcia_selectproc; + hwif->hold = 1; + hwif->mmio = 2; + sibyte_set_ideops(&ide_hwifs[i]); + + printk("SiByte onboard PCMCIA-IDE configured as device %i\n", i); + + return 0; +} + +static int __init sibyte_pcmcia_init(void) +{ + servinfo_t info; + u32 addr, temp; + u64 cfg; + + CardServices(GetCardServicesInfo, &info); + if (info.Revision != CS_RELEASE_CODE) { + printk(KERN_ERR PFX "Card Services release does not match!\n"); + return -1; + } + + cfg = in64(IO_SPACE_BASE + A_SCD_SYSTEM_CFG); + if (!(cfg & M_SYS_PCMCIA_ENABLE)) { + printk(KERN_INFO PFX "chip not configured for PCMCIA\n"); + return -1; + } + + /* Find memory base address and size */ + addr = A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, PCMCIA_CS)); + temp = G_IO_MULT_SIZE(csr_in32(IO_SPACE_BASE + addr)); + printk(PFX "Looking up addr 0x%x: 0x%4.4x (IO size)\n", addr, temp); + sb_pcmcia_size = (temp+1) << S_IO_REGSIZE; + + addr = A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, PCMCIA_CS)); + temp = G_IO_START_ADDR(csr_in32(KSEG1|addr)); + printk(PFX "Looking up addr 0x%x: 0x%4.4x (IO Base Address)\n", addr, temp); + if (temp << S_IO_ADDRBASE != PCMCIA_PHYS) + panic(PFX "pcmcia base doesn't match gencs value\n"); + + /* check and request memory region */ + if (check_mem_region(sb_pcmcia_base, sb_pcmcia_size)) { + printk(KERN_ERR PFX "Can't request memory region?\n"); + } else { + request_mem_region(sb_pcmcia_base, sb_pcmcia_size, "sibyte-pcmcia"); + printk(PFX "Memory region 0x%8.8lx of size 0x%8.8lx requested.\n", + sb_pcmcia_base, sb_pcmcia_size); + } + + /* register with socket services */ + if (register_ss_entry(1, &sb1250pc_operations)) { + printk(KERN_ERR PFX "register_ss_entry() failed\n"); + release_region(sb_pcmcia_base, sb_pcmcia_size); + return -ENODEV; + } + + if (!sibyte_pc_prep_ide()) { + /* XXXKW hack for ide-cs warning squash */ + request_region(sb1250pc_cap.io_offset, 16, "ide-cs"); + request_mem_region(SIBYTE_CS_REG(0), 8, "sibyte-ide-cs"); + } + + return 0; +} + +static void __exit sibyte_pcmcia_exit(void) +{ + /* XXXKW untested as module */ + unregister_ss_entry(&sb1250pc_operations); + release_region(sb_pcmcia_base, sb_pcmcia_size); +} + +module_init(sibyte_pcmcia_init); +module_exit(sibyte_pcmcia_exit); diff -urN linux-2.4.24/drivers/pcmcia/vrc4173_cardu.c linux-2.4.25/drivers/pcmcia/vrc4173_cardu.c --- linux-2.4.24/drivers/pcmcia/vrc4173_cardu.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/pcmcia/vrc4173_cardu.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,628 @@ +/* + * FILE NAME + * drivers/pcmcia/vrc4173_cardu.c + * + * BRIEF MODULE DESCRIPTION + * NEC VRC4173 CARDU driver for Socket Services + * (This device doesn't support CardBus. it is supporting only 16bit PC Card.) + * + * Copyright 2002,2003 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include + +#include + +#include + +#include "vrc4173_cardu.h" + +MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services"); +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_LICENSE("GPL"); + +static int vrc4173_cardu_slots; + +static vrc4173_socket_t cardu_sockets[CARDU_MAX_SOCKETS]; + +extern struct socket_info_t *pcmcia_register_socket (int slot, + struct pccard_operations *vtable, + int use_bus_pm); +extern void pcmcia_unregister_socket(struct socket_info_t *s); + +static inline uint8_t exca_readb(vrc4173_socket_t *socket, uint16_t offset) +{ + return readb(socket->base + EXCA_REGS_BASE + offset); +} + +static inline uint16_t exca_readw(vrc4173_socket_t *socket, uint16_t offset) +{ + uint16_t val; + + val = readb(socket->base + EXCA_REGS_BASE + offset); + val |= (u16)readb(socket->base + EXCA_REGS_BASE + offset + 1) << 8; + + return val; +} + +static inline void exca_writeb(vrc4173_socket_t *socket, uint16_t offset, uint8_t val) +{ + writeb(val, socket->base + EXCA_REGS_BASE + offset); +} + +static inline void exca_writew(vrc4173_socket_t *socket, uint8_t offset, uint16_t val) +{ + writeb((u8)val, socket->base + EXCA_REGS_BASE + offset); + writeb((u8)(val >> 8), socket->base + EXCA_REGS_BASE + offset + 1); +} + +static inline uint32_t cardbus_socket_readl(vrc4173_socket_t *socket, u16 offset) +{ + return readl(socket->base + CARDBUS_SOCKET_REGS_BASE + offset); +} + +static inline void cardbus_socket_writel(vrc4173_socket_t *socket, u16 offset, uint32_t val) +{ + writel(val, socket->base + CARDBUS_SOCKET_REGS_BASE + offset); +} + +static void cardu_pciregs_init(struct pci_dev *dev) +{ + u32 syscnt; + u16 brgcnt; + u8 devcnt; + + pci_write_config_dword(dev, 0x1c, 0x10000000); + pci_write_config_dword(dev, 0x20, 0x17fff000); + pci_write_config_dword(dev, 0x2c, 0); + pci_write_config_dword(dev, 0x30, 0xfffc); + + pci_read_config_word(dev, BRGCNT, &brgcnt); + brgcnt &= ~IREQ_INT; + pci_write_config_word(dev, BRGCNT, brgcnt); + + pci_read_config_dword(dev, SYSCNT, &syscnt); + syscnt &= ~(BAD_VCC_REQ_DISB|PCPCI_EN|CH_ASSIGN_MASK|SUB_ID_WR_EN|PCI_CLK_RIN); + syscnt |= (CH_ASSIGN_NODMA|ASYN_INT_MODE); + pci_write_config_dword(dev, SYSCNT, syscnt); + + pci_read_config_byte(dev, DEVCNT, &devcnt); + devcnt &= ~(ZOOM_VIDEO_EN|SR_PCI_INT_SEL_MASK|PCI_INT_MODE|IRQ_MODE); + devcnt |= (SR_PCI_INT_SEL_NONE|IFG); + pci_write_config_byte(dev, DEVCNT, devcnt); + + pci_write_config_byte(dev, CHIPCNT, S_PREF_DISB); + + pci_write_config_byte(dev, SERRDIS, 0); +} + +static int cardu_init(unsigned int slot) +{ + vrc4173_socket_t *socket = &cardu_sockets[slot]; + + cardu_pciregs_init(socket->dev); + + /* CARD_SC bits are cleared by reading CARD_SC. */ + exca_writeb(socket, GLO_CNT, 0); + + socket->cap.features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS; + socket->cap.irq_mask = 0; + socket->cap.map_size = 0x1000; + socket->cap.pci_irq = socket->dev->irq; + socket->events = 0; + spin_lock_init(socket->event_lock); + + /* Enable PC Card status interrupts */ + exca_writeb(socket, CARD_SCI, CARD_DT_EN|RDY_EN|BAT_WAR_EN|BAT_DEAD_EN); + + return 0; +} + +static int cardu_suspend(unsigned int slot) +{ + return -EINVAL; +} + +static int cardu_register_callback(unsigned int sock, + void (*handler)(void *, unsigned int), + void * info) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + + socket->handler = handler; + socket->info = info; + + if (handler) + MOD_INC_USE_COUNT; + else + MOD_DEC_USE_COUNT; + + return 0; +} + +static int cardu_inquire_socket(unsigned int sock, socket_cap_t *cap) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + + *cap = socket->cap; + + return 0; +} + +static int cardu_get_status(unsigned int sock, u_int *value) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint32_t state; + uint8_t status; + u_int val = 0; + + status = exca_readb(socket, IF_STATUS); + if (status & CARD_PWR) val |= SS_POWERON; + if (status & READY) val |= SS_READY; + if (status & CARD_WP) val |= SS_WRPROT; + if ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2)) + val |= SS_DETECT; + if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) { + if (status & STSCHG) val |= SS_STSCHG; + } else { + status &= BV_DETECT_MASK; + if (status != BV_DETECT_GOOD) { + if (status == BV_DETECT_WARN) val |= SS_BATWARN; + else val |= SS_BATDEAD; + } + } + + state = cardbus_socket_readl(socket, SKT_PRE_STATE); + if (state & VOL_3V_CARD_DT) val |= SS_3VCARD; + if (state & VOL_XV_CARD_DT) val |= SS_XVCARD; + if (state & CB_CARD_DT) val |= SS_CARDBUS; + if (!(state & + (VOL_YV_CARD_DT|VOL_XV_CARD_DT|VOL_3V_CARD_DT|VOL_5V_CARD_DT|CCD20|CCD10))) + val |= SS_PENDING; + + *value = val; + + return 0; +} + +static inline u_char get_Vcc_value(uint8_t val) +{ + switch (val & VCC_MASK) { + case VCC_3V: + return 33; + case VCC_5V: + return 50; + } + + return 0; +} + +static inline u_char get_Vpp_value(uint8_t val) +{ + switch (val & VPP_MASK) { + case VPP_12V: + return 120; + case VPP_VCC: + return get_Vcc_value(val); + } + + return 0; +} + +static int cardu_get_socket(unsigned int sock, socket_state_t *state) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint8_t val; + + val = exca_readb(socket, PWR_CNT); + state->Vcc = get_Vcc_value(val); + state->Vpp = get_Vpp_value(val); + state->flags = 0; + if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA; + + val = exca_readb(socket, INT_GEN_CNT); + if (!(val & CARD_REST0)) state->flags |= SS_RESET; + if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD; + + return 0; +} + +static inline uint8_t set_Vcc_value(u_char Vcc) +{ + switch (Vcc) { + case 33: + return VCC_3V; + case 50: + return VCC_5V; + } + + return VCC_0V; +} + +static inline uint8_t set_Vpp_value(u_char Vpp) +{ + switch (Vpp) { + case 33: + case 50: + return VPP_VCC; + case 120: + return VPP_12V; + } + + return VPP_0V; +} + +static int cardu_set_socket(unsigned int sock, socket_state_t *state) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint8_t val; + + if (((state->Vpp == 33) || (state->Vpp == 50)) && (state->Vpp != state->Vcc)) + return -EINVAL; + + val = set_Vcc_value(state->Vcc); + val |= set_Vpp_value(state->Vpp); + if (state->flags & SS_OUTPUT_ENA) val |= CARD_OUT_EN; + exca_writeb(socket, PWR_CNT, val); + + val = exca_readb(socket, INT_GEN_CNT) & CARD_REST0; + if (state->flags & SS_RESET) val &= ~CARD_REST0; + else val |= CARD_REST0; + if (state->flags & SS_IOCARD) val |= CARD_TYPE_IO; + exca_writeb(socket, INT_GEN_CNT, val); + + return 0; +} + +static int cardu_get_io_map(unsigned int sock, struct pccard_io_map *io) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint8_t ioctl, window; + u_char map; + + map = io->map; + if (map > 1) + return -EINVAL; + + io->start = exca_readw(socket, IO_WIN_SA(map)); + io->stop = exca_readw(socket, IO_WIN_EA(map)); + + ioctl = exca_readb(socket, IO_WIN_CNT); + window = exca_readb(socket, ADR_WIN_EN); + io->flags = (window & IO_WIN_EN(map)) ? MAP_ACTIVE : 0; + if (ioctl & IO_WIN_DATA_AUTOSZ(map)) + io->flags |= MAP_AUTOSZ; + else if (ioctl & IO_WIN_DATA_16BIT(map)) + io->flags |= MAP_16BIT; + + return 0; +} + +static int cardu_set_io_map(unsigned int sock, struct pccard_io_map *io) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint16_t ioctl; + uint8_t window, enable; + u_char map; + + map = io->map; + if (map > 1) + return -EINVAL; + + window = exca_readb(socket, ADR_WIN_EN); + enable = IO_WIN_EN(map); + + if (window & enable) { + window &= ~enable; + exca_writeb(socket, ADR_WIN_EN, window); + } + + exca_writew(socket, IO_WIN_SA(map), io->start); + exca_writew(socket, IO_WIN_EA(map), io->stop); + + ioctl = exca_readb(socket, IO_WIN_CNT) & ~IO_WIN_CNT_MASK(map); + if (io->flags & MAP_AUTOSZ) ioctl |= IO_WIN_DATA_AUTOSZ(map); + else if (io->flags & MAP_16BIT) ioctl |= IO_WIN_DATA_16BIT(map); + exca_writeb(socket, IO_WIN_CNT, ioctl); + + if (io->flags & MAP_ACTIVE) + exca_writeb(socket, ADR_WIN_EN, window | enable); + + return 0; +} + +static int cardu_get_mem_map(unsigned int sock, struct pccard_mem_map *mem) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint32_t start, stop, offset, page; + uint8_t window; + u_char map; + + map = mem->map; + if (map > 4) + return -EINVAL; + + window = exca_readb(socket, ADR_WIN_EN); + mem->flags = (window & MEM_WIN_EN(map)) ? MAP_ACTIVE : 0; + + start = exca_readw(socket, MEM_WIN_SA(map)); + mem->flags |= (start & MEM_WIN_DSIZE) ? MAP_16BIT : 0; + start = (start & 0x0fff) << 12; + + stop = exca_readw(socket, MEM_WIN_EA(map)); + stop = ((stop & 0x0fff) << 12) + 0x0fff; + + offset = exca_readw(socket, MEM_WIN_OA(map)); + mem->flags |= (offset & MEM_WIN_WP) ? MAP_WRPROT : 0; + mem->flags |= (offset & MEM_WIN_REGSET) ? MAP_ATTRIB : 0; + offset = ((offset & 0x3fff) << 12) + start; + mem->card_start = offset & 0x03ffffff; + + page = exca_readb(socket, MEM_WIN_SAU(map)) << 24; + mem->sys_start = start + page; + mem->sys_stop = start + page; + + return 0; +} + +static int cardu_set_mem_map(unsigned int sock, struct pccard_mem_map *mem) +{ + vrc4173_socket_t *socket = &cardu_sockets[sock]; + uint16_t value; + uint8_t window, enable; + u_long sys_start, sys_stop, card_start; + u_char map; + + map = mem->map; + sys_start = mem->sys_start; + sys_stop = mem->sys_stop; + card_start = mem->card_start; + + if (map > 4 || sys_start > sys_stop || ((sys_start ^ sys_stop) >> 24) || + (card_start >> 26)) + return -EINVAL; + + window = exca_readb(socket, ADR_WIN_EN); + enable = MEM_WIN_EN(map); + if (window & enable) { + window &= ~enable; + exca_writeb(socket, ADR_WIN_EN, window); + } + + exca_writeb(socket, MEM_WIN_SAU(map), sys_start >> 24); + + value = (sys_start >> 12) & 0x0fff; + if (mem->flags & MAP_16BIT) value |= MEM_WIN_DSIZE; + exca_writew(socket, MEM_WIN_SA(map), value); + + value = (sys_stop >> 12) & 0x0fff; + exca_writew(socket, MEM_WIN_EA(map), value); + + value = ((card_start - sys_start) >> 12) & 0x3fff; + if (mem->flags & MAP_WRPROT) value |= MEM_WIN_WP; + if (mem->flags & MAP_ATTRIB) value |= MEM_WIN_REGSET; + exca_writew(socket, MEM_WIN_OA(map), value); + + if (mem->flags & MAP_ACTIVE) + exca_writeb(socket, ADR_WIN_EN, window | enable); + + return 0; +} + +static void cardu_proc_setup(unsigned int sock, struct proc_dir_entry *base) +{ +} + +static struct pccard_operations cardu_operations = { + .init = cardu_init, + .suspend = cardu_suspend, + .register_callback = cardu_register_callback, + .inquire_socket = cardu_inquire_socket, + .get_status = cardu_get_status, + .get_socket = cardu_get_socket, + .set_socket = cardu_set_socket, + .get_io_map = cardu_get_io_map, + .set_io_map = cardu_set_io_map, + .get_mem_map = cardu_get_mem_map, + .set_mem_map = cardu_set_mem_map, + .proc_setup = cardu_proc_setup, +}; + +static void cardu_bh(void *data) +{ + vrc4173_socket_t *socket = (vrc4173_socket_t *)data; + uint16_t events; + + spin_lock_irq(&socket->event_lock); + events = socket->events; + socket->events = 0; + spin_unlock_irq(&socket->event_lock); + + if (socket->handler) + socket->handler(socket->info, events); +} + +static uint16_t get_events(vrc4173_socket_t *socket) +{ + uint16_t events = 0; + uint8_t csc, status; + + status = exca_readb(socket, IF_STATUS); + csc = exca_readb(socket, CARD_SC); + if ((csc & CARD_DT_CHG) && + ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2))) + events |= SS_DETECT; + + if ((csc & RDY_CHG) && (status & READY)) + events |= SS_READY; + + if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) { + if ((csc & BAT_DEAD_ST_CHG) && (status & STSCHG)) + events |= SS_STSCHG; + } else { + if (csc & (BAT_WAR_CHG|BAT_DEAD_ST_CHG)) { + if ((status & BV_DETECT_MASK) != BV_DETECT_GOOD) { + if (status == BV_DETECT_WARN) events |= SS_BATWARN; + else events |= SS_BATDEAD; + } + } + } + + return events; +} + +static void cardu_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + vrc4173_socket_t *socket = (vrc4173_socket_t *)dev_id; + uint16_t events; + + socket->tq_task.routine = cardu_bh; + socket->tq_task.data = socket; + + events = get_events(socket); + if (events) { + spin_lock(&socket->event_lock); + socket->events |= events; + spin_unlock(&socket->event_lock); + schedule_task(&socket->tq_task); + } +} + +static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + vrc4173_socket_t *socket; + unsigned long start, len, flags; + int slot, err; + + slot = vrc4173_cardu_slots++; + socket = &cardu_sockets[slot]; + if (socket->noprobe != 0) + return -EBUSY; + + sprintf(socket->name, "NEC VRC4173 CARDU%1d", slot+1); + + if ((err = pci_enable_device(dev)) < 0) + return err; + + start = pci_resource_start(dev, 0); + if (start == 0) + return -ENODEV; + + len = pci_resource_len(dev, 0); + if (len == 0) + return -ENODEV; + + if (((flags = pci_resource_flags(dev, 0)) & IORESOURCE_MEM) == 0) + return -EBUSY; + + if ((err = pci_request_regions(dev, socket->name)) < 0) + return err; + + socket->base = ioremap(start, len); + if (socket->base == NULL) + return -ENODEV; + + socket->dev = dev; + + socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1); + if (socket->pcmcia_socket == NULL) { + iounmap(socket->base); + socket->base = NULL; + return -ENOMEM; + } + + if (request_irq(dev->irq, cardu_interrupt, SA_SHIRQ, socket->name, socket) < 0) { + pcmcia_unregister_socket(socket->pcmcia_socket); + socket->pcmcia_socket = NULL; + iounmap(socket->base); + socket->base = NULL; + return -EBUSY; + } + + printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq); + + return 0; +} + +static int __devinit vrc4173_cardu_setup(char *options) +{ + if (options == NULL || *options == '\0') + return 0; + + if (strncmp(options, "cardu1:", 7) == 0) { + options += 7; + if (*options != '\0') { + if (strncmp(options, "noprobe", 7) == 0) { + cardu_sockets[CARDU1].noprobe = 1; + options += 7; + } + + if (*options != ',') + return 0; + } else + return 0; + } + + if (strncmp(options, "cardu2:", 7) == 0) { + options += 7; + if ((*options != '\0') && (strncmp(options, "noprobe", 7) == 0)) + cardu_sockets[CARDU2].noprobe = 1; + } + + return 0; +} + +__setup("vrc4173_cardu=", vrc4173_cardu_setup); + +static struct pci_device_id vrc4173_cardu_id_table[] __devinitdata = { + { .vendor = PCI_VENDOR_ID_NEC, + .device = PCI_DEVICE_ID_NEC_NAPCCARD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, + {0, } +}; + +static struct pci_driver vrc4173_cardu_driver = { + .name = "NEC VRC4173 CARDU", + .probe = vrc4173_cardu_probe, + .id_table = vrc4173_cardu_id_table, +}; + +static int __devinit vrc4173_cardu_init(void) +{ + vrc4173_cardu_slots = 0; + + return pci_module_init(&vrc4173_cardu_driver); +} + +static void __devexit vrc4173_cardu_exit(void) +{ + pci_unregister_driver(&vrc4173_cardu_driver); +} + +module_init(vrc4173_cardu_init); +module_exit(vrc4173_cardu_exit); diff -urN linux-2.4.24/drivers/pcmcia/vrc4173_cardu.h linux-2.4.25/drivers/pcmcia/vrc4173_cardu.h --- linux-2.4.24/drivers/pcmcia/vrc4173_cardu.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/pcmcia/vrc4173_cardu.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,247 @@ +/* + * FILE NAME + * drivers/pcmcia/vrc4173_cardu.h + * + * BRIEF MODULE DESCRIPTION + * Include file for NEC VRC4173 CARDU. + * + * Copyright 2002 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _VRC4173_CARDU_H +#define _VRC4173_CARDU_H + +#include + +#include + +#define CARDU_MAX_SOCKETS 2 +#define CARDU1 0 +#define CARDU2 1 + +/* + * PCI Configuration Registers + */ +#define BRGCNT 0x3e + #define POST_WR_EN 0x0400 + #define MEM1_PREF_EN 0x0200 + #define MEM0_PREF_EN 0x0100 + #define IREQ_INT 0x0080 + #define CARD_RST 0x0040 + #define MABORT_MODE 0x0020 + #define VGA_EN 0x0008 + #define ISA_EN 0x0004 + #define SERR_EN 0x0002 + #define PERR_EN 0x0001 + +#define SYSCNT 0x80 + #define BAD_VCC_REQ_DISB 0x00200000 + #define PCPCI_EN 0x00080000 + #define CH_ASSIGN_MASK 0x00070000 + #define CH_ASSIGN_NODMA 0x00040000 + #define SUB_ID_WR_EN 0x00000008 + #define ASYN_INT_MODE 0x00000004 + #define PCI_CLK_RIN 0x00000002 + +#define DEVCNT 0x91 + #define ZOOM_VIDEO_EN 0x40 + #define SR_PCI_INT_SEL_MASK 0x18 + #define SR_PCI_INT_SEL_NONE 0x00 + #define PCI_INT_MODE 0x04 + #define IRQ_MODE 0x02 + #define IFG 0x01 + +#define CHIPCNT 0x9c + #define S_PREF_DISB 0x10 + +#define SERRDIS 0x9f + #define SERR_DIS_MAB 0x10 + #define SERR_DIS_TAB 0x08 + #define SERR_DIS_DT_PERR 0x04 + +/* + * ExCA Registers + */ +#define EXCA_REGS_BASE 0x800 +#define EXCA_REGS_SIZE 0x800 + +#define ID_REV 0x000 + #define IF_TYPE_16BIT 0x80 + +#define IF_STATUS 0x001 + #define CARD_PWR 0x40 + #define READY 0x20 + #define CARD_WP 0x10 + #define CARD_DETECT2 0x08 + #define CARD_DETECT1 0x04 + #define BV_DETECT_MASK 0x03 + #define BV_DETECT_GOOD 0x03 /* Memory card */ + #define BV_DETECT_WARN 0x02 + #define BV_DETECT_BAD1 0x01 + #define BV_DETECT_BAD0 0x00 + #define STSCHG 0x02 /* I/O card */ + #define SPKR 0x01 + +#define PWR_CNT 0x002 + #define CARD_OUT_EN 0x80 + #define VCC_MASK 0x18 + #define VCC_3V 0x18 + #define VCC_5V 0x10 + #define VCC_0V 0x00 + #define VPP_MASK 0x03 + #define VPP_12V 0x02 + #define VPP_VCC 0x01 + #define VPP_0V 0x00 + +#define INT_GEN_CNT 0x003 + #define CARD_REST0 0x40 + #define CARD_TYPE_MASK 0x20 + #define CARD_TYPE_IO 0x20 + #define CARD_TYPE_MEM 0x00 + +#define CARD_SC 0x004 + #define CARD_DT_CHG 0x08 + #define RDY_CHG 0x04 + #define BAT_WAR_CHG 0x02 + #define BAT_DEAD_ST_CHG 0x01 + +#define CARD_SCI 0x005 + #define CARD_DT_EN 0x08 + #define RDY_EN 0x04 + #define BAT_WAR_EN 0x02 + #define BAT_DEAD_EN 0x01 + +#define ADR_WIN_EN 0x006 + #define IO_WIN_EN(x) (0x40 << (x)) + #define MEM_WIN_EN(x) (0x01 << (x)) + +#define IO_WIN_CNT 0x007 + #define IO_WIN_CNT_MASK(x) (0x03 << ((x) << 2)) + #define IO_WIN_DATA_AUTOSZ(x) (0x02 << ((x) << 2)) + #define IO_WIN_DATA_16BIT(x) (0x01 << ((x) << 2)) + +#define IO_WIN_SA(x) (0x008 + ((x) << 2)) +#define IO_WIN_EA(x) (0x00a + ((x) << 2)) + +#define MEM_WIN_SA(x) (0x010 + ((x) << 3)) + #define MEM_WIN_DSIZE 0x8000 + +#define MEM_WIN_EA(x) (0x012 + ((x) << 3)) + +#define MEM_WIN_OA(x) (0x014 + ((x) << 3)) + #define MEM_WIN_WP 0x8000 + #define MEM_WIN_REGSET 0x4000 + +#define GEN_CNT 0x016 + #define VS2_STATUS 0x80 + #define VS1_STATUS 0x40 + #define EXCA_REG_RST_EN 0x02 + +#define GLO_CNT 0x01e + #define FUN_INT_LEV 0x08 + #define INT_WB_CLR 0x04 + #define CSC_INT_LEV 0x02 + +#define IO_WIN_OAL(x) (0x036 + ((x) << 1)) +#define IO_WIN_OAH(x) (0x037 + ((x) << 1)) + +#define MEM_WIN_SAU(x) (0x040 + (x)) + +#define IO_SETUP_TIM 0x080 +#define IO_CMD_TIM 0x081 +#define IO_HOLD_TIM 0x082 +#define MEM_SETUP_TIM(x) (0x084 + ((x) << 2)) +#define MEM_CMD_TIM(x) (0x085 + ((x) << 2)) +#define MEM_HOLD_TIM(x) (0x086 + ((x) << 2)) + #define TIM_CLOCKS(x) ((x) - 1) + +#define MEM_TIM_SEL1 0x08c +#define MEM_TIM_SEL2 0x08d + #define MEM_WIN_TIMSEL1(x) (0x03 << (((x) & 3) << 1)) + +#define MEM_WIN_PWEN 0x091 + #define POSTWEN 0x01 + +/* + * CardBus Socket Registers + */ +#define CARDBUS_SOCKET_REGS_BASE 0x000 +#define CARDBUS_SOCKET_REGS_SIZE 0x800 + +#define SKT_EV 0x000 + #define POW_CYC_EV 0x00000008 + #define CCD2_EV 0x00000004 + #define CCD1_EV 0x00000002 + #define CSTSCHG_EV 0x00000001 + +#define SKT_MASK 0x004 + #define POW_CYC_MASK 0x00000008 + #define CCD_MASK 0x00000006 + #define CSC_MASK 0x00000001 + +#define SKT_PRE_STATE 0x008 +#define SKT_FORCE_EV 0x00c + #define VOL_3V_SKT 0x20000000 + #define VOL_5V_SKT 0x10000000 + #define CVS_TEST 0x00004000 + #define VOL_YV_CARD_DT 0x00002000 + #define VOL_XV_CARD_DT 0x00001000 + #define VOL_3V_CARD_DT 0x00000800 + #define VOL_5V_CARD_DT 0x00000400 + #define BAD_VCC_REQ 0x00000200 + #define DATA_LOST 0x00000100 + #define NOT_A_CARD 0x00000080 + #define CREADY 0x00000040 + #define CB_CARD_DT 0x00000020 + #define R2_CARD_DT 0x00000010 + #define POW_UP 0x00000008 + #define CCD20 0x00000004 + #define CCD10 0x00000002 + #define CSTSCHG 0x00000001 + +#define SKT_CNT 0x010 + #define STP_CLK_EN 0x00000080 + #define VCC_CNT_MASK 0x00000070 + #define VCC_CNT_3V 0x00000030 + #define VCC_CNT_5V 0x00000020 + #define VCC_CNT_0V 0x00000000 + #define VPP_CNT_MASK 0x00000007 + #define VPP_CNT_3V 0x00000003 + #define VPP_CNT_5V 0x00000002 + #define VPP_CNT_12V 0x00000001 + #define VPP_CNT_0V 0x00000000 + +typedef struct vrc4173_socket { + int noprobe; + struct pci_dev *dev; + void *base; + void (*handler)(void *, unsigned int); + void *info; + socket_cap_t cap; + spinlock_t event_lock; + uint16_t events; + struct socket_info_t *pcmcia_socket; + struct tq_struct tq_task; + char name[20]; +} vrc4173_socket_t; + +#endif /* _VRC4173_CARDU_H */ diff -urN linux-2.4.24/drivers/pcmcia/yenta.c linux-2.4.25/drivers/pcmcia/yenta.c --- linux-2.4.24/drivers/pcmcia/yenta.c 2003-06-13 07:51:35.000000000 -0700 +++ linux-2.4.25/drivers/pcmcia/yenta.c 2004-02-18 05:36:31.000000000 -0800 @@ -26,7 +26,7 @@ #include "i82365.h" #if 0 -#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) +#define DEBUG(x,args...) printk(KERN_DEBUG __FUNCTION__ ": " x,##args) #else #define DEBUG(x,args...) #endif @@ -576,7 +576,8 @@ socket->cap.cb_dev = socket->dev; socket->cap.bus = NULL; - printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); + printk(KERN_INFO "Yenta ISA IRQ mask 0x%04x, PCI irq %d\n", + socket->cap.irq_mask, socket->cb_irq); } extern void cardbus_register(pci_socket_t *socket); @@ -603,7 +604,8 @@ /* Figure out what the dang thing can do for the PCMCIA layer... */ yenta_get_socket_capabilities(socket, isa_interrupts); - printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); + printk(KERN_INFO "Socket status: %08x\n", + cb_readl(socket, CB_SOCKET_STATE)); /* Register it with the pcmcia layer.. */ cardbus_register(socket); @@ -634,6 +636,7 @@ */ static void yenta_config_init(pci_socket_t *socket) { + u32 state; u16 bridge; struct pci_dev *dev = socket->dev; @@ -673,6 +676,10 @@ exca_writeb(socket, I365_GENCTL, 0x00); /* Redo card voltage interrogation */ + state = cb_readl(socket, CB_SOCKET_STATE); + if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | + CB_3VCARD | CB_XVCARD | CB_YVCARD))) + cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); } @@ -889,7 +896,7 @@ if (pci_enable_device(dev)) return -1; if (!pci_resource_start(dev, 0)) { - printk("No cardbus resource!\n"); + printk(KERN_ERR "No cardbus resource!\n"); return -1; } diff -urN linux-2.4.24/drivers/s390/block/dasd.c linux-2.4.25/drivers/s390/block/dasd.c --- linux-2.4.24/drivers/s390/block/dasd.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * - * $Revision: 1.289 $ + * $Revision: 1.311 $ * * History of changes (starts July 2000) * 11/09/00 complete redesign after code review @@ -36,6 +36,7 @@ * 07/09/01 fixed PL030324MSH (wrong statistics output) * 07/16/01 merged in new fixes for handling low-mem situations * 01/22/01 fixed PL030579KBE (wrong statistics) + * 08/07/03 fixed LTC BZ 3847 Erroneous message when formatting DASD */ #include @@ -162,6 +163,8 @@ static inline dasd_device_t ** dasd_device_from_devno (int); static void dasd_process_queues (dasd_device_t * device); static int dasd_sleep_on_immediate (ccw_req_t *cqr); +static int dasd_devno_from_devindex (int devindex); +static int dasd_devindex_from_devno (int devno); /******************************************************************************** * SECTION: static variables of dasd.c @@ -229,29 +232,7 @@ dasd_create_range (int from, int to, int features) { dasd_range_t *range = NULL; - int i; - - if ( from > to ) { - - MESSAGE (KERN_WARNING, - "Adding device range %04x-%04x: " - "range invalid, ignoring.", - from, - to); - - return NULL; - } - for (i=from;i<=to;i++) { - if (dasd_device_from_devno(i)) { - MESSAGE (KERN_WARNING, - "device range %04x-%04x: device " - "%04x is already in a range.", - from, - to, - i); - } - } range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL); if (range == NULL) return NULL; @@ -307,31 +288,70 @@ /* * function: dasd_add_range * creates a dasd_range_t according to the arguments and - * appends it to the list of ranges + * appends it to the list of ranges. + * If a device in the range is already in an other range, we split the + * range and add the subranges (no duplicate devices). * additionally a devreg_t is created and added to the list of devregs */ -static inline dasd_range_t * +static inline void dasd_add_range (int from, int to, int features) { dasd_range_t *range; + int start, end, index, i; - range = dasd_create_range (from, to, features); - if (!range) - return NULL; + if (from > to) { + MESSAGE (KERN_DEBUG, + "Adding device range %04x-%04x: " + "range invalid, ignoring.", + from, to); + return; + } + + /* loop over the given range, remove the already contained devices */ + /* and add the remaining subranges */ + for (start = index = from, end = -EINVAL; index <= to; index++) { + + if (dasd_devindex_from_devno(index) > 0) { + /* current device is already in range */ + MESSAGE (KERN_DEBUG, + "dasd_add_range %04x-%04x: " + "device %04x is already in range", + from, to, index); + + if (start == index) + start++; /* first already in range */ + else + end = index -1; /* current already in range */ + } else { + if (index == to) + end = to; /* end of original range reached */ + } - dasd_append_range (range); + range = NULL; + if (end != -EINVAL) { + MESSAGE (KERN_DEBUG, + "dasd_add_range %04x-%04x: " + "add (sub)range %04x-%04x", + from, to, start, end); + + range = dasd_create_range (start, end, features); + end = -EINVAL; + start = index + 1; + } + + if (range) { + dasd_append_range (range); #ifdef CONFIG_DASD_DYNAMIC - /* allocate and chain devreg infos for the devnos... */ - { - int i; - for (i = range->from; i <= range->to; i++) { - dasd_devreg_t *reg = dasd_create_devreg (i); - s390_device_register (®->devreg); - list_add (®->list, &dasd_devreg_head); - } - } + /* allocate and chain devreg infos for the devnos... */ + for (i = range->from; i <= range->to; i++) { + dasd_devreg_t *reg = dasd_create_devreg (i); + s390_device_register (®->devreg); + list_add (®->list, &dasd_devreg_head); + } #endif /* CONFIG_DASD_DYNAMIC */ - return range; + } + } + return; } /* @@ -534,10 +554,10 @@ if (buffer==NULL) { - MESSAGE (KERN_WARNING, - "can't parse dasd= parameter %s due " - "to low memory", - str); + MESSAGE_LOG (KERN_WARNING, + "can't parse dasd= parameter %s due " + "to low memory", + str); } /* remove leading '0x' */ @@ -580,16 +600,16 @@ break; } - MESSAGE (KERN_WARNING, - "unsupported feature: %s, " - "ignoring setting", - buffer); + MESSAGE_LOG (KERN_WARNING, + "unsupported feature: %s, " + "ignoring setting", + buffer); } } } *stra = temp+i; - if ((val > 65535) || (val < 0)) + if ((val > 0xFFFF) || (val < 0)) return -EINVAL; return val; } @@ -1754,7 +1774,7 @@ now = get_clock (); cqr->startclk = now; - if (device->accessible) + if (!device->stopped) rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options); else rc = -EBUSY; @@ -2158,10 +2178,6 @@ /* to be filled with MIH */ } break; - - case CQR_STATUS_PENDING: - /* just wait */ - break; default: MESSAGE (KERN_EMERG, "invalid cqr (%p) detected with status %02x ", @@ -2235,65 +2251,42 @@ } /* - * DASD_HANDLE_STATE_CHANGE_PENDING + * function dasd_handle_state_change_pending * - * DESCRIPTION - * Handles the state change pending interrupt. - * Search for the device related request queue and check if the first - * cqr in queue in in status 'CQR_STATUE_PENDING'. - * If so the status is set to 'CQR_STATUS_QUEUED' to reactivate - * the device. - * - * PARAMETER - * stat device status of state change pending interrupt. + * handles the state change pending interrupt. */ void dasd_handle_state_change_pending (devstat_t * stat) { - dasd_device_t **device_addr; + + dasd_device_t **device_addr, *device; ccw_req_t *cqr; device_addr = dasd_device_from_devno (stat->devno); - if (device_addr == NULL) { - - MESSAGE (KERN_DEBUG, - "unable to find device for state change pending " - "interrupt: devno%04x", - stat->devno); + if (!device_addr) return; - } - - /* re-activate first request in queue */ - cqr = (*device_addr)->queue.head; - if (cqr == NULL) { - MESSAGE (KERN_DEBUG, - "got state change pending interrupt on" - "idle device: %04x", - stat->devno); - return; - } + device = *device_addr; + if (!device) + return; - if (cqr->status == CQR_STATUS_PENDING) { - - DEV_MESSAGE (KERN_DEBUG, (*device_addr), "%s", - "device request queue restarted by " - "state change pending interrupt"); - - del_timer_sync (&(*device_addr)->blocking_timer); - - check_then_set (&cqr->status, - CQR_STATUS_PENDING, CQR_STATUS_QUEUED); - + /* restart all 'running' IO on queue */ + cqr = device->queue.head; + while (cqr) { + if (cqr->status == CQR_STATUS_IN_IO) { + cqr->status = CQR_STATUS_QUEUED; + } + cqr = cqr->next; } - if (cqr->status == CQR_STATUS_IN_IO) { - cqr->status = CQR_STATUS_QUEUED; - DEV_MESSAGE (KERN_WARNING, (*device_addr), "%s", - "redriving state change pending condition while in IO"); - } - dasd_schedule_bh (*device_addr); + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "device request queue restarted by " + "state change pending interrupt"); + + del_timer_sync (&(device->blocking_timer)); + device->stopped &= ~DASD_STOPPED_PENDING; + dasd_schedule_bh (device); } /* end dasd_handle_state_change_pending */ @@ -2634,15 +2627,18 @@ rc = -ENOMEM; break; } - if ((rc = dasd_sleep_on_req (req)) != 0) { - DEV_MESSAGE (KERN_WARNING, device, - " Formatting of unit %d failed " - "with rc = %d", - fdata->start_unit, rc); - break; - } - dasd_free_request (req, device); /* request is no longer used */ + rc = dasd_sleep_on_req (req); + dasd_free_request (req, device); /* request is no longer used */ + + if ( rc ) { + if (rc != -ERESTARTSYS ) + DEV_MESSAGE (KERN_WARNING, device, + " Formatting of unit %d failed" + " with rc = %d", + fdata->start_unit, rc); + break; + } fdata->start_unit++; } return rc; @@ -2864,6 +2860,37 @@ rc = dasd_format (device, &fdata); break; } + case BIODASDGATTR: { /* Get Attributes (cache operations) */ + + attrib_data_t attrib; + + if (!capable (CAP_SYS_ADMIN)) { + rc = -EACCES; + break; + } + + if (!data) { + rc = -EINVAL; + break; + } + + if (!device->discipline->get_attrib) { + rc = -EINVAL; + break; + } + + device->discipline->get_attrib (device, + &attrib); + + rc = copy_to_user ((void *) data, &attrib, + sizeof (attrib_data_t)); + + if (rc) { + rc = -EFAULT; + } + + break; + } case BIODASDSATTR: { /* Set Attributes (cache operations) */ attrib_data_t attrib; @@ -3410,7 +3437,7 @@ while ( cqr != NULL ) { if ( cqr->status == CQR_STATUS_IN_IO ) device->discipline->term_IO (cqr); - if ( cqr->status != CQR_STATUS_DONE || + if ( cqr->status != CQR_STATUS_DONE && cqr->status != CQR_STATUS_FAILED ) { cqr->status = CQR_STATUS_FAILED; @@ -3530,6 +3557,8 @@ dasd_discipline_t *discipline, int all, int force ) { + dasd_device_t **dptr; + dasd_device_t *device; dasd_range_t *rrange; int j; @@ -3541,10 +3570,8 @@ } do { for (j = rrange->from; j <= rrange->to; j++) { - dasd_device_t **dptr; - dasd_device_t *device; dptr = dasd_device_from_devno(j); - if ( dptr == NULL ) { + if (dptr == NULL) { continue; } device = *dptr; @@ -3555,6 +3582,9 @@ dasd_disable_volume(device, force); } + + if (rrange->list.next == NULL) + break; rrange = list_entry (rrange->list.next, dasd_range_t, list); } while ( all && rrange && rrange != range ); @@ -3723,7 +3753,8 @@ "device is not accessible, disabling it temporary\n"); s390irq_spin_lock_irqsave (device->devinfo.irq, flags); - device->accessible = 0; + device->stopped |= DASD_STOPPED_NOT_ACC; + if (status == DEVSTAT_NOT_ACC_ERR) { cqr = device->queue.head; while (cqr) { @@ -3755,7 +3786,7 @@ int devno; int rc = 0; major_info_t *major_info; - dasd_range_t *rptr,range; + dasd_range_t range; dasd_device_t *device; struct list_head *l; unsigned long flags; @@ -3783,33 +3814,25 @@ break; } - if ( device && - (device->level == DASD_STATE_ONLINE) && - (!device->accessible) ) { + if (device && + device->level >= DASD_STATE_READY) { s390irq_spin_lock_irqsave (device->devinfo.irq, flags); DEV_MESSAGE (KERN_DEBUG, device, "%s", - "device is accessible again, reenabling it\n"); - device->accessible = 1; + "device is accessible again, reenabling it\n"); + device->stopped &= ~DASD_STOPPED_NOT_ACC; + s390irq_spin_unlock_irqrestore(device->devinfo.irq, flags); - - dasd_schedule_bh(device); } else { if (dasd_autodetect) { - rptr = dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT); - if ( rptr == NULL ) { - rc = -ENOMEM; - goto out; - } - } else { - range.from = devno; - range.to = devno; - rptr = ⦥ + dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT); } - dasd_enable_ranges (rptr, NULL, 0); + range.from = devno; + range.to = devno; + dasd_enable_ranges (&range, NULL, 0); } out: return rc; @@ -3868,7 +3891,6 @@ memset (device, 0, sizeof (dasd_device_t)); dasd_plug_device (device); - device->accessible = 1; INIT_LIST_HEAD (&device->lowmem_pool); /* allocate pages for lowmem pool */ @@ -4040,13 +4062,18 @@ rc = s390_request_irq_special (device->devinfo.irq, device->discipline->int_handler, dasd_not_oper_handler, - 0, DASD_NAME, + SA_DOPATHGROUP, DASD_NAME, &device->dev_status); if ( rc ) { MESSAGE (KERN_DEBUG, "%s", "No request IRQ"); + if (rc == -EUSERS) { + /* Device is reserved by someone else. */ + device->level = DASD_STATE_BOXED; + } + goto out; } } @@ -4674,9 +4701,9 @@ for (; isspace(*str); str++); if (range->from < 0 || range->to < 0) { - MESSAGE (KERN_WARNING, - "/proc/dasd/devices: range parse error in '%s'", - buffer); + MESSAGE_LOG (KERN_WARNING, + "/proc/dasd/devices: range parse error in '%s'", + buffer); return ERR_PTR (-EINVAL); } @@ -4698,7 +4725,7 @@ /* Negative numbers in str/from/to indicate errors */ if (IS_ERR (str) || (range.from < 0) || (range.to < 0) - || (range.from > 65535) || (range.to > 65535)) + || (range.from > 0xFFFF) || (range.to > 0xFFFF)) return; if (strncmp (str, "on", 2) == 0) { @@ -4708,12 +4735,12 @@ dasd_disable_ranges (&range, NULL, 0, 1); } else { - MESSAGE (KERN_WARNING, - "/proc/dasd/devices: " - "only 'on' and 'off' are alowed in 'set' " - "command ('%s'/'%s')", - buffer, - str); + MESSAGE_LOG (KERN_WARNING, + "/proc/dasd/devices: " + "only 'on' and 'off' are alowed in 'set' " + "command ('%s'/'%s')", + buffer, + str); } return; @@ -4734,7 +4761,7 @@ /* Negative numbers in str/from/to indicate errors */ if (IS_ERR (str) || (range.from < 0) || (range.to < 0) - || (range.from > 65535) || (range.to > 65535)) + || (range.from > 0xFFFF) || (range.to > 0xFFFF)) return; dasd_add_range (range.from, range.to, range.features); @@ -4795,13 +4822,13 @@ rc = s390_request_irq_special (device->devinfo.irq, device->discipline->int_handler, dasd_not_oper_handler, - 0, + SA_DOPATHGROUP | SA_FORCE, DASD_NAME, &device->dev_status); if ( rc ) goto out; - rc = dasd_steal_lock (device); + rc = dasd_steal_lock (device); /* unregister the int handler to enable re-sensing */ free_irq (device->devinfo.irq, @@ -4841,10 +4868,10 @@ /* check for discipline = 'eckd' */ if (strncmp(str, "eckd", 4) != 0) { - MESSAGE (KERN_WARNING, - "/proc/dasd/devices: 'brk " - "is only allowed for 'eckd' (%s)", - str); + MESSAGE_LOG (KERN_WARNING, + "/proc/dasd/devices: 'brk " + "is only allowed for 'eckd' (%s)", + str); return; } @@ -4897,10 +4924,10 @@ buffer[user_len] = '\0'; } - MESSAGE (KERN_INFO, - "/proc/dasd/devices: '%s'", - buffer); - + MESSAGE_LOG (KERN_INFO, + "/proc/dasd/devices: '%s'", + buffer); + if (strncmp (buffer, "set ", 4) == 0) { /* handle 'set on/off' */ dasd_proc_set (buffer); @@ -5270,10 +5297,10 @@ while ( (rc=request_module(name)) != 0 ) { DECLARE_WAIT_QUEUE_HEAD(wait); - MESSAGE (KERN_INFO, - "request_module returned %d for %s", - rc, - (char*)name); + MESSAGE_LOG (KERN_INFO, + "request_module returned %d for %s", + rc, + (char*)name); sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */ } @@ -5371,14 +5398,13 @@ irq = get_irq_next (irq)) { int devno = get_devno_by_irq (irq); int index = dasd_devindex_from_devno (devno); - if (index == -ENODEV) { /* not included in ranges */ + if (index < 0) { /* not included in ranges */ DBF_EVENT (DBF_CRIT, "add %04x to range", devno); - dasd_add_range (devno, - devno, + dasd_add_range (devno, devno, DASD_FEATURE_DEFAULT); } } diff -urN linux-2.4.24/drivers/s390/block/dasd_3990_erp.c linux-2.4.25/drivers/s390/block/dasd_3990_erp.c --- linux-2.4.24/drivers/s390/block/dasd_3990_erp.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd_3990_erp.c 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * - * $Revision: 1.50 $ + * $Revision: 1.52 $ * * History of changes: * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5) @@ -447,13 +447,6 @@ * Block the given device request queue to prevent from further * processing until the started timer has expired or an related * interrupt was received. - * - * PARAMETER - * erp request to be blocked - * expires time to wait until restart (in seconds) - * - * RETURN VALUES - * void */ void dasd_3990_erp_block_queue (ccw_req_t *erp, @@ -466,15 +459,17 @@ "blocking request queue for %is", (int) expires); + device->stopped |= DASD_STOPPED_PENDING; + check_then_set (&erp->status, CQR_STATUS_ERROR, - CQR_STATUS_PENDING); + CQR_STATUS_QUEUED); /* restart queue after some time */ if (!timer_pending(&device->blocking_timer)) { init_timer(&device->blocking_timer); device->blocking_timer.function = dasd_3990_erp_restart_queue; - device->blocking_timer.data = (unsigned long) erp; + device->blocking_timer.data = (unsigned long) device; device->blocking_timer.expires = jiffies + (expires * HZ); add_timer(&device->blocking_timer); } else { @@ -487,24 +482,15 @@ * DASD_3990_ERP_RESTART_QUEUE * * DESCRIPTION - * Restarts request currently in status PENDING. - * This has to be done if either an related interrupt has received, or - * a timer has expired. - * - * - * PARAMETER - * erp pointer to the PENDING ERP - * - * RETURN VALUES - * void - * + * Restarts request queue of current device. + * This has to be done if either an related interrupt was received, or + * the timer has expired. */ void -dasd_3990_erp_restart_queue (unsigned long erp) +dasd_3990_erp_restart_queue (unsigned long device_ptr) { - ccw_req_t *cqr = (void *) erp; - dasd_device_t *device = cqr->device; + dasd_device_t *device = (dasd_device_t *) device_ptr; unsigned long flags; /* get the needed locks to modify the request queue */ @@ -512,20 +498,13 @@ flags); /* 'restart' the device queue */ - if (cqr->status == CQR_STATUS_PENDING) { - - DEV_MESSAGE (KERN_INFO, device, "%s", - "request queue restarted by MIH"); + DEV_MESSAGE (KERN_INFO, device, "%s", + "request queue restarted by MIH"); - check_then_set (&cqr->status, - CQR_STATUS_PENDING, - CQR_STATUS_QUEUED); - } + device->stopped &= ~DASD_STOPPED_PENDING; - /* release the lock */ s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags); - dasd_schedule_bh (device); } /* end dasd_3990_erp_restart_queue */ @@ -771,14 +750,18 @@ if (sense[25] == 0x1D) { /* state change pending */ - DEV_MESSAGE (KERN_INFO, device, "%s", + DEV_MESSAGE (KERN_INFO, device, "waiting for state change pending " - "int"); - + "interrupt, %d retries left", + erp->retries); + dasd_3990_erp_block_queue (erp, 30); } else { - DEV_MESSAGE (KERN_INFO, device, "redriving request immediately, %d retries left", erp->retries); + DEV_MESSAGE (KERN_INFO, device, + "redriving request immediately, " + "%d retries left", + erp->retries); /* no state change pending - retry */ check_then_set (&erp->status, CQR_STATUS_ERROR, diff -urN linux-2.4.24/drivers/s390/block/dasd_diag.c linux-2.4.25/drivers/s390/block/dasd_diag.c --- linux-2.4.24/drivers/s390/block/dasd_diag.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd_diag.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.47 $ + * $Revision: 1.49 $ * * History of changes * 07/13/00 Added fixup sections for diagnoses ans saved some registers @@ -83,7 +83,7 @@ " .quad 0b,1b\n" ".previous\n" #endif - : "+&d" (rc) + : "=&d" (rc) : "d" (cmd), "d" (addr) : "0", "1", "cc"); return rc; } @@ -269,7 +269,7 @@ dasd_diag_private_t *private; diag210_t *rdc_data; ccw_req_t *cqr; - long *label; + unsigned long *label; int sb; if (device == NULL) { @@ -280,6 +280,8 @@ return -ENODEV; } + + label = NULL; device->private = kmalloc (sizeof (dasd_diag_private_t), GFP_KERNEL); if (device->private == NULL) { @@ -291,6 +293,7 @@ goto fail; } private = (dasd_diag_private_t *) device->private; + memset (private, 0, sizeof(dasd_diag_private_t)); rdc_data = (void *) &(private->rdc_data); rdc_data->vrdcdvno = device->devinfo.devno; @@ -324,8 +327,13 @@ } else { BUG(); } - private->label = (long *) get_free_page (GFP_KERNEL); - label = private->label; + label = (unsigned long *) get_free_page (GFP_KERNEL); + if (!label) { + MESSAGE (KERN_WARNING, "%s", + "No memory to allocate label struct"); + rc = -ENOMEM; + goto fail; + } mdsk_term_io (device); /* first terminate all outstanding operations */ /* figure out blocksize of device */ for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { @@ -345,7 +353,6 @@ MESSAGE (KERN_WARNING, "%s", "No memory to allocate initialization request"); - free_page ((long) private->label); rc = -ENOMEM; goto fail; } @@ -353,7 +360,7 @@ memset (bio, 0, sizeof (diag_bio_t)); bio->type = MDSK_READ_REQ; bio->block_number = device->sizes.pt_block + 1; - bio->buffer = __pa (private->label); + bio->buffer = __pa (label); cqr->device = device; cqr->status = CQR_STATUS_FILLED; memset (iob, 0, sizeof (diag_rw_io_t)); @@ -391,15 +398,17 @@ (device->sizes.bp_block >> 10), (device->sizes.blocks << device->sizes.s2b_shift) >> 1); - free_page ((long) private->label); rc = 0; goto out; fail: - if ( rc ) { + if (device->private) { kfree (device->private); device->private = NULL; } out: + if (label) { + free_page ((unsigned long) label); + } return rc; } @@ -507,32 +516,25 @@ return rc; } -static char * -dasd_diag_dump_sense (struct dasd_device_t *device, ccw_req_t * req) -{ - char *page = (char *) get_free_page (GFP_KERNEL); - int len; - if (page == NULL) { - return NULL; - } - len = sprintf (page, KERN_WARNING PRINTK_HEADER - "device %04X on irq %d: I/O status report:\n", - device->devinfo.devno, device->devinfo.irq); - - return page; -} +/* + * max_blocks: We want to fit one CP into one page of memory so that we can + * effectively use available resources. + * The ccw_req_t has less than 256 bytes (including safety) + * and diag_bio_t for each block has 16 bytes. + * That makes: + * (4096 - 256) / 16 = 240 blocks at maximum. + */ dasd_discipline_t dasd_diag_discipline = { owner: THIS_MODULE, name:"DIAG", ebcname:"DIAG", - max_blocks:PAGE_SIZE / sizeof (diag_bio_t), + max_blocks:240, check_characteristics:dasd_diag_check_characteristics, fill_geometry:dasd_diag_fill_geometry, start_IO:dasd_start_diag, examine_error:dasd_diag_examine_error, build_cp_from_req:dasd_diag_build_cp_from_req, - dump_sense:dasd_diag_dump_sense, int_handler:(void *) dasd_ext_handler, fill_info:dasd_diag_fill_info, list:LIST_HEAD_INIT(dasd_diag_discipline.list), diff -urN linux-2.4.24/drivers/s390/block/dasd_eckd.c linux-2.4.25/drivers/s390/block/dasd_eckd.c --- linux-2.4.24/drivers/s390/block/dasd_eckd.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd_eckd.c 2004-02-18 05:36:31.000000000 -0800 @@ -539,8 +539,8 @@ private->rdc_data.sec_per_trk); /* set default cache operations */ - private->attrib.operation = DASD_SEQ_ACCESS; - private->attrib.nr_cyl = 0x02; + private->attrib.operation = DASD_NORMAL_CACHE; + private->attrib.nr_cyl = 0; /* Read Configuration Data */ rc = read_conf_data (device->devinfo.irq, @@ -1630,7 +1630,26 @@ /* - * DASD_ECKD_SET_ATTRUB + * DASD_ECKD_GET_ATTRIB + * + * DESCRIPTION + * returnes the cache attributes used in Define Extend (DE). + */ +int +dasd_eckd_get_attrib (dasd_device_t *device, + attrib_data_t *attrib) +{ + dasd_eckd_private_t *private; + + private = (dasd_eckd_private_t *) device->private; + *attrib = private->attrib; + + return 0; + +} /* end dasd_eckd_get_attrib */ + +/* + * DASD_ECKD_SET_ATTRIB * * DESCRIPTION * stores the attributes for cache operation to be used in Define Extend (DE). @@ -1639,7 +1658,6 @@ dasd_eckd_set_attrib (dasd_device_t *device, attrib_data_t *attrib) { - int rc = 0; dasd_eckd_private_t *private; private = (dasd_eckd_private_t *) device->private; @@ -1650,13 +1668,12 @@ "%x (%i cylinder prestage)", private->attrib.operation, private->attrib.nr_cyl); - - return rc; + return 0; } /* end dasd_eckd_set_attrib */ -static char* +static void dasd_eckd_dump_sense (struct dasd_device_t *device, ccw_req_t *req) { @@ -1671,7 +1688,7 @@ MESSAGE (KERN_ERR, "%s", "No memory to dump sense data"); - return NULL; + return; } len = sprintf (page, KERN_ERR PRINTK_HEADER @@ -1734,13 +1751,11 @@ } } - MESSAGE (KERN_ERR, - "Sense data:\n%s", - page); + MESSAGE_LOG (KERN_ERR, + "Sense data:\n%s", + page); free_page ((unsigned long) page); - - return NULL; } @@ -1770,6 +1785,7 @@ fill_info:dasd_eckd_fill_info, read_stats:dasd_eckd_read_stats, ret_stats:dasd_eckd_ret_stats, + get_attrib:dasd_eckd_get_attrib, set_attrib:dasd_eckd_set_attrib, list:LIST_HEAD_INIT(dasd_eckd_discipline.list), }; diff -urN linux-2.4.24/drivers/s390/block/dasd_fba.c linux-2.4.25/drivers/s390/block/dasd_fba.c --- linux-2.4.24/drivers/s390/block/dasd_fba.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd_fba.c 2004-02-18 05:36:31.000000000 -0800 @@ -4,7 +4,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.49 $ + * $Revision: 1.50 $ * * History of changes * fixed partition handling and HDIO_GETGEO @@ -409,21 +409,6 @@ } -static char * -dasd_fba_dump_sense (struct dasd_device_t *device, ccw_req_t * req) -{ - char *page = (char *) get_free_page (GFP_KERNEL); - int len; - if (page == NULL) { - return NULL; - } - len = sprintf (page, KERN_WARNING PRINTK_HEADER - "device %04X on irq %d: I/O status report:\n", - device->devinfo.devno, device->devinfo.irq); - - return page; -} - dasd_discipline_t dasd_fba_discipline = { owner: THIS_MODULE, name:"FBA ", @@ -439,7 +424,6 @@ erp_action:dasd_fba_erp_action, erp_postaction:dasd_fba_erp_postaction, build_cp_from_req:dasd_fba_build_cp_from_req, - dump_sense:dasd_fba_dump_sense, int_handler:dasd_int_handler, fill_info:dasd_fba_fill_info, list:LIST_HEAD_INIT(dasd_fba_discipline.list), diff -urN linux-2.4.24/drivers/s390/block/dasd_int.h linux-2.4.25/drivers/s390/block/dasd_int.h --- linux-2.4.24/drivers/s390/block/dasd_int.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/dasd_int.h 2004-02-18 05:36:31.000000000 -0800 @@ -5,7 +5,7 @@ * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.26 $ + * $Revision: 1.36 $ * * History of changes (starts July 2000) * 02/01/01 added dynamic registration of ioctls @@ -292,6 +292,7 @@ d_args); \ } while(0) +/* general messages to be written via klogd and dbf */ #define MESSAGE(d_loglevel,d_string,d_args...)\ do { \ printk(d_loglevel PRINTK_HEADER \ @@ -303,6 +304,14 @@ d_args); \ } while(0) +/* general messages to be written via klogd only */ +#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\ +do { \ + printk(d_loglevel PRINTK_HEADER \ + " " d_string "\n", \ + d_args); \ +} while(0) + struct dasd_device_t; struct request; @@ -321,11 +330,13 @@ typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information2_t *); typedef int (*dasd_use_count_fn_t) (int); +typedef int (*dasd_get_attrib_fn_t) (struct dasd_device_t *, + struct attrib_data_t *); typedef int (*dasd_set_attrib_fn_t) (struct dasd_device_t *, struct attrib_data_t *); typedef void (*dasd_int_handler_fn_t) (int irq, void *, struct pt_regs *); -typedef char * (*dasd_dump_sense_fn_t) (struct dasd_device_t *, +typedef void (*dasd_dump_sense_fn_t) (struct dasd_device_t *, ccw_req_t *); typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *); @@ -378,6 +389,7 @@ dasd_info_fn_t fill_info; dasd_read_stats_fn_t read_stats; dasd_ret_stats_fn_t ret_stats; /* return performance statistics */ + dasd_get_attrib_fn_t get_attrib; /* get attributes (cache operations */ dasd_set_attrib_fn_t set_attrib; /* set attributes (cache operations */ struct list_head list; /* used for list of disciplines */ } dasd_discipline_t; @@ -429,10 +441,14 @@ dasd_profile_info_t profile; ccw_req_t *init_cqr; atomic_t plugged; - int accessible; /* set to !=0 if doing IO is permitted */ + int stopped; /* device (do_IO) was stopped */ struct list_head lowmem_pool; } dasd_device_t; +/* reasons why device (do_IO) was stopped */ +#define DASD_STOPPED_NOT_ACC 1 /* not accessible */ +#define DASD_STOPPED_PENDING 2 /* long busy */ + int dasd_init (void); void dasd_discipline_add (dasd_discipline_t *); diff -urN linux-2.4.24/drivers/s390/block/xpram.c linux-2.4.25/drivers/s390/block/xpram.c --- linux-2.4.24/drivers/s390/block/xpram.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/s390/block/xpram.c 2004-02-18 05:36:31.000000000 -0800 @@ -184,9 +184,7 @@ "All devices with size 0 equally partition the " "remaining space on the expanded strorage not " "claimed by explicit sizes\n"); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12)) -MODULE_LICENSE ("GPL"); -#endif +MODULE_LICENSE("GPL"); /* The following items are obtained through kmalloc() in init_module() */ @@ -273,7 +271,7 @@ return XPRAM_INVALF; if ( (**strptr == '0') && ( (*((*strptr)+1) == 'x') || (*((*strptr) +1) == 'X') ) - && isdigit(*((*strptr)+3)) ) { + && isxdigit(*((*strptr)+2)) ) { *strptr=(*strptr)+2; return XPRAM_HEXF; } else return XPRAM_DECF; diff -urN linux-2.4.24/drivers/s390/ccwcache.c linux-2.4.25/drivers/s390/ccwcache.c --- linux-2.4.24/drivers/s390/ccwcache.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.25/drivers/s390/ccwcache.c 2004-02-18 05:36:31.000000000 -0800 @@ -146,7 +146,7 @@ /* determine cache index for the requested size */ for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) - if ( size_needed < (SMALLEST_SLAB << cachind) ) + if ( size_needed <= (SMALLEST_SLAB << cachind) ) break; /* Try to fulfill the request from a cache */ diff -urN linux-2.4.24/drivers/s390/net/ctcmain.c linux-2.4.25/drivers/s390/net/ctcmain.c --- linux-2.4.24/drivers/s390/net/ctcmain.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/net/ctcmain.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.60 2003/06/18 11:16:32 cotte Exp $ + * $Id: ctcmain.c,v 1.63 2003/10/22 19:32:57 felfert Exp $ * * CTC / ESCON network driver * @@ -35,7 +35,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.60 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.63 $ * */ @@ -400,12 +400,14 @@ static __inline__ void ctc_clear_busy(net_device *dev) { clear_bit(0, &(((ctc_priv *)dev->priv)->tbusy)); - netif_wake_queue(dev); + if (((ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_wake_queue(dev); } static __inline__ int ctc_test_and_set_busy(net_device *dev) { - netif_stop_queue(dev); + if (((ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_stop_queue(dev); return test_and_set_bit(0, &((ctc_priv *)dev->priv)->tbusy); } @@ -417,7 +419,7 @@ */ static void print_banner(void) { static int printed = 0; - char vbuf[] = "$Revision: 1.60 $"; + char vbuf[] = "$Revision: 1.63 $"; char *version = vbuf; if (printed) @@ -2833,7 +2835,6 @@ fsm_event(privptr->fsm, DEV_EVENT_START, dev); if (privptr->protocol == CTC_PROTO_LINUX_TTY) return -EBUSY; - dst_link_failure(skb); dev_kfree_skb(skb); privptr->stats.tx_dropped++; privptr->stats.tx_errors++; @@ -3058,7 +3059,7 @@ privptr = (ctc_priv *)dev->priv; - if (count >= 3) + if (count >= 20) return -EINVAL; if (copy_from_user(tmp, buf, count)) diff -urN linux-2.4.24/drivers/s390/s390io.c linux-2.4.25/drivers/s390/s390io.c --- linux-2.4.24/drivers/s390/s390io.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/s390/s390io.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /* * drivers/s390/s390io.c * S/390 common I/O routines - * $Revision: 1.247 $ + * $Revision: 1.258 $ * * S390 version * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, @@ -766,6 +766,8 @@ return; } +void s390_free_irq (unsigned int irq, void *dev_id); + /* * Note : internal use of irqflags SA_PROBE for NOT path grouping * @@ -802,7 +804,11 @@ */ s390irq_spin_lock_irqsave (irq, flags); - if (!ioinfo[irq]->ui.flags.ready) { + if (ioinfo[irq]->ui.flags.unfriendly && + !(irqflags & SA_FORCE)) { + retval = -EUSERS; + + } else if (!ioinfo[irq]->ui.flags.ready) { retry = 5; ioinfo[irq]->irq_desc.handler = io_handler; @@ -836,12 +842,55 @@ s390irq_spin_unlock_irqrestore (irq, flags); if (retval == 0) { + if (irqflags & SA_DOPATHGROUP) { + ioinfo[irq]->ui.flags.pgid_supp = 1; + ioinfo[irq]->ui.flags.notacccap = 1; + } + if ((irqflags & SA_DOPATHGROUP) && + (!ioinfo[irq]->ui.flags.pgid || + irqflags & SA_PROBE)) { + pgid_t pgid; + int i, mask; + /* + * Do an initial SensePGID to find out if device + * is locked by someone else. + */ + memcpy(&pgid, global_pgid, sizeof(pgid_t)); + + retval = -EAGAIN; + for (i=0; i<8 && retval==-EAGAIN; i++) { + + mask = (0x80 >> i) & ioinfo[irq]->opm; + + if (!mask) + continue; + + retval = s390_SensePGID(irq, mask, &pgid); + + if (retval == -EOPNOTSUPP) + /* Doesn't prevent us from proceeding */ + retval = 0; + } + + } if (!(irqflags & SA_PROBE) && + (irqflags & SA_DOPATHGROUP) && (!ioinfo[irq]->ui.flags.unfriendly)) s390_DevicePathVerification (irq, 0); - ioinfo[irq]->ui.flags.newreq = 1; - ioinfo[irq]->nopfunc = not_oper_handler; + if (ioinfo[irq]->ui.flags.unfriendly && + !(irqflags & SA_FORCE)) { + /* + * We found out during path verification that the + * device is locked by someone else and we have to + * let the device driver know. + */ + retval = -EUSERS; + free_irq(irq, dev_id); + } else { + ioinfo[irq]->ui.flags.newreq = 1; + ioinfo[irq]->nopfunc = not_oper_handler; + } } if (cio_debug_initialized) @@ -981,61 +1030,6 @@ } /* - * Generic enable/disable code - */ -int -disable_irq (unsigned int irq) -{ - unsigned long flags; - int ret; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (!ioinfo[irq]->ui.flags.ready) - return -ENODEV; - - sprintf (dbf_txt, "disirq%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - s390irq_spin_lock_irqsave (irq, flags); - ret = disable_subchannel (irq); - s390irq_spin_unlock_irqrestore (irq, flags); - - synchronize_irq (); - - sprintf (dbf_txt, "ret:%d", ret); - CIO_TRACE_EVENT (4, dbf_txt); - - return (ret); -} - -int -enable_irq (unsigned int irq) -{ - unsigned long flags; - int ret; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (!ioinfo[irq]->ui.flags.ready) - return -ENODEV; - - sprintf (dbf_txt, "enirq%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - s390irq_spin_lock_irqsave (irq, flags); - ret = enable_subchannel (irq); - s390irq_spin_unlock_irqrestore (irq, flags); - - sprintf (dbf_txt, "ret:%d", ret); - CIO_TRACE_EVENT (4, dbf_txt); - - return (ret); -} - -/* * Enable IRQ by modifying the subchannel */ static int @@ -1442,8 +1436,6 @@ } - ioinfo[irq]->ulpm = ioinfo[irq]->orb.lpm; - /* * If synchronous I/O processing is requested, we have * to wait for the corresponding interrupt to occur by @@ -1782,35 +1774,6 @@ */ if (!ioinfo[irq]->ui.flags.busy) { /* last I/O completed ? */ ret = s390_start_IO (irq, cpa, user_intparm, lpm, flag); - if ((ret == -ETIMEDOUT) && (flag & DOIO_CANCEL_ON_TIMEOUT)) { - /* - * We should better cancel the io request here - * or we might not be able to do io on this sch - * again - */ - cancel_IO (irq); - } - - } else if (ioinfo[irq]->ui.flags.fast) { - /* - * If primary status was received and ending status is missing, - * the device driver won't be notified on the ending status - * if early (fast) interrupt notification was requested. - * Therefore we have to queue the next incoming request. If - * halt_IO() is issued while there is a request queued, a HSCH - * needs to be issued and the queued request must be deleted - * but its intparm must be returned (see halt_IO() processing) - */ - if (ioinfo[irq]->ui.flags.w4final - && !ioinfo[irq]->ui.flags.doio_q) { - ioinfo[irq]->qflag = flag; - ioinfo[irq]->qcpa = cpa; - ioinfo[irq]->qintparm = user_intparm; - ioinfo[irq]->qlpm = lpm; - } else { - ret = -EBUSY; - - } } else { ret = -EBUSY; @@ -3004,47 +2967,6 @@ */ dp->intparm = 0; - /* - * Was there anything queued ? Start the pending channel program - * if there is one. - */ - if (ioinfo[irq]->ui.flags.doio_q) { - int ret; - int do_cancel = - ioinfo[irq]-> - qflag & DOIO_CANCEL_ON_TIMEOUT; - - ret = s390_start_IO (irq, - ioinfo[irq]->qcpa, - ioinfo[irq]-> - qintparm, - ioinfo[irq]->qlpm, - ioinfo[irq]-> - qflag); - - ioinfo[irq]->ui.flags.doio_q = 0; - - /* - * If s390_start_IO() failed call the device's interrupt - * handler, the IRQ related devstat area was setup by - * s390_start_IO() accordingly already (status pending - * condition). - */ - if (ret) { - ioinfo[irq]->irq_desc. - handler (irq, udp, NULL); - - } - - /* - * better cancel the io when we time out... - */ - if ((ret == -ETIMEDOUT) && do_cancel) { - cancel_IO (irq); - } - - } - } else { ioinfo[irq]->ui.flags.w4final = 1; @@ -3098,32 +3020,19 @@ ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER; ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS; - /* - * When we find a device "not oper" we save the status - * information into the device status area and call the - * device specific interrupt handler. - * - * Note: currently we don't have any way to reenable - * the device unless an unsolicited interrupt - * is presented. We don't check for spurious - * interrupts on "not oper" conditions. - */ - - if ((ioinfo[irq]->ui.flags.fast) - && (ioinfo[irq]->ui.flags.w4final)) { - /* - * If a new request was queued already, we have - * to simulate the "not oper" status for the - * queued request by switching the "intparm" value - * and notify the interrupt handler. - */ - if (ioinfo[irq]->ui.flags.doio_q) { - ioinfo[irq]->devstat.intparm = - ioinfo[irq]->qintparm; - } - } + /* + * When we find a device "not oper" we save the status + * information into the device status area and call the + * device specific interrupt handler. + * + * Note: currently we don't have any way to reenable + * the device unless an unsolicited interrupt + * is presented. We don't check for spurious + * interrupts on "not oper" conditions. + */ + ioinfo[irq]->ui.flags.fast = 0; ioinfo[irq]->ui.flags.repall = 0; ioinfo[irq]->ui.flags.w4final = 0; @@ -3175,9 +3084,8 @@ * without having to delay I/O processing (by queueing) * for non-console devices. * - * Setting of this isc is done by set_cons_dev(), while - * reset_cons_dev() resets this isc and re-enables the - * default isc3 for this device. wait_cons_dev() allows + * Setting of this isc is done by set_cons_dev(). + * wait_cons_dev() allows * to actively wait on an interrupt for this device in * disabed state. When the interrupt condition is * encountered, wait_cons_dev(9 calls do_IRQ() to have @@ -3229,52 +3137,6 @@ } int -reset_cons_dev (int irq) -{ - int rc = 0; - int ccode; - char dbf_txt[15]; - - SANITY_CHECK (irq); - - if (cons_dev != -1) - return -EBUSY; - - sprintf (dbf_txt, "rcons%x", irq); - CIO_TRACE_EVENT (4, dbf_txt); - - /* - * reset the indicated console device to operate - * on default console interrupt sublass 3 - */ - ccode = stsch (irq, &(ioinfo[irq]->schib)); - - if (ccode) { - rc = -ENODEV; - ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER; - } else { - - ioinfo[irq]->schib.pmcw.isc = 3; - - ccode = msch (irq, &(ioinfo[irq]->schib)); - - if (ccode) { - rc = -EIO; - } else { - cons_dev = -1; - - /* - * disable special console I/O-interrupt sublass 7 - */ - ctl_clear_bit(6, 24); - - } - } - - return (rc); -} - -int wait_cons_dev (int irq) { int rc = 0; @@ -3376,10 +3238,8 @@ cr6 |= 0x04000000; /* disable standard isc 3 */ cr6 &= 0xEFFFFFFF; - /* disable console isc 7, - * if neccessary */ - if (cons_dev != -1) - cr6 &= 0xFEFFFFFF; + /* disable console isc 7 */ + cr6 &= 0xFEFFFFFF; ioinfo[irq]->ui.flags.syncio = 1; __ctl_load (cr6, 6, 6); rc = 0; @@ -3500,10 +3360,8 @@ cr6 &= 0xFBFFFFFF; /* enable standard isc 3 */ cr6 |= 0x10000000; - /* enable console isc 7, - * if neccessary */ - if (cons_dev != -1) - cr6 |= 0x01000000; + /* enable console isc 7 */ + cr6 |= 0x01000000; __ctl_load (cr6, 6, 6); retry2 = 0; @@ -4515,69 +4373,50 @@ int irq_ret; devstat_t devstat; - irq_ret = request_irq (irq, - init_IRQ_handler, - SA_PROBE, "INIT", &devstat); + if (ioinfo[irq]->ui.flags.pgid_supp) + irq_ret = request_irq (irq, + init_IRQ_handler, + SA_PROBE | SA_DOPATHGROUP, + "INIT", &devstat); + else + irq_ret = request_irq (irq, + init_IRQ_handler, + SA_PROBE, "INIT", &devstat); if (!irq_ret) { ret = enable_cpu_sync_isc (irq); if (!ret) { - pgid_t pgid; - int i, mask; - /* - * First thing we should do is a sensePGID in - * order to find out how we can proceed with - * the recognition process. - * An unfriendly (locked by so else) device - * won't take kindly to our attempts at - * SetPGID and SenseID... - */ - - memcpy(&pgid, global_pgid, sizeof(pgid_t)); - - ret = -EAGAIN; - for (i=0; i<8 && ret==-EAGAIN; i++) { - - mask = (0x80 >> i) & ioinfo[irq]->opm; - - if (!mask) - continue; - - ret = s390_SensePGID(irq, mask, &pgid); - + ioinfo[irq]->ui.flags.unknown = 0; + + memset (&ioinfo[irq]->senseid, '\0', + sizeof (senseid_t)); + + if (cio_sid_with_pgid) { + + ret = s390_DevicePathVerification(irq,0); + if (ret == -EOPNOTSUPP) /* * Doesn't prevent us from proceeding */ ret = 0; - } - - if (!ret && !ioinfo[irq]->ui.flags.unfriendly) { - - ioinfo[irq]->ui.flags.unknown = 0; - - memset (&ioinfo[irq]->senseid, '\0', - sizeof (senseid_t)); - - if (cio_sid_with_pgid) { - - ret = s390_DevicePathVerification(irq,0); - - if (ret == -EOPNOTSUPP) - /* - * Doesn't prevent us from proceeding - */ - ret = 0; + + /* + * we'll fallthrough here if we don't want + * to do SPID before SID + */ + if (!ret) { + ret = s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff); + if (ret == -ETIMEDOUT) { + /* SenseID timed out. + * We consider this device to be + * boxed for now. + */ + ioinfo[irq]->ui.flags.unfriendly = 1; } - /* - * we'll fallthrough here if we don't want - * to do SPID before SID - */ - if (!ret) { - s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff); #if 0 /* FIXME */ /* * We initially check the configuration data for @@ -4620,7 +4459,6 @@ } } #endif - } } disable_cpu_sync_isc (irq); @@ -4628,7 +4466,7 @@ free_irq (irq, &devstat); - } + } } } @@ -4716,6 +4554,13 @@ return -EBUSY; } + /* + * This function is called by dasd if it just executed a "steal lock". + * Therefore, re-initialize the 'unfriendly' flag to 0. + * We run into timeouts if the device is still boxed... + */ + ioinfo[irq]->ui.flags.unfriendly = 0; + s390_device_recognition_irq(irq); return 0; @@ -4897,8 +4742,6 @@ if (ioinfo[irq]->st) return -ENODEV; - ioinfo[irq]->ui.flags.pgid_supp = 1; - ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom; @@ -5577,7 +5420,7 @@ if (!ioinfo[irq]->ui.flags.unknown) irq_ret = 0; - else + else if (irq_ret != -ETIMEDOUT) irq_ret = -ENODEV; return (irq_ret); @@ -5845,9 +5688,24 @@ "No logical path for sch %d...\n", irq); - if (ioinfo[irq]->nopfunc) - ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); - + if (ioinfo[irq]->nopfunc) { + if (ioinfo[irq]->ui.flags.notacccap) + ioinfo[irq]->nopfunc(irq, + DEVSTAT_NOT_ACC); + else { + not_oper_handler_func_t nopfunc = + ioinfo[irq]->nopfunc; +#ifdef CONFIG_PROC_FS + /* remove procfs entry */ + if (cio_proc_devinfo) + cio_procfs_device_remove + (ioinfo[irq]->devno); +#endif + free_irq(irq, + ioinfo[irq]->irq_desc.dev_id); + nopfunc(irq, DEVSTAT_DEVICE_GONE); + } + } return -ENODEV; } if (!old_opm) { @@ -5905,7 +5763,9 @@ return 0; } - return s390_do_path_verification (irq, usermask); + if (ioinfo[irq]->ui.flags.ready) + return s390_do_path_verification (irq, usermask); + return 0; } @@ -7249,10 +7109,15 @@ s390irq_spin_unlock(irq); - /* Tell the device driver not to disturb us. */ + /* + * Tell the device driver not to disturb us. + * If the driver is not capable of handling + * DEVSTAT_NOT_ACC, it doesn't want path grouping anyway. + */ if (ioinfo[irq]->ui.flags.ready && schib->pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) { + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) { if (err) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR); else @@ -7387,7 +7252,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && ioinfo[irq]->schib.pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); ioinfo[irq]->ui.flags.noio = 1; @@ -7463,7 +7329,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && ioinfo[irq]->schib.pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); ioinfo[irq]->ui.flags.noio = 1; @@ -7489,11 +7356,41 @@ } } +static int +__get_chpid_from_lir(void *data) +{ + struct lir { + u8 iq; + u8 ic; + u16 sci; + /* incident-node descriptor */ + u32 indesc[28]; + /* attached-node descriptor */ + u32 andesc[28]; + /* incident-specific information */ + u32 isinfo[28]; + } *lir; + + lir = (struct lir*) data; + if (!(lir->iq&0x80)) + /* NULL link incident record */ + return -EINVAL; + if (!(lir->indesc[0]&0xc0000000)) + /* node descriptor not valid */ + return -EINVAL; + if (!(lir->indesc[0]&0x10000000)) + /* don't handle device-type nodes - FIXME */ + return -EINVAL; + /* Byte 3 contains the chpid. Could also be CTCA, but we don't care */ + + return (u16) (lir->indesc[0]&0x000000ff); +} + void s390_process_css( void ) { - int ccode, do_sei; + int ccode, do_sei, chpid; CIO_TRACE_EVENT( 2, "prcss"); @@ -7646,9 +7543,11 @@ chsc_area_sei->response_block. response_block_data.sei_res.rsid); - s390_do_chpid_processing(chsc_area_sei->response_block. - response_block_data.sei_res.rsid); - + chpid = __get_chpid_from_lir(chsc_area_sei->response_block. + response_block_data.sei_res. + ccdf); + if (chpid >= 0) + s390_do_chpid_processing(chpid); break; case 2: /* i/o resource accessibiliy */ @@ -7788,7 +7687,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && schib->pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) { + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) { if (err) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC_ERR); else @@ -7823,7 +7723,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && schib->pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); ioinfo[irq]->ui.flags.noio = 1; @@ -8198,7 +8099,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && schib->pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); if (out) @@ -8228,7 +8130,8 @@ /* Tell the device driver not to disturb us. */ if (ioinfo[irq]->ui.flags.ready && schib->pmcw.pim != 0x80 && - ioinfo[irq]->nopfunc) + ioinfo[irq]->nopfunc && + ioinfo[irq]->ui.flags.notacccap) ioinfo[irq]->nopfunc(irq, DEVSTAT_NOT_ACC); ioinfo[irq]->ui.flags.noio = 1; @@ -8238,10 +8141,7 @@ /* Wait for interrupt. */ break; - if (ioinfo[irq]->ui.flags.ready) - s390_schedule_path_verification(irq); - else - ioinfo[irq]->ui.flags.noio = 0; + s390_schedule_path_verification(irq); break; } @@ -9256,7 +9156,6 @@ #ifdef CIO_DEBUG_IO printk("/proc/chpids: '%s'\n", buffer); #endif /* CIO_DEBUG_IO */ - CIO_MSG_EVENT( 2, "/proc/chpids: '%s'\n", buffer); cio_parse_chpids_proc_parameters(buffer); diff -urN linux-2.4.24/drivers/sbus/char/flash.c linux-2.4.25/drivers/sbus/char/flash.c --- linux-2.4.24/drivers/sbus/char/flash.c 2001-10-10 23:42:47.000000000 -0700 +++ linux-2.4.25/drivers/sbus/char/flash.c 2004-02-18 05:36:31.000000000 -0800 @@ -161,10 +161,13 @@ { struct sbus_bus *sbus; struct sbus_dev *sdev = 0; +#ifdef CONFIG_PCI struct linux_ebus *ebus; struct linux_ebus_device *edev = 0; struct linux_prom_registers regs[2]; - int len, err, nregs; + int len, nregs; +#endif + int err; for_all_sbusdev(sdev, sbus) { if (!strcmp(sdev->prom_name, "flashprom")) { diff -urN linux-2.4.24/drivers/scsi/3w-xxxx.c linux-2.4.25/drivers/scsi/3w-xxxx.c --- linux-2.4.24/drivers/scsi/3w-xxxx.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/3w-xxxx.c 2004-02-18 05:36:31.000000000 -0800 @@ -173,6 +173,8 @@ 1.02.00.035 - Improve tw_allocate_memory() memory allocation. Fix tw_chrdev_ioctl() to sleep correctly. 1.02.00.036 - Increase character ioctl timeout to 60 seconds. + 1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds + for 'smartmontools' support. */ #include @@ -240,7 +242,7 @@ }; /* Globals */ -char *tw_driver_version="1.02.00.036"; +char *tw_driver_version="1.02.00.037"; TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; int tw_device_extension_count = 0; static int twe_major = -1; @@ -1930,12 +1932,15 @@ } passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id]; - passthru->sg_list[0].length = passthru->sector_count*512; - if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) { - printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length); - return 1; + /* Don't load sg_list for non-data ATA cmds */ + if ((passthru->param != 0) && (passthru->param != 0x8)) { + passthru->sg_list[0].length = passthru->sector_count*512; + if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) { + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length); + return 1; + } + passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id]; } - passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id]; tw_post_command_packet(tw_dev, request_id); return 0; case TW_CMD_PACKET: @@ -2186,7 +2191,14 @@ switch (ioctl->opcode) { case TW_ATA_PASSTHRU: passthru = (TW_Passthru *)ioctl->data; - memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512); + /* Don't return data for non-data ATA cmds */ + if ((passthru->param != 0) && (passthru->param != 0x8)) + memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512); + else { + /* For non-data cmds, return cmd pkt */ + if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command)) + memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command)); + } break; case TW_CMD_PACKET_WITH_DATA: dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n"); diff -urN linux-2.4.24/drivers/scsi/53c7xx.c linux-2.4.25/drivers/scsi/53c7xx.c --- linux-2.4.24/drivers/scsi/53c7xx.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/53c7xx.c 2004-02-18 05:36:31.000000000 -0800 @@ -1104,8 +1104,8 @@ } /* - * Function : static int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, - * int chip, u32 base, int io_port, int irq, int dma, long long options, + * Function : int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, + * unsigned long base, int io_port, int irq, int dma, long long options, * int clock); * * Purpose : initializes a NCR53c7,8x0 based on base addresses, diff -urN linux-2.4.24/drivers/scsi/53c7xx.h linux-2.4.25/drivers/scsi/53c7xx.h --- linux-2.4.24/drivers/scsi/53c7xx.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/53c7xx.h 2004-02-18 05:36:31.000000000 -0800 @@ -1600,5 +1600,9 @@ /* Paranoid people could use panic() here. */ #define FATAL(host) shutdown((host)); +extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, + unsigned long base, int io_port, int irq, int dma, + long long options, int clock); + #endif /* NCR53c710_C */ #endif /* NCR53c710_H */ diff -urN linux-2.4.24/drivers/scsi/Config.in linux-2.4.25/drivers/scsi/Config.in --- linux-2.4.24/drivers/scsi/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -237,7 +237,7 @@ if [ "$CONFIG_AMIGA" = "y" ]; then dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4000T SCSI support (EXPERIMENTAL)' CONFIG_A4000T_SCSI + bool 'Amiga NCR53c710 SCSI support (EXPERIMENTAL)' CONFIG_SCSI_AMIGA7XX fi fi if [ "$CONFIG_ZORRO" = "y" ]; then @@ -249,12 +249,8 @@ dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'A4091 SCSI support (EXPERIMENTAL)' CONFIG_A4091_SCSI - bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI - bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI -# bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI fi fi diff -urN linux-2.4.24/drivers/scsi/Makefile linux-2.4.25/drivers/scsi/Makefile --- linux-2.4.24/drivers/scsi/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -33,10 +33,7 @@ obj-$(CONFIG_SCSI) += scsi_mod.o -obj-$(CONFIG_A4000T_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_A4091_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_BLZ603EPLUS_SCSI) += amiga7xx.o 53c7xx.o -obj-$(CONFIG_WARPENGINE_SCSI) += amiga7xx.o 53c7xx.o +obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o diff -urN linux-2.4.24/drivers/scsi/NCR53C9x.h linux-2.4.25/drivers/scsi/NCR53C9x.h --- linux-2.4.24/drivers/scsi/NCR53C9x.h 2001-09-14 14:40:00.000000000 -0700 +++ linux-2.4.25/drivers/scsi/NCR53C9x.h 2004-02-18 05:36:31.000000000 -0800 @@ -639,8 +639,7 @@ /* External functions */ -extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, - unchar cmd); +extern void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, unchar cmd); extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *); extern void esp_deallocate(struct NCR_ESP *); extern void esp_release(void); diff -urN linux-2.4.24/drivers/scsi/aha152x.c linux-2.4.25/drivers/scsi/aha152x.c --- linux-2.4.24/drivers/scsi/aha152x.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/scsi/aha152x.c 2004-02-18 05:36:31.000000000 -0800 @@ -222,10 +222,6 @@ #include -#if defined(PCMCIA) -#undef MODULE -#endif - #include #include #include @@ -254,6 +250,10 @@ #include +#if defined(PCMCIA) +#undef MODULE +#endif + /* DEFINES */ /* For PCMCIA cards, always use AUTOCONF */ @@ -3951,7 +3951,9 @@ return thislength < length ? thislength : length; } +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = AHA152X; #include "scsi_module.c" +#endif diff -urN linux-2.4.24/drivers/scsi/aha1542.c linux-2.4.25/drivers/scsi/aha1542.c --- linux-2.4.24/drivers/scsi/aha1542.c 2001-10-12 15:35:53.000000000 -0700 +++ linux-2.4.25/drivers/scsi/aha1542.c 2004-02-18 05:36:31.000000000 -0800 @@ -111,8 +111,6 @@ static int setup_busoff[MAXBOARDS]; static int setup_dmaspeed[MAXBOARDS] __initdata = { -1, -1, -1, -1 }; -static char *setup_str[MAXBOARDS] __initdata; - /* * LILO/Module params: aha1542=[,,[,]] * @@ -960,6 +958,7 @@ #ifndef MODULE static int setup_idx = 0; +static char *setup_str[MAXBOARDS] __initdata; void __init aha1542_setup(char *str, int *ints) { diff -urN linux-2.4.24/drivers/scsi/amiga7xx.c linux-2.4.25/drivers/scsi/amiga7xx.c --- linux-2.4.24/drivers/scsi/amiga7xx.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/scsi/amiga7xx.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,6 +1,6 @@ /* * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux. - * Amiga MacroSystemUS WarpEngine SCSI controller. + * Amiga MacroSystemUS WarpEngine SCSI controller. * Amiga Technologies A4000T SCSI controller. * Amiga Technologies/DKB A4091 SCSI controller. * @@ -14,13 +14,13 @@ #include #include #include +#include #include #include #include #include #include - #include #include "scsi.h" @@ -28,107 +28,83 @@ #include "53c7xx.h" #include "amiga7xx.h" -#include - -extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); -int __init amiga7xx_detect(Scsi_Host_Template *tpnt) +static int amiga7xx_register_one(Scsi_Host_Template *tpnt, + unsigned long address) { - static unsigned char called = 0; - int num = 0, clock; long long options; - struct zorro_dev *z = NULL; - unsigned long address; + int clock; - if (called || !MACH_IS_AMIGA) + if (!request_mem_region(address, 0x1000, "ncr53c710")) return 0; - tpnt->proc_name = "Amiga7xx"; + address = (unsigned long)z_ioremap(address, 0x1000); + options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | OPTION_INTFLY | + OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS | + OPTION_DISCONNECT; + clock = 50000000; /* 50 MHz SCSI Clock */ + ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE, + options, clock); + return 1; +} -#ifdef CONFIG_A4000T_SCSI - if (AMIGAHW_PRESENT(A4000_SCSI)) { - address = 0xdd0040; - if (request_mem_region(address, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE, - options, clock); - num++; - } - } -#endif + +#ifdef CONFIG_ZORRO + +static struct { + zorro_id id; + unsigned long offset; + int absolute; /* offset is absolute address */ +} amiga7xx_table[] = { + { .id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, .offset = 0xf40000, + .absolute = 1 }, + { .id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, .offset = 0x40000 }, + { .id = ZORRO_PROD_CBM_A4091_1, .offset = 0x800000 }, + { .id = ZORRO_PROD_CBM_A4091_2, .offset = 0x800000 }, + { .id = ZORRO_PROD_GVP_GFORCE_040_060, .offset = 0x40000 }, + { 0 } +}; + +static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt) +{ + int num = 0, i; + struct zorro_dev *z = NULL; + unsigned long address; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - unsigned long address = z->resource.start; - unsigned long size = z->resource.end-z->resource.start+1; - switch (z->id) { -#ifdef CONFIG_BLZ603EPLUS_SCSI - case ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS: - address = 0xf40000; - if (request_mem_region(address, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, - DMA_NONE, options, clock); - num++; - } + for (i = 0; amiga7xx_table[i].id; i++) + if (z->id == amiga7xx_table[i].id) break; -#endif + if (!amiga7xx_table[i].id) + continue; + if (amiga7xx_table[i].absolute) + address = amiga7xx_table[i].offset; + else + address = z->resource.start + amiga7xx_table[i].offset; + num += amiga7xx_register_one(tpnt, address); + } + return num; +} -#ifdef CONFIG_WARPENGINE_SCSI - case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx: - if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - address = (unsigned long)z_ioremap(address, size); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } - break; -#endif +#endif /* CONFIG_ZORRO */ -#ifdef CONFIG_A4091_SCSI - case ZORRO_PROD_CBM_A4091_1: - case ZORRO_PROD_CBM_A4091_2: - if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) { - address = (unsigned long)z_ioremap(address, size); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x800000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } - break; -#endif -#ifdef CONFIG_GVP_TURBO_SCSI - case ZORRO_PROD_GVP_GFORCE_040_060: - if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) { - address = ZTWO_VADDR(address); - options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 | - OPTION_INTFLY | OPTION_SYNCHRONOUS | - OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT; - clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0, - IRQ_AMIGA_PORTS, DMA_NONE, options, clock); - num++; - } +int __init amiga7xx_detect(Scsi_Host_Template *tpnt) +{ + static unsigned char called = 0; + int num = 0; + + if (called || !MACH_IS_AMIGA) + return 0; + + tpnt->proc_name = "Amiga7xx"; + + if (AMIGAHW_PRESENT(A4000_SCSI)) + num += amiga7xx_register_one(tpnt, 0xdd0040); + +#ifdef CONFIG_ZORRO + num += amiga7xx_zorro_detect(tpnt); #endif - } - } called = 1; return num; diff -urN linux-2.4.24/drivers/scsi/bvme6000.c linux-2.4.25/drivers/scsi/bvme6000.c --- linux-2.4.24/drivers/scsi/bvme6000.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/scsi/bvme6000.c 2004-02-18 05:36:31.000000000 -0800 @@ -23,9 +23,6 @@ #include -extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); int bvme6000_scsi_detect(Scsi_Host_Template *tpnt) { diff -urN linux-2.4.24/drivers/scsi/changelog.megaraid2 linux-2.4.25/drivers/scsi/changelog.megaraid2 --- linux-2.4.24/drivers/scsi/changelog.megaraid2 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/changelog.megaraid2 2004-02-18 05:36:31.000000000 -0800 @@ -1,3 +1,31 @@ +### Version 2.10.1 +Wed Dec 3 15:34:42 EST 2003 - Atul Mukker +1. pci_dma_sync_sg(), 2nd argument is pointer to scatter-gather list. All + previous drivers have a pointer which is incremented beyond the end of + the scatter-gather list +2. Remove 'ipdev', pci device pointer, to allocate memory for internal + commands. pci_alloc_consistent() guaranteed to allocate memory below + 4GB, which is a requirement for these commands - + Tom Coughlan +3. Added support for LSI SATA PCI-X controllers +4. Advanced Server 3.0 version of the driver is the reference driver now. + For all other kernels, we create patches. +5. Removed superfluous white spaces. +6. Corrected some comments + +### Version 2.10.0 +Tue Nov 4 14:33:43 EST 2003 - Atul Mukker +1. Added vendor ids and device ids for PCI-Express controllers, + PERC4E/Si, PERC4E/Di, PERC4E/DC, PERC4E/SC +2. Backport some minor changes from 2.6 kernel version of the driver. + +### Version 2.00.9a +Fri Oct 3 18:04:29 EDT 2003 - Atul Mukker +1. Minor changes which are brough in when sync'ing with kernel 2.9-test6. +2. Use sizeof(mbox_t) in synchronous routines instead of hard-coded value + of 16 bytes. +3. De-couple adapter->host->pci_dev. Replace with adapter->pdev + ### Version 2.00.9 Thu Sep 4 17:49:42 EDT 2003 - Atul Mukker i. For extended passthru commands, 64-bit scatter-gather list and 64-bit diff -urN linux-2.4.24/drivers/scsi/cpqfcTSi2c.c linux-2.4.25/drivers/scsi/cpqfcTSi2c.c --- linux-2.4.24/drivers/scsi/cpqfcTSi2c.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/scsi/cpqfcTSi2c.c 2004-02-18 05:36:31.000000000 -0800 @@ -59,7 +59,6 @@ #define SLAVE_WRITE_ADDRESS 0xA0 -static void i2c_delay(u32 mstime); static void tl_i2c_clock_pulse(u8, void *GPIOout); static u8 tl_read_i2c_data(void *); diff -urN linux-2.4.24/drivers/scsi/cpqfcTSstructs.h linux-2.4.25/drivers/scsi/cpqfcTSstructs.h --- linux-2.4.24/drivers/scsi/cpqfcTSstructs.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/scsi/cpqfcTSstructs.h 2004-02-18 05:36:31.000000000 -0800 @@ -219,7 +219,6 @@ #define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept #define ELS_RJT 0x1000000 #define SCSI_REPORT_LUNS 0x0A0 -#define REPORT_LUNS 0xA0 // SCSI-3 command op-code #define FCP_TARGET_RESET 0x200 #define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame diff -urN linux-2.4.24/drivers/scsi/fdomain.c linux-2.4.25/drivers/scsi/fdomain.c --- linux-2.4.24/drivers/scsi/fdomain.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/scsi/fdomain.c 2004-02-18 05:36:31.000000000 -0800 @@ -2046,7 +2046,9 @@ MODULE_LICENSE("GPL"); +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = FDOMAIN_16X0; #include "scsi_module.c" +#endif diff -urN linux-2.4.24/drivers/scsi/ips.c linux-2.4.25/drivers/scsi/ips.c --- linux-2.4.24/drivers/scsi/ips.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/ips.c 2004-02-18 05:36:31.000000000 -0800 @@ -131,6 +131,8 @@ /* 5.30.00 - use __devexit_p() */ /* 6.00.00 - Add 6x Adapters and Battery Flash */ /* 6.10.00 - Remove 1G Addressing Limitations */ +/* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */ +/* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */ /*****************************************************************************/ /* @@ -196,11 +198,11 @@ /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "6.10" -#define IPS_VERSION_LOW ".24 " +#define IPS_VERSION_HIGH "6.11" +#define IPS_VERSION_LOW ".07 " -#if !defined(__i386__) && !defined(__ia64__) -#error "This driver has only been tested on the x86/ia64 platforms" +#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) +#warning "This driver has only been tested on the x86/ia64/x86_64 platforms" #endif #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) @@ -245,6 +247,7 @@ static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */ static int ips_cd_boot; /* Booting from Manager CD */ static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ +static dma_addr_t ips_flashbusaddr; static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ static Scsi_Host_Template ips_driver_template = IPS; @@ -468,8 +471,7 @@ static int ips_host_info(ips_ha_t *, char *, off_t, int); static void copy_mem_info(IPS_INFOSTR *, char *, int); static int copy_info(IPS_INFOSTR *, char *, ...); -static int ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer, - int intr); +static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr); static void ips_version_check(ips_ha_t * ha, int intr); static int ips_abort_init(ips_ha_t * ha, int index); static int ips_init_phase2(int index); @@ -559,17 +561,6 @@ ips_setup(ips); #endif - /* If Booting from the Manager CD, Allocate a large Flash */ - /* Buffer ( so we won't need to allocate one for each adapter ). */ - if (ips_cd_boot) { - ips_FlashData = (char *) __get_free_pages(IPS_INIT_GFP, 7); - if (ips_FlashData == NULL) { - /* The validity of this pointer is checked in ips_make_passthru() before it is used */ - printk(KERN_WARNING - "ERROR: Can't Allocate Large Buffer for Flashing\n"); - } - } - SHT->proc_info = ips_proc_info; SHT->proc_name = "ips"; @@ -1578,21 +1569,20 @@ ips_alloc_passthru_buffer(ips_ha_t * ha, int length) { void *bigger_buf; - int count; - int order; + dma_addr_t dma_busaddr; - if (ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order)) + if (ha->ioctl_data && length <= ha->ioctl_len) return 0; /* there is no buffer or it's not big enough, allocate a new one */ - for (count = PAGE_SIZE, order = 0; - count < length; order++, count <<= 1) ; - bigger_buf = (void *) __get_free_pages(IPS_ATOMIC_GFP, order); + bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr); if (bigger_buf) { /* free the old memory */ - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); + pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data, + ha->ioctl_busaddr); /* use the new memory */ ha->ioctl_data = (char *) bigger_buf; - ha->ioctl_order = order; + ha->ioctl_len = length; + ha->ioctl_busaddr = dma_busaddr; } else { return -1; } @@ -1708,7 +1698,7 @@ static int ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) { - int datasize, count; + int datasize; /* Trombone is the only copperhead that can do packet flash, but only * for firmware. No one said it had to make sence. */ @@ -1728,24 +1718,28 @@ pt->BasicStatus = 0; return ips_flash_bios(ha, pt, scb); } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) { - if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)) { + if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){ ha->flash_data = ips_FlashData; - ha->flash_order = 7; + ha->flash_busaddr = ips_flashbusaddr; + ha->flash_len = PAGE_SIZE << 7; ha->flash_datasize = 0; } else if (!ha->flash_data) { datasize = pt->CoppCP.cmd.flashfw.total_packets * pt->CoppCP.cmd.flashfw.count; - for (count = PAGE_SIZE, ha->flash_order = 0; - count < datasize; ha->flash_order++, count <<= 1) ; - ha->flash_data = - (char *) __get_free_pages(IPS_ATOMIC_GFP, - ha->flash_order); + ha->flash_data = pci_alloc_consistent(ha->pcidev, + datasize, + &ha->flash_busaddr); + if (!ha->flash_data){ + printk(KERN_WARNING "Unable to allocate a flash buffer\n"); + return IPS_FAILURE; + } ha->flash_datasize = 0; + ha->flash_len = datasize; } else return IPS_FAILURE; } else { if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize > - (PAGE_SIZE << ha->flash_order)) { + ha->flash_len) { ips_free_flash_copperhead(ha); printk(KERN_WARNING "failed size sanity check\n"); return IPS_FAILURE; @@ -1928,7 +1922,8 @@ if (ha->flash_data == ips_FlashData) test_and_clear_bit(0, &ips_FlashDataInUse); else if (ha->flash_data) - free_pages((unsigned long) ha->flash_data, ha->flash_order); + pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data, + ha->flash_busaddr); ha->flash_data = NULL; } @@ -1981,12 +1976,7 @@ if (pt->CmdBSize) { scb->data_len = pt->CmdBSize; - scb->data_busaddr = pci_map_single(ha->pcidev, - ha->ioctl_data + - sizeof (ips_passthru_t), - pt->CmdBSize, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t); } else { scb->data_busaddr = 0L; } @@ -2410,9 +2400,7 @@ } else { /* Morpheus Family - Send Command to the card */ - buffer = kmalloc(0x1000, IPS_ATOMIC_GFP); - if (!buffer) - return; + buffer = ha->ioctl_data; memset(buffer, 0, 0x1000); @@ -2431,11 +2419,7 @@ scb->cmd.flashfw.total_packets = 1; scb->cmd.flashfw.packet_num = 0; scb->data_len = 0x1000; - scb->data_busaddr = - pci_map_single(ha->pcidev, buffer, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.flashfw.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr; /* issue the command */ if ( @@ -2443,7 +2427,6 @@ IPS_FAILURE) || (ret == IPS_SUCCESS_IMM) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) { /* Error occurred */ - kfree(buffer); return; } @@ -2453,11 +2436,8 @@ minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */ subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */ } else { - kfree(buffer); return; } - - kfree(buffer); } ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4]; @@ -2806,6 +2786,11 @@ scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]]; + /* Allow a WRITE BUFFER Command to Have no Data */ + /* This is Used by Tape Flash Utilites */ + if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0)) + scb->dcdb.cmd_attribute = 0; + if (!(scb->dcdb.cmd_attribute & 0x3)) scb->dcdb.transfer_length = 0; @@ -3786,23 +3771,14 @@ scb->scsi_cmd->result = DID_OK << 16; } } else { - scb->cmd.logical_info.op_code = - IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = - IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; + scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; - scb->data_len = - sizeof (ha->adapt->logical_drive_info); - scb->data_busaddr = - pci_map_single(ha->pcidev, - &ha->adapt-> - logical_drive_info, - scb->data_len, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - scb->cmd.logical_info.buffer_addr = - scb->data_busaddr; + scb->data_len = sizeof (IPS_LD_INFO); + scb->data_busaddr = ha->logical_drive_info_dma_addr; + scb->flags = 0; + scb->cmd.logical_info.buffer_addr = scb->data_busaddr; ret = IPS_SUCCESS; } @@ -3930,28 +3906,19 @@ scb->cmd.basic_io.segment_4G = 0; scb->cmd.basic_io.enhanced_sg = 0; scb->data_len = sizeof (*ha->enq); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, - scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.basic_io.sg_addr = ha->enq_busaddr; ret = IPS_SUCCESS; break; case READ_CAPACITY: scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO; - scb->cmd.logical_info.command_id = - IPS_COMMAND_ID(ha, scb); + scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.logical_info.reserved = 0; scb->cmd.logical_info.reserved2 = 0; scb->cmd.logical_info.reserved3 = 0; - scb->data_len = sizeof (ha->adapt->logical_drive_info); - scb->data_busaddr = pci_map_single(ha->pcidev, - &ha->adapt-> - logical_drive_info, - scb->data_len, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->data_len = sizeof (IPS_LD_INFO); + scb->data_busaddr = ha->logical_drive_info_dma_addr; + scb->flags = 0; scb->cmd.logical_info.buffer_addr = scb->data_busaddr; ret = IPS_SUCCESS; break; @@ -4275,19 +4242,17 @@ return (0); if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) { - memset(&ha->adapt->logical_drive_info, 0, - sizeof (ha->adapt->logical_drive_info)); - - return (0); + memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO)); + return (0); } - if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + if (ha->logical_drive_info->drive_info[scb->target_id].state != IPS_LD_OFFLINE - && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + && ha->logical_drive_info->drive_info[scb->target_id].state != IPS_LD_FREE - && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + && ha->logical_drive_info->drive_info[scb->target_id].state != IPS_LD_CRS - && ha->adapt->logical_drive_info.drive_info[scb->target_id].state != + && ha->logical_drive_info->drive_info[scb->target_id].state != IPS_LD_SYS) return (1); else return (0); @@ -4349,7 +4314,7 @@ cap.lba = cpu_to_be32(le32_to_cpu - (ha->adapt->logical_drive_info. + (ha->logical_drive_info-> drive_info[scb->target_id].sector_count) - 1); cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE); @@ -4488,7 +4453,8 @@ if (ha) { if (ha->enq) { - kfree(ha->enq); + pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ), + ha->enq, ha->enq_busaddr); ha->enq = NULL; } @@ -4503,6 +4469,14 @@ sizeof (IPS_IO_CMD), ha->adapt, ha->adapt->hw_status_start); ha->adapt = NULL; + } + + if (ha->logical_drive_info) { + pci_free_consistent(ha->pcidev, + sizeof (IPS_LD_INFO), + ha->logical_drive_info, + ha->logical_drive_info_dma_addr); + ha->logical_drive_info = NULL; } if (ha->nvram) { @@ -4516,11 +4490,11 @@ } if (ha->ioctl_data) { - free_pages((unsigned long) ha->ioctl_data, - ha->ioctl_order); + pci_free_consistent(ha->pcidev, ha->ioctl_len, + ha->ioctl_data, ha->ioctl_busaddr); ha->ioctl_data = NULL; ha->ioctl_datasize = 0; - ha->ioctl_order = 0; + ha->ioctl_len = 0; } ips_deallocatescbs(ha, ha->max_cmds); @@ -4694,6 +4668,7 @@ } ha->scb_freelist = scb->q_next; + scb->flags = 0; scb->q_next = NULL; ips_init_scb(ha, scb); @@ -5861,10 +5836,7 @@ scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; scb->data_len = sizeof (*ha->enq); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, - IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.basic_io.sg_addr = ha->enq_busaddr; /* send command */ if ( @@ -5907,10 +5879,7 @@ scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; scb->data_len = sizeof (*ha->subsys); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; /* send command */ if ( @@ -5919,6 +5888,7 @@ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) return (0); + memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys)); return (1); } @@ -5954,10 +5924,7 @@ scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->data_len = sizeof (*ha->conf); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.basic_io.sg_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr; /* send command */ if ( @@ -5977,7 +5944,8 @@ return (0); } - + + memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf)); return (1); } @@ -6012,11 +5980,10 @@ scb->cmd.nvram.reserved = 0; scb->cmd.nvram.reserved2 = 0; scb->data_len = sizeof (*ha->nvram); - scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.nvram.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; - + scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr; + if (write) + memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram)); + /* issue the command */ if ( ((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == @@ -6027,7 +5994,8 @@ return (0); } - + if (!write) + memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram)); return (1); } @@ -6155,7 +6123,7 @@ scb->cmd.ffdc.op_code = IPS_CMD_FFDC; scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.ffdc.reset_count = 0; - scb->cmd.ffdc.reset_type = 0x80; + scb->cmd.ffdc.reset_type = 0; /* convert time to what the card wants */ ips_fix_ffdc_time(ha, scb, ha->last_ffdc); @@ -6750,16 +6718,18 @@ static void ips_version_check(ips_ha_t * ha, int intr) { - IPS_VERSION_DATA VersionInfo; + IPS_VERSION_DATA *VersionInfo; uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1]; uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1]; int MatchError; - int rc; + int rc; char BiosString[10]; char FirmwareString[10]; METHOD_TRACE("ips_version_check", 1); + VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data; + memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); @@ -6769,10 +6739,11 @@ rc = IPS_FAILURE; if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */ + memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA)); /* Get the Version Info with a Get Version Command */ - rc = ips_get_version_info(ha, &VersionInfo, intr); + rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr); if (rc == IPS_SUCCESS) - memcpy(FirmwareVersion, VersionInfo.compatibilityId, + memcpy(FirmwareVersion, VersionInfo->compatibilityId, IPS_COMPAT_ID_LENGTH); } @@ -6835,14 +6806,13 @@ /* 0 if Successful, else non-zero */ /*---------------------------------------------------------------------------*/ static int -ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer, int intr) +ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr) { ips_scb_t *scb; int rc; METHOD_TRACE("ips_get_version_info", 1); - memset(Buffer, 0, sizeof (IPS_VERSION_DATA)); scb = &ha->scbs[ha->max_cmds - 1]; ips_init_scb(ha, scb); @@ -6854,11 +6824,10 @@ scb->cmd.version_info.reserved = 0; scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA); scb->cmd.version_info.reserved2 = 0; - scb->data_len = sizeof (*Buffer); - scb->data_busaddr = pci_map_single(ha->pcidev, Buffer, - scb->data_len, IPS_DMA_DIR(scb)); - scb->cmd.version_info.buffer_addr = scb->data_busaddr; - scb->flags |= IPS_SCB_MAP_SINGLE; + scb->data_len = sizeof (IPS_VERSION_DATA); + scb->data_busaddr = Buffer; + scb->cmd.version_info.buffer_addr = Buffer; + scb->flags = 0; /* issue command */ rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); @@ -7176,7 +7145,6 @@ uint16_t subdevice_id; int j; int index; - uint32_t count; dma_addr_t dma_address; char *ioremap_ptr; char *mem_ptr; @@ -7292,17 +7260,21 @@ * are guaranteed to be < 4G. */ if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) && - !pci_set_dma_mask(ha->pcidev, (u64) 0xffffffffffffffff)) { + !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) { (ha)->flags |= IPS_HA_ENH_SG; } else { - if (pci_set_dma_mask(ha->pcidev, (u64) 0xffffffff) != 0) { + if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) { printk(KERN_WARNING "Unable to set DMA Mask\n"); return ips_abort_init(ha, index); } } - - ha->enq = kmalloc(sizeof (IPS_ENQ), IPS_INIT_GFP); - + if(ips_cd_boot && !ips_FlashData){ + ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7, + &ips_flashbusaddr); + } + + ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ), + &ha->enq_busaddr); if (!ha->enq) { printk(KERN_WARNING "Unable to allocate host inquiry structure\n"); @@ -7318,15 +7290,24 @@ } ha->adapt->hw_status_start = dma_address; ha->dummy = (void *) (ha->adapt + 1); - - ha->conf = kmalloc(sizeof (IPS_CONF), IPS_INIT_GFP); + + ha->logical_drive_info = pci_alloc_consistent(pci_dev, sizeof (IPS_LD_INFO), + &dma_address); + if (!ha->logical_drive_info) { + printk(KERN_WARNING + "Unable to allocate host logical drive info structure\n"); + return ips_abort_init(ha, index); + } + ha->logical_drive_info_dma_addr = dma_address; + + ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL); if (!ha->conf) { printk(KERN_WARNING "Unable to allocate host conf structure\n"); return ips_abort_init(ha, index); } - ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), IPS_INIT_GFP); + ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL); if (!ha->nvram) { printk(KERN_WARNING @@ -7334,7 +7315,7 @@ return ips_abort_init(ha, index); } - ha->subsys = kmalloc(sizeof (IPS_SUBSYS), IPS_INIT_GFP); + ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL); if (!ha->subsys) { printk(KERN_WARNING @@ -7342,18 +7323,18 @@ return ips_abort_init(ha, index); } - for (count = PAGE_SIZE, ha->ioctl_order = 0; - count < ips_ioctlsize; ha->ioctl_order++, count <<= 1) ; - - ha->ioctl_data = - (char *) __get_free_pages(IPS_INIT_GFP, ha->ioctl_order); - ha->ioctl_datasize = count; + /* the ioctl buffer is now used during adapter initialization, so its + * successful allocation is now required */ + if (ips_ioctlsize < PAGE_SIZE) + ips_ioctlsize = PAGE_SIZE; + + ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize, + &ha->ioctl_busaddr); + ha->ioctl_len = ips_ioctlsize; if (!ha->ioctl_data) { printk(KERN_WARNING "Unable to allocate IOCTL data\n"); - ha->ioctl_data = NULL; - ha->ioctl_order = 0; - ha->ioctl_datasize = 0; + return ips_abort_init(ha, index); } /* diff -urN linux-2.4.24/drivers/scsi/ips.h linux-2.4.25/drivers/scsi/ips.h --- linux-2.4.24/drivers/scsi/ips.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/ips.h 2004-02-18 05:36:31.000000000 -0800 @@ -111,22 +111,13 @@ #define min(x,y) ((x) < (y) ? x : y) #endif + #define pci_dma_hi32(a) ((a >> 16) >> 16) #define pci_dma_lo32(a) (a & 0xffffffff) #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO) #define IPS_ENABLE_DMA64 (1) - #define pci_dma_hi32(a) (a >> 32) #else #define IPS_ENABLE_DMA64 (0) - #define pci_dma_hi32(a) (0) - #endif - - #if defined(__ia64__) - #define IPS_ATOMIC_GFP (GFP_DMA | GFP_ATOMIC) - #define IPS_INIT_GFP GFP_DMA - #else - #define IPS_ATOMIC_GFP GFP_ATOMIC - #define IPS_INIT_GFP GFP_KERNEL #endif /* @@ -734,7 +725,6 @@ volatile PIPS_STATUS p_status_tail; volatile uint32_t hw_status_start; volatile uint32_t hw_status_tail; - IPS_LD_INFO logical_drive_info; } IPS_ADAPTER, *PIPS_ADAPTER; typedef struct { @@ -1092,6 +1082,8 @@ ips_scb_queue_t scb_activelist; /* Active SCB list */ IPS_IO_CMD *dummy; /* dummy command */ IPS_ADAPTER *adapt; /* Adapter status area */ + IPS_LD_INFO *logical_drive_info; /* Logical Drive Info */ + dma_addr_t logical_drive_info_dma_addr; /* Logical Drive Info DMA Address */ IPS_ENQ *enq; /* Adapter Enquiry data */ IPS_CONF *conf; /* Adapter config data */ IPS_NVRAM_P5 *nvram; /* NVRAM page 5 data */ @@ -1109,7 +1101,8 @@ uint16_t device_id; /* PCI device ID */ uint8_t slot_num; /* PCI Slot Number */ uint16_t subdevice_id; /* Subsystem device ID */ - uint8_t ioctl_order; /* Number of pages in ioctl */ + int ioctl_len; /* size of ioctl buffer */ + dma_addr_t ioctl_busaddr; /* dma address of ioctl buffer*/ uint8_t bios_version[8]; /* BIOS Revision */ uint32_t mem_addr; /* Memory mapped address */ uint32_t io_len; /* Size of IO Address */ @@ -1119,8 +1112,10 @@ ips_hw_func_t func; /* hw function pointers */ struct pci_dev *pcidev; /* PCI device handle */ char *flash_data; /* Save Area for flash data */ - u8 flash_order; /* Save Area for flash size order */ + int flash_len; /* length of flash buffer */ u32 flash_datasize; /* Save Area for flash data size */ + dma_addr_t flash_busaddr; /* dma address of flash buffer*/ + dma_addr_t enq_busaddr; /* dma address of enq struct */ uint8_t requires_esl; /* Requires an EraseStripeLock */ } ips_ha_t; @@ -1136,8 +1131,8 @@ uint8_t bus; uint8_t lun; uint8_t cdb[12]; - uint32_t scb_busaddr; - uint32_t data_busaddr; + uint32_t scb_busaddr; + uint32_t old_data_busaddr; // Obsolete field left in to not break utilities uint32_t timeout; uint8_t basic_status; uint8_t extended_status; @@ -1153,6 +1148,7 @@ ips_scb_callback callback; uint32_t sg_busaddr; int sg_count; + dma_addr_t data_busaddr; } ips_scb_t; typedef struct ips_scb_pt { @@ -1208,13 +1204,13 @@ #define IPS_VER_MAJOR 6 #define IPS_VER_MAJOR_STRING "6" -#define IPS_VER_MINOR 10 -#define IPS_VER_MINOR_STRING "10" -#define IPS_VER_BUILD 24 -#define IPS_VER_BUILD_STRING "24" -#define IPS_VER_STRING "6.10.24" -#define IPS_RELEASE_ID 0x00010000 -#define IPS_BUILD_IDENT 1250 +#define IPS_VER_MINOR 11 +#define IPS_VER_MINOR_STRING "11" +#define IPS_VER_BUILD 07 +#define IPS_VER_BUILD_STRING "07" +#define IPS_VER_STRING "6.11.07" +#define IPS_RELEASE_ID 0x00010001 +#define IPS_BUILD_IDENT 2224 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved." #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved." #define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003." @@ -1224,11 +1220,11 @@ #define IPS_VER_SERVERAID2 "2.88.13" #define IPS_VER_NAVAJO "2.88.13" #define IPS_VER_SERVERAID3 "6.10.24" -#define IPS_VER_SERVERAID4H "6.10.24" -#define IPS_VER_SERVERAID4MLx "6.10.24" -#define IPS_VER_SARASOTA "6.10.24" -#define IPS_VER_MARCO "6.10.24" -#define IPS_VER_SEBRING "6.10.24" +#define IPS_VER_SERVERAID4H "6.11.07" +#define IPS_VER_SERVERAID4MLx "6.11.07" +#define IPS_VER_SARASOTA "6.11.07" +#define IPS_VER_MARCO "6.11.07" +#define IPS_VER_SEBRING "6.11.07" /* Compatability IDs for various adapters */ #define IPS_COMPAT_UNKNOWN "" diff -urN linux-2.4.24/drivers/scsi/mac_esp.c linux-2.4.25/drivers/scsi/mac_esp.c --- linux-2.4.24/drivers/scsi/mac_esp.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/scsi/mac_esp.c 2004-02-18 05:36:31.000000000 -0800 @@ -44,7 +44,7 @@ #define mac_turnon_irq(x) mac_enable_irq(x) #define mac_turnoff_irq(x) mac_disable_irq(x) -extern inline void esp_handle(struct NCR_ESP *esp); +extern void esp_handle(struct NCR_ESP *esp); extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count); @@ -148,92 +148,98 @@ #define DRIVER_SETUP /* - * Function : mac_esp_setup(char *str, int *ints) + * Function : mac_esp_setup(char *str) * * Purpose : booter command line initialization of the overrides array, * - * Inputs : str - unused, ints - array of integer parameters with ints[0] - * equal to the number of ints. + * Inputs : str - parameters, separated by commas. * * Currently unused in the new driver; need to add settable parameters to the * detect function. * */ -static int __init mac_esp_setup(char *str, int *ints) { +static int __init mac_esp_setup(char *str) { #ifdef DRIVER_SETUP /* Format of mac53c9x parameter is: * mac53c9x=,,,,,,, * Negative values mean don't change. */ - /* Grmbl... the standard parameter parsing can't handle negative numbers - * :-( So let's do it ourselves! - */ + char *this_opt; + long opt; - int i = ints[0]+1, fact; + this_opt = strsep (&str, ","); + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt >= 0 && opt <= 2) + setup_num_esps = opt; + else if (opt > 2) + printk( "mac_esp_setup: invalid number of hosts %ld !\n", opt ); - while( str && (isdigit(*str) || *str == '-') && i <= 10) { - if (*str == '-') - fact = -1, ++str; - else - fact = 1; - ints[i++] = simple_strtoul( str, NULL, 0 ) * fact; - if ((str = strchr( str, ',' )) != NULL) - ++str; + this_opt = strsep (&str, ","); } - ints[0] = i-1; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); - if (ints[0] < 1) { - printk( "mac_esp_setup: no arguments!\n" ); - return 0; + if (opt > 0) + setup_disconnect = opt; + + this_opt = strsep (&str, ","); } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); - if (ints[0] >= 1) { - if (ints[1] > 0) - /* no limits on this, just > 0 */ - if (ints[1] >= 0 && ints[1] <= 2) - setup_num_esps = ints[1]; - else if (ints[1] > 2) - printk( "mac_esp_setup: invalid number of hosts %d !\n", ints[1] ); - } - if (ints[0] >= 2) { - if (ints[2] > 0) - setup_disconnect = ints[2]; - } - if (ints[0] >= 3) { - if (ints[3] >= 0) { - setup_nosync = ints[3]; - } + if (opt >= 0) + setup_nosync = opt; + + this_opt = strsep (&str, ","); + } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt > 0) + setup_can_queue = opt; + + this_opt = strsep (&str, ","); } - if (ints[0] >= 4) { - if (ints[4] > 0) - /* no limits on this, just > 0 */ - setup_can_queue = ints[4]; - } - if (ints[0] >= 5) { - if (ints[5] > 0) - setup_cmd_per_lun = ints[5]; - } - if (ints[0] >= 6) { - if (ints[6] >= 0) { - setup_sg_tablesize = ints[6]; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt > 0) + setup_cmd_per_lun = opt; + + this_opt = strsep (&str, ","); + } + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + + if (opt >= 0) { + setup_sg_tablesize = opt; /* Must be <= SG_ALL (255) */ if (setup_sg_tablesize > SG_ALL) setup_sg_tablesize = SG_ALL; } + + this_opt = strsep (&str, ","); } - if (ints[0] >= 7) { + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + /* Must be between 0 and 7 */ - if (ints[7] >= 0 && ints[7] <= 7) - setup_hostid = ints[7]; - else if (ints[7] > 7) - printk( "mac_esp_setup: invalid host ID %d !\n", ints[7] ); + if (opt >= 0 && opt <= 7) + setup_hostid = opt; + else if (opt > 7) + printk( "mac_esp_setup: invalid host ID %ld !\n", opt); + + this_opt = strsep (&str, ","); } #ifdef SUPPORT_TAGS - if (ints[0] >= 8) { - if (ints[8] >= 0) - setup_use_tagged_queuing = !!ints[8]; + if(this_opt) { + opt = simple_strtol( this_opt, NULL, 0 ); + if (opt >= 0) + setup_use_tagged_queuing = !!opt; } #endif #endif @@ -242,6 +248,7 @@ __setup("mac53c9x=", mac_esp_setup); + /* * ESP address 'detection' */ diff -urN linux-2.4.24/drivers/scsi/mac_scsi.c linux-2.4.25/drivers/scsi/mac_scsi.c --- linux-2.4.24/drivers/scsi/mac_scsi.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/mac_scsi.c 2004-02-18 05:36:31.000000000 -0800 @@ -74,9 +74,6 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance); #endif -static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg); -static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value); - static int setup_called = 0; static int setup_can_queue = -1; static int setup_cmd_per_lun = -1; @@ -102,6 +99,52 @@ static volatile unsigned char *mac_scsi_drq = NULL; static volatile unsigned char *mac_scsi_nodrq = NULL; + +/* + * NCR 5380 register access functions + */ + +#if 0 +/* Debug versions */ +#define CTRL(p,v) (*ctrl = (v)) + +static char macscsi_read(struct Scsi_Host *instance, int reg) +{ + int iobase = instance->io_port; + int i; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + + CTRL(iobase, 0); + i = in_8(iobase + (reg<<4)); + CTRL(iobase, 0x40); + + return i; +} + +static void macscsi_write(struct Scsi_Host *instance, int reg, int value) +{ + int iobase = instance->io_port; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + + CTRL(iobase, 0); + out_8(iobase + (reg<<4), value); + CTRL(iobase, 0x40); +} +#else + +/* Fast versions */ +static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg) +{ + return in_8(instance->io_port + (reg<<4)); +} + +static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value) +{ + out_8(instance->io_port + (reg<<4), value); +} +#endif + + /* * Function : mac_scsi_setup(char *str) * @@ -163,18 +206,20 @@ if (ints[5] >= 0) setup_use_pdma = ints[5]; } -#endif +#endif /* SUPPORT_TAGS */ -#endif +#endif /* DRIVER_SETUP */ return 1; } __setup("mac5380=", mac_scsi_setup); /* - * XXX: status debug + * If you want to find the instance with (k)gdb ... */ +#if NDEBUG static struct Scsi_Host *default_instance; +#endif /* * Function : int macscsi_detect(Scsi_Host_Template * tpnt) @@ -223,7 +268,9 @@ /* Once we support multiple 5380s (e.g. DuoDock) we'll do something different here */ instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); +#if NDEBUG default_instance = instance; +#endif if (macintosh_config->ident == MAC_MODEL_IIFX) { mac_scsi_regp = via1+0x8000; @@ -331,49 +378,6 @@ return ""; } -/* - * NCR 5380 register access functions - */ - -/* Debug versions -#define CTRL(p,v) (*ctrl = (v)) - -static char macscsi_read(struct Scsi_Host *instance, int reg) -{ - int iobase = instance->io_port; - int i; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - - CTRL(iobase, 0); - i = in_8(iobase + (reg<<4)); - CTRL(iobase, 0x40); - - return i; -} - -static void macscsi_write(struct Scsi_Host *instance, int reg, int value) -{ - int iobase = instance->io_port; - int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; - - CTRL(iobase, 0); - out_8(value, iobase + (reg<<4)); - CTRL(iobase, 0x40); -} -*/ - -/* Fast versions */ -static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg) -{ - return in_8(instance->io_port + (reg<<4)); -} - -static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value) -{ - out_8(value, instance->io_port + (reg<<4)); -} - - /* Pseudo-DMA: (Ove Edlund) The code attempts to catch bus errors that occur if one for example diff -urN linux-2.4.24/drivers/scsi/megaraid.c linux-2.4.25/drivers/scsi/megaraid.c --- linux-2.4.24/drivers/scsi/megaraid.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/megaraid.c 2004-02-18 05:36:31.000000000 -0800 @@ -4991,7 +4991,7 @@ if( !scsicmd->result && outlen ) { if (copy_to_user(uaddr, kvaddr, length)) { - return -EFAULT; + ret = -EFAULT; goto out_ioctl_cmd_new; } } diff -urN linux-2.4.24/drivers/scsi/megaraid2.c linux-2.4.25/drivers/scsi/megaraid2.c --- linux-2.4.24/drivers/scsi/megaraid2.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/megaraid2.c 2004-02-18 05:36:31.000000000 -0800 @@ -14,7 +14,7 @@ * - speed-ups (list handling fixes, issued_list, optimizations.) * - lots of cleanups. * - * Version : v2.00.9 (Sep 04, 2003) - Atul Mukker + * Version : v2.10.1 (Dec 03, 2003) - Atul Mukker * * Description: Linux device driver for LSI Logic MegaRAID controller * @@ -102,7 +102,7 @@ static struct mcontroller mcontroller[MAX_CONTROLLERS]; /* The current driver version */ -static u32 driver_ver = 0x02000000; +static u32 driver_ver = 0x02100000; /* major number used by the device for character interface */ static int major; @@ -142,6 +142,7 @@ * products. All of them share the same vendor id, device id, and subsystem * vendor id but different subsystem ids. As of now, driver does not use the * subsystem id. + * PERC4E device ids are for the PCI-Express controllers */ static int megaraid_detect(Scsi_Host_Template *host_template) @@ -150,13 +151,16 @@ u16 dev_sw_table[] = { /* Table of all supported vendor/device ids */ - PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY, - PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI, - PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE, - PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID, - PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2, - PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, - PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3, + PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SATA_PCIX, + PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4E_DC_SC, + PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_SI_DI, + PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY, + PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI, + PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE, + PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID, + PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2, + PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, + PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3 }; @@ -246,7 +250,6 @@ u8 did_ioremap_f = 0; u8 did_req_region_f = 0; u8 did_scsi_reg_f = 0; - u8 got_ipdev_f = 0; u8 alloc_int_buf_f = 0; u8 alloc_scb_f = 0; u8 got_irq_f = 0; @@ -261,7 +264,6 @@ did_ioremap_f = 0; did_req_region_f = 0; did_scsi_reg_f = 0; - got_ipdev_f = 0; alloc_int_buf_f = 0; alloc_scb_f = 0; got_irq_f = 0; @@ -277,9 +279,15 @@ * valid and 64 bit is implicit */ if( (pci_vendor == PCI_VENDOR_ID_DELL && - pci_device == PCI_DEVICE_ID_PERC4_DI) || + pci_device == PCI_DEVICE_ID_PERC4_DI) || (pci_vendor == PCI_VENDOR_ID_LSI_LOGIC && - pci_device == PCI_DEVICE_ID_PERC4_QC_VERDE) ) { + pci_device == PCI_DEVICE_ID_PERC4_QC_VERDE) || + (pci_vendor == PCI_VENDOR_ID_LSI_LOGIC && + pci_device == PCI_DEVICE_ID_PERC4E_DC_SC) || + (pci_vendor == PCI_VENDOR_ID_DELL && + pci_device == PCI_DEVICE_ID_PERC4E_SI_DI) || + (pci_vendor == PCI_VENDOR_ID_LSI_LOGIC && + pci_device == PCI_DEVICE_ID_LSI_SATA_PCIX)) { flag |= BOARD_64BIT; } @@ -367,21 +375,6 @@ adapter = (adapter_t *)host->hostdata; memset(adapter, 0, sizeof(adapter_t)); - /* - * Allocate a pci device structure for allocations done - * internally - all of which would be in memory <4GB - */ - adapter->ipdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); - - if( adapter->ipdev == NULL ) goto fail_attach; - - got_ipdev_f = 1; - - memcpy(adapter->ipdev, pdev, sizeof(struct pci_dev)); - - if( pci_set_dma_mask(adapter->ipdev, 0xffffffff) != 0 ) - goto fail_attach; - printk(KERN_NOTICE "scsi%d:Found MegaRAID controller at 0x%lx, IRQ:%d\n", host->host_no, mega_baseport, irq); @@ -395,10 +388,24 @@ adapter->flag = flag; spin_lock_init(&adapter->lock); - // replace adapter->lock with io_request_lock for kernels w/o - // per host lock and delete the line which tries to initialize - // the lock in host structure. +#ifdef SCSI_HAS_HOST_LOCK +# if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,9) + /* This is the Red Hat AS2.1 kernel */ + adapter->host_lock = &adapter->lock; + host->lock = adapter->host_lock; +# elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + /* This is the later Red Hat 2.4 kernels */ + adapter->host_lock = &adapter->lock; + host->host_lock = adapter->host_lock; +# else + /* This is the 2.6 and later kernel series */ + adapter->host_lock = &adapter->lock; + scsi_set_host_lock(&adapter->lock); +# endif +#else + /* And this is the remainder of the 2.4 kernel series */ adapter->host_lock = &io_request_lock; +#endif host->cmd_per_lun = max_cmd_per_lun; host->max_sectors = max_sectors_per_io; @@ -613,14 +620,14 @@ /* Set the Mode of addressing to 64 bit if we can */ if((adapter->flag & BOARD_64BIT)&&(sizeof(dma_addr_t) == 8)) { - pci_set_dma_mask(pdev, 0xffffffffffffffff); + pci_set_dma_mask(pdev, 0xffffffffffffffffULL); adapter->has_64bit_addr = 1; } else { pci_set_dma_mask(pdev, 0xffffffff); adapter->has_64bit_addr = 0; } - + init_MUTEX(&adapter->int_mtx); init_waitqueue_head(&adapter->int_waitq); @@ -669,8 +676,6 @@ adapter->buf_dma_handle); } - if( got_ipdev_f ) kfree(adapter->ipdev); - if( did_scsi_reg_f ) scsi_unregister(host); if( did_ioremap_f ) { @@ -701,7 +706,7 @@ sizeof(mbox64_t), &adapter->una_mbox64_dma); if( !adapter->una_mbox64 ) return -1; - + adapter->mbox = &adapter->una_mbox64->mbox; adapter->mbox = (mbox_t *)((((unsigned long) adapter->mbox) + 15) & @@ -754,7 +759,7 @@ { dma_addr_t prod_info_dma_handle; mega_inquiry3 *inquiry3; - u8 raw_mbox[16]; + u8 raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int retval; @@ -763,7 +768,7 @@ mbox = (mbox_t *)raw_mbox; memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE); - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); /* * Try to issue Inquiry3 command @@ -1695,21 +1700,22 @@ u8 status; int i; - raw_mbox[0x1] = 0xFE; /* Set cmdid */ - raw_mbox[0xF] = 1; /* Set busy */ - /* Wait until mailbox is free */ if(mega_busywait_mbox (adapter)) goto bug_blocked_mailbox; /* Copy mailbox data into host structure */ - memcpy((char *) mbox, raw_mbox, 16); + memcpy((char *)mbox, raw_mbox, 16); + mbox->cmdid = 0xFE; + mbox->busy = 1; switch (raw_mbox[0]) { + case MEGA_MBOXCMD_EXTPTHRU: + if( !adapter->has_64bit_addr ) break; + // else fall through case MEGA_MBOXCMD_LREAD64: case MEGA_MBOXCMD_LWRITE64: case MEGA_MBOXCMD_PASSTHRU64: - case MEGA_MBOXCMD_EXTPTHRU: mbox64->xfer_segment_lo = mbox->xferaddr; mbox64->xfer_segment_hi = 0; mbox->xferaddr = 0xFFFFFFFF; @@ -1989,6 +1995,7 @@ Scsi_Cmnd *cmd = NULL; mega_passthru *pthru = NULL; mbox_t *mbox = NULL; + int islogical; u8 c; scb_t *scb; int cmdid; @@ -2072,9 +2079,10 @@ #if MEGA_HAVE_STATS { - int islogical = adapter->logdrv_chan[cmd->channel]; int logdrv = mbox->logdrv; + islogical = adapter->logdrv_chan[cmd->channel]; + /* * Maintain an error counter for the logical drive. * Some application like SNMP agent need such @@ -2110,23 +2118,21 @@ * hard disk and not logical, request should return failure! - * PJ */ - if(cmd->cmnd[0] == INQUIRY) { - int islogical = adapter->logdrv_chan[cmd->channel]; + islogical = adapter->logdrv_chan[cmd->channel]; + if (cmd->cmnd[0] == INQUIRY && !islogical) { - if(!islogical) { - if( cmd->use_sg ) { - sgl = (struct scatterlist *) - cmd->request_buffer; - c = *(u8 *)sgl[0].address; - } - else { - c = *(u8 *)cmd->request_buffer; - } + if( cmd->use_sg ) { + sgl = (struct scatterlist *) + cmd->request_buffer; + c = *(u8 *)sgl[0].address; + } + else { + c = *(u8 *)cmd->request_buffer; + } - if(IS_RAID_CH(adapter, cmd->channel) && - ((c & 0x1F ) == TYPE_DISK)) { - status = 0xF0; - } + if(IS_RAID_CH(adapter, cmd->channel) && + ((c & 0x1F ) == TYPE_DISK)) { + status = 0xF0; } } @@ -2243,12 +2249,11 @@ break; case MEGA_BULK_DATA: - pci_unmap_page(adapter->host->pci_dev, scb->dma_h_bulkdata, + pci_unmap_page(adapter->dev, scb->dma_h_bulkdata, scb->cmd->request_bufflen, scb->dma_direction); if( scb->dma_direction == PCI_DMA_FROMDEVICE ) { - pci_dma_sync_single(adapter->host->pci_dev, - scb->dma_h_bulkdata, + pci_dma_sync_single(adapter->dev, scb->dma_h_bulkdata, scb->cmd->request_bufflen, PCI_DMA_FROMDEVICE); } @@ -2256,12 +2261,11 @@ break; case MEGA_SGLIST: - pci_unmap_sg(adapter->host->pci_dev, scb->cmd->request_buffer, + pci_unmap_sg(adapter->dev, scb->cmd->request_buffer, scb->cmd->use_sg, scb->dma_direction); if( scb->dma_direction == PCI_DMA_FROMDEVICE ) { - pci_dma_sync_sg(adapter->host->pci_dev, - scb->cmd->request_buffer, + pci_dma_sync_sg(adapter->dev, scb->cmd->request_buffer, scb->cmd->use_sg, PCI_DMA_FROMDEVICE); } @@ -2332,8 +2336,7 @@ offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK); - scb->dma_h_bulkdata = pci_map_page(adapter->host->pci_dev, - page, offset, + scb->dma_h_bulkdata = pci_map_page(adapter->dev, page, offset, cmd->request_bufflen, scb->dma_direction); scb->dma_type = MEGA_BULK_DATA; @@ -2355,7 +2358,7 @@ } if( scb->dma_direction == PCI_DMA_TODEVICE ) { - pci_dma_sync_single(adapter->host->pci_dev, + pci_dma_sync_single(adapter->dev, scb->dma_h_bulkdata, cmd->request_bufflen, PCI_DMA_TODEVICE); @@ -2371,8 +2374,7 @@ * * The number of sg elements returned must not exceed our limit */ - sgcnt = pci_map_sg(adapter->host->pci_dev, sgl, cmd->use_sg, - scb->dma_direction); + sgcnt = pci_map_sg(adapter->dev, sgl, cmd->use_sg, scb->dma_direction); scb->dma_type = MEGA_SGLIST; @@ -2400,8 +2402,8 @@ *len = (u32)cmd->request_bufflen; if( scb->dma_direction == PCI_DMA_TODEVICE ) { - pci_dma_sync_sg(adapter->host->pci_dev, cmd->request_buffer, cmd->use_sg, - PCI_DMA_TODEVICE); + pci_dma_sync_sg(adapter->dev, cmd->request_buffer, + cmd->use_sg, PCI_DMA_TODEVICE); } /* Return count of SG requests */ @@ -2458,7 +2460,7 @@ { adapter_t *adapter; mbox_t *mbox; - u_char raw_mbox[16]; + u_char raw_mbox[sizeof(mbox_t)]; #ifdef CONFIG_PROC_FS char buf[12] = { 0 }; #endif @@ -2469,7 +2471,7 @@ printk(KERN_NOTICE "megaraid: being unloaded..."); /* Flush adapter cache */ - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = FLUSH_ADAPTER; irq_disable(adapter); @@ -2479,7 +2481,7 @@ issue_scb_block(adapter, raw_mbox); /* Flush disks cache */ - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = FLUSH_SYSTEM; /* Issue a blocking (interrupts disabled) command to the card */ @@ -2540,8 +2542,6 @@ pci_free_consistent(adapter->dev, sizeof(mbox64_t), (void *)adapter->una_mbox64, adapter->una_mbox64_dma); - kfree(adapter->ipdev); - hba_count--; if( hba_count == 0 ) { @@ -2723,7 +2723,7 @@ */ if( !(iter % 1000) ) { printk( - "megarid: Waiting for %d commands to flush: iter:%ld\n", + "megaraid: Waiting for %d commands to flush: iter:%ld\n", atomic_read(&adapter->pend_cmds), iter); } @@ -2742,7 +2742,7 @@ if( rval == SUCCESS ) { printk(KERN_INFO - "megaraid: abort sequence successfully complete.\n"); + "megaraid: abort sequence successfully completed.\n"); } return rval; @@ -2803,7 +2803,7 @@ */ if( !(iter % 1000) ) { printk( - "megarid: Waiting for %d commands to flush: iter:%ld\n", + "megaraid: Waiting for %d commands to flush: iter:%ld\n", atomic_read(&adapter->pend_cmds), iter); } @@ -2822,7 +2822,7 @@ if( rval == SUCCESS ) { printk(KERN_INFO - "megaraid: reset sequence successfully complete.\n"); + "megaraid: reset sequence successfully completed.\n"); } return rval; @@ -2953,7 +2953,7 @@ len += sprintf(page+len, "Base = %08lx, Irq = %d, ", adapter->base, adapter->host->irq); - len += sprintf(page+len, "Logical Drives = %d, Channels = %d\n", + len += sprintf(page+len, "Initial Logical Drives = %d, Channels = %d\n", adapter->numldrv, adapter->product_info.nchannels); len += sprintf(page+len, "Version =%s:%s, DRAM = %dMb\n", @@ -3109,7 +3109,7 @@ struct pci_dev *pdev; int len = 0; - pdev = adapter->ipdev; + pdev = adapter->dev; if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { *eof = 1; @@ -3171,7 +3171,7 @@ char str[256]; int len = 0; - pdev = adapter->ipdev; + pdev = adapter->dev; if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { *eof = 1; @@ -3209,22 +3209,22 @@ if(battery_status & MEGA_BATT_MODULE_MISSING) strcat(str, " Module Missing"); - + if(battery_status & MEGA_BATT_LOW_VOLTAGE) strcat(str, " Low Voltage"); - + if(battery_status & MEGA_BATT_TEMP_HIGH) strcat(str, " Temperature High"); - + if(battery_status & MEGA_BATT_PACK_MISSING) strcat(str, " Pack Missing"); - + if(battery_status & MEGA_BATT_CHARGE_INPROG) strcat(str, " Charge In-progress"); - + if(battery_status & MEGA_BATT_CHARGE_FAIL) strcat(str, " Charge Fail"); - + if(battery_status & MEGA_BATT_CYCLES_EXCEEDED) strcat(str, " Cycles Exceeded"); @@ -3354,7 +3354,7 @@ char str[80]; int i; - pdev = adapter->ipdev; + pdev = adapter->dev; if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { return len; @@ -3403,32 +3403,27 @@ switch( state & 0x0F ) { case PDRV_ONLINE: - sprintf(str, - "Channel:%2d Id:%2d State: Online", + sprintf(str, "Channel:%2d Id:%2d State: Online", channel, tgt); break; case PDRV_FAILED: - sprintf(str, - "Channel:%2d Id:%2d State: Failed", + sprintf(str, "Channel:%2d Id:%2d State: Failed", channel, tgt); break; case PDRV_RBLD: - sprintf(str, - "Channel:%2d Id:%2d State: Rebuild", + sprintf(str, "Channel:%2d Id:%2d State: Rebuild", channel, tgt); break; case PDRV_HOTSPARE: - sprintf(str, - "Channel:%2d Id:%2d State: Hot spare", + sprintf(str, "Channel:%2d Id:%2d State: Hot spare", channel, tgt); break; default: - sprintf(str, - "Channel:%2d Id:%2d State: Un-configured", + sprintf(str, "Channel:%2d Id:%2d State: Un-configured", channel, tgt); break; @@ -3543,7 +3538,7 @@ * @eof - set if no more data needs to be returned * @data - pointer to our soft state * - * Display real time information about the logical drives 0 through 9. + * Display real time information about the logical drives 10 through 19. */ static int proc_rdrv_20(char *page, char **start, off_t offset, int count, int *eof, @@ -3566,7 +3561,7 @@ * @eof - set if no more data needs to be returned * @data - pointer to our soft state * - * Display real time information about the logical drives 0 through 9. + * Display real time information about the logical drives 20 through 29. */ static int proc_rdrv_30(char *page, char **start, off_t offset, int count, int *eof, @@ -3589,7 +3584,7 @@ * @eof - set if no more data needs to be returned * @data - pointer to our soft state * - * Display real time information about the logical drives 0 through 9. + * Display real time information about the logical drives 30 through 39. */ static int proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof, @@ -3614,7 +3609,7 @@ * /proc/scsi/scsi interface */ static int -proc_rdrv(adapter_t *adapter, char *page, int start, int end ) +proc_rdrv(adapter_t *adapter, char *page, int start, int end) { dma_addr_t dma_handle; logdrv_param *lparam; @@ -3630,7 +3625,7 @@ int i; u8 span8_flag = 1; - pdev = adapter->ipdev; + pdev = adapter->dev; if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { return len; @@ -3650,7 +3645,7 @@ memset(&mc, 0, sizeof(megacmd_t)); if( adapter->flag & BOARD_40LD ) { - + array_sz = sizeof(disk_array_40ld); rdrv_state = ((mega_inquiry3 *)inquiry)->ldrv_state; @@ -3747,7 +3742,7 @@ else { lparam = (logdrv_param*) &((diskarray_span4_t*) (disk_array))->log_drv[i]; - } + } } /* @@ -3792,7 +3787,7 @@ len += sprintf(page+len, ", initialization in progress"); } - + len += sprintf(page+len, "\n"); len += sprintf(page+len, "Span depth:%3d, ", @@ -3966,7 +3961,7 @@ if (blksize_size[ma]) block = blksize_size[ma][mi]; - + if (!(bh = bread(MKDEV(ma,mi), 0, block))) return -1; @@ -4026,7 +4021,7 @@ { adapter_t *adapter; struct Scsi_Host *host; - u8 raw_mbox[16]; + u8 raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int i; @@ -4042,7 +4037,7 @@ mbox = (mbox_t *)raw_mbox; /* Flush adapter cache */ - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = FLUSH_ADAPTER; irq_disable(adapter); @@ -4055,7 +4050,7 @@ issue_scb_block(adapter, raw_mbox); /* Flush disks cache */ - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = FLUSH_SYSTEM; issue_scb_block(adapter, raw_mbox); @@ -4374,7 +4369,7 @@ * For all internal commands, the buffer must be allocated in * <4GB address range */ - pdev = adapter->ipdev; + pdev = adapter->dev; /* Is it a passthru command or a DCMD */ if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) { @@ -4786,13 +4781,13 @@ static int mega_is_bios_enabled(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int ret; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE); @@ -4819,13 +4814,13 @@ static void mega_enum_raid_scsi(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int i; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); /* * issue command to find out what channels are raid/scsi @@ -4848,7 +4843,7 @@ } - for( i = 0; i < adapter->product_info.nchannels; i++ ) { + for( i = 0; i < adapter->product_info.nchannels; i++ ) { if( (adapter->mega_ch_class >> i) & 0x01 ) { printk(KERN_INFO "megaraid: channel[%d] is raid.\n", i); @@ -4874,7 +4869,7 @@ mega_get_boot_drv(adapter_t *adapter) { struct private_bios_data *prv_bios_data; - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; u16 cksum = 0; u8 *cksum_p; @@ -4883,7 +4878,7 @@ mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, sizeof(raw_mbox)); + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = BIOS_PVT_DATA; raw_mbox[2] = GET_BIOS_PVT_DATA; @@ -4940,13 +4935,13 @@ static int mega_support_random_del(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int rval; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); /* * issue command @@ -4969,13 +4964,13 @@ static int mega_support_ext_cdb(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; int rval; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, 16); + memset(raw_mbox, 0, sizeof(raw_mbox)); /* * issue command to find out if controller supports extended CDBs. */ @@ -5053,7 +5048,9 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv) { int rval; - u8 raw_mbox[16]; + u8 raw_mbox[sizeof(mbox_t)]; + + memset(raw_mbox, 0, sizeof(raw_mbox)); raw_mbox[0] = FC_DEL_LOGDRV; raw_mbox[2] = OP_DEL_LOGDRV; @@ -5088,12 +5085,12 @@ static void mega_get_max_sgl(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, sizeof(raw_mbox)); + memset(raw_mbox, 0, sizeof(raw_mbox)); memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE); @@ -5111,7 +5108,7 @@ } else { adapter->sglen = *((char *)adapter->mega_buffer); - + /* * Make sure this is not more than the resources we are * planning to allocate @@ -5133,12 +5130,12 @@ static int mega_support_cluster(adapter_t *adapter) { - unsigned char raw_mbox[16]; + unsigned char raw_mbox[sizeof(mbox_t)]; mbox_t *mbox; mbox = (mbox_t *)raw_mbox; - memset(mbox, 0, sizeof(raw_mbox)); + memset(raw_mbox, 0, sizeof(raw_mbox)); memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE); @@ -5183,7 +5180,7 @@ int ldrv_num; tgt = cmd->target; - + if ( tgt > adapter->this_id ) tgt--; /* we do not get inquires for initiator id */ @@ -5485,7 +5482,7 @@ * For all internal commands, the buffer must be allocated in <4GB * address range */ - pdev = adapter->ipdev; + pdev = adapter->dev; pthru = pci_alloc_consistent(pdev, sizeof(mega_passthru), &pthru_dma_handle); diff -urN linux-2.4.24/drivers/scsi/megaraid2.h linux-2.4.25/drivers/scsi/megaraid2.h --- linux-2.4.24/drivers/scsi/megaraid2.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/scsi/megaraid2.h 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ #define MEGARAID_VERSION \ - "v2.00.9 (Release Date: Thu Sep 4 17:49:42 EDT 2003)\n" + "v2.10.1 (Release Date: Wed Dec 3 15:34:42 EST 2003)\n" /* * Driver features - change the values to enable or disable features in the @@ -77,6 +77,9 @@ #define PCI_DEVICE_ID_DISCOVERY 0x000E #define PCI_DEVICE_ID_PERC4_DI 0x000F #define PCI_DEVICE_ID_PERC4_QC_VERDE 0x0407 +#define PCI_DEVICE_ID_PERC4E_SI_DI 0x0013 +#define PCI_DEVICE_ID_PERC4E_DC_SC 0x0408 +#define PCI_DEVICE_ID_LSI_SATA_PCIX 0x0409 /* Sub-System Vendor IDs */ #define AMI_SUBSYS_VID 0x101E @@ -520,10 +523,10 @@ typedef struct { unsigned char channel; - unsigned char target; + unsigned char target; }__attribute__ ((packed)) device_t; -typedef struct { +typedef struct { unsigned long start_blk; unsigned long total_blks; device_t device[ MAX_STRIPES ]; @@ -537,38 +540,38 @@ unsigned long size; }__attribute__ ((packed)) phydrv_t; -typedef struct { +typedef struct { unsigned char span_depth; unsigned char raid; - unsigned char read_ahead; /* 0=No rdahead,1=RDAHEAD,2=adaptive */ + unsigned char read_ahead; /* 0=No rdahead,1=RDAHEAD,2=adaptive */ unsigned char stripe_sz; unsigned char status; - unsigned char write_policy; /* 0=wrthru,1=wrbak */ - unsigned char direct_io; /* 1=directio,0=cached */ + unsigned char write_policy; /* 0=wrthru,1=wrbak */ + unsigned char direct_io; /* 1=directio,0=cached */ unsigned char no_stripes; span_t span[ SPAN4_DEPTH ]; }__attribute__ ((packed)) ld_span4_t; -typedef struct { +typedef struct { unsigned char span_depth; unsigned char raid; - unsigned char read_ahead; /* 0=No rdahead,1=RDAHEAD,2=adaptive */ + unsigned char read_ahead; /* 0=No rdahead,1=RDAHEAD,2=adaptive */ unsigned char stripe_sz; unsigned char status; - unsigned char write_policy; /* 0=wrthru,1=wrbak */ - unsigned char direct_io; /* 1=directio,0=cached */ + unsigned char write_policy; /* 0=wrthru,1=wrbak */ + unsigned char direct_io; /* 1=directio,0=cached */ unsigned char no_stripes; span_t span[ SPAN8_DEPTH ]; }__attribute__ ((packed)) ld_span8_t; -typedef struct { +typedef struct { unsigned char no_log_drives; unsigned char pad[3]; ld_span4_t log_drv[ MAX_LOGICAL_DRIVES_8LD ]; phydrv_t phys_drv[ MAX_PHYDRVS ]; }__attribute__ ((packed)) diskarray_span4_t; -typedef struct { +typedef struct { unsigned char no_log_drives; unsigned char pad[3]; ld_span8_t log_drv[ MAX_LOGICAL_DRIVES_8LD ]; @@ -894,9 +897,7 @@ volatile mbox64_t *mbox64;/* ptr to 64-bit mailbox */ volatile mbox_t *mbox; /* ptr to standard mailbox */ dma_addr_t mbox_dma; - - struct pci_dev *dev; - struct pci_dev *ipdev; /* for internal allocation */ + struct pci_dev *dev; struct list_head free_list; struct list_head pending_list; diff -urN linux-2.4.24/drivers/scsi/mvme16x.c linux-2.4.25/drivers/scsi/mvme16x.c --- linux-2.4.24/drivers/scsi/mvme16x.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/scsi/mvme16x.c 2004-02-18 05:36:31.000000000 -0800 @@ -21,9 +21,6 @@ #include -extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); int mvme16x_scsi_detect(Scsi_Host_Template *tpnt) { diff -urN linux-2.4.24/drivers/scsi/osst.c linux-2.4.25/drivers/scsi/osst.c --- linux-2.4.24/drivers/scsi/osst.c 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.25/drivers/scsi/osst.c 2004-02-18 05:36:31.000000000 -0800 @@ -16,15 +16,15 @@ Copyright 1992 - 2000 Kai Makisara email Kai.Makisara@metla.fi - $Header: /home/cvsroot/Driver/osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $ + $Header: /cvsroot/osst/Driver/osst.c,v 1.67.2.1 2003/06/28 00:21:28 riede Exp $ Microscopic alterations - Rik Ling, 2000/12/21 Last modified: Wed Feb 2 22:04:05 2000 by makisara@kai.makisara.local Some small formal changes - aeb, 950809 */ -static const char * cvsid = "$Id: osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $"; -const char * osst_version = "0.9.10"; +static const char * cvsid = "$Id: osst.c,v 1.67.2.2 2003/12/14 14:28:46 wriede Exp $"; +const char * osst_version = "0.9.14"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -75,9 +76,8 @@ #include "constants.h" -static int buffer_kbs = 0; +static int max_dev = 0; static int write_threshold_kbs = 0; -static int max_buffers = 0; static int max_sg_segs = 0; #ifdef MODULE @@ -85,18 +85,16 @@ MODULE_DESCRIPTION("OnStream SCSI Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(buffer_kbs, "i"); +MODULE_PARM(max_dev, "i"); MODULE_PARM(write_threshold_kbs, "i"); -MODULE_PARM(max_buffers, "i"); MODULE_PARM(max_sg_segs, "i"); #else static struct osst_dev_parm { char *name; int *val; } parms[] __initdata = { - { "buffer_kbs", &buffer_kbs }, + { "max_dev", &max_dev }, { "write_threshold_kbs", &write_threshold_kbs }, - { "max_buffers", &max_buffers }, { "max_sg_segs", &max_sg_segs } }; #endif @@ -117,11 +115,16 @@ // #define OSST_INJECT_ERRORS 1 #endif -#define MAX_RETRIES 0 +#define MAX_RETRIES 2 +#define MAX_READ_RETRIES 0 #define MAX_WRITE_RETRIES 0 -#define MAX_READY_RETRIES 5 +#define MAX_READY_RETRIES 0 #define NO_TAPE NOT_READY +#define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) +#define OSST_WAIT_WRITE_COMPLETE (HZ / 12) +#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) + #define OSST_TIMEOUT (200 * HZ) #define OSST_LONG_TIMEOUT (1800 * HZ) @@ -137,6 +140,7 @@ static int osst_write_threshold = OSST_WRITE_THRESHOLD; static int osst_max_buffers = OSST_MAX_BUFFERS; static int osst_max_sg_segs = OSST_MAX_SG; +static int osst_max_dev = OSST_MAX_TAPES; static OS_Scsi_Tape **os_scsi_tapes = NULL; static OSST_buffer **osst_buffers = NULL; @@ -539,8 +543,6 @@ STp->first_frame_position); goto err_out; } - STp->frame_in_buffer = 1; - if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { if (!quiet) #if DEBUG @@ -567,12 +569,14 @@ } if (aux->frame_type == OS_FRAME_TYPE_EOD) { STps->eof = ST_EOD_1; + STp->frame_in_buffer = 1; } if (aux->frame_type == OS_FRAME_TYPE_DATA) { blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); STp->buffer->buffer_bytes = blk_cnt * blk_sz; STp->buffer->read_pointer = 0; + STp->frame_in_buffer = 1; /* See what block size was used to write file */ if (STp->block_size != blk_sz && blk_sz > 0) { @@ -599,18 +603,23 @@ /* * Wait for the unit to become Ready */ -static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout) +static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay) { unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt; long startwait = jiffies; #if DEBUG int dbg = debugging; - int dev = TAPE_NR(STp->devt); + int dev = TAPE_NR(STp->devt); printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev); #endif + if (initial_delay > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(initial_delay); + } + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; @@ -722,10 +731,10 @@ { int retval; - osst_wait_ready(STp, aSRpnt, 15 * 60); /* TODO - can this catch a write error? */ + osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ retval = osst_set_frame_position(STp, aSRpnt, frame, 0); if (retval) return (retval); - osst_wait_ready(STp, aSRpnt, 15 * 60); + osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); return (osst_get_frame_position(STp, aSRpnt)); } @@ -738,6 +747,7 @@ Scsi_Request * SRpnt; int result = 0; + int delay = OSST_WAIT_WRITE_COMPLETE; #if DEBUG int dev = TAPE_NR(STp->devt); @@ -751,12 +761,17 @@ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); - - if ((STp->buffer)->syscall_result) - result = osst_write_error_recovery(STp, aSRpnt, 0); - - result |= osst_wait_ready(STp, aSRpnt, 5 * 60); + if (STp->buffer->syscall_result) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) { + if (SRpnt->sr_sense_buffer[13] == 8) { + delay = OSST_WAIT_LONG_WRITE_COMPLETE; + } + } else + result = osst_write_error_recovery(STp, aSRpnt, 0); + } + result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; + return (result); } @@ -833,9 +848,6 @@ /* TODO: Error handling */ if (STp->poll) retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout); -#if 0// DEBUG - printk ("osst_read: wait for frame returned %i\n", retval); -#endif memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; @@ -847,7 +859,7 @@ printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", dev); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -903,7 +915,8 @@ #endif if (STps->rw != ST_READING) { /* Initialize read operation */ - if (STps->rw == ST_WRITING) { + if (STps->rw == ST_WRITING || STp->dirty) { + STp->write_type = OS_WRITE_DATA; osst_flush_write_buffer(STp, aSRpnt); osst_flush_drive_buffer(STp, aSRpnt); } @@ -921,7 +934,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tape\n", dev); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; retval = STp->buffer->syscall_result; } @@ -940,6 +953,15 @@ position; /* + * If we want just any frame (-1) and there is a frame in the buffer, return it + */ + if (frame_seq_number == -1 && STp->frame_in_buffer) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Frame %d still in buffer\n", dev, STp->frame_seq_number); +#endif + return (STps->eof); + } + /* * Search and wait for the next logical tape frame */ while (1) { @@ -1092,6 +1114,7 @@ if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; move /= (OS_DATA_SIZE / STp->block_size); } + if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", @@ -1289,7 +1312,7 @@ cmd[8] = 32768 & 0xff; SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "osst%d:E: Failed to read frame back from OnStream buffer\n", dev); @@ -1329,7 +1352,7 @@ dev, new_frame+i, frame_seq_number+i); #endif osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); - osst_wait_ready(STp, aSRpnt, 60); + osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); osst_get_frame_position(STp, aSRpnt); SRpnt = * aSRpnt; @@ -1397,6 +1420,7 @@ if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { /* in the process of becoming ready */ + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); continue; } @@ -1469,6 +1493,8 @@ osst_set_frame_position(STp, aSRpnt, frame + skip, 1); flag = 0; attempts--; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); } if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ #if DEBUG @@ -1529,6 +1555,7 @@ debugging = 0; } #endif + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); } printk(KERN_ERR "osst%d:E: Failed to find valid tape media\n", dev); @@ -1674,12 +1701,7 @@ dev, last_mark_ppos); return (-EIO); } - if (mt_op == MTBSFM) { - STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); - } - return 0; + goto found; } #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark backwards\n", dev); @@ -1707,10 +1729,13 @@ return (-EIO); } } +found: if (mt_op == MTBSFM) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -1763,8 +1788,10 @@ } if (mt_op == MTFSF) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -1910,8 +1937,10 @@ } if (mt_op == MTFSF) { STp->frame_seq_number++; - STp->frame_in_buffer = 0; - STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + STp->frame_in_buffer = 0; + STp->buffer->buffer_bytes = 0; + STp->buffer->read_pointer = 0; + STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; } @@ -2011,7 +2040,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group %d\n", dev, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_FILLER; while (count--) { @@ -2037,7 +2066,7 @@ #if DEBUG printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group %d\n", dev, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_HEADER; while (count--) { @@ -2158,7 +2187,8 @@ if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) { if (osst_set_frame_position(STp, aSRpnt, ppos, 0)) printk(KERN_WARNING "osst%i:W: Couldn't position tape\n", dev); - if (osst_initiate_read (STp, aSRpnt)) { + osst_wait_ready(STp, aSRpnt, 60 * 15, 0); + if (osst_initiate_read(STp, aSRpnt)) { printk(KERN_WARNING "osst%i:W: Couldn't initiate read\n", dev); return 0; } @@ -2377,11 +2407,12 @@ static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) { + int write_pass = STp->wrt_pass_cntr; int frame_position = STp->first_frame_position; - int frame_seq_numbr = STp->frame_seq_number; + int frame_seq_numbr = STp->frame_seq_number; int logical_blk_num = STp->logical_blk_num; - int halfway_frame = STp->frame_in_buffer; - int read_pointer = STp->buffer->read_pointer; + int halfway_frame = STp->frame_in_buffer; + int read_pointer = STp->buffer->read_pointer; int prev_mark_ppos = -1; int actual_mark_ppos, i, n; #if DEBUG @@ -2389,12 +2420,24 @@ printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one we think before writing\n", dev); #endif - osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); - if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { + if (frame_position <= STp->first_data_ppos) { + /* check header match */ + if (!osst_analyze_headers(STp, aSRpnt) || + (write_pass != STp->wrt_pass_cntr)) { #if DEBUG - printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev); + printk(OSST_DEB_MSG "osst%d:D: Couldn't match header in verify_position\n", dev); #endif - return (-EIO); + return (-EIO); + } + } else { + /* find preceding data frame of current write pass */ + osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0); + if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_position\n", dev); +#endif + return (-EIO); + } } if (STp->linux_media_version >= 4) { for (i=0; ifilemark_cnt; i++) @@ -2671,7 +2714,7 @@ STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!SRpnt) { STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; return (-EBUSY); @@ -2692,7 +2735,7 @@ scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!STp->buffer->syscall_result) memcpy (SRpnt->sr_sense_buffer, mysense, 16); } @@ -2764,7 +2807,7 @@ scmd[9] = 0x80; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout, - MAX_READY_RETRIES, TRUE); + MAX_RETRIES, TRUE); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -2777,7 +2820,7 @@ result = (-EIO); } if (pp != ppos) - osst_wait_ready(STp, aSRpnt, 5 * 60); + osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } while ((pp != ppos) && (pp = ppos)); STp->first_frame_position = STp->last_frame_position = ppos; STps->eof = ST_NOEOF; @@ -2787,7 +2830,29 @@ return result; } +static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT) +{ + ST_partstat * STps = &(STp->ps[STp->partition]); + int result = 0; + + if (STp->write_type != OS_WRITE_NEW_MARK) { + /* true unless the user wrote the filemark for us */ + result = osst_flush_drive_buffer(STp, aSRpnt); + if (result < 0) goto out; + result = osst_write_filemark(STp, aSRpnt); + if (result < 0) goto out; + + if (STps->drv_file >= 0) + STps->drv_file++ ; + STps->drv_block = 0; + } + result = osst_write_eod(STp, aSRpnt); + osst_write_header(STp, aSRpnt, leave_at_EOT); + STps->eof = ST_FM; +out: + return result; +} /* osst versions of st functions - augmented and stripped to suit OnStream only */ @@ -2905,7 +2970,7 @@ result = (-EIO); } } - STps->drv_block = (-1); + STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */ } else { STp->first_frame_position++; @@ -2941,9 +3006,10 @@ return 0; STps = &(STp->ps[STp->partition]); - if (STps->rw == ST_WRITING) /* Writing */ + if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ + STp->write_type = OS_WRITE_DATA; return osst_flush_write_buffer(STp, aSRpnt); - + } if (STp->block_size == 0) return 0; @@ -3166,12 +3232,16 @@ if (STps->rw == ST_READING) { +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Switching from read to write at file %d, block %d\n", dev, + STps->drv_file, STps->drv_block); +#endif retval = osst_flush_buffer(STp, &SRpnt, 0); if (retval) goto out; STps->rw = ST_IDLE; } - else if (STps->rw != ST_WRITING) { + if (STps->rw != ST_WRITING) { /* Are we totally rewriting this tape? */ if (!STp->header_ok || (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || @@ -3524,9 +3594,19 @@ printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left %d, needed %d.\n", dev, STps->eof, (STp->buffer)->buffer_bytes, count - total); #endif + /* force multiple of block size, note block_size may have been adjusted */ transfer = (((STp->buffer)->buffer_bytes < count - total ? (STp->buffer)->buffer_bytes : count - total)/ - STp->block_size) * STp->block_size; /* force multiple of block size */ + STp->block_size) * STp->block_size; + + if (transfer == 0) { + printk(KERN_WARNING + "osst%d:W: Nothing can be transfered, requested %d, tape block size (%d%c).\n", + dev, count, STp->block_size < 1024? + STp->block_size:STp->block_size/1024, + STp->block_size<1024?'b':'k'); + break; + } i = from_buffer(STp->buffer, buf, transfer); if (i) { retval = i; @@ -3553,7 +3633,7 @@ /* Change the eof state if no data from tape or buffer */ if (total == 0) { if (STps->eof == ST_FM_HIT) { - STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; + STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM; STps->drv_block = 0; if (STps->drv_file >= 0) STps->drv_file++; @@ -3876,9 +3956,10 @@ } break; case MTWEOF: - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) + if ((STps->rw == ST_WRITING || STp->dirty) && !(STp->device)->was_reset) { + STp->write_type = OS_WRITE_DATA; ioctl_result = osst_flush_write_buffer(STp, &SRpnt); - else + } else ioctl_result = 0; #if DEBUG if (debugging) @@ -3961,8 +4042,8 @@ if (debugging) printk(OSST_DEB_MSG "osst%d:D: Spacing to end of recorded medium.\n", dev); #endif - osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0); - if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) { + if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) || + (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) { ioctl_result = -EIO; goto os_bypass; } @@ -4020,6 +4101,23 @@ break; case MTSETBLK: /* Set block length */ + if ((STps->drv_block == 0 ) && + !STp->dirty && + ((STp->buffer)->buffer_bytes == 0) && + ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) && + ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) && + !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) { + /* + * Only allowed to change the block size if you opened the + * device at the beginning of a file before writing anything. + * Note, that when reading, changing block_size is futile, + * as the size used when writing overrides it. + */ + STp->block_size = (arg & MT_ST_BLKSIZE_MASK); + printk(KERN_INFO "osst%d:I: Block size set to %d bytes.\n", + dev, STp->block_size); + return 0; + } case MTSETDENSITY: /* Set tape density */ case MTSETDRVBUFFER: /* Set drive buffering */ case SET_DENS_AND_BLK: /* Set density and block size */ @@ -4027,11 +4125,11 @@ if (STp->dirty || (STp->buffer)->buffer_bytes != 0) return (-EIO); /* Not allowed if data in buffer */ if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && - (arg & MT_ST_BLKSIZE_MASK) != 0 && - ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block || - (arg & MT_ST_BLKSIZE_MASK) > STp->max_block || - (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) { - printk(KERN_WARNING "osst%d:W: Illegal block size.\n", dev); + (arg & MT_ST_BLKSIZE_MASK) != 0 && + (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) { + printk(KERN_WARNING "osst%d:W: Illegal to set block size to %d%s.\n", + dev, (int)(arg & MT_ST_BLKSIZE_MASK), + (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now"); return (-EINVAL); } return 0; /* FIXME silently ignore if block size didn't change */ @@ -4083,6 +4181,14 @@ if (cmd_in == MTEOM) STps->eof = ST_EOD; + else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) { + ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1); + STps->drv_block++; + STp->logical_blk_num++; + STp->frame_seq_number++; + STp->frame_in_buffer = 0; + STp->buffer->read_pointer = 0; + } else if (cmd_in == MTFSF) STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; else if (chg_eof) @@ -4091,7 +4197,6 @@ if (cmd_in == MTOFFL || cmd_in == MTUNLOAD) STp->rew_at_close = 0; else if (cmd_in == MTLOAD) { -/* STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0; FIXME */ for (i=0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */ @@ -4140,10 +4245,15 @@ STp->door_locked = ST_LOCK_FAILS; if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) - ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60); + ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } *aSRpnt = SRpnt; +#if DEBUG + printk(OSST_DEB_MSG "osst%d:D: Ioctl %s, ppos %d fseq %d lblk %d bytes %d file %d blk %d\n", dev, + ioctl_result?"fail":"success", STp->first_frame_position, STp->frame_seq_number, + STp->logical_blk_num, STp->buffer->buffer_bytes, STps->drv_file, STps->drv_block); +#endif return ioctl_result; } @@ -4263,7 +4373,7 @@ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); } - osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60); + osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ @@ -4410,7 +4520,7 @@ } } - if (osst_wait_ready(STp, &SRpnt, 15 * 60)) /* FIXME - not allowed with NOBLOCK */ + if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */ printk(KERN_INFO "osst%i:I: Device did not become Ready in open\n",dev); if ((STp->buffer)->syscall_result != 0) { @@ -4551,7 +4661,8 @@ STm = &(STp->modes[STp->current_mode]); STps = &(STp->ps[STp->partition]); - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) { + if ((STps->rw == ST_WRITING || STp->dirty) && !(STp->device)->was_reset) { + STp->write_type = OS_WRITE_DATA; result = osst_flush_write_buffer(STp, &SRpnt); if (result != 0 && result != (-ENOSPC)) goto out; @@ -4566,22 +4677,7 @@ dev, STp->nbr_waits, STp->nbr_finished); } #endif - if (STp->write_type != OS_WRITE_NEW_MARK) { - /* true unless the user wrote the filemark for us */ - result = osst_flush_drive_buffer(STp, &SRpnt); - if (result < 0) goto out; - result = osst_write_filemark(STp, &SRpnt); - if (result < 0) goto out; - - if (STps->drv_file >= 0) - STps->drv_file++ ; - STps->drv_block = 0; - } - result = osst_write_eod(STp, &SRpnt); - osst_write_header(STp, &SRpnt, !(STp->rew_at_close)); - - STps->eof = ST_FM; - + result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close)); #if DEBUG if (debugging) printk(OSST_DEB_MSG "osst%d:D: Buffer flushed, %d EOF(s) written\n", @@ -4592,7 +4688,7 @@ STps = &(STp->ps[STp->partition]); if (!STm->sysv || STps->rw != ST_READING) { if (STp->can_bsr) - result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ + result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ else if (STps->eof == ST_FM_HIT) { result = cross_eof(STp, &SRpnt, FALSE); if (result) { @@ -4607,7 +4703,7 @@ } else if ((STps->eof == ST_NOEOF && !(result = cross_eof(STp, &SRpnt, TRUE))) || - STps->eof == ST_FM_HIT) { + STps->eof == ST_FM_HIT) { if (STps->drv_file >= 0) STps->drv_file++; STps->drv_block = 0; @@ -4721,6 +4817,7 @@ #endif if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) { struct mtop mtc; + int auto_weof = 0; if (_IOC_SIZE(cmd_in) != sizeof(mtc)) { retval = (-EINVAL); @@ -4801,10 +4898,41 @@ } } - if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM && - mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK && - mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART) - STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */ + if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && + mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && + mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETDRVBUFFER && + mtc.mt_op != MTMKPART && mtc.mt_op != MTSETPART && + mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM ) { + + /* + * The user tells us to move to another position on the tape. + * If we were appending to the tape content, that would leave + * the tape without proper end, in that case write EOD and + * update the header to reflect its position. + */ +#if DEBUG + printk(KERN_WARNING "osst%d:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",dev, + STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle", + STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number, + STp->logical_blk_num, STps->drv_file, STps->drv_block ); +#endif + if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) { + auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) && + !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); + i = osst_write_trailer(STp, &SRpnt, + !(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL)); +#if DEBUG + printk(KERN_WARNING "osst%d:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", + dev, auto_weof, STp->first_frame_position, STp->eod_frame_ppos, + STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block ); +#endif + if (i < 0) { + retval = i; + goto out; + } + } + STps->rw = ST_IDLE; + } if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0); /* Ignore result! */ @@ -4816,12 +4944,6 @@ } if (mtc.mt_op == MTSETPART) { -/* if (!STp->can_partitions || - mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS) - return (-EINVAL); - if (mtc.mt_count >= STp->nbr_partitions && - (STp->nbr_partitions = nbr_partitions(inode)) < 0) - return (-EIO);*/ if (mtc.mt_count >= STp->nbr_partitions) retval = -EINVAL; else { @@ -4864,14 +4986,14 @@ goto out; } -/* if (STp->can_partitions && STp->ready == ST_READY && - (i = update_partition(inode)) < 0) - {retval=i;goto out;}*/ + if (auto_weof) + cross_eof(STp, &SRpnt, FALSE); if (mtc.mt_op == MTCOMPRESSION) - retval = -EINVAL /*osst_compression(STp, (mtc.mt_count & 1))*/; + retval = -EINVAL; /* OnStream drives don't have compression hardware */ else - + /* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS MTLOAD + * MTLOCK MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTUNLOCK MTWEOF MTWSM */ retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count); goto out; } @@ -4886,10 +5008,6 @@ goto out; } -/* if (STp->can_partitions && - (i = update_partition(inode)) < 0) - {retval=i;goto out;}*/ - if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { struct mtget mt_status; @@ -5119,9 +5237,10 @@ for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size; segs < max_segs && got < new_size; ) { STbuffer->sg[segs].address = - (unsigned char *)__get_free_pages(priority, order); + (unsigned char *)__get_free_pages(priority, + (new_size - got <= PAGE_SIZE) ? 0 : order); if (STbuffer->sg[segs].address == NULL) { - if (new_size - got <= (max_segs - segs) * b_size / 2) { + if (new_size - got <= (max_segs - segs) * b_size / 2 && order) { b_size /= 2; /* Large enough for the rest of the buffers */ order--; continue; @@ -5135,9 +5254,9 @@ return FALSE; } STbuffer->sg[segs].page = NULL; - STbuffer->sg[segs].length = b_size; + STbuffer->sg[segs].length = (new_size - got <= PAGE_SIZE / 2) ? (new_size - got) : b_size; STbuffer->sg_segs += 1; - got += b_size; + got += STbuffer->sg[segs].length; STbuffer->buffer_size = got; segs++; } @@ -5320,28 +5439,26 @@ static void validate_options (void) { - if (buffer_kbs > 0) - osst_buffer_size = buffer_kbs * ST_KILOBYTE; + if (max_dev > 0) + osst_max_dev = osst_max_buffers = max_dev; if (write_threshold_kbs > 0) osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; if (osst_write_threshold > osst_buffer_size) osst_write_threshold = osst_buffer_size; - if (max_buffers > 0) - osst_max_buffers = max_buffers; if (max_sg_segs >= OSST_FIRST_SG) osst_max_sg_segs = max_sg_segs; #if DEBUG - printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n", + printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max devices %d, s/g segs %d.\n", osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs); -//printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n", -// sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error"); #endif } #ifndef MODULE -/* Set the boot options. Syntax: osst=xxx,yyy,... - where xxx is buffer size in 1024 byte blocks and yyy is write threshold - in 1024 byte blocks. */ +/* Set the boot options. Syntax: osst=xxx,yyy,zzz + * where xxx is maximum nr of devices to attach, + * yyy is write threshold in 1024 byte blocks + * and zzz the maximum nr of s/g segments to handle. + */ static int __init osst_setup (char *str) { int i, ints[5]; @@ -5417,6 +5534,72 @@ return 0; } +/* + * /proc support for accessing ADR header information + */ +static struct proc_dir_entry * osst_proc_dir = NULL; +static char osst_proc_dirname[] = "osst"; + +static int osst_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int l = 0; + OS_Scsi_Tape * STp = (OS_Scsi_Tape *) data; + + if (!osst_proc_dir) return 0; + + if (STp->header_ok && STp->linux_media) + l = sprintf(page, "%d.%d LIN%d %8d %8d %8d \n", + STp->header_cache->major_rev, + STp->header_cache->minor_rev, + STp->linux_media_version, + STp->first_data_ppos, + STp->eod_frame_ppos, + STp->filemark_cnt ); + return l; +} + +static void osst_proc_init(void) +{ + if (!proc_scsi) return; + + osst_proc_dir = proc_mkdir(osst_proc_dirname, proc_scsi); + osst_proc_dir->owner = THIS_MODULE; +} + +static void osst_proc_create(OS_Scsi_Tape * STp, int dev) +{ + char s[16]; + struct proc_dir_entry * p_entry; + + if (!osst_proc_dir) return; + + sprintf(s, "osst%d", dev); + p_entry = create_proc_read_entry(s, 0444, osst_proc_dir, osst_proc_read, (void *) STp); + p_entry->owner = THIS_MODULE; +} + +static void osst_proc_destroy(int dev) +{ + char s[16]; + + if (!osst_proc_dir) return; + + sprintf(s, "osst%d", dev); + remove_proc_entry(s, osst_proc_dir); +} + +static void osst_proc_cleanup(void) +{ + if ((! proc_scsi) || (!osst_proc_dir)) return; + + remove_proc_entry(osst_proc_dirname, proc_scsi); + osst_proc_dir = NULL; +} + +/* + * osst startup / cleanup code + */ + static int osst_attach(Scsi_Device * SDp) { OS_Scsi_Tape * tpnt; @@ -5462,34 +5645,18 @@ /* Rewind entry */ sprintf (name, "mt%s", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tpnt->de_r[mode] = devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5), S_IFCHR | S_IRUGO | S_IWUGO, &osst_fops, NULL); -# else - tpnt->de_r[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5), - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif /* No-rewind entry */ sprintf (name, "mt%sn", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tpnt->de_n[mode] = devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5) + 128, S_IFCHR | S_IRUGO | S_IWUGO, &osst_fops, NULL); -# else - tpnt->de_n[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5) + 128, - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif } devfs_register_tape (tpnt->de_r[0]); #endif @@ -5522,7 +5689,8 @@ tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); tpnt->omit_blklims = 1; - tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); + tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || + (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); tpnt->frame_in_buffer = 0; tpnt->header_ok = 0; tpnt->linux_media = 0; @@ -5559,6 +5727,8 @@ osst_template.nr_dev++; + osst_proc_create(tpnt, dev); + printk(KERN_INFO "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as osst%d\n", SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, dev); @@ -5597,7 +5767,7 @@ } if (os_scsi_tapes) return 0; - osst_template.dev_max = OSST_MAX_TAPES; + osst_template.dev_max = osst_max_dev; if (osst_template.dev_max > 128 / ST_NBR_MODES) printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES); os_scsi_tapes = @@ -5637,39 +5807,42 @@ printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n", osst_buffer_size, osst_write_threshold); #endif + osst_proc_init(); return 0; } static void osst_detach(Scsi_Device * SDp) { - OS_Scsi_Tape * tpnt; - int i; + OS_Scsi_Tape * tpnt; + int i; #ifdef CONFIG_DEVFS_FS - int mode; + int mode; #endif - - for(i=0; idevice == SDp) { - tpnt->device = NULL; + for(i=0; idevice == SDp) { + osst_proc_destroy(i); + tpnt->device = NULL; #ifdef CONFIG_DEVFS_FS - for (mode = 0; mode < ST_NBR_MODES; ++mode) { - devfs_unregister (tpnt->de_r[mode]); - tpnt->de_r[mode] = NULL; - devfs_unregister (tpnt->de_n[mode]); - tpnt->de_n[mode] = NULL; + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + devfs_unregister (tpnt->de_r[mode]); + tpnt->de_r[mode] = NULL; + devfs_unregister (tpnt->de_n[mode]); + tpnt->de_n[mode] = NULL; + } +#endif + if (tpnt->header_cache != NULL) { + vfree(tpnt->header_cache); + } + kfree(tpnt); + os_scsi_tapes[i] = NULL; + SDp->attached--; + osst_template.nr_dev--; + osst_template.dev_noticed--; + return; } -#endif - kfree(tpnt); - os_scsi_tapes[i] = NULL; - SDp->attached--; - osst_template.nr_dev--; - osst_template.dev_noticed--; - return; } - } - return; } static int __init init_osst(void) @@ -5681,38 +5854,32 @@ static void __exit exit_osst (void) { - int i; - OS_Scsi_Tape * STp; + int i; - scsi_unregister_module(MODULE_SCSI_DEV, &osst_template); + scsi_unregister_module(MODULE_SCSI_DEV, &osst_template); #ifdef CONFIG_DEVFS_FS - devfs_unregister_chrdev(MAJOR_NR, "osst"); + devfs_unregister_chrdev(MAJOR_NR, "osst"); #else - unregister_chrdev(MAJOR_NR, "osst"); + unregister_chrdev(MAJOR_NR, "osst"); #endif - osst_registered--; - if(os_scsi_tapes != NULL) { - for (i=0; i < osst_template.dev_max; ++i) { - if ((STp = os_scsi_tapes[i])) { - if (STp->header_cache != NULL) vfree(STp->header_cache); - kfree(STp); - } - } - kfree(os_scsi_tapes); + osst_registered--; + osst_proc_cleanup(); + + if(os_scsi_tapes != NULL) { + kfree(os_scsi_tapes); + } if (osst_buffers != NULL) { for (i=0; i < osst_nbr_buffers; i++) - if (osst_buffers[i] != NULL) { - osst_buffers[i]->orig_sg_segs = 0; - normalize_buffer(osst_buffers[i]); - kfree(osst_buffers[i]); - } - + if (osst_buffers[i] != NULL) { + osst_buffers[i]->orig_sg_segs = 0; + normalize_buffer(osst_buffers[i]); + kfree(osst_buffers[i]); + } kfree(osst_buffers); } - } - osst_template.dev_max = 0; - printk(KERN_INFO "osst :I: Unloaded.\n"); + osst_template.dev_max = 0; + printk(KERN_INFO "osst :I: Unloaded.\n"); } module_init(init_osst); diff -urN linux-2.4.24/drivers/scsi/osst.h linux-2.4.25/drivers/scsi/osst.h --- linux-2.4.24/drivers/scsi/osst.h 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.25/drivers/scsi/osst.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvsroot/Driver/osst.h,v 1.12 2001/10/11 00:30:15 riede Exp $ + * $Header: /cvsroot/osst/Driver/osst.h,v 1.12 2001/10/11 00:30:15 riede Exp $ */ #include diff -urN linux-2.4.24/drivers/scsi/osst_options.h linux-2.4.25/drivers/scsi/osst_options.h --- linux-2.4.24/drivers/scsi/osst_options.h 2001-06-11 19:15:27.000000000 -0700 +++ linux-2.4.25/drivers/scsi/osst_options.h 2004-02-18 05:36:31.000000000 -0800 @@ -8,7 +8,7 @@ Changed (and renamed) for OnStream SCSI drives garloff@suse.de 2000-06-21 - $Header: /home/cvsroot/Driver/osst_options.h,v 1.5 2001/01/07 22:19:15 riede Exp $ + $Header: /cvsroot/osst/Driver/osst_options.h,v 1.5 2001/01/07 22:19:15 riede Exp $ */ #ifndef _OSST_OPTIONS_H diff -urN linux-2.4.24/drivers/scsi/qlogicfas.c linux-2.4.25/drivers/scsi/qlogicfas.c --- linux-2.4.24/drivers/scsi/qlogicfas.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/scsi/qlogicfas.c 2004-02-18 05:36:31.000000000 -0800 @@ -111,10 +111,6 @@ #include -#ifdef PCMCIA -#undef MODULE -#endif - #include /* to get disk capacity */ #include #include @@ -131,6 +127,10 @@ #include "qlogicfas.h" #include +#ifdef PCMCIA +#undef MODULE +#endif + /*----------------------------------------------------------------*/ /* driver state info, local to driver */ static int qbase; /* Port */ @@ -647,7 +647,7 @@ if(request_irq(qlirq, do_ql_ihandl, SA_SHIRQ, "qlogicfas", hreg) < 0) #endif { - scsi_unregister(host); + scsi_unregister(hreg); goto err_release_mem; } #endif @@ -717,7 +717,9 @@ } MODULE_LICENSE("GPL"); +#ifndef PCMCIA /* Eventually this will go into an include file, but this will be later */ static Scsi_Host_Template driver_template = QLOGICFAS; #include "scsi_module.c" +#endif diff -urN linux-2.4.24/drivers/scsi/sgiwd93.c linux-2.4.25/drivers/scsi/sgiwd93.c --- linux-2.4.24/drivers/scsi/sgiwd93.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/scsi/sgiwd93.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,23 +1,23 @@ /* - * sgiwd93.c: SGI WD93 scsi driver. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * 1999 Andrew R. Baker (andrewb@uab.edu) - * - Support for 2nd SCSI controller on Indigo2 - * 2001 Florian Lohoff (flo@rfc822.org) - * - Delete HPC scatter gather (Read corruption on - * multiple disks) - * - Cleanup wback cache handling + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) + * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) + * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) * * (In all truth, Jed Schimmel wrote all this code.) - * */ #include +#include #include #include #include #include #include +#include #include #include @@ -37,13 +37,29 @@ #include +#if 0 +#define DPRINTK(args...) printk(args) +#else +#define DPRINTK(args...) +#endif + +#define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) + +struct ip22_hostdata { + struct WD33C93_hostdata wh; + struct hpc_data { + dma_addr_t dma; + void * cpu; + } hd; +}; + struct hpc_chunk { struct hpc_dma_desc desc; u32 _padding; /* align to quadword boundary */ }; -struct Scsi_Host *sgiwd93_host = NULL; -struct Scsi_Host *sgiwd93_host1 = NULL; +struct Scsi_Host *sgiwd93_host; +struct Scsi_Host *sgiwd93_host1; /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ static inline void write_wd33c93_count(const wd33c93_regs regs, @@ -79,74 +95,70 @@ spin_unlock_irqrestore(&io_request_lock, flags); } -#undef DEBUG_DMA - static inline -void fill_hpc_entries (struct hpc_chunk **hcp, char *addr, unsigned long len) +void fill_hpc_entries(struct hpc_chunk *hcp, Scsi_Cmnd *cmd, int datainp) { - unsigned long physaddr; + unsigned long len = cmd->SCp.this_residual; + void *addr = cmd->SCp.ptr; + dma_addr_t physaddr; unsigned long count; - - physaddr = PHYSADDR(addr); + + physaddr = pci_map_single(NULL, addr, len, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->SCp.dma_handle = physaddr; + while (len) { /* * even cntinfo could be up to 16383, without * magic only 8192 works correctly */ count = len > 8192 ? 8192 : len; - (*hcp)->desc.pbuf = physaddr; - (*hcp)->desc.cntinfo = count; - (*hcp)++; + hcp->desc.pbuf = physaddr; + hcp->desc.cntinfo = count; + hcp++; len -= count; physaddr += count; } + + /* + * To make sure, if we trip an HPC bug, that we transfer every single + * byte, we tag on an extra zero length dma descriptor at the end of + * the chain. + */ + hcp->desc.pbuf = 0; + hcp->desc.cntinfo = HPCDMA_EOX; } static int dma_setup(Scsi_Cmnd *cmd, int datainp) { - struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)cmd->host->hostdata; - struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->host->base; - struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->dma_bounce_buffer; - -#ifdef DEBUG_DMA - printk("dma_setup: datainp<%d> hcp<%p> ", - datainp, hcp); -#endif + struct ip22_hostdata *hdata = HDATA(cmd->host); + struct hpc3_scsiregs *hregs = + (struct hpc3_scsiregs *) cmd->host->base; + struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - hdata->dma_dir = datainp; + DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + + hdata->wh.dma_dir = datainp; /* - * wd33c93 shouldn't pass us bogus dma_setups, but - * it does:-( The other wd33c93 drivers deal with - * it the same way (which isn't that obvious). - * IMHO a better fix would be, not to do these - * dma setups in the first place + * wd33c93 shouldn't pass us bogus dma_setups, but it does:-( The + * other wd33c93 drivers deal with it the same way (which isn't that + * obvious). IMHO a better fix would be, not to do these dma setups + * in the first place. */ if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries (&hcp, cmd->SCp.ptr, cmd->SCp.this_residual); + fill_hpc_entries(hcp, cmd, datainp); - /* To make sure, if we trip an HPC bug, that we transfer - * every single byte, we tag on an extra zero length dma - * descriptor at the end of the chain. - */ - hcp->desc.pbuf = 0; - hcp->desc.cntinfo = (HPCDMA_EOX); - -#ifdef DEBUG_DMA - printk(" HPCGO\n"); -#endif + DPRINTK(" HPCGO\n"); /* Start up the HPC. */ - hregs->ndptr = PHYSADDR(hdata->dma_bounce_buffer); - if(datainp) { - dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual); - hregs->ctrl = (HPC3_SCTRL_ACTIVE); - } else { - dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual); - hregs->ctrl = (HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR); - } + hregs->ndptr = hdata->hd.dma; + if (datainp) + hregs->ctrl = HPC3_SCTRL_ACTIVE; + else + hregs->ctrl = HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR; return 0; } @@ -154,7 +166,7 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, int status) { - struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)instance->hostdata; + struct ip22_hostdata *hdata = HDATA(instance); struct hpc3_scsiregs *hregs; if (!SCpnt) @@ -162,21 +174,19 @@ hregs = (struct hpc3_scsiregs *) SCpnt->host->base; -#ifdef DEBUG_DMA - printk("dma_stop: status<%d> ", status); -#endif + DPRINTK("dma_stop: status<%d> ", status); /* First stop the HPC and flush it's FIFO. */ - if(hdata->dma_dir) { + if (hdata->wh.dma_dir) { hregs->ctrl |= HPC3_SCTRL_FLUSH; - while(hregs->ctrl & HPC3_SCTRL_ACTIVE) + while (hregs->ctrl & HPC3_SCTRL_ACTIVE) barrier(); } hregs->ctrl = 0; + pci_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); -#ifdef DEBUG_DMA - printk("\n"); -#endif + DPRINTK("\n"); } void sgiwd93_reset(unsigned long base) @@ -184,119 +194,97 @@ struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) base; hregs->ctrl = HPC3_SCTRL_CRESET; - udelay (50); + udelay(50); hregs->ctrl = 0; } -static inline void init_hpc_chain(uchar *buf) +static inline void init_hpc_chain(struct hpc_data *hd) { - struct hpc_chunk *hcp = (struct hpc_chunk *) buf; + struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu; + struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma; unsigned long start, end; - start = (unsigned long) buf; + start = (unsigned long) hcp; end = start + PAGE_SIZE; - while(start < end) { - hcp->desc.pnext = PHYSADDR((hcp + 1)); + while (start < end) { + hcp->desc.pnext = (u32) (dma + 1); hcp->desc.cntinfo = HPCDMA_EOX; - hcp++; + hcp++; dma++; start += sizeof(struct hpc_chunk); }; hcp--; - hcp->desc.pnext = PHYSADDR(buf); - - /* Force flush to memory */ - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); + hcp->desc.pnext = hd->dma; } -int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) +static struct Scsi_Host * __init sgiwd93_setup_scsi( + Scsi_Host_Template *SGIblows, int unit, int irq, + struct hpc3_scsiregs *hregs, unsigned char *wdregs) { - static unsigned char called = 0; - struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0; - struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1; - struct WD33C93_hostdata *hdata; - struct WD33C93_hostdata *hdata1; + struct ip22_hostdata *hdata; + struct Scsi_Host *host; wd33c93_regs regs; - uchar *buf; - - if(called) - return 0; /* Should bitch on the console about this... */ - SGIblows->proc_name = "SGIWD93"; - - sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - if(sgiwd93_host == NULL) - return 0; - sgiwd93_host->base = (unsigned long) hregs; - sgiwd93_host->irq = SGI_WD93_0_IRQ; - - buf = (uchar *) get_zeroed_page(GFP_KERNEL); - if (!buf) { - printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n"); - scsi_unregister(sgiwd93_host); - return 0; + host = scsi_register(SGIblows, sizeof(struct ip22_hostdata)); + if (!host) + return NULL; + + host->base = (unsigned long) hregs; + host->irq = irq; + + hdata = HDATA(host); + hdata->hd.cpu = pci_alloc_consistent(NULL, PAGE_SIZE, &hdata->hd.dma); + if (!hdata->hd.cpu) { + printk(KERN_WARNING "sgiwd93: Could not allocate memory for " + "host %d buffer.\n", unit); + goto out_unregister; } - init_hpc_chain(buf); - - /* HPC_SCSI_REG0 | 0x03 | KSEG1 */ - regs.SASR = (unsigned char*) KSEG1ADDR (0x1fbc0003); - regs.SCMD = (unsigned char*) KSEG1ADDR (0x1fbc0007); - wd33c93_init(sgiwd93_host, regs, dma_setup, dma_stop, WD33C93_FS_16_20); - - hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata; - hdata->no_sync = 0; - hdata->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); + init_hpc_chain(&hdata->hd); - if (request_irq(SGI_WD93_0_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host)) { - printk(KERN_WARNING "sgiwd93: Could not register IRQ %d (for host 0).\n", SGI_WD93_0_IRQ); -#ifdef MODULE - wd33c93_release(); -#endif - free_page((unsigned long)buf); - scsi_unregister(sgiwd93_host); - return 0; + regs.SASR = wdregs + 3; + regs.SCMD = wdregs + 7; + + wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_16_20); + + hdata->wh.no_sync = 0; + + if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) { + printk(KERN_WARNING "sgiwd93: Could not register irq %d " + "for host %d.\n", irq, unit); + goto out_free; } - /* set up second controller on the Indigo2 */ - if(ip22_is_fullhouse()) { - sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - if(sgiwd93_host1 != NULL) - { - sgiwd93_host1->base = (unsigned long) hregs1; - sgiwd93_host1->irq = SGI_WD93_1_IRQ; - - buf = (uchar *) get_zeroed_page(GFP_KERNEL); - if (!buf) { - printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n"); - scsi_unregister(sgiwd93_host1); - called = 1; - return 1; /* We registered host0 so return success*/ - } - init_hpc_chain(buf); - - /* HPC_SCSI_REG1 | 0x03 | KSEG1 */ - regs.SASR = (unsigned char*) KSEG1ADDR(0x1fbc8003); - regs.SCMD = (unsigned char*) KSEG1ADDR(0x1fbc8007); - wd33c93_init(sgiwd93_host1, regs, dma_setup, dma_stop, - WD33C93_FS_16_20); - - hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata; - hdata1->no_sync = 0; - hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf)); - - if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) { - printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ); -#ifdef MODULE - wd33c93_release(); -#endif - free_page((unsigned long)buf); - scsi_unregister(sgiwd93_host1); - /* Fall through since host0 registered OK */ - } - } + return host; + +out_free: + pci_free_consistent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); + wd33c93_release(); + +out_unregister: + scsi_unregister(host); + + return NULL; +} + +int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) +{ + int found = 0; + + SGIblows->proc_name = "SGIWD93"; + sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ, + &hpc3c0->scsi_chan0, + (unsigned char *)hpc3c0->scsi0_ext); + if (sgiwd93_host) + found++; + + /* Set up second controller on the Indigo2 */ + if (ip22_is_fullhouse()) { + sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ, + &hpc3c0->scsi_chan1, + (unsigned char *)hpc3c0->scsi1_ext); + if (sgiwd93_host1) + found++; } - - called = 1; - return 1; /* Found one. */ + return found; } #define HOSTS_C @@ -311,11 +299,12 @@ { #ifdef MODULE free_irq(SGI_WD93_0_IRQ, sgiwd93_intr); - free_page(KSEG0ADDR(hdata->dma_bounce_buffer)); + pci_free_consistent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); wd33c93_release(); - if(ip22_is_fullhouse()) { + if (ip22_is_fullhouse()) { free_irq(SGI_WD93_1_IRQ, sgiwd93_intr); - free_page(KSEG0ADDR(hdata1->dma_bounce_buffer)); + pci_free_consistent(NULL, PAGE_SIZE, hdata1->hd.cpu, + hdata1->hd.dma); wd33c93_release(); } #endif diff -urN linux-2.4.24/drivers/scsi/st.c linux-2.4.25/drivers/scsi/st.c --- linux-2.4.24/drivers/scsi/st.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/scsi/st.c 2004-02-18 05:36:31.000000000 -0800 @@ -9,10 +9,10 @@ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2003 Kai Makisara + Copyright 1992 - 2004 Kai Makisara email Kai.Makisara@kolumbus.fi - Last modified: Sun Apr 6 22:44:42 2003 by makisara + Last modified: Fri Jan 2 17:50:08 2004 by makisara Some small formal changes - aeb, 950809 Last modified: 18-JAN-1998 Richard Gooch Devfs support @@ -21,7 +21,7 @@ error handling will be discarded. */ -static char *verstr = "20030406"; +static char *verstr = "20040102"; #include @@ -1277,6 +1277,18 @@ goto out; } + if ((STp->buffer)->writing) { + write_behind_check(STp); + if ((STp->buffer)->syscall_result) { + DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n", + dev, (STp->buffer)->midlevel_result)); + if ((STp->buffer)->midlevel_result == INT_MAX) + STps->eof = ST_EOM_OK; + else + STps->eof = ST_EOM_ERROR; + } + } + if (STp->block_size == 0) { if (STp->max_block > 0 && (count < STp->min_block || count > STp->max_block)) { @@ -1324,18 +1336,6 @@ } } - if ((STp->buffer)->writing) { - write_behind_check(STp); - if ((STp->buffer)->syscall_result) { - DEBC(printk(ST_DEB_MSG "st%d: Async write error (write) %x.\n", - dev, (STp->buffer)->midlevel_result)); - if ((STp->buffer)->midlevel_result == INT_MAX) - STps->eof = ST_EOM_OK; - else - STps->eof = ST_EOM_ERROR; - } - } - if (STps->eof == ST_EOM_OK) { retval = (-ENOSPC); goto out; diff -urN linux-2.4.24/drivers/sound/ac97_plugin_ad1980.c linux-2.4.25/drivers/sound/ac97_plugin_ad1980.c --- linux-2.4.24/drivers/sound/ac97_plugin_ad1980.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/sound/ac97_plugin_ad1980.c 2004-02-18 05:36:31.000000000 -0800 @@ -45,7 +45,7 @@ * use of the codec after the probe function. */ -static void ad1980_remove(struct ac97_codec *codec) +static void ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver) { /* Nothing to do in the simple example */ } @@ -72,9 +72,11 @@ #define AC97_AD_MISC 0x76 - /* Switch the inputs/outputs over (from Dell code) */ + /* Switch the inputs/outputs over (from Dell code) + Set the ADI compatibility mode (AC97NC bit) */ + control = codec->codec_read(codec, AC97_AD_MISC); - codec->codec_write(codec, AC97_AD_MISC, control | 0x0420); + codec->codec_write(codec, AC97_AD_MISC, control | 0x4420); /* We could refuse the device since we dont need to hang around, but we will claim it */ @@ -120,5 +122,6 @@ return ac97_register_driver(&ad1980_driver); } +MODULE_LICENSE("GPL"); module_init(ad1980_init); module_exit(ad1980_exit); diff -urN linux-2.4.24/drivers/sound/au1000.c linux-2.4.25/drivers/sound/au1000.c --- linux-2.4.24/drivers/sound/au1000.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/sound/au1000.c 2004-02-18 05:36:31.000000000 -0800 @@ -2027,7 +2027,7 @@ s->codec = ac97_alloc_codec(); if(s->codec == NULL) { - error("Out of memory"); + err("Out of memory"); return -1; } s->codec->private_data = s; diff -urN linux-2.4.24/drivers/sound/hal2.c linux-2.4.25/drivers/sound/hal2.c --- linux-2.4.24/drivers/sound/hal2.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/sound/hal2.c 2004-02-18 05:36:31.000000000 -0800 @@ -21,19 +21,18 @@ * /dev/dsp standard dsp device, (mostly) OSS compatible * /dev/mixer standard mixer device, (mostly) OSS compatible * - * TODO: 4 channel mode? */ - #include #include #include #include #include #include +#include #include #include + #include -#include #include #include @@ -51,15 +50,83 @@ #define DEBUG_MIX(args...) #endif +/* + * Before touching these look how it works. It is a bit unusual I know, + * but it helps to keep things simple. This driver is considered complete + * and I won't add any new features although hardware has many cool + * capabilities. + * (Historical note: HAL2 driver was first written by Ulf Carlsson - ALSA + * 0.3 running with 2.2.x kernel. Then ALSA changed completely and it + * seemed easier to me to write OSS driver from scratch - this one. Now + * when ALSA is official part of 2.6 kernel it's time to write ALSA driver + * using (hopefully) final version of ALSA interface) + */ +#define H2_BLOCK_SIZE 1024 +#define H2_ADC_BUFSIZE 8192 +#define H2_DAC_BUFSIZE 16834 + +struct hal2_pbus { + struct hpc3_pbus_dmacregs *pbus; + int pbusnr; + unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */ +}; + +struct hal2_desc { + struct hpc_dma_desc desc; + u32 cnt; /* don't touch, it is also padding */ +}; + +struct hal2_codec { + unsigned char *buffer; + struct hal2_desc *desc; + int desc_count; + int tail, head; /* tail index, head index */ + struct hal2_pbus pbus; + unsigned int format; /* Audio data format */ + int voices; /* mono/stereo */ + unsigned int sample_rate; + unsigned int master; /* Master frequency */ + unsigned short mod; /* MOD value */ + unsigned short inc; /* INC value */ + + wait_queue_head_t dma_wait; + spinlock_t lock; + struct semaphore sem; + + int usecount; /* recording and playback are + * independent */ +}; + +#define H2_MIX_OUTPUT_ATT 0 +#define H2_MIX_INPUT_GAIN 1 +#define H2_MIXERS 2 +struct hal2_mixer { + int modcnt; + unsigned int master; + unsigned int volume[H2_MIXERS]; +}; + +struct hal2_card { + int dev_dsp; /* audio device */ + int dev_mixer; /* mixer device */ + int dev_midi; /* midi device */ + + struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */ + struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */ + struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */ + struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */ + + struct hal2_codec dac; + struct hal2_codec adc; + struct hal2_mixer mixer; +}; + #define H2_INDIRECT_WAIT(regs) while (regs->isr & H2_ISR_TSTATUS); #define H2_READ_ADDR(addr) (addr | (1<<7)) #define H2_WRITE_ADDR(addr) (addr) static char *hal2str = "HAL2"; -static int msmix = 0; -static int ibufs = 4; -static int obufs = 8; /* * I doubt anyone has a machine with two HAL2 cards. It's possible to @@ -111,10 +178,10 @@ regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - ret = regs->idr0; + ret = regs->idr0 & 0xffff; regs->iar = H2_READ_ADDR(addr | 0x1); H2_INDIRECT_WAIT(regs); - ret |= regs->idr0 << 16; + ret |= (regs->idr0 & 0xffff) << 16; return ret; } @@ -148,7 +215,7 @@ regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - regs->idr0 = regs->idr0 | bit; + regs->idr0 = (regs->idr0 & 0xffff) | bit; regs->idr1 = 0; regs->idr2 = 0; regs->idr3 = 0; @@ -163,7 +230,7 @@ regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - tmp = regs->idr0 | (regs->idr1 << 16) | bit; + tmp = (regs->idr0 & 0xffff) | (regs->idr1 << 16) | bit; regs->idr0 = tmp & 0xffff; regs->idr1 = tmp >> 16; regs->idr2 = 0; @@ -178,7 +245,7 @@ regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - regs->idr0 = regs->idr0 & ~bit; + regs->idr0 = (regs->idr0 & 0xffff) & ~bit; regs->idr1 = 0; regs->idr2 = 0; regs->idr3 = 0; @@ -194,7 +261,7 @@ regs->iar = H2_READ_ADDR(addr); H2_INDIRECT_WAIT(regs); - tmp = (regs->idr0 | (regs->idr1 << 16)) & ~bit; + tmp = ((regs->idr0 & 0xffff) | (regs->idr1 << 16)) & ~bit; regs->idr0 = tmp & 0xffff; regs->idr1 = tmp >> 16; regs->idr2 = 0; @@ -250,24 +317,33 @@ return NULL; } +static void hal2_inc_head(struct hal2_codec *codec) +{ + codec->head++; + if (codec->head == codec->desc_count) + codec->head = 0; +} + +static void hal2_inc_tail(struct hal2_codec *codec) +{ + codec->tail++; + if (codec->tail == codec->desc_count) + codec->tail = 0; +} static void hal2_dac_interrupt(struct hal2_codec *dac) { int running; spin_lock(&dac->lock); - /* if tail buffer contains zero samples DMA stream was already * stopped */ - running = dac->tail->info.cnt; - dac->tail->info.cnt = 0; - dac->tail->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; - dma_cache_wback_inv((unsigned long) dac->tail, - sizeof(struct hpc_dma_desc)); + running = dac->desc[dac->tail].cnt; + dac->desc[dac->tail].cnt = 0; + dac->desc[dac->tail].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; /* we just proccessed empty buffer, don't update tail pointer */ if (running) - dac->tail = dac->tail->info.next; - + hal2_inc_tail(dac); spin_unlock(&dac->lock); wake_up(&dac->dma_wait); @@ -278,20 +354,14 @@ int running; spin_lock(&adc->lock); - /* if head buffer contains nonzero samples DMA stream was already * stopped */ - running = !adc->head->info.cnt; - adc->head->info.cnt = H2_BUFFER_SIZE; - adc->head->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX; - dma_cache_wback_inv((unsigned long) adc->head, - sizeof(struct hpc_dma_desc)); + running = !adc->desc[adc->head].cnt; + adc->desc[adc->head].cnt = H2_BLOCK_SIZE; + adc->desc[adc->head].desc.cntinfo = HPCDMA_XIE | HPCDMA_EOR; /* we just proccessed empty buffer, don't update head pointer */ - if (running) { - dma_cache_inv((unsigned long) adc->head->data, H2_BUFFER_SIZE); - adc->head = adc->head->info.next; - } - + if (running) + hal2_inc_head(adc); spin_unlock(&adc->lock); wake_up(&adc->dma_wait); @@ -371,13 +441,11 @@ * endian. The information is written later, on the start call. */ sample_size = 2 * hal2->dac.voices; - /* Fifo should be set to hold exactly four samples. Highwater mark * should be set to two samples. */ highwater = (sample_size * 2) >> 1; /* halfwords */ fifobeg = 0; /* playback is first */ fifoend = (sample_size * 4) >> 3; /* doublewords */ - pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD | (highwater << 8) | (fifobeg << 16) | (fifoend << 24) | (hal2->dac.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0); @@ -407,11 +475,9 @@ DEBUG("hal2_setup_adc\n"); sample_size = 2 * hal2->adc.voices; - highwater = (sample_size * 2) >> 1; /* halfwords */ fifobeg = (4 * 4) >> 3; /* record is second */ fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */ - pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | (highwater << 8) | (fifobeg << 16) | (fifoend << 24) | (hal2->adc.format & AFMT_S16_LE ? HPC3_PDMACTRL_SEL : 0); @@ -432,124 +498,118 @@ | (hal2->adc.voices << H2I_C1_DATAT_SHIFT)); } +static dma_addr_t hal2_desc_addr(struct hal2_codec *codec, int i) +{ + if (--i < 0) + i = codec->desc_count - 1; + return codec->desc[i].desc.pnext; +} + static void hal2_start_dac(struct hal2_card *hal2) { - struct hal2_pbus *pbus = &hal2->dac.pbus; + struct hal2_codec *dac = &hal2->dac; + struct hal2_pbus *pbus = &dac->pbus; - DEBUG("hal2_start_dac\n"); - - pbus->pbus->pbdma_dptr = PHYSADDR(hal2->dac.tail); + pbus->pbus->pbdma_dptr = hal2_desc_addr(dac, dac->tail); pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; - /* enable DAC */ hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); } static void hal2_start_adc(struct hal2_card *hal2) { - struct hal2_pbus *pbus = &hal2->adc.pbus; + struct hal2_codec *adc = &hal2->adc; + struct hal2_pbus *pbus = &adc->pbus; - DEBUG("hal2_start_adc\n"); - - pbus->pbus->pbdma_dptr = PHYSADDR(hal2->adc.head); + pbus->pbus->pbdma_dptr = hal2_desc_addr(adc, adc->head); pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; - /* enable ADC */ hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); } static inline void hal2_stop_dac(struct hal2_card *hal2) { - DEBUG("hal2_stop_dac\n"); - hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; /* The HAL2 itself may remain enabled safely */ } static inline void hal2_stop_adc(struct hal2_card *hal2) { - DEBUG("hal2_stop_adc\n"); - hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; } -#define hal2_alloc_dac_dmabuf(hal2) hal2_alloc_dmabuf(hal2, 1) -#define hal2_alloc_adc_dmabuf(hal2) hal2_alloc_dmabuf(hal2, 0) -static int hal2_alloc_dmabuf(struct hal2_card *hal2, int is_dac) -{ - int buffers, cntinfo; - struct hal2_buf *buf, *prev; - struct hal2_codec *codec; - - if (is_dac) { - codec = &hal2->dac; - buffers = obufs; - cntinfo = HPCDMA_XIE | HPCDMA_EOX; - } else { - codec = &hal2->adc; - buffers = ibufs; - cntinfo = HPCDMA_XIE | H2_BUFFER_SIZE; - } - - DEBUG("allocating %d DMA buffers.\n", buffers); - - buf = (struct hal2_buf *)get_zeroed_page(GFP_KERNEL); - if (!buf) +static int hal2_alloc_dmabuf(struct hal2_codec *codec, int size, + int count, int cntinfo, int dir) +{ + struct hal2_desc *desc, *dma_addr; + int i; + + DEBUG("allocating %dk DMA buffer.\n", size / 1024); + + codec->buffer = (unsigned char *)__get_free_pages(GFP_KERNEL | GFP_DMA, + get_order(size)); + if (!codec->buffer) return -ENOMEM; - codec->head = buf; - codec->tail = buf; - - while (--buffers) { - buf->info.desc.pbuf = PHYSADDR(&buf->data); - buf->info.desc.cntinfo = cntinfo; - buf->info.cnt = 0; - prev = buf; - buf = (struct hal2_buf *)get_zeroed_page(GFP_KERNEL); - if (!buf) { - printk(KERN_ERR - "HAL2: Not enough memory for DMA buffer.\n"); - buf = codec->head; - while (buf) { - prev = buf; - free_page((unsigned long) buf); - buf = prev->info.next; - } - return -ENOMEM; - } - prev->info.next = buf; - prev->info.desc.pnext = PHYSADDR(buf); - /* The PBUS can prolly not read this stuff when it's in - * the cache so we have to flush it back to main memory */ - dma_cache_wback_inv((unsigned long) prev, PAGE_SIZE); - } - buf->info.desc.pbuf = PHYSADDR(&buf->data); - buf->info.desc.cntinfo = cntinfo; - buf->info.cnt = 0; - buf->info.next = codec->head; - buf->info.desc.pnext = PHYSADDR(codec->head); - dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE); - + desc = pci_alloc_consistent(NULL, count * sizeof(struct hal2_desc), + (dma_addr_t *)&dma_addr); + if (!desc) { + free_pages((unsigned long)codec->buffer, get_order(size)); + return -ENOMEM; + } + codec->desc = desc; + for (i = 0; i < count; i++) { + desc->desc.pbuf = pci_map_single(NULL, + (void *)(codec->buffer + i * H2_BLOCK_SIZE), + H2_BLOCK_SIZE, dir); + desc->desc.cntinfo = cntinfo; + desc->desc.pnext = (i == count - 1) ? + (u32)dma_addr : (u32)(dma_addr + i + 1); + desc->cnt = 0; + desc++; + } + codec->desc_count = count; + codec->head = codec->tail = 0; return 0; } -#define hal2_free_dac_dmabuf(hal2) hal2_free_dmabuf(hal2, 1) -#define hal2_free_adc_dmabuf(hal2) hal2_free_dmabuf(hal2, 0) -static void hal2_free_dmabuf(struct hal2_card *hal2, int is_dac) +static int hal2_alloc_dac_dmabuf(struct hal2_codec *codec) { - struct hal2_buf *buf, *next; - struct hal2_codec *codec = (is_dac) ? &hal2->dac : &hal2->adc; + return hal2_alloc_dmabuf(codec, H2_DAC_BUFSIZE, + H2_DAC_BUFSIZE / H2_BLOCK_SIZE, + HPCDMA_XIE | HPCDMA_EOX, + PCI_DMA_TODEVICE); +} - if (!codec->head) - return; - - buf = codec->head->info.next; - codec->head->info.next = NULL; - while (buf) { - next = buf->info.next; - free_page((unsigned long) buf); - buf = next; - } - codec->head = codec->tail = NULL; +static int hal2_alloc_adc_dmabuf(struct hal2_codec *codec) +{ + return hal2_alloc_dmabuf(codec, H2_ADC_BUFSIZE, + H2_ADC_BUFSIZE / H2_BLOCK_SIZE, + HPCDMA_XIE | H2_BLOCK_SIZE, + PCI_DMA_FROMDEVICE); +} + +static void hal2_free_dmabuf(struct hal2_codec *codec, int size, int dir) +{ + dma_addr_t dma_addr; + int i; + + dma_addr = codec->desc[codec->desc_count - 1].desc.pnext; + for (i = 0; i < codec->desc_count; i++) + pci_unmap_single(NULL, codec->desc[i].desc.pbuf, + H2_BLOCK_SIZE, dir); + pci_free_consistent(NULL, codec->desc_count * sizeof(struct hal2_desc), + (void *)codec->desc, dma_addr); + free_pages((unsigned long)codec->buffer, get_order(size)); +} + +static void hal2_free_dac_dmabuf(struct hal2_codec *codec) +{ + return hal2_free_dmabuf(codec, H2_DAC_BUFSIZE, PCI_DMA_TODEVICE); +} + +static void hal2_free_adc_dmabuf(struct hal2_codec *codec) +{ + return hal2_free_dmabuf(codec, H2_ADC_BUFSIZE, PCI_DMA_FROMDEVICE); } /* @@ -560,43 +620,37 @@ { unsigned long flags; int size, ret = 0; + unsigned char *buf; + struct hal2_desc *tail; struct hal2_codec *adc = &hal2->adc; - spin_lock_irqsave(&adc->lock, flags); - DEBUG("getting %d bytes ", count); + spin_lock_irqsave(&adc->lock, flags); + tail = &adc->desc[adc->tail]; /* enable DMA stream if there are no data */ - if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && - adc->tail->info.cnt == 0) + if (!tail->cnt && !(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT)) hal2_start_adc(hal2); - - while (adc->tail->info.cnt > 0 && count > 0) { - size = min(adc->tail->info.cnt, count); + while (tail->cnt > 0 && count > 0) { + size = min((int)tail->cnt, count); + buf = &adc->buffer[(adc->tail + 1) * H2_BLOCK_SIZE - tail->cnt]; spin_unlock_irqrestore(&adc->lock, flags); - - if (copy_to_user(buffer, - &adc->tail->data[H2_BUFFER_SIZE - - adc->tail->info.cnt], - size)) { + pci_dma_sync_single(NULL, tail->desc.pbuf, size, + PCI_DMA_FROMDEVICE); + if (copy_to_user(buffer, buf, size)) { ret = -EFAULT; goto out; } - spin_lock_irqsave(&adc->lock, flags); - - adc->tail->info.cnt -= size; + tail->cnt -= size; /* buffer is empty, update tail pointer */ - if (adc->tail->info.cnt == 0) { - adc->tail->info.desc.cntinfo = HPCDMA_XIE | - H2_BUFFER_SIZE; - dma_cache_wback_inv((unsigned long) adc->tail, - sizeof(struct hpc_dma_desc)); - adc->tail = adc->tail->info.next; + if (tail->cnt == 0) { + tail->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE; + hal2_inc_tail(adc); + tail = &adc->desc[adc->tail]; /* enable DMA stream again if needed */ if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT)) hal2_start_adc(hal2); - } buffer += size; ret += size; @@ -618,37 +672,38 @@ static int hal2_add_buffer(struct hal2_card *hal2, char *buffer, int count) { unsigned long flags; + unsigned char *buf; int size, ret = 0; + struct hal2_desc *head; struct hal2_codec *dac = &hal2->dac; - spin_lock_irqsave(&dac->lock, flags); - DEBUG("adding %d bytes ", count); - while (dac->head->info.cnt == 0 && count > 0) { - size = min((int)H2_BUFFER_SIZE, count); + spin_lock_irqsave(&dac->lock, flags); + head = &dac->desc[dac->head]; + while (head->cnt == 0 && count > 0) { + size = min((int)H2_BLOCK_SIZE, count); + buf = &dac->buffer[dac->head * H2_BLOCK_SIZE]; spin_unlock_irqrestore(&dac->lock, flags); - - if (copy_from_user(dac->head->data, buffer, size)) { + if (copy_from_user(buf, buffer, size)) { ret = -EFAULT; goto out; } + pci_dma_sync_single(NULL, head->desc.pbuf, size, + PCI_DMA_TODEVICE); spin_lock_irqsave(&dac->lock, flags); - - dac->head->info.desc.cntinfo = size | HPCDMA_XIE; - dac->head->info.cnt = size; - dma_cache_wback_inv((unsigned long) dac->head, - size + PAGE_SIZE - H2_BUFFER_SIZE); + head->desc.cntinfo = size | HPCDMA_XIE; + head->cnt = size; buffer += size; ret += size; count -= size; - dac->head = dac->head->info.next; + hal2_inc_head(dac); + head = &dac->desc[dac->head]; DEBUG("(%d) ", size); } if (!(dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && ret > 0) hal2_start_dac(hal2); - spin_unlock_irqrestore(&dac->lock, flags); out: DEBUG("\n"); @@ -660,19 +715,17 @@ #define hal2_reset_adc_pointer(hal2) hal2_reset_pointer(hal2, 0) static void hal2_reset_pointer(struct hal2_card *hal2, int is_dac) { + int i; struct hal2_codec *codec = (is_dac) ? &hal2->dac : &hal2->adc; DEBUG("hal2_reset_pointer\n"); - codec->tail = codec->head; - do { - codec->tail->info.desc.cntinfo = HPCDMA_XIE | (is_dac) ? - HPCDMA_EOX : H2_BUFFER_SIZE; - codec->tail->info.cnt = 0; - dma_cache_wback_inv((unsigned long) codec->tail, - sizeof(struct hpc_dma_desc)); - codec->tail = codec->tail->info.next; - } while (codec->tail != codec->head); + for (i = 0; i < codec->desc_count; i++) { + codec->desc[i].cnt = 0; + codec->desc[i].desc.cntinfo = HPCDMA_XIE | (is_dac) ? + HPCDMA_EOX : H2_BLOCK_SIZE; + } + codec->head = codec->tail = 0; } static int hal2_sync_dac(struct hal2_card *hal2) @@ -680,21 +733,18 @@ DECLARE_WAITQUEUE(wait, current); struct hal2_codec *dac = &hal2->dac; int ret = 0; - signed long timeout = 1000 * H2_BUFFER_SIZE * 2 * dac->voices * + unsigned long flags; + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * dac->voices * HZ / dac->sample_rate / 900; - down(&dac->sem); - while (dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) { add_wait_queue(&dac->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system is - * heavily loaded */ - if (dac->tail->info.cnt) { - printk(KERN_NOTICE "HAL2: timeout...\n"); - ret = -ETIME; - } + schedule_timeout(timeout); + spin_lock_irqsave(&dac->lock, flags); + if (dac->desc[dac->tail].cnt) + ret = -ETIME; + spin_unlock_irqrestore(&dac->lock, flags); if (signal_pending(current)) ret = -ERESTARTSYS; if (ret) { @@ -704,8 +754,6 @@ remove_wait_queue(&dac->dma_wait, &wait); } - up(&dac->sem); - return ret; } @@ -900,7 +948,7 @@ static int hal2_open_mixdev(struct inode *inode, struct file *file) { - struct hal2_card *hal2 = hal2_mixer_find_card(MINOR(inode->i_rdev)); + struct hal2_card *hal2 = hal2_mixer_find_card(minor(inode->i_rdev)); if (hal2) { file->private_data = hal2; @@ -1038,52 +1086,45 @@ return 0; case SNDCTL_DSP_GETOSPACE: { - unsigned long flags; audio_buf_info info; - struct hal2_buf *buf; + int i; + unsigned long flags; struct hal2_codec *dac = &hal2->dac; if (!(file->f_mode & FMODE_WRITE)) return -EINVAL; - - spin_lock_irqsave(&dac->lock, flags); info.fragments = 0; - buf = dac->head; - while (buf->info.cnt == 0 && buf != dac->tail) { - info.fragments++; - buf = buf->info.next; - } + spin_lock_irqsave(&dac->lock, flags); + for (i = 0; i < dac->desc_count; i++) + if (dac->desc[i].cnt == 0) + info.fragments++; spin_unlock_irqrestore(&dac->lock, flags); - - info.fragstotal = obufs; - info.fragsize = H2_BUFFER_SIZE; + info.fragstotal = dac->desc_count; + info.fragsize = H2_BLOCK_SIZE; info.bytes = info.fragsize * info.fragments; return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; } case SNDCTL_DSP_GETISPACE: { - unsigned long flags; audio_buf_info info; - struct hal2_buf *buf; + int i; + unsigned long flags; struct hal2_codec *adc = &hal2->adc; if (!(file->f_mode & FMODE_READ)) return -EINVAL; - - spin_lock_irqsave(&adc->lock, flags); info.fragments = 0; info.bytes = 0; - buf = adc->tail; - while (buf->info.cnt > 0 && buf != adc->head) { - info.fragments++; - info.bytes += buf->info.cnt; - buf = buf->info.next; - } + spin_lock_irqsave(&adc->lock, flags); + for (i = 0; i < adc->desc_count; i++) + if (adc->desc[i].cnt > 0) { + info.fragments++; + info.bytes += adc->desc[i].cnt; + } spin_unlock_irqrestore(&adc->lock, flags); - - info.fragstotal = ibufs; - info.fragsize = H2_BUFFER_SIZE; + info.fragstotal = adc->desc_count; + info.fragsize = H2_BLOCK_SIZE; return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; } @@ -1093,7 +1134,7 @@ return 0; case SNDCTL_DSP_GETBLKSIZE: - return put_user(H2_BUFFER_SIZE, (int *)arg); + return put_user(H2_BLOCK_SIZE, (int *)arg); case SNDCTL_DSP_SETFRAGMENT: return 0; @@ -1115,8 +1156,7 @@ return put_user(val, (int *)arg); case SOUND_PCM_READ_BITS: - val = 16; - return put_user(val, (int *)arg); + return put_user(16, (int *)arg); } return hal2_mixer_ioctl(hal2, cmd, arg); @@ -1129,21 +1169,21 @@ struct hal2_card *hal2 = (struct hal2_card *) file->private_data; struct hal2_codec *adc = &hal2->adc; - if (count == 0) + if (!count) return 0; if (ppos != &file->f_pos) return -ESPIPE; - - down(&adc->sem); - + if (down_interruptible(&adc->sem)) + return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_get_buffer(hal2, buffer, count); err = err == 0 ? -EAGAIN : err; } else { do { /* ~10% longer */ - signed long timeout = 1000 * H2_BUFFER_SIZE * + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * adc->voices * HZ / adc->sample_rate / 900; + unsigned long flags; DECLARE_WAITQUEUE(wait, current); ssize_t cnt = 0; @@ -1157,26 +1197,21 @@ if (count > 0 && err >= 0) { add_wait_queue(&adc->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - /* Well, it is possible, that interrupt already - * arrived. Hmm, shit happens, we have one more - * buffer filled ;) */ - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system - * is heavily loaded */ - if (!adc->tail->info.cnt) { - printk(KERN_NOTICE - "HAL2: timeout...\n"); - hal2_stop_adc(hal2); - hal2_reset_adc_pointer(hal2); - err = -EAGAIN; - } + schedule_timeout(timeout); + spin_lock_irqsave(&adc->lock, flags); + if (!adc->desc[adc->tail].cnt) + err = -EAGAIN; + spin_unlock_irqrestore(&adc->lock, flags); if (signal_pending(current)) err = -ERESTARTSYS; remove_wait_queue(&adc->dma_wait, &wait); + if (err < 0) { + hal2_stop_adc(hal2); + hal2_reset_adc_pointer(hal2); + } } } while (count > 0 && err >= 0); } - up(&adc->sem); return err; @@ -1190,21 +1225,21 @@ struct hal2_card *hal2 = (struct hal2_card *) file->private_data; struct hal2_codec *dac = &hal2->dac; - if (count == 0) + if (!count) return 0; if (ppos != &file->f_pos) return -ESPIPE; - - down(&dac->sem); - + if (down_interruptible(&dac->sem)) + return -EINTR; if (file->f_flags & O_NONBLOCK) { err = hal2_add_buffer(hal2, buf, count); err = err == 0 ? -EAGAIN : err; } else { do { /* ~10% longer */ - signed long timeout = 1000 * H2_BUFFER_SIZE * + signed long timeout = 1000 * H2_BLOCK_SIZE * 2 * dac->voices * HZ / dac->sample_rate / 900; + unsigned long flags; DECLARE_WAITQUEUE(wait, current); ssize_t cnt = 0; @@ -1218,26 +1253,21 @@ if (count > 0 && err >= 0) { add_wait_queue(&dac->dma_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - /* Well, it is possible, that interrupt already - * arrived. Hmm, shit happens, we have one more - * buffer free ;) */ - if (!schedule_timeout(timeout)) - /* We may get bogus timeout when system - * is heavily loaded */ - if (dac->head->info.cnt) { - printk(KERN_NOTICE - "HAL2: timeout...\n"); - hal2_stop_dac(hal2); - hal2_reset_dac_pointer(hal2); - err = -EAGAIN; - } + schedule_timeout(timeout); + spin_lock_irqsave(&dac->lock, flags); + if (dac->desc[dac->head].cnt) + err = -EAGAIN; + spin_unlock_irqrestore(&dac->lock, flags); if (signal_pending(current)) err = -ERESTARTSYS; remove_wait_queue(&dac->dma_wait, &wait); + if (err < 0) { + hal2_stop_dac(hal2); + hal2_reset_dac_pointer(hal2); + } } } while (count > 0 && err >= 0); } - up(&dac->sem); return err; @@ -1252,9 +1282,9 @@ if (file->f_mode & FMODE_READ) { struct hal2_codec *adc = &hal2->adc; - poll_wait(file, &hal2->adc.dma_wait, wait); + poll_wait(file, &adc->dma_wait, wait); spin_lock_irqsave(&adc->lock, flags); - if (adc->tail->info.cnt > 0) + if (adc->desc[adc->tail].cnt > 0) mask |= POLLIN; spin_unlock_irqrestore(&adc->lock, flags); } @@ -1264,7 +1294,7 @@ poll_wait(file, &dac->dma_wait, wait); spin_lock_irqsave(&dac->lock, flags); - if (dac->head->info.cnt == 0) + if (dac->desc[dac->head].cnt == 0) mask |= POLLOUT; spin_unlock_irqrestore(&dac->lock, flags); } @@ -1275,51 +1305,42 @@ static int hal2_open(struct inode *inode, struct file *file) { int err; - struct hal2_card *hal2 = hal2_dsp_find_card(MINOR(inode->i_rdev)); - - DEBUG("opening audio device.\n"); + struct hal2_card *hal2 = hal2_dsp_find_card(minor(inode->i_rdev)); if (!hal2) return -ENODEV; - file->private_data = hal2; - if (file->f_mode & FMODE_READ) { - if (hal2->adc.usecount) - return -EBUSY; + struct hal2_codec *adc = &hal2->adc; + if (adc->usecount) + return -EBUSY; /* OSS spec wanted us to use 8 bit, 8 kHz mono by default, * but HAL2 can't do 8bit audio */ - hal2->adc.format = AFMT_S16_BE; - hal2->adc.voices = 1; - hal2->adc.sample_rate = hal2_compute_rate(&hal2->adc, 8000); + adc->format = AFMT_S16_BE; + adc->voices = 1; + adc->sample_rate = hal2_compute_rate(adc, 8000); hal2_set_adc_rate(hal2); - - /* alloc DMA buffers */ - err = hal2_alloc_adc_dmabuf(hal2); + err = hal2_alloc_adc_dmabuf(adc); if (err) return err; hal2_setup_adc(hal2); - - hal2->adc.usecount++; + adc->usecount++; } - if (file->f_mode & FMODE_WRITE) { - if (hal2->dac.usecount) - return -EBUSY; + struct hal2_codec *dac = &hal2->dac; - hal2->dac.format = AFMT_S16_BE; - hal2->dac.voices = 1; - hal2->dac.sample_rate = hal2_compute_rate(&hal2->dac, 8000); + if (dac->usecount) + return -EBUSY; + dac->format = AFMT_S16_BE; + dac->voices = 1; + dac->sample_rate = hal2_compute_rate(dac, 8000); hal2_set_dac_rate(hal2); - - /* alloc DMA buffers */ - err = hal2_alloc_dac_dmabuf(hal2); + err = hal2_alloc_dac_dmabuf(dac); if (err) return err; hal2_setup_dac(hal2); - - hal2->dac.usecount++; + dac->usecount++; } return 0; @@ -1330,15 +1351,22 @@ struct hal2_card *hal2 = (struct hal2_card *) file->private_data; if (file->f_mode & FMODE_READ) { + struct hal2_codec *adc = &hal2->adc; + + down(&adc->sem); hal2_stop_adc(hal2); - hal2_free_adc_dmabuf(hal2); - hal2->adc.usecount--; + hal2_free_adc_dmabuf(adc); + adc->usecount--; + up(&adc->sem); } - if (file->f_mode & FMODE_WRITE) { + struct hal2_codec *dac = &hal2->dac; + + down(&dac->sem); hal2_sync_dac(hal2); - hal2_free_dac_dmabuf(hal2); - hal2->dac.usecount--; + hal2_free_dac_dmabuf(dac); + dac->usecount--; + up(&dac->sem); } return 0; @@ -1363,47 +1391,16 @@ .release = hal2_release_mixdev, }; -static int hal2_request_irq(struct hal2_card *hal2, int irq) -{ - unsigned long flags; - int ret = 0; - - save_and_cli(flags); - if (request_irq(irq, hal2_interrupt, SA_SHIRQ, hal2str, hal2)) { - printk(KERN_ERR "HAL2: Can't get irq %d\n", irq); - ret = -EAGAIN; - } - restore_flags(flags); - return ret; -} - -static int hal2_alloc_resources(struct hal2_card *hal2, struct hpc3_regs *hpc3) -{ - struct hal2_pbus *pbus; - - pbus = &hal2->dac.pbus; - pbus->pbusnr = 0; - pbus->pbus = &hpc3->pbdma[pbus->pbusnr]; - - pbus = &hal2->adc.pbus; - pbus->pbusnr = 1; - pbus->pbus = &hpc3->pbdma[pbus->pbusnr]; - - return hal2_request_irq(hal2, SGI_HPCDMA_IRQ); -} - -static void hal2_init_codec(struct hal2_codec *codec) +static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3, + int index) { + codec->pbus.pbusnr = index; + codec->pbus.pbus = &hpc3->pbdma[index]; init_waitqueue_head(&codec->dma_wait); init_MUTEX(&codec->sem); spin_lock_init(&codec->lock); } -static void hal2_free_resources(struct hal2_card *hal2) -{ - free_irq(SGI_HPCDMA_IRQ, hal2); -} - static int hal2_detect(struct hal2_card *hal2) { unsigned short board, major, minor; @@ -1411,16 +1408,12 @@ /* reset HAL2 */ hal2_isr_write(hal2, 0); - /* release reset */ hal2_isr_write(hal2, H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N); hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); - - if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) { - DEBUG("HAL2: no device detected, rev: 0x%04hx\n", rev); + if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) return -ENODEV; - } board = (rev & H2_REV_BOARD_M) >> 12; major = (rev & H2_REV_MAJOR_CHIP_M) >> 4; @@ -1449,27 +1442,11 @@ if (hal2_detect(hal2) < 0) { ret = -ENODEV; - goto fail1; - } - - hal2_init_codec(&hal2->dac); - hal2_init_codec(&hal2->adc); - - ret = hal2_alloc_resources(hal2, hpc3); - if (ret) - goto fail1; - - hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1); - if (hal2->dev_dsp < 0) { - ret = hal2->dev_dsp; - goto fail2; + goto free_card; } - hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1); - if (hal2->dev_mixer < 0) { - ret = hal2->dev_mixer; - goto fail3; - } + hal2_init_codec(&hal2->dac, hpc3, 0); + hal2_init_codec(&hal2->adc, hpc3, 1); /* * All DMA channel interfaces in HAL2 are designed to operate with @@ -1497,15 +1474,34 @@ hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844; hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844; + if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, SA_SHIRQ, + hal2str, hal2)) { + printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ); + ret = -EAGAIN; + goto free_card; + } + + hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1); + if (hal2->dev_dsp < 0) { + ret = hal2->dev_dsp; + goto free_irq; + } + + hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1); + if (hal2->dev_mixer < 0) { + ret = hal2->dev_mixer; + goto unregister_dsp; + } + hal2_init_mixer(hal2); *phal2 = hal2; return 0; -fail3: +unregister_dsp: unregister_sound_dsp(hal2->dev_dsp); -fail2: - hal2_free_resources(hal2); -fail1: +free_irq: + free_irq(SGI_HPCDMA_IRQ, hal2); +free_card: kfree(hal2); return ret; @@ -1514,8 +1510,8 @@ extern void (*indy_volume_button)(int); /* - * We are assuming only one HAL2 card. If you ever meet machine with more than - * one, tell immediately about it to someone. Preferably to me. --ladis + * Assuming only one HAL2 card. Mail me if you ever meet machine with + * more than one. */ static int __init init_hal2(void) { @@ -1524,17 +1520,6 @@ for (i = 0; i < MAXCARDS; i++) hal2_card[i] = NULL; - /* adjust input and output buffer count to some reasonable value */ - if (ibufs < 2) - ibufs = 2; - else if (ibufs > 16) - ibufs = 16; - - if (obufs < 2) - obufs = 2; - else if (obufs > 64) - obufs = 64; - error = hal2_init_card(&hal2_card[0], hpc3c0); /* let Indy's volume buttons work */ @@ -1554,7 +1539,7 @@ for (i = 0; i < MAXCARDS; i++) if (hal2_card[i]) { - hal2_free_resources(hal2_card[i]); + free_irq(SGI_HPCDMA_IRQ, hal2_card[i]); unregister_sound_dsp(hal2_card[i]->dev_dsp); unregister_sound_mixer(hal2_card[i]->dev_mixer); kfree(hal2_card[i]); @@ -1564,31 +1549,6 @@ module_init(init_hal2); module_exit(exit_hal2); -#ifndef MODULE -static int __init setup_hal2(char *str) -{ - /* enable main mixer control, input buffers, output buffers */ - int ints[3]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - msmix = ints[1]; - ibufs = ints[2]; - obufs = ints[3]; - - return 1; -} - -__setup("hal2=", setup_hal2); -#endif - -MODULE_PARM(msmix, "i"); -MODULE_PARM(ibufs, "i"); -MODULE_PARM(obufs, "i"); -MODULE_PARM_DESC(msmix, "Enables master volume mixer"); -MODULE_PARM_DESC(ibufs, "Number of (page sized) input buffers"); -MODULE_PARM_DESC(obufs, "Number of (page sized) output buffers"); - MODULE_DESCRIPTION("OSS compatible driver for SGI HAL2 audio"); MODULE_AUTHOR("Ladislav Michl"); MODULE_LICENSE("GPL"); diff -urN linux-2.4.24/drivers/sound/hal2.h linux-2.4.25/drivers/sound/hal2.h --- linux-2.4.24/drivers/sound/hal2.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/sound/hal2.h 2004-02-18 05:36:31.000000000 -0800 @@ -203,26 +203,19 @@ struct hal2_ctl_regs { u32 _unused0[4]; - u16 _isr; - volatile u16 isr; /* 0x10 Status Register */ + volatile u32 isr; /* 0x10 Status Register */ u32 _unused1[3]; - u16 _rev; - volatile u16 rev; /* 0x20 Revision Register */ + volatile u32 rev; /* 0x20 Revision Register */ u32 _unused2[3]; - u16 _iar; - volatile u16 iar; /* 0x30 Indirect Address Register */ + volatile u32 iar; /* 0x30 Indirect Address Register */ u32 _unused3[3]; - u16 _idr0; - volatile u16 idr0; /* 0x40 Indirect Data Register 0 */ + volatile u32 idr0; /* 0x40 Indirect Data Register 0 */ u32 _unused4[3]; - u16 _idr1; - volatile u16 idr1; /* 0x50 Indirect Data Register 1 */ + volatile u32 idr1; /* 0x50 Indirect Data Register 1 */ u32 _unused5[3]; - u16 _idr2; - volatile u16 idr2; /* 0x60 Indirect Data Register 2 */ + volatile u32 idr2; /* 0x60 Indirect Data Register 2 */ u32 _unused6[3]; - u16 _idr3; - volatile u16 idr3; /* 0x70 Indirect Data Register 3 */ + volatile u32 idr3; /* 0x70 Indirect Data Register 3 */ }; struct hal2_aes_regs { @@ -252,68 +245,4 @@ volatile u32 dram; /* DRAM Access */ }; -/* driver specific structures */ - -struct hal2_pbus { - struct hpc3_pbus_dmacregs *pbus; - int pbusnr; - unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */ -}; - -struct hal2_buf; -struct hal2_binfo { - volatile struct hpc_dma_desc desc; - struct hal2_buf *next; /* pointer to next buffer */ - int cnt; /* bytes in buffer */ -}; -#define H2_BUFFER_SIZE (PAGE_SIZE - \ - ((sizeof(struct hal2_binfo) - 1) / 8 + 1) * 8) -struct hal2_buf { - struct hal2_binfo info; - u8 data[H2_BUFFER_SIZE] __attribute__((aligned(8))); -}; - -struct hal2_codec { - struct hal2_buf *head; - struct hal2_buf *tail; - struct hal2_pbus pbus; - unsigned int format; /* Audio data format */ - int voices; /* mono/stereo */ - unsigned int sample_rate; - unsigned int master; /* Master frequency */ - unsigned short mod; /* MOD value */ - unsigned short inc; /* INC value */ - - wait_queue_head_t dma_wait; - spinlock_t lock; - struct semaphore sem; - - int usecount; /* recording and playback are - * independent */ -}; - -#define H2_MIX_OUTPUT_ATT 0 -#define H2_MIX_INPUT_GAIN 1 -#define H2_MIXERS 2 -struct hal2_mixer { - int modcnt; - unsigned int master; - unsigned int volume[H2_MIXERS]; -}; - -struct hal2_card { - int dev_dsp; /* audio device */ - int dev_mixer; /* mixer device */ - int dev_midi; /* midi device */ - - struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */ - struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */ - struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */ - struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */ - - struct hal2_codec dac; - struct hal2_codec adc; - struct hal2_mixer mixer; -}; - #endif /* __HAL2_H */ diff -urN linux-2.4.24/drivers/sound/nec_vrc5477.c linux-2.4.25/drivers/sound/nec_vrc5477.c --- linux-2.4.24/drivers/sound/nec_vrc5477.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/sound/nec_vrc5477.c 2004-02-18 05:36:31.000000000 -0800 @@ -1965,7 +1965,7 @@ return -1; } -static void __devinit vrc5477_ac97_remove(struct pci_dev *dev) +static void __devexit vrc5477_ac97_remove(struct pci_dev *dev) { struct vrc5477_ac97_state *s = pci_get_drvdata(dev); @@ -2001,7 +2001,7 @@ name: VRC5477_AC97_MODULE_NAME, id_table: id_table, probe: vrc5477_ac97_probe, - remove: vrc5477_ac97_remove + remove: __devexit_p(vrc5477_ac97_remove) }; static int __init init_vrc5477_ac97(void) diff -urN linux-2.4.24/drivers/sound/ymfpci.c linux-2.4.25/drivers/sound/ymfpci.c --- linux-2.4.24/drivers/sound/ymfpci.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/sound/ymfpci.c 2004-02-18 05:36:31.000000000 -0800 @@ -152,22 +152,19 @@ writel(val, codec->reg_area_virt + offset); } -static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched) +static int ymfpci_codec_ready(ymfpci_t *unit, int secondary) { - signed long end_time; + enum { READY_STEP = 10 }; u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; + int i; - end_time = jiffies + 3 * (HZ / 4); - do { - if ((ymfpci_readw(codec, reg) & 0x8000) == 0) + for (i = 0; i < ((3*1000)/4) / READY_STEP; i++) { + if ((ymfpci_readw(unit, reg) & 0x8000) == 0) return 0; - if (sched) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } - } while (end_time - (signed long)jiffies >= 0); + mdelay(READY_STEP); + } printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n", - secondary, ymfpci_readw(codec, reg)); + secondary, ymfpci_readw(unit, reg)); return -EBUSY; } @@ -178,38 +175,35 @@ spin_lock(&codec->ac97_lock); /* XXX Do make use of dev->id */ - ymfpci_codec_ready(codec, 0, 0); + ymfpci_codec_ready(codec, 0); cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val; ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd); spin_unlock(&codec->ac97_lock); } -static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg) +static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg) { + ymfpci_t *unit = dev->private_data; + u16 ret; int i; - if (ymfpci_codec_ready(unit, 0, 0)) - return ~0; + spin_lock(&unit->ac97_lock); + if (ymfpci_codec_ready(unit, 0)) + goto out_err; ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg); - if (ymfpci_codec_ready(unit, 0, 0)) - return ~0; + if (ymfpci_codec_ready(unit, 0)) + goto out_err; if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) { for (i = 0; i < 600; i++) ymfpci_readw(unit, YDSXGR_PRISTATUSDATA); } - return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA); -} - -static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg) -{ - ymfpci_t *unit = dev->private_data; - u16 ret; - - spin_lock(&unit->ac97_lock); - ret = _ymfpci_codec_read(unit, reg); + ret = ymfpci_readw(unit, YDSXGR_PRISTATUSDATA); spin_unlock(&unit->ac97_lock); - return ret; + + out_err: + spin_unlock(&unit->ac97_lock); + return ~0; } /* @@ -2123,7 +2117,7 @@ int i; ymfpci_aclink_reset(unit->pci); - ymfpci_codec_ready(unit, 0, 1); /* prints diag if not ready. */ + ymfpci_codec_ready(unit, 0); /* prints diag if not ready. */ #ifdef CONFIG_SOUND_YMFPCI_LEGACY /* XXX At this time the legacy registers are probably deprogrammed. */ @@ -2549,7 +2543,7 @@ (char *)ent->driver_data, base, pcidev->irq); ymfpci_aclink_reset(pcidev); - if (ymfpci_codec_ready(codec, 0, 1) < 0) + if (ymfpci_codec_ready(codec, 0) < 0) goto out_unmap; #ifdef CONFIG_SOUND_YMFPCI_LEGACY @@ -2625,6 +2619,7 @@ out_release_region: release_mem_region(pci_resource_start(pcidev, 0), 0x8000); out_free: + kfree(codec); return -ENODEV; } @@ -2652,6 +2647,7 @@ unload_uart401(&codec->mpu_data); } #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ + kfree(codec); } MODULE_AUTHOR("Jaroslav Kysela"); diff -urN linux-2.4.24/drivers/tc/lk201.c linux-2.4.25/drivers/tc/lk201.c --- linux-2.4.24/drivers/tc/lk201.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/tc/lk201.c 2004-02-18 05:36:31.000000000 -0800 @@ -316,7 +316,7 @@ static int prev_scancode; unsigned char c = scancodeRemap[ch]; - if (stat && stat != 4) { + if (stat && stat != TTY_OVERRUN) { printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", stat); return; diff -urN linux-2.4.24/drivers/tc/zs.c linux-2.4.25/drivers/tc/zs.c --- linux-2.4.24/drivers/tc/zs.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/tc/zs.c 2004-02-18 05:36:31.000000000 -0800 @@ -6,7 +6,7 @@ * * DECstation changes * Copyright (C) 1998-2000 Harald Koerfgen - * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003, 2004 Maciej W. Rozycki * * For the rest of the code the original Copyright applies: * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) @@ -166,19 +166,19 @@ #endif static unsigned char zs_init_regs[16] __initdata = { - 0, /* write 0 */ - 0, /* write 1 */ - 0xf0, /* write 2 */ - (Rx8), /* write 3 */ - (X16CLK | SB1), /* write 4 */ - (Tx8), /* write 5 */ - 0, 0, 0, /* write 6, 7, 8 */ - (VIS), /* write 9 */ - (NRZ), /* write 10 */ - (TCBR | RCBR), /* write 11 */ - 0, 0, /* BRG time constant, write 12 + 13 */ - (BRSRC | BRENABL), /* write 14 */ - 0 /* write 15 */ + 0, /* write 0 */ + 0, /* write 1 */ + 0, /* write 2 */ + 0, /* write 3 */ + (X16CLK), /* write 4 */ + 0, /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (MIE | DLC | NV), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRSRC | BRENABL), /* write 14 */ + 0 /* write 15 */ }; DECLARE_TASK_QUEUE(tq_zs_serial); @@ -317,9 +317,9 @@ /* ZS_CLEARERR(channel); ZS_CLEARFIFO(channel); */ /* Load 'em up */ - write_zsreg(channel, R4, regs[R4]); write_zsreg(channel, R3, regs[R3] & ~RxENABLE); write_zsreg(channel, R5, regs[R5] & ~TxENAB); + write_zsreg(channel, R4, regs[R4]); write_zsreg(channel, R9, regs[R9]); write_zsreg(channel, R1, regs[R1]); write_zsreg(channel, R2, regs[R2]); @@ -730,8 +730,13 @@ /* * Clear the interrupt registers. */ - write_zsreg(info->zs_channel, 0, ERR_RES); - write_zsreg(info->zs_channel, 0, RES_H_IUS); + write_zsreg(info->zs_channel, R0, ERR_RES); + write_zsreg(info->zs_channel, R0, RES_H_IUS); + + /* + * Set the speed of the serial port + */ + change_speed(info); /* * Turn on RTS and DTR. @@ -741,35 +746,30 @@ /* * Finally, enable sequencing and interrupts */ - info->zs_channel->curregs[1] = (info->zs_channel->curregs[1] & ~0x18) | (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB); - info->zs_channel->curregs[3] |= (RxENABLE | Rx8); - info->zs_channel->curregs[5] |= (TxENAB | Tx8); - info->zs_channel->curregs[15] |= (DCDIE | CTSIE | TxUIE | BRKIE); - info->zs_channel->curregs[9] |= (VIS | MIE); - write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]); - write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); - write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); - write_zsreg(info->zs_channel, 15, info->zs_channel->curregs[15]); - write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]); + info->zs_channel->curregs[R1] &= ~RxINT_MASK; + info->zs_channel->curregs[R1] |= (RxINT_ALL | TxINT_ENAB | + EXT_INT_ENAB); + info->zs_channel->curregs[R3] |= RxENABLE; + info->zs_channel->curregs[R5] |= TxENAB; + info->zs_channel->curregs[R15] |= (DCDIE | CTSIE | TxUIE | BRKIE); + write_zsreg(info->zs_channel, R1, info->zs_channel->curregs[R1]); + write_zsreg(info->zs_channel, R3, info->zs_channel->curregs[R3]); + write_zsreg(info->zs_channel, R5, info->zs_channel->curregs[R5]); + write_zsreg(info->zs_channel, R15, info->zs_channel->curregs[R15]); /* * And clear the interrupt registers again for luck. */ - write_zsreg(info->zs_channel, 0, ERR_RES); - write_zsreg(info->zs_channel, 0, RES_H_IUS); + write_zsreg(info->zs_channel, R0, ERR_RES); + write_zsreg(info->zs_channel, R0, RES_H_IUS); + + /* Save the current value of RR0 */ + info->read_reg_zero = read_zsreg(info->zs_channel, R0); if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - /* - * Set the speed of the serial port - */ - change_speed(info); - - /* Save the current value of RR0 */ - info->read_reg_zero = read_zsreg(info->zs_channel, 0); - info->flags |= ZILOG_INITIALIZED; restore_flags(flags); return 0; @@ -852,9 +852,7 @@ save_flags(flags); cli(); info->zs_baud = baud_table[i]; - info->clk_divisor = 16; if (info->zs_baud) { - info->zs_channel->curregs[4] = X16CLK; brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor); info->zs_channel->curregs[12] = (brg & 255); info->zs_channel->curregs[13] = ((brg >> 8) & 255); @@ -1723,7 +1721,7 @@ static void __init show_serial_version(void) { - printk("DECstation Z8530 serial driver version 0.07\n"); + printk("DECstation Z8530 serial driver version 0.08\n"); } /* Initialize Z8530s zs_channels @@ -1733,6 +1731,7 @@ { struct dec_serial **pp; int i, n, n_chips = 0, n_channels, chip, channel; + unsigned long flags; /* * did we get here by accident? @@ -1852,23 +1851,23 @@ } } -/* save_and_cli(flags); + save_and_cli(flags); for (n = 0; n < zs_channels_found; n++) { - if (((int)zs_channels[n].control & 0xf) == 1) { + if (n % 2 == 0) { write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES); - mdelay(10); + udelay(10); write_zsreg(zs_soft[n].zs_chan_a, R9, 0); } - load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs); + load_zsregs(zs_soft[n].zs_channel, + zs_soft[n].zs_channel->curregs); } - restore_flags(flags); */ + restore_flags(flags); } /* zs_init inits the driver */ int __init zs_init(void) { int channel, i; - unsigned long flags; struct dec_serial *info; if(!BUS_PRESENT) @@ -1949,8 +1948,10 @@ info->tty = 0; info->x_char = 0; - if (info->hook && info->hook->init_info) + if (info->hook && info->hook->init_info) { + (*info->hook->init_info)(info); continue; + } info->magic = SERIAL_MAGIC; info->port = (int) info->zs_channel->control; @@ -1985,15 +1986,12 @@ printk(KERN_ERR "decserial: can't get irq %d\n", zs_soft[channel].irq); - if (zs_soft[channel].hook && - zs_soft[channel].hook->init_channel) - (*zs_soft[channel].hook->init_channel) - (&zs_soft[channel]); - } - - for (info = zs_chain, i = 0; info; info = info->zs_next, i++) { - if (info->hook && info->hook->init_info) - (*info->hook->init_info)(info); + if (zs_soft[channel].hook) { + zs_startup(&zs_soft[channel]); + if (zs_soft[channel].hook->init_channel) + (*zs_soft[channel].hook->init_channel) + (&zs_soft[channel]); + } } return 0; @@ -2056,16 +2054,9 @@ return 0; } else { - info->hook = hook; - - if (zs_chain == 0) - probe_sccs(); - - if (!(info->flags & ZILOG_INITIALIZED)) - zs_startup(info); - hook->poll_rx_char = zs_poll_rx_char; hook->poll_tx_char = zs_poll_tx_char; + info->hook = hook; return 1; } @@ -2126,11 +2117,13 @@ static int __init serial_console_setup(struct console *co, char *options) { struct dec_serial *info; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - char *s; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int clk_divisor = 16; + int brg; + char *s; unsigned long flags; if(!BUS_PRESENT) @@ -2182,6 +2175,10 @@ case 9600: default: cflag |= B9600; + /* + * Set this to a sane value to prevent a divide error. + */ + baud = 9600; break; } switch(bits) { @@ -2202,43 +2199,64 @@ break; } co->cflag = cflag; -#if 1 + save_and_cli(flags); /* + * Set up the baud rate generator. + */ + brg = BPS_TO_BRG(baud, zs_parms->clock / clk_divisor); + info->zs_channel->curregs[R12] = (brg & 255); + info->zs_channel->curregs[R13] = ((brg >> 8) & 255); + + /* + * Set byte size and parity. + */ + if (bits == 7) { + info->zs_channel->curregs[R3] |= Rx7; + info->zs_channel->curregs[R5] |= Tx7; + } else { + info->zs_channel->curregs[R3] |= Rx8; + info->zs_channel->curregs[R5] |= Tx8; + } + if (cflag & PARENB) { + info->zs_channel->curregs[R4] |= PAR_ENA; + } + if (!(cflag & PARODD)) { + info->zs_channel->curregs[R4] |= PAR_EVEN; + } + info->zs_channel->curregs[R4] |= SB1; + + /* * Turn on RTS and DTR. */ zs_rtsdtr(info, RTS | DTR, 1); /* - * Finally, enable sequencing + * Finally, enable sequencing. */ - info->zs_channel->curregs[3] |= (RxENABLE | Rx8); - info->zs_channel->curregs[5] |= (TxENAB | Tx8); - info->zs_channel->curregs[9] |= (VIS); - write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]); - write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]); - write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]); + info->zs_channel->curregs[R3] |= RxENABLE; + info->zs_channel->curregs[R5] |= TxENAB; /* * Clear the interrupt registers. */ - write_zsreg(info->zs_channel, 0, ERR_RES); - write_zsreg(info->zs_channel, 0, RES_H_IUS); + write_zsreg(info->zs_channel, R0, ERR_RES); + write_zsreg(info->zs_channel, R0, RES_H_IUS); /* - * Set the speed of the serial port + * Load up the new values. */ - change_speed(info); + load_zsregs(info->zs_channel, info->zs_channel->curregs); /* Save the current value of RR0 */ - info->read_reg_zero = read_zsreg(info->zs_channel, 0); + info->read_reg_zero = read_zsreg(info->zs_channel, R0); - zs_soft[co->index].clk_divisor = 16; + zs_soft[co->index].clk_divisor = clk_divisor; zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]); restore_flags(flags); -#endif + return 0; } @@ -2296,7 +2314,7 @@ int one, nine; nine = read_zsreg(chan, 9); if (yes == 1) { - one = EXT_INT_ENAB|INT_ALL_Rx; + one = EXT_INT_ENAB|RxINT_ALL; nine |= MIE; printk("turning serial ints on\n"); } else { diff -urN linux-2.4.24/drivers/tc/zs.h linux-2.4.25/drivers/tc/zs.h --- linux-2.4.24/drivers/tc/zs.h 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/tc/zs.h 2004-02-18 05:36:31.000000000 -0800 @@ -223,8 +223,9 @@ #define RxINT_DISAB 0 /* Rx Int Disable */ #define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ -#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ -#define INT_ERR_Rx 0x18 /* Int on error only */ +#define RxINT_ALL 0x10 /* Int on all Rx Characters or error */ +#define RxINT_ERR 0x18 /* Int on error only */ +#define RxINT_MASK 0x18 #define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ #define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ diff -urN linux-2.4.24/drivers/usb/Config.in linux-2.4.25/drivers/usb/Config.in --- linux-2.4.24/drivers/usb/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -92,7 +92,6 @@ dep_tristate ' USB Realtek RTL8150 based ethernet device support (EXPERIMENTAL)' CONFIG_USB_RTL8150 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL dep_tristate ' USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL dep_tristate ' USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL - dep_tristate ' USB ASIX AX88172 based ethernet device support (EXPERIMENTAL)' CONFIG_USB_AX8817X $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL dep_tristate ' USB Communication Class Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL dep_tristate ' USB-to-USB Networking cables, Linux PDAs, ... (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL fi diff -urN linux-2.4.24/drivers/usb/Makefile linux-2.4.25/drivers/usb/Makefile --- linux-2.4.24/drivers/usb/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -110,7 +110,6 @@ obj-$(CONFIG_USB_RTL8150) += rtl8150.o obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o -obj-$(CONFIG_USB_AX8817X) += ax8817x.o obj-$(CONFIG_USB_CDCETHER) += CDCEther.o obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TIGL) += tiglusb.o diff -urN linux-2.4.24/drivers/usb/auermain.c linux-2.4.25/drivers/usb/auermain.c --- linux-2.4.24/drivers/usb/auermain.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/usb/auermain.c 2004-02-18 05:36:31.000000000 -0800 @@ -2,7 +2,7 @@ /* * auermain.c -- Auerswald PBX/System Telephone usb driver. * - * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de) + * Copyright (C) 2002-2004 Wolfgang Mües (wolfgang@iksw-muees.de) * * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl) * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you. @@ -55,7 +55,7 @@ /*-------------------------------------------------------------------*/ /* Version Information */ -#define DRIVER_VERSION "1.2.3" +#define DRIVER_VERSION "1.2.6" #define DRIVER_AUTHOR "Wolfgang Mües " #define DRIVER_DESC "Auerswald PBX/System Telephone usb driver" @@ -828,9 +828,10 @@ static struct usb_device_id auerswald_ids[] = { {USB_DEVICE(ID_AUERSWALD, 0x00C0)}, /* COMpact 2104 USB/DSL */ {USB_DEVICE(ID_AUERSWALD, 0x00DB)}, /* COMpact 4410/2206 USB */ - {USB_DEVICE(ID_AUERSWALD, 0x00DC)}, /* comming soon... */ - {USB_DEVICE(ID_AUERSWALD, 0x00F1)}, /* Comfort 2000 System Telephone */ - {USB_DEVICE(ID_AUERSWALD, 0x00F2)}, /* Comfort 1200 System Telephone */ + {USB_DEVICE(ID_AUERSWALD, 0x00DC)}, /* COMpact 4406 DSL */ + {USB_DEVICE(ID_AUERSWALD, 0x00DD)}, /* COMpact 2204 USB */ + {USB_DEVICE(ID_AUERSWALD, 0x00F1)}, /* COMfort 2000 System Telephone */ + {USB_DEVICE(ID_AUERSWALD, 0x00F2)}, /* COMfort 1200 System Telephone */ {} /* Terminating entry */ }; diff -urN linux-2.4.24/drivers/usb/ax8817x.c linux-2.4.25/drivers/usb/ax8817x.c --- linux-2.4.24/drivers/usb/ax8817x.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/ax8817x.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1291 +0,0 @@ -/* - * ASIX AX8817x USB 2.0 10/100/HomePNA Ethernet controller driver - * - * $Id: ax8817x.c,v 1.15 2003/06/15 18:45:21 dhollis Exp $ - * - * Copyright (c) 2002-2003 TiVo Inc. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * History - * - * 2003-06-28 - Dave Hollis 1.0.2 - * * Added support for Intellinet - * 2003-06-12 - Dave Hollis 1.0.1 - * * use usb_make_path for ethtool info - * * Use crc32.h for crc functions - * * Additional callback cases for other host ctrlrs - * * Force minimum default rcv buffers - * - * 2003-06-12 - Dave Hollis 1.0.0 - * * Backport removal of multiple tx_urb / lengthy - * start_xmit routines, etc. - * * ethtool driver name returns driver name, not - * long description - * - * 2003-06-05 - Dave Hollis 0.9.9 - * * Cleanup unnecessary #if 0 - * * Fix coding style to match kernel style - * - * 2003-05-31 - Dave Hollis 0.9.8 - * * Don't stop/start the queue in start_xmit - * * Swallow URB status upon hard removal - * * Cleanup remaining comments (kill // style) - * - * 2003-05-29 - Dave Hollis 0.9.7 - * * Set module owner - * * Follow-up on suggestions from David Brownell & - * Oliver Neukum which should help with robustness - * * Use ether_crc from stock kernel if available - * - * 2003-05-28 - Dave Hollis 0.9.6 - * * Added basic ethtool & mii support - * - * 2003-05-28 - Dave Hollis 0.9.5 - * * Workout devrequest change to usb_ctrlrequest structure - * * Replace FILL_BULK_URB macros to non-deprecated - * usb_fill_bulk_urb macros - * * Replace printks with equivalent macros - * * Use defines for module description, version, author to - * simplify future changes - * - * Known Issues - * usb-uhci.c: process_transfer: fixed toggle message to console - * Possible bug in usb-uhci or bug in this driver that - * makes it spit that out. Doesn't seem to have harmful - * effects. - * - * Todo - * Fix mii/ethtool output -*/ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Version Information */ -#define DRIVER_VERSION "v1.0.0" -#define DRIVER_AUTHOR "TiVo, Inc." -#define DRIVER_DESC "ASIX AX8817x USB Ethernet driver" - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); - - -#define AX_REQ_READ ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE ) -#define AX_REQ_WRITE ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE ) - -#define AX_CMD_SET_SW_MII 0x06 -#define AX_CMD_READ_MII_REG 0x07 -#define AX_CMD_WRITE_MII_REG 0x08 -#define AX_CMD_SET_HW_MII 0x0a -#define AX_CMD_WRITE_RX_CTL 0x10 -#define AX_CMD_WRITE_MULTI_FILTER 0x16 -#define AX_CMD_READ_NODE_ID 0x17 -#define AX_CMD_READ_PHY_ID 0x19 -#define AX_CMD_WRITE_MEDIUM_MODE 0x1b -#define AX_CMD_WRITE_GPIOS 0x1f - -#define AX_RX_MAX ETH_FRAME_LEN -#define AX_TIMEOUT_CMD ( HZ / 10 ) -#define AX_TIMEOUT_TX ( HZ * 2 ) -#define AX_MAX_MCAST 64 - -#define AX_DRV_STATE_INITIALIZING 0x00 -#define AX_DRV_STATE_RUNNING 0x01 -#define AX_DRV_STATE_EXITING 0x02 - -#define AX_PHY_STATE_INITIALIZING 0x00 -#define AX_PHY_STATE_NO_LINK 0x01 -#define AX_PHY_STATE_POLLING_1 0x02 -#define AX_PHY_STATE_POLLING_2 0x03 -#define AX_PHY_STATE_POLLING_3 0x04 -#define AX_PHY_STATE_POLLING_4 0x05 -#define AX_PHY_STATE_SETTING_MAC 0x06 -#define AX_PHY_STATE_LINK 0x07 -#define AX_PHY_STATE_ABORT_POLL 0x08 -#define AX_PHY_STATE_ABORTING 0x09 - -#define AX_MAX_PHY_RETRY 50 - -#define AX_RX_URBS_DEFAULT 2 - -static const char driver_name[] = "ax8817x"; -static int n_rx_urbs = AX_RX_URBS_DEFAULT; - -MODULE_PARM(n_rx_urbs, "i"); -MODULE_PARM_DESC(n_rx_urbs, - "Number of rx buffers to queue at once (def 2)"); - -struct ax8817x_info; -struct ax_cmd_req; -typedef int (*ax_cmd_callback_t) (struct ax8817x_info *, - struct ax_cmd_req *); - -struct ax_cmd_req { - struct list_head list; - ax_cmd_callback_t cmd_callback; - void *priv; - int status; - void *data; - int data_size; - int timeout; - struct usb_ctrlrequest devreq; -}; - -struct ax8817x_info { - struct usb_device *usb; - struct net_device *net; - struct urb **rx_urbs; - struct urb *tx_urb; - struct urb *int_urb; - u8 *int_buf; - struct urb *ctl_urb; - struct list_head ctl_queue; - spinlock_t ctl_lock; - atomic_t rx_refill_cnt; - int tx_head; - int tx_tail; - spinlock_t tx_lock; - struct net_device_stats stats; - struct ax_cmd_req phy_req; - u8 phy_id; - u8 phy_state; - u8 drv_state; -}; - - -const struct usb_device_id ax8817x_id_table[] __devinitdata = { - /* Linksys USB200M */ - {USB_DEVICE(0x077b, 0x2226), driver_info:0x00130103}, - /* Hawking UF200, TRENDnet TU2-ET100 */ - {USB_DEVICE(0x07b8, 0x420a), driver_info:0x001f1d1f}, - /* NETGEAR FA120 */ - {USB_DEVICE(0x0846, 0x1040), driver_info:0x00130103}, - /* D-Link DUB-E100 */ - {USB_DEVICE(0x2001, 0x1a00), driver_info:0x009f9d9f}, - /* Intellinet USB Ethernet*/ - {USB_DEVICE(0x0b95, 0x1720), driver_info:0x00130103}, - - {} -}; - -MODULE_DEVICE_TABLE(usb, ax8817x_id_table); - -static void ax_run_ctl_queue(struct ax8817x_info *, struct ax_cmd_req *, - int); -static void ax_rx_callback(struct urb *urb); - -static void ax_ctl_callback(struct urb *urb) -{ - struct ax8817x_info *ax_info = - (struct ax8817x_info *) urb->context; - - ax_run_ctl_queue(ax_info, NULL, - urb->status ? urb->status : urb->actual_length); -} - -/* - * Queue a new ctl request, or dequeue the first in the list -*/ -static void ax_run_ctl_queue(struct ax8817x_info *ax_info, - struct ax_cmd_req *req, int status) -{ - struct ax_cmd_req *next_req = NULL; - struct ax_cmd_req *last_req = NULL; - unsigned long flags; - - /* Need to lock around queue list manipulation */ - spin_lock_irqsave(&ax_info->ctl_lock, flags); - - if (req == NULL) { - last_req = - list_entry(ax_info->ctl_queue.next, struct ax_cmd_req, - list); - } else { - if (list_empty(&ax_info->ctl_queue)) { - next_req = req; - } - - req->status = -EINPROGRESS; - list_add_tail(&req->list, &ax_info->ctl_queue); - } - - while (1) { - if (last_req != NULL) { - /* dequeue completed entry */ - list_del(&last_req->list); - - last_req->status = status; - if (last_req->cmd_callback(ax_info, last_req)) { - /* requeue if told to do so */ - last_req->status = -EINPROGRESS; - list_add_tail(&last_req->list, - &ax_info->ctl_queue); - } - - if (list_empty(&ax_info->ctl_queue)) { - next_req = NULL; - } else { - next_req = - list_entry(ax_info->ctl_queue.next, - struct ax_cmd_req, list); - } - } - - spin_unlock_irqrestore(&ax_info->ctl_lock, flags); - - if (next_req == NULL) { - break; - } - - /* XXX: do something with timeout */ - usb_fill_control_urb(ax_info->ctl_urb, ax_info->usb, - next_req->devreq. - bRequestType & USB_DIR_IN ? - usb_rcvctrlpipe(ax_info->usb, - 0) : - usb_sndctrlpipe(ax_info->usb, 0), - (void *) &next_req->devreq, - next_req->data, next_req->data_size, - ax_ctl_callback, ax_info); - - status = usb_submit_urb(ax_info->ctl_urb); - if (status >= 0) { - break; - } - - last_req = next_req; - - spin_lock_irqsave(&ax_info->ctl_lock, flags); - } -} - -static int ax_sync_cmd_callback(struct ax8817x_info *unused, - struct ax_cmd_req *req) -{ - wait_queue_head_t *wq = (wait_queue_head_t *) req->priv; - - wake_up(wq); - - return 0; -} - -static int ax_async_cmd_callback(struct ax8817x_info *unused, - struct ax_cmd_req *req) -{ - if (req->status < 0) { - err("%s: Async command %d failed: %d\n", __FUNCTION__, - req->devreq.bRequest, req->status); - } - - /* Nothing else to do here, just need to free the request (and its - allocated data) */ - if (req->data != NULL) { - kfree(req->data); - } - kfree(req); - - return 0; -} - -/* - * This is mostly the same as usb_control_msg(), except that it is able - * to queue control messages -*/ -static int ax_control_msg(struct ax8817x_info *ax_info, u8 requesttype, - u8 request, u16 value, u16 index, void *data, - u16 size, int timeout) -{ - struct ax_cmd_req *req; - DECLARE_WAIT_QUEUE_HEAD(wq); - DECLARE_WAITQUEUE(wait, current); - int ret; - - req = kmalloc(sizeof(struct ax_cmd_req), GFP_KERNEL); - if (req == NULL) { - return -ENOMEM; - } - - req->devreq.bRequestType = requesttype; - req->devreq.bRequest = request; - req->devreq.wValue = cpu_to_le16(value); - req->devreq.wIndex = cpu_to_le16(index); - req->devreq.wLength = cpu_to_le16(size); - req->data = data; - req->data_size = size; - req->timeout = timeout; - - req->priv = &wq; - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&wq, &wait); - - req->cmd_callback = ax_sync_cmd_callback; - - ax_run_ctl_queue(ax_info, req, 0); - schedule(); - - ret = req->status; - - kfree(req); - - return ret; -} - -/* - * Same, but can be used asynchronously, may fail, and returns no exit - * status -*/ -static void ax_control_msg_async(struct ax8817x_info *ax_info, - u8 requesttype, u8 request, u16 value, - u16 index, void *data, u16 size, - int timeout) -{ - struct ax_cmd_req *req; - - req = kmalloc(sizeof(struct ax_cmd_req), GFP_ATOMIC); - if (req == NULL) { - /* There's not much else we can do here... */ - err("%s: Failed alloc\n", __FUNCTION__); - return; - } - - req->devreq.bRequestType = requesttype; - req->devreq.bRequest = request; - req->devreq.wValue = cpu_to_le16(value); - req->devreq.wIndex = cpu_to_le16(index); - req->devreq.wLength = cpu_to_le16(size); - req->data = data; - req->data_size = size; - req->timeout = timeout; - - req->cmd_callback = ax_async_cmd_callback; - - ax_run_ctl_queue(ax_info, req, 0); -} - -static inline int ax_read_cmd(struct ax8817x_info *ax_info, u8 cmd, - u16 value, u16 index, u16 size, void *data) -{ - return ax_control_msg(ax_info, AX_REQ_READ, cmd, value, index, - data, size, AX_TIMEOUT_CMD); -} - -static inline int ax_write_cmd(struct ax8817x_info *ax_info, u8 cmd, - u16 value, u16 index, u16 size, void *data) -{ - return ax_control_msg(ax_info, AX_REQ_WRITE, cmd, value, index, - data, size, AX_TIMEOUT_CMD); -} - -static inline void ax_write_cmd_async(struct ax8817x_info *ax_info, u8 cmd, - u16 value, u16 index, u16 size, - void *data) -{ - ax_control_msg_async(ax_info, AX_REQ_WRITE, cmd, value, index, - data, size, AX_TIMEOUT_CMD); -} - -static int ax_refill_rx_urb(struct ax8817x_info *ax_info, struct urb *urb) -{ - struct sk_buff *skb; - int ret; - - skb = dev_alloc_skb(AX_RX_MAX + 2); - if (skb != NULL) { - skb_reserve(skb, 2); /* for IP header alignment */ - skb->dev = ax_info->net; - - usb_fill_bulk_urb(urb, ax_info->usb, - usb_rcvbulkpipe(ax_info->usb, 3), - skb->data, AX_RX_MAX, ax_rx_callback, - skb); - - ret = usb_submit_urb(urb); - if (ret < 0) { - err("Failed submit rx URB (%d)\n", ret); - dev_kfree_skb_irq(skb); - urb->context = NULL; - } else { - ret = 0; - } - } else { - /* this just means we're low on memory at the moment. Try to - handle it gracefully. */ - urb->context = NULL; - ret = 1; - } - - return ret; -} - -static int ax_phy_cmd_callback(struct ax8817x_info *ax_info, - struct ax_cmd_req *req) -{ - int full_duplex; - int flow_control; - u16 mii_data_le; - - if (req->status < 0) { - err("%s: Failed at state %d: %d\n", __FUNCTION__, - ax_info->phy_state, req->status); - /* Not sure what else we can do, so just bail */ - ax_info->phy_state = AX_PHY_STATE_ABORTING; - } - - switch (ax_info->phy_state) { - /* Now that we're in software MII mode, read the BMSR */ - case AX_PHY_STATE_POLLING_1: - ax_info->phy_state = AX_PHY_STATE_POLLING_2; - req->devreq.bRequestType = AX_REQ_READ; - req->devreq.bRequest = AX_CMD_READ_MII_REG; - req->devreq.wValue = cpu_to_le16(ax_info->phy_id); - req->devreq.wIndex = cpu_to_le16(MII_BMSR); - req->devreq.wLength = cpu_to_le16(2); - req->data_size = 2; - (long) req->priv = 0; /* This is the retry count */ - return 1; - - /* Done reading BMSR */ - case AX_PHY_STATE_POLLING_2: - mii_data_le = *(u16 *) req->data; - if ((mii_data_le & - cpu_to_le16(BMSR_LSTATUS | BMSR_ANEGCAPABLE)) - == cpu_to_le16(BMSR_LSTATUS | BMSR_ANEGCAPABLE)) { - if (mii_data_le & cpu_to_le16(BMSR_ANEGCOMPLETE)) { - /* Autonegotiation done, go on to read LPA */ - ax_info->phy_state = - AX_PHY_STATE_POLLING_3; - req->devreq.wIndex = cpu_to_le16(MII_LPA); - return 1; - } else if ((long) req->priv++ < AX_MAX_PHY_RETRY) { - /* Reread BMSR if it's still autonegotiating. This is - probably unnecessary logic, I've never seen it take - more than 1 try... */ - return 1; - } - /* else fall through to abort */ - } - /* XXX: should probably handle auto-neg failure better, - by reverting to manual setting of something safe. (?) */ - - ax_info->phy_state = AX_PHY_STATE_ABORT_POLL; - /* and then fall through to set hw MII */ - - /* Got what we needed from PHY, set back to hardware MII mode - (Do same for abort in mid-poll) */ - case AX_PHY_STATE_POLLING_3: - case AX_PHY_STATE_ABORT_POLL: - ax_info->phy_state += 1; - req->devreq.bRequestType = AX_REQ_WRITE; - req->devreq.bRequest = AX_CMD_SET_HW_MII; - req->devreq.wValue = cpu_to_le16(0); - req->devreq.wIndex = cpu_to_le16(0); - req->devreq.wLength = cpu_to_le16(0); - req->data_size = 0; - return 1; - - /* The end result, set the right duplex and flow control mode in the - MAC (based on the PHY's LPA reg, which should still be in the data - buffer) */ - case AX_PHY_STATE_POLLING_4: - mii_data_le = *(u16 *) req->data; - ax_info->phy_state = AX_PHY_STATE_SETTING_MAC; - req->devreq.bRequest = AX_CMD_WRITE_MEDIUM_MODE; - full_duplex = mii_data_le & cpu_to_le16(LPA_DUPLEX); - flow_control = full_duplex && - (mii_data_le & cpu_to_le16(0x0400)); - req->devreq.wValue = cpu_to_le16(0x04) | - (full_duplex ? cpu_to_le16(0x02) : 0) | - (flow_control ? cpu_to_le16(0x10) : 0); - info("%s: Link established, %s duplex, flow control %sabled\n", ax_info->net->name, full_duplex ? "full" : "half", flow_control ? "en" : "dis"); - return 1; - - /* All done */ - case AX_PHY_STATE_SETTING_MAC: - ax_info->phy_state = AX_PHY_STATE_LINK; - netif_carrier_on(ax_info->net); - return 0; - - default: - err("%s: Unknown state %d\n", __FUNCTION__, - ax_info->phy_state); - /* fall through */ - case AX_PHY_STATE_ABORTING: - ax_info->phy_state = AX_PHY_STATE_NO_LINK; - return 0; - } -} - -static void ax_int_callback(struct urb *urb) -{ - struct ax8817x_info *ax_info = - (struct ax8817x_info *) urb->context; - u8 phy_link; - - if (ax_info->drv_state == AX_DRV_STATE_EXITING || - urb->actual_length < 3) { - return; - } - - /* Ignore the first PHY link report, it will sometimes be reported as - link active, even though we just told the PHY to reset. If it - really has link, we'll pick it up next int callback. - */ - if (ax_info->phy_state == AX_PHY_STATE_INITIALIZING) { - netif_carrier_off(ax_info->net); - ax_info->phy_state = AX_PHY_STATE_NO_LINK; - return; - } - - /* Assume we're only interested in the primary PHY for now. */ - phy_link = ax_info->int_buf[2] & 1; - - if (phy_link == - (ax_info->phy_state == AX_PHY_STATE_NO_LINK) ? 0 : 1) { - /* Common case, no change */ - return; - } - - if (phy_link == 0) { - netif_carrier_off(ax_info->net); - /* Abort an in-progress poll of the PHY if necessary */ - switch (ax_info->phy_state) { - case AX_PHY_STATE_POLLING_1: - case AX_PHY_STATE_POLLING_2: - case AX_PHY_STATE_POLLING_3: - ax_info->phy_state = AX_PHY_STATE_ABORT_POLL; - break; - - case AX_PHY_STATE_POLLING_4: - case AX_PHY_STATE_SETTING_MAC: - ax_info->phy_state = AX_PHY_STATE_ABORTING; - break; - - case AX_PHY_STATE_LINK: - ax_info->phy_state = AX_PHY_STATE_NO_LINK; - break; - - default: - /* If we're already aborting, continue aborting */ - break; - } - } else { - /* Note that we only fall into this case if previous phy_state was - AX_PHY_STATE_NO_LINK. When the link is reported active while - we're still polling, or when we're aborting, the logic above - will just return, and we'll check again next int callback. */ - - ax_info->phy_state = AX_PHY_STATE_POLLING_1; - ax_info->phy_req.devreq.bRequestType = AX_REQ_WRITE; - ax_info->phy_req.devreq.bRequest = AX_CMD_SET_SW_MII; - ax_info->phy_req.devreq.wValue = cpu_to_le16(0); - ax_info->phy_req.devreq.wIndex = cpu_to_le16(0); - ax_info->phy_req.devreq.wLength = cpu_to_le16(0); - ax_info->phy_req.data_size = 0; - ax_info->phy_req.timeout = AX_TIMEOUT_CMD; - ax_info->phy_req.cmd_callback = ax_phy_cmd_callback; - - ax_run_ctl_queue(ax_info, &ax_info->phy_req, 0); - } -} - -static void ax_rx_callback(struct urb *urb) -{ - struct sk_buff *skb = (struct sk_buff *) urb->context; - struct net_device *net = skb->dev; - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - int ret, len, refill; - - switch (urb->status) { - case 0: - break; - - default: - err("%s: URB status %d\n", __FUNCTION__, urb->status); - /* It's not clear that we can do much in this case, the rx pipe - doesn't ever seem to stall, so if we got -ETIMEDOUT, that - usually means the device was unplugged, and we just haven't - noticed yet. - Just fall through and free skb without resubmitting urb. */ - case -ENOENT: /* */ - case -ECONNRESET: /* Async unlink */ - case -ESHUTDOWN: /* Hardware gone */ - case -EILSEQ: /* Get this when you yank it out on UHCI */ - case -ETIMEDOUT: /* OHCI */ - case -EPROTO: /* EHCI */ - case -EPIPE: - dev_kfree_skb_any(skb); - urb->context = NULL; - return; - } - - if (ax_info->drv_state == AX_DRV_STATE_INITIALIZING) { - /* Not really expecting this to ever happen, since we haven't yet - enabled receive in the rx_ctl register, but ya never know... */ - goto refill_same; - } else if (ax_info->drv_state == AX_DRV_STATE_EXITING) { - dev_kfree_skb_any(skb); - urb->context = NULL; - return; - } - - len = urb->actual_length; - if (len == 0) { - /* this shouldn't happen... */ - goto refill_same; - } - - refill = ax_refill_rx_urb(ax_info, urb); - - if (refill == 0 - || atomic_read(&ax_info->rx_refill_cnt) < n_rx_urbs) { - /* Send the receive buffer up the network stack */ - skb_put(skb, len); - skb->protocol = eth_type_trans(skb, net); - net->last_rx = jiffies; - ax_info->stats.rx_packets++; - ax_info->stats.rx_bytes += len; - - netif_rx(skb); - - if (refill == 0) { - int i; - - /* This is the common case. This URB got refilled OK, and - no other URBs need to be refilled. */ - if (atomic_read(&ax_info->rx_refill_cnt) == 0) { - return; - } - - for (i = 0; i < n_rx_urbs; i++) { - struct urb *urb = ax_info->rx_urbs[i]; - - if (urb->context == NULL) { - if (ax_refill_rx_urb(ax_info, urb) - == 0) { - atomic_dec(&ax_info-> - rx_refill_cnt); - } else { - break; - } - } - } - } else { - /* remember to refill this one later */ - atomic_inc(&ax_info->rx_refill_cnt); - } - - return; - } else { - ax_info->stats.rx_dropped++; - if (refill < 0) { - /* the error code was already printk'ed in ax_refill_rx_urb() - so just note the consequences here: */ - warn("Halting rx due to error\n"); - return; - } - - /* fall through to resubmit this URB with the existing skb - will try to reallocate skb's on next rx callback */ - } - - refill_same: - usb_fill_bulk_urb(urb, ax_info->usb, - usb_rcvbulkpipe(ax_info->usb, 3), skb->data, - AX_RX_MAX, ax_rx_callback, skb); - - ret = usb_submit_urb(urb); - if (ret < 0) { - err("Failed submit rx URB (%d)\n", ret); - } -} - -static int ax8817x_open(struct net_device *net) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - u8 buf[4]; - int i, ret; - - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf); - if (ret < 0) { - return ret; - } - - ret = 0; - - ax_info->tx_urb = usb_alloc_urb(0); - if (ax_info->tx_urb == NULL) - ret = -ENOMEM; - - atomic_set(&ax_info->rx_refill_cnt, 0); - - for (i = 0; i < n_rx_urbs && ret == 0; i++) { - struct urb *urb = ax_info->rx_urbs[i]; - - if (urb == NULL) { - urb = ax_info->rx_urbs[i] = usb_alloc_urb(0); - if (urb == NULL) { - ret = -ENOMEM; - break; - } - if (n_rx_urbs > 1) { - urb->transfer_flags |= USB_QUEUE_BULK; - } - } - ret = ax_refill_rx_urb(ax_info, urb); - if (ret == 1) { - atomic_inc(&ax_info->rx_refill_cnt); - ret = 0; - } - } - - /* XXX: should handle the case where we couldn't allocate any skb's - better. They get allocated with GFP_ATOMIC, so they may all fail... */ - if (ret == 0 && atomic_read(&ax_info->rx_refill_cnt) < n_rx_urbs) { - netif_start_queue(net); - } else { - /* Error: clean up anything we allocated and bail. */ - usb_free_urb(ax_info->tx_urb); - - for (i = 0; i < n_rx_urbs; i++) { - struct urb *urb = ax_info->rx_urbs[i]; - - if (urb != NULL) { - /* skb gets freed in the URB callback */ - usb_unlink_urb(urb); - usb_free_urb(urb); - } - } - - err("%s: Failed start rx queue (%d)\n", __FUNCTION__, ret); - } - return ret; -} - -static int ax8817x_stop(struct net_device *net) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - u8 buf[4]; - int i, ret; - - netif_stop_queue(net); - - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf); - if (ret < 0 && ax_info->drv_state != AX_DRV_STATE_EXITING) { - err("%s: Failed cmd (%d)\n", __FUNCTION__, ret); - } - - if (ax_info->tx_urb != NULL) { - usb_unlink_urb(ax_info->tx_urb); - usb_free_urb(ax_info->tx_urb); - ax_info->tx_urb = NULL; - } - - for (i = 0; i < n_rx_urbs; i++) { - struct urb *urb = ax_info->rx_urbs[i]; - if (urb != NULL) { - /* skb gets freed in the URB callback */ - usb_unlink_urb(urb); - usb_free_urb(urb); - ax_info->rx_urbs[i] = NULL; - } - } - - return 0; -} - -static void write_bulk_callback(struct urb *urb) -{ - struct ax8817x_info *ax_info = urb->context; - - if (!ax_info || (ax_info->drv_state == AX_DRV_STATE_EXITING)) - return; - - if (!netif_device_present(ax_info->net)) - return; - - if (urb->status) - info("%s: TX status %d", ax_info->net->name, urb->status); - - ax_info->net->trans_start = jiffies; - netif_wake_queue(ax_info->net); -} - -static int ax8817x_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - struct ax8817x_info *ax_info = net->priv; - int res; - - netif_stop_queue(net); - - ax_info->tx_urb->transfer_flags |= USB_ZERO_PACKET; - usb_fill_bulk_urb(ax_info->tx_urb, ax_info->usb, - usb_sndbulkpipe(ax_info->usb, 2), - skb->data, skb->len, write_bulk_callback, - ax_info); - if ((res = usb_submit_urb(ax_info->tx_urb))) { - warn("Failed tx_urb %d", res); - ax_info->stats.tx_errors++; - netif_start_queue(net); - } else { - ax_info->stats.tx_packets++; - ax_info->stats.tx_bytes += skb->len; - net->trans_start = jiffies; - } - dev_kfree_skb(skb); - - return 0; -} - -static void ax8817x_tx_timeout(struct net_device *net) -{ - struct ax8817x_info *ax_info = net->priv; - - if (!ax_info) - return; - - warn("%s: Tx timed out.", net->name); - ax_info->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; - usb_unlink_urb(ax_info->tx_urb); - ax_info->stats.tx_errors++; -} - -static struct net_device_stats *ax8817x_stats(struct net_device *net) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - - return &ax_info->stats; -} - -static void ax8817x_set_multicast(struct net_device *net) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - u8 rx_ctl = 0x8c; - - if (net->flags & IFF_PROMISC) { - rx_ctl |= 0x01; - } else if (net->flags & IFF_ALLMULTI - || net->mc_count > AX_MAX_MCAST) { - rx_ctl |= 0x02; - } else if (net->mc_count == 0) { - /* just broadcast and directed */ - } else { - struct dev_mc_list *mc_list = net->mc_list; - u8 *multi_filter; - u32 crc_bits; - int i; - - multi_filter = kmalloc(8, GFP_ATOMIC); - if (multi_filter == NULL) { - /* Oops, couldn't allocate a DMA buffer for setting the multicast - filter. Try all multi mode, although the ax_write_cmd_async - will almost certainly fail, too... (but it will printk). */ - rx_ctl |= 0x02; - } else { - memset(multi_filter, 0, 8); - - /* Build the multicast hash filter. */ - for (i = 0; i < net->mc_count; i++) { - crc_bits = - ether_crc(ETH_ALEN, - mc_list->dmi_addr) >> 26; - multi_filter[crc_bits >> 3] |= - 1 << (crc_bits & 7); - mc_list = mc_list->next; - } - - ax_write_cmd_async(ax_info, - AX_CMD_WRITE_MULTI_FILTER, 0, 0, - 8, multi_filter); - - rx_ctl |= 0x10; - } - } - - ax_write_cmd_async(ax_info, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, - NULL); -} - -static int ax8817x_ethtool_ioctl(struct net_device *net, void *uaddr) -{ - struct ax8817x_info *ax_info; - int cmd; - - ax_info = net->priv; - if (get_user(cmd, (int *) uaddr)) - return -EFAULT; - - switch (cmd) { - case ETHTOOL_GDRVINFO:{ - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - - strncpy(info.driver, driver_name, - ETHTOOL_BUSINFO_LEN); - strncpy(info.version, DRIVER_VERSION, - ETHTOOL_BUSINFO_LEN); - usb_make_path(ax_info->usb, info.bus_info, - sizeof info.bus_info); - if (copy_to_user(uaddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - case ETHTOOL_GSET:{ - struct ethtool_cmd ecmd; - - if (copy_from_user(&ecmd, uaddr, sizeof(ecmd))) - return -EFAULT; - ecmd.supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_TP | SUPPORTED_MII); - ecmd.port = PORT_TP; - ecmd.transceiver = XCVR_INTERNAL; - ecmd.phy_address = 0; /* FIXME */ - - if (copy_to_user(uaddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - case ETHTOOL_SSET: - return -ENOTSUPP; - case ETHTOOL_GLINK:{ - struct ethtool_value edata = { ETHTOOL_GLINK }; - - edata.data = netif_carrier_ok(net); - if (copy_to_user(uaddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - default: - return -EOPNOTSUPP; - } -} - -static int ax8817x_mii_ioctl(struct net_device *net, struct ifreq *ifr, - int cmd) -{ - struct ax8817x_info *ax_info; - struct mii_ioctl_data *data_ptr = - (struct mii_ioctl_data *) &(ifr->ifr_data); - - ax_info = net->priv; - - switch (cmd) { - case SIOCGMIIPHY: - data_ptr->phy_id = ax_info->phy_id; - break; - case SIOCGMIIREG: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - ax_read_cmd(ax_info, AX_CMD_READ_MII_REG, 0, - data_ptr->reg_num & 0x1f, 2, - &(data_ptr->val_out)); - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int ax8817x_ioctl(struct net_device *net, struct ifreq *ifr, - int cmd) -{ - struct ax8817x_info *ax_info; - int res; - - ax_info = net->priv; - res = 0; - - switch (cmd) { - case SIOCETHTOOL: - res = ax8817x_ethtool_ioctl(net, ifr->ifr_data); - break; - case SIOCGMIIPHY: /* Get address of PHY in use */ - case SIOCGMIIREG: /* Read from MII PHY register */ - case SIOCSMIIREG: /* Write to MII PHY register */ - return ax8817x_mii_ioctl(net, ifr, cmd); - default: - res = -EOPNOTSUPP; - } - - return res; -} - -static int ax8817x_net_init(struct net_device *net) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv; - u8 buf[6]; - u16 *buf16 = (u16 *) buf; - int ret; - - spin_lock_init(&ax_info->tx_lock); - - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf); - if (ret < 0) { - return ret; - } - - memset(buf, 0, 6); - - /* Get the MAC address */ - ret = ax_read_cmd(ax_info, AX_CMD_READ_NODE_ID, 0, 0, 6, buf); - if (ret < 0) { - return ret; - } - - memcpy(net->dev_addr, buf, 6); - - /* Get the PHY id */ - ret = ax_read_cmd(ax_info, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); - if (ret < 0) { - return ret; - } else if (ret < 2) { - /* this should always return 2 bytes */ - return -EIO; - } - - /* Reset the PHY, and drop it into auto-negotiation mode */ - ax_info->phy_id = buf[1]; - ax_info->phy_state = AX_PHY_STATE_INITIALIZING; - - ret = ax_write_cmd(ax_info, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); - if (ret < 0) { - return ret; - } - - *buf16 = cpu_to_le16(BMCR_RESET); - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG, - ax_info->phy_id, MII_BMCR, 2, buf16); - if (ret < 0) { - return ret; - } - - /* Advertise that we can do full-duplex pause */ - *buf16 = cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400); - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG, - ax_info->phy_id, MII_ADVERTISE, 2, buf16); - if (ret < 0) { - return ret; - } - - *buf16 = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART); - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG, - ax_info->phy_id, MII_BMCR, 2, buf16); - if (ret < 0) { - return ret; - } - - ret = ax_write_cmd(ax_info, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); - if (ret < 0) { - return ret; - } - - net->open = ax8817x_open; - net->stop = ax8817x_stop; - net->hard_start_xmit = ax8817x_start_xmit; - net->tx_timeout = ax8817x_tx_timeout; - net->watchdog_timeo = AX_TIMEOUT_TX; - net->get_stats = ax8817x_stats; - net->do_ioctl = ax8817x_ioctl; - net->set_multicast_list = ax8817x_set_multicast; - - return 0; -} - -static void *ax8817x_bind(struct usb_device *usb, unsigned intf, - const struct usb_device_id *id) -{ - struct ax8817x_info *ax_info; - struct net_device *net; - int i, ret; - unsigned long gpio_bits = id->driver_info; - u8 buf[2]; - - /* Allocate the URB lists along with the device info struct */ - ax_info = kmalloc(sizeof(struct ax8817x_info) + - n_rx_urbs * sizeof(struct urb *), GFP_KERNEL); - if (ax_info == NULL) { - err("%s: Failed ax alloc\n", __FUNCTION__); - goto exit_err; - } - - memset(ax_info, 0, sizeof(struct ax8817x_info) + - n_rx_urbs * sizeof(struct urb *)); - - ax_info->drv_state = AX_DRV_STATE_INITIALIZING; - ax_info->rx_urbs = (struct urb **) (ax_info + 1); - ax_info->usb = usb; - - /* Set up the control URB queue */ - - INIT_LIST_HEAD(&ax_info->ctl_queue); - spin_lock_init(&ax_info->ctl_lock); - ax_info->ctl_urb = usb_alloc_urb(0); - if (ax_info->ctl_urb == NULL) { - goto exit_err_free_ax; - } - - /* Toggle the GPIOs in a manufacturer/model specific way */ - - for (i = 2; i >= 0; i--) { - ret = ax_write_cmd(ax_info, AX_CMD_WRITE_GPIOS, - (gpio_bits >> (i * 8)) & 0xff, 0, 0, - buf); - if (ret < 0) { - goto exit_err_free_ax; - } - wait_ms(5); - } - - /* Set up the net device */ - - net = alloc_etherdev(0); - if (net == NULL) { - err("%s: Failed net alloc\n", __FUNCTION__); - goto exit_err_free_ax; - } - - ax_info->net = net; - - SET_MODULE_OWNER(net); - net->init = ax8817x_net_init; - net->priv = ax_info; - - ret = register_netdev(net); - if (ret < 0) { - err("%s: Failed net init (%d)\n", __FUNCTION__, ret); - goto exit_err_free_net; - } - - /* Set up the interrupt URB, and start PHY state monitoring */ - - ax_info->int_urb = usb_alloc_urb(0); - if (ax_info->int_urb == NULL) { - goto exit_err_unregister_net; - } - ax_info->int_buf = kmalloc(8, GFP_KERNEL); - if (ax_info->int_buf == NULL) { - goto exit_err_free_int_urb; - } - ax_info->phy_req.data = kmalloc(2, GFP_KERNEL); - if (ax_info->phy_req.data == NULL) { - goto exit_err_free_int_buf; - } - - usb_fill_int_urb(ax_info->int_urb, usb, usb_rcvintpipe(usb, 1), - ax_info->int_buf, 8, ax_int_callback, ax_info, - 100); - - ret = usb_submit_urb(ax_info->int_urb); - if (ret < 0) { - err("%s: Failed int URB submit (%d)\n", __FUNCTION__, ret); - goto exit_err_free_phy_buf; - } - - ax_info->drv_state = AX_DRV_STATE_RUNNING; - return ax_info; - - exit_err_free_phy_buf: - kfree(ax_info->phy_req.data); - - exit_err_free_int_buf: - kfree(ax_info->int_buf); - - exit_err_free_int_urb: - usb_free_urb(ax_info->int_urb); - - exit_err_unregister_net: - ax_info->drv_state = AX_DRV_STATE_EXITING; - unregister_netdev(net); - - exit_err_free_net: - kfree(net); - - exit_err_free_ax: - if (ax_info->ctl_urb != NULL) { - /* no need to unlink, since there should not be any ctl URBs - pending at this point */ - usb_free_urb(ax_info->ctl_urb); - } - - kfree(ax_info); - - exit_err: - err("%s: Failed to initialize\n", __FUNCTION__); - return NULL; -} - -static void ax8817x_disconnect(struct usb_device *usb, void *p) -{ - struct ax8817x_info *ax_info = (struct ax8817x_info *) p; - - ax_info->drv_state = AX_DRV_STATE_EXITING; - - if (ax_info->int_urb != NULL) { - usb_unlink_urb(ax_info->int_urb); - usb_free_urb(ax_info->int_urb); - kfree(ax_info->int_buf); - } - - unregister_netdev(ax_info->net); - - /* XXX: hmmm... need to go through and clear out the ctl queue, too... */ - if (ax_info->ctl_urb != NULL) { - usb_unlink_urb(ax_info->ctl_urb); - usb_free_urb(ax_info->ctl_urb); - } - - kfree(ax_info); -} - - -static struct usb_driver ax8817x_driver = { - .owner = THIS_MODULE, - .name = driver_name, - .probe = ax8817x_bind, - .disconnect = ax8817x_disconnect, - .id_table = ax8817x_id_table, -}; - -static int __init ax8817x_init(void) -{ - int ret; - - if (n_rx_urbs < 1) - n_rx_urbs = AX_RX_URBS_DEFAULT; - - ret = usb_register(&ax8817x_driver); - if (ret < 0) { - err("%s: Failed to register\n", __FUNCTION__); - } else { - info(DRIVER_DESC " " DRIVER_VERSION); - } - - return ret; -} - -static void __exit ax8817x_exit(void) -{ - usb_deregister(&ax8817x_driver); -} - -module_init(ax8817x_init); -module_exit(ax8817x_exit); - -EXPORT_NO_SYMBOLS; diff -urN linux-2.4.24/drivers/usb/gadget/Config.in linux-2.4.25/drivers/usb/gadget/Config.in --- linux-2.4.24/drivers/usb/gadget/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -5,28 +5,31 @@ # Long term, this likely doesn't all belong in one directory # Plan to split it up eventually. # -# CAREFUL! Some versions of "xconfig" don't execute this correctly. -# mainmenu_option next_comment comment 'Support for USB gadgets' -bool 'Support for USB Gadgets' CONFIG_USB_GADGET -if [ "$CONFIG_USB_GADGET" = "y" ]; then +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. # - comment 'USB Peripheral Controller Drivers' - - # assume all the dependencies may be undefined ("== true", yeech) + choice 'USB Peripheral Controller Driver' "\ + NetChip-2280 CONFIG_USB_GADGET_NET2280 \ + Toshiba-TC86C001(Goku-S) CONFIG_USB_GADGET_GOKU \ + " NetChip-2280 + define_tristate CONFIG_USB_GADGET_CONTROLLER n - if [ "$CONFIG_PCI" = "y" ] ; then - tristate ' NetChip 2280 support' CONFIG_USB_NET2280 + + if [ "$CONFIG_PCI" = "y" -a "$CONFIG_USB_GADGET_NET2280" = "y" ] ; then + define_tristate CONFIG_USB_NET2280 $CONFIG_USB_GADGET define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_NET2280 fi - - # pxa2xx_udc, goku_udc, and others also work on 2.4 ... + 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_CONTROLLER" = "y" -o "$CONFIG_USB_GADGET_CONTROLLER" = "m" ] ; then @@ -46,32 +49,30 @@ comment 'USB Gadget Drivers' dep_tristate ' Gadget Zero (DEVELOPMENT)' CONFIG_USB_ZERO $CONFIG_USB_GADGET_CONTROLLER - if [ "$CONFIG_USB_ZERO" = "y" -o "$CONFIG_USB_ZERO" = "m" ]; then - if [ "$CONFIG_USB_NET2280" = "y" -o "$CONFIG_USB_NET2280" = "m" ]; then - define_bool CONFIG_USB_ZERO_NET2280 y - else if [ "$CONFIG_USB_PXA2XX" = "y" -o "$CONFIG_USB_PXA2XX" = "m" ]; then - define_bool CONFIG_USB_ZERO_PXA2XX y - else if [ "$CONFIG_USB_GOKU" = "y" -o "$CONFIG_USB_GOKU" = "m" ]; then - define_bool CONFIG_USB_ZERO_GOKU y - fi fi fi - # ... - fi - dep_tristate ' Ethernet Gadget (EXPERIMENTAL)' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET - if [ "$CONFIG_USB_ETH" = "y" -o "$CONFIG_USB_ETH" = "m" ]; then - if [ "$CONFIG_USB_NET2280" = "y" -o "$CONFIG_USB_NET2280" = "m" ]; then - define_bool CONFIG_USB_ETH_NET2280 y - else if [ "$CONFIG_USB_PXA2XX" = "y" -o "$CONFIG_USB_PXA2XX" = "m" ]; then - define_bool CONFIG_USB_ETH_PXA2XX y - else if [ "$CONFIG_USB_GOKU" = "y" -o "$CONFIG_USB_GOKU" = "m" ]; then - define_bool CONFIG_USB_ETH_GOKU y - fi fi fi - # ... - 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 - - # ... or other gadget drivers: printer class, hid, etc ... + # enforce the "only one statically linked gadget driver" rule + + if [ "$CONFIG_USB_ZERO" = "y" ]; then + # zero = y + define_tristate CONFIG_USB_ETH n + define_tristate CONFIG_USB_FILE_STORAGE n + fi + + if [ "$CONFIG_USB_ETH" = "y" ]; then + define_tristate CONFIG_USB_ZERO n + # eth = y + define_tristate CONFIG_USB_FILE_STORAGE n + fi + + if [ "$CONFIG_USB_FILE_STORAGE" = "y" ]; then + define_tristate CONFIG_USB_ZERO n + define_tristate CONFIG_USB_ETH n + # file_storage = y + fi fi fi endmenu diff -urN linux-2.4.24/drivers/usb/gadget/Makefile linux-2.4.25/drivers/usb/gadget/Makefile --- linux-2.4.24/drivers/usb/gadget/Makefile 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -6,12 +6,14 @@ # for static linking O_TARGET := built-in.o -list-multi := g_zero.o g_ether.o +list-multi := g_zero.o g_ether.o g_file_storage.o obj-$(CONFIG_USB_NET2280) += net2280.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_GOKU) += goku_udc.o # ... and only one of these, too; kbuild/kconfig don't help though. g_zero-objs := zero.o usbstring.o @@ -20,6 +22,8 @@ g_ether-objs := ether.o usbstring.o obj-$(CONFIG_USB_ETH) += g_ether.o +g_file_storage-objs := file_storage.o usbstring.o +obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o export-objs := $(controller-y) $(controller-m) @@ -29,3 +33,5 @@ $(LD) -r -o $@ $(g_zero-objs) g_ether.o: $(g_ether-objs) $(LD) -r -o $@ $(g_ether-objs) +g_file_storage.o: $(g_file_storage-objs) + $(LD) -r -o $@ $(g_file_storage-objs) diff -urN linux-2.4.24/drivers/usb/gadget/ether.c linux-2.4.25/drivers/usb/gadget/ether.c --- linux-2.4.24/drivers/usb/gadget/ether.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/ether.c 2004-02-18 05:36:31.000000000 -0800 @@ -134,12 +134,9 @@ * * CHIP ... hardware identifier * DRIVER_VERSION_NUM ... alerts the host side driver to differences - * EP0_MAXPACKET ... controls packetization of control requests * 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 ... unless we can run on bus power, USB_CONFIG_ATT_SELFPOWER * WAKEUP ... if hardware supports remote wakeup AND we will issue the * usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP * @@ -155,6 +152,9 @@ /* #undef on hardware that can't implement CDC */ #define DEV_CONFIG_CDC +/* undef on bus-powered hardware, and #define MAX_USB_POWER */ +#define SELFPOWER + /* * NetChip 2280, PCI based. * @@ -164,11 +164,10 @@ * performance note: only PIO needs per-usb-packet IRQs (ep0, ep-e, ep-f) * otherwise IRQs are per-Ethernet-packet unless TX_DELAY and chaining help. */ -#ifdef CONFIG_USB_ETH_NET2280 +#ifdef CONFIG_USB_GADGET_NET2280 #define CHIP "net2280" #define DEFAULT_QLEN 4 /* has dma chaining */ #define DRIVER_VERSION_NUM 0x0111 -#define EP0_MAXPACKET 64 static const char EP_OUT_NAME [] = "ep-a"; #define EP_OUT_NUM 1 static const char EP_IN_NAME [] = "ep-b"; @@ -176,8 +175,6 @@ static const char EP_STATUS_NAME [] = "ep-f"; #define EP_STATUS_NUM 3 #define HIGHSPEED -/* specific hardware configs could be bus-powered */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* supports remote wakeup, but this driver doesn't */ extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode); @@ -193,22 +190,19 @@ /* * PXA-2xx UDC: widely used in second gen Linux-capable ARM PDAs - * and other products. + * and other products. The IXP-42x UDC is register-compatible. * * multiple interfaces (or altsettings) aren't usable. so this hardware * can't implement CDC, which needs both capabilities. */ -#ifdef CONFIG_USB_ETH_PXA2XX +#ifdef CONFIG_USB_GADGET_PXA2XX #undef DEV_CONFIG_CDC #define CHIP "pxa2xx" #define DRIVER_VERSION_NUM 0x0113 -#define EP0_MAXPACKET 16 static const char EP_OUT_NAME [] = "ep2out-bulk"; #define EP_OUT_NUM 2 static const char EP_IN_NAME [] = "ep1in-bulk"; #define EP_IN_NUM 1 -/* doesn't support bus-powered operation */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* supports remote wakeup, but this driver doesn't */ /* no hw optimizations to apply */ @@ -221,17 +215,14 @@ * can't have a notification endpoint, since there are only the two * bulk-capable ones. the CDC spec allows that. */ -#ifdef CONFIG_USB_ETH_SA1100 +#ifdef CONFIG_USB_GADGET_SA1100 #define CHIP "sa1100" #define DRIVER_VERSION_NUM 0x0115 -#define EP0_MAXPACKET 8 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 // EP_STATUS_NUM is undefined -/* doesn't support bus-powered operation */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* doesn't support remote wakeup? */ /* no hw optimizations to apply */ @@ -243,25 +234,43 @@ * * This has three semi-configurable full speed bulk/interrupt endpoints. */ -#ifdef CONFIG_USB_ETH_GOKU +#ifdef CONFIG_USB_GADGET_GOKU #define CHIP "goku" #define DRIVER_VERSION_NUM 0x0116 -#define EP0_MAXPACKET 8 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 static const char EP_STATUS_NAME [] = "ep3-bulk"; #define EP_STATUS_NUM 3 -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* doesn't support remote wakeup */ #define hw_optimize(g) do {} while (0) #endif +/* + * SuperH UDC: UDC built-in to some Renesas SH processors. + * + * This has three semi-configurable full speed bulk/interrupt endpoints. + * + * Only one configuration and interface is supported. So this hardware + * can't implement CDC. + */ +#ifdef CONFIG_USB_GADGET_SUPERH +#undef DEV_CONFIG_CDC +#define CHIP "superh" +#define DRIVER_VERSION_NUM 0x0117 +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 + +#define hw_optimize(g) do {} while (0) +#endif + /*-------------------------------------------------------------------------*/ -#ifndef EP0_MAXPACKET +#ifndef CHIP # error Configure some USB peripheral controller driver! #endif @@ -292,19 +301,15 @@ * hardware that supports remote wakeup defaults to disabling it. */ -#ifndef SELFPOWER -/* default: say we rely on bus power */ -#define SELFPOWER 0 -/* else: - * - SELFPOWER value must be USB_CONFIG_ATT_SELFPOWER - * - 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 */ +#ifdef SELFPOWER +/* some hosts are confused by 0mA */ +#define MAX_USB_POWER 2 /* mA */ +#else +/* bus powered */ +#error Define your bus power consumption! #endif +#endif /* MAX_USB_POWER */ #ifndef WAKEUP /* default: this driver won't do remote wakeup */ @@ -388,7 +393,7 @@ /* * This device advertises one configuration. */ -static const struct usb_device_descriptor +static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, @@ -398,7 +403,6 @@ .bDeviceClass = DEV_CONFIG_CLASS, .bDeviceSubClass = 0, .bDeviceProtocol = 0, - .bMaxPacketSize0 = EP0_MAXPACKET, .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), @@ -408,7 +412,7 @@ .bNumConfigurations = 1, }; -static const struct usb_config_descriptor +static struct usb_config_descriptor eth_config = { .bLength = sizeof eth_config, .bDescriptorType = USB_DT_CONFIG, @@ -421,7 +425,7 @@ #endif .bConfigurationValue = DEV_CONFIG_VALUE, .iConfiguration = STRING_PRODUCT, - .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP, + .bmAttributes = USB_CONFIG_ATT_ONE | WAKEUP, .bMaxPower = (MAX_USB_POWER + 1) / 2, }; @@ -657,7 +661,7 @@ .bInterval = 1, }; -static const struct usb_qualifier_descriptor +static struct usb_qualifier_descriptor dev_qualifier = { .bLength = sizeof dev_qualifier, .bDescriptorType = USB_DT_DEVICE_QUALIFIER, @@ -665,12 +669,10 @@ .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = DEV_CONFIG_CLASS, - /* assumes ep0 uses the same value for both speeds ... */ - .bMaxPacketSize0 = EP0_MAXPACKET, - .bNumConfigurations = 1, }; + /* maxpacket and other transfer characteristics vary by speed. */ #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) @@ -971,7 +973,7 @@ if (number == dev->config) return 0; -#ifdef CONFIG_USB_ETH_SA1100 +#ifdef CONFIG_USB_GADGET_SA1100 if (dev->config && atomic_read (&dev->tx_qlen) != 0) { /* tx fifo is full, but we can't clear it...*/ INFO (dev, "can't change configurations\n"); @@ -1018,6 +1020,7 @@ /* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications */ #define CDC_NOTIFY_NETWORK_CONNECTION 0x00 /* required; 6.3.1 */ +#define CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 /* optional; 6.3.2 */ #define CDC_NOTIFY_SPEED_CHANGE 0x2a /* required; 6.3.8 */ struct cdc_notification { @@ -1135,6 +1138,8 @@ /* see section 3.8.2 table 10 of the CDC spec for more ethernet * requests, mostly for filters (multicast, pm) and statistics */ +#define CDC_SEND_ENCAPSULATED_REQUEST 0x00 /* optional */ +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 /* optional */ #define CDC_SET_ETHERNET_PACKET_FILTER 0x43 /* required */ /* @@ -1200,7 +1205,7 @@ value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC); spin_unlock (&dev->lock); break; -#ifdef CONFIG_USB_ETH_PXA2XX +#ifdef CONFIG_USB_GADGET_PXA2XX /* PXA UDC prevents us from using SET_INTERFACE in normal ways. * And it hides GET_CONFIGURATION and GET_INTERFACE too. */ @@ -1650,7 +1655,7 @@ req->context = skb; req->complete = tx_complete; -#ifdef CONFIG_USB_ETH_SA1100 +#ifdef CONFIG_USB_GADGET_SA1100 /* don't demand zlp (req->zero) support from all hardware */ if ((length % dev->in_ep->maxpacket) == 0) length++; @@ -1782,6 +1787,17 @@ return -ENODEV; #endif + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; +#ifdef HIGHSPEED + /* assumes ep0 uses the same value for both speeds ... */ + dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; +#endif + +#ifdef SELFPOWERED + eth_config.bmAttributes |= USB_CONFIG_ATT_SELFPOWERED; + usb_gadget_set_selfpowered (gadget); +#endif + net = alloc_etherdev (sizeof *dev); if (!net) return status; diff -urN linux-2.4.24/drivers/usb/gadget/file_storage.c linux-2.4.25/drivers/usb/gadget/file_storage.c --- linux-2.4.24/drivers/usb/gadget/file_storage.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/file_storage.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,4047 @@ +/* + * file_storage.c -- File-backed USB Storage Gadget, for USB development + * + * Copyright (C) 2003 Alan Stern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the above-listed copyright holders may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* + * The File-backed Storage Gadget acts as a USB Mass Storage device, + * appearing to the host as a disk drive. In addition to providing an + * example of a genuinely useful gadget driver for a USB device, it also + * illustrates a technique of double-buffering for increased throughput. + * Last but not least, it gives an easy way to probe the behavior of the + * Mass Storage drivers in a USB host. + * + * Backing storage is provided by a regular file or a block device, specified + * by the "file" module parameter. Access can be limited to read-only by + * setting the optional "ro" module parameter. + * + * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), + * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected + * by the optional "transport" module parameter. It also supports the + * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), + * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by + * the optional "protocol" module parameter. For testing purposes the + * gadget will indicate that it has removable media if the optional + * "removable" module parameter is set. In addition, the default Vendor ID, + * Product ID, and release number can be overridden. + * + * There is support for multiple logical units (LUNs), each of which has + * its own backing file. The number of LUNs can be set using the optional + * "luns" module parameter (anywhere from 1 to 8), and the corresponding + * files are specified using comma-separated lists for "file" and "ro". + * The default number of LUNs is taken from the number of "file" elements; + * it is 1 if "file" is not given. If "removable" is not set then a backing + * file must be specified for each LUN. If it is set, then an unspecified + * or empty backing filename means the LUN's medium is not loaded. + * + * Requirements are modest; only a bulk-in and a bulk-out endpoint are + * needed (an interrupt-out endpoint is also needed for CBI). The memory + * requirement amounts to two 16K buffers, size configurable by a parameter. + * Support is included for both full-speed and high-speed operation. + * + * Module options: + * + * file=filename[,filename...] + * Required if "removable" is not set, names of + * the files or block devices used for + * backing storage + * ro=b[,b...] Default false, booleans for read-only access + * luns=N Default N = number of filenames, number of + * LUNs to support + * transport=XXX Default BBB, transport name (CB, CBI, or BBB) + * protocol=YYY Default SCSI, protocol name (RBC, 8020 or + * ATAPI, QIC, UFI, 8070, or SCSI; + * also 1 - 6) + * removable Default false, boolean for removable media + * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID + * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID + * release=0xRRRR Override the USB release number (bcdDevice) + * buflen=N Default N=16384, buffer size used (will be + * rounded down to a multiple of + * PAGE_CACHE_SIZE) + * stall Default determined according to the type of + * USB device controller (usually true), + * boolean to permit the driver to halt + * bulk endpoints + * + * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file" and "ro" + * options are available; default values are used for everything else. + * + * This gadget driver is heavily based on "Gadget Zero" by David Brownell. + */ + + +/* + * Driver Design + * + * The FSG driver is fairly straightforward. There is a main kernel + * thread that handles most of the work. Interrupt routines field + * callbacks from the controller driver: bulk- and interrupt-request + * completion notifications, endpoint-0 events, and disconnect events. + * Completion events are passed to the main thread by wakeup calls. Many + * ep0 requests are handled at interrupt time, but SetInterface, + * SetConfiguration, and device reset requests are forwarded to the + * thread in the form of "exceptions" using SIGUSR1 signals (since they + * should interrupt any ongoing file I/O operations). + * + * The thread's main routine implements the standard command/data/status + * parts of a SCSI interaction. It and its subroutines are full of tests + * for pending signals/exceptions -- all this polling is necessary since + * the kernel has no setjmp/longjmp equivalents. (Maybe this is an + * indication that the driver really wants to be running in userspace.) + * An important point is that so long as the thread is alive it keeps an + * open reference to the backing file. This will prevent unmounting + * the backing file's underlying filesystem and could cause problems + * during system shutdown, for example. To prevent such problems, the + * thread catches INT, TERM, and KILL signals and converts them into + * an EXIT exception. + * + * In normal operation the main thread is started during the gadget's + * fsg_bind() callback and stopped during fsg_unbind(). But it can also + * exit when it receives a signal, and there's no point leaving the + * gadget running when the thread is dead. So just before the thread + * exits, it deregisters the gadget driver. This makes things a little + * tricky: The driver is deregistered at two places, and the exiting + * thread can indirectly call fsg_unbind() which in turn can tell the + * thread to exit. The first problem is resolved through the use of the + * REGISTERED atomic bitflag; the driver will only be deregistered once. + * The second problem is resolved by having fsg_unbind() check + * fsg->state; it won't try to stop the thread if the state is already + * FSG_STATE_TERMINATED. + * + * To provide maximum throughput, the driver uses a circular pipeline of + * buffer heads (struct fsg_buffhd). In principle the pipeline can be + * arbitrarily long; in practice the benefits don't justify having more + * than 2 stages (i.e., double buffering). But it helps to think of the + * pipeline as being a long one. Each buffer head contains a bulk-in and + * a bulk-out request pointer (since the buffer can be used for both + * output and input -- directions always are given from the host's + * point of view) as well as a pointer to the buffer and various state + * variables. + * + * Use of the pipeline follows a simple protocol. There is a variable + * (fsg->next_buffhd_to_fill) that points to the next buffer head to use. + * At any time that buffer head may still be in use from an earlier + * request, so each buffer head has a state variable indicating whether + * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the + * buffer head to be EMPTY, filling the buffer either by file I/O or by + * USB I/O (during which the buffer head is BUSY), and marking the buffer + * head FULL when the I/O is complete. Then the buffer will be emptied + * (again possibly by USB I/O, during which it is marked BUSY) and + * finally marked EMPTY again (possibly by a completion routine). + * + * A module parameter tells the driver to avoid stalling the bulk + * endpoints wherever the transport specification allows. This is + * necessary for some UDCs like the SuperH, which cannot reliably clear a + * halt on a bulk endpoint. However, under certain circumstances the + * Bulk-only specification requires a stall. In such cases the driver + * will halt the endpoint and set a flag indicating that it should clear + * the halt in software during the next device reset. Hopefully this + * will permit everything to work correctly. + * + * One subtle point concerns sending status-stage responses for ep0 + * requests. Some of these requests, such as device reset, can involve + * interrupting an ongoing file I/O operation, which might take an + * arbitrarily long time. During that delay the host might give up on + * the original ep0 request and issue a new one. When that happens the + * driver should not notify the host about completion of the original + * request, as the host will no longer be waiting for it. So the driver + * assigns to each ep0 request a unique tag, and it keeps track of the + * tag value of the request associated with a long-running exception + * (device-reset, interface-change, or configuration-change). When the + * exception handler is finished, the status-stage response is submitted + * only if the current ep0 request tag is equal to the exception request + * tag. Thus only the most recently received ep0 request will get a + * status-stage response. + * + * Warning: This driver source file is too long. It ought to be split up + * into a header file plus about 3 separate .c files, to handle the details + * of the Gadget, USB Mass Storage, and SCSI protocols. + */ + + +#undef DEBUG +#undef VERBOSE +#undef DUMP_MSGS + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/*-------------------------------------------------------------------------*/ + +#define DRIVER_DESC "File-backed Storage Gadget" +#define DRIVER_NAME "g_file_storage" +#define DRIVER_VERSION "14 January 2004" + +static const char longname[] = DRIVER_DESC; +static const char shortname[] = DRIVER_NAME; + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Alan Stern"); +MODULE_LICENSE("Dual BSD/GPL"); + +/* Thanks to NetChip Technologies for donating this product ID. + * + * DO NOT REUSE THESE IDs with any other driver!! Ever!! + * Instead: allocate your own, using normal USB-IF procedures. */ +#define DRIVER_VENDOR_ID 0x0525 // NetChip +#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. + */ +#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 + + +/*-------------------------------------------------------------------------*/ + +#define fakedev_printk(level, dev, format, args...) \ + printk(level "%s %s: " format , DRIVER_NAME , (dev)->name , ## args) + +#define xprintk(f,level,fmt,args...) \ + fakedev_printk(level , (f)->gadget , fmt , ## args) +#define yprintk(l,level,fmt,args...) \ + fakedev_printk(level , &(l)->dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(fsg,fmt,args...) \ + xprintk(fsg , KERN_DEBUG , fmt , ## args) +#define LDBG(lun,fmt,args...) \ + yprintk(lun , KERN_DEBUG , fmt , ## args) +#define MDBG(fmt,args...) \ + printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) +#else +#define DBG(fsg,fmt,args...) \ + do { } while (0) +#define LDBG(lun,fmt,args...) \ + do { } while (0) +#define MDBG(fmt,args...) \ + do { } while (0) +#undef VERBOSE +#undef DUMP_MSGS +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#define VLDBG LDBG +#else +#define VDBG(fsg,fmt,args...) \ + do { } while (0) +#define VLDBG(lun,fmt,args...) \ + do { } while (0) +#endif /* VERBOSE */ + +#define ERROR(fsg,fmt,args...) \ + xprintk(fsg , KERN_ERR , fmt , ## args) +#define LERROR(lun,fmt,args...) \ + yprintk(lun , KERN_ERR , fmt , ## args) + +#define WARN(fsg,fmt,args...) \ + xprintk(fsg , KERN_WARNING , fmt , ## args) +#define LWARN(lun,fmt,args...) \ + yprintk(lun , KERN_WARNING , fmt , ## args) + +#define INFO(fsg,fmt,args...) \ + xprintk(fsg , KERN_INFO , fmt , ## args) +#define LINFO(lun,fmt,args...) \ + yprintk(lun , KERN_INFO , fmt , ## args) + +#define MINFO(fmt,args...) \ + printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) + + +/*-------------------------------------------------------------------------*/ + +/* Encapsulate the module parameter settings */ + +#define MAX_LUNS 8 + +static char *file[MAX_LUNS] = {NULL, }; +static int ro[MAX_LUNS] = {0, }; +static unsigned int luns = 0; +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 int buflen = 16384; +static int stall = CAN_STALL; + +static struct { + unsigned int nluns; + + char *transport_parm; + char *protocol_parm; + int removable; + unsigned short vendor; + unsigned short product; + unsigned short release; + unsigned int buflen; + int can_stall; + + int transport_type; + char *transport_name; + int protocol_type; + char *protocol_name; + +} mod_data; + + +MODULE_PARM(file, "1-8s"); +MODULE_PARM_DESC(file, "names of backing files or devices"); + +MODULE_PARM(ro, "1-8b"); +MODULE_PARM_DESC(ro, "true to force read-only"); + + +/* In the non-TEST version, only the file and ro module parameters + * are available. */ +#ifdef CONFIG_USB_FILE_STORAGE_TEST + +MODULE_PARM(luns, "i"); +MODULE_PARM_DESC(luns, "number of LUNs"); + +MODULE_PARM(transport, "s"); +MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)"); + +MODULE_PARM(protocol, "s"); +MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, " + "8070, or SCSI)"); + +MODULE_PARM(removable, "b"); +MODULE_PARM_DESC(removable, "true to simulate removable media"); + +MODULE_PARM(vendor, "h"); +MODULE_PARM_DESC(vendor, "USB Vendor ID"); + +MODULE_PARM(product, "h"); +MODULE_PARM_DESC(product, "USB Product ID"); + +MODULE_PARM(release, "h"); +MODULE_PARM_DESC(release, "USB release number"); + +MODULE_PARM(buflen, "i"); +MODULE_PARM_DESC(buflen, "I/O buffer size"); + +MODULE_PARM(stall, "i"); +MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); + +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ + + +/*-------------------------------------------------------------------------*/ + +/* USB protocol value = the transport method */ +#define USB_PR_CBI 0x00 // Control/Bulk/Interrupt +#define USB_PR_CB 0x01 // Control/Bulk w/o interrupt +#define USB_PR_BULK 0x50 // Bulk-only + +/* USB subclass value = the protocol encapsulation */ +#define USB_SC_RBC 0x01 // Reduced Block Commands (flash) +#define USB_SC_8020 0x02 // SFF-8020i, MMC-2, ATAPI (CD-ROM) +#define USB_SC_QIC 0x03 // QIC-157 (tape) +#define USB_SC_UFI 0x04 // UFI (floppy) +#define USB_SC_8070 0x05 // SFF-8070i (removable) +#define USB_SC_SCSI 0x06 // Transparent SCSI + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct bulk_cb_wrap { + u32 Signature; // Contains 'USBC' + u32 Tag; // Unique per command id + u32 DataTransferLength; // Size of the data + u8 Flags; // Direction in bit 7 + u8 Lun; // LUN (normally 0) + u8 Length; // Of the CDB, <= MAX_COMMAND_SIZE + u8 CDB[16]; // Command Data Block +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355 // Spells out USBC +#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct bulk_cs_wrap { + u32 Signature; // Should = 'USBS' + u32 Tag; // Same as original command + u32 Residue; // Amount not transferred + u8 Status; // See below +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355 // Spells out 'USBS' +#define USB_STATUS_PASS 0 +#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + +/* Bulk-only class specific requests */ +#define USB_BULK_RESET_REQUEST 0xff +#define USB_BULK_GET_MAX_LUN_REQUEST 0xfe + + +/* CBI Interrupt data structure */ +struct interrupt_data { + u8 bType; + u8 bValue; +}; + +#define CBI_INTERRUPT_DATA_LEN 2 + +/* CBI Accept Device-Specific Command request */ +#define USB_CBI_ADSC_REQUEST 0x00 + + +#define MAX_COMMAND_SIZE 16 // Length of a SCSI Command Data Block + +/* SCSI commands that we recognize */ +#define SC_FORMAT_UNIT 0x04 +#define SC_INQUIRY 0x12 +#define SC_MODE_SELECT_6 0x15 +#define SC_MODE_SELECT_10 0x55 +#define SC_MODE_SENSE_6 0x1a +#define SC_MODE_SENSE_10 0x5a +#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e +#define SC_READ_6 0x08 +#define SC_READ_10 0x28 +#define SC_READ_12 0xa8 +#define SC_READ_CAPACITY 0x25 +#define SC_READ_FORMAT_CAPACITIES 0x23 +#define SC_RELEASE 0x17 +#define SC_REQUEST_SENSE 0x03 +#define SC_RESERVE 0x16 +#define SC_SEND_DIAGNOSTIC 0x1d +#define SC_START_STOP_UNIT 0x1b +#define SC_SYNCHRONIZE_CACHE 0x35 +#define SC_TEST_UNIT_READY 0x00 +#define SC_VERIFY 0x2f +#define SC_WRITE_6 0x0a +#define SC_WRITE_10 0x2a +#define SC_WRITE_12 0xaa + +/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ +#define SS_NO_SENSE 0 +#define SS_COMMUNICATION_FAILURE 0x040800 +#define SS_INVALID_COMMAND 0x052000 +#define SS_INVALID_FIELD_IN_CDB 0x052400 +#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 +#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 +#define SS_MEDIUM_NOT_PRESENT 0x023a00 +#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 +#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 +#define SS_RESET_OCCURRED 0x062900 +#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 +#define SS_UNRECOVERED_READ_ERROR 0x031100 +#define SS_WRITE_ERROR 0x030c02 +#define SS_WRITE_PROTECTED 0x072700 + +#define SK(x) ((u8) ((x) >> 16)) // Sense Key byte, etc. +#define ASC(x) ((u8) ((x) >> 8)) +#define ASCQ(x) ((u8) (x)) + + +/*-------------------------------------------------------------------------*/ + +/* + * These definitions will permit the compiler to avoid generating code for + * parts of the driver that aren't used in the non-TEST version. Even gcc + * can recognize when a test of a constant expression yields a dead code + * path. + * + * Also, in the non-TEST version, open_backing_file() is only used during + * initialization and the sysfs attribute store_xxx routines aren't used + * at all. We will define NORMALLY_INIT to mark them as __init so they + * don't occupy kernel code space unnecessarily. + */ + +#ifdef CONFIG_USB_FILE_STORAGE_TEST + +#define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK) +#define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI) +#define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI) +#define backing_file_is_open(curlun) ((curlun)->filp != NULL) +#define NORMALLY_INIT + +#else + +#define transport_is_bbb() 1 +#define transport_is_cbi() 0 +#define protocol_is_scsi() 1 +#define backing_file_is_open(curlun) 1 +#define NORMALLY_INIT __init + +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ + + +struct lun { + struct file *filp; + loff_t file_length; + loff_t num_sectors; + + unsigned int ro : 1; + unsigned int prevent_medium_removal : 1; + unsigned int registered : 1; + + u32 sense_data; + u32 sense_data_info; + u32 unit_attention_data; + +#define BUS_ID_SIZE 20 + struct __lun_device { + char name[BUS_ID_SIZE]; + void *driver_data; + } dev; +}; + + +/* Big enough to hold our biggest descriptor */ +#define EP0_BUFSIZE 256 +#define DELAYED_STATUS (EP0_BUFSIZE + 999) // An impossibly large value + +/* Number of buffers we will use. 2 is enough for double-buffering */ +#define NUM_BUFFERS 2 + +enum fsg_buffer_state { + BUF_STATE_EMPTY = 0, + BUF_STATE_FULL, + BUF_STATE_BUSY +}; + +struct fsg_buffhd { + void *buf; + dma_addr_t dma; + volatile enum fsg_buffer_state state; + struct fsg_buffhd *next; + + /* The NetChip 2280 is faster, and handles some protocol faults + * better, if we don't submit any short bulk-out read requests. + * So we will record the intended request length here. */ + unsigned int bulk_out_intended_length; + + struct usb_request *inreq; + volatile int inreq_busy; + struct usb_request *outreq; + volatile int outreq_busy; +}; + +enum fsg_state { + FSG_STATE_COMMAND_PHASE = -10, // This one isn't used anywhere + FSG_STATE_DATA_PHASE, + FSG_STATE_STATUS_PHASE, + + FSG_STATE_IDLE = 0, + FSG_STATE_ABORT_BULK_OUT, + FSG_STATE_RESET, + FSG_STATE_INTERFACE_CHANGE, + FSG_STATE_CONFIG_CHANGE, + FSG_STATE_DISCONNECT, + FSG_STATE_EXIT, + FSG_STATE_TERMINATED +}; + +enum data_direction { + DATA_DIR_UNKNOWN = 0, + DATA_DIR_FROM_HOST, + DATA_DIR_TO_HOST, + DATA_DIR_NONE +}; + +struct fsg_dev { + /* lock protects: state, all the req_busy's, and cbbuf_cmnd */ + spinlock_t lock; + struct usb_gadget *gadget; + + /* filesem protects: backing files in use */ + struct rw_semaphore filesem; + + struct usb_ep *ep0; // Handy copy of gadget->ep0 + struct usb_request *ep0req; // For control responses + volatile unsigned int ep0_req_tag; + const char *ep0req_name; + + struct usb_request *intreq; // For interrupt responses + volatile int intreq_busy; + struct fsg_buffhd *intr_buffhd; + + unsigned int bulk_out_maxpacket; + enum fsg_state state; // For exception handling + unsigned int exception_req_tag; + + u8 config, new_config; + + unsigned int running : 1; + unsigned int bulk_in_enabled : 1; + unsigned int bulk_out_enabled : 1; + unsigned int intr_in_enabled : 1; + unsigned int phase_error : 1; + unsigned int short_packet_received : 1; + unsigned int bad_lun_okay : 1; + + unsigned long atomic_bitflags; +#define REGISTERED 0 +#define CLEAR_BULK_HALTS 1 + + struct usb_ep *bulk_in; + struct usb_ep *bulk_out; + struct usb_ep *intr_in; + + struct fsg_buffhd *next_buffhd_to_fill; + struct fsg_buffhd *next_buffhd_to_drain; + struct fsg_buffhd buffhds[NUM_BUFFERS]; + + wait_queue_head_t thread_wqh; + int thread_wakeup_needed; + struct completion thread_notifier; + int thread_pid; + struct task_struct *thread_task; + sigset_t thread_signal_mask; + + int cmnd_size; + u8 cmnd[MAX_COMMAND_SIZE]; + enum data_direction data_dir; + u32 data_size; + u32 data_size_from_cmnd; + u32 tag; + unsigned int lun; + u32 residue; + u32 usb_amount_left; + + /* The CB protocol offers no way for a host to know when a command + * has completed. As a result the next command may arrive early, + * and we will still have to handle it. For that reason we need + * a buffer to store new commands when using CB (or CBI, which + * does not oblige a host to wait for command completion either). */ + int cbbuf_cmnd_size; + u8 cbbuf_cmnd[MAX_COMMAND_SIZE]; + + unsigned int nluns; + struct lun *luns; + struct lun *curlun; +}; + +typedef void (*fsg_routine_t)(struct fsg_dev *); + +static int inline exception_in_progress(struct fsg_dev *fsg) +{ + return (fsg->state > FSG_STATE_IDLE); +} + +/* Make bulk-out requests be divisible by the maxpacket size */ +static void inline set_bulk_out_req_length(struct fsg_dev *fsg, + struct fsg_buffhd *bh, unsigned int length) +{ + unsigned int rem; + + bh->bulk_out_intended_length = length; + rem = length % fsg->bulk_out_maxpacket; + if (rem > 0) + length += fsg->bulk_out_maxpacket - rem; + bh->outreq->length = length; +} + +static struct fsg_dev *the_fsg; +static struct usb_gadget_driver fsg_driver; + +static void close_backing_file(struct lun *curlun); +static void close_all_backing_files(struct fsg_dev *fsg); + + +/*-------------------------------------------------------------------------*/ + +#ifdef DUMP_MSGS + +static void dump_msg(struct fsg_dev *fsg, const char *label, + const u8 *buf, unsigned int length) +{ + unsigned int start, num, i; + char line[52], *p; + + if (length >= 512) + return; + DBG(fsg, "%s, length %u:\n", label, length); + + start = 0; + while (length > 0) { + num = min(length, 16u); + p = line; + for (i = 0; i < num; ++i) { + if (i == 8) + *p++ = ' '; + sprintf(p, " %02x", buf[i]); + p += 3; + } + *p = 0; + printk(KERN_DEBUG "%6x: %s\n", start, line); + buf += num; + start += num; + length -= num; + } +} + +static void inline dump_cdb(struct fsg_dev *fsg) +{} + +#else + +static void inline dump_msg(struct fsg_dev *fsg, const char *label, + const u8 *buf, unsigned int length) +{} + +static void inline dump_cdb(struct fsg_dev *fsg) +{ + int i; + char cmdbuf[3*MAX_COMMAND_SIZE + 1]; + + for (i = 0; i < fsg->cmnd_size; ++i) + sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]); + VDBG(fsg, "SCSI CDB: %s\n", cmdbuf); +} + +#endif /* DUMP_MSGS */ + + +static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) +{ + const char *name; + + if (ep == fsg->bulk_in) + name = "bulk-in"; + else if (ep == fsg->bulk_out) + name = "bulk-out"; + else + name = ep->name; + DBG(fsg, "%s set halt\n", name); + return usb_ep_set_halt(ep); +} + + +/*-------------------------------------------------------------------------*/ + +/* Routines for unaligned data access */ + +static u16 inline get_be16(u8 *buf) +{ + return ((u16) buf[0] << 8) | ((u16) buf[1]); +} + +static u32 inline get_be32(u8 *buf) +{ + return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | + ((u32) buf[2] << 8) | ((u32) buf[3]); +} + +static void inline put_be16(u8 *buf, u16 val) +{ + buf[0] = val >> 8; + buf[1] = val; +} + +static void inline put_be32(u8 *buf, u32 val) +{ + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; +} + + +/*-------------------------------------------------------------------------*/ + +/* + * DESCRIPTORS ... most are static, but strings and (full) configuration + * descriptors are built on demand. Also the (static) config and interface + * descriptors are adjusted during fsg_bind(). + */ +#define STRING_MANUFACTURER 1 +#define STRING_PRODUCT 2 +#define STRING_SERIAL 3 + +/* There is only one configuration. */ +#define CONFIG_VALUE 1 + +static struct usb_device_descriptor +device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_PER_INTERFACE, + + /* 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), + + .iManufacturer = STRING_MANUFACTURER, + .iProduct = STRING_PRODUCT, + .iSerialNumber = STRING_SERIAL, + .bNumConfigurations = 1, +}; + +static struct usb_config_descriptor +config_desc = { + .bLength = sizeof config_desc, + .bDescriptorType = USB_DT_CONFIG, + + /* wTotalLength adjusted during bind() */ + .bNumInterfaces = 1, + .bConfigurationValue = CONFIG_VALUE, + .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER, + .bMaxPower = (MAX_USB_POWER + 1) / 2, +}; + +/* There is only one interface. */ + +static struct usb_interface_descriptor +intf_desc = { + .bLength = sizeof intf_desc, + .bDescriptorType = USB_DT_INTERFACE, + + .bNumEndpoints = 2, // Adjusted during bind() + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = USB_SC_SCSI, // Adjusted during bind() + .bInterfaceProtocol = USB_PR_BULK, // Adjusted during bind() +}; + +/* Three full-speed endpoint descriptors: bulk-in, bulk-out, + * and interrupt-in. */ + +static const 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, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(FS_BULK_IN_MAXPACKET), +}; + +static const struct usb_endpoint_descriptor +fs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = EP_BULK_OUT_NUM, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(FS_BULK_OUT_MAXPACKET), +}; + +static const 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, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = __constant_cpu_to_le16(2), + .bInterval = 32, // frames -> 32 ms +}; + +#ifdef HIGHSPEED + +/* + * USB 2.0 devices need to expose both high speed and full speed + * descriptors, unless they only run at full speed. + * + * That means alternate endpoint descriptors (bigger packets) + * and a "device qualifier" ... plus more construction options + * for the config descriptor. + */ +static const 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, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512), +}; + +static const struct usb_endpoint_descriptor +hs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = EP_BULK_OUT_NUM, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(512), + .bInterval = 1, // NAK every 1 uframe +}; + +static const 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, + .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, +}; + +/* Maxpacket and other transfer characteristics vary by speed. */ +#define ep_desc(g,fs,hs) (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs)) + +#else + +/* If there's no high speed support, maxpacket doesn't change. */ +#define ep_desc(g,fs,hs) fs + +#endif /* !HIGHSPEED */ + + +/* The CBI specification limits the serial string to 12 uppercase hexadecimal + * characters. */ +static char serial[13]; + +/* Static strings, in ISO 8859/1 */ +static struct usb_string strings[] = { + { STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, }, + { STRING_PRODUCT, longname, }, + { STRING_SERIAL, serial, }, + { } // end of list +}; + +static struct usb_gadget_strings stringtab = { + .language = 0x0409, // en-us + .strings = strings, +}; + + +/* + * 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. + */ +static int populate_config_buf(enum usb_device_speed speed, + u8 *buf0, u8 type, unsigned index) +{ + u8 *buf = buf0; +#ifdef HIGHSPEED + int hs; +#endif + + 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); + 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 +#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; + } + } + + return buf - buf0; +} + + +/*-------------------------------------------------------------------------*/ + +/* These routines may be called in process context or in_irq */ + +static void wakeup_thread(struct fsg_dev *fsg) +{ + /* Tell the main thread that something has happened */ + fsg->thread_wakeup_needed = 1; + wake_up_all(&fsg->thread_wqh); +} + + +static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) +{ + unsigned long flags; + struct task_struct *thread_task; + + /* Do nothing if a higher-priority exception is already in progress. + * If a lower-or-equal priority exception is in progress, preempt it + * and notify the main thread by sending it a signal. */ + spin_lock_irqsave(&fsg->lock, flags); + if (fsg->state <= new_state) { + fsg->exception_req_tag = fsg->ep0_req_tag; + fsg->state = new_state; + thread_task = fsg->thread_task; + if (thread_task) + send_sig_info(SIGUSR1, (void *) 1L, thread_task); + } + spin_unlock_irqrestore(&fsg->lock, flags); +} + + +/*-------------------------------------------------------------------------*/ + +/* The disconnect callback and ep0 routines. These always run in_irq, + * except that ep0_queue() is called in the main thread to acknowledge + * completion of various requests: set config, set interface, and + * Bulk-only device reset. */ + +static void fsg_disconnect(struct usb_gadget *gadget) +{ + struct fsg_dev *fsg = get_gadget_data(gadget); + + DBG(fsg, "disconnect or port reset\n"); + raise_exception(fsg, FSG_STATE_DISCONNECT); +} + + +static int ep0_queue(struct fsg_dev *fsg) +{ + int rc; + + rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); + if (rc != 0 && rc != -ESHUTDOWN) { + + /* We can't do much more than wait for a reset */ + WARN(fsg, "error in submission: %s --> %d\n", + fsg->ep0->name, rc); + } + return rc; +} + +static void ep0_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + + if (req->actual > 0) + dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); + if (req->status || req->actual != req->length) + DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + req->status, req->actual, req->length); + if (req->status == -ECONNRESET) // Request was cancelled + usb_ep_fifo_flush(ep); + + if (req->status == 0 && req->context) + ((fsg_routine_t) (req->context))(fsg); +} + + +/*-------------------------------------------------------------------------*/ + +/* Bulk and interrupt endpoint completion handlers. + * These always run in_irq. */ + +static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; + + if (req->status || req->actual != req->length) + DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + req->status, req->actual, req->length); + if (req->status == -ECONNRESET) // Request was cancelled + usb_ep_fifo_flush(ep); + + /* Hold the lock while we update the request and buffer states */ + spin_lock(&fsg->lock); + bh->inreq_busy = 0; + bh->state = BUF_STATE_EMPTY; + spin_unlock(&fsg->lock); + wakeup_thread(fsg); +} + +static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; + + dump_msg(fsg, "bulk-out", req->buf, req->actual); + if (req->status || req->actual != bh->bulk_out_intended_length) + DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + req->status, req->actual, + bh->bulk_out_intended_length); + if (req->status == -ECONNRESET) // Request was cancelled + usb_ep_fifo_flush(ep); + + /* Hold the lock while we update the request and buffer states */ + spin_lock(&fsg->lock); + bh->outreq_busy = 0; + bh->state = BUF_STATE_FULL; + spin_unlock(&fsg->lock); + wakeup_thread(fsg); +} + +static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) +{ +#ifdef CONFIG_USB_FILE_STORAGE_TEST + struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; + struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; + + if (req->status || req->actual != req->length) + DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, + req->status, req->actual, req->length); + if (req->status == -ECONNRESET) // Request was cancelled + usb_ep_fifo_flush(ep); + + /* Hold the lock while we update the request and buffer states */ + spin_lock(&fsg->lock); + fsg->intreq_busy = 0; + bh->state = BUF_STATE_EMPTY; + spin_unlock(&fsg->lock); + wakeup_thread(fsg); +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ +} + + +/*-------------------------------------------------------------------------*/ + +/* Ep0 class-specific handlers. These always run in_irq. */ + +static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ +#ifdef CONFIG_USB_FILE_STORAGE_TEST + struct usb_request *req = fsg->ep0req; + static u8 cbi_reset_cmnd[6] = { + SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; + + /* Error in command transfer? */ + if (req->status || req->length != req->actual || + req->actual < 6 || req->actual > MAX_COMMAND_SIZE) { + + /* Not all controllers allow a protocol stall after + * receiving control-out data, but we'll try anyway. */ + fsg_set_halt(fsg, fsg->ep0); + return; // Wait for reset + } + + /* Is it the special reset command? */ + if (req->actual >= sizeof cbi_reset_cmnd && + memcmp(req->buf, cbi_reset_cmnd, + sizeof cbi_reset_cmnd) == 0) { + + /* Raise an exception to stop the current operation + * and reinitialize our state. */ + DBG(fsg, "cbi reset request\n"); + raise_exception(fsg, FSG_STATE_RESET); + return; + } + + VDBG(fsg, "CB[I] accept device-specific command\n"); + spin_lock(&fsg->lock); + + /* Save the command for later */ + if (fsg->cbbuf_cmnd_size) + WARN(fsg, "CB[I] overwriting previous command\n"); + fsg->cbbuf_cmnd_size = req->actual; + memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); + + spin_unlock(&fsg->lock); + wakeup_thread(fsg); +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ +} + + +static int class_setup_req(struct fsg_dev *fsg, + const struct usb_ctrlrequest *ctrl) +{ + struct usb_request *req = fsg->ep0req; + int value = -EOPNOTSUPP; + + if (!fsg->config) + return value; + + /* Handle Bulk-only class-specific requests */ + if (transport_is_bbb()) { + switch (ctrl->bRequest) { + + case USB_BULK_RESET_REQUEST: + if (ctrl->bRequestType != (USB_DIR_OUT | + USB_TYPE_CLASS | USB_RECIP_INTERFACE)) + break; + if (ctrl->wIndex != 0) { + value = -EDOM; + break; + } + + /* Raise an exception to stop the current operation + * and reinitialize our state. */ + DBG(fsg, "bulk reset request\n"); + raise_exception(fsg, FSG_STATE_RESET); + value = DELAYED_STATUS; + break; + + case USB_BULK_GET_MAX_LUN_REQUEST: + if (ctrl->bRequestType != (USB_DIR_IN | + USB_TYPE_CLASS | USB_RECIP_INTERFACE)) + break; + if (ctrl->wIndex != 0) { + value = -EDOM; + break; + } + VDBG(fsg, "get max LUN\n"); + *(u8 *) req->buf = fsg->nluns - 1; + value = min(ctrl->wLength, (u16) 1); + break; + } + } + + /* Handle CBI class-specific requests */ + else { + switch (ctrl->bRequest) { + + case USB_CBI_ADSC_REQUEST: + if (ctrl->bRequestType != (USB_DIR_OUT | + USB_TYPE_CLASS | USB_RECIP_INTERFACE)) + break; + if (ctrl->wIndex != 0) { + value = -EDOM; + break; + } + if (ctrl->wLength > MAX_COMMAND_SIZE) { + value = -EOVERFLOW; + break; + } + value = ctrl->wLength; + fsg->ep0req->context = received_cbi_adsc; + break; + } + } + + if (value == -EOPNOTSUPP) + VDBG(fsg, + "unknown class-specific control req " + "%02x.%02x v%04x i%04x l%u\n", + ctrl->bRequestType, ctrl->bRequest, + ctrl->wValue, ctrl->wIndex, ctrl->wLength); + return value; +} + + +/*-------------------------------------------------------------------------*/ + +/* Ep0 standard request handlers. These always run in_irq. */ + +static int standard_setup_req(struct fsg_dev *fsg, + const struct usb_ctrlrequest *ctrl) +{ + struct usb_request *req = fsg->ep0req; + int value = -EOPNOTSUPP; + + /* Usually this just stores reply data in the pre-allocated ep0 buffer, + * but config change events will also reconfigure hardware. */ + switch (ctrl->bRequest) { + + case USB_REQ_GET_DESCRIPTOR: + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | + USB_RECIP_DEVICE)) + break; + switch (ctrl->wValue >> 8) { + + case USB_DT_DEVICE: + VDBG(fsg, "get device descriptor\n"); + value = min(ctrl->wLength, (u16) sizeof device_desc); + memcpy(req->buf, &device_desc, value); + break; +#ifdef HIGHSPEED + case USB_DT_DEVICE_QUALIFIER: + VDBG(fsg, "get device qualifier\n"); + 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"); + goto get_config; +#endif /* HIGHSPEED */ + case USB_DT_CONFIG: + VDBG(fsg, "get configuration descriptor\n"); +#ifdef HIGHSPEED + get_config: +#endif /* HIGHSPEED */ + value = populate_config_buf(fsg->gadget->speed, + req->buf, + ctrl->wValue >> 8, + ctrl->wValue & 0xff); + if (value >= 0) + value = min(ctrl->wLength, (u16) value); + break; + + case USB_DT_STRING: + VDBG(fsg, "get string descriptor\n"); + + /* wIndex == language code */ + value = usb_gadget_get_string(&stringtab, + ctrl->wValue & 0xff, req->buf); + if (value >= 0) + value = min(ctrl->wLength, (u16) value); + break; + } + break; + + /* One config, two speeds */ + case USB_REQ_SET_CONFIGURATION: + if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | + USB_RECIP_DEVICE)) + break; + VDBG(fsg, "set configuration\n"); + if (ctrl->wValue == CONFIG_VALUE || ctrl->wValue == 0) { + fsg->new_config = ctrl->wValue; + + /* Raise an exception to wipe out previous transaction + * state (queued bufs, etc) and set the new config. */ + raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); + value = DELAYED_STATUS; + } + break; + case USB_REQ_GET_CONFIGURATION: + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | + USB_RECIP_DEVICE)) + break; + VDBG(fsg, "get configuration\n"); + *(u8 *) req->buf = fsg->config; + value = min(ctrl->wLength, (u16) 1); + break; + + case USB_REQ_SET_INTERFACE: + if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD | + USB_RECIP_INTERFACE)) + break; + if (fsg->config && ctrl->wIndex == 0) { + + /* Raise an exception to wipe out previous transaction + * state (queued bufs, etc) and install the new + * interface altsetting. */ + raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); + value = DELAYED_STATUS; + } + break; + case USB_REQ_GET_INTERFACE: + if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | + USB_RECIP_INTERFACE)) + break; + if (!fsg->config) + break; + if (ctrl->wIndex != 0) { + value = -EDOM; + break; + } + VDBG(fsg, "get interface\n"); + *(u8 *) req->buf = 0; + value = min(ctrl->wLength, (u16) 1); + break; + + default: + VDBG(fsg, + "unknown control req %02x.%02x v%04x i%04x l%u\n", + ctrl->bRequestType, ctrl->bRequest, + ctrl->wValue, ctrl->wIndex, ctrl->wLength); + } + + return value; +} + + +static int fsg_setup(struct usb_gadget *gadget, + const struct usb_ctrlrequest *ctrl) +{ + struct fsg_dev *fsg = get_gadget_data(gadget); + int rc; + + ++fsg->ep0_req_tag; // Record arrival of a new request + fsg->ep0req->context = NULL; + fsg->ep0req->length = 0; + dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); + + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) + rc = class_setup_req(fsg, ctrl); + else + rc = standard_setup_req(fsg, ctrl); + + /* Respond with data/status or defer until later? */ + if (rc >= 0 && rc != DELAYED_STATUS) { + fsg->ep0req->length = rc; + fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? + "ep0-in" : "ep0-out"); + rc = ep0_queue(fsg); + } + + /* Device either stalls (rc < 0) or reports success */ + return rc; +} + + +/*-------------------------------------------------------------------------*/ + +/* All the following routines run in process context */ + + +/* Use this for bulk or interrupt transfers, not ep0 */ +static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, + struct usb_request *req, volatile int *pbusy, + volatile enum fsg_buffer_state *state) +{ + int rc; + + if (ep == fsg->bulk_in) + dump_msg(fsg, "bulk-in", req->buf, req->length); + else if (ep == fsg->intr_in) + dump_msg(fsg, "intr-in", req->buf, req->length); + *pbusy = 1; + *state = BUF_STATE_BUSY; + rc = usb_ep_queue(ep, req, GFP_KERNEL); + if (rc != 0) { + *pbusy = 0; + *state = BUF_STATE_EMPTY; + + /* We can't do much more than wait for a reset */ + + /* Note: currently the net2280 driver fails zero-length + * submissions if DMA is enabled. */ + if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && + req->length == 0)) + WARN(fsg, "error in submission: %s --> %d\n", + ep->name, rc); + } +} + + +static int sleep_thread(struct fsg_dev *fsg) +{ + int rc; + + /* Wait until a signal arrives or we are woken up */ + rc = wait_event_interruptible(fsg->thread_wqh, + fsg->thread_wakeup_needed); + fsg->thread_wakeup_needed = 0; + return (rc ? -EINTR : 0); +} + + +/*-------------------------------------------------------------------------*/ + +static int do_read(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + u32 lba; + struct fsg_buffhd *bh; + int rc; + u32 amount_left; + loff_t file_offset, file_offset_tmp; + unsigned int amount; + unsigned int partial_page; + ssize_t nread; + + /* Get the starting Logical Block Address and check that it's + * not too big */ + if (fsg->cmnd[0] == SC_READ_6) + lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]); + else { + lba = get_be32(&fsg->cmnd[2]); + + /* We allow DPO (Disable Page Out = don't save data in the + * cache) and FUA (Force Unit Access = don't read from the + * cache), but we don't implement them. */ + if ((fsg->cmnd[1] & ~0x18) != 0) { + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + } + if (lba >= curlun->num_sectors) { + curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + return -EINVAL; + } + file_offset = ((loff_t) lba) << 9; + + /* Carry out the file reads */ + amount_left = fsg->data_size_from_cmnd; + if (unlikely(amount_left == 0)) + return -EIO; // No default reply + + for (;;) { + + /* Figure out how much we need to read: + * Try to read the remaining amount. + * But don't read more than the buffer size. + * And don't try to read past the end of the file. + * Finally, if we're not at a page boundary, don't read past + * the next page. + * If this means reading 0 then we were asked to read past + * the end of file. */ + amount = min((unsigned int) amount_left, mod_data.buflen); + amount = min((loff_t) amount, + curlun->file_length - file_offset); + partial_page = file_offset & (PAGE_CACHE_SIZE - 1); + if (partial_page > 0) + amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - + partial_page); + + /* Wait for the next buffer to become available */ + bh = fsg->next_buffhd_to_fill; + while (bh->state != BUF_STATE_EMPTY) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + /* If we were asked to read past the end of file, + * end with an empty buffer. */ + if (amount == 0) { + curlun->sense_data = + SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + curlun->sense_data_info = file_offset >> 9; + bh->inreq->length = 0; + bh->state = BUF_STATE_FULL; + break; + } + + /* Perform the read */ + file_offset_tmp = file_offset; + nread = curlun->filp->f_op->read(curlun->filp, + (char *) bh->buf, + amount, &file_offset_tmp); + VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, + (int) nread); + if (signal_pending(current)) + return -EINTR; + + if (nread < 0) { + LDBG(curlun, "error in file read: %d\n", + (int) nread); + nread = 0; + } else if (nread < amount) { + LDBG(curlun, "partial file read: %d/%u\n", + (int) nread, amount); + nread -= (nread & 511); // Round down to a block + } + file_offset += nread; + amount_left -= nread; + fsg->residue -= nread; + bh->inreq->length = nread; + bh->state = BUF_STATE_FULL; + + /* If an error occurred, report it and its position */ + if (nread < amount) { + curlun->sense_data = SS_UNRECOVERED_READ_ERROR; + curlun->sense_data_info = file_offset >> 9; + break; + } + + if (amount_left == 0) + break; // No more left to read + + /* Send this buffer and go read some more */ + bh->inreq->zero = 0; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + } + + return -EIO; // No default reply +} + + +/*-------------------------------------------------------------------------*/ + +static int do_write(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + u32 lba; + struct fsg_buffhd *bh; + int get_some_more; + u32 amount_left_to_req, amount_left_to_write; + loff_t usb_offset, file_offset, file_offset_tmp; + unsigned int amount; + unsigned int partial_page; + ssize_t nwritten; + int rc; + + if (curlun->ro) { + curlun->sense_data = SS_WRITE_PROTECTED; + return -EINVAL; + } + curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait + + /* Get the starting Logical Block Address and check that it's + * not too big */ + if (fsg->cmnd[0] == SC_WRITE_6) + lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]); + else { + lba = get_be32(&fsg->cmnd[2]); + + /* We allow DPO (Disable Page Out = don't save data in the + * cache) and FUA (Force Unit Access = write directly to the + * medium). We don't implement DPO; we implement FUA by + * performing synchronous output. */ + if ((fsg->cmnd[1] & ~0x18) != 0) { + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + if (fsg->cmnd[1] & 0x08) // FUA + curlun->filp->f_flags |= O_SYNC; + } + if (lba >= curlun->num_sectors) { + curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + return -EINVAL; + } + + /* Carry out the file writes */ + get_some_more = 1; + file_offset = usb_offset = ((loff_t) lba) << 9; + amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; + + while (amount_left_to_write > 0) { + + /* Queue a request for more data from the host */ + bh = fsg->next_buffhd_to_fill; + if (bh->state == BUF_STATE_EMPTY && get_some_more) { + + /* Figure out how much we want to get: + * Try to get the remaining amount. + * But don't get more than the buffer size. + * And don't try to go past the end of the file. + * If we're not at a page boundary, + * don't go past the next page. + * If this means getting 0, then we were asked + * to write past the end of file. + * Finally, round down to a block boundary. */ + amount = min(amount_left_to_req, mod_data.buflen); + amount = min((loff_t) amount, curlun->file_length - + usb_offset); + partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); + if (partial_page > 0) + amount = min(amount, + (unsigned int) PAGE_CACHE_SIZE - partial_page); + + if (amount == 0) { + get_some_more = 0; + curlun->sense_data = + SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + curlun->sense_data_info = usb_offset >> 9; + continue; + } + amount -= (amount & 511); + if (amount == 0) { + + /* Why were we were asked to transfer a + * partial block? */ + get_some_more = 0; + continue; + } + + /* Get the next buffer */ + usb_offset += amount; + fsg->usb_amount_left -= amount; + amount_left_to_req -= amount; + if (amount_left_to_req == 0) + get_some_more = 0; + + /* amount is always divisible by 512, hence by + * the bulk-out maxpacket size */ + bh->outreq->length = bh->bulk_out_intended_length = + amount; + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + continue; + } + + /* Write the received data to the backing file */ + bh = fsg->next_buffhd_to_drain; + if (bh->state == BUF_STATE_EMPTY && !get_some_more) + break; // We stopped early + if (bh->state == BUF_STATE_FULL) { + fsg->next_buffhd_to_drain = bh->next; + bh->state = BUF_STATE_EMPTY; + + /* Did something go wrong with the transfer? */ + if (bh->outreq->status != 0) { + curlun->sense_data = SS_COMMUNICATION_FAILURE; + curlun->sense_data_info = file_offset >> 9; + break; + } + + amount = bh->outreq->actual; + if (curlun->file_length - file_offset < amount) { + LERROR(curlun, + "write %u @ %llu beyond end %llu\n", + amount, (unsigned long long) file_offset, + (unsigned long long) curlun->file_length); + amount = curlun->file_length - file_offset; + } + + /* Perform the write */ + file_offset_tmp = file_offset; + nwritten = curlun->filp->f_op->write(curlun->filp, + (char *) bh->buf, + amount, &file_offset_tmp); + VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, + (int) nwritten); + if (signal_pending(current)) + return -EINTR; // Interrupted! + + if (nwritten < 0) { + LDBG(curlun, "error in file write: %d\n", + (int) nwritten); + nwritten = 0; + } else if (nwritten < amount) { + LDBG(curlun, "partial file write: %d/%u\n", + (int) nwritten, amount); + nwritten -= (nwritten & 511); + // Round down to a block + } + file_offset += nwritten; + amount_left_to_write -= nwritten; + fsg->residue -= nwritten; + + /* If an error occurred, report it and its position */ + if (nwritten < amount) { + curlun->sense_data = SS_WRITE_ERROR; + curlun->sense_data_info = file_offset >> 9; + break; + } + + /* Did the host decide to stop early? */ + if (bh->outreq->actual != bh->outreq->length) { + fsg->short_packet_received = 1; + break; + } + continue; + } + + /* Wait for something to happen */ + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + return -EIO; // No default reply +} + + +/*-------------------------------------------------------------------------*/ + +/* Sync the file data, don't bother with the metadata. + * This code was copied from fs/buffer.c:sys_fdatasync(). */ +static int fsync_sub(struct lun *curlun) +{ + struct file *filp = curlun->filp; + struct inode *inode; + int rc, err; + + if (curlun->ro || !filp) + return 0; + if (!filp->f_op->fsync) + return -EINVAL; + + inode = filp->f_dentry->d_inode; + down(&inode->i_sem); + rc = filemap_fdatasync(inode->i_mapping); + err = filp->f_op->fsync(filp, filp->f_dentry, 1); + if (!rc) + rc = err; + err = filemap_fdatawait(inode->i_mapping); + if (!rc) + rc = err; + up(&inode->i_sem); + VLDBG(curlun, "fdatasync -> %d\n", rc); + return rc; +} + +static void fsync_all(struct fsg_dev *fsg) +{ + int i; + + for (i = 0; i < fsg->nluns; ++i) + fsync_sub(&fsg->luns[i]); +} + +static int do_synchronize_cache(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + int rc; + + /* We ignore the requested LBA and write out all file's + * dirty data buffers. */ + rc = fsync_sub(curlun); + if (rc) + curlun->sense_data = SS_WRITE_ERROR; + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +static void invalidate_sub(struct lun *curlun) +{ + struct file *filp = curlun->filp; + struct inode *inode = filp->f_dentry->d_inode; + + invalidate_inode_pages(inode); +} + +static int do_verify(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + u32 lba; + u32 verification_length; + struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + loff_t file_offset, file_offset_tmp; + u32 amount_left; + unsigned int amount; + ssize_t nread; + + /* Get the starting Logical Block Address and check that it's + * not too big */ + lba = get_be32(&fsg->cmnd[2]); + if (lba >= curlun->num_sectors) { + curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + return -EINVAL; + } + + /* We allow DPO (Disable Page Out = don't save data in the + * cache) but we don't implement it. */ + if ((fsg->cmnd[1] & ~0x10) != 0) { + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + + verification_length = get_be16(&fsg->cmnd[7]); + if (unlikely(verification_length == 0)) + return -EIO; // No default reply + + /* Prepare to carry out the file verify */ + amount_left = verification_length << 9; + file_offset = ((loff_t) lba) << 9; + + /* Write out all the dirty buffers before invalidating them */ + fsync_sub(curlun); + if (signal_pending(current)) + return -EINTR; + + invalidate_sub(curlun); + if (signal_pending(current)) + return -EINTR; + + /* Just try to read the requested blocks */ + while (amount_left > 0) { + + /* Figure out how much we need to read: + * Try to read the remaining amount, but not more than + * the buffer size. + * And don't try to read past the end of the file. + * If this means reading 0 then we were asked to read + * past the end of file. */ + amount = min((unsigned int) amount_left, mod_data.buflen); + amount = min((loff_t) amount, + curlun->file_length - file_offset); + if (amount == 0) { + curlun->sense_data = + SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + curlun->sense_data_info = file_offset >> 9; + break; + } + + /* Perform the read */ + file_offset_tmp = file_offset; + nread = curlun->filp->f_op->read(curlun->filp, + (char *) bh->buf, + amount, &file_offset_tmp); + VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, + (int) nread); + if (signal_pending(current)) + return -EINTR; + + if (nread < 0) { + LDBG(curlun, "error in file verify: %d\n", + (int) nread); + nread = 0; + } else if (nread < amount) { + LDBG(curlun, "partial file verify: %d/%u\n", + (int) nread, amount); + nread -= (nread & 511); // Round down to a sector + } + if (nread == 0) { + curlun->sense_data = SS_UNRECOVERED_READ_ERROR; + curlun->sense_data_info = file_offset >> 9; + break; + } + file_offset += nread; + amount_left -= nread; + } + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + u8 *buf = (u8 *) bh->buf; + + static char vendor_id[] = "Linux "; + static char product_id[] = "File-Stor Gadget"; + + if (!fsg->curlun) { // Unsupported LUNs are okay + fsg->bad_lun_okay = 1; + memset(buf, 0, 36); + buf[0] = 0x7f; // Unsupported, no device-type + return 36; + } + + memset(buf, 0, 8); // Non-removable, direct-access device + if (mod_data.removable) + buf[1] = 0x80; + buf[2] = 2; // ANSI SCSI level 2 + buf[3] = 2; // SCSI-2 INQUIRY data format + buf[4] = 31; // Additional length + // No special options + sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id, + DRIVER_VERSION_NUM); + return 36; +} + + +static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + struct lun *curlun = fsg->curlun; + u8 *buf = (u8 *) bh->buf; + u32 sd, sdinfo; + + /* + * From the SCSI-2 spec., section 7.9 (Unit attention condition): + * + * If a REQUEST SENSE command is received from an initiator + * with a pending unit attention condition (before the target + * generates the contingent allegiance condition), then the + * target shall either: + * a) report any pending sense data and preserve the unit + * attention condition on the logical unit, or, + * b) report the unit attention condition, may discard any + * pending sense data, and clear the unit attention + * condition on the logical unit for that initiator. + * + * FSG normally uses option a); enable this code to use option b). + */ +#if 0 + if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { + curlun->sense_data = curlun->unit_attention_data; + curlun->unit_attention_data = SS_NO_SENSE; + } +#endif + + if (!curlun) { // Unsupported LUNs are okay + fsg->bad_lun_okay = 1; + sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; + sdinfo = 0; + } else { + sd = curlun->sense_data; + sdinfo = curlun->sense_data_info; + curlun->sense_data = SS_NO_SENSE; + curlun->sense_data_info = 0; + } + + memset(buf, 0, 18); + 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[12] = ASC(sd); + buf[13] = ASCQ(sd); + return 18; +} + + +static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + struct lun *curlun = fsg->curlun; + u32 lba = get_be32(&fsg->cmnd[2]); + int pmi = fsg->cmnd[8]; + u8 *buf = (u8 *) bh->buf; + + /* Check the PMI and LBA fields */ + if (pmi > 1 || (pmi == 0 && lba != 0)) { + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + + put_be32(&buf[0], curlun->num_sectors - 1); // Max logical block + put_be32(&buf[4], 512); // Block length + return 8; +} + + +static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + struct lun *curlun = fsg->curlun; + int mscmnd = fsg->cmnd[0]; + u8 *buf = (u8 *) bh->buf; + u8 *buf0 = buf; + int pc, page_code; + int changeable_values, all_pages; + int valid_page = 0; + int len, limit; + + if ((fsg->cmnd[1] & ~0x08) != 0) { // Mask away DBD + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + pc = fsg->cmnd[2] >> 6; + page_code = fsg->cmnd[2] & 0x3f; + if (pc == 3) { + curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; + return -EINVAL; + } + changeable_values = (pc == 1); + all_pages = (page_code == 0x3f); + + /* Write the mode parameter header. Fixed values are: default + * medium type, no cache control (DPOFUA), and no block descriptors. + * The only variable value is the WriteProtect bit. We will fill in + * the mode data length later. */ + memset(buf, 0, 8); + if (mscmnd == SC_MODE_SENSE_6) { + buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA + buf += 4; + limit = 255; + } else { // SC_MODE_SENSE_10 + buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA + buf += 8; + limit = 65535; // Should really be mod_data.buflen + } + + /* No block descriptors */ + + /* The mode pages, in numerical order. The only page we support + * is the Caching page. */ + if (page_code == 0x08 || all_pages) { + valid_page = 1; + buf[0] = 0x08; // Page code + buf[1] = 10; // Page length + memset(buf+2, 0, 10); // None of the fields are changeable + + if (!changeable_values) { + buf[2] = 0x04; // Write cache enable, + // Read cache not disabled + // No cache retention priorities + put_be16(&buf[4], 0xffff); // Don't disable prefetch + // Minimum prefetch = 0 + put_be16(&buf[8], 0xffff); // Maximum prefetch + put_be16(&buf[10], 0xffff); // Maximum prefetch ceiling + } + buf += 12; + } + + /* Check that a valid page was requested and the mode data length + * isn't too long. */ + len = buf - buf0; + if (!valid_page || len > limit) { + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + + /* Store the mode data length */ + if (mscmnd == SC_MODE_SENSE_6) + buf0[0] = len - 1; + else + put_be16(buf0, len - 2); + return len; +} + + +static int do_start_stop(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + int loej, start; + + if (!mod_data.removable) { + curlun->sense_data = SS_INVALID_COMMAND; + return -EINVAL; + } + + // int immed = fsg->cmnd[1] & 0x01; + loej = fsg->cmnd[4] & 0x02; + start = fsg->cmnd[4] & 0x01; + +#ifdef CONFIG_USB_FILE_STORAGE_TEST + if ((fsg->cmnd[1] & ~0x01) != 0 || // Mask away Immed + (fsg->cmnd[4] & ~0x03) != 0) { // Mask LoEj, Start + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + + if (!start) { + + /* Are we allowed to unload the media? */ + if (curlun->prevent_medium_removal) { + LDBG(curlun, "unload attempt prevented\n"); + curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; + return -EINVAL; + } + if (loej) { // Simulate an unload/eject + up_read(&fsg->filesem); + down_write(&fsg->filesem); + close_backing_file(curlun); + up_write(&fsg->filesem); + down_read(&fsg->filesem); + } + } else { + + /* Our emulation doesn't support mounting; the medium is + * available for use as soon as it is loaded. */ + if (!backing_file_is_open(curlun)) { + curlun->sense_data = SS_MEDIUM_NOT_PRESENT; + return -EINVAL; + } + } +#endif + return 0; +} + + +static int do_prevent_allow(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + int prevent; + + if (!mod_data.removable) { + curlun->sense_data = SS_INVALID_COMMAND; + return -EINVAL; + } + + prevent = fsg->cmnd[4] & 0x01; + if ((fsg->cmnd[4] & ~0x01) != 0) { // Mask away Prevent + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + + if (curlun->prevent_medium_removal && !prevent) + fsync_sub(curlun); + curlun->prevent_medium_removal = prevent; + return 0; +} + + +static int do_read_format_capacities(struct fsg_dev *fsg, + struct fsg_buffhd *bh) +{ + struct lun *curlun = fsg->curlun; + u8 *buf = (u8 *) bh->buf; + + buf[0] = buf[1] = buf[2] = 0; + buf[3] = 8; // Only the Current/Maximum Capacity Descriptor + buf += 4; + + put_be32(&buf[0], curlun->num_sectors); // Number of blocks + put_be32(&buf[4], 512); // Block length + buf[4] = 0x02; // Current capacity + return 12; +} + + +static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + struct lun *curlun = fsg->curlun; + + /* We don't support MODE SELECT */ + curlun->sense_data = SS_INVALID_COMMAND; + return -EINVAL; +} + + +/*-------------------------------------------------------------------------*/ + +static int halt_bulk_in_endpoint(struct fsg_dev *fsg) +{ + int rc; + + rc = fsg_set_halt(fsg, fsg->bulk_in); + if (rc == -EAGAIN) + VDBG(fsg, "delayed bulk-in endpoint halt\n"); + while (rc != 0) { + if (rc != -EAGAIN) { + WARN(fsg, "usb_ep_set_halt -> %d\n", rc); + rc = 0; + break; + } + + /* Wait for a short time and then try again */ + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(HZ / 10) != 0) + return -EINTR; + rc = usb_ep_set_halt(fsg->bulk_in); + } + return rc; +} + +static int pad_with_zeros(struct fsg_dev *fsg) +{ + struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + u32 nkeep = bh->inreq->length; + u32 nsend; + int rc; + + bh->state = BUF_STATE_EMPTY; // For the first iteration + fsg->usb_amount_left = nkeep + fsg->residue; + while (fsg->usb_amount_left > 0) { + + /* Wait for the next buffer to be free */ + while (bh->state != BUF_STATE_EMPTY) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + nsend = min(fsg->usb_amount_left, (u32) mod_data.buflen); + memset(bh->buf + nkeep, 0, nsend - nkeep); + bh->inreq->length = nsend; + bh->inreq->zero = 0; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + bh = fsg->next_buffhd_to_fill = bh->next; + fsg->usb_amount_left -= nsend; + nkeep = 0; + } + return 0; +} + +static int throw_away_data(struct fsg_dev *fsg) +{ + struct fsg_buffhd *bh; + u32 amount; + int rc; + + while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY || + fsg->usb_amount_left > 0) { + + /* Throw away the data in a filled buffer */ + if (bh->state == BUF_STATE_FULL) { + bh->state = BUF_STATE_EMPTY; + fsg->next_buffhd_to_drain = bh->next; + + /* A short packet or an error ends everything */ + if (bh->outreq->actual != bh->outreq->length || + bh->outreq->status != 0) { + raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + return -EINTR; + } + continue; + } + + /* Try to submit another request if we need one */ + bh = fsg->next_buffhd_to_fill; + if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) { + amount = min(fsg->usb_amount_left, + (u32) mod_data.buflen); + + /* amount is always divisible by 512, hence by + * the bulk-out maxpacket size */ + bh->outreq->length = bh->bulk_out_intended_length = + amount; + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + fsg->usb_amount_left -= amount; + continue; + } + + /* Otherwise wait for something to happen */ + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + return 0; +} + + +static int finish_reply(struct fsg_dev *fsg) +{ + struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; + int rc = 0; + + switch (fsg->data_dir) { + case DATA_DIR_NONE: + break; // Nothing to send + + /* If we don't know whether the host wants to read or write, + * this must be CB or CBI with an unknown command. We mustn't + * try to send or receive any data. So stall both bulk pipes + * if we can and wait for a reset. */ + case DATA_DIR_UNKNOWN: + if (mod_data.can_stall) { + fsg_set_halt(fsg, fsg->bulk_out); + rc = halt_bulk_in_endpoint(fsg); + } + break; + + /* All but the last buffer of data must have already been sent */ + case DATA_DIR_TO_HOST: + if (fsg->data_size == 0) + ; // Nothing to send + + /* If there's no residue, simply send the last buffer */ + else if (fsg->residue == 0) { + bh->inreq->zero = 0; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + } + + /* There is a residue. For CB and CBI, simply mark the end + * of the data with a short packet. However, if we are + * allowed to stall, there was no data at all (residue == + * data_size), and the command failed (invalid LUN or + * sense data is set), then halt the bulk-in endpoint + * instead. */ + else if (!transport_is_bbb()) { + if (mod_data.can_stall && + fsg->residue == fsg->data_size && + (!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) { + bh->state = BUF_STATE_EMPTY; + rc = halt_bulk_in_endpoint(fsg); + } else { + bh->inreq->zero = 1; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + } + } + + /* For Bulk-only, if we're allowed to stall then send the + * short packet and halt the bulk-in endpoint. If we can't + * stall, pad out the remaining data with 0's. */ + else { + if (mod_data.can_stall) { + bh->inreq->zero = 1; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + rc = halt_bulk_in_endpoint(fsg); + } else + rc = pad_with_zeros(fsg); + } + break; + + /* We have processed all we want from the data the host has sent. + * There may still be outstanding bulk-out requests. */ + case DATA_DIR_FROM_HOST: + if (fsg->residue == 0) + ; // Nothing to receive + + /* Did the host stop sending unexpectedly early? */ + else if (fsg->short_packet_received) { + raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + rc = -EINTR; + } + + /* We haven't processed all the incoming data. If we are + * allowed to stall, halt the bulk-out endpoint and cancel + * any outstanding requests. */ + else if (mod_data.can_stall) { + fsg_set_halt(fsg, fsg->bulk_out); + raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); + rc = -EINTR; + } + + /* We can't stall. Read in the excess data and throw it + * all away. */ + else + rc = throw_away_data(fsg); + break; + } + return rc; +} + + +static int send_status(struct fsg_dev *fsg) +{ + struct lun *curlun = fsg->curlun; + struct fsg_buffhd *bh; + int rc; + u8 status = USB_STATUS_PASS; + u32 sd, sdinfo = 0; + + /* Wait for the next buffer to become available */ + bh = fsg->next_buffhd_to_fill; + while (bh->state != BUF_STATE_EMPTY) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + if (curlun) { + sd = curlun->sense_data; + sdinfo = curlun->sense_data_info; + } else if (fsg->bad_lun_okay) + sd = SS_NO_SENSE; + else + sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; + + if (fsg->phase_error) { + DBG(fsg, "sending phase-error status\n"); + status = USB_STATUS_PHASE_ERROR; + sd = SS_INVALID_COMMAND; + } else if (sd != SS_NO_SENSE) { + DBG(fsg, "sending command-failure status\n"); + status = USB_STATUS_FAIL; + VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" + " info x%x\n", + SK(sd), ASC(sd), ASCQ(sd), sdinfo); + } + + if (transport_is_bbb()) { + struct bulk_cs_wrap *csw = (struct bulk_cs_wrap *) bh->buf; + + /* 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->Status = status; + + bh->inreq->length = USB_BULK_CS_WRAP_LEN; + bh->inreq->zero = 0; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + + } else if (mod_data.transport_type == USB_PR_CB) { + + /* Control-Bulk transport has no status stage! */ + return 0; + + } else { // USB_PR_CBI + struct interrupt_data *buf = (struct interrupt_data *) + bh->buf; + + /* Store and send the Interrupt data. UFI sends the ASC + * and ASCQ bytes. Everything else sends a Type (which + * is always 0) and the status Value. */ + if (mod_data.protocol_type == USB_SC_UFI) { + buf->bType = ASC(sd); + buf->bValue = ASCQ(sd); + } else { + buf->bType = 0; + buf->bValue = status; + } + fsg->intreq->length = CBI_INTERRUPT_DATA_LEN; + + fsg->intr_buffhd = bh; // Point to the right buffhd + fsg->intreq->buf = bh->inreq->buf; + fsg->intreq->dma = bh->inreq->dma; + fsg->intreq->context = bh; + start_transfer(fsg, fsg->intr_in, fsg->intreq, + &fsg->intreq_busy, &bh->state); + } + + fsg->next_buffhd_to_fill = bh->next; + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +/* Check whether the command is properly formed and whether its data size + * and direction agree with the values we already have. */ +static int check_command(struct fsg_dev *fsg, int cmnd_size, + enum data_direction data_dir, unsigned int mask, + int needs_medium, const char *name) +{ + int i; + int lun = fsg->cmnd[1] >> 5; + static const char dirletter[4] = {'u', 'o', 'i', 'n'}; + char hdlen[20]; + struct lun *curlun; + + /* Adjust the expected cmnd_size for protocol encapsulation padding. + * Transparent SCSI doesn't pad. */ + if (protocol_is_scsi()) + ; + + /* There's some disagreement as to whether RBC pads commands or not. + * We'll play it safe and accept either form. */ + else if (mod_data.protocol_type == USB_SC_RBC) { + if (fsg->cmnd_size == 12) + cmnd_size = 12; + + /* All the other protocols pad to 12 bytes */ + } else + cmnd_size = 12; + + hdlen[0] = 0; + if (fsg->data_dir != DATA_DIR_UNKNOWN) + sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir], + fsg->data_size); + VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", + name, cmnd_size, dirletter[(int) data_dir], + fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); + + /* We can't reply at all until we know the correct data direction + * and size. */ + if (fsg->data_size_from_cmnd == 0) + data_dir = DATA_DIR_NONE; + if (fsg->data_dir == DATA_DIR_UNKNOWN) { // CB or CBI + fsg->data_dir = data_dir; + fsg->data_size = fsg->data_size_from_cmnd; + + } else { // Bulk-only + if (fsg->data_size < fsg->data_size_from_cmnd) { + + /* Host data size < Device data size is a phase error. + * Carry out the command, but only transfer as much + * as we are allowed. */ + fsg->data_size_from_cmnd = fsg->data_size; + fsg->phase_error = 1; + } + } + fsg->residue = fsg->usb_amount_left = fsg->data_size; + + /* Conflicting data directions is a phase error */ + if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) + goto phase_error; + + /* Verify the length of the command itself */ + if (cmnd_size != fsg->cmnd_size) { + + /* Special case workaround: MS-Windows issues REQUEST SENSE + * with cbw->Length == 12 (it should be 6). */ + if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12) + cmnd_size = fsg->cmnd_size; + else + goto phase_error; + } + + /* Check that the LUN values are oonsistent */ + if (transport_is_bbb()) { + if (fsg->lun != lun) + DBG(fsg, "using LUN %d from CBW, " + "not LUN %d from CDB\n", + fsg->lun, lun); + } else + fsg->lun = lun; // Use LUN from the command + + /* Check the LUN */ + if (fsg->lun >= 0 && fsg->lun < fsg->nluns) { + fsg->curlun = curlun = &fsg->luns[fsg->lun]; + if (fsg->cmnd[0] != SC_REQUEST_SENSE) { + curlun->sense_data = SS_NO_SENSE; + curlun->sense_data_info = 0; + } + } else { + fsg->curlun = curlun = NULL; + fsg->bad_lun_okay = 0; + + /* INQUIRY and REQUEST SENSE commands are explicitly allowed + * to use unsupported LUNs; all others may not. */ + if (fsg->cmnd[0] != SC_INQUIRY && + fsg->cmnd[0] != SC_REQUEST_SENSE) { + DBG(fsg, "unsupported LUN %d\n", fsg->lun); + return -EINVAL; + } + } + + /* If a unit attention condition exists, only INQUIRY and + * REQUEST SENSE commands are allowed; anything else must fail. */ + if (curlun && curlun->unit_attention_data != SS_NO_SENSE && + fsg->cmnd[0] != SC_INQUIRY && + fsg->cmnd[0] != SC_REQUEST_SENSE) { + curlun->sense_data = curlun->unit_attention_data; + curlun->unit_attention_data = SS_NO_SENSE; + return -EINVAL; + } + + /* Check that only command bytes listed in the mask are non-zero */ + fsg->cmnd[1] &= 0x1f; // Mask away the LUN + for (i = 1; i < cmnd_size; ++i) { + if (fsg->cmnd[i] && !(mask & (1 << i))) { + if (curlun) + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; + return -EINVAL; + } + } + + /* If the medium isn't mounted and the command needs to access + * it, return an error. */ + if (curlun && !backing_file_is_open(curlun) && needs_medium) { + curlun->sense_data = SS_MEDIUM_NOT_PRESENT; + return -EINVAL; + } + + return 0; + +phase_error: + fsg->phase_error = 1; + return -EINVAL; +} + + +static int do_scsi_command(struct fsg_dev *fsg) +{ + struct fsg_buffhd *bh; + int rc; + int reply = -EINVAL; + int i; + static char unknown[16]; + + dump_cdb(fsg); + + /* Wait for the next buffer to become available for data or status */ + bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; + while (bh->state != BUF_STATE_EMPTY) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + fsg->phase_error = 0; + fsg->short_packet_received = 0; + + down_read(&fsg->filesem); // We're using the backing file + switch (fsg->cmnd[0]) { + + case SC_INQUIRY: + fsg->data_size_from_cmnd = fsg->cmnd[4]; + if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, + (1<<4), 0, + "INQUIRY")) == 0) + reply = do_inquiry(fsg, bh); + break; + + case SC_MODE_SELECT_6: + fsg->data_size_from_cmnd = fsg->cmnd[4]; + if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, + (1<<1) | (1<<4), 0, + "MODE SELECT(6)")) == 0) + reply = do_mode_select(fsg, bh); + break; + + case SC_MODE_SELECT_10: + fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); + if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, + (1<<1) | (3<<7), 0, + "MODE SELECT(10)")) == 0) + reply = do_mode_select(fsg, bh); + break; + + case SC_MODE_SENSE_6: + fsg->data_size_from_cmnd = fsg->cmnd[4]; + if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, + (1<<1) | (1<<2) | (1<<4), 0, + "MODE SENSE(6)")) == 0) + reply = do_mode_sense(fsg, bh); + break; + + case SC_MODE_SENSE_10: + fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); + if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, + (1<<1) | (1<<2) | (3<<7), 0, + "MODE SENSE(10)")) == 0) + reply = do_mode_sense(fsg, bh); + break; + + case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: + fsg->data_size_from_cmnd = 0; + if ((reply = check_command(fsg, 6, DATA_DIR_NONE, + (1<<4), 0, + "PREVENT-ALLOW MEDIUM REMOVAL")) == 0) + reply = do_prevent_allow(fsg); + break; + + case SC_READ_6: + i = fsg->cmnd[4]; + fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; + if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, + (7<<1) | (1<<4), 1, + "READ(6)")) == 0) + reply = do_read(fsg); + break; + + case SC_READ_10: + fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9; + if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, + (1<<1) | (0xf<<2) | (3<<7), 1, + "READ(10)")) == 0) + reply = do_read(fsg); + break; + + case SC_READ_12: + fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9; + if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, + (1<<1) | (0xf<<2) | (0xf<<6), 1, + "READ(12)")) == 0) + reply = do_read(fsg); + break; + + case SC_READ_CAPACITY: + fsg->data_size_from_cmnd = 8; + if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, + (0xf<<2) | (1<<8), 1, + "READ CAPACITY")) == 0) + reply = do_read_capacity(fsg, bh); + break; + + case SC_READ_FORMAT_CAPACITIES: + fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); + if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, + (3<<7), 1, + "READ FORMAT CAPACITIES")) == 0) + reply = do_read_format_capacities(fsg, bh); + break; + + case SC_REQUEST_SENSE: + fsg->data_size_from_cmnd = fsg->cmnd[4]; + if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, + (1<<4), 0, + "REQUEST SENSE")) == 0) + reply = do_request_sense(fsg, bh); + break; + + case SC_START_STOP_UNIT: + fsg->data_size_from_cmnd = 0; + if ((reply = check_command(fsg, 6, DATA_DIR_NONE, + (1<<1) | (1<<4), 0, + "START-STOP UNIT")) == 0) + reply = do_start_stop(fsg); + break; + + case SC_SYNCHRONIZE_CACHE: + fsg->data_size_from_cmnd = 0; + if ((reply = check_command(fsg, 10, DATA_DIR_NONE, + (0xf<<2) | (3<<7), 1, + "SYNCHRONIZE CACHE")) == 0) + reply = do_synchronize_cache(fsg); + break; + + case SC_TEST_UNIT_READY: + fsg->data_size_from_cmnd = 0; + reply = check_command(fsg, 6, DATA_DIR_NONE, + 0, 1, + "TEST UNIT READY"); + break; + + /* Although optional, this command is used by MS-Windows. We + * support a minimal version: BytChk must be 0. */ + case SC_VERIFY: + fsg->data_size_from_cmnd = 0; + if ((reply = check_command(fsg, 10, DATA_DIR_NONE, + (1<<1) | (0xf<<2) | (3<<7), 1, + "VERIFY")) == 0) + reply = do_verify(fsg); + break; + + case SC_WRITE_6: + i = fsg->cmnd[4]; + fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; + if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, + (7<<1) | (1<<4), 1, + "WRITE(6)")) == 0) + reply = do_write(fsg); + break; + + case SC_WRITE_10: + fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9; + if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, + (1<<1) | (0xf<<2) | (3<<7), 1, + "WRITE(10)")) == 0) + reply = do_write(fsg); + break; + + case SC_WRITE_12: + fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9; + if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, + (1<<1) | (0xf<<2) | (0xf<<6), 1, + "WRITE(12)")) == 0) + reply = do_write(fsg); + break; + + /* Some mandatory commands that we recognize but don't implement. + * They don't mean much in this setting. It's left as an exercise + * for anyone interested to implement RESERVE and RELEASE in terms + * of Posix locks. */ + case SC_FORMAT_UNIT: + case SC_RELEASE: + case SC_RESERVE: + case SC_SEND_DIAGNOSTIC: + // Fall through + + default: + fsg->data_size_from_cmnd = 0; + sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); + if ((reply = check_command(fsg, fsg->cmnd_size, + DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { + fsg->curlun->sense_data = SS_INVALID_COMMAND; + reply = -EINVAL; + } + break; + } + up_read(&fsg->filesem); + + if (reply == -EINTR || signal_pending(current)) + return -EINTR; + + /* Set up the single reply buffer for finish_reply() */ + if (reply == -EINVAL) + reply = 0; // Error reply length + if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) { + reply = min((u32) reply, fsg->data_size_from_cmnd); + bh->inreq->length = reply; + bh->state = BUF_STATE_FULL; + fsg->residue -= reply; + } // Otherwise it's already set + + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) +{ + struct usb_request *req = bh->outreq; + struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *) req->buf; + + /* Was this a real packet? */ + if (req->status) + return -EINVAL; + + /* Is the CBW valid? */ + if (req->actual != USB_BULK_CB_WRAP_LEN || + cbw->Signature != __constant_cpu_to_le32( + USB_BULK_CB_SIG)) { + DBG(fsg, "invalid CBW: len %u sig 0x%x\n", + req->actual, + le32_to_cpu(cbw->Signature)); + + /* The Bulk-only spec says we MUST stall the bulk pipes! + * If we want to avoid stalls, set a flag so that we will + * clear the endpoint halts at the next reset. */ + if (!mod_data.can_stall) + set_bit(CLEAR_BULK_HALTS, &fsg->atomic_bitflags); + fsg_set_halt(fsg, fsg->bulk_out); + halt_bulk_in_endpoint(fsg); + return -EINVAL; + } + + /* Is the CBW meaningful? */ + if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || + cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) { + DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " + "cmdlen %u\n", + cbw->Lun, cbw->Flags, cbw->Length); + + /* We can do anything we want here, so let's stall the + * bulk pipes if we are allowed to. */ + if (mod_data.can_stall) { + fsg_set_halt(fsg, fsg->bulk_out); + halt_bulk_in_endpoint(fsg); + } + return -EINVAL; + } + + /* Save the command for later */ + fsg->cmnd_size = cbw->Length; + memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size); + if (cbw->Flags & USB_BULK_IN_FLAG) + fsg->data_dir = DATA_DIR_TO_HOST; + else + fsg->data_dir = DATA_DIR_FROM_HOST; + fsg->data_size = cbw->DataTransferLength; + if (fsg->data_size == 0) + fsg->data_dir = DATA_DIR_NONE; + fsg->lun = cbw->Lun; + fsg->tag = cbw->Tag; + return 0; +} + + +static int get_next_command(struct fsg_dev *fsg) +{ + struct fsg_buffhd *bh; + int rc = 0; + + if (transport_is_bbb()) { + + /* Wait for the next buffer to become available */ + bh = fsg->next_buffhd_to_fill; + while (bh->state != BUF_STATE_EMPTY) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + /* Queue a request to read a Bulk-only CBW */ + set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + + /* We will drain the buffer in software, which means we + * can reuse it for the next filling. No need to advance + * next_buffhd_to_fill. */ + + /* Wait for the CBW to arrive */ + while (bh->state != BUF_STATE_FULL) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + rc = received_cbw(fsg, bh); + bh->state = BUF_STATE_EMPTY; + + } else { // USB_PR_CB or USB_PR_CBI + + /* Wait for the next command to arrive */ + while (fsg->cbbuf_cmnd_size == 0) { + if ((rc = sleep_thread(fsg)) != 0) + return rc; + } + + /* Is the previous status interrupt request still busy? + * The host is allowed to skip reading the status, + * so we must cancel it. */ + if (fsg->intreq_busy) + usb_ep_dequeue(fsg->intr_in, fsg->intreq); + + /* Copy the command and mark the buffer empty */ + fsg->data_dir = DATA_DIR_UNKNOWN; + spin_lock_irq(&fsg->lock); + fsg->cmnd_size = fsg->cbbuf_cmnd_size; + memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); + fsg->cbbuf_cmnd_size = 0; + spin_unlock_irq(&fsg->lock); + } + return rc; +} + + +/*-------------------------------------------------------------------------*/ + +static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep, + const struct usb_endpoint_descriptor *d) +{ + int rc; + + ep->driver_data = fsg; + rc = usb_ep_enable(ep, d); + if (rc) + ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); + return rc; +} + +static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep, + struct usb_request **preq) +{ + *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (*preq) + return 0; + ERROR(fsg, "can't allocate request for %s\n", ep->name); + return -ENOMEM; +} + +/* + * Reset interface setting and re-init endpoint state (toggle etc). + * Call with altsetting < 0 to disable the interface. The only other + * available altsetting is 0, which enables the interface. + */ +static int do_set_interface(struct fsg_dev *fsg, int altsetting) +{ + int rc = 0; + int i; + const struct usb_endpoint_descriptor *d; + + if (fsg->running) + DBG(fsg, "reset interface\n"); + +reset: + /* Deallocate the requests */ + for (i = 0; i < NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &fsg->buffhds[i]; + + if (bh->inreq) { + usb_ep_free_request(fsg->bulk_in, bh->inreq); + bh->inreq = NULL; + } + if (bh->outreq) { + usb_ep_free_request(fsg->bulk_out, bh->outreq); + bh->outreq = NULL; + } + } + if (fsg->intreq) { + usb_ep_free_request(fsg->intr_in, fsg->intreq); + fsg->intreq = NULL; + } + + /* Disable the endpoints */ + if (fsg->bulk_in_enabled) { + usb_ep_disable(fsg->bulk_in); + fsg->bulk_in_enabled = 0; + } + if (fsg->bulk_out_enabled) { + usb_ep_disable(fsg->bulk_out); + fsg->bulk_out_enabled = 0; + } + if (fsg->intr_in_enabled) { + usb_ep_disable(fsg->intr_in); + fsg->intr_in_enabled = 0; + } + + fsg->running = 0; + if (altsetting < 0 || rc != 0) + return rc; + + DBG(fsg, "set interface %d\n", altsetting); + + /* Enable the endpoints */ + d = ep_desc(fsg->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc); + if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) + goto reset; + fsg->bulk_in_enabled = 1; + + d = ep_desc(fsg->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc); + if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) + goto reset; + fsg->bulk_out_enabled = 1; + + if (transport_is_cbi()) { + d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc); + if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) + goto reset; + fsg->intr_in_enabled = 1; + } + + /* Allocate the requests */ + for (i = 0; i < NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &fsg->buffhds[i]; + + if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) + goto reset; + if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) + goto reset; + bh->inreq->buf = bh->outreq->buf = bh->buf; + bh->inreq->dma = bh->outreq->dma = bh->dma; + bh->inreq->context = bh->outreq->context = bh; + bh->inreq->complete = bulk_in_complete; + bh->outreq->complete = bulk_out_complete; + } + if (transport_is_cbi()) { + if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0) + goto reset; + fsg->intreq->complete = intr_in_complete; + } + + fsg->running = 1; + for (i = 0; i < fsg->nluns; ++i) + fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; + return rc; +} + + +/* + * Change our operational configuration. This code must agree with the code + * that returns config descriptors, and with interface altsetting code. + * + * It's also responsible for power management interactions. Some + * configurations might not work with our current power sources. + * For now we just assume the gadget is always self-powered. + */ +static int do_set_config(struct fsg_dev *fsg, u8 new_config) +{ + int rc = 0; + + /* Disable the single interface */ + if (fsg->config != 0) { + DBG(fsg, "reset config\n"); + fsg->config = 0; + rc = do_set_interface(fsg, -1); + } + + /* Enable the interface */ + if (new_config != 0) { + fsg->config = new_config; + if ((rc = do_set_interface(fsg, 0)) != 0) + fsg->config = 0; // Reset on errors + else { + char *speed; + + switch (fsg->gadget->speed) { + case USB_SPEED_LOW: speed = "low"; break; + case USB_SPEED_FULL: speed = "full"; break; + case USB_SPEED_HIGH: speed = "high"; break; + default: speed = "?"; break; + } + INFO(fsg, "%s speed config #%d\n", speed, fsg->config); + } + } + return rc; +} + + +/*-------------------------------------------------------------------------*/ + +static void handle_exception(struct fsg_dev *fsg) +{ + siginfo_t info; + int sig; + int i; + int num_active; + struct fsg_buffhd *bh; + enum fsg_state old_state; + u8 new_config; + struct lun *curlun; + unsigned int exception_req_tag; + int rc; + + /* Clear the existing signals. Anything but SIGUSR1 is converted + * into a high-priority EXIT exception. */ + for (;;) { + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&fsg->thread_signal_mask, &info); + spin_unlock_irq(¤t->sigmask_lock); + if (!sig) + break; + if (sig != SIGUSR1) { + if (fsg->state < FSG_STATE_EXIT) + DBG(fsg, "Main thread exiting on signal\n"); + raise_exception(fsg, FSG_STATE_EXIT); + } + } + + /* Cancel all the pending transfers */ + if (fsg->intreq_busy) + usb_ep_dequeue(fsg->intr_in, fsg->intreq); + for (i = 0; i < NUM_BUFFERS; ++i) { + bh = &fsg->buffhds[i]; + if (bh->inreq_busy) + usb_ep_dequeue(fsg->bulk_in, bh->inreq); + if (bh->outreq_busy) + usb_ep_dequeue(fsg->bulk_out, bh->outreq); + } + + /* Wait until everything is idle */ + for (;;) { + num_active = fsg->intreq_busy; + for (i = 0; i < NUM_BUFFERS; ++i) { + bh = &fsg->buffhds[i]; + num_active += bh->inreq_busy + bh->outreq_busy; + } + if (num_active == 0) + break; + if (sleep_thread(fsg)) + return; + } + + /* Clear out the controller's fifos */ + if (fsg->bulk_in_enabled) + usb_ep_fifo_flush(fsg->bulk_in); + if (fsg->bulk_out_enabled) + usb_ep_fifo_flush(fsg->bulk_out); + if (fsg->intr_in_enabled) + usb_ep_fifo_flush(fsg->intr_in); + + /* Reset the I/O buffer states and pointers, the SCSI + * state, and the exception. Then invoke the handler. */ + spin_lock_irq(&fsg->lock); + + for (i = 0; i < NUM_BUFFERS; ++i) { + bh = &fsg->buffhds[i]; + bh->state = BUF_STATE_EMPTY; + } + fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain = + &fsg->buffhds[0]; + + exception_req_tag = fsg->exception_req_tag; + new_config = fsg->new_config; + old_state = fsg->state; + + if (old_state == FSG_STATE_ABORT_BULK_OUT) + fsg->state = FSG_STATE_STATUS_PHASE; + else { + for (i = 0; i < fsg->nluns; ++i) { + curlun = &fsg->luns[i]; + curlun->prevent_medium_removal = 0; + curlun->sense_data = curlun->unit_attention_data = + SS_NO_SENSE; + curlun->sense_data_info = 0; + } + fsg->state = FSG_STATE_IDLE; + } + spin_unlock_irq(&fsg->lock); + + /* Carry out any extra actions required for the exception */ + switch (old_state) { + default: + break; + + case FSG_STATE_ABORT_BULK_OUT: + send_status(fsg); + spin_lock_irq(&fsg->lock); + if (fsg->state == FSG_STATE_STATUS_PHASE) + fsg->state = FSG_STATE_IDLE; + spin_unlock_irq(&fsg->lock); + break; + + case FSG_STATE_RESET: + /* In case we were forced against our will to halt a + * bulk endpoint, clear the halt now. (The SuperH UDC + * requires this.) */ + if (test_and_clear_bit(CLEAR_BULK_HALTS, + &fsg->atomic_bitflags)) { + usb_ep_clear_halt(fsg->bulk_in); + usb_ep_clear_halt(fsg->bulk_out); + } + + if (transport_is_bbb()) { + if (fsg->ep0_req_tag == exception_req_tag) + ep0_queue(fsg); // Complete the status stage + + } else if (transport_is_cbi()) + send_status(fsg); // Status by interrupt pipe + + /* Technically this should go here, but it would only be + * a waste of time. Ditto for the INTERFACE_CHANGE and + * CONFIG_CHANGE cases. */ + // for (i = 0; i < fsg->nluns; ++i) + // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; + break; + + case FSG_STATE_INTERFACE_CHANGE: + rc = do_set_interface(fsg, 0); + if (fsg->ep0_req_tag != exception_req_tag) + break; + if (rc != 0) // STALL on errors + fsg_set_halt(fsg, fsg->ep0); + else // Complete the status stage + ep0_queue(fsg); + break; + + case FSG_STATE_CONFIG_CHANGE: + rc = do_set_config(fsg, new_config); + if (fsg->ep0_req_tag != exception_req_tag) + break; + if (rc != 0) // STALL on errors + fsg_set_halt(fsg, fsg->ep0); + else // Complete the status stage + ep0_queue(fsg); + break; + + case FSG_STATE_DISCONNECT: + fsync_all(fsg); + do_set_config(fsg, 0); // Unconfigured state + break; + + case FSG_STATE_EXIT: + case FSG_STATE_TERMINATED: + do_set_config(fsg, 0); // Free resources + spin_lock_irq(&fsg->lock); + fsg->state = FSG_STATE_TERMINATED; // Stop the thread + spin_unlock_irq(&fsg->lock); + break; + } +} + + +/*-------------------------------------------------------------------------*/ + +static int fsg_main_thread(void *fsg_) +{ + struct fsg_dev *fsg = (struct fsg_dev *) fsg_; + + fsg->thread_task = current; + + /* Release all our userspace resources */ + daemonize(); + reparent_to_init(); + strncpy(current->comm, "file-storage-gadget", + sizeof(current->comm) - 1); + + /* Allow the thread to be killed by a signal, but set the signal mask + * to block everything but INT, TERM, KILL, and USR1. */ + siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | + sigmask(SIGTERM) | sigmask(SIGKILL) | + sigmask(SIGUSR1)); + spin_lock_irq(¤t->sigmask_lock); + flush_signals(current); + current->blocked = fsg->thread_signal_mask; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + /* Arrange for userspace references to be interpreted as kernel + * pointers. That way we can pass a kernel pointer to a routine + * that expects a __user pointer and it will work okay. */ + set_fs(get_ds()); + + /* Wait for the gadget registration to finish up */ + wait_for_completion(&fsg->thread_notifier); + + /* The main loop */ + while (fsg->state != FSG_STATE_TERMINATED) { + if (exception_in_progress(fsg) || signal_pending(current)) { + handle_exception(fsg); + continue; + } + + if (!fsg->running) { + sleep_thread(fsg); + continue; + } + + if (get_next_command(fsg)) + continue; + + spin_lock_irq(&fsg->lock); + if (!exception_in_progress(fsg)) + fsg->state = FSG_STATE_DATA_PHASE; + spin_unlock_irq(&fsg->lock); + + if (do_scsi_command(fsg) || finish_reply(fsg)) + continue; + + spin_lock_irq(&fsg->lock); + if (!exception_in_progress(fsg)) + fsg->state = FSG_STATE_STATUS_PHASE; + spin_unlock_irq(&fsg->lock); + + if (send_status(fsg)) + continue; + + spin_lock_irq(&fsg->lock); + if (!exception_in_progress(fsg)) + fsg->state = FSG_STATE_IDLE; + spin_unlock_irq(&fsg->lock); + } + + fsg->thread_task = NULL; + flush_signals(current); + + /* In case we are exiting because of a signal, unregister the + * gadget driver and close the backing file. */ + if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) { + usb_gadget_unregister_driver(&fsg_driver); + close_all_backing_files(fsg); + } + + /* Let the unbind and cleanup routines know the thread has exited */ + complete_and_exit(&fsg->thread_notifier, 0); +} + + +/*-------------------------------------------------------------------------*/ + +/* If the next two routines are called while the gadget is registered, + * the caller must own fsg->filesem for writing. */ + +static int NORMALLY_INIT open_backing_file(struct lun *curlun, + const char *filename) +{ + int ro; + struct file *filp = NULL; + int rc = -EINVAL; + struct inode *inode = NULL; + loff_t size; + loff_t num_sectors; + + /* R/W if we can, R/O if we must */ + ro = curlun->ro; + if (!ro) { + filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); + if (-EROFS == PTR_ERR(filp)) + ro = 1; + } + if (ro) + filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(filp)) { + LINFO(curlun, "unable to open backing file: %s\n", filename); + return PTR_ERR(filp); + } + + if (!(filp->f_mode & FMODE_WRITE)) + ro = 1; + + if (filp->f_dentry) + inode = filp->f_dentry->d_inode; + if (inode && S_ISBLK(inode->i_mode)) { + kdev_t dev = inode->i_rdev; + + if (blk_size[MAJOR(dev)]) + size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << + BLOCK_SIZE_BITS; + else { + LINFO(curlun, "unable to find file size: %s\n", + filename); + goto out; + } + } else if (inode && S_ISREG(inode->i_mode)) + size = inode->i_size; + else { + LINFO(curlun, "invalid file type: %s\n", filename); + goto out; + } + + /* If we can't read the file, it's no good. + * If we can't write the file, use it read-only. */ + if (!filp->f_op || !filp->f_op->read) { + LINFO(curlun, "file not readable: %s\n", filename); + goto out; + } + if (IS_RDONLY(inode) || !filp->f_op->write) + ro = 1; + + num_sectors = size >> 9; // File size in 512-byte sectors + if (num_sectors == 0) { + LINFO(curlun, "file too small: %s\n", filename); + rc = -ETOOSMALL; + goto out; + } + + get_file(filp); + curlun->ro = ro; + curlun->filp = filp; + curlun->file_length = size; + curlun->num_sectors = num_sectors; + LDBG(curlun, "open backing file: %s\n", filename); + rc = 0; + +out: + filp_close(filp, current->files); + return rc; +} + + +static void close_backing_file(struct lun *curlun) +{ + if (curlun->filp) { + LDBG(curlun, "close backing file\n"); + fput(curlun->filp); + curlun->filp = NULL; + } +} + +static void close_all_backing_files(struct fsg_dev *fsg) +{ + int i; + + for (i = 0; i < fsg->nluns; ++i) + close_backing_file(&fsg->luns[i]); +} + + +/*-------------------------------------------------------------------------*/ + +static void fsg_unbind(struct usb_gadget *gadget) +{ + struct fsg_dev *fsg = get_gadget_data(gadget); + int i; + struct usb_request *req = fsg->ep0req; + + DBG(fsg, "unbind\n"); + clear_bit(REGISTERED, &fsg->atomic_bitflags); + + /* If the thread isn't already dead, tell it to exit now */ + if (fsg->state != FSG_STATE_TERMINATED) { + raise_exception(fsg, FSG_STATE_EXIT); + wait_for_completion(&fsg->thread_notifier); + + /* The cleanup routine waits for this completion also */ + complete(&fsg->thread_notifier); + } + + /* Free the data buffers */ + for (i = 0; i < NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &fsg->buffhds[i]; + + if (bh->buf) + usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma, + mod_data.buflen); + } + + /* Free the request and buffer for endpoint 0 */ + if (req) { + if (req->buf) + usb_ep_free_buffer(fsg->ep0, req->buf, + req->dma, EP0_BUFSIZE); + usb_ep_free_request(fsg->ep0, req); + } + + set_gadget_data(gadget, 0); +} + + +static int __init check_parameters(struct fsg_dev *fsg) +{ + int prot; + + /* Store the default values */ + mod_data.transport_type = USB_PR_BULK; + mod_data.transport_name = "Bulk-only"; + mod_data.protocol_type = USB_SC_SCSI; + mod_data.protocol_name = "Transparent SCSI"; + + prot = simple_strtol(mod_data.protocol_parm, NULL, 0); + +#ifdef CONFIG_USB_FILE_STORAGE_TEST + if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) { + ; // Use default setting + } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) { + mod_data.transport_type = USB_PR_CB; + mod_data.transport_name = "Control-Bulk"; + } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) { + 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); + return -EINVAL; + } + + if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 || + prot == USB_SC_SCSI) { + ; // Use default setting + } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 || + prot == USB_SC_RBC) { + mod_data.protocol_type = USB_SC_RBC; + mod_data.protocol_name = "RBC"; + } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 || + strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 || + prot == USB_SC_8020) { + mod_data.protocol_type = USB_SC_8020; + mod_data.protocol_name = "8020i (ATAPI)"; + } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 || + prot == USB_SC_QIC) { + mod_data.protocol_type = USB_SC_QIC; + mod_data.protocol_name = "QIC-157"; + } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 || + prot == USB_SC_UFI) { + mod_data.protocol_type = USB_SC_UFI; + mod_data.protocol_name = "UFI"; + } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 || + prot == USB_SC_8070) { + mod_data.protocol_type = USB_SC_8070; + mod_data.protocol_name = "8070i"; + } else { + INFO(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"); + return -ETOOSMALL; + } +#endif /* CONFIG_USB_FILE_STORAGE_TEST */ + + return 0; +} + + +static int __init fsg_bind(struct usb_gadget *gadget) +{ + struct fsg_dev *fsg = the_fsg; + int rc; + int i; + struct lun *curlun; + struct usb_ep *ep; + struct usb_request *req; + char *pathbuf, *p; + + fsg->gadget = gadget; + set_gadget_data(gadget, fsg); + fsg->ep0 = gadget->ep0; + fsg->ep0->driver_data = fsg; + + if ((rc = check_parameters(fsg)) != 0) + goto out; + + /* Find out how many LUNs there should be */ + i = mod_data.nluns; + if (i == 0) { + for (i = MAX_LUNS; i > 1; --i) { + if (file[i - 1]) + break; + } + } + if (i > MAX_LUNS) { + INFO(fsg, "invalid number of LUNs: %d\n", i); + rc = -EINVAL; + goto out; + } + + /* Create the LUNs and open their backing files. We can't register + * the LUN devices until the gadget itself is registered, which + * doesn't happen until after fsg_bind() returns. */ + fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL); + if (!fsg->luns) { + rc = -ENOMEM; + goto out; + } + memset(fsg->luns, 0, i * sizeof(struct lun)); + fsg->nluns = i; + + for (i = 0; i < fsg->nluns; ++i) { + curlun = &fsg->luns[i]; + curlun->ro = ro[i]; + curlun->dev.driver_data = fsg; + snprintf(curlun->dev.name, BUS_ID_SIZE, + "%s-lun%d", gadget->name, i); + + if (file[i] && *file[i]) { + 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); + rc = -EINVAL; + goto out; + } + } + + /* 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; + + /* 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); + + rc = -ENOMEM; + + /* Allocate the request and buffer for endpoint 0 */ + fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); + if (!req) + goto out; + req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE, + &req->dma, GFP_KERNEL); + if (!req->buf) + goto out; + req->complete = ep0_complete; + + /* Allocate the data buffers */ + for (i = 0; i < NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &fsg->buffhds[i]; + + bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, + &bh->dma, GFP_KERNEL); + if (!bh->buf) + goto out; + bh->next = bh + 1; + } + fsg->buffhds[NUM_BUFFERS - 1].next = &fsg->buffhds[0]; + + /* This should reflect the actual gadget power source */ + usb_gadget_set_selfpowered(gadget); + + /* 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) { + unsigned char c = DRIVER_VERSION[i / 2]; + + if (!c) + break; + sprintf(&serial[i], "%02X", c); + } + + if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS | + CLONE_FILES))) < 0) + goto out; + fsg->thread_pid = rc; + + INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); + INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); + + pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); + for (i = 0; i < fsg->nluns; ++i) { + curlun = &fsg->luns[i]; + if (backing_file_is_open(curlun)) { + p = NULL; + if (pathbuf) { + p = d_path(curlun->filp->f_dentry, + curlun->filp->f_vfsmnt, + pathbuf, PATH_MAX); + if (IS_ERR(p)) + p = NULL; + } + LINFO(curlun, "ro=%d, file: %s\n", + curlun->ro, (p ? p : "(error)")); + } + } + kfree(pathbuf); + + DBG(fsg, "transport=%s (x%02x)\n", + mod_data.transport_name, mod_data.transport_type); + DBG(fsg, "protocol=%s (x%02x)\n", + mod_data.protocol_name, mod_data.protocol_type); + DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", + mod_data.vendor, mod_data.product, mod_data.release); + DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", + mod_data.removable, mod_data.can_stall, + mod_data.buflen); + DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid); + return 0; + +out: + fsg->state = FSG_STATE_TERMINATED; // The thread is dead + fsg_unbind(gadget); + close_all_backing_files(fsg); + return rc; +} + + +/*-------------------------------------------------------------------------*/ + +static struct usb_gadget_driver fsg_driver = { +#ifdef HIGHSPEED + .speed = USB_SPEED_HIGH, +#else + .speed = USB_SPEED_FULL, +#endif + .function = (char *) longname, + .bind = fsg_bind, + .unbind = fsg_unbind, + .disconnect = fsg_disconnect, + .setup = fsg_setup, + + .driver = { + .name = (char *) shortname, + // .release = ... + // .suspend = ... + // .resume = ... + }, +}; + + +static int __init fsg_alloc(void) +{ + struct fsg_dev *fsg; + + fsg = kmalloc(sizeof *fsg, GFP_KERNEL); + if (!fsg) + return -ENOMEM; + memset(fsg, 0, sizeof *fsg); + spin_lock_init(&fsg->lock); + init_rwsem(&fsg->filesem); + init_waitqueue_head(&fsg->thread_wqh); + init_completion(&fsg->thread_notifier); + + the_fsg = fsg; + return 0; +} + + +static void fsg_free(struct fsg_dev *fsg) +{ + kfree(fsg->luns); + kfree(fsg); +} + + +static int __init fsg_init(void) +{ + int rc; + struct fsg_dev *fsg; + + /* Put the module parameters where they belong -- arghh! */ + mod_data.nluns = luns; + mod_data.transport_parm = transport; + mod_data.protocol_parm = protocol; + mod_data.removable = removable; + mod_data.vendor = vendor; + mod_data.product = product; + mod_data.release = release; + mod_data.buflen = buflen; + mod_data.can_stall = stall; + + if ((rc = fsg_alloc()) != 0) + return rc; + fsg = the_fsg; + if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) { + fsg_free(fsg); + return rc; + } + set_bit(REGISTERED, &fsg->atomic_bitflags); + + /* Tell the thread to start working */ + complete(&fsg->thread_notifier); + return 0; +} +module_init(fsg_init); + + +static void __exit fsg_cleanup(void) +{ + struct fsg_dev *fsg = the_fsg; + + /* Unregister the driver iff the thread hasn't already done so */ + if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) + usb_gadget_unregister_driver(&fsg_driver); + + /* Wait for the thread to finish up */ + wait_for_completion(&fsg->thread_notifier); + + close_all_backing_files(fsg); + fsg_free(fsg); +} +module_exit(fsg_cleanup); diff -urN linux-2.4.24/drivers/usb/gadget/goku_udc.c linux-2.4.25/drivers/usb/gadget/goku_udc.c --- linux-2.4.24/drivers/usb/gadget/goku_udc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/goku_udc.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1975 @@ +/* + * Toshiba TC86C001 ("Goku-S") USB Device Controller driver + * + * Copyright (C) 2000-2002 Lineo + * by Stuart Lynne, Tom Rushworth, and Bruce Balden + * Copyright (C) 2002 Toshiba Corporation + * Copyright (C) 2003 MontaVista Software (source@mvista.com) + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* + * This device has ep0 and three semi-configurable bulk/interrupt endpoints. + * + * - Endpoint numbering is fixed: ep{1,2,3}-bulk + * - Gadget drivers can choose ep maxpacket (8/16/32/64) + * - Gadget drivers can choose direction (IN, OUT) + * - DMA works with ep1 (OUT transfers) and ep2 (IN transfers). + */ + +#undef DEBUG +// #define VERBOSE /* extra debug messages (success too) */ +// #define USB_TRACE /* packet-level success messages */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "goku_udc.h" + +#define DRIVER_DESC "TC86C001 USB Device Controller" +#define DRIVER_VERSION "30-Oct 2003" + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +static const char driver_name [] = "goku_udc"; +static const char driver_desc [] = DRIVER_DESC; + +MODULE_AUTHOR("source@mvista.com"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + + +/* + * IN dma behaves ok under testing, though the IN-dma abort paths don't + * seem to behave quite as expected. Used by default. + * + * OUT dma documents design problems handling the common "short packet" + * transfer termination policy; it couldn't enabled by default, even + * if the OUT-dma abort problems had a resolution. + */ +static unsigned use_dma = 1; + +#if 0 +//#include +/* "modprobe goku_udc use_dma=1" etc + * 0 to disable dma + * 1 to use IN dma only (normal operation) + * 2 to use IN and OUT dma + */ +module_param(use_dma, uint, S_IRUGO); +#endif + +/*-------------------------------------------------------------------------*/ + +static void nuke(struct goku_ep *, int status); + +static inline void +command(struct goku_udc_regs *regs, int command, unsigned epnum) +{ + writel(COMMAND_EP(epnum) | command, ®s->Command); + udelay(300); +} + +static int +goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) +{ + struct goku_udc *dev; + struct goku_ep *ep; + u32 mode; + u16 max; + unsigned long flags; + + ep = container_of(_ep, struct goku_ep, ep); + if (!_ep || !desc || ep->desc + || desc->bDescriptorType != USB_DT_ENDPOINT) + return -EINVAL; + dev = ep->dev; + if (ep == &dev->ep[0]) + return -EINVAL; + if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + if (ep->num != (desc->bEndpointAddress & 0x0f)) + return -EINVAL; + + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_BULK: + case USB_ENDPOINT_XFER_INT: + break; + default: + return -EINVAL; + } + + if ((readl(ep->reg_status) & EPxSTATUS_EP_MASK) + != EPxSTATUS_EP_INVALID) + return -EBUSY; + + /* enabling the no-toggle interrupt mode would need an api hook */ + mode = 0; + max = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); + switch (max) { + case 64: mode++; + case 32: mode++; + case 16: mode++; + case 8: mode <<= 3; + break; + default: + return -EINVAL; + } + mode |= 2 << 1; /* bulk, or intr-with-toggle */ + + /* ep1/ep2 dma direction is chosen early; it works in the other + * direction, with pio. be cautious with out-dma. + */ + ep->is_in = (USB_DIR_IN & desc->bEndpointAddress) != 0; + if (ep->is_in) { + mode |= 1; + ep->dma = (use_dma != 0) && (ep->num == UDC_MSTRD_ENDPOINT); + } else { + ep->dma = (use_dma == 2) && (ep->num == UDC_MSTWR_ENDPOINT); + if (ep->dma) + DBG(dev, "%s out-dma hides short packets\n", + ep->ep.name); + } + + spin_lock_irqsave(&ep->dev->lock, flags); + + /* ep1 and ep2 can do double buffering and/or dma */ + if (ep->num < 3) { + struct goku_udc_regs *regs = ep->dev->regs; + u32 tmp; + + /* double buffer except (for now) with pio in */ + tmp = ((ep->dma || !ep->is_in) + ? 0x10 /* double buffered */ + : 0x11 /* single buffer */ + ) << ep->num; + tmp |= readl(®s->EPxSingle); + writel(tmp, ®s->EPxSingle); + + tmp = (ep->dma ? 0x10/*dma*/ : 0x11/*pio*/) << ep->num; + tmp |= readl(®s->EPxBCS); + writel(tmp, ®s->EPxBCS); + } + writel(mode, ep->reg_mode); + command(ep->dev->regs, COMMAND_RESET, ep->num); + ep->ep.maxpacket = max; + ep->stopped = 0; + ep->desc = desc; + spin_unlock_irqrestore(&ep->dev->lock, flags); + + DBG(dev, "enable %s %s %s maxpacket %u\n", ep->ep.name, + ep->is_in ? "IN" : "OUT", + ep->dma ? "dma" : "pio", + max); + + return 0; +} + +static void ep_reset(struct goku_udc_regs *regs, struct goku_ep *ep) +{ + struct goku_udc *dev = ep->dev; + + if (regs) { + command(regs, COMMAND_INVALID, ep->num); + if (ep->num) { + if (ep->num == UDC_MSTWR_ENDPOINT) + dev->int_enable &= ~(INT_MSTWREND + |INT_MSTWRTMOUT); + else if (ep->num == UDC_MSTRD_ENDPOINT) + dev->int_enable &= ~INT_MSTRDEND; + dev->int_enable &= ~INT_EPxDATASET (ep->num); + } else + dev->int_enable &= ~INT_EP0; + writel(dev->int_enable, ®s->int_enable); + readl(®s->int_enable); + if (ep->num < 3) { + struct goku_udc_regs *regs = ep->dev->regs; + u32 tmp; + + tmp = readl(®s->EPxSingle); + tmp &= ~(0x11 << ep->num); + writel(tmp, ®s->EPxSingle); + + tmp = readl(®s->EPxBCS); + tmp &= ~(0x11 << ep->num); + writel(tmp, ®s->EPxBCS); + } + /* reset dma in case we're still using it */ + if (ep->dma) { + u32 master; + + master = readl(®s->dma_master) & MST_RW_BITS; + if (ep->num == UDC_MSTWR_ENDPOINT) { + master &= ~MST_W_BITS; + master |= MST_WR_RESET; + } else { + master &= ~MST_R_BITS; + master |= MST_RD_RESET; + } + writel(master, ®s->dma_master); + } + } + + ep->ep.maxpacket = MAX_FIFO_SIZE; + ep->desc = 0; + ep->stopped = 1; + ep->irqs = 0; + ep->dma = 0; +} + +static int goku_ep_disable(struct usb_ep *_ep) +{ + struct goku_ep *ep; + struct goku_udc *dev; + unsigned long flags; + + ep = container_of(_ep, struct goku_ep, ep); + if (!_ep || !ep->desc) + return -ENODEV; + dev = ep->dev; + if (dev->ep0state == EP0_SUSPEND) + return -EBUSY; + + VDBG(dev, "disable %s\n", _ep->name); + + spin_lock_irqsave(&dev->lock, flags); + nuke(ep, -ESHUTDOWN); + ep_reset(dev->regs, ep); + spin_unlock_irqrestore(&dev->lock, flags); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct usb_request * +goku_alloc_request(struct usb_ep *_ep, int gfp_flags) +{ + struct goku_request *req; + + if (!_ep) + return 0; + req = kmalloc(sizeof *req, gfp_flags); + if (!req) + return 0; + + memset(req, 0, sizeof *req); + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD(&req->queue); + return &req->req; +} + +static void +goku_free_request(struct usb_ep *_ep, struct usb_request *_req) +{ + struct goku_request *req; + + if (!_ep || !_req) + return; + + req = container_of(_req, struct goku_request, req); + WARN_ON(!list_empty(&req->queue)); + kfree(req); +} + +/*-------------------------------------------------------------------------*/ + +#undef USE_KMALLOC + +/* many common platforms have dma-coherent caches, which means that it's + * safe to use kmalloc() memory for all i/o buffers without using any + * cache flushing calls. (unless you're trying to share cache lines + * between dma and non-dma activities, which is a slow idea in any case.) + * + * other platforms need more care, with 2.6 having a moderately general + * solution except for the common "buffer is smaller than a page" case. + */ +#if defined(CONFIG_X86) +#define USE_KMALLOC + +#elif defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO) +#define USE_KMALLOC + +#elif defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE) +#define USE_KMALLOC + +#endif + +/* allocating buffers this way eliminates dma mapping overhead, which + * on some platforms will mean eliminating a per-io buffer copy. with + * some kinds of system caches, further tweaks may still be needed. + */ +static void * +goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes, + dma_addr_t *dma, int gfp_flags) +{ + void *retval; + struct goku_ep *ep; + + ep = container_of(_ep, struct goku_ep, ep); + if (!_ep) + return 0; + *dma = DMA_ADDR_INVALID; + +#if defined(USE_KMALLOC) + retval = kmalloc(bytes, gfp_flags); + if (retval) + *dma = virt_to_phys(retval); +#else + if (ep->dma) { + /* one problem with this call is that it wastes memory on + * typical 1/N page allocations: it allocates 1-N pages. + * another is that it always uses GFP_ATOMIC. + */ +#warning Using pci_alloc_consistent even with buffers smaller than a page. + retval = pci_alloc_consistent(ep->dev->pdev, bytes, dma); + } else + retval = kmalloc(bytes, gfp_flags); +#endif + return retval; +} + +static void +goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes) +{ + /* free memory into the right allocator */ +#ifndef USE_KMALLOC + if (dma != DMA_ADDR_INVALID) { + struct goku_ep *ep; + + ep = container_of(_ep, struct goku_ep, ep); + if (!_ep) + return; + /* one problem with this call is that some platforms + * don't allow it to be used in_irq(). + */ + pci_free_consistent(ep->dev->pdev, bytes, buf, dma); + } else +#endif + kfree (buf); +} + +/*-------------------------------------------------------------------------*/ + +static void +done(struct goku_ep *ep, struct goku_request *req, int status) +{ + struct goku_udc *dev; + unsigned stopped = ep->stopped; + + list_del_init(&req->queue); + + if (likely(req->req.status == -EINPROGRESS)) + req->req.status = status; + else + status = req->req.status; + + dev = ep->dev; + if (req->mapped) { + pci_unmap_single(dev->pdev, req->req.dma, req->req.length, + ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } + +#ifndef USB_TRACE + if (status && status != -ESHUTDOWN) +#endif + VDBG(dev, "complete %s req %p stat %d len %u/%u\n", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); + + /* don't modify queue heads during completion callback */ + ep->stopped = 1; + spin_unlock(&dev->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dev->lock); + ep->stopped = stopped; +} + +/*-------------------------------------------------------------------------*/ + +static inline int +write_packet(u32 *fifo, u8 *buf, struct goku_request *req, unsigned max) +{ + unsigned length, count; + + length = min(req->req.length - req->req.actual, max); + req->req.actual += length; + + count = length; + while (likely(count--)) + writel(*buf++, fifo); + return length; +} + +// return: 0 = still running, 1 = completed, negative = errno +static int write_fifo(struct goku_ep *ep, struct goku_request *req) +{ + struct goku_udc *dev = ep->dev; + u32 tmp; + u8 *buf; + unsigned count; + int is_last; + + tmp = readl(&dev->regs->DataSet); + buf = req->req.buf + req->req.actual; + prefetch(buf); + + dev = ep->dev; + if (unlikely(ep->num == 0 && dev->ep0state != EP0_IN)) + return -EL2HLT; + + /* NOTE: just single-buffered PIO-IN for now. */ + if (unlikely((tmp & DATASET_A(ep->num)) != 0)) + return 0; + + /* clear our "packet available" irq */ + if (ep->num != 0) + writel(~INT_EPxDATASET(ep->num), &dev->regs->int_status); + + count = write_packet(ep->reg_fifo, buf, req, ep->ep.maxpacket); + + /* last packet often short (sometimes a zlp, especially on ep0) */ + if (unlikely(count != ep->ep.maxpacket)) { + writel(~(1<num), &dev->regs->EOP); + if (ep->num == 0) { + dev->ep[0].stopped = 1; + dev->ep0state = EP0_STATUS; + } + is_last = 1; + } else { + if (likely(req->req.length != req->req.actual) + || req->req.zero) + is_last = 0; + else + is_last = 1; + } +#if 0 /* printk seemed to trash is_last...*/ +//#ifdef USB_TRACE + VDBG(dev, "wrote %s %u bytes%s IN %u left %p\n", + ep->ep.name, count, is_last ? "/last" : "", + req->req.length - req->req.actual, req); +#endif + + /* requests complete when all IN data is in the FIFO, + * or sometimes later, if a zlp was needed. + */ + if (is_last) { + done(ep, req, 0); + return 1; + } + + return 0; +} + +static int read_fifo(struct goku_ep *ep, struct goku_request *req) +{ + struct goku_udc_regs *regs; + u32 size, set; + u8 *buf; + unsigned bufferspace, is_short, dbuff; + + regs = ep->dev->regs; +top: + buf = req->req.buf + req->req.actual; + prefetchw(buf); + + if (unlikely(ep->num == 0 && ep->dev->ep0state != EP0_OUT)) + return -EL2HLT; + + dbuff = (ep->num == 1 || ep->num == 2); + do { + /* ack dataset irq matching the status we'll handle */ + if (ep->num != 0) + writel(~INT_EPxDATASET(ep->num), ®s->int_status); + + set = readl(®s->DataSet) & DATASET_AB(ep->num); + size = readl(®s->EPxSizeLA[ep->num]); + bufferspace = req->req.length - req->req.actual; + + /* usually do nothing without an OUT packet */ + if (likely(ep->num != 0 || bufferspace != 0)) { + if (unlikely(set == 0)) + break; + /* use ep1/ep2 double-buffering for OUT */ + if (!(size & PACKET_ACTIVE)) + size = readl(®s->EPxSizeLB[ep->num]); + if (!(size & PACKET_ACTIVE)) // "can't happen" + break; + size &= DATASIZE; /* EPxSizeH == 0 */ + + /* ep0out no-out-data case for set_config, etc */ + } else + size = 0; + + /* read all bytes from this packet */ + req->req.actual += size; + is_short = (size < ep->ep.maxpacket); +#ifdef USB_TRACE + VDBG(ep->dev, "read %s %u bytes%s OUT req %p %u/%u\n", + ep->ep.name, size, is_short ? "/S" : "", + req, req->req.actual, req->req.length); +#endif + while (likely(size-- != 0)) { + u8 byte = (u8) readl(ep->reg_fifo); + + if (unlikely(bufferspace == 0)) { + /* this happens when the driver's buffer + * is smaller than what the host sent. + * discard the extra data in this packet. + */ + if (req->req.status != -EOVERFLOW) + DBG(ep->dev, "%s overflow %u\n", + ep->ep.name, size); + req->req.status = -EOVERFLOW; + } else { + *buf++ = byte; + bufferspace--; + } + } + + /* completion */ + if (unlikely(is_short || req->req.actual == req->req.length)) { + if (unlikely(ep->num == 0)) { + /* non-control endpoints now usable? */ + if (ep->dev->req_config) + writel(ep->dev->configured + ? USBSTATE_CONFIGURED + : 0, + ®s->UsbState); + /* ep0out status stage */ + writel(~(1<<0), ®s->EOP); + ep->stopped = 1; + ep->dev->ep0state = EP0_STATUS; + } + done(ep, req, 0); + + /* empty the second buffer asap */ + if (dbuff && !list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, + struct goku_request, queue); + goto top; + } + return 1; + } + } while (dbuff); + return 0; +} + +static inline void +pio_irq_enable(struct goku_udc *dev, struct goku_udc_regs *regs, int epnum) +{ + dev->int_enable |= INT_EPxDATASET (epnum); + writel(dev->int_enable, ®s->int_enable); + /* write may still be posted */ +} + +static inline void +pio_irq_disable(struct goku_udc *dev, struct goku_udc_regs *regs, int epnum) +{ + dev->int_enable &= ~INT_EPxDATASET (epnum); + writel(dev->int_enable, ®s->int_enable); + /* write may still be posted */ +} + +static inline void +pio_advance(struct goku_ep *ep) +{ + struct goku_request *req; + + if (unlikely(list_empty (&ep->queue))) + return; + req = list_entry(ep->queue.next, struct goku_request, queue); + (ep->is_in ? write_fifo : read_fifo)(ep, req); +} + + +/*-------------------------------------------------------------------------*/ + +// return: 0 = q running, 1 = q stopped, negative = errno +static int start_dma(struct goku_ep *ep, struct goku_request *req) +{ + struct goku_udc_regs *regs = ep->dev->regs; + u32 master; + u32 start = req->req.dma; + u32 end = start + req->req.length - 1; + + master = readl(®s->dma_master) & MST_RW_BITS; + + /* re-init the bits affecting IN dma; careful with zlps */ + if (likely(ep->is_in)) { + if (unlikely(master & MST_RD_ENA)) { + DBG (ep->dev, "start, IN active dma %03x!!\n", + master); +// return -EL2HLT; + } + writel(end, ®s->in_dma_end); + writel(start, ®s->in_dma_start); + + master &= ~MST_R_BITS; + if (unlikely(req->req.length == 0)) + master = MST_RD_ENA | MST_RD_EOPB; + else if ((req->req.length % ep->ep.maxpacket) != 0 + || req->req.zero) + master = MST_RD_ENA | MST_EOPB_ENA; + else + master = MST_RD_ENA | MST_EOPB_DIS; + + ep->dev->int_enable |= INT_MSTRDEND; + + /* Goku DMA-OUT merges short packets, which plays poorly with + * protocols where short packets mark the transfer boundaries. + * The chip supports a nonstandard policy with INT_MSTWRTMOUT, + * ending transfers after 3 SOFs; we don't turn it on. + */ + } else { + if (unlikely(master & MST_WR_ENA)) { + DBG (ep->dev, "start, OUT active dma %03x!!\n", + master); +// return -EL2HLT; + } + writel(end, ®s->out_dma_end); + writel(start, ®s->out_dma_start); + + master &= ~MST_W_BITS; + master |= MST_WR_ENA | MST_TIMEOUT_DIS; + + ep->dev->int_enable |= INT_MSTWREND|INT_MSTWRTMOUT; + } + + writel(master, ®s->dma_master); + writel(ep->dev->int_enable, ®s->int_enable); + return 0; +} + +static void dma_advance(struct goku_udc *dev, struct goku_ep *ep) +{ + struct goku_request *req; + struct goku_udc_regs *regs = ep->dev->regs; + u32 master; + + master = readl(®s->dma_master); + + if (unlikely(list_empty(&ep->queue))) { +stop: + if (ep->is_in) + dev->int_enable &= ~INT_MSTRDEND; + else + dev->int_enable &= ~(INT_MSTWREND|INT_MSTWRTMOUT); + writel(dev->int_enable, ®s->int_enable); + return; + } + req = list_entry(ep->queue.next, struct goku_request, queue); + + /* normal hw dma completion (not abort) */ + if (likely(ep->is_in)) { + if (unlikely(master & MST_RD_ENA)) + return; + req->req.actual = readl(®s->in_dma_current); + } else { + if (unlikely(master & MST_WR_ENA)) + return; + + /* hardware merges short packets, and also hides packet + * overruns. a partial packet MAY be in the fifo here. + */ + req->req.actual = readl(®s->out_dma_current); + } + req->req.actual -= req->req.dma; + req->req.actual++; + +#ifdef USB_TRACE + VDBG(dev, "done %s %s dma, %u/%u bytes, req %p\n", + ep->ep.name, ep->is_in ? "IN" : "OUT", + req->req.actual, req->req.length, req); +#endif + done(ep, req, 0); + if (list_empty(&ep->queue)) + goto stop; + req = list_entry(ep->queue.next, struct goku_request, queue); + (void) start_dma(ep, req); +} + +static void abort_dma(struct goku_ep *ep, int status) +{ + struct goku_udc_regs *regs = ep->dev->regs; + struct goku_request *req; + u32 curr, master; + + /* NAK future host requests, hoping the implicit delay lets the + * dma engine finish reading (or writing) its latest packet and + * empty the dma buffer (up to 16 bytes). + * + * This avoids needing to clean up a partial packet in the fifo; + * we can't do that for IN without side effects to HALT and TOGGLE. + */ + command(regs, COMMAND_FIFO_DISABLE, ep->num); + req = list_entry(ep->queue.next, struct goku_request, queue); + master = readl(®s->dma_master) & MST_RW_BITS; + + /* FIXME using these resets isn't usably documented. this may + * not work unless it's followed by disabling the endpoint. + * + * FIXME the OUT reset path doesn't even behave consistently. + */ + if (ep->is_in) { + if (unlikely((readl(®s->dma_master) & MST_RD_ENA) == 0)) + goto finished; + curr = readl(®s->in_dma_current); + + writel(curr, ®s->in_dma_end); + writel(curr, ®s->in_dma_start); + + master &= ~MST_R_BITS; + master |= MST_RD_RESET; + writel(master, ®s->dma_master); + + if (readl(®s->dma_master) & MST_RD_ENA) + DBG(ep->dev, "IN dma active after reset!\n"); + + } else { + if (unlikely((readl(®s->dma_master) & MST_WR_ENA) == 0)) + goto finished; + curr = readl(®s->out_dma_current); + + writel(curr, ®s->out_dma_end); + writel(curr, ®s->out_dma_start); + + master &= ~MST_W_BITS; + master |= MST_WR_RESET; + writel(master, ®s->dma_master); + + if (readl(®s->dma_master) & MST_WR_ENA) + DBG(ep->dev, "OUT dma active after reset!\n"); + } + req->req.actual = (curr - req->req.dma) + 1; + req->req.status = status; + + VDBG(ep->dev, "%s %s %s %d/%d\n", __FUNCTION__, ep->ep.name, + ep->is_in ? "IN" : "OUT", + req->req.actual, req->req.length); + + command(regs, COMMAND_FIFO_ENABLE, ep->num); + + return; + +finished: + /* dma already completed; no abort needed */ + command(regs, COMMAND_FIFO_ENABLE, ep->num); + req->req.actual = req->req.length; + req->req.status = 0; +} + +/*-------------------------------------------------------------------------*/ + +static int +goku_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) +{ + struct goku_request *req; + struct goku_ep *ep; + struct goku_udc *dev; + unsigned long flags; + int status; + + /* always require a cpu-view buffer so pio works */ + req = container_of(_req, struct goku_request, req); + if (unlikely(!_req || !_req->complete + || !_req->buf || !list_empty(&req->queue))) + return -EINVAL; + ep = container_of(_ep, struct goku_ep, ep); + if (unlikely(!_ep || (!ep->desc && ep->num != 0))) + return -EINVAL; + dev = ep->dev; + if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) + return -ESHUTDOWN; + + /* can't touch registers when suspended */ + if (dev->ep0state == EP0_SUSPEND) + return -EBUSY; + + /* set up dma mapping in case the caller didn't */ + if (ep->dma && _req->dma == DMA_ADDR_INVALID) { + _req->dma = pci_map_single(dev->pdev, _req->buf, _req->length, + ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + req->mapped = 1; + } + +#ifdef USB_TRACE + VDBG(dev, "%s queue req %p, len %u buf %p\n", + _ep->name, _req, _req->length, _req->buf); +#endif + + spin_lock_irqsave(&dev->lock, flags); + + _req->status = -EINPROGRESS; + _req->actual = 0; + + /* for ep0 IN without premature status, zlp is required and + * writing EOP starts the status stage (OUT). + */ + if (unlikely(ep->num == 0 && ep->is_in)) + _req->zero = 1; + + /* kickstart this i/o queue? */ + status = 0; + if (list_empty(&ep->queue) && likely(!ep->stopped)) { + /* dma: done after dma completion IRQ (or error) + * pio: done after last fifo operation + */ + if (ep->dma) + status = start_dma(ep, req); + else + status = (ep->is_in ? write_fifo : read_fifo)(ep, req); + + if (unlikely(status != 0)) { + if (status > 0) + status = 0; + req = 0; + } + + } /* else pio or dma irq handler advances the queue. */ + + if (likely(req != 0)) + list_add_tail(&req->queue, &ep->queue); + + if (likely(!list_empty(&ep->queue)) + && likely(ep->num != 0) + && !ep->dma + && !(dev->int_enable & INT_EPxDATASET (ep->num))) + pio_irq_enable(dev, dev->regs, ep->num); + + spin_unlock_irqrestore(&dev->lock, flags); + + /* pci writes may still be posted */ + return status; +} + +/* dequeue ALL requests */ +static void nuke(struct goku_ep *ep, int status) +{ + struct goku_request *req; + + ep->stopped = 1; + if (list_empty(&ep->queue)) + return; + if (ep->dma) + abort_dma(ep, status); + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, struct goku_request, queue); + done(ep, req, status); + } +} + +/* dequeue JUST ONE request */ +static int goku_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct goku_request *req; + struct goku_ep *ep; + struct goku_udc *dev; + unsigned long flags; + + ep = container_of(_ep, struct goku_ep, ep); + if (!_ep || !_req || (!ep->desc && ep->num != 0)) + return -EINVAL; + dev = ep->dev; + if (!dev->driver) + return -ESHUTDOWN; + + /* we can't touch (dma) registers when suspended */ + if (dev->ep0state == EP0_SUSPEND) + return -EBUSY; + + VDBG(dev, "%s %s %s %s %p\n", __FUNCTION__, _ep->name, + ep->is_in ? "IN" : "OUT", + ep->dma ? "dma" : "pio", + _req); + + spin_lock_irqsave(&dev->lock, flags); + + /* make sure it's actually 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; + } + + if (ep->dma && ep->queue.next == &req->queue && !ep->stopped) { + abort_dma(ep, -ECONNRESET); + done(ep, req, -ECONNRESET); + dma_advance(dev, ep); + } else if (!list_empty(&req->queue)) + done(ep, req, -ECONNRESET); + else + req = 0; + spin_unlock_irqrestore(&dev->lock, flags); + + return req ? 0 : -EOPNOTSUPP; +} + +/*-------------------------------------------------------------------------*/ + +static void goku_clear_halt(struct goku_ep *ep) +{ + // assert (ep->num !=0) + VDBG(ep->dev, "%s clear halt\n", ep->ep.name); + command(ep->dev->regs, COMMAND_SETDATA0, ep->num); + command(ep->dev->regs, COMMAND_STALL_CLEAR, ep->num); + if (ep->stopped) { + ep->stopped = 0; + if (ep->dma) { + struct goku_request *req; + + if (list_empty(&ep->queue)) + return; + req = list_entry(ep->queue.next, struct goku_request, + queue); + (void) start_dma(ep, req); + } else + pio_advance(ep); + } +} + +static int goku_set_halt(struct usb_ep *_ep, int value) +{ + struct goku_ep *ep; + unsigned long flags; + int retval = 0; + + if (!_ep) + return -ENODEV; + ep = container_of (_ep, struct goku_ep, ep); + + if (ep->num == 0) { + if (value) { + ep->dev->ep0state = EP0_STALL; + ep->dev->ep[0].stopped = 1; + } else + return -EINVAL; + + /* don't change EPxSTATUS_EP_INVALID to READY */ + } else if (!ep->desc) { + DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name); + return -EINVAL; + } + + spin_lock_irqsave(&ep->dev->lock, flags); + if (!list_empty(&ep->queue)) + retval = -EAGAIN; + else if (ep->is_in && value + /* data in (either) packet buffer? */ + && (ep->dev->regs->DataSet & DATASET_AB(ep->num))) + retval = -EAGAIN; + else if (!value) + goku_clear_halt(ep); + else { + ep->stopped = 1; + VDBG(ep->dev, "%s set halt\n", ep->ep.name); + command(ep->dev->regs, COMMAND_STALL, ep->num); + readl(ep->reg_status); + } + spin_unlock_irqrestore(&ep->dev->lock, flags); + return retval; +} + +static int goku_fifo_status(struct usb_ep *_ep) +{ + struct goku_ep *ep; + struct goku_udc_regs *regs; + u32 size; + + if (!_ep) + return -ENODEV; + ep = container_of(_ep, struct goku_ep, ep); + + /* size is only reported sanely for OUT */ + if (ep->is_in) + return -EOPNOTSUPP; + + /* ignores 16-byte dma buffer; SizeH == 0 */ + regs = ep->dev->regs; + size = readl(®s->EPxSizeLA[ep->num]) & DATASIZE; + size += readl(®s->EPxSizeLB[ep->num]) & DATASIZE; + VDBG(ep->dev, "%s %s %u\n", __FUNCTION__, ep->ep.name, size); + return size; +} + +static void goku_fifo_flush(struct usb_ep *_ep) +{ + struct goku_ep *ep; + struct goku_udc_regs *regs; + u32 size; + + if (!_ep) + return; + ep = container_of(_ep, struct goku_ep, ep); + VDBG(ep->dev, "%s %s\n", __FUNCTION__, ep->ep.name); + + /* don't change EPxSTATUS_EP_INVALID to READY */ + if (!ep->desc && ep->num != 0) { + DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name); + return; + } + + regs = ep->dev->regs; + size = readl(®s->EPxSizeLA[ep->num]); + size &= DATASIZE; + + /* Non-desirable behavior: FIFO_CLEAR also clears the + * endpoint halt feature. For OUT, we _could_ just read + * the bytes out (PIO, if !ep->dma); for in, no choice. + */ + if (size) + command(regs, COMMAND_FIFO_CLEAR, ep->num); +} + +static struct usb_ep_ops goku_ep_ops = { + .enable = goku_ep_enable, + .disable = goku_ep_disable, + + .alloc_request = goku_alloc_request, + .free_request = goku_free_request, + + .alloc_buffer = goku_alloc_buffer, + .free_buffer = goku_free_buffer, + + .queue = goku_queue, + .dequeue = goku_dequeue, + + .set_halt = goku_set_halt, + .fifo_status = goku_fifo_status, + .fifo_flush = goku_fifo_flush, +}; + +/*-------------------------------------------------------------------------*/ + +static int goku_get_frame(struct usb_gadget *_gadget) +{ + return -EOPNOTSUPP; +} + +static const struct usb_gadget_ops goku_ops = { + .get_frame = goku_get_frame, + // no remote wakeup + // not selfpowered +}; + +/*-------------------------------------------------------------------------*/ + +static inline char *dmastr(void) +{ + if (use_dma == 0) + return "(dma disabled)"; + else if (use_dma == 2) + return "(dma IN and OUT)"; + else + return "(dma IN)"; +} + +/* if we're trying to save space, don't bother with this proc file */ + +#if defined(CONFIG_PROC_FS) && !defined(CONFIG_EMBEDDED) +# define UDC_PROC_FILE +#endif + +#ifdef UDC_PROC_FILE + +static const char proc_node_name [] = "driver/udc"; + +#define FOURBITS "%s%s%s%s" +#define EIGHTBITS FOURBITS FOURBITS + +static void +dump_intmask(const char *label, u32 mask, char **next, unsigned *size) +{ + int t; + + /* int_status is the same format ... */ + t = snprintf(*next, *size, + "%s %05X =" FOURBITS EIGHTBITS EIGHTBITS "\n", + label, mask, + (mask & INT_PWRDETECT) ? " power" : "", + (mask & INT_SYSERROR) ? " sys" : "", + (mask & INT_MSTRDEND) ? " in-dma" : "", + (mask & INT_MSTWRTMOUT) ? " wrtmo" : "", + + (mask & INT_MSTWREND) ? " out-dma" : "", + (mask & INT_MSTWRSET) ? " wrset" : "", + (mask & INT_ERR) ? " err" : "", + (mask & INT_SOF) ? " sof" : "", + + (mask & INT_EP3NAK) ? " ep3nak" : "", + (mask & INT_EP2NAK) ? " ep2nak" : "", + (mask & INT_EP1NAK) ? " ep1nak" : "", + (mask & INT_EP3DATASET) ? " ep3" : "", + + (mask & INT_EP2DATASET) ? " ep2" : "", + (mask & INT_EP1DATASET) ? " ep1" : "", + (mask & INT_STATUSNAK) ? " ep0snak" : "", + (mask & INT_STATUS) ? " ep0status" : "", + + (mask & INT_SETUP) ? " setup" : "", + (mask & INT_ENDPOINT0) ? " ep0" : "", + (mask & INT_USBRESET) ? " reset" : "", + (mask & INT_SUSPEND) ? " suspend" : ""); + *size -= t; + *next += t; +} + + +static int +udc_proc_read(char *buffer, char **start, off_t off, int count, + int *eof, void *_dev) +{ + char *buf = buffer; + struct goku_udc *dev = _dev; + struct goku_udc_regs *regs = dev->regs; + char *next = buf; + unsigned size = count; + unsigned long flags; + int i, t, is_usb_connected; + u32 tmp; + + if (off != 0) + return 0; + + local_irq_save(flags); + + /* basic device status */ + tmp = readl(®s->power_detect); + is_usb_connected = tmp & PW_DETECT; + t = snprintf(next, size, + "%s - %s\n" + "%s version: %s %s\n" + "Gadget driver: %s\n" + "Host %s, %s\n" + "\n", + pci_name(dev->pdev), driver_desc, + driver_name, DRIVER_VERSION, dmastr(), + dev->driver ? dev->driver->driver.name : "(none)", + is_usb_connected + ? ((tmp & PW_PULLUP) ? "full speed" : "powered") + : "disconnected", + ({char *tmp; + switch(dev->ep0state){ + case EP0_DISCONNECT: tmp = "ep0_disconnect"; break; + case EP0_IDLE: tmp = "ep0_idle"; break; + case EP0_IN: tmp = "ep0_in"; break; + case EP0_OUT: tmp = "ep0_out"; break; + case EP0_STATUS: tmp = "ep0_status"; break; + case EP0_STALL: tmp = "ep0_stall"; break; + case EP0_SUSPEND: tmp = "ep0_suspend"; break; + default: tmp = "ep0_?"; break; + } tmp; }) + ); + size -= t; + next += t; + + dump_intmask("int_status", readl(®s->int_status), &next, &size); + dump_intmask("int_enable", readl(®s->int_enable), &next, &size); + + if (!is_usb_connected || !dev->driver || (tmp & PW_PULLUP) == 0) + goto done; + + /* registers for (active) device and ep0 */ + t = snprintf(next, size, "\nirqs %lu\ndataset %02x " + "single.bcs %02x.%02x state %x addr %u\n", + dev->irqs, readl(®s->DataSet), + readl(®s->EPxSingle), readl(®s->EPxBCS), + readl(®s->UsbState), + readl(®s->address)); + size -= t; + next += t; + + tmp = readl(®s->dma_master); + t = snprintf(next, size, + "dma %03X =" EIGHTBITS "%s %s\n", tmp, + (tmp & MST_EOPB_DIS) ? " eopb-" : "", + (tmp & MST_EOPB_ENA) ? " eopb+" : "", + (tmp & MST_TIMEOUT_DIS) ? " tmo-" : "", + (tmp & MST_TIMEOUT_ENA) ? " tmo+" : "", + + (tmp & MST_RD_EOPB) ? " eopb" : "", + (tmp & MST_RD_RESET) ? " in_reset" : "", + (tmp & MST_WR_RESET) ? " out_reset" : "", + (tmp & MST_RD_ENA) ? " IN" : "", + + (tmp & MST_WR_ENA) ? " OUT" : "", + (tmp & MST_CONNECTION) + ? "ep1in/ep2out" + : "ep1out/ep2in"); + size -= t; + next += t; + + /* dump endpoint queues */ + for (i = 0; i < 4; i++) { + struct goku_ep *ep = &dev->ep [i]; + struct goku_request *req; + int t; + + if (i && !ep->desc) + continue; + + tmp = readl(ep->reg_status); + t = snprintf(next, size, + "%s %s max %u %s, irqs %lu, " + "status %02x (%s) " FOURBITS "\n", + ep->ep.name, + ep->is_in ? "in" : "out", + ep->ep.maxpacket, + ep->dma ? "dma" : "pio", + ep->irqs, + tmp, ({ char *s; + switch (tmp & EPxSTATUS_EP_MASK) { + case EPxSTATUS_EP_READY: + s = "ready"; break; + case EPxSTATUS_EP_DATAIN: + s = "packet"; break; + case EPxSTATUS_EP_FULL: + s = "full"; break; + case EPxSTATUS_EP_TX_ERR: // host will retry + s = "tx_err"; break; + case EPxSTATUS_EP_RX_ERR: + s = "rx_err"; break; + case EPxSTATUS_EP_BUSY: /* ep0 only */ + s = "busy"; break; + case EPxSTATUS_EP_STALL: + s = "stall"; break; + case EPxSTATUS_EP_INVALID: // these "can't happen" + s = "invalid"; break; + default: + s = "?"; break; + }; s; }), + (tmp & EPxSTATUS_TOGGLE) ? "data1" : "data0", + (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "", + (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "", + (tmp & EPxSTATUS_STAGE_ERROR) ? " ep0stat" : "" + ); + if (t <= 0 || t > size) + goto done; + size -= t; + next += t; + + if (list_empty(&ep->queue)) { + t = snprintf(next, size, "\t(nothing queued)\n"); + if (t <= 0 || t > size) + goto done; + size -= t; + next += t; + continue; + } + list_for_each_entry(req, &ep->queue, queue) { + if (ep->dma && req->queue.prev == &ep->queue) { + if (i == UDC_MSTRD_ENDPOINT) + tmp = readl(®s->in_dma_current); + else + tmp = readl(®s->out_dma_current); + tmp -= req->req.dma; + tmp++; + } else + tmp = req->req.actual; + + t = snprintf(next, size, + "\treq %p len %u/%u buf %p\n", + &req->req, tmp, req->req.length, + req->req.buf); + if (t <= 0 || t > size) + goto done; + size -= t; + next += t; + } + } + +done: + local_irq_restore(flags); + *eof = 1; + return count - size; +} + +#endif /* UDC_PROC_FILE */ + +/*-------------------------------------------------------------------------*/ + +static void udc_reinit (struct goku_udc *dev) +{ + static char *names [] = { "ep0", "ep1-bulk", "ep2-bulk", "ep3-bulk" }; + + unsigned i; + + INIT_LIST_HEAD (&dev->gadget.ep_list); + dev->gadget.ep0 = &dev->ep [0].ep; + dev->gadget.speed = USB_SPEED_UNKNOWN; + dev->ep0state = EP0_DISCONNECT; + dev->irqs = 0; + + for (i = 0; i < 4; i++) { + struct goku_ep *ep = &dev->ep[i]; + + ep->num = i; + ep->ep.name = names[i]; + ep->reg_fifo = &dev->regs->ep_fifo [i]; + ep->reg_status = &dev->regs->ep_status [i]; + ep->reg_mode = &dev->regs->ep_mode[i]; + + ep->ep.ops = &goku_ep_ops; + list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); + ep->dev = dev; + INIT_LIST_HEAD (&ep->queue); + + ep_reset(0, ep); + } + + dev->ep[0].reg_mode = 0; + dev->ep[0].ep.maxpacket = MAX_EP0_SIZE; + list_del_init (&dev->ep[0].ep.ep_list); +} + +static void udc_reset(struct goku_udc *dev) +{ + struct goku_udc_regs *regs = dev->regs; + + writel(0, ®s->power_detect); + writel(0, ®s->int_enable); + readl(®s->int_enable); + dev->int_enable = 0; + + /* deassert reset, leave USB D+ at hi-Z (no pullup) + * don't let INT_PWRDETECT sequence begin + */ + udelay(250); + writel(PW_RESETB, ®s->power_detect); + readl(®s->int_enable); +} + +static void ep0_start(struct goku_udc *dev) +{ + struct goku_udc_regs *regs = dev->regs; + unsigned i; + + VDBG(dev, "%s\n", __FUNCTION__); + + udc_reset(dev); + udc_reinit (dev); + //writel(MST_EOPB_ENA | MST_TIMEOUT_ENA, ®s->dma_master); + + /* hw handles set_address, set_feature, get_status; maybe more */ + writel( G_REQMODE_SET_INTF | G_REQMODE_GET_INTF + | G_REQMODE_SET_CONF | G_REQMODE_GET_CONF + | G_REQMODE_GET_DESC + | G_REQMODE_CLEAR_FEAT + , ®s->reqmode); + + for (i = 0; i < 4; i++) + dev->ep[i].irqs = 0; + + /* can't modify descriptors after writing UsbReady */ + for (i = 0; i < DESC_LEN; i++) + writel(0, ®s->descriptors[i]); + writel(0, ®s->UsbReady); + + /* expect ep0 requests when the host drops reset */ + writel(PW_RESETB | PW_PULLUP, ®s->power_detect); + dev->int_enable = INT_DEVWIDE | INT_EP0; + writel(dev->int_enable, &dev->regs->int_enable); + readl(®s->int_enable); + dev->gadget.speed = USB_SPEED_FULL; + dev->ep0state = EP0_IDLE; +} + +static void udc_enable(struct goku_udc *dev) +{ + /* start enumeration now, or after power detect irq */ + if (readl(&dev->regs->power_detect) & PW_DETECT) + ep0_start(dev); + else { + DBG(dev, "%s\n", __FUNCTION__); + dev->int_enable = INT_PWRDETECT; + writel(dev->int_enable, &dev->regs->int_enable); + } +} + +/*-------------------------------------------------------------------------*/ + +/* keeping it simple: + * - one bus driver, initted first; + * - one function driver, initted second + */ + +static struct goku_udc *the_controller; + +/* 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 goku_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; + + /* hook up the driver */ + dev->driver = driver; + retval = driver->bind(&dev->gadget); + if (retval) { + DBG(dev, "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. + */ + udc_enable(dev); + + DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); + return 0; +} +EXPORT_SYMBOL(usb_gadget_register_driver); + +static void +stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) +{ + unsigned i; + + DBG (dev, "%s\n", __FUNCTION__); + + if (dev->gadget.speed == USB_SPEED_UNKNOWN) + driver = 0; + + /* disconnect gadget driver after quiesceing hw and the driver */ + udc_reset (dev); + for (i = 0; i < 4; i++) + nuke(&dev->ep [i], -ESHUTDOWN); + if (driver) { + spin_unlock(&dev->lock); + driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + + if (dev->driver) + udc_enable(dev); +} + +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct goku_udc *dev = the_controller; + unsigned long flags; + + if (!dev) + return -ENODEV; + if (!driver || driver != dev->driver) + return -EINVAL; + + spin_lock_irqsave(&dev->lock, flags); + dev->driver = 0; + stop_activity(dev, driver); + spin_unlock_irqrestore(&dev->lock, flags); + + driver->unbind(&dev->gadget); + + DBG(dev, "unregistered driver '%s'\n", driver->driver.name); + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); + + +/*-------------------------------------------------------------------------*/ + +static void ep0_setup(struct goku_udc *dev) +{ + struct goku_udc_regs *regs = dev->regs; + struct usb_ctrlrequest ctrl; + int tmp; + + /* read SETUP packet and enter DATA stage */ + ctrl.bRequestType = readl(®s->bRequestType); + ctrl.bRequest = readl(®s->bRequest); + ctrl.wValue = (readl(®s->wValueH) << 8) | readl(®s->wValueL); + ctrl.wIndex = (readl(®s->wIndexH) << 8) | readl(®s->wIndexL); + ctrl.wLength = (readl(®s->wLengthH) << 8) | readl(®s->wLengthL); + writel(0, ®s->SetupRecv); + + nuke(&dev->ep[0], 0); + dev->ep[0].stopped = 0; + if (likely(ctrl.bRequestType & USB_DIR_IN)) { + dev->ep[0].is_in = 1; + dev->ep0state = EP0_IN; + /* detect early status stages */ + writel(ICONTROL_STATUSNAK, &dev->regs->IntControl); + } else { + dev->ep[0].is_in = 0; + dev->ep0state = EP0_OUT; + + /* NOTE: CLEAR_FEATURE is done in software so that we can + * synchronize transfer restarts after bulk IN stalls. data + * won't even enter the fifo until the halt is cleared. + */ + switch (ctrl.bRequest) { + case USB_REQ_CLEAR_FEATURE: + switch (ctrl.bRequestType) { + case USB_RECIP_ENDPOINT: + tmp = ctrl.wIndex & 0x0f; + /* active endpoint */ + if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) + goto stall; + if (ctrl.wIndex & USB_DIR_IN) { + if (!dev->ep[tmp].is_in) + goto stall; + } else { + if (dev->ep[tmp].is_in) + goto stall; + } + /* endpoint halt */ + if (ctrl.wValue != 0) + goto stall; + if (tmp) + goku_clear_halt(&dev->ep[tmp]); +succeed: + /* start ep0out status stage */ + writel(~(1<<0), ®s->EOP); + dev->ep[0].stopped = 1; + dev->ep0state = EP0_STATUS; + return; + case USB_RECIP_DEVICE: + /* device remote wakeup: always clear */ + if (ctrl.wValue != 1) + goto stall; + VDBG(dev, "clear dev remote wakeup\n"); + goto succeed; + case USB_RECIP_INTERFACE: + goto stall; + default: /* pass to gadget driver */ + break; + } + break; + default: + break; + } + } + +#ifdef USB_TRACE + VDBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", + ctrl.bRequestType, ctrl.bRequest, + ctrl.wValue, ctrl.wIndex, ctrl.wLength); +#endif + + /* hw wants to know when we're configured (or not) */ + dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION + && ctrl.bRequestType == USB_RECIP_DEVICE); + if (unlikely(dev->req_config)) + dev->configured = (ctrl.wValue != 0); + + /* delegate everything to the gadget driver. + * it may respond after this irq handler returns. + */ + spin_unlock (&dev->lock); + tmp = dev->driver->setup(&dev->gadget, &ctrl); + spin_lock (&dev->lock); + if (unlikely(tmp < 0)) { +stall: +#ifdef USB_TRACE + VDBG(dev, "req %02x.%02x protocol STALL; err %d\n", + ctrl.bRequestType, ctrl.bRequest, tmp); +#endif + command(regs, COMMAND_STALL, 0); + dev->ep[0].stopped = 1; + dev->ep0state = EP0_STALL; + } + + /* expect at least one data or status stage irq */ +} + +#define ACK(irqbit) { \ + stat &= ~irqbit; \ + writel(~irqbit, ®s->int_status); \ + handled = 1; \ + } + +static irqreturn_t goku_irq(int irq, void *_dev, struct pt_regs *r) +{ + struct goku_udc *dev = _dev; + struct goku_udc_regs *regs = dev->regs; + struct goku_ep *ep; + u32 stat, handled = 0; + unsigned i, rescans = 5; + + spin_lock(&dev->lock); + +rescan: + stat = readl(®s->int_status) & dev->int_enable; + if (!stat) + goto done; + dev->irqs++; + + /* device-wide irqs */ + if (unlikely(stat & INT_DEVWIDE)) { + if (stat & INT_SYSERROR) { + ERROR(dev, "system error\n"); + stop_activity(dev, dev->driver); + stat = 0; + handled = 1; + // FIXME have a neater way to prevent re-enumeration + dev->driver = 0; + goto done; + } + if (stat & INT_PWRDETECT) { + writel(~stat, ®s->int_status); + if (readl(&dev->regs->power_detect) & PW_DETECT) { + VDBG(dev, "connect\n"); + ep0_start(dev); + } else { + DBG(dev, "disconnect\n"); + if (dev->gadget.speed == USB_SPEED_FULL) + stop_activity(dev, dev->driver); + dev->ep0state = EP0_DISCONNECT; + dev->int_enable = INT_DEVWIDE; + writel(dev->int_enable, &dev->regs->int_enable); + } + stat = 0; + handled = 1; + goto done; + } + if (stat & INT_SUSPEND) { + ACK(INT_SUSPEND); + if (readl(®s->ep_status[0]) & EPxSTATUS_SUSPEND) { + switch (dev->ep0state) { + case EP0_DISCONNECT: + case EP0_SUSPEND: + goto pm_next; + default: + break; + } + DBG(dev, "USB suspend\n"); + dev->ep0state = EP0_SUSPEND; + if (dev->gadget.speed != USB_SPEED_UNKNOWN + && dev->driver + && dev->driver->suspend) { + spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); + } + } else { + if (dev->ep0state != EP0_SUSPEND) { + DBG(dev, "bogus USB resume %d\n", + dev->ep0state); + goto pm_next; + } + DBG(dev, "USB resume\n"); + dev->ep0state = EP0_IDLE; + if (dev->gadget.speed != USB_SPEED_UNKNOWN + && dev->driver + && dev->driver->resume) { + spin_unlock(&dev->lock); + dev->driver->resume(&dev->gadget); + spin_lock(&dev->lock); + } + } + } +pm_next: + if (stat & INT_USBRESET) { /* hub reset done */ + ACK(INT_USBRESET); + INFO(dev, "USB reset done, gadget %s\n", + dev->driver->driver.name); + } + // and INT_ERR on some endpoint's crc/bitstuff/... problem + } + + /* progress ep0 setup, data, or status stages. + * no transition {EP0_STATUS, EP0_STALL} --> EP0_IDLE; saves irqs + */ + if (stat & INT_SETUP) { + ACK(INT_SETUP); + dev->ep[0].irqs++; + ep0_setup(dev); + } + if (stat & INT_STATUSNAK) { + ACK(INT_STATUSNAK|INT_ENDPOINT0); + if (dev->ep0state == EP0_IN) { + ep = &dev->ep[0]; + ep->irqs++; + nuke(ep, 0); + writel(~(1<<0), ®s->EOP); + dev->ep0state = EP0_STATUS; + } + } + if (stat & INT_ENDPOINT0) { + ACK(INT_ENDPOINT0); + ep = &dev->ep[0]; + ep->irqs++; + pio_advance(ep); + } + + /* dma completion */ + if (stat & INT_MSTRDEND) { /* IN */ + ACK(INT_MSTRDEND); + ep = &dev->ep[UDC_MSTRD_ENDPOINT]; + ep->irqs++; + dma_advance(dev, ep); + } + if (stat & INT_MSTWREND) { /* OUT */ + ACK(INT_MSTWREND); + ep = &dev->ep[UDC_MSTWR_ENDPOINT]; + ep->irqs++; + dma_advance(dev, ep); + } + if (stat & INT_MSTWRTMOUT) { /* OUT */ + ACK(INT_MSTWRTMOUT); + ep = &dev->ep[UDC_MSTWR_ENDPOINT]; + ep->irqs++; + ERROR(dev, "%s write timeout ?\n", ep->ep.name); + // reset dma? then dma_advance() + } + + /* pio */ + for (i = 1; i < 4; i++) { + u32 tmp = INT_EPxDATASET(i); + + if (!(stat & tmp)) + continue; + ep = &dev->ep[i]; + pio_advance(ep); + if (list_empty (&ep->queue)) + pio_irq_disable(dev, regs, i); + stat &= ~tmp; + handled = 1; + ep->irqs++; + } + + if (rescans--) + goto rescan; + +done: + (void)readl(®s->int_enable); + spin_unlock(&dev->lock); + if (stat) + DBG(dev, "unhandled irq status: %05x (%05x, %05x)\n", stat, + readl(®s->int_status), dev->int_enable); + return IRQ_RETVAL(handled); +} + +#undef ACK + +/*-------------------------------------------------------------------------*/ + +/* tear down the binding between this driver and the pci device */ + +static void goku_remove(struct pci_dev *pdev) +{ + struct goku_udc *dev = pci_get_drvdata(pdev); + + DBG(dev, "%s\n", __FUNCTION__); + /* start with the driver above us */ + if (dev->driver) { + /* should have been done already by driver model core */ + WARN(dev, "pci remove, driver '%s' is still registered\n", + dev->driver->driver.name); + usb_gadget_unregister_driver(dev->driver); + } + +#ifdef UDC_PROC_FILE + remove_proc_entry(proc_node_name, NULL); +#endif + if (dev->regs) + udc_reset(dev); + if (dev->got_irq) + free_irq(pdev->irq, dev); + if (dev->regs) + iounmap(dev->regs); + if (dev->got_region) + release_mem_region(pci_resource_start (pdev, 0), + pci_resource_len (pdev, 0)); + if (dev->enabled) + pci_disable_device(pdev); + + pci_set_drvdata(pdev, 0); + dev->regs = 0; + the_controller = 0; + + INFO(dev, "unbind\n"); +} + +/* wrap this driver around the specified pci device, but + * don't respond over USB until a gadget driver binds to us. + */ + +static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct goku_udc *dev = 0; + unsigned long resource, len; + void *base = 0; + int retval; + char buf [8], *bufp; + + /* if you want to support more than one controller in a system, + * usb_gadget_driver_{register,unregister}() must change. + */ + if (the_controller) { + WARN(dev, "ignoring %s\n", pci_name(pdev)); + return -EBUSY; + } + if (!pdev->irq) { + printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); + retval = -ENODEV; + goto done; + } + + /* alloc, and start init */ + dev = kmalloc (sizeof *dev, SLAB_KERNEL); + if (dev == NULL){ + pr_debug("enomem %s\n", pci_name(pdev)); + retval = -ENOMEM; + goto done; + } + + memset(dev, 0, sizeof *dev); + spin_lock_init(&dev->lock); + dev->pdev = pdev; + dev->gadget.ops = &goku_ops; + + /* the "gadget" abstracts/virtualizes the controller */ + dev->gadget.dev.bus_id = "gadget"; + dev->gadget.name = driver_name; + + /* now all the pci goodies ... */ + retval = pci_enable_device(pdev); + if (retval < 0) { + DBG(dev, "can't enable, %d\n", retval); + goto done; + } + dev->enabled = 1; + + resource = pci_resource_start(pdev, 0); + len = pci_resource_len(pdev, 0); + if (!request_mem_region(resource, len, driver_name)) { + DBG(dev, "controller already in use\n"); + retval = -EBUSY; + goto done; + } + dev->got_region = 1; + + base = ioremap_nocache(resource, len); + if (base == NULL) { + DBG(dev, "can't map memory\n"); + retval = -EFAULT; + goto done; + } + dev->regs = (struct goku_udc_regs *) base; + + pci_set_drvdata(pdev, dev); + INFO(dev, "%s\n", driver_desc); + INFO(dev, "version: " DRIVER_VERSION " %s\n", dmastr()); +#ifndef __sparc__ + snprintf(buf, sizeof buf, "%d", pdev->irq); + bufp = buf; +#else + bufp = __irq_itoa(pdev->irq); +#endif + INFO(dev, "irq %s, pci mem %p\n", bufp, base); + + /* init to known state, then setup irqs */ + udc_reset(dev); + udc_reinit (dev); + if (request_irq(pdev->irq, goku_irq, SA_SHIRQ/*|SA_SAMPLE_RANDOM*/, + driver_name, dev) != 0) { + DBG(dev, "request interrupt %s failed\n", bufp); + retval = -EBUSY; + goto done; + } + dev->got_irq = 1; + if (use_dma) + pci_set_master(pdev); + + +#ifdef UDC_PROC_FILE + create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); +#endif + + /* done */ + the_controller = dev; + + return 0; + +done: + if (dev) + goku_remove (pdev); + return retval; +} + + +/*-------------------------------------------------------------------------*/ + +static struct pci_device_id pci_ids [] = { { + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class_mask = ~0, + .vendor = 0x102f, /* Toshiba */ + .device = 0x0107, /* this UDC */ + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + +}, { /* end: all zeroes */ } +}; +MODULE_DEVICE_TABLE (pci, pci_ids); + +static struct pci_driver goku_pci_driver = { + .name = (char *) driver_name, + .id_table = pci_ids, + + .probe = goku_probe, + .remove = goku_remove, + + /* FIXME add power management support */ +}; + +static int __init init (void) +{ + return pci_module_init (&goku_pci_driver); +} +module_init (init); + +static void __exit cleanup (void) +{ + pci_unregister_driver (&goku_pci_driver); +} +module_exit (cleanup); diff -urN linux-2.4.24/drivers/usb/gadget/goku_udc.h linux-2.4.25/drivers/usb/gadget/goku_udc.h --- linux-2.4.24/drivers/usb/gadget/goku_udc.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/goku_udc.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,321 @@ +/* + * Toshiba TC86C001 ("Goku-S") USB Device Controller driver + * + * Copyright (C) 2000-2002 Lineo + * by Stuart Lynne, Tom Rushworth, and Bruce Balden + * Copyright (C) 2002 Toshiba Corporation + * Copyright (C) 2003 MontaVista Software (source@mvista.com) + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* + * PCI BAR 0 points to these registers. + */ +struct goku_udc_regs { + /* irq management */ + u32 int_status; /* 0x000 */ + u32 int_enable; +#define INT_SUSPEND 0x00001 /* or resume */ +#define INT_USBRESET 0x00002 +#define INT_ENDPOINT0 0x00004 +#define INT_SETUP 0x00008 +#define INT_STATUS 0x00010 +#define INT_STATUSNAK 0x00020 +#define INT_EPxDATASET(n) (0x00020 << (n)) /* 0 < n < 4 */ +# define INT_EP1DATASET 0x00040 +# define INT_EP2DATASET 0x00080 +# define INT_EP3DATASET 0x00100 +#define INT_EPnNAK(n) (0x00100 < (n)) /* 0 < n < 4 */ +# define INT_EP1NAK 0x00200 +# define INT_EP2NAK 0x00400 +# define INT_EP3NAK 0x00800 +#define INT_SOF 0x01000 +#define INT_ERR 0x02000 +#define INT_MSTWRSET 0x04000 +#define INT_MSTWREND 0x08000 +#define INT_MSTWRTMOUT 0x10000 +#define INT_MSTRDEND 0x20000 +#define INT_SYSERROR 0x40000 +#define INT_PWRDETECT 0x80000 + +#define INT_DEVWIDE (INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND) +#define INT_EP0 (INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK) + + u32 dma_master; +#define MST_EOPB_DIS 0x0800 +#define MST_EOPB_ENA 0x0400 +#define MST_TIMEOUT_DIS 0x0200 +#define MST_TIMEOUT_ENA 0x0100 +#define MST_RD_EOPB 0x0080 /* write-only */ +#define MST_RD_RESET 0x0040 +#define MST_WR_RESET 0x0020 +#define MST_RD_ENA 0x0004 /* 1:start, 0:ignore */ +#define MST_WR_ENA 0x0002 /* 1:start, 0:ignore */ +#define MST_CONNECTION 0x0001 /* 0 for ep1out/ep2in */ + +#define MST_R_BITS (MST_EOPB_DIS|MST_EOPB_ENA \ + |MST_RD_ENA|MST_RD_RESET) +#define MST_W_BITS (MST_TIMEOUT_DIS|MST_TIMEOUT_ENA \ + |MST_WR_ENA|MST_WR_RESET) +#define MST_RW_BITS (MST_R_BITS|MST_W_BITS \ + |MST_CONNECTION) + +/* these values assume (dma_master & MST_CONNECTION) == 0 */ +#define UDC_MSTWR_ENDPOINT 1 +#define UDC_MSTRD_ENDPOINT 2 + + /* dma master write */ + u32 out_dma_start; + u32 out_dma_end; + u32 out_dma_current; + + /* dma master read */ + u32 in_dma_start; + u32 in_dma_end; + u32 in_dma_current; + + u32 power_detect; +#define PW_DETECT 0x04 +#define PW_RESETB 0x02 +#define PW_PULLUP 0x01 + + u8 _reserved0 [0x1d8]; + + /* endpoint registers */ + u32 ep_fifo [4]; /* 0x200 */ + u8 _reserved1 [0x10]; + u32 ep_mode [4]; /* only 1-3 valid */ + u8 _reserved2 [0x10]; + + u32 ep_status [4]; +#define EPxSTATUS_TOGGLE 0x40 +#define EPxSTATUS_SUSPEND 0x20 +#define EPxSTATUS_EP_MASK (0x07<<2) +# define EPxSTATUS_EP_READY (0<<2) +# define EPxSTATUS_EP_DATAIN (1<<2) +# define EPxSTATUS_EP_FULL (2<<2) +# define EPxSTATUS_EP_TX_ERR (3<<2) +# define EPxSTATUS_EP_RX_ERR (4<<2) +# define EPxSTATUS_EP_BUSY (5<<2) +# define EPxSTATUS_EP_STALL (6<<2) +# define EPxSTATUS_EP_INVALID (7<<2) +#define EPxSTATUS_FIFO_DISABLE 0x02 +#define EPxSTATUS_STAGE_ERROR 0x01 + + u8 _reserved3 [0x10]; + u32 EPxSizeLA[4]; +#define PACKET_ACTIVE (1<<7) +#define DATASIZE 0x7f + u8 _reserved3a [0x10]; + u32 EPxSizeLB[4]; /* only 1,2 valid */ + u8 _reserved3b [0x10]; + u32 EPxSizeHA[4]; /* only 1-3 valid */ + u8 _reserved3c [0x10]; + u32 EPxSizeHB[4]; /* only 1,2 valid */ + u8 _reserved4[0x30]; + + /* SETUP packet contents */ + u32 bRequestType; /* 0x300 */ + u32 bRequest; + u32 wValueL; + u32 wValueH; + u32 wIndexL; + u32 wIndexH; + u32 wLengthL; + u32 wLengthH; + + /* command interaction/handshaking */ + u32 SetupRecv; /* 0x320 */ + u32 CurrConfig; + u32 StdRequest; + u32 Request; + u32 DataSet; +#define DATASET_A(epnum) (1<<(2*(epnum))) +#define DATASET_B(epnum) (2<<(2*(epnum))) +#define DATASET_AB(epnum) (3<<(2*(epnum))) + u8 _reserved5[4]; + + u32 UsbState; +#define USBSTATE_CONFIGURED 0x04 +#define USBSTATE_ADDRESSED 0x02 +#define USBSTATE_DEFAULT 0x01 + + u32 EOP; + + u32 Command; /* 0x340 */ +#define COMMAND_SETDATA0 2 +#define COMMAND_RESET 3 +#define COMMAND_STALL 4 +#define COMMAND_INVALID 5 +#define COMMAND_FIFO_DISABLE 7 +#define COMMAND_FIFO_ENABLE 8 +#define COMMAND_INIT_DESCRIPTOR 9 +#define COMMAND_FIFO_CLEAR 10 /* also stall */ +#define COMMAND_STALL_CLEAR 11 +#define COMMAND_EP(n) ((n) << 4) + + u32 EPxSingle; + u8 _reserved6[4]; + u32 EPxBCS; + u8 _reserved7[8]; + u32 IntControl; +#define ICONTROL_STATUSNAK 1 + u8 _reserved8[4]; + + u32 reqmode; // 0x360 standard request mode, low 8 bits +#define G_REQMODE_SET_INTF (1<<7) +#define G_REQMODE_GET_INTF (1<<6) +#define G_REQMODE_SET_CONF (1<<5) +#define G_REQMODE_GET_CONF (1<<4) +#define G_REQMODE_GET_DESC (1<<3) +#define G_REQMODE_SET_FEAT (1<<2) +#define G_REQMODE_CLEAR_FEAT (1<<1) +#define G_REQMODE_GET_STATUS (1<<0) + + u32 ReqMode; + u8 _reserved9[0x18]; + u32 PortStatus; /* 0x380 */ + u8 _reserved10[8]; + u32 address; + u32 buff_test; + u8 _reserved11[4]; + u32 UsbReady; + u8 _reserved12[4]; + u32 SetDescStall; /* 0x3a0 */ + u8 _reserved13[0x45c]; + + /* hardware could handle limited GET_DESCRIPTOR duties */ +#define DESC_LEN 0x80 + u32 descriptors[DESC_LEN]; /* 0x800 */ + u8 _reserved14[0x600]; + +} __attribute__ ((packed)); + +#define MAX_FIFO_SIZE 64 +#define MAX_EP0_SIZE 8 /* ep0 fifo is bigger, though */ + + +/*-------------------------------------------------------------------------*/ + +/* DRIVER DATA STRUCTURES and UTILITIES */ + +struct goku_ep { + struct usb_ep ep; + struct goku_udc *dev; + unsigned long irqs; + + unsigned num:8, + dma:1, + is_in:1, + stopped:1; + + /* analogous to a host-side qh */ + struct list_head queue; + const struct usb_endpoint_descriptor *desc; + + u32 *reg_fifo; + u32 *reg_mode; + u32 *reg_status; +}; + +struct goku_request { + struct usb_request req; + struct list_head queue; + + unsigned mapped:1; +}; + +enum ep0state { + EP0_DISCONNECT, /* no host */ + EP0_IDLE, /* between STATUS ack and SETUP report */ + EP0_IN, EP0_OUT, /* data stage */ + EP0_STATUS, /* status stage */ + EP0_STALL, /* data or status stages */ + EP0_SUSPEND, /* usb suspend */ +}; + +struct goku_udc { + /* each pci device provides one gadget, several endpoints */ + struct usb_gadget gadget; + spinlock_t lock; + struct goku_ep ep[4]; + struct usb_gadget_driver *driver; + + enum ep0state ep0state; + unsigned got_irq:1, + got_region:1, + req_config:1, + configured:1, + enabled:1; + + /* pci state used to access those endpoints */ + struct pci_dev *pdev; + struct goku_udc_regs *regs; + u32 int_enable; + + /* statistics... */ + unsigned long irqs; +}; + +/*-------------------------------------------------------------------------*/ + +#define xprintk(dev,level,fmt,args...) \ + printk(level "%s %s: " fmt , driver_name , \ + pci_name(dev->pdev) , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while (0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/*-------------------------------------------------------------------------*/ + +/* 2.5 stuff that's sometimes missing in 2.4 */ + +#ifndef container_of +#define container_of list_entry +#endif + +#ifndef likely +#define likely(x) (x) +#define unlikely(x) (x) +#endif + +#ifndef BUG_ON +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) +#endif + +#ifndef WARN_ON +#define WARN_ON(x) do { } while (0) +#endif + +#ifndef IRQ_NONE +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef pci_name +#define pci_name(pdev) ((pdev)->slot_name) +#endif diff -urN linux-2.4.24/drivers/usb/gadget/net2280.c linux-2.4.25/drivers/usb/gadget/net2280.c --- linux-2.4.24/drivers/usb/gadget/net2280.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/net2280.c 2004-02-18 05:36:31.000000000 -0800 @@ -25,9 +25,6 @@ * rev1 chips. Rev1a silicon (0110) fixes almost all of them. */ -#define USE_DMA_CHAINING - - /* * Copyright (C) 2003 David Brownell * Copyright (C) 2003 NetChip Technologies @@ -47,14 +44,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define DEBUG 1 -// #define VERBOSE /* extra debug messages (success too) */ +#undef DEBUG /* messages on error and most fault paths */ +#undef VERBOSE /* extra debug messages (success too) */ #include #include #include #include -#include #include #include #include @@ -77,7 +73,7 @@ #define DRIVER_DESC "NetChip 2280 USB Peripheral Controller" -#define DRIVER_VERSION "Bastille Day 2003" +#define DRIVER_VERSION "2004 Jan 14" #define DMA_ADDR_INVALID (~(dma_addr_t)0) #define EP_DONTUSE 13 /* nonzero */ @@ -95,7 +91,23 @@ "ep-e", "ep-f", }; +/* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) + * use_dma_chaining -- dma descriptor queueing gives even more irq reduction + * + * The net2280 DMA engines are not tightly integrated with their FIFOs; + * not all cases are (yet) handled well in this driver or the silicon. + * Some gadget drivers work better with the dma support here than others. + * These two parameters let you use PIO or more aggressive DMA. + */ static int use_dma = 1; +static int use_dma_chaining = 0; + +MODULE_PARM (use_dma, "i"); +MODULE_PARM_DESC (use_dma, "true to use dma controllers"); + +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 @@ -103,9 +115,6 @@ */ static ushort fifo_mode = 0; -MODULE_PARM (use_dma, "i"); -MODULE_PARM_DESC (use_dma, "true to use dma controllers"); - MODULE_PARM (fifo_mode, "h"); MODULE_PARM_DESC (fifo_mode, "net2280 fifo mode"); @@ -162,6 +171,7 @@ /* ep_reset() has already been called */ ep->stopped = 0; + ep->out_overflow = 0; /* set speed-dependent max packet; may kick in high bandwidth */ set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max); @@ -169,8 +179,8 @@ /* FIFO lines can't go to different packets. PIO is ok, so * use it instead of troublesome (non-bulk) multi-packet DMA. */ - if (ep->is_in && ep->dma && (max % 4) != 0) { - DEBUG (ep->dev, "%s, no IN dma for maxpacket %d\n", + if (ep->dma && (max % 4) != 0 && use_dma_chaining) { + DEBUG (ep->dev, "%s, no dma for maxpacket %d\n", ep->ep.name, ep->ep.maxpacket); ep->dma = 0; } @@ -179,17 +189,21 @@ writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat); tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); if (tmp == USB_ENDPOINT_XFER_INT) { - /* not just because of erratum 0105; avoid ever - * kicking in the "toggle-irrelevant" mode. - */ - tmp = USB_ENDPOINT_XFER_BULK; + /* erratum 0105 workaround prevents hs NYET */ + if (dev->chiprev == 0100 + && dev->gadget.speed == USB_SPEED_HIGH + && !(desc->bEndpointAddress & USB_DIR_IN)) + writel ((1 << CLEAR_NAK_OUT_PACKETS_MODE), + &ep->regs->ep_rsp); } else if (tmp == USB_ENDPOINT_XFER_BULK) { /* catch some particularly blatant driver bugs */ if ((dev->gadget.speed == USB_SPEED_HIGH && max != 512) || (dev->gadget.speed == USB_SPEED_FULL - && max > 64)) + && max > 64)) { + spin_unlock_irqrestore (&dev->lock, flags); return -ERANGE; + } } ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; tmp <<= ENDPOINT_TYPE; @@ -205,11 +219,6 @@ writel (tmp, &ep->regs->ep_cfg); -#ifdef NET2280_DMA_OUT_WORKAROUND - if (!ep->is_in) - ep->dma = 0; -#endif - /* enable irqs */ if (!ep->dma) { /* pio, per-packet */ tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); @@ -388,6 +397,7 @@ } td->dmacount = 0; /* not VALID */ td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); + td->dmadesc = td->dmaaddr; req->td = td; } return &req->req; @@ -430,6 +440,9 @@ #elif defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE) #define USE_KMALLOC +#elif defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO) +#define USE_KMALLOC + /* FIXME there are other cases, including an x86-64 one ... */ #endif @@ -451,31 +464,23 @@ ep = container_of (_ep, struct net2280_ep, ep); if (!_ep) return 0; - *dma = DMA_ADDR_INVALID; - if (ep->dma) { + #if defined(USE_KMALLOC) - retval = kmalloc (bytes, gfp_flags); - if (retval) - *dma = virt_to_phys (retval); - -#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,5,58) -#warning Using dma_alloc_consistent even with sub-page allocations - /* the main problem with this call is that it wastes memory - * on typical 1/N page allocations: it allocates 1-N pages. - */ - retval = dma_alloc_coherent (&ep->dev->pdev->dev, - bytes, dma, gfp_flags); + retval = kmalloc(bytes, gfp_flags); + if (retval) + *dma = virt_to_phys(retval); #else -#error No dma-coherent memory allocator is available - /* pci_alloc_consistent works, but pci_free_consistent() - * isn't safe in_interrupt(). plus, in addition to the - * 1/Nth page weakness, it doesn't understand gfp_flags. + if (ep->dma) { + /* one problem with this call is that it wastes memory on + * typical 1/N page allocations: it allocates 1..N pages. + * another is that it always uses GFP_ATOMIC. */ -#endif +#warning Using pci_alloc_consistent even with buffers smaller than a page. + retval = pci_alloc_consistent(ep->dev->pdev, bytes, dma); } else - retval = kmalloc (bytes, gfp_flags); - + retval = kmalloc(bytes, gfp_flags); +#endif return retval; } @@ -488,9 +493,17 @@ ) { /* free memory into the right allocator */ #ifndef USE_KMALLOC - if (dma != DMA_ADDR_INVALID) - dma_free_coherent (ep->dev->pdev, bytes, dma); - else + if (dma != DMA_ADDR_INVALID) { + struct net2280_ep *ep; + + ep = container_of(_ep, struct net2280_ep, ep); + if (!_ep) + return; + /* one problem with this call is that some platforms + * don't allow it to be used in_irq(). + */ + pci_free_consistent(ep->dev->pdev, bytes, buf, dma); + } else #endif kfree (buf); } @@ -541,8 +554,11 @@ count -= 4; } - /* last fifo entry is "short" unless we wrote a full packet */ - if (total < ep->ep.maxpacket) { + /* last fifo entry is "short" unless we wrote a full packet. + * also explicitly validate last word in (periodic) transfers + * when maxpacket is not a multiple of 4 bytes. + */ + if (count || total < ep->ep.maxpacket) { tmp = count ? get_unaligned ((u32 *)buf) : count; cpu_to_le32s (&tmp); set_fifo_bytecount (ep, count & 0x03); @@ -555,6 +571,9 @@ /* work around erratum 0106: PCI and USB race over the OUT fifo. * caller guarantees chiprev 0100, out endpoint is NAKing, and * there's no real data in the fifo. + * + * NOTE: also used in cases where that erratum doesn't apply: + * where the host wrote "too much" data to us. */ static void out_flush (struct net2280_ep *ep) { @@ -599,13 +618,13 @@ /* erratum 0106 ... packets coming in during fifo reads might * be incompletely rejected. not all cases have workarounds. */ - if (ep->dev->chiprev == 0x0100) { + if (ep->dev->chiprev == 0x0100 + && ep->dev->gadget.speed == USB_SPEED_FULL) { + udelay (1); tmp = readl (&ep->regs->ep_stat); if ((tmp & (1 << NAK_OUT_PACKETS))) - /* cleanup = 1 */; - else if ((tmp & (1 << FIFO_FULL)) - /* don't break hs PING protocol ... */ - || ep->dev->gadget.speed == USB_SPEED_FULL) { + cleanup = 1; + else if ((tmp & (1 << FIFO_FULL))) { start_out_naking (ep); prevent = 1; } @@ -617,6 +636,15 @@ */ prefetchw (buf); count = readl (®s->ep_avail); + if (unlikely (count == 0)) { + udelay (1); + tmp = readl (&ep->regs->ep_stat); + count = readl (®s->ep_avail); + /* handled that data already? */ + if (count == 0 && (tmp & (1 << NAK_OUT_PACKETS)) == 0) + return 0; + } + tmp = req->req.length - req->req.actual; if (count > tmp) { /* as with DMA, data overflow gets flushed */ @@ -626,7 +654,10 @@ ep->ep.name, count, tmp); req->req.status = -EOVERFLOW; cleanup = 1; - } + /* NAK_OUT_PACKETS will be set, so flushing is safe; + * the next read will start with the next packet + */ + } /* else it's a ZLP, no worries */ count = tmp; } req->req.actual += count; @@ -665,7 +696,7 @@ } /* fill out dma descriptor to match a given request */ -static inline void +static void fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid) { struct net2280_dma *td = req->td; @@ -678,15 +709,13 @@ */ if (ep->is_in) dmacount |= (1 << DMA_DIRECTION); - else + else if ((dmacount % ep->ep.maxpacket) != 0) dmacount |= (1 << END_OF_CHAIN); req->valid = valid; if (valid) dmacount |= (1 << VALID_BIT); -#ifdef USE_DMA_CHAINING - if (!req->req.no_interrupt) -#endif + if (likely(!req->req.no_interrupt || !use_dma_chaining)) dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE); /* td->dmadesc = previously set by caller */ @@ -698,7 +727,8 @@ } static const u32 dmactl_default = - (1 << DMA_CLEAR_COUNT_ENABLE) + (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) + | (1 << DMA_CLEAR_COUNT_ENABLE) /* erratum 0116 workaround part 1 (use POLLING) */ | (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) | (1 << DMA_VALID_BIT_POLLING_ENABLE) @@ -714,18 +744,41 @@ static inline void stop_dma (struct net2280_dma_regs *dma) { - writel (dmactl_default & ~(1 << DMA_ENABLE), &dma->dmactl); + writel (readl (&dma->dmactl) & ~(1 << DMA_ENABLE), &dma->dmactl); spin_stop_dma (dma); } +static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) +{ + struct net2280_dma_regs *dma = ep->dma; + + writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION), + &dma->dmacount); + writel (readl (&dma->dmastat), &dma->dmastat); + + writel (td_dma, &dma->dmadesc); + writel (dmactl, &dma->dmactl); + + /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ + (void) readl (&ep->dev->pci->pcimstctl); + + writel ((1 << DMA_START), &dma->dmastat); + + if (!ep->is_in) + stop_out_naking (ep); +} + static void start_dma (struct net2280_ep *ep, struct net2280_request *req) { u32 tmp; - int clear_nak = 0; struct net2280_dma_regs *dma = ep->dma; /* FIXME can't use DMA for ZLPs */ + /* on this path we "know" there's no dma active (yet) */ + WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE)); + writel (0, &ep->dma->dmactl); + /* previous OUT packet might have been short */ if (!ep->is_in && ((tmp = readl (&ep->regs->ep_stat)) & (1 << NAK_OUT_PACKETS)) != 0) { @@ -733,9 +786,9 @@ &ep->regs->ep_stat); tmp = readl (&ep->regs->ep_avail); - if (tmp == 0) - clear_nak = 1; - else { + if (tmp) { + writel (readl (&dma->dmastat), &dma->dmastat); + /* transfer all/some fifo data */ writel (req->req.dma, &dma->dmaaddr); tmp = min (tmp, req->req.length); @@ -744,6 +797,8 @@ req->td->dmacount = cpu_to_le32 (req->req.length - tmp); writel ((1 << DMA_DONE_INTERRUPT_ENABLE) | tmp, &dma->dmacount); + req->td->dmadesc = 0; + req->valid = 1; writel ((1 << DMA_ENABLE), &dma->dmactl); writel ((1 << DMA_START), &dma->dmastat); @@ -751,8 +806,6 @@ } } - /* on this path we know there's no dma queue (yet) */ - WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE)); tmp = dmactl_default; /* force packet boundaries between dma requests, but prevent the @@ -772,25 +825,10 @@ req->td->dmadesc = cpu_to_le32 (ep->td_dma); fill_dma_desc (ep, req, 1); -#ifdef USE_DMA_CHAINING - writel ( (1 << VALID_BIT) - | (ep->is_in << DMA_DIRECTION) - | 0, &dma->dmacount); -#else - req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN); -#endif - - writel (req->td_dma, &dma->dmadesc); - writel (tmp, &dma->dmactl); - - /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ - (void) readl (&ep->dev->pci->pcimstctl); + if (!use_dma_chaining) + req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN); - writel ((1 << DMA_START), &dma->dmastat); - - /* recover from previous short read; erratum 0112 workaround #1 */ - if (clear_nak) - writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); + start_queue (ep, tmp, req->td_dma); } static inline void @@ -893,7 +931,6 @@ _req->status = -EINPROGRESS; _req->actual = 0; - req->dma_done = 0; /* kickstart this i/o queue? */ if (list_empty (&ep->queue) && !ep->stopped) { @@ -977,10 +1014,11 @@ ) { req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount); - rmb (); done (ep, req, status); } +static void restart_dma (struct net2280_ep *ep); + static void scan_dma_completions (struct net2280_ep *ep) { /* only look at descriptors that were "naturally" retired, @@ -1000,14 +1038,37 @@ break; /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short" - * packets, including overruns, even when the transfer was - * exactly the length requested (dmacount now zero). - * FIXME there's an overrun case here too, where we expect - * a short packet but receive a max length one (won't NAK). + * cases where DMA must be aborted; this code handles + * all non-abort DMA completions. */ - if (!ep->is_in && (req->req.length % ep->ep.maxpacket) != 0) { - req->dma_done = 1; + if (unlikely (req->td->dmadesc == 0)) { + /* paranoia */ + tmp = readl (&ep->dma->dmacount); + if (tmp & DMA_BYTE_COUNT_MASK) + break; + /* single transfer mode */ + dma_done (ep, req, tmp, 0); break; + } else if (!ep->is_in + && (req->req.length % ep->ep.maxpacket) != 0) { + tmp = readl (&ep->regs->ep_stat); + + /* AVOID TROUBLE HERE by not issuing short reads from + * your gadget driver. That helps avoids errata 0121, + * 0122, and 0124; not all cases trigger the warning. + */ + if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { + WARN (ep->dev, "%s lost packet sync!\n", + ep->ep.name); + req->req.status = -EOVERFLOW; + } else if ((tmp = readl (&ep->regs->ep_avail)) != 0) { + /* fifo gets flushed later */ + ep->out_overflow = 1; + DEBUG (ep->dev, "%s dma, discard %d len %d\n", + ep->ep.name, tmp, + req->req.length); + req->req.status = -EOVERFLOW; + } } dma_done (ep, req, tmp, 0); } @@ -1016,41 +1077,50 @@ static void restart_dma (struct net2280_ep *ep) { struct net2280_request *req; + u32 dmactl = dmactl_default; if (ep->stopped) return; req = list_entry (ep->queue.next, struct net2280_request, queue); -#ifdef USE_DMA_CHAINING + if (!use_dma_chaining) { + start_dma (ep, req); + return; + } + /* the 2280 will be processing the queue unless queue hiccups after * the previous transfer: * IN: wanted automagic zlp, head doesn't (or vice versa) + * DMA_FIFO_VALIDATE doesn't init from dma descriptors. * OUT: was "usb-short", we must restart. */ - if (!req->valid) { + if (ep->is_in && !req->valid) { struct net2280_request *entry, *prev = 0; - int qmode, reqmode, done = 0; + int reqmode, done = 0; DEBUG (ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); - qmode = likely (req->req.zero + ep->in_fifo_validate = likely (req->req.zero || (req->req.length % ep->ep.maxpacket) != 0); + if (ep->in_fifo_validate) + dmactl |= (1 << DMA_FIFO_VALIDATE); list_for_each_entry (entry, &ep->queue, queue) { u32 dmacount; - if (entry != req) + if (entry == req) continue; dmacount = entry->td->dmacount; if (!done) { reqmode = likely (entry->req.zero || (entry->req.length % ep->ep.maxpacket) != 0); - if (reqmode == qmode) { + if (reqmode == ep->in_fifo_validate) { entry->valid = 1; dmacount |= valid_bit; entry->td->dmacount = dmacount; prev = entry; continue; } else { + /* force a hiccup */ prev->td->dmacount |= dma_done_ie; done = 1; } @@ -1062,22 +1132,21 @@ entry->td->dmacount = dmacount; prev = entry; } - start_dma (ep, req); - } else if (!ep->is_in - && (readl (&ep->regs->ep_stat) - & (1 << NAK_OUT_PACKETS)) != 0) - start_dma (ep, req); -#else - start_dma (ep, req); -#endif + } + + writel (0, &ep->dma->dmactl); + start_queue (ep, dmactl, req->td_dma); } -static inline void abort_dma (struct net2280_ep *ep) +static void abort_dma (struct net2280_ep *ep) { /* abort the current transfer */ - writel ((1 << DMA_ABORT), &ep->dma->dmastat); - - /* collect completed transfers (except the current one) */ + if (likely (!list_empty (&ep->queue))) { + /* FIXME work around errata 0121, 0122, 0124 */ + writel ((1 << DMA_ABORT), &ep->dma->dmastat); + spin_stop_dma (ep->dma); + } else + stop_dma (ep->dma); scan_dma_completions (ep); } @@ -1108,43 +1177,53 @@ int stopped; ep = container_of (_ep, struct net2280_ep, ep); - req = container_of (_req, struct net2280_request, req); if (!_ep || (!ep->desc && ep->num != 0) || !_req) return -EINVAL; spin_lock_irqsave (&ep->dev->lock, flags); stopped = ep->stopped; - /* pause dma while we scan the queue */ + /* quiesce dma while we patch the queue */ dmactl = 0; ep->stopped = 1; if (ep->dma) { dmactl = readl (&ep->dma->dmactl); - writel (dmactl & ~(1 << DMA_ENABLE), &ep->dma->dmactl); - /* force synch, clean any completed requests */ - spin_stop_dma (ep->dma); + /* WARNING erratum 0127 may kick in ... */ + stop_dma (ep->dma); scan_dma_completions (ep); } + /* 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 (&ep->dev->lock, flags); + return -EINVAL; + } + /* queue head may be partially complete. */ if (ep->queue.next == &req->queue) { if (ep->dma) { DEBUG (ep->dev, "unlink (%s) dma\n", _ep->name); _req->status = -ECONNRESET; abort_dma (ep); - if (likely (ep->queue.next == &req->queue)) + if (likely (ep->queue.next == &req->queue)) { + // NOTE: misreports single-transfer mode + req->td->dmacount = 0; /* invalidate */ dma_done (ep, req, - le32_to_cpup (&req->td->dmacount), + readl (&ep->dma->dmacount), -ECONNRESET); + } } else { DEBUG (ep->dev, "unlink (%s) pio\n", _ep->name); done (ep, req, -ECONNRESET); } req = 0; -#ifdef USE_DMA_CHAINING /* patch up hardware chaining data */ - } else if (ep->dma) { + } else if (ep->dma && use_dma_chaining) { if (req->queue.prev == ep->queue.next) { writel (le32_to_cpu (req->td->dmadesc), &ep->dma->dmadesc); @@ -1161,7 +1240,6 @@ if (req->td->dmacount & dma_done_ie) prev->td->dmacount |= dma_done_ie; } -#endif } if (req) @@ -1188,10 +1266,14 @@ /*-------------------------------------------------------------------------*/ +static int net2280_fifo_status (struct usb_ep *_ep); + static int net2280_set_halt (struct usb_ep *_ep, int value) { struct net2280_ep *ep; + unsigned long flags; + int retval = 0; ep = container_of (_ep, struct net2280_ep, ep); if (!_ep || (!ep->desc && ep->num != 0)) @@ -1202,19 +1284,27 @@ == USB_ENDPOINT_XFER_ISOC) return -EINVAL; - VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear"); - - /* set/clear, then synch memory views with the device */ - if (value) { - if (ep->num == 0) - ep->dev->protocol_stall = 1; - else - set_halt (ep); - } else - clear_halt (ep); - (void) readl (&ep->regs->ep_rsp); + spin_lock_irqsave (&ep->dev->lock, flags); + if (!list_empty (&ep->queue)) + retval = -EAGAIN; + else if (ep->is_in && value && net2280_fifo_status (_ep) != 0) + retval = -EAGAIN; + else { + VDEBUG (ep->dev, "%s %s halt\n", _ep->name, + value ? "set" : "clear"); + /* set/clear, then synch memory views with the device */ + if (value) { + if (ep->num == 0) + ep->dev->protocol_stall = 1; + else + set_halt (ep); + } else + clear_halt (ep); + (void) readl (&ep->regs->ep_rsp); + } + spin_unlock_irqrestore (&ep->dev->lock, flags); - return 0; + return retval; } static int @@ -1290,21 +1380,49 @@ static int net2280_wakeup (struct usb_gadget *_gadget) { struct net2280 *dev; + u32 tmp; + unsigned long flags; if (!_gadget) return 0; dev = container_of (_gadget, struct net2280, gadget); - writel (1 << GENERATE_RESUME, &dev->usb->usbstat); + + spin_lock_irqsave (&dev->lock, flags); + tmp = readl (&dev->usb->usbctl); + if (tmp & (1 << DEVICE_REMOTE_WAKEUP_ENABLE)) + writel (1 << GENERATE_RESUME, &dev->usb->usbstat); + spin_unlock_irqrestore (&dev->lock, flags); /* pci writes may still be posted */ return 0; } +static int net2280_set_selfpowered (struct usb_gadget *_gadget, int value) +{ + struct net2280 *dev; + u32 tmp; + unsigned long flags; + + if (!_gadget) + return 0; + dev = container_of (_gadget, struct net2280, gadget); + + spin_lock_irqsave (&dev->lock, flags); + tmp = readl (&dev->usb->usbctl); + if (value) + tmp |= (1 << SELF_POWERED_STATUS); + else + tmp &= ~(1 << SELF_POWERED_STATUS); + writel (tmp, &dev->usb->usbctl); + spin_unlock_irqrestore (&dev->lock, flags); + + return 0; +} + static const struct usb_gadget_ops net2280_ops = { .get_frame = net2280_get_frame, .wakeup = net2280_wakeup, - - // .set_selfpowered = net2280_set_selfpowered, + .set_selfpowered = net2280_set_selfpowered, }; /*-------------------------------------------------------------------------*/ @@ -1348,11 +1466,14 @@ /* Main Control Registers */ t = snprintf (next, size, "%s version " DRIVER_VERSION - ", chiprev %04x\n" + ", chiprev %04x, dma %s\n\n" "devinit %03x fifoctl %08x gadget '%s'\n" "pci irqenb0 %02x irqenb1 %08x " "irqstat0 %04x irqstat1 %08x\n", driver_name, dev->chiprev, + use_dma + ? (use_dma_chaining ? "chaining" : "enabled") + : "disabled", readl (&dev->regs->devinit), readl (&dev->regs->fifoctl), s, @@ -1399,7 +1520,7 @@ t1 = readl (&ep->regs->ep_cfg); t2 = readl (&ep->regs->ep_rsp) & 0xff; t = snprintf (next, size, - "%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" + "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" "irqenb %02x\n", ep->ep.name, t1, t2, (t2 & (1 << CLEAR_NAK_OUT_PACKETS)) @@ -1453,7 +1574,7 @@ // none yet /* Statistics */ - t = snprintf (next, size, "irqs: "); + t = snprintf (next, size, "\nirqs: "); size -= t; next += t; for (i = 0; i < 7; i++) { @@ -1462,7 +1583,7 @@ ep = &dev->ep [i]; if (i && !ep->irqs) continue; - t = snprintf (next, size, " %s/%ld", ep->ep.name, ep->irqs); + t = snprintf (next, size, " %s/%lu", ep->ep.name, ep->irqs); size -= t; next += t; @@ -1504,7 +1625,7 @@ continue; t = d->bEndpointAddress; t = snprintf (next, size, - "%s (ep%d%s-%s) max %04x %s\n", + "\n%s (ep%d%s-%s) max %04x %s fifo %d\n", ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK, (t & USB_DIR_IN) ? "in" : "out", ({ char *val; @@ -1517,7 +1638,7 @@ val = "iso"; break; }; val; }), le16_to_cpu (d->wMaxPacketSize) & 0x1fff, - ep->dma ? "dma" : "pio" + ep->dma ? "dma" : "pio", ep->fifo_size ); } else /* ep0 should only have one transfer queued */ t = snprintf (next, size, "ep0 max 64 pio %s\n", @@ -1552,6 +1673,20 @@ goto done; size -= t; next += t; + + if (ep->dma) { + struct net2280_dma *td; + + td = req->td; + t = snprintf (next, size, "\t td %08x " + " count %08x buf %08x desc %08x\n", + req->td_dma, td->dmacount, + td->dmaaddr, td->dmadesc); + if (t <= 0 || t > size) + goto done; + size -= t; + next += t; + } } } @@ -1686,8 +1821,10 @@ /* clear old dma and irq state */ for (tmp = 0; tmp < 4; tmp++) { - writel ((1 << DMA_ABORT), &dev->dma [tmp].dmastat); - stop_dma (&dev->dma [tmp]); + struct net2280_ep *ep = &dev->ep [tmp + 1]; + + if (ep->dma) + abort_dma (ep); } writel (~0, &dev->regs->irqstat0), writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), @@ -1767,7 +1904,7 @@ | (1 << SELF_POWERED_USB_DEVICE) | (1 << REMOTE_WAKEUP_SUPPORT) | (1 << USB_DETECT_ENABLE) - | (1 << DEVICE_REMOTE_WAKEUP_ENABLE) + | (1 << SELF_POWERED_STATUS) , &dev->usb->usbctl); /* enable irqs so we can see ep0 and general operation */ @@ -1939,6 +2076,8 @@ ep->stopped = 1; set_halt (ep); } + if (!req) + allow_status (ep); mode = 2; /* reply to extra IN data tokens with a zlp */ } else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) { @@ -1979,41 +2118,62 @@ if (likely (ep->dma != 0)) { if (t & (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)) { u32 count; + int stopped = ep->stopped; /* TRANSFERRED works around OUT_DONE erratum 0112. * we expect (N <= maxpacket) bytes; host wrote M. * iff (M < N) we won't ever see a DMA interrupt. */ - count = readl (&ep->dma->dmacount); - count &= DMA_BYTE_COUNT_MASK; - if (!req->dma_done) { - /* dma can finish with the FIFO non-empty, - * on (M > N) errors. + ep->stopped = 1; + for (count = 0; ; t = readl (&ep->regs->ep_stat)) { + + /* any preceding dma transfers must finish. + * dma handles (M >= N), may empty the queue + */ + scan_dma_completions (ep); + if (unlikely (list_empty (&ep->queue) + || ep->out_overflow)) { + req = 0; + break; + } + req = list_entry (ep->queue.next, + struct net2280_request, queue); + + /* here either (M < N), a "real" short rx; + * or (M == N) and the queue didn't empty */ - while (count && (t & (1 << FIFO_EMPTY)) == 0) { - cpu_relax (); - t = readl (&ep->regs->ep_stat); + if (likely (t & (1 << FIFO_EMPTY))) { count = readl (&ep->dma->dmacount); count &= DMA_BYTE_COUNT_MASK; + if (readl (&ep->dma->dmadesc) + != req->td_dma) + req = 0; + break; } + udelay(1); } /* stop DMA, leave ep NAKing */ writel ((1 << DMA_ABORT), &ep->dma->dmastat); spin_stop_dma (ep->dma); - /* buffer might have been too small */ - t = readl (&ep->regs->ep_avail); - if (t != 0) - DEBUG (ep->dev, "%s dma, discard %d len %d\n", - ep->ep.name, t, count); - dma_done (ep, req, count, t ? -EOVERFLOW : 0); + if (likely (req != 0)) { + req->td->dmacount = 0; + t = readl (&ep->regs->ep_avail); + dma_done (ep, req, count, t); + } /* also flush to prevent erratum 0106 trouble */ - if (t || ep->dev->chiprev == 0x0100) + if (unlikely (ep->out_overflow + || (ep->dev->chiprev == 0x0100 + && ep->dev->gadget.speed + == USB_SPEED_FULL))) { out_flush (ep); + ep->out_overflow = 0; + } - /* restart dma (still NAKing OUT!) if needed */ + /* (re)start dma if needed, stop NAKing */ + ep->stopped = stopped; if (!list_empty (&ep->queue)) restart_dma (ep); } else @@ -2184,11 +2344,12 @@ * that'll mean a lot less irqs for some drivers. */ ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0; - if (ep->is_in) + if (ep->is_in) { scratch = (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | (1 << DATA_IN_TOKEN_INTERRUPT); - else + stop_out_naking (ep); + } else scratch = (1 << DATA_PACKET_RECEIVED_INTERRUPT) | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | (1 << DATA_IN_TOKEN_INTERRUPT); @@ -2390,18 +2551,18 @@ tmp = readl (&dma->dmastat); writel (tmp, &dma->dmastat); -#ifdef USE_DMA_CHAINING - /* chaining should stop only on error (which?) + /* chaining should stop on abort, short OUT from fifo, * or (stat0 codepath) short OUT transfer. */ -#else - if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) == 0) { - DEBUG (ep->dev, "%s no xact done? %08x\n", - ep->ep.name, tmp); - continue; + if (!use_dma_chaining) { + if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) + == 0) { + DEBUG (ep->dev, "%s no xact done? %08x\n", + ep->ep.name, tmp); + continue; + } + stop_dma (ep->dma); } - stop_dma (ep->dma); -#endif /* OUT transfers terminate when the data from the * host is in our memory. Process whatever's done. @@ -2417,16 +2578,14 @@ /* disable dma on inactive queues; else maybe restart */ if (list_empty (&ep->queue)) { -#ifdef USE_DMA_CHAINING - stop_dma (ep->dma); -#endif + if (use_dma_chaining) + stop_dma (ep->dma); } else { tmp = readl (&dma->dmactl); - if ((tmp & (1 << DMA_SCATTER_GATHER_ENABLE)) == 0 + if (!use_dma_chaining || (tmp & (1 << DMA_ENABLE)) == 0) restart_dma (ep); -#ifdef USE_DMA_CHAINING - else if (ep->desc->bEndpointAddress & USB_DIR_IN) { + else if (ep->is_in && use_dma_chaining) { struct net2280_request *req; u32 dmacount; @@ -2441,12 +2600,9 @@ dmacount &= __constant_cpu_to_le32 ( (1 << VALID_BIT) | DMA_BYTE_COUNT_MASK); - if (dmacount && (dmacount & valid_bit) == 0) { - stop_dma (ep->dma); + if (dmacount && (dmacount & valid_bit) == 0) restart_dma (ep); - } } -#endif } ep->irqs++; } @@ -2646,20 +2802,20 @@ } td->dmacount = 0; /* not VALID */ td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); + td->dmadesc = td->dmaaddr; dev->ep [i].dummy = td; } /* enable lower-overhead pci memory bursts during DMA */ - writel ((1 << PCI_RETRY_ABORT_ENABLE) - | (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) + writel ( (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) + // 256 write retries may not be enough... + // | (1 << PCI_RETRY_ABORT_ENABLE) | (1 << DMA_READ_MULTIPLE_ENABLE) | (1 << DMA_READ_LINE_ENABLE) , &dev->pci->pcimstctl); /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */ pci_set_master (pdev); -#ifdef HAVE_PCI_SET_MWI pci_set_mwi (pdev); -#endif /* ... also flushes any posted pci writes */ dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff; @@ -2669,15 +2825,10 @@ INFO (dev, "%s\n", driver_desc); INFO (dev, "irq %s, pci mem %p, chip rev %04x\n", bufp, base, dev->chiprev); - bufp = DRIVER_VERSION -#ifndef USE_DMA_CHAINING - " (no dma chain)" -#endif -#ifdef NET2280_DMA_OUT_WORKAROUND - " (no dma out)" -#endif - ; - INFO (dev, "version: %s\n", bufp); + INFO (dev, "version: " DRIVER_VERSION "; dma %s\n", + use_dma + ? (use_dma_chaining ? "chaining" : "enabled") + : "disabled"); the_controller = dev; return 0; @@ -2720,6 +2871,8 @@ static int __init init (void) { + if (!use_dma) + use_dma_chaining = 0; return pci_module_init (&net2280_pci_driver); } module_init (init); diff -urN linux-2.4.24/drivers/usb/gadget/net2280.h linux-2.4.25/drivers/usb/gadget/net2280.h --- linux-2.4.24/drivers/usb/gadget/net2280.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/net2280.h 2004-02-18 05:36:31.000000000 -0800 @@ -520,6 +520,7 @@ unsigned num : 8, fifo_size : 12, in_fifo_validate : 1, + out_overflow : 1, stopped : 1, is_in : 1, is_iso : 1; @@ -529,6 +530,7 @@ { /* ep0 only */ writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) + | (1 << CLEAR_NAK_OUT_PACKETS) | (1 << CLEAR_NAK_OUT_PACKETS_MODE) , &ep->regs->ep_rsp); ep->stopped = 1; @@ -546,7 +548,6 @@ dma_addr_t td_dma; struct list_head queue; unsigned mapped : 1, - dma_done : 1, valid : 1; }; @@ -559,8 +560,7 @@ unsigned enabled : 1, protocol_stall : 1, got_irq : 1, - region : 1, - selfpowered : 1; + region : 1; u16 chiprev; /* pci state used to access those endpoints */ diff -urN linux-2.4.24/drivers/usb/gadget/zero.c linux-2.4.25/drivers/usb/gadget/zero.c --- linux-2.4.24/drivers/usb/gadget/zero.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/gadget/zero.c 2004-02-18 05:36:31.000000000 -0800 @@ -106,18 +106,14 @@ * * CHIP ... hardware identifier * DRIVER_VERSION_NUM ... alerts the host side driver to differences - * EP0_MAXPACKET ... controls packetization of control requests * 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 ... unless we can run on bus power, USB_CONFIG_ATT_SELFPOWER + * 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 * - * hw_optimize(gadget) ... for any hardware tweaks we want to kick in - * before we enable our endpoints - * * add other defines for other portability issues, like hardware that * for some reason doesn't handle full speed bulk maxpacket of 64. */ @@ -133,28 +129,16 @@ * DMA channels to manage their FIFOs. It supports high speed. * Those endpoints can be arranged in any desired configuration. */ -#ifdef CONFIG_USB_ZERO_NET2280 +#ifdef CONFIG_USB_GADGET_NET2280 #define CHIP "net2280" #define DRIVER_VERSION_NUM 0x0111 -#define EP0_MAXPACKET 64 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 */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* supports remote wakeup, but this driver doesn't */ - -extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode); - -static inline void hw_optimize (struct usb_gadget *gadget) -{ - /* we can have bigger ep-a/ep-b fifos (2KB each, 4 packets - * for highspeed bulk) because we're not using ep-c/ep-d. - */ - net2280_set_fifo_mode (gadget, 1); -} #endif /* @@ -168,20 +152,15 @@ * can't use altsettings or reset the interfaces independently. * So stick to a single interface. */ -#ifdef CONFIG_USB_ZERO_PXA2XX +#ifdef CONFIG_USB_GADGET_PXA2XX #define CHIP "pxa2xx" #define DRIVER_VERSION_NUM 0x0113 -#define EP0_MAXPACKET 16 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 */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* supports remote wakeup, but this driver doesn't */ - -/* no hw optimizations to apply */ -#define hw_optimize(g) do {} while (0) #endif /* @@ -195,20 +174,15 @@ * in special situations. So this is a case of "choose it right * during enumeration" ... */ -#ifdef CONFIG_USB_ZERO_SA1100 +#ifdef CONFIG_USB_GADGET_SA1100 #define CHIP "sa1100" #define DRIVER_VERSION_NUM 0x0115 -#define EP0_MAXPACKET 8 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 */ -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* doesn't support remote wakeup? */ - -/* no hw optimizations to apply */ -#define hw_optimize(g) do {} while (0) #endif /* @@ -216,23 +190,19 @@ * * This has three semi-configurable full speed bulk/interrupt endpoints. */ -#ifdef CONFIG_USB_ZERO_GOKU +#ifdef CONFIG_USB_GADGET_GOKU #define CHIP "goku" #define DRIVER_VERSION_NUM 0x0116 -#define EP0_MAXPACKET 8 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 -#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* doesn't support remote wakeup */ - -#define hw_optimize(g) do {} while (0) #endif /*-------------------------------------------------------------------------*/ -#ifndef EP0_MAXPACKET +#ifndef EP_OUT_NUM # error Configure some USB peripheral controller driver! #endif @@ -241,10 +211,10 @@ */ #ifndef SELFPOWER -/* default: say we rely on bus power */ -#define SELFPOWER 0 +/* default: say we're self-powered */ +#define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* else: - * - SELFPOWER value must be USB_CONFIG_ATT_SELFPOWER + * - SELFPOWER value must be zero * - MAX_USB_POWER may be nonzero. */ #endif @@ -362,14 +332,13 @@ #define CONFIG_SOURCE_SINK 3 #define CONFIG_LOOPBACK 2 -static const struct usb_device_descriptor +static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, - .bMaxPacketSize0 = EP0_MAXPACKET, .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), @@ -481,7 +450,7 @@ .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static const struct usb_qualifier_descriptor +static struct usb_qualifier_descriptor dev_qualifier = { .bLength = sizeof dev_qualifier, .bDescriptorType = USB_DT_DEVICE_QUALIFIER, @@ -489,9 +458,6 @@ .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, - /* assumes ep0 uses the same value for both speeds ... */ - .bMaxPacketSize0 = EP0_MAXPACKET, - .bNumConfigurations = 2, }; @@ -975,7 +941,7 @@ if (number == dev->config) return 0; -#ifdef CONFIG_USB_ZERO_SA1100 +#ifdef CONFIG_USB_GADGET_SA1100 if (dev->config) { /* tx fifo is full, but we can't clear it...*/ INFO (dev, "can't change configurations\n"); @@ -983,7 +949,6 @@ } #endif zero_reset_config (dev); - hw_optimize (gadget); switch (number) { case CONFIG_SOURCE_SINK: @@ -1052,7 +1017,7 @@ case USB_REQ_GET_DESCRIPTOR: if (ctrl->bRequestType != USB_DIR_IN) - break; + goto unknown; switch (ctrl->wValue >> 8) { case USB_DT_DEVICE: @@ -1092,14 +1057,14 @@ /* currently two configs, two speeds */ case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != 0) - break; + goto unknown; spin_lock (&dev->lock); value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC); spin_unlock (&dev->lock); break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) - break; + goto unknown; *(u8 *)req->buf = dev->config; value = min (ctrl->wLength, (u16) 1); break; @@ -1110,7 +1075,7 @@ */ case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) - break; + goto unknown; spin_lock (&dev->lock); if (dev->config && ctrl->wIndex == 0 && ctrl->wValue == 0) { u8 config = dev->config; @@ -1130,7 +1095,7 @@ break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) - break; + goto unknown; if (!dev->config) break; if (ctrl->wIndex != 0) { @@ -1141,7 +1106,35 @@ value = min (ctrl->wLength, (u16) 1); break; + /* + * These are the same vendor-specific requests supported by + * Intel's USB 2.0 compliance test devices. We exceed that + * device spec by allowing multiple-packet requests. + */ + case 0x5b: /* control WRITE test -- fill the buffer */ + if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR)) + goto unknown; + if (ctrl->wValue || ctrl->wIndex) + break; + /* just read that many bytes into the buffer */ + if (ctrl->wLength > USB_BUFSIZ) + break; + value = ctrl->wLength; + break; + case 0x5c: /* control READ test -- return the buffer */ + if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR)) + goto unknown; + if (ctrl->wValue || ctrl->wIndex) + break; + /* expect those bytes are still in the buffer; send back */ + if (ctrl->wLength > USB_BUFSIZ + || ctrl->wLength != req->length) + break; + value = ctrl->wLength; + break; + default: +unknown: VDEBUG (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, @@ -1223,6 +1216,12 @@ dev->req->complete = zero_setup_complete; + device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; +#ifdef HIGHSPEED + /* assume ep0 uses the same value for both speeds ... */ + dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; +#endif + gadget->ep0->driver_data = dev; INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); diff -urN linux-2.4.24/drivers/usb/hid-core.c linux-2.4.25/drivers/usb/hid-core.c --- linux-2.4.24/drivers/usb/hid-core.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/hid-core.c 2004-02-18 05:36:31.000000000 -0800 @@ -1235,8 +1235,8 @@ { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_OKI, USB_VENDOR_ID_OKI_MULITI, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, - { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, { 0, 0 } }; diff -urN linux-2.4.24/drivers/usb/host/ehci-dbg.c linux-2.4.25/drivers/usb/host/ehci-dbg.c --- linux-2.4.24/drivers/usb/host/ehci-dbg.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/ehci-dbg.c 2004-02-18 05:36:31.000000000 -0800 @@ -73,6 +73,7 @@ buf[0] = 0; for (i = 0; i < HCS_N_PORTS (params); i++) { + // FIXME MIPS won't readb() ... byte = readb (&ehci->caps->portroute[(i>>1)]); sprintf(tmp, "%d ", ((i & 0x1) ? ((byte)&0xf) : ((byte>>4)&0xf))); @@ -125,7 +126,7 @@ #ifdef DEBUG static void __attribute__((__unused__)) -dbg_qtd (char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) +dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) { ehci_dbg (ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd, cpu_to_le32p (&qtd->hw_next), @@ -141,7 +142,7 @@ } static void __attribute__((__unused__)) -dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) +dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) { ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, qh, qh->hw_next, qh->hw_info1, qh->hw_info2, @@ -149,6 +150,36 @@ dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next); } +static void __attribute__((__unused__)) +dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) +{ + ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n", + label, itd->frame, itd, le32_to_cpu(itd->hw_next), itd->urb); + ehci_dbg (ehci, + " trans: %08x %08x %08x %08x %08x %08x %08x %08x\n", + le32_to_cpu(itd->hw_transaction[0]), + le32_to_cpu(itd->hw_transaction[1]), + le32_to_cpu(itd->hw_transaction[2]), + le32_to_cpu(itd->hw_transaction[3]), + le32_to_cpu(itd->hw_transaction[4]), + le32_to_cpu(itd->hw_transaction[5]), + le32_to_cpu(itd->hw_transaction[6]), + le32_to_cpu(itd->hw_transaction[7])); + ehci_dbg (ehci, + " buf: %08x %08x %08x %08x %08x %08x %08x\n", + le32_to_cpu(itd->hw_bufp[0]), + le32_to_cpu(itd->hw_bufp[1]), + le32_to_cpu(itd->hw_bufp[2]), + le32_to_cpu(itd->hw_bufp[3]), + le32_to_cpu(itd->hw_bufp[4]), + le32_to_cpu(itd->hw_bufp[5]), + le32_to_cpu(itd->hw_bufp[6])); + ehci_dbg (ehci, " index: %d %d %d %d %d %d %d %d\n", + itd->index[0], itd->index[1], itd->index[2], + itd->index[3], itd->index[4], itd->index[5], + itd->index[6], itd->index[7]); +} + static int __attribute__((__unused__)) dbg_status_buf (char *buf, unsigned len, char *label, u32 status) { @@ -571,7 +602,7 @@ spin_lock_irqsave (&ehci->lock, flags); /* Capability Registers */ - i = readw (&ehci->caps->hci_version); + i = HC_VERSION(readl (&ehci->caps->hc_capbase)); temp = snprintf (next, size, "%s\nEHCI %x.%02x, hcd state %d (driver " DRIVER_VERSION ")\n", pdev->dev.name, diff -urN linux-2.4.24/drivers/usb/host/ehci-hcd.c linux-2.4.25/drivers/usb/host/ehci-hcd.c --- linux-2.4.24/drivers/usb/host/ehci-hcd.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/ehci-hcd.c 2004-02-18 05:36:31.000000000 -0800 @@ -68,6 +68,9 @@ * * HISTORY: * + * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka, + * , updates by DB). + * * 2002-11-29 Correct handling for hw async_next register. * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared; * only scheduling is different, no arbitrary limitations. @@ -91,14 +94,16 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2003-Jun-19/2.4" +#define DRIVER_VERSION "2003-Dec-29/2.4" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" static const char hcd_name [] = "ehci_hcd"; -// #define EHCI_VERBOSE_DEBUG +#undef EHCI_VERBOSE_DEBUG +#undef EHCI_URB_TRACE + // #define have_split_iso #ifdef DEBUG @@ -333,8 +338,8 @@ spin_lock_init (&ehci->lock); ehci->caps = (struct ehci_caps *) hcd->regs; - ehci->regs = (struct ehci_regs *) (hcd->regs + - readb (&ehci->caps->length)); + ehci->regs = (struct ehci_regs *) (hcd->regs + + HC_LENGTH (readl (&ehci->caps->hc_capbase))); dbg_hcs_params (ehci, "ehci_start"); dbg_hcc_params (ehci, "ehci_start"); @@ -486,7 +491,7 @@ /* PCI Serial Bus Release Number is at 0x60 offset */ pci_read_config_byte (hcd->pdev, 0x60, &tempbyte); - temp = readw (&ehci->caps->hci_version); + temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, "USB %x.%x enabled, EHCI %x.%02x, driver %s\n", ((tempbyte & 0xf0)>>4), (tempbyte & 0x0f), @@ -895,8 +900,16 @@ struct ehci_qh *qh; char *why; - /* dev->ep never has ITDs or SITDs */ + /* dev->ep is a QH unless info1.maxpacket of zero + * marks an iso stream head. + * FIXME do something smarter here with ISO + */ qh = (struct ehci_qh *) dev->ep [i]; + if (qh->hw_info1 == 0) { + ehci_err (ehci, "no iso cleanup!!\n"); + continue; + } + /* detect/report non-recoverable errors */ if (in_interrupt ()) diff -urN linux-2.4.24/drivers/usb/host/ehci-mem.c linux-2.4.25/drivers/usb/host/ehci-mem.c --- linux-2.4.24/drivers/usb/host/ehci-mem.c 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/usb/host/ehci-mem.c 2004-02-18 05:36:31.000000000 -0800 @@ -28,7 +28,7 @@ * - driver buffers, read/written by HC ... single shot DMA mapped * * There's also PCI "register" data, which is memory mapped. - * No memory seen by this driver is pagable. + * No memory seen by this driver is pageable. */ /*-------------------------------------------------------------------------*/ @@ -130,6 +130,7 @@ } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); + // usb_put_dev (qh->dev); pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); } diff -urN linux-2.4.24/drivers/usb/host/ehci-q.c linux-2.4.25/drivers/usb/host/ehci-q.c --- linux-2.4.24/drivers/usb/host/ehci-q.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/ehci-q.c 2004-02-18 05:36:31.000000000 -0800 @@ -225,6 +225,16 @@ } spin_unlock (&urb->lock); +#ifdef EHCI_URB_TRACE + ehci_dbg (ehci, + "%s %s urb %p ep%d%s status %d len %d/%d\n", + __FUNCTION__, urb->dev->devpath, urb, + usb_pipeendpoint (urb->pipe), + usb_pipein (urb->pipe) ? "in" : "out", + urb->status, + urb->actual_length, urb->transfer_buffer_length); +#endif + /* complete() can reenter this HCD */ spin_unlock (&ehci->lock); usb_hcd_giveback_urb (&ehci->hcd, urb, regs); @@ -673,6 +683,10 @@ qh->period = urb->interval; } + + /* support for tt scheduling */ + // qh->dev = usb_get_dev (urb->dev); + qh->dev = urb->dev; } /* using TT? */ @@ -732,8 +746,6 @@ usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); return qh; } -#undef hb_mult -#undef hb_packet /*-------------------------------------------------------------------------*/ @@ -929,10 +941,14 @@ if (usb_pipein (urb->pipe) && !usb_pipecontrol (urb->pipe)) epnum |= 0x10; - ehci_vdbg (ehci, "submit_async urb %p len %d ep%d%s qtd %p [qh %p]\n", - urb, urb->transfer_buffer_length, - epnum & 0x0f, (epnum & 0x10) ? "in" : "out", +#ifdef EHCI_URB_TRACE + ehci_dbg (ehci, + "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", + __FUNCTION__, urb->dev->devpath, urb, + epnum & 0x0f, usb_pipein (urb->pipe) ? "in" : "out", + urb->transfer_buffer_length, qtd, dev ? dev->ep [epnum] : (void *)~0); +#endif spin_lock_irqsave (&ehci->lock, flags); qh = qh_append_tds (ehci, urb, qtd_list, epnum, &dev->ep [epnum]); diff -urN linux-2.4.24/drivers/usb/host/ehci-sched.c linux-2.4.25/drivers/usb/host/ehci-sched.c --- linux-2.4.24/drivers/usb/host/ehci-sched.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/ehci-sched.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2001-2002 by David Brownell + * Copyright (c) 2001-2003 by David Brownell + * Copyright (c) 2003 Michal Sojka, for high-speed iso transfers * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -27,10 +28,10 @@ * Note that for interrupt transfers, the QH/QTD manipulation is shared * with the "asynchronous" transaction support (control/bulk transfers). * The only real difference is in how interrupt transfers are scheduled. - * We get some funky API restrictions from the current URB model, which - * works notably better for reading transfers than for writing. (And - * which accordingly needs to change before it'll work inside devices, - * or with "USB On The Go" additions to USB 2.0 ...) + * + * For ISO, we make an "iso_stream" head to serve the same role as a QH. + * It keeps track of every ITD (or SITD) that's linked, and holds enough + * pre-calculated schedule data to make appending to the queue be quick. */ static int ehci_get_frame (struct usb_hcd *hcd); @@ -126,9 +127,7 @@ q = &q->fstn->fstn_next; break; case Q_TYPE_ITD: - /* NOTE the "one uframe per itd" policy */ - if (q->itd->hw_transaction [uframe] != 0) - usecs += q->itd->usecs; + usecs += q->itd->usecs [uframe]; q = &q->itd->itd_next; break; #ifdef have_split_iso @@ -520,417 +519,649 @@ /*-------------------------------------------------------------------------*/ -static void -itd_free_list (struct ehci_hcd *ehci, struct urb *urb) +static inline struct ehci_iso_stream * +iso_stream_alloc (int mem_flags) { - struct ehci_itd *first_itd = urb->hcpriv; + struct ehci_iso_stream *stream; - while (!list_empty (&first_itd->itd_list)) { - struct ehci_itd *itd; - - itd = list_entry ( - first_itd->itd_list.next, - struct ehci_itd, itd_list); - list_del (&itd->itd_list); - pci_pool_free (ehci->itd_pool, itd, itd->itd_dma); + stream = kmalloc(sizeof *stream, mem_flags); + if (likely (stream != 0)) { + memset (stream, 0, sizeof(*stream)); + INIT_LIST_HEAD(&stream->itd_list); + INIT_LIST_HEAD(&stream->free_itd_list); + stream->next_uframe = -1; + stream->refcount = 1; } - pci_pool_free (ehci->itd_pool, first_itd, first_itd->itd_dma); - urb->hcpriv = 0; + return stream; } -static int -itd_fill ( - struct ehci_hcd *ehci, - struct ehci_itd *itd, - struct urb *urb, - unsigned index, // urb->iso_frame_desc [index] - dma_addr_t dma // mapped transfer buffer -) { - u64 temp; - u32 buf1; - unsigned i, epnum, maxp, multi; - unsigned length; - int is_input; - - itd->hw_next = EHCI_LIST_END; - itd->urb = urb; - itd->index = index; - - /* tell itd about its transfer buffer, max 2 pages */ - length = urb->iso_frame_desc [index].length; - dma += urb->iso_frame_desc [index].offset; - temp = dma & ~0x0fff; - for (i = 0; i < 2; i++) { - itd->hw_bufp [i] = cpu_to_le32 ((u32) temp); - itd->hw_bufp_hi [i] = cpu_to_le32 ((u32)(temp >> 32)); - temp += 0x1000; - } - itd->buf_dma = dma; +static inline void +iso_stream_init ( + struct ehci_iso_stream *stream, + struct usb_device *dev, + int pipe, + unsigned interval +) +{ + u32 buf1; + unsigned epnum, maxp, multi; + int is_input; + long bandwidth; /* * this might be a "high bandwidth" highspeed endpoint, - * as encoded in the ep descriptor's maxpacket field + * as encoded in the ep descriptor's wMaxPacket field */ - epnum = usb_pipeendpoint (urb->pipe); - is_input = usb_pipein (urb->pipe); + epnum = usb_pipeendpoint (pipe); + is_input = usb_pipein (pipe) ? USB_DIR_IN : 0; if (is_input) { - maxp = urb->dev->epmaxpacketin [epnum]; + maxp = dev->epmaxpacketin [epnum]; buf1 = (1 << 11); } else { - maxp = urb->dev->epmaxpacketout [epnum]; + maxp = dev->epmaxpacketout [epnum]; buf1 = 0; } - buf1 |= (maxp & 0x03ff); - multi = 1; - multi += (maxp >> 11) & 0x03; - maxp &= 0x03ff; + + multi = hb_mult(maxp); + maxp = max_packet(maxp); + buf1 |= maxp; maxp *= multi; - /* transfer can't fit in any uframe? */ - if (length < 0 || maxp < length) { - dbg ("BAD iso packet: %d bytes, max %d, urb %p [%d] (of %d)", - length, maxp, urb, index, - urb->iso_frame_desc [index].length); - return -ENOSPC; - } - itd->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 1, length); - - /* "plus" info in low order bits of buffer pointers */ - itd->hw_bufp [0] |= cpu_to_le32 ((epnum << 8) | urb->dev->devnum); - itd->hw_bufp [1] |= cpu_to_le32 (buf1); - itd->hw_bufp [2] |= cpu_to_le32 (multi); - - /* figure hw_transaction[] value (it's scheduled later) */ - itd->transaction = EHCI_ISOC_ACTIVE; - itd->transaction |= dma & 0x0fff; /* offset; buffer=0 */ - if ((index + 1) == urb->number_of_packets) - itd->transaction |= EHCI_ITD_IOC; /* end-of-urb irq */ - itd->transaction |= length << 16; - cpu_to_le32s (&itd->transaction); + stream->dev = (struct hcd_dev *)dev->hcpriv; + + stream->bEndpointAddress = is_input | epnum; + stream->interval = interval; + stream->maxp = maxp; + + stream->buf0 = cpu_to_le32 ((epnum << 8) | dev->devnum); + stream->buf1 = cpu_to_le32 (buf1); + stream->buf2 = cpu_to_le32 (multi); + + /* usbfs wants to report the average usecs per frame tied up + * when transfers on this endpoint are scheduled ... + */ + stream->usecs = HS_USECS_ISO (maxp); + bandwidth = stream->usecs * 8; + bandwidth /= 1 << (interval - 1); + stream->bandwidth = bandwidth; +} + +static void +iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) +{ + stream->refcount--; + + /* free whenever just a dev->ep reference remains. + * not like a QH -- no persistent state (toggle, halt) + */ + if (stream->refcount == 1) { + int is_in; + + // BUG_ON (!list_empty(&stream->itd_list)); + + while (!list_empty (&stream->free_itd_list)) { + struct ehci_itd *itd; + + itd = list_entry (stream->free_itd_list.next, + struct ehci_itd, itd_list); + list_del (&itd->itd_list); + pci_pool_free (ehci->itd_pool, itd, itd->itd_dma); + } + + is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; + stream->bEndpointAddress &= 0x0f; + stream->dev->ep [is_in + stream->bEndpointAddress] = 0; + + if (stream->rescheduled) { + ehci_info (ehci, "ep%d%s-iso rescheduled " + "%lu times in %lu seconds\n", + stream->bEndpointAddress, is_in ? "in" : "out", + stream->rescheduled, + ((jiffies - stream->start)/HZ) + ); + } + + kfree(stream); + } +} + +static inline struct ehci_iso_stream * +iso_stream_get (struct ehci_iso_stream *stream) +{ + if (likely (stream != 0)) + stream->refcount++; + return stream; +} + +static struct ehci_iso_stream * +iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) +{ + unsigned epnum; + struct hcd_dev *dev; + struct ehci_iso_stream *stream; + unsigned long flags; + + epnum = usb_pipeendpoint (urb->pipe); + if (usb_pipein(urb->pipe)) + epnum += 0x10; + + spin_lock_irqsave (&ehci->lock, flags); + + dev = (struct hcd_dev *)urb->dev->hcpriv; + stream = dev->ep [epnum]; + + if (unlikely (stream == 0)) { + stream = iso_stream_alloc(GFP_ATOMIC); + if (likely (stream != 0)) { + /* dev->ep owns the initial refcount */ + dev->ep[epnum] = stream; + iso_stream_init(stream, urb->dev, urb->pipe, + urb->interval); + } + + /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ + } else if (unlikely (stream->hw_info1 != 0)) { + ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", + urb->dev->devpath, epnum & 0x0f, + (epnum & 0x10) ? "in" : "out"); + stream = 0; + } + + /* caller guarantees an eventual matching iso_stream_put */ + stream = iso_stream_get (stream); + + spin_unlock_irqrestore (&ehci->lock, flags); + return stream; +} + +/*-------------------------------------------------------------------------*/ +static inline struct ehci_itd_sched * +itd_sched_alloc (unsigned packets, int mem_flags) +{ + struct ehci_itd_sched *itd_sched; + int size = sizeof *itd_sched; + + size += packets * sizeof (struct ehci_iso_uframe); + itd_sched = kmalloc (size, mem_flags); + if (likely (itd_sched != 0)) { + memset(itd_sched, 0, size); + INIT_LIST_HEAD (&itd_sched->itd_list); + } + return itd_sched; +} + +static int +itd_sched_init ( + struct ehci_itd_sched *itd_sched, + struct ehci_iso_stream *stream, + struct urb *urb +) +{ + unsigned i; + dma_addr_t dma = urb->transfer_dma; + + /* how many uframes are needed for these transfers */ + itd_sched->span = urb->number_of_packets * stream->interval; + + /* figure out per-uframe itd fields that we'll need later + * when we fit new itds into the schedule. + */ + for (i = 0; i < urb->number_of_packets; i++) { + struct ehci_iso_uframe *uframe = &itd_sched->packet [i]; + unsigned length; + dma_addr_t buf; + u32 trans; + + length = urb->iso_frame_desc [i].length; + buf = dma + urb->iso_frame_desc [i].offset; + + trans = EHCI_ISOC_ACTIVE; + trans |= buf & 0x0fff; + if (unlikely ((i + 1) == urb->number_of_packets)) + trans |= EHCI_ITD_IOC; + trans |= length << 16; + uframe->transaction = cpu_to_le32 (trans); + + /* might need to cross a buffer page within a td */ + uframe->bufp = (buf & ~(u64)0x0fff); + buf += length; + if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff)))) + uframe->cross = 1; + } return 0; } +static void +itd_sched_free ( + struct ehci_iso_stream *stream, + struct ehci_itd_sched *itd_sched +) +{ + list_splice (&itd_sched->itd_list, &stream->free_itd_list); + kfree (itd_sched); +} + static int itd_urb_transaction ( + struct ehci_iso_stream *stream, struct ehci_hcd *ehci, struct urb *urb, int mem_flags -) { - int frame_index; - struct ehci_itd *first_itd, *itd; +) +{ + struct ehci_itd *itd; int status; dma_addr_t itd_dma; + int i; + unsigned num_itds; + struct ehci_itd_sched *itd_sched; + + itd_sched = itd_sched_alloc (urb->number_of_packets, mem_flags); + if (unlikely (itd_sched == 0)) + return -ENOMEM; + + status = itd_sched_init (itd_sched, stream, urb); + if (unlikely (status != 0)) { + itd_sched_free (stream, itd_sched); + return status; + } + + if (urb->interval < 8) + num_itds = 1 + (itd_sched->span + 7) / 8; + else + num_itds = urb->number_of_packets; /* allocate/init ITDs */ - for (frame_index = 0, first_itd = 0; - frame_index < urb->number_of_packets; - frame_index++) { - itd = pci_pool_alloc (ehci->itd_pool, mem_flags, &itd_dma); - if (!itd) { - status = -ENOMEM; - goto fail; + for (i = 0; i < num_itds; i++) { + + /* free_itd_list.next might be cache-hot ... but maybe + * the HC caches it too. avoid that issue for now. + */ + + /* prefer previously-allocated itds */ + if (likely (!list_empty(&stream->free_itd_list))) { + itd = list_entry (stream->free_itd_list.prev, + struct ehci_itd, itd_list); + list_del (&itd->itd_list); + itd_dma = itd->itd_dma; + } else + itd = pci_pool_alloc (ehci->itd_pool, mem_flags, + &itd_dma); + + if (unlikely (0 == itd)) { + itd_sched_free (stream, itd_sched); + return -ENOMEM; } memset (itd, 0, sizeof *itd); itd->itd_dma = itd_dma; - - status = itd_fill (ehci, itd, urb, frame_index, - urb->transfer_dma); - if (status != 0) - goto fail; - - if (first_itd) - list_add_tail (&itd->itd_list, - &first_itd->itd_list); - else { - INIT_LIST_HEAD (&itd->itd_list); - urb->hcpriv = first_itd = itd; - } + list_add (&itd->itd_list, &itd_sched->itd_list); } + + /* temporarily store schedule info in hcpriv */ + urb->hcpriv = itd_sched; urb->error_count = 0; return 0; - -fail: - if (urb->hcpriv) - itd_free_list (ehci, urb); - return status; -} - -/*-------------------------------------------------------------------------*/ - -static inline void -itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) -{ - /* always prepend ITD/SITD ... only QH tree is order-sensitive */ - itd->itd_next = ehci->pshadow [frame]; - itd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].itd = itd; - ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD; } /* - * return zero on success, else -errno - * - start holds first uframe to start scheduling into - * - max is the first uframe it's NOT (!) OK to start scheduling into - * math to be done modulo "mod" (ehci->periodic_size << 3) + * This scheduler plans almost as far into the future as it has actual + * periodic schedule slots. (Affected by TUNE_FLS, which defaults to + * "as small as possible" to be cache-friendlier.) That limits the size + * transfers you can stream reliably; avoid more than 64 msec per urb. + * Also avoid queue depths of less than the system's worst irq latency. */ -static int get_iso_range ( + +#define SCHEDULE_SLOP 10 /* frames */ + +static int +itd_stream_schedule ( struct ehci_hcd *ehci, struct urb *urb, - unsigned *start, - unsigned *max, - unsigned mod -) { - struct list_head *lh; - struct hcd_dev *dev = urb->dev->hcpriv; - int last = -1; - unsigned now, span, end; - - span = urb->interval * urb->number_of_packets; - - /* first see if we know when the next transfer SHOULD happen */ - list_for_each (lh, &dev->urb_list) { - struct urb *u; - struct ehci_itd *itd; - unsigned s; + struct ehci_iso_stream *stream +) +{ + u32 now, start, end, max; + int status; + unsigned mod = ehci->periodic_size << 3; + struct ehci_itd_sched *itd_sched = urb->hcpriv; - u = list_entry (lh, struct urb, urb_list); - if (u == urb || u->pipe != urb->pipe) - continue; - if (u->interval != urb->interval) { /* must not change! */ - dbg ("urb %p interval %d ... != %p interval %d", - u, u->interval, urb, urb->interval); - return -EINVAL; - } - - /* URB for this endpoint... covers through when? */ - itd = urb->hcpriv; - s = itd->uframe + u->interval * u->number_of_packets; - if (last < 0) - last = s; - else { - /* - * So far we can only queue two ISO URBs... - * - * FIXME do interval math, figure out whether - * this URB is "before" or not ... also, handle - * the case where the URB might have completed, - * but hasn't yet been processed. - */ - dbg ("NYET: queue >2 URBs per ISO endpoint"); - return -EDOM; - } + if (unlikely (itd_sched->span > (mod - 8 * SCHEDULE_SLOP))) { + ehci_dbg (ehci, "iso request %p too long\n", urb); + status = -EFBIG; + goto fail; } - /* calculate the legal range [start,max) */ - now = readl (&ehci->regs->frame_index) + 1; /* next uframe */ - if (!ehci->periodic_sched) - now += 8; /* startup delay */ - now %= mod; - end = now + mod; - if (last < 0) { - *start = now + ehci->i_thresh + /* paranoia */ 1; - *max = end - span; - if (*max < *start + 1) - *max = *start + 1; - } else { - *start = last % mod; - *max = (last + 1) % mod; - } + now = readl (&ehci->regs->frame_index) % mod; - /* explicit start frame? */ - if (!(urb->transfer_flags & URB_ISO_ASAP)) { - unsigned temp; - - /* sanity check: must be in range */ - urb->start_frame %= ehci->periodic_size; - temp = urb->start_frame << 3; - if (temp < *start) - temp += mod; - if (temp > *max) - return -EDOM; - - /* use that explicit start frame */ - *start = urb->start_frame << 3; - temp += 8; - if (temp < *max) - *max = temp; + /* when's the last uframe this urb could start? */ + max = now + mod; + max -= itd_sched->span; + max -= 8 * SCHEDULE_SLOP; + + /* typical case: reuse current schedule. stream is still active, + * and no gaps from host falling behind (irq delays etc) + */ + if (likely (!list_empty (&stream->itd_list))) { + + start = stream->next_uframe; + if (start < now) + start += mod; + if (likely (start < max)) + goto ready; + + /* two cases: + * (a) we missed some uframes ... can reschedule + * (b) trying to overcommit the schedule + * FIXME (b) should be a hard failure + */ } - // FIXME minimize wraparound to "now" ... insist max+span - // (and start+span) remains a few frames short of "end" + /* need to schedule; when's the next (u)frame we could start? + * this is bigger than ehci->i_thresh allows; scheduling itself + * isn't free, the slop should handle reasonably slow cpus. it + * can also help high bandwidth if the dma and irq loads don't + * jump until after the queue is primed. + */ + start = SCHEDULE_SLOP * 8 + (now & ~0x07); + end = start; - *max %= ehci->periodic_size; - if ((*start + span) < end) - return 0; - return -EFBIG; -} + ehci_vdbg (ehci, "%s schedule from %d (%d..%d), was %d\n", + __FUNCTION__, now, start, max, + stream->next_uframe); -static int -itd_schedule (struct ehci_hcd *ehci, struct urb *urb) -{ - unsigned start, max, i; - int status; - unsigned mod = ehci->periodic_size << 3; + /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc [i].status = -EINPROGRESS; - urb->iso_frame_desc [i].actual_length = 0; - } + if (likely (max > (start + urb->interval))) + max = start + urb->interval; - if ((status = get_iso_range (ehci, urb, &start, &max, mod)) != 0) - return status; + /* hack: account for itds already scheduled to this endpoint */ + if (unlikely (list_empty (&stream->itd_list))) + end = max; + /* within [start..max] find a uframe slot with enough bandwidth */ + end %= mod; do { unsigned uframe; - unsigned usecs; - struct ehci_itd *itd; + int enough_space = 1; /* check schedule: enough space? */ - itd = urb->hcpriv; uframe = start; - for (i = 0, uframe = start; - i < urb->number_of_packets; - i++, uframe += urb->interval) { + do { uframe %= mod; /* can't commit more than 80% periodic == 100 usec */ if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7) - > (100 - itd->usecs)) { - itd = 0; + > (100 - stream->usecs)) { + enough_space = 0; break; } - itd = list_entry (itd->itd_list.next, - struct ehci_itd, itd_list); - } - if (!itd) - continue; - - /* that's where we'll schedule this! */ - itd = urb->hcpriv; - urb->start_frame = start >> 3; - vdbg ("ISO urb %p (%d packets period %d) starting %d.%d", - urb, urb->number_of_packets, urb->interval, - urb->start_frame, start & 0x7); - for (i = 0, uframe = start, usecs = 0; - i < urb->number_of_packets; - i++, uframe += urb->interval) { - uframe %= mod; - - itd->uframe = uframe; - itd->hw_transaction [uframe & 0x07] = itd->transaction; - itd_link (ehci, (uframe >> 3) % ehci->periodic_size, - itd); - wmb (); - usecs += itd->usecs; - - itd = list_entry (itd->itd_list.next, - struct ehci_itd, itd_list); - } - /* update bandwidth utilization records (for usbfs) - * - * FIXME This claims each URB queued to an endpoint, as if - * transfers were concurrent, not sequential. So bandwidth - * typically gets double-billed ... comes from tying it to - * URBs rather than endpoints in the schedule. Luckily we - * don't use this usbfs data for serious decision making. - */ - usecs /= urb->number_of_packets; - usecs /= urb->interval; - usecs >>= 3; - if (usecs < 1) - usecs = 1; - usb_claim_bandwidth (urb->dev, urb, usecs, 1); - - /* maybe enable periodic schedule processing */ - if (!ehci->periodic_sched++) { - if ((status = enable_periodic (ehci)) != 0) { - // FIXME deschedule right away - err ("itd_schedule, enable = %d", status); + /* we know urb->interval is 2^N uframes */ + uframe += urb->interval; + } while (uframe != end); + + /* (re)schedule it here if there's enough bandwidth */ + if (enough_space) { + start %= mod; + if (unlikely (!list_empty (&stream->itd_list))) { + /* host fell behind ... maybe irq latencies + * delayed this request queue for too long. + */ + stream->rescheduled++; + pr_debug ("ehci %s devpath %d " + "iso%d%s %d.%d skip %d.%d\n", + ehci->pdev->slot_name, + urb->dev->devpath, + stream->bEndpointAddress & 0x0f, + (stream->bEndpointAddress & USB_DIR_IN) + ? "in" : "out", + stream->next_uframe >> 3, + stream->next_uframe & 0x7, + start >> 3, start & 0x7); } + stream->next_uframe = start; + goto ready; } - return 0; - - } while ((start = ++start % mod) != max); + } while (++start < max); /* no room in the schedule */ - dbg ("urb %p, CAN'T SCHEDULE", urb); - return -ENOSPC; + ehci_dbg (ehci, "iso %ssched full %p (now %d end %d max %d)\n", + list_empty (&stream->itd_list) ? "" : "re", + urb, now, end, max); + status = -ENOSPC; + +fail: + itd_sched_free (stream, itd_sched); + urb->hcpriv = 0; + return status; + +ready: + urb->start_frame = stream->next_uframe; + return 0; } /*-------------------------------------------------------------------------*/ +static inline void +itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd) +{ + int i; + + itd->hw_next = EHCI_LIST_END; + itd->hw_bufp [0] = stream->buf0; + itd->hw_bufp [1] = stream->buf1; + itd->hw_bufp [2] = stream->buf2; + + for (i = 0; i < 8; i++) + itd->index[i] = -1; + + /* All other fields are filled when scheduling */ +} + +static inline void +itd_patch ( + struct ehci_itd *itd, + struct ehci_itd_sched *itd_sched, + unsigned index, + u16 uframe, + int first +) +{ + struct ehci_iso_uframe *uf = &itd_sched->packet [index]; + unsigned pg = itd->pg; + + // BUG_ON (pg == 6 && uf->cross); + + uframe &= 0x07; + itd->index [uframe] = index; + + itd->hw_transaction [uframe] = uf->transaction; + itd->hw_transaction [uframe] |= cpu_to_le32 (pg << 12); + itd->hw_bufp [pg] |= cpu_to_le32 (uf->bufp & ~(u32)0); + itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(uf->bufp >> 32)); + + /* iso_frame_desc[].offset must be strictly increasing */ + if (unlikely (!first && uf->cross)) { + u64 bufp = uf->bufp + 4096; + itd->pg = ++pg; + itd->hw_bufp [pg] |= cpu_to_le32 (bufp & ~(u32)0); + itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(bufp >> 32)); + } +} + +static inline void +itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) +{ + /* always prepend ITD/SITD ... only QH tree is order-sensitive */ + itd->itd_next = ehci->pshadow [frame]; + itd->hw_next = ehci->periodic [frame]; + ehci->pshadow [frame].itd = itd; + itd->frame = frame; + wmb (); + ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD; +} + +/* fit urb's itds into the selected schedule slot; activate as needed */ +static int +itd_link_urb ( + struct ehci_hcd *ehci, + struct urb *urb, + unsigned mod, + struct ehci_iso_stream *stream +) +{ + int packet, first = 1; + unsigned next_uframe, uframe, frame; + struct ehci_itd_sched *itd_sched = urb->hcpriv; + struct ehci_itd *itd; + + next_uframe = stream->next_uframe % mod; + + if (unlikely (list_empty(&stream->itd_list))) { + hcd_to_bus (&ehci->hcd)->bandwidth_allocated + += stream->bandwidth; + ehci_vdbg (ehci, + "schedule devp %s ep%d%s-iso period %d start %d.%d\n", + urb->dev->devpath, stream->bEndpointAddress & 0x0f, + (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", + urb->interval, + next_uframe >> 3, next_uframe & 0x7); + stream->start = jiffies; + } + hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs++; + + /* fill iTDs uframe by uframe */ + for (packet = 0, itd = 0; packet < urb->number_of_packets; ) { + if (itd == 0) { + /* ASSERT: we have all necessary itds */ + // BUG_ON (list_empty (&itd_sched->itd_list)); + + /* ASSERT: no itds for this endpoint in this uframe */ + + itd = list_entry (itd_sched->itd_list.next, + struct ehci_itd, itd_list); + list_move_tail (&itd->itd_list, &stream->itd_list); + itd->stream = iso_stream_get (stream); + itd->urb = usb_get_urb (urb); + first = 1; + itd_init (stream, itd); + } + + uframe = next_uframe & 0x07; + frame = next_uframe >> 3; + + itd->usecs [uframe] = stream->usecs; + itd_patch (itd, itd_sched, packet, uframe, first); + first = 0; + + next_uframe += stream->interval; + next_uframe %= mod; + packet++; + + /* link completed itds into the schedule */ + if (((next_uframe >> 3) != frame) + || packet == urb->number_of_packets) { + itd_link (ehci, frame % ehci->periodic_size, itd); + itd = 0; + } + } + stream->next_uframe = next_uframe; + + /* don't need that schedule data any more */ + itd_sched_free (stream, itd_sched); + urb->hcpriv = 0; + + if (unlikely (!ehci->periodic_sched++)) + return enable_periodic (ehci); + return 0; +} + #define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) static unsigned itd_complete ( struct ehci_hcd *ehci, struct ehci_itd *itd, - unsigned uframe, struct pt_regs *regs ) { struct urb *urb = itd->urb; struct usb_iso_packet_descriptor *desc; u32 t; + unsigned uframe; + int urb_index = -1; + struct ehci_iso_stream *stream = itd->stream; + struct usb_device *dev; + + /* for each uframe with a packet */ + for (uframe = 0; uframe < 8; uframe++) { + if (likely (itd->index[uframe] == -1)) + continue; + urb_index = itd->index[uframe]; + desc = &urb->iso_frame_desc [urb_index]; - /* update status for this uframe's transfers */ - desc = &urb->iso_frame_desc [itd->index]; + t = le32_to_cpup (&itd->hw_transaction [uframe]); + itd->hw_transaction [uframe] = 0; - t = itd->hw_transaction [uframe]; - itd->hw_transaction [uframe] = 0; - if (t & EHCI_ISOC_ACTIVE) - desc->status = -EXDEV; - else if (t & ISO_ERRS) { - urb->error_count++; - if (t & EHCI_ISOC_BUF_ERR) - desc->status = usb_pipein (urb->pipe) - ? -ENOSR /* couldn't read */ - : -ECOMM; /* couldn't write */ - else if (t & EHCI_ISOC_BABBLE) - desc->status = -EOVERFLOW; - else /* (t & EHCI_ISOC_XACTERR) */ - desc->status = -EPROTO; - - /* HC need not update length with this error */ - if (!(t & EHCI_ISOC_BABBLE)) - desc->actual_length += EHCI_ITD_LENGTH (t); - } else { - desc->status = 0; - desc->actual_length += EHCI_ITD_LENGTH (t); + /* report transfer status */ + if (unlikely (t & ISO_ERRS)) { + urb->error_count++; + if (t & EHCI_ISOC_BUF_ERR) + desc->status = usb_pipein (urb->pipe) + ? -ENOSR /* hc couldn't read */ + : -ECOMM; /* hc couldn't write */ + else if (t & EHCI_ISOC_BABBLE) + desc->status = -EOVERFLOW; + else /* (t & EHCI_ISOC_XACTERR) */ + desc->status = -EPROTO; + + /* HC need not update length with this error */ + if (!(t & EHCI_ISOC_BABBLE)) + desc->actual_length = EHCI_ITD_LENGTH (t); + } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { + desc->status = 0; + desc->actual_length = EHCI_ITD_LENGTH (t); + } } - vdbg ("itd %p urb %p packet %d/%d trans %x status %d len %d", - itd, urb, itd->index + 1, urb->number_of_packets, - t, desc->status, desc->actual_length); + usb_put_urb (urb); + itd->urb = 0; + itd->stream = 0; + list_move (&itd->itd_list, &stream->free_itd_list); + iso_stream_put (ehci, stream); /* handle completion now? */ - if ((itd->index + 1) != urb->number_of_packets) + if (likely ((urb_index + 1) != urb->number_of_packets)) return 0; - /* - * Always give the urb back to the driver ... expect it to submit - * a new urb (or resubmit this), and to have another already queued - * when un-interrupted transfers are needed. - * - * NOTE that for now we don't accelerate ISO unlinks; they just - * happen according to the current schedule. Means a delay of - * up to about a second (max). + /* ASSERT: it's really the last itd for this urb + list_for_each_entry (itd, &stream->itd_list, itd_list) + BUG_ON (itd->urb == urb); */ - itd_free_list (ehci, urb); - if (urb->status == -EINPROGRESS) - urb->status = 0; - - /* complete() can reenter this HCD */ - spin_unlock (&ehci->lock); - usb_hcd_giveback_urb (&ehci->hcd, urb, regs); - spin_lock (&ehci->lock); + + /* give urb back to the driver ... can be out-of-order */ + //dev = usb_get_dev (urb->dev); + dev = urb->dev; + ehci_urb_done (ehci, urb, regs); + urb = 0; /* defer stopping schedule; completion can submit */ ehci->periodic_sched--; - if (!ehci->periodic_sched) + if (unlikely (!ehci->periodic_sched)) (void) disable_periodic (ehci); + hcd_to_bus (&ehci->hcd)->bandwidth_isoc_reqs--; + + if (unlikely (list_empty (&stream->itd_list))) { + hcd_to_bus (&ehci->hcd)->bandwidth_allocated + -= stream->bandwidth; + ehci_vdbg (ehci, + "deschedule devp %s ep%d%s-iso\n", + dev->devpath, stream->bEndpointAddress & 0x0f, + (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); + } + iso_stream_put (ehci, stream); + //usb_put_dev (dev); return 1; } @@ -939,23 +1170,50 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags) { - int status; - unsigned long flags; + int status = -EINVAL; + unsigned long flags; + struct ehci_iso_stream *stream; - dbg ("itd_submit urb %p", urb); + /* Get iso_stream head */ + stream = iso_stream_find (ehci, urb); + if (unlikely (stream == 0)) { + ehci_dbg (ehci, "can't get iso stream\n"); + return -ENOMEM; + } + if (unlikely (urb->interval != stream->interval)) { + ehci_dbg (ehci, "can't change iso interval %d --> %d\n", + stream->interval, urb->interval); + goto done; + } + +#ifdef EHCI_URB_TRACE + ehci_dbg (ehci, + "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n", + __FUNCTION__, urb->dev->devpath, urb, + usb_pipeendpoint (urb->pipe), + usb_pipein (urb->pipe) ? "in" : "out", + urb->transfer_buffer_length, + urb->number_of_packets, urb->interval, + stream); +#endif /* allocate ITDs w/o locking anything */ - status = itd_urb_transaction (ehci, urb, mem_flags); - if (status < 0) - return status; + status = itd_urb_transaction (stream, ehci, urb, mem_flags); + if (unlikely (status < 0)) { + ehci_dbg (ehci, "can't init itds\n"); + goto done; + } /* schedule ... need to lock */ spin_lock_irqsave (&ehci->lock, flags); - status = itd_schedule (ehci, urb); + status = itd_stream_schedule (ehci, urb, stream); + if (likely (status == 0)) + itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); spin_unlock_irqrestore (&ehci->lock, flags); - if (status < 0) - itd_free_list (ehci, urb); +done: + if (unlikely (status < 0)) + iso_stream_put (ehci, stream); return status; } @@ -986,24 +1244,23 @@ * When running, scan from last scan point up to "now" * else clean up by scanning everything that's left. * Touches as few pages as possible: cache-friendly. - * Don't scan ISO entries more than once, though. */ - frame = ehci->next_uframe >> 3; + now_uframe = ehci->next_uframe; if (HCD_IS_RUNNING (ehci->hcd.state)) - now_uframe = readl (&ehci->regs->frame_index); + clock = readl (&ehci->regs->frame_index) % mod; else - now_uframe = (frame << 3) - 1; - now_uframe %= mod; - clock = now_uframe >> 3; + clock = now_uframe + mod - 1; for (;;) { union ehci_shadow q, *q_p; u32 type, *hw_p; unsigned uframes; + frame = now_uframe >> 3; restart: /* scan schedule to _before_ current frame index */ - if (frame == clock) + if ((frame == (clock >> 3)) + && HCD_IS_RUNNING (ehci->hcd.state)) uframes = now_uframe & 0x07; else uframes = 8; @@ -1043,34 +1300,31 @@ case Q_TYPE_ITD: last = (q.itd->hw_next == EHCI_LIST_END); - /* Unlink each (S)ITD we see, since the ISO - * URB model forces constant rescheduling. - * That complicates sharing uframes in ITDs, - * and means we need to skip uframes the HC - * hasn't yet processed. - */ - for (uf = 0; uf < uframes; uf++) { - if (q.itd->hw_transaction [uf] != 0) { - temp = q; - *q_p = q.itd->itd_next; - *hw_p = q.itd->hw_next; - type = Q_NEXT_TYPE (*hw_p); - - /* might free q.itd ... */ - count += itd_complete (ehci, - temp.itd, uf, regs); - break; - } - } - /* we might skip this ITD's uframe ... */ - if (uf == uframes) { + /* skip itds for later in the frame */ + rmb (); + for (uf = uframes; uf < 8; uf++) { + if (0 == (q.itd->hw_transaction [uf] + & ISO_ACTIVE)) + continue; q_p = &q.itd->itd_next; hw_p = &q.itd->hw_next; type = Q_NEXT_TYPE (q.itd->hw_next); + q = *q_p; + break; } + if (uf != 8) + break; - q = *q_p; - break; + /* this one's ready ... HC won't cache the + * pointer for much longer, if at all. + */ + *q_p = q.itd->itd_next; + *hw_p = q.itd->hw_next; + wmb(); + + /* always rescan here; simpler */ + count += itd_complete (ehci, q.itd, regs); + goto restart; #ifdef have_split_iso case Q_TYPE_SITD: last = (q.sitd->hw_next == EHCI_LIST_END); @@ -1104,7 +1358,7 @@ // FIXME: likewise assumes HC doesn't halt mid-scan - if (frame == clock) { + if (now_uframe == clock) { unsigned now; if (!HCD_IS_RUNNING (ehci->hcd.state)) @@ -1115,9 +1369,13 @@ break; /* rescan the rest of this frame, then ... */ - now_uframe = now; - clock = now_uframe >> 3; - } else - frame = (frame + 1) % ehci->periodic_size; + clock = now; + } else { + /* FIXME sometimes we can scan the next frame + * right away, not always inching up on it ... + */ + now_uframe++; + now_uframe %= mod; + } } } diff -urN linux-2.4.24/drivers/usb/host/ehci.h linux-2.4.25/drivers/usb/host/ehci.h --- linux-2.4.24/drivers/usb/host/ehci.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/ehci.h 2004-02-18 05:36:31.000000000 -0800 @@ -153,9 +153,12 @@ /* Section 2.2 Host Controller Capability Registers */ struct ehci_caps { - u8 length; /* CAPLENGTH - size of this struct */ - u8 reserved; /* offset 0x1 */ - u16 hci_version; /* HCIVERSION - offset 0x2 */ + /* these fields are specified as 8 and 16 bit registers, + * but some hosts can't perform 8 or 16 bit PCI accesses. + */ + u32 hc_capbase; +#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ +#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ u32 hcs_params; /* HCSPARAMS - offset 0x4 */ #define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */ #define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ @@ -378,11 +381,68 @@ unsigned short period; /* polling interval */ unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ - + struct usb_device *dev; /* access to TT */ } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ +/* description of one iso highspeed transaction (up to 3 KB data) */ +struct ehci_iso_uframe { + /* These will be copied to iTD when scheduling */ + u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */ + u32 transaction; /* itd->hw_transaction[i] |= */ + u8 cross; /* buf crosses pages */ +}; + +/* temporary schedule data for highspeed packets from iso urbs + * each packet is one uframe's usb transactions, in some itd, + * beginning at stream->next_uframe + */ +struct ehci_itd_sched { + struct list_head itd_list; + unsigned span; + struct ehci_iso_uframe packet [0]; +}; + +/* + * ehci_iso_stream - groups all (s)itds for this endpoint. + * acts like a qh would, if EHCI had them for ISO. + */ +struct ehci_iso_stream { + /* first two fields match QH, but info1 == 0 */ + u32 hw_next; + u32 hw_info1; + + u32 refcount; + u8 bEndpointAddress; + struct list_head itd_list; /* queued itds */ + struct list_head free_itd_list; /* list of unused itds */ + struct hcd_dev *dev; + + /* output of (re)scheduling */ + unsigned long start; /* jiffies */ + unsigned long rescheduled; + int next_uframe; + + /* the rest is derived from the endpoint descriptor, + * trusting urb->interval == (1 << (epdesc->bInterval - 1)), + * including the extra info for hw_bufp[0..2] + */ + u8 interval; + u8 usecs; + u16 maxp; + unsigned bandwidth; + + /* This is used to initialize iTD's hw_bufp fields */ + u32 buf0; + u32 buf1; + u32 buf2; + + /* ... sITD won't use buf[012], and needs TT access ... */ +}; + +/*-------------------------------------------------------------------------*/ + /* * EHCI Specification 0.95 Section 3.3 * Fig 3-4 "Isochronous Transaction Descriptor (iTD)" @@ -397,9 +457,11 @@ #define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */ #define EHCI_ISOC_BABBLE (1<<29) /* babble detected */ #define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */ -#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x7fff) +#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff) #define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */ +#define ISO_ACTIVE __constant_cpu_to_le32(EHCI_ISOC_ACTIVE) + u32 hw_bufp [7]; /* see EHCI 3.3.3 */ u32 hw_bufp_hi [7]; /* Appendix B */ @@ -408,14 +470,14 @@ union ehci_shadow itd_next; /* ptr to periodic q entry */ struct urb *urb; - struct list_head itd_list; /* list of urb frames' itds */ - dma_addr_t buf_dma; /* frame's buffer address */ + struct ehci_iso_stream *stream; /* endpoint's queue */ + struct list_head itd_list; /* list of stream's itds */ - /* for now, only one hw_transaction per itd */ - u32 transaction; - u16 index; /* in urb->iso_frame_desc */ - u16 uframe; /* in periodic schedule */ - u16 usecs; + /* any/all hw_transactions here may be used by that urb */ + unsigned frame; /* where scheduled */ + unsigned pg; + unsigned index[8]; /* in urb->iso_frame_desc */ + u8 usecs[8]; } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ diff -urN linux-2.4.24/drivers/usb/host/sl811.c linux-2.4.25/drivers/usb/host/sl811.c --- linux-2.4.24/drivers/usb/host/sl811.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/host/sl811.c 2004-02-18 05:36:31.000000000 -0800 @@ -652,7 +652,7 @@ { struct sl811_urb_priv *urbp; - urbp = kmalloc(sizeof(*urbp), GFP_KERNEL); + urbp = kmalloc(sizeof(*urbp), GFP_ATOMIC); if (!urbp) return NULL; @@ -763,7 +763,7 @@ struct sl811_urb_priv *urbp = urb->hcpriv; struct sl811_td *td; - td = kmalloc(sizeof (*td), GFP_KERNEL); + td = kmalloc(sizeof (*td), GFP_ATOMIC); if (!td) return NULL; diff -urN linux-2.4.24/drivers/usb/host/usb-ohci.c linux-2.4.25/drivers/usb/host/usb-ohci.c --- linux-2.4.24/drivers/usb/host/usb-ohci.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/host/usb-ohci.c 2004-02-18 05:36:31.000000000 -0800 @@ -628,7 +628,7 @@ /* allocate the private part of the URB */ urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + in_interrupt() ? GFP_ATOMIC : GFP_NOIO); if (!urb_priv) { usb_dec_dev_use (urb->dev); return -ENOMEM; diff -urN linux-2.4.24/drivers/usb/host/usb-ohci.h linux-2.4.25/drivers/usb/host/usb-ohci.h --- linux-2.4.24/drivers/usb/host/usb-ohci.h 2003-06-13 07:51:36.000000000 -0700 +++ linux-2.4.25/drivers/usb/host/usb-ohci.h 2004-02-18 05:36:31.000000000 -0800 @@ -439,7 +439,7 @@ /*-------------------------------------------------------------------------*/ -#define ALLOC_FLAGS (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL) +#define ALLOC_FLAGS (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_NOIO) #ifdef DEBUG # define OHCI_MEM_FLAGS SLAB_POISON diff -urN linux-2.4.24/drivers/usb/host/usb-uhci.c linux-2.4.25/drivers/usb/host/usb-uhci.c --- linux-2.4.24/drivers/usb/host/usb-uhci.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/host/usb-uhci.c 2004-02-18 05:36:31.000000000 -0800 @@ -88,8 +88,8 @@ static kmem_cache_t *urb_priv_kmem; #endif -#define SLAB_FLAG (in_interrupt () || current->state != TASK_RUNNING ? SLAB_ATOMIC : SLAB_KERNEL) -#define KMALLOC_FLAG (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL) +#define SLAB_FLAG (in_interrupt () || current->state != TASK_RUNNING ? SLAB_ATOMIC : SLAB_NOIO) +#define KMALLOC_FLAG (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_NOIO) /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth * Reclamation: feature that puts loop on descriptor loop when diff -urN linux-2.4.24/drivers/usb/inode.c linux-2.4.25/drivers/usb/inode.c --- linux-2.4.24/drivers/usb/inode.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/usb/inode.c 2004-02-18 05:36:31.000000000 -0800 @@ -158,9 +158,7 @@ inode->i_uid = inode->i_gid = 0; inode->i_size = 0; list_del(&inode->u.usbdev_i.slist); - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); list_del(&inode->u.usbdev_i.dlist); - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); iput(inode); } @@ -512,8 +510,6 @@ inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME; inode->i_mode = S_IFREG; inode->i_gid = inode->i_uid = 0; - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); inode->u.usbdev_i.p.dev = NULL; inode->u.usbdev_i.p.bus = NULL; switch (ITYPE(inode->i_ino)) { diff -urN linux-2.4.24/drivers/usb/pegasus.c linux-2.4.25/drivers/usb/pegasus.c --- linux-2.4.24/drivers/usb/pegasus.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/pegasus.c 2004-02-18 05:36:31.000000000 -0800 @@ -54,7 +54,7 @@ BMSR_100FULL | BMSR_ANEGCAPABLE) static int loopback = 0; -static int mii_mode = 1; +static int mii_mode = 0; static int multicast_filter_limit = 32; static struct usb_eth_dev usb_dev_id[] = { @@ -486,7 +486,7 @@ if (linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF)) data[1] |= 0x10; /* set 100 Mbps */ if (mii_mode) - data[1] = 0; + data[1] |= 1; data[2] = (loopback & 1) ? 0x09 : 0x01; memcpy(pegasus->eth_regs, data, sizeof(data)); set_registers(pegasus, EthCtrl0, 3, data); @@ -900,6 +900,7 @@ info.cmd = ETHTOOL_GDRVINFO; strncpy(info.driver, driver_name, sizeof (info.driver) - 1); + strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN); strncpy(info.version, DRIVER_VERSION, sizeof (info.version) - 1); usb_make_path(pegasus->usb, info.bus_info, diff -urN linux-2.4.24/drivers/usb/pegasus.h linux-2.4.25/drivers/usb/pegasus.h --- linux-2.4.24/drivers/usb/pegasus.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/pegasus.h 2004-02-18 05:36:31.000000000 -0800 @@ -133,8 +133,10 @@ #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 +#define VENDOR_MICROSOFT 0x045e #define VENDOR_MOBILITY 0x1342 #define VENDOR_NETGEAR 0x0846 +#define VENDOR_OCT 0x0b39 #define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMC 0x0707 #define VENDOR_SOHOWARE 0x15e8 @@ -170,7 +172,7 @@ DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8511, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8513, DEFAULT_GPIO_RESET | PEGASUS_II ) @@ -255,8 +257,12 @@ DEFAULT_GPIO_RESET ) PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "Microsoft MN-110", VENDOR_MICROSOFT, 0x007a, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "OCT Inc.", VENDOR_OCT, 0x0109, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200, diff -urN linux-2.4.24/drivers/usb/printer.c linux-2.4.25/drivers/usb/printer.c --- linux-2.4.24/drivers/usb/printer.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/usb/printer.c 2004-02-18 05:36:31.000000000 -0800 @@ -22,8 +22,11 @@ * v0.7 - fixed bulk-IN read and poll (David Paschal) * v0.8 - add devfs support * v0.9 - fix unplug-while-open paths - * v0.10 - add proto_bias option (Pete Zaitcev) - * v0.11 - add hpoj.sourceforge.net ioctls (David Paschal) + * v0.10- remove sleep_on, fix error on oom (oliver@neukum.org) + * v0.11 - add proto_bias option (Pete Zaitcev) + * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal) + * v0.13 - alloc space for statusbuf ( not on stack); + * use usb_buffer_alloc() for read buf & write buf; */ /* @@ -58,12 +61,12 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.11" +#define DRIVER_VERSION "v0.13" #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal" #define DRIVER_DESC "USB Printer Device Class driver" #define USBLP_BUF_SIZE 8192 -#define DEVICE_ID_SIZE 1024 +#define USBLP_DEVICE_ID_SIZE 1024 /* ioctls: */ #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */ @@ -115,12 +118,20 @@ #define USBLP_LAST_PROTOCOL 3 #define USBLP_MAX_PROTOCOLS (USBLP_LAST_PROTOCOL+1) +/* + * some arbitrary status buffer size; + * need a status buffer that is allocated via kmalloc(), not on stack + */ +#define STATUS_BUF_SIZE 8 + struct usblp { struct usb_device *dev; /* USB device */ devfs_handle_t devfs; /* devfs device */ struct semaphore sem; /* locks this struct, especially "dev" */ - char *buf; /* writeurb.transfer_buffer */ - struct urb readurb, writeurb; /* The urbs */ + char *writebuf; /* write transfer_buffer */ + char *readbuf; /* read transfer_buffer */ + char *statusbuf; /* status transfer_buffer */ + struct urb *readurb, *writeurb; /* The urbs */ wait_queue_head_t wait; /* Zzzzz ... */ int readcount; /* Counter for reads */ int ifnum; /* Interface number */ @@ -133,8 +144,11 @@ } protocol[USBLP_MAX_PROTOCOLS]; int current_protocol; int minor; /* minor number of device */ + int wcomplete; /* writing is completed */ + int rcomplete; /* reading is completed */ unsigned int quirks; /* quirks flags */ unsigned char used; /* True if open */ + unsigned char present; /* True if not disconnected */ unsigned char bidir; /* interface is bidirectional */ unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ /* first 2 bytes are (big-endian) length */ @@ -146,8 +160,11 @@ dbg("usblp=0x%p", usblp); dbg("dev=0x%p", usblp->dev); - dbg("devfs=0x%p", usblp->devfs); - dbg("buf=0x%p", usblp->buf); + dbg("present=%d", usblp->present); + dbg("readbuf=0x%p", usblp->readbuf); + dbg("writebuf=0x%p", usblp->writebuf); + dbg("readurb=0x%p", usblp->readurb); + dbg("writeurb=0x%p", usblp->writeurb); dbg("readcount=%d", usblp->readcount); dbg("ifnum=%d", usblp->ifnum); for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) { @@ -157,6 +174,8 @@ } dbg("current_protocol=%d", usblp->current_protocol); dbg("minor=%d", usblp->minor); + dbg("wcomplete=%d", usblp->wcomplete); + dbg("rcomplete=%d", usblp->rcomplete); dbg("quirks=%d", usblp->quirks); dbg("used=%d", usblp->used); dbg("bidir=%d", usblp->bidir); @@ -239,17 +258,31 @@ * URB callback. */ -static void usblp_bulk(struct urb *urb) +static void usblp_bulk_read(struct urb *urb) { struct usblp *usblp = urb->context; - if (!usblp || !usblp->dev || !usblp->used) + if (!usblp || !usblp->dev || !usblp->used || !usblp->present) return; - if (urb->status) + if (unlikely(urb->status)) warn("usblp%d: nonzero read/write bulk status received: %d", usblp->minor, urb->status); + usblp->rcomplete = 1; + wake_up_interruptible(&usblp->wait); +} + +static void usblp_bulk_write(struct urb *urb) +{ + struct usblp *usblp = urb->context; + + if (!usblp || !usblp->dev || !usblp->used || !usblp->present) + return; + if (unlikely(urb->status)) + warn("usblp%d: nonzero read/write bulk status received: %d", + usblp->minor, urb->status); + usblp->wcomplete = 1; wake_up_interruptible(&usblp->wait); } @@ -257,25 +290,28 @@ * Get and print printer errors. */ -static char *usblp_messages[] = { "ok", "out of paper", "off-line", "unknown error" }; +static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; static int usblp_check_status(struct usblp *usblp, int err) { unsigned char status, newerr = 0; int error; - error = usblp_read_status (usblp, &status); + error = usblp_read_status (usblp, usblp->statusbuf); if (error < 0) { err("usblp%d: error %d reading printer status", usblp->minor, error); return 0; } - if (~status & LP_PERRORP) { + status = *usblp->statusbuf; + + if (~status & LP_PERRORP) newerr = 3; - if (status & LP_POUTPA) newerr = 1; - if (~status & LP_PSELECD) newerr = 2; - } + if (status & LP_POUTPA) + newerr = 1; + if (~status & LP_PSELECD) + newerr = 2; if (newerr != err) info("usblp%d: %s", usblp->minor, usblp_messages[newerr]); @@ -300,7 +336,7 @@ usblp = usblp_table[minor]; retval = -ENODEV; - if (!usblp || !usblp->dev) + if (!usblp || !usblp->dev || !usblp->present) goto out; retval = -EBUSY; @@ -324,13 +360,14 @@ usblp->used = 1; file->private_data = usblp; - usblp->writeurb.transfer_buffer_length = 0; - usblp->writeurb.status = 0; + usblp->writeurb->transfer_buffer_length = 0; + usblp->wcomplete = 1; /* we begin writeable */ + usblp->rcomplete = 0; if (usblp->bidir) { usblp->readcount = 0; - usblp->readurb.dev = usblp->dev; - if (usb_submit_urb(&usblp->readurb) < 0) { + usblp->readurb->dev = usblp->dev; + if (usb_submit_urb(usblp->readurb) < 0) { retval = -EIO; usblp->used = 0; file->private_data = NULL; @@ -347,16 +384,20 @@ usblp_table [usblp->minor] = NULL; info("usblp%d: removed", usblp->minor); - kfree (usblp->writeurb.transfer_buffer); + kfree (usblp->writebuf); + kfree (usblp->readbuf); kfree (usblp->device_id_string); + kfree (usblp->statusbuf); + usb_free_urb(usblp->writeurb); + usb_free_urb(usblp->readurb); kfree (usblp); } static void usblp_unlink_urbs(struct usblp *usblp) { - usb_unlink_urb(&usblp->writeurb); + usb_unlink_urb(usblp->writeurb); if (usblp->bidir) - usb_unlink_urb(&usblp->readurb); + usb_unlink_urb(usblp->readurb); } static int usblp_release(struct inode *inode, struct file *file) @@ -366,7 +407,7 @@ down (&usblp->sem); lock_kernel(); usblp->used = 0; - if (usblp->dev) { + if (usblp->present) { usblp_unlink_urbs(usblp); up(&usblp->sem); } else /* finish cleanup from disconnect */ @@ -380,21 +421,21 @@ { struct usblp *usblp = file->private_data; poll_wait(file, &usblp->wait, wait); - return ((!usblp->bidir || usblp->readurb.status == -EINPROGRESS) ? 0 : POLLIN | POLLRDNORM) - | (usblp->writeurb.status == -EINPROGRESS ? 0 : POLLOUT | POLLWRNORM); + return ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM) + | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); } static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct usblp *usblp = file->private_data; int length, err, i; - unsigned char lpstatus, newChannel; + unsigned char newChannel; int status; int twoints[2]; int retval = 0; down (&usblp->sem); - if (!usblp->dev) { + if (!usblp->present) { retval = -ENODEV; goto done; } @@ -534,24 +575,24 @@ break; default: - retval = -EINVAL; + retval = -ENOTTY; } else /* old-style ioctl value */ switch (cmd) { case LPGETSTATUS: - if (usblp_read_status(usblp, &lpstatus)) { + if (usblp_read_status(usblp, usblp->statusbuf)) { err("usblp%d: failed reading printer status", usblp->minor); retval = -EIO; goto done; } - status = lpstatus; + status = *usblp->statusbuf; if (copy_to_user ((int *)arg, &status, sizeof(int))) retval = -EFAULT; break; default: - retval = -EINVAL; + retval = -ENOTTY; } done: @@ -561,41 +602,48 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { + DECLARE_WAITQUEUE(wait, current); struct usblp *usblp = file->private_data; int timeout, err = 0; size_t writecount = 0; while (writecount < count) { - - // FIXME: only use urb->status inside completion - // callbacks; this way is racey... - if (usblp->writeurb.status == -EINPROGRESS) { - + if (!usblp->wcomplete) { + barrier(); if (file->f_flags & O_NONBLOCK) return -EAGAIN; timeout = USBLP_WRITE_TIMEOUT; - while (timeout && usblp->writeurb.status == -EINPROGRESS) { + add_wait_queue(&usblp->wait, &wait); + while ( 1==1 ) { - if (signal_pending(current)) + if (signal_pending(current)) { + remove_wait_queue(&usblp->wait, &wait); return writecount ? writecount : -EINTR; - - timeout = interruptible_sleep_on_timeout(&usblp->wait, timeout); + } + set_current_state(TASK_INTERRUPTIBLE); + if (timeout && !usblp->wcomplete) { + timeout = schedule_timeout(timeout); + } else { + set_current_state(TASK_RUNNING); + break; + } } + remove_wait_queue(&usblp->wait, &wait); } down (&usblp->sem); - if (!usblp->dev) { + if (!usblp->present) { up (&usblp->sem); return -ENODEV; } - if (usblp->writeurb.status != 0) { + if (usblp->writeurb->status != 0) { if (usblp->quirks & USBLP_QUIRK_BIDIR) { - if (usblp->writeurb.status != -EINPROGRESS) + if (!usblp->wcomplete) err("usblp%d: error %d writing to printer", - usblp->minor, usblp->writeurb.status); - err = usblp->writeurb.status; + usblp->minor, usblp->writeurb->status); + err = usblp->writeurb->status; } else err = usblp_check_status(usblp, err); up (&usblp->sem); @@ -607,25 +655,30 @@ continue; } - writecount += usblp->writeurb.transfer_buffer_length; - usblp->writeurb.transfer_buffer_length = 0; + writecount += usblp->writeurb->transfer_buffer_length; + usblp->writeurb->transfer_buffer_length = 0; if (writecount == count) { up (&usblp->sem); break; } - usblp->writeurb.transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ? - (count - writecount) : USBLP_BUF_SIZE; + usblp->writeurb->transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ? + (count - writecount) : USBLP_BUF_SIZE; - if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount, - usblp->writeurb.transfer_buffer_length)) { + if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount, + usblp->writeurb->transfer_buffer_length)) { up(&usblp->sem); return writecount ? writecount : -EFAULT; } - usblp->writeurb.dev = usblp->dev; - usb_submit_urb(&usblp->writeurb); + usblp->writeurb->dev = usblp->dev; + usblp->wcomplete = 0; + if (usb_submit_urb(usblp->writeurb)) { + count = -EIO; + up (&usblp->sem); + break; + } up (&usblp->sem); } @@ -635,63 +688,77 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct usblp *usblp = file->private_data; + DECLARE_WAITQUEUE(wait, current); if (!usblp->bidir) return -EINVAL; down (&usblp->sem); - if (!usblp->dev) { + if (!usblp->present) { count = -ENODEV; goto done; } - if (usblp->readurb.status == -EINPROGRESS) { + if (!usblp->rcomplete) { + barrier(); if (file->f_flags & O_NONBLOCK) { count = -EAGAIN; goto done; } - // FIXME: only use urb->status inside completion - // callbacks; this way is racey... - while (usblp->readurb.status == -EINPROGRESS) { + add_wait_queue(&usblp->wait, &wait); + while (1==1) { if (signal_pending(current)) { count = -EINTR; + remove_wait_queue(&usblp->wait, &wait); goto done; } up (&usblp->sem); - interruptible_sleep_on(&usblp->wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!usblp->rcomplete) { + schedule(); + } else { + set_current_state(TASK_RUNNING); + break; + } down (&usblp->sem); } + remove_wait_queue(&usblp->wait, &wait); } - if (!usblp->dev) { + if (!usblp->present) { count = -ENODEV; goto done; } - if (usblp->readurb.status) { + if (usblp->readurb->status) { err("usblp%d: error %d reading from printer", - usblp->minor, usblp->readurb.status); - usblp->readurb.dev = usblp->dev; + usblp->minor, usblp->readurb->status); + usblp->readurb->dev = usblp->dev; usblp->readcount = 0; - usb_submit_urb(&usblp->readurb); + if (usb_submit_urb(usblp->readurb) < 0) + dbg("error submitting urb"); count = -EIO; goto done; } - count = count < usblp->readurb.actual_length - usblp->readcount ? - count : usblp->readurb.actual_length - usblp->readcount; + count = count < usblp->readurb->actual_length - usblp->readcount ? + count : usblp->readurb->actual_length - usblp->readcount; - if (copy_to_user(buffer, usblp->readurb.transfer_buffer + usblp->readcount, count)) { + if (copy_to_user(buffer, usblp->readurb->transfer_buffer + usblp->readcount, count)) { count = -EFAULT; goto done; } - if ((usblp->readcount += count) == usblp->readurb.actual_length) { + if ((usblp->readcount += count) == usblp->readurb->actual_length) { usblp->readcount = 0; - usblp->readurb.dev = usblp->dev; - usb_submit_urb(&usblp->readurb); + usblp->readurb->dev = usblp->dev; + usblp->rcomplete = 0; + if (usb_submit_urb(usblp->readurb)) { + count = -EIO; + goto done; + } } done: @@ -766,19 +833,42 @@ } } + usblp->writeurb = usb_alloc_urb(0); + if (!usblp->writeurb) { + err("out of memory"); + goto abort; + } + usblp->readurb = usb_alloc_urb(0); + if (!usblp->readurb) { + err("out of memory"); + goto abort; + } + /* Malloc device ID string buffer to the largest expected length, * since we can re-query it on an ioctl and a dynamic string * could change in length. */ - if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) { + if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { err("out of memory for device_id_string"); goto abort; } - /* Malloc write/read buffers in one chunk. We somewhat wastefully + usblp->writebuf = usblp->readbuf = NULL; + /* Malloc write & read buffers. We somewhat wastefully * malloc both regardless of bidirectionality, because the * alternate setting can be changed later via an ioctl. */ - if (!(usblp->buf = kmalloc(2 * USBLP_BUF_SIZE, GFP_KERNEL))) { - err("out of memory for buf"); + if (!(usblp->writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) { + err("out of memory for write buf"); + goto abort; + } + if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) { + err("out of memory for read buf"); + goto abort; + } + + /* Allocate buffer for printer status */ + usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); + if (!usblp->statusbuf) { + err("out of memory for statusbuf"); goto abort; } @@ -818,17 +908,26 @@ info("usblp%d: USB %sdirectional printer dev %d " "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", - usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, ifnum, + usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, + usblp->ifnum, usblp->protocol[usblp->current_protocol].alt_setting, usblp->current_protocol, usblp->dev->descriptor.idVendor, usblp->dev->descriptor.idProduct); + usblp->present = 1; + return usblp; abort: if (usblp) { - if (usblp->buf) kfree(usblp->buf); - if (usblp->device_id_string) kfree(usblp->device_id_string); + if (usblp->writebuf) + kfree (usblp->writebuf); + if (usblp->readbuf) + kfree (usblp->readbuf); + kfree(usblp->statusbuf); + kfree(usblp->device_id_string); + usb_free_urb(usblp->writeurb); + usb_free_urb(usblp->readurb); kfree(usblp); } return NULL; @@ -943,19 +1042,19 @@ return r; } - FILL_BULK_URB(&usblp->writeurb, usblp->dev, + usb_fill_bulk_urb(usblp->writeurb, usblp->dev, usb_sndbulkpipe(usblp->dev, - usblp->protocol[protocol].epwrite->bEndpointAddress), - usblp->buf, 0, - usblp_bulk, usblp); + usblp->protocol[protocol].epwrite->bEndpointAddress), + usblp->writebuf, 0, + usblp_bulk_write, usblp); usblp->bidir = (usblp->protocol[protocol].epread != 0); if (usblp->bidir) - FILL_BULK_URB(&usblp->readurb, usblp->dev, + usb_fill_bulk_urb(usblp->readurb, usblp->dev, usb_rcvbulkpipe(usblp->dev, - usblp->protocol[protocol].epread->bEndpointAddress), - usblp->buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, - usblp_bulk, usblp); + usblp->protocol[protocol].epread->bEndpointAddress), + usblp->readbuf, USBLP_BUF_SIZE, + usblp_bulk_read, usblp); usblp->current_protocol = protocol; dbg("usblp%d set protocol %d", usblp->minor, protocol); @@ -969,7 +1068,7 @@ { int err, length; - err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1); + err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1); if (err < 0) { dbg("usblp%d: error = %d reading IEEE-1284 Device ID string", usblp->minor, err); @@ -983,8 +1082,8 @@ length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; if (length < 2) length = 2; - else if (length >= DEVICE_ID_SIZE) - length = DEVICE_ID_SIZE - 1; + else if (length >= USBLP_DEVICE_ID_SIZE) + length = USBLP_DEVICE_ID_SIZE - 1; usblp->device_id_string[length] = '\0'; dbg("usblp%d Device ID string [len=%d]=\"%s\"", @@ -1004,13 +1103,13 @@ down (&usblp->sem); lock_kernel(); - usblp->dev = NULL; + usblp->present = 0; usblp_unlink_urbs(usblp); if (!usblp->used) usblp_cleanup (usblp); - else /* cleanup later, on close */ + else /* cleanup later, on release */ up (&usblp->sem); unlock_kernel(); } diff -urN linux-2.4.24/drivers/usb/scanner.c linux-2.4.25/drivers/usb/scanner.c --- linux-2.4.24/drivers/usb/scanner.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/scanner.c 2004-02-18 05:36:31.000000000 -0800 @@ -385,6 +385,10 @@ * - Use static declarations for usb_scanner_init/usb_scanner_exit * (Daniele Bellucci). * + * 0.4.16 2003-11-04 + * - Added vendor/product ids for Epson, Genius, Microtek, Plustek, Reflecta, and + * Visioneer scanners. Removed ids for HP PSC devices as these are supported by + * the hpoj userspace driver. * * TODO * - Performance diff -urN linux-2.4.24/drivers/usb/scanner.h linux-2.4.25/drivers/usb/scanner.h --- linux-2.4.24/drivers/usb/scanner.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/scanner.h 2004-02-18 05:36:31.000000000 -0800 @@ -44,7 +44,7 @@ // #define DEBUG -#define DRIVER_VERSION "0.4.15" +#define DRIVER_VERSION "0.4.16" #define DRIVER_DESC "USB Scanner Driver" #include @@ -147,7 +147,12 @@ { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */ { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */ { USB_DEVICE(0x0458, 0x2018) }, /* ColorPage HR7X */ + { USB_DEVICE(0x0458, 0x201b) }, /* Colorpage Vivid 4x */ /* Hewlett Packard */ + /* IMPORTANT: Hewlett-Packard multi-function peripherals (OfficeJet, + Printer/Scanner/Copier (PSC), LaserJet, or PhotoSmart printer) + should not be added to this table because they are accessed by a + userspace driver (hpoj) */ { USB_DEVICE(0x03f0, 0x0101) }, /* ScanJet 4100C */ { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */ { USB_DEVICE(0x03f0, 0x0105) }, /* ScanJet 4200C */ @@ -169,10 +174,10 @@ { USB_DEVICE(0x03F0, 0x1105) }, /* ScanJet 5470C */ { USB_DEVICE(0x03f0, 0x1205) }, /* ScanJet 5550C */ { USB_DEVICE(0x03f0, 0x1305) }, /* Scanjet 4570c */ - { USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 */ + // { USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 - NOT SUPPORTED - use hpoj userspace driver */ { USB_DEVICE(0x03f0, 0x2005) }, /* ScanJet 3570c */ { USB_DEVICE(0x03f0, 0x2205) }, /* ScanJet 3500c */ - { USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 */ + // { USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 - NOT SUPPORTED - use hpoj userspace driver */ /* Lexmark */ { USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */ { USB_DEVICE(0x043d, 0x003d) }, /* X83 */ @@ -188,6 +193,7 @@ { USB_DEVICE(0x05da, 0x30ce) }, /* ScanMaker 3800 */ { USB_DEVICE(0x05da, 0x30cf) }, /* ScanMaker 4800 */ { USB_DEVICE(0x05da, 0x30d4) }, /* ScanMaker 3830 + 3840 */ + { USB_DEVICE(0x05da, 0x30d8) }, /* ScanMaker 5900 */ { USB_DEVICE(0x04a7, 0x0224) }, /* Scanport 3000 (actually Visioneer?)*/ /* The following SCSI-over-USB Microtek devices are supported by the microtek driver: Enable SCSI and USB Microtek in kernel config */ @@ -246,6 +252,7 @@ { USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */ { USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */ { USB_DEVICE(0x07b3, 0x0403) }, /* U16B */ + { USB_DEVICE(0x07b3, 0x0413) }, /* OpticSlim 1200 */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0301) }, /* G2E-300 #1 */ @@ -262,6 +269,8 @@ { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ /* Prolink */ { USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */ + /* Reflecta */ + { USB_DEVICE(0x05e3, 0x0120) }, /* iScan 1800 */ /* Relisis */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ { USB_DEVICE(0x0475, 0x0210) }, /* Scorpio Ultra 3 */ @@ -286,6 +295,7 @@ { USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */ { USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */ { USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */ + { USB_DEVICE(0x04b8, 0x011f) }, /* Perfection 1670 */ { USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */ { USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */ /* Siemens */ @@ -310,6 +320,7 @@ { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0224) }, /* OneTouch 4800 USB */ { USB_DEVICE(0x04a7, 0x0226) }, /* OneTouch 5800 USB */ + { USB_DEVICE(0x04a7, 0x0229) }, /* OneTouch 7100 USB */ { USB_DEVICE(0x04a7, 0x022c) }, /* OneTouch 9020 USB */ { USB_DEVICE(0x04a7, 0x0231) }, /* 6100 USB */ { USB_DEVICE(0x04a7, 0x0311) }, /* 6200 EPP/USB */ diff -urN linux-2.4.24/drivers/usb/serial/ftdi_sio.c linux-2.4.25/drivers/usb/serial/ftdi_sio.c --- linux-2.4.24/drivers/usb/serial/ftdi_sio.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/ftdi_sio.c 2004-02-18 05:36:31.000000000 -0800 @@ -333,6 +333,10 @@ { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) }, { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) }, { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, { } /* Terminating entry */ }; @@ -407,6 +411,10 @@ { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) }, { } /* Terminating entry */ }; @@ -496,6 +504,10 @@ { USB_DEVICE(OCT_VID, OCT_US101_PID) }, { USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) }, { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) }, + { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) }, + { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) }, + { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) }, + { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) }, { } /* Terminating entry */ }; diff -urN linux-2.4.24/drivers/usb/serial/ftdi_sio.h linux-2.4.25/drivers/usb/serial/ftdi_sio.h --- linux-2.4.24/drivers/usb/serial/ftdi_sio.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/ftdi_sio.h 2004-02-18 05:36:31.000000000 -0800 @@ -145,6 +145,14 @@ /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ +/* + * Protego product ids + */ +#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ +#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ +#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ +#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff -urN linux-2.4.24/drivers/usb/serial/io_edgeport.c linux-2.4.25/drivers/usb/serial/io_edgeport.c --- linux-2.4.24/drivers/usb/serial/io_edgeport.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/io_edgeport.c 2004-02-18 05:36:31.000000000 -0800 @@ -1468,15 +1468,19 @@ urb->transfer_flags |= USB_QUEUE_BULK; urb->dev = edge_serial->serial->dev; + /* decrement the number of credits we have by the number we just sent */ + edge_port->txCredits -= count; + edge_port->icount.tx += count; + status = usb_submit_urb(urb); if (status) { /* something went wrong */ dbg("%s - usb_submit_urb(write bulk) failed", __FUNCTION__); edge_port->write_in_progress = FALSE; - } else { - /* decrement the number of credits we have by the number we just sent */ - edge_port->txCredits -= count; - edge_port->icount.tx += count; + + /*revert the count if something bad happened...*/ + edge_port->txCredits += count; + edge_port->icount.tx -= count; } dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __FUNCTION__, count, edge_port->txCredits, fifo->count); } diff -urN linux-2.4.24/drivers/usb/serial/io_fw_boot.h linux-2.4.25/drivers/usb/serial/io_fw_boot.h --- linux-2.4.24/drivers/usb/serial/io_fw_boot.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/io_fw_boot.h 2004-02-18 05:36:31.000000000 -0800 @@ -17,7 +17,7 @@ unsigned short Addr; unsigned short Len; unsigned char Data[0]; - }; + } __attribute__ ((packed)); struct edge_firmware_version_info { unsigned char MajorVersion; diff -urN linux-2.4.24/drivers/usb/serial/io_fw_boot2.h linux-2.4.25/drivers/usb/serial/io_fw_boot2.h --- linux-2.4.24/drivers/usb/serial/io_fw_boot2.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/io_fw_boot2.h 2004-02-18 05:36:31.000000000 -0800 @@ -17,7 +17,7 @@ unsigned short Addr; unsigned short Len; unsigned char Data[0]; - }; + } __attribute__ ((packed)); struct edge_firmware_version_info { unsigned char MajorVersion; diff -urN linux-2.4.24/drivers/usb/serial/io_fw_down.h linux-2.4.25/drivers/usb/serial/io_fw_down.h --- linux-2.4.24/drivers/usb/serial/io_fw_down.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/io_fw_down.h 2004-02-18 05:36:31.000000000 -0800 @@ -17,7 +17,7 @@ unsigned short Addr; unsigned short Len; unsigned char Data[0]; - }; + } __attribute ((packed)); struct edge_firmware_version_info { unsigned char MajorVersion; diff -urN linux-2.4.24/drivers/usb/serial/io_fw_down2.h linux-2.4.25/drivers/usb/serial/io_fw_down2.h --- linux-2.4.24/drivers/usb/serial/io_fw_down2.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/io_fw_down2.h 2004-02-18 05:36:31.000000000 -0800 @@ -17,7 +17,7 @@ unsigned short Addr; unsigned short Len; unsigned char Data[0]; - }; + } __attribute__ ((packed)); struct edge_firmware_version_info { unsigned char MajorVersion; diff -urN linux-2.4.24/drivers/usb/serial/ir-usb.c linux-2.4.25/drivers/usb/serial/ir-usb.c --- linux-2.4.24/drivers/usb/serial/ir-usb.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/ir-usb.c 2004-02-18 05:36:31.000000000 -0800 @@ -568,7 +568,9 @@ case B115200: ir_baud = SPEED_115200; break; case B576000: ir_baud = SPEED_576000; break; case B1152000: ir_baud = SPEED_1152000; break; +#ifdef B4000000 case B4000000: ir_baud = SPEED_4000000; break; +#endif } if (xbof == -1) { diff -urN linux-2.4.24/drivers/usb/serial/mct_u232.c linux-2.4.25/drivers/usb/serial/mct_u232.c --- linux-2.4.24/drivers/usb/serial/mct_u232.c 2002-11-28 15:53:15.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/mct_u232.c 2004-02-18 05:36:31.000000000 -0800 @@ -24,6 +24,11 @@ * Basic tests have been performed with minicom/zmodem transfers and * modem dialing under Linux 2.4.0-test10 (for me it works fine). * + * 04-Nov-2003 Bill Marr + * - Mimic Windows driver by sending 2 USB 'device request' messages + * following normal 'baud rate change' message. This allows data to be + * transmitted to RS-232 devices which don't assert the 'CTS' signal. + * * 10-Nov-2001 Wolfgang Grandegger * - Fixed an endianess problem with the baudrate selection for PowerPC. * @@ -85,7 +90,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.1" +#define DRIVER_VERSION "v1.2" #define DRIVER_AUTHOR "Wolfgang Grandegger " #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" @@ -201,6 +206,7 @@ { unsigned int divisor; int rc; + unsigned char zero_byte = 0; divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value)); rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCT_U232_SET_BAUD_RATE_REQUEST, @@ -210,6 +216,35 @@ if (rc < 0) err("Set BAUD RATE %d failed (error = %d)", value, rc); dbg("set_baud_rate: value: %d, divisor: 0x%x", value, divisor); + + /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which + always sends two extra USB 'device request' messages after the + 'baud rate change' message. The actual functionality of the + request codes in these messages is not fully understood but these + particular codes are never seen in any operation besides a baud + rate change. Both of these messages send a single byte of data + whose value is always zero. The second of these two extra messages + is required in order for data to be properly written to an RS-232 + device which does not assert the 'CTS' signal. */ + + rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + MCT_U232_SET_UNKNOWN1_REQUEST, + MCT_U232_SET_REQUEST_TYPE, + 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, + WDR_TIMEOUT); + if (rc < 0) + err("Sending USB device request code %d failed (error = %d)", + MCT_U232_SET_UNKNOWN1_REQUEST, rc); + + rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + MCT_U232_SET_UNKNOWN2_REQUEST, + MCT_U232_SET_REQUEST_TYPE, + 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE, + WDR_TIMEOUT); + if (rc < 0) + err("Sending USB device request code %d failed (error = %d)", + MCT_U232_SET_UNKNOWN2_REQUEST, rc); + return rc; } /* mct_u232_set_baud_rate */ diff -urN linux-2.4.24/drivers/usb/serial/mct_u232.h linux-2.4.25/drivers/usb/serial/mct_u232.h --- linux-2.4.24/drivers/usb/serial/mct_u232.h 2001-12-21 09:41:55.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/mct_u232.h 2004-02-18 05:36:31.000000000 -0800 @@ -57,6 +57,21 @@ #define MCT_U232_SET_MODEM_CTRL_REQUEST 10 /* Set Modem Control Register (MCR) */ #define MCT_U232_SET_MODEM_CTRL_SIZE 1 +/* This USB device request code is not well understood. It is transmitted by + the MCT-supplied Windows driver whenever the baud rate changes. +*/ +#define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */ +#define MCT_U232_SET_UNKNOWN1_SIZE 1 + +/* This USB device request code is not well understood. It is transmitted by + the MCT-supplied Windows driver whenever the baud rate changes. + + Without this USB device request, the USB/RS-232 adapter will not write to + RS-232 devices which do not assert the 'CTS' signal. +*/ +#define MCT_U232_SET_UNKNOWN2_REQUEST 12 /* Unknown functionality */ +#define MCT_U232_SET_UNKNOWN2_SIZE 1 + /* * Baud rate (divisor) */ @@ -137,22 +152,31 @@ * Baud rate (divisor) * ------------------- * - * BmRequestType: 0x4 (0100 0000B) - * bRequest: 0x5 - * wValue: 0x0 - * wIndex: 0x0 - * wLength: 0x4 + * BmRequestType: 0x40 (0100 0000B) + * bRequest: 0x05 + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0004 * Data: divisor = 115200 / baud_rate * + * SniffUSB observations (Nov 2003): Contrary to the 'wLength' value of 4 + * shown above, observations with a Belkin F5U109 adapter, using the + * MCT-supplied Windows98 driver (U2SPORT.VXD, "File version: 1.21P.0104 for + * Win98/Me"), show this request has a length of 1 byte, presumably because + * of the fact that the Belkin adapter and the 'Sitecom U232-P25' adapter + * use a baud-rate code instead of a conventional RS-232 baud rate divisor. + * The current source code for this driver does not reflect this fact, but + * the driver works fine with this adapter/driver combination nonetheless. + * * * Line Control Register (LCR) * --------------------------- * - * BmRequestType: 0x4 (0100 0000B) 0xc (1100 0000B) - * bRequest: 0x7 0x6 - * wValue: 0x0 - * wIndex: 0x0 - * wLength: 0x1 + * BmRequestType: 0x40 (0100 0000B) 0xc0 (1100 0000B) + * bRequest: 0x07 0x06 + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0001 * Data: LCR (see below) * * Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data @@ -186,18 +210,18 @@ * * SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs * in the Win98 driver: the break does not work (bit 6 is not asserted) and the - * sticky parity bit is not cleared when set once. The LCR can also be read + * stick parity bit is not cleared when set once. The LCR can also be read * back with USB request 6 but this has never been observed with SniffUSB. * * * Modem Control Register (MCR) * ---------------------------- * - * BmRequestType: 0x4 (0100 0000B) - * bRequest: 0xa - * wValue: 0x0 - * wIndex: 0x0 - * wLength: 0x1 + * BmRequestType: 0x40 (0100 0000B) + * bRequest: 0x0a + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0001 * Data: MCR (Bit 4..7, see below) * * Bit 7: Reserved, always 0. @@ -226,11 +250,11 @@ * Modem Status Register (MSR) * --------------------------- * - * BmRequestType: 0xc (1100 0000B) - * bRequest: 0x2 - * wValue: 0x0 - * wIndex: 0x0 - * wLength: 0x1 + * BmRequestType: 0xc0 (1100 0000B) + * bRequest: 0x02 + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0001 * Data: MSR (see below) * * Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the @@ -287,6 +311,41 @@ * minicom/zmodem transfers (CRC errors). * * + * Unknown #1 + * ------------------- + * + * BmRequestType: 0x40 (0100 0000B) + * bRequest: 0x0b + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0001 + * Data: 0x00 + * + * SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver + * (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request + * occurs immediately after a "Baud rate (divisor)" message. It was not + * observed at any other time. It is unclear what purpose this message + * serves. + * + * + * Unknown #2 + * ------------------- + * + * BmRequestType: 0x40 (0100 0000B) + * bRequest: 0x0c + * wValue: 0x0000 + * wIndex: 0x0000 + * wLength: 0x0001 + * Data: 0x00 + * + * SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver + * (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request + * occurs immediately after the 'Unknown #1' message (see above). It was + * not observed at any other time. It is unclear what other purpose (if + * any) this message might serve, but without it, the USB/RS-232 adapter + * will not write to RS-232 devices which do not assert the 'CTS' signal. + * + * * Flow control * ------------ * diff -urN linux-2.4.24/drivers/usb/serial/pl2303.c linux-2.4.25/drivers/usb/serial/pl2303.c --- linux-2.4.24/drivers/usb/serial/pl2303.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/pl2303.c 2004-02-18 05:36:31.000000000 -0800 @@ -69,6 +69,7 @@ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, + { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, @@ -156,6 +157,7 @@ struct pl2303_private { spinlock_t lock; + wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; u8 termios_initialized; @@ -173,6 +175,7 @@ return -ENOMEM; memset (priv, 0x00, sizeof (struct pl2303_private)); spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); usb_set_serial_port_data(&serial->port[i], priv); } return 0; @@ -563,6 +566,42 @@ return 0; } +static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) +{ + struct pl2303_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int prevstatus; + unsigned int status; + unsigned int changed; + + spin_lock_irqsave (&priv->lock, flags); + prevstatus = priv->line_status; + spin_unlock_irqrestore (&priv->lock, flags); + + while (1) { + interruptible_sleep_on(&priv->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + + spin_lock_irqsave (&priv->lock, flags); + status = priv->line_status; + spin_unlock_irqrestore (&priv->lock, flags); + + changed=prevstatus^status; + + if (((arg & TIOCM_RNG) && (changed & UART_RING)) || + ((arg & TIOCM_DSR) && (changed & UART_DSR)) || + ((arg & TIOCM_CD) && (changed & UART_DCD)) || + ((arg & TIOCM_CTS) && (changed & UART_CTS)) ) { + return 0; + } + prevstatus = status; + } + /* NOTREACHED */ + return 0; +} + static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd); @@ -579,6 +618,10 @@ dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, port->number); return set_modem_info(port, cmd, (unsigned int *) arg); + case TIOCMIWAIT: + dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); + return wait_modem_info(port, arg); + default: dbg("%s not supported = 0x%04x", __FUNCTION__, cmd); break; @@ -662,6 +705,7 @@ spin_lock_irqsave(&priv->lock, flags); priv->line_status = data[UART_STATE]; spin_unlock_irqrestore(&priv->lock, flags); + wake_up_interruptible (&priv->delta_msr_wait); return; } diff -urN linux-2.4.24/drivers/usb/serial/pl2303.h linux-2.4.25/drivers/usb/serial/pl2303.h --- linux-2.4.24/drivers/usb/serial/pl2303.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/pl2303.h 2004-02-18 05:36:31.000000000 -0800 @@ -12,6 +12,7 @@ #define PL2303_PRODUCT_ID_RSAQ2 0x04bb #define ATEN_VENDOR_ID 0x0557 +#define ATEN_VENDOR_ID2 0x0547 #define ATEN_PRODUCT_ID 0x2008 #define IODATA_VENDOR_ID 0x04bb diff -urN linux-2.4.24/drivers/usb/serial/visor.c linux-2.4.25/drivers/usb/serial/visor.c --- linux-2.4.24/drivers/usb/serial/visor.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/visor.c 2004-02-18 05:36:31.000000000 -0800 @@ -211,6 +211,8 @@ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { } /* Terminating entry */ @@ -241,6 +243,8 @@ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { } /* Terminating entry */ diff -urN linux-2.4.24/drivers/usb/serial/visor.h linux-2.4.25/drivers/usb/serial/visor.h --- linux-2.4.24/drivers/usb/serial/visor.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/serial/visor.h 2004-02-18 05:36:31.000000000 -0800 @@ -41,6 +41,8 @@ #define SONY_CLIE_4_1_ID 0x009A #define SONY_CLIE_NX60_ID 0x00DA #define SONY_CLIE_NZ90V_ID 0x00E9 +#define SONY_CLIE_UX50_ID 0x0144 +#define SONY_CLIE_TJ25_ID 0x0169 #define SAMSUNG_VENDOR_ID 0x04E8 #define SAMSUNG_SCH_I330_ID 0x8001 diff -urN linux-2.4.24/drivers/usb/storage/transport.c linux-2.4.25/drivers/usb/storage/transport.c --- linux-2.4.24/drivers/usb/storage/transport.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/storage/transport.c 2004-02-18 05:36:31.000000000 -0800 @@ -1140,7 +1140,7 @@ US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n", le32_to_cpu(bcb->Signature), bcb->Tag, (bcb->Lun >> 4), (bcb->Lun & 0x0F), - bcb->DataTransferLength, bcb->Flags, bcb->Length); + le32_to_cpu(bcb->DataTransferLength), bcb->Flags, bcb->Length); result = usb_stor_bulk_msg(us, bcb, pipe, US_BULK_CB_WRAP_LEN, &partial); US_DEBUGP("Bulk command transfer result=%d\n", result); diff -urN linux-2.4.24/drivers/usb/storage/unusual_devs.h linux-2.4.25/drivers/usb/storage/unusual_devs.h --- linux-2.4.24/drivers/usb/storage/unusual_devs.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/storage/unusual_devs.h 2004-02-18 05:36:31.000000000 -0800 @@ -53,7 +53,7 @@ UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, "Mitsumi", "USB FDD", - US_SC_UFI, US_PR_CBI, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN ), UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, @@ -102,6 +102,12 @@ "Finecam S4", US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY), +/* Patch submitted by Stephane Galles */ +UNUSUAL_DEV( 0x0482, 0x0103, 0x0100, 0x0100, + "Kyocera", + "Finecam S5", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), + /* Reported by Paul Stewart * This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, @@ -257,7 +263,7 @@ UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100, "Sony", "Memorystick MSAC-US1", - US_SC_UFI, US_PR_CB, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN ), /* Submitted by Klaus Mueller */ @@ -283,7 +289,7 @@ UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, "Sony", "PEG Mass Storage", - US_SC_8070, US_PR_CBI, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299, @@ -298,6 +304,12 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN), +/* Fabrizio Fellini */ +UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, + "Fujifilm", + "Digital Camera EX-20 DSC", + US_SC_8070, US_PR_CBI, NULL, 0 ), + UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, "LaCie", "USB Hard Disk", @@ -354,6 +366,13 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Submitted Alexander Oltu */ +UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, + "", + "USB TO IDE", + US_SC_SCSI, US_PR_DEVICE, NULL, + US_FL_MODE_XLATE ), + /* Reported by Peter Marks * Like the SIIG unit above, this unit needs an INQUIRY to ask for exactly * 36 bytes of data. No more, no less. That is the only reason this entry @@ -400,6 +419,28 @@ "DIMAGE E223", US_SC_SCSI, US_PR_DEVICE, NULL, 0 ), +/* Following three Minolta cameras reported by Martin Pool + * . Originally discovered by Kedar Petankar, + * Matthew Geier, Mikael Lofj"ard, Marcel de Boer. + */ +UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0686, 0x400b, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7i", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0686, 0x400f, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7Hi", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara", "FlashGate SmartMedia", @@ -528,6 +569,14 @@ US_SC_SCSI, US_PR_DATAFAB, NULL, US_FL_MODE_XLATE ), #endif +#ifdef CONFIG_USB_STORAGE_SDDR55 +/* SM part - aeb */ +UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, + "Datafab Systems, Inc.", + "USB to CF + SM Combo (LC1)", + US_SC_SCSI, US_PR_SDDR55, NULL, + US_FL_SINGLE_LUN ), +#endif /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 * Only revision 1.13 tested (same for all of the above devices, @@ -570,11 +619,27 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MODE_XLATE ), +/*Medion 6047 Digital Camera +Davide Andrian <_nessuno_@katamail.com> +*/ +UNUSUAL_DEV( 0x08ca, 0x2011, 0x0001, 0x0001, + "3MegaCam", + "3MegaCam", + US_SC_DEVICE, US_PR_BULK, NULL, + US_FL_MODE_XLATE ), + +/* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ +UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, + "Trumpion", + "MP3 player", + US_SC_RBC, US_PR_BULK, NULL, + US_FL_MODE_XLATE), + /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", "5-in-1 Card Reader", - US_SC_SCSI, US_PR_BULK, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001, @@ -602,11 +667,18 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* This entry from in the Debian mailing list */ +UNUSUAL_DEV( 0x0a17, 0x0006, 0x0000, 0xffff, + "Pentax", + "Optio 330GS", + US_SC_8070, US_PR_CB, NULL, + US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ), + /* Submitted by Per Winkvist */ UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009, "Pentax", - "Optio S", - US_SC_8070, US_PR_CBI, NULL, + "Optio S/S4", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), #ifdef CONFIG_USB_STORAGE_ISD200 @@ -617,13 +689,6 @@ 0 ), #endif -/* Submitted by Antoine Mairesse */ -UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, - "USB", - "Solid state disk", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_INQUIRY ), - /* Submitted by Joris Struyve */ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, "Medion", @@ -640,6 +705,24 @@ "Jenoptik", "JD 5200 z3", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), + +/* Reported by Lubomir Blaha + * I _REALLY_ don't know what 3rd, 4th number and all defines mean, but this + * works for me. Can anybody correct these values? (I able to test corrected + * version.) + */ +UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff, + "Netac", + "USB-CF-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Antoine Mairesse */ +UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, + "USB", + "Solid state disk", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), /* Reported by Kevin Cernekee * Tested on hardware version 1.10. @@ -669,3 +752,12 @@ US_SC_SCSI, US_PR_SDDR55, NULL, US_FL_SINGLE_LUN), #endif + +/* Patch for Kyocera Finecam L3 + * Submitted by Michael Krauth + */ +UNUSUAL_DEV( 0x0482, 0x0105, 0x0100, 0x0100, + "Kyocera", + "Finecam L3", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_INQUIRY), diff -urN linux-2.4.24/drivers/usb/storage/usb.c linux-2.4.25/drivers/usb/storage/usb.c --- linux-2.4.24/drivers/usb/storage/usb.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/usb/storage/usb.c 2004-02-18 05:36:31.000000000 -0800 @@ -332,6 +332,8 @@ /* set our name for identification purposes */ sprintf(current->comm, "usb-storage-%d", us->host_number); + + current->flags |= PF_MEMALLOC; unlock_kernel(); @@ -726,6 +728,7 @@ /* allocate an IRQ callback if one is needed */ if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) { + up(&(ss->dev_semaphore)); usb_dec_dev_use(dev); return NULL; } @@ -733,6 +736,7 @@ /* allocate the URB we're going to use */ ss->current_urb = usb_alloc_urb(0); if (!ss->current_urb) { + up(&(ss->dev_semaphore)); usb_dec_dev_use(dev); return NULL; } diff -urN linux-2.4.24/drivers/usb/usb.c linux-2.4.25/drivers/usb/usb.c --- linux-2.4.24/drivers/usb/usb.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/usb.c 2004-02-18 05:36:31.000000000 -0800 @@ -1198,7 +1198,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { - struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); int ret; if (!dr) diff -urN linux-2.4.24/drivers/usb/vicam.c linux-2.4.25/drivers/usb/vicam.c --- linux-2.4.24/drivers/usb/vicam.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/vicam.c 2004-02-18 05:36:31.000000000 -0800 @@ -601,12 +601,19 @@ case VIDIOCSWIN: { - struct video_window *vw = (struct video_window *) arg; - DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height); + struct video_window vw; - if ( vw->width != 320 || vw->height != 240 ) + if (copy_from_user(&vw, arg, sizeof(vw))) + { retval = -EFAULT; + break; + } + + DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height); + if ( vw.width != 320 || vw.height != 240 ) + retval = -EFAULT; + break; } diff -urN linux-2.4.24/drivers/usb/w9968cf.c linux-2.4.25/drivers/usb/w9968cf.c --- linux-2.4.24/drivers/usb/w9968cf.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/w9968cf.c 2004-02-18 05:36:31.000000000 -0800 @@ -1,14 +1,14 @@ /*************************************************************************** * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. * * * - * Copyright (C) 2002 2003 by Luca Risolia * + * Copyright (C) 2002 2003 by Luca Risolia * * * * - Memory management code from bttv driver by Ralph Metzler, * * Marcus Metzler and Gerd Knorr. * * - I2C interface to kernel, high-level CMOS sensor control routines and * * some symbolic names from OV511 driver by Mark W. McClelland. * * - Low-level I2C fast write function by Piotr Czerczak. * - * - Low-level I2C read function by Frédéric Jouault. * + * - Low-level I2C read function by Frederic Jouault. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -46,17 +46,19 @@ #include "w9968cf.h" #include "w9968cf_decoder.h" -EXPORT_NO_SYMBOLS; - - /**************************************************************************** - * Modules paramaters * + * Module macros and paramaters * ****************************************************************************/ +MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL); +MODULE_DESCRIPTION(W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION); +MODULE_LICENSE(W9968CF_MODULE_LICENSE); +MODULE_SUPPORTED_DEVICE("Video"); + static u8 vppmod_load = W9968CF_VPPMOD_LOAD; static u8 simcams = W9968CF_SIMCAMS; -static int video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /* -1=first free */ +static s8 video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /* -1=first free */ static u16 packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_PACKET_SIZE}; static u8 max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BUFFERS}; static u8 double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] = @@ -74,10 +76,10 @@ static u8 lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LIGHTFREQ}; static u8 bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]= W9968CF_BANDINGFILTER}; -static int clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV}; +static s8 clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV}; static u8 backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT}; static u8 mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR}; -static u8 sensor_mono[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_SENSOR_MONO}; +static u8 monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME}; static u16 brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BRIGHTNESS}; static u16 hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE}; static u16 colour[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR}; @@ -88,36 +90,27 @@ static u8 specific_debug = W9968CF_SPECIFIC_DEBUG; #endif -MODULE_AUTHOR("Luca Risolia "); - -MODULE_DESCRIPTION("Video4Linux driver for " - "W996[87]CF JPEG USB Dual Mode Camera Chip"); - -MODULE_SUPPORTED_DEVICE("Video"); - -MODULE_LICENSE("GPL"); - -MODULE_PARM(vppmod_load, "i"); +MODULE_PARM(vppmod_load, "b"); MODULE_PARM(simcams, "i"); MODULE_PARM(video_nr, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); MODULE_PARM(packet_size, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); MODULE_PARM(max_buffers, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); -MODULE_PARM(double_buffer, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); -MODULE_PARM(clamping, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); +MODULE_PARM(double_buffer, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(clamping, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); MODULE_PARM(filter_type, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); -MODULE_PARM(largeview, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); +MODULE_PARM(largeview, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); MODULE_PARM(decompression, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); -MODULE_PARM(upscaling, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); +MODULE_PARM(upscaling, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); MODULE_PARM(force_palette, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); MODULE_PARM(force_rgb, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); -MODULE_PARM(autobright, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(autoexp, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(lightfreq, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(bandingfilter, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(clockdiv, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(backlight, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(mirror, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); -MODULE_PARM(sensor_mono, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); +MODULE_PARM(autobright, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(autoexp, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(lightfreq, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); +MODULE_PARM(bandingfilter, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(clockdiv, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i"); +MODULE_PARM(backlight, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(mirror, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); +MODULE_PARM(monochrome, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b"); MODULE_PARM(brightness, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); MODULE_PARM(hue, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); MODULE_PARM(colour, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); @@ -125,7 +118,7 @@ MODULE_PARM(whiteness, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l"); #ifdef W9968CF_DEBUG MODULE_PARM(debug, "i"); -MODULE_PARM(specific_debug, "i"); +MODULE_PARM(specific_debug, "b"); #endif MODULE_PARM_DESC(vppmod_load, @@ -163,7 +156,7 @@ "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")." "\n"); MODULE_PARM_DESC(max_buffers, - "\n Only for advanced users." + "\n For advanced users." "\nSpecify the maximum number of video frame buffers" "\nto allocate for each device, from 2 to " __MODULE_STRING(W9968CF_MAX_BUFFERS) @@ -206,7 +199,8 @@ "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING) " for every device." "\nIf 'w9968cf-vpp' is not loaded, this paramater is" - " set to 0."); + " set to 0." + "\n"); MODULE_PARM_DESC(decompression, "\n<0|1|2[,...]> Software video decompression:" "\n- 0 disables decompression (doesn't allow formats needing" @@ -221,7 +215,8 @@ "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION) " for every device." "\nIf 'w9968cf-vpp' is not loaded, forcing decompression is " - "\nnot allowed; in this case this paramater is set to 2."); + "\nnot allowed; in this case this paramater is set to 2." + "\n"); MODULE_PARM_DESC(force_palette, "\n<0" "|" __MODULE_STRING(VIDEO_PALETTE_UYVY) @@ -255,7 +250,8 @@ "\nInitial palette is " __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"." "\nIf 'w9968cf-vpp' is not loaded, this paramater is" - " set to 9 (UYVY)."); + " set to 9 (UYVY)." + "\n"); MODULE_PARM_DESC(force_rgb, "\n<0|1[,...]> Read RGB video data instead of BGR:" "\n 1 = use RGB component ordering." @@ -314,10 +310,11 @@ "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR) " for every device." "\n"); -MODULE_PARM_DESC(sensor_mono, - "\n<0|1[,...]> The OV CMOS sensor is monochrome:" +MODULE_PARM_DESC(monochrome, + "\n<0|1[,...]> Use OV CMOS sensor as monochrome sensor:" "\n 0 = no, 1 = yes" - "\nDefault value is "__MODULE_STRING(W9968CF_SENSOR_MONO) + "\nNot all the sensors support monochrome color." + "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME) " for every device." "\n"); MODULE_PARM_DESC(brightness, @@ -349,7 +346,7 @@ #ifdef W9968CF_DEBUG MODULE_PARM_DESC(debug, "\n Debugging information level, from 0 to 6:" - "\n0 = none (be cautious)" + "\n0 = none (use carefully)" "\n1 = critical errors" "\n2 = significant informations" "\n3 = configuration or general messages" @@ -383,29 +380,23 @@ static int w9968cf_release(struct inode*, struct file*); static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*); static int w9968cf_mmap(struct file*, struct vm_area_struct*); -static int w9968cf_ioctl(struct inode*, struct file*, - unsigned int, unsigned long); -static int w9968cf_do_ioctl(struct w9968cf_device*, unsigned int, void*); +static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long); +static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*); -/* /proc interface */ #if defined(CONFIG_VIDEO_PROC_FS) +/* /proc interface */ static void w9968cf_proc_create(void); static void w9968cf_proc_destroy(void); static void w9968cf_proc_create_dev(struct w9968cf_device*); static void w9968cf_proc_destroy_dev(struct w9968cf_device*); static int w9968cf_proc_read_global(char*, char**, off_t, int, int*, void*); static int w9968cf_proc_read_dev(char*, char**, off_t, int, int*, void*); -#else -static inline void w9968cf_proc_create(void) {} -static inline void w9968cf_proc_destroy(void) {} -static inline void w9968cf_proc_create_dev(struct w9968cf_device* cam) {} -static inline void w9968cf_proc_destroy_dev(struct w9968cf_device* cam) {} #endif /* USB-specific */ -static void w9968cf_urb_complete(struct urb *urb); static int w9968cf_start_transfer(struct w9968cf_device*); static int w9968cf_stop_transfer(struct w9968cf_device*); +static void w9968cf_urb_complete(struct urb *urb); static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index); static int w9968cf_read_reg(struct w9968cf_device*, u16 index); static int w9968cf_write_fsb(struct w9968cf_device*, u16* data); @@ -413,7 +404,6 @@ static int w9968cf_read_sb(struct w9968cf_device*); static int w9968cf_upload_quantizationtables(struct w9968cf_device*); - /* Low-level I2C (SMBus) I/O */ static int w9968cf_smbus_start(struct w9968cf_device*); static int w9968cf_smbus_stop(struct w9968cf_device*); @@ -421,6 +411,7 @@ static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v); static int w9968cf_smbus_write_ack(struct w9968cf_device*); static int w9968cf_smbus_read_ack(struct w9968cf_device*); +static int w9968cf_smbus_refresh_bus(struct w9968cf_device*); static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam, u16 address, u8* value); static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address, @@ -457,12 +448,11 @@ static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val); static inline int w9968cf_sensor_cmd(struct w9968cf_device*, unsigned int cmd, void *arg); -static void w9968cf_sensor_configure(struct w9968cf_device*); -static int w9968cf_sensor_change_settings(struct w9968cf_device*); -static int w9968cf_sensor_get_picture(struct w9968cf_device*, - struct video_picture*); -static int w9968cf_sensor_set_picture(struct w9968cf_device*, - struct video_picture pict); +static int w9968cf_sensor_init(struct w9968cf_device*); +static int w9968cf_sensor_update_settings(struct w9968cf_device*); +static int w9968cf_sensor_get_picture(struct w9968cf_device*); +static int w9968cf_sensor_update_picture(struct w9968cf_device*, + struct video_picture pict); /* Other helper functions */ static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*, @@ -608,8 +598,6 @@ * Memory management functions * ****************************************************************************/ -/* Shameless copy from bttv-driver.c */ - /* Here we want the physical address of the memory. This is used when initializing the contents of the area. */ static inline unsigned long kvirt_to_pa(unsigned long adr) @@ -660,7 +648,6 @@ } vfree(mem); } -/* End of shameless copy */ /*-------------------------------------------------------------------------- @@ -834,7 +821,7 @@ list_for_each(ptr, list) { cam = list_entry(ptr, struct w9968cf_device, v4llist); out += sprintf(out,"/dev/video%d : %s\n", - cam->v4ldev.minor, symbolic(camlist, cam->id)); + cam->v4ldev->minor, symbolic(camlist, cam->id)); } up(&w9968cf_devlist_sem); @@ -865,21 +852,18 @@ int len; char* out = page; - static struct video_picture pict; /* it has to be static */ - static int rc = 0; - if (down_interruptible(&cam->procfs_sem)) return -ERESTARTSYS; if (offset == 0) - rc = w9968cf_sensor_get_picture(cam, &pict); + w9968cf_sensor_get_picture(cam); out += sprintf(out,"camera_model : %s\n", symbolic(camlist, cam->id)); out += sprintf(out,"sensor_model : %s\n", symbolic(senlist, cam->sensor)); out += sprintf(out,"sensor_monochrome : %s\n", - YES_NO(cam->sensor_mono)); + YES_NO(cam->monochrome)); if (cam->users) out += sprintf(out,"user_program : %s\n",cam->command); out += sprintf(out,"packet_size_bytes : %d\n", @@ -920,13 +904,11 @@ out += sprintf(out,"banding_filter : %s\n",YES_NO(cam->bandfilt)); out += sprintf(out,"back_light : %s\n",YES_NO(cam->backlight)); out += sprintf(out,"mirror : %s\n",YES_NO(cam->mirror)); - if (!rc) { - out += sprintf(out,"brightness : %d\n",pict.brightness); - out += sprintf(out,"colour : %d\n",pict.colour); - out += sprintf(out,"contrast : %d\n",pict.contrast); - out += sprintf(out,"hue : %d\n",pict.hue); - out += sprintf(out,"whiteness : %d\n",pict.whiteness); - } + out += sprintf(out,"brightness : %d\n",cam->picture.brightness); + out += sprintf(out,"colour : %d\n",cam->picture.colour); + out += sprintf(out,"contrast : %d\n",cam->picture.contrast); + out += sprintf(out,"hue : %d\n",cam->picture.hue); + out += sprintf(out,"whiteness : %d\n",cam->picture.whiteness); out += sprintf(out,"hs_polarity : %d\n",cam->hs_polarity); out += sprintf(out,"vs_polarity : %d\n",cam->vs_polarity); #ifdef W9968CF_DEBUG @@ -954,34 +936,40 @@ static void w9968cf_proc_create_dev(struct w9968cf_device* cam) { - char name[5]; + char name[6]; if (!w9968cf_proc_entry) return; /* Create per-device readable entry */ - sprintf(name, "dev%d", cam->v4ldev.minor); - cam->proc_dev = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, + sprintf(name, "dev%d", cam->v4ldev->minor); + cam->proc_dev = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, w9968cf_proc_entry, w9968cf_proc_read_dev, (void*)cam); if (!cam->proc_dev) return; cam->proc_dev->owner = THIS_MODULE; + + DBG(2, "Per-device entry /proc/video/w9968cf/dev%d created.", + cam->v4ldev->minor) } static void w9968cf_proc_destroy_dev(struct w9968cf_device* cam) { - char name[5]; + char name[6]; if (!cam->proc_dev) return; - sprintf(name, "dev%d", cam->v4ldev.minor); + sprintf(name, "dev%d", cam->v4ldev->minor); /* Destroy per-device entry */ remove_proc_entry(name, w9968cf_proc_entry); + + DBG(2, "Per-device entry /proc/video/w9968cf/dev%d removed.", + cam->v4ldev->minor) } @@ -1010,7 +998,7 @@ else DBG(2, "Unable to create /proc/video/w9968cf/global") - DBG(5, "/proc entries successfully created.") + DBG(2, "Main entry /proc/video/w9968cf/global created.") } @@ -1024,7 +1012,7 @@ remove_proc_entry("w9968cf", video_proc_entry); - DBG(5, "/proc entries removed.") + DBG(2, "Main entry /proc/video/w9968cf/global removed.") } #endif /* CONFIG_VIDEO_PROC_FS */ @@ -1184,14 +1172,12 @@ for (i = 0; i < W9968CF_URBS; i++) { urb = usb_alloc_urb(W9968CF_ISO_PACKETS); cam->urb[i] = urb; - if (!urb) { for (j = 0; j < i; j++) usb_free_urb(cam->urb[j]); DBG(1, "Couldn't allocate the URB structures.") return -ENOMEM; } - urb->dev = udev; urb->context = (void*)cam; urb->pipe = usb_rcvisocpipe(udev, 1); @@ -1214,7 +1200,7 @@ t_size = (w*h*d)/16; - err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */ + err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */ err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */ /* Transfer size */ @@ -1287,11 +1273,12 @@ spin_unlock_irqrestore(&cam->urb_lock, lock_flags); for (i = W9968CF_URBS-1; i >= 0; i--) - if (cam->urb[i]) + if (cam->urb[i]) { if (!usb_unlink_urb(cam->urb[i])) { usb_free_urb(cam->urb[i]); cam->urb[i] = NULL; } + } if (cam->disconnected) goto exit; @@ -1347,8 +1334,7 @@ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, (void*)buff, - 2, W9968CF_USB_CTRL_TIMEOUT); + 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT); if (res < 0) DBG(4, "Failed to read a register " @@ -1360,7 +1346,7 @@ /*-------------------------------------------------------------------------- - Write data to the fast serial bus registers. + Write 64-bit data to the fast serial bus registers. Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data) @@ -1373,8 +1359,7 @@ res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - value, 0x06, (void*)data, 6, - W9968CF_USB_CTRL_TIMEOUT); + value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT); if (res < 0) DBG(4, "Failed to write the FSB registers " @@ -1536,6 +1521,22 @@ } +/* This is seems to refresh the communication through the serial bus */ +static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam) +{ + int err = 0, j; + + for (j = 1; j <= 10; j++) { + err = w9968cf_write_reg(cam, 0x0020, 0x01); + err += w9968cf_write_reg(cam, 0x0000, 0x01); + if (err) + break; + } + + return err; +} + + /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */ static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, @@ -1544,8 +1545,10 @@ u16* data = cam->data_buffer; int err = 0; - /* Enable SBUS outputs */ - err += w9968cf_write_reg(cam, 0x0020, 0x01); + err += w9968cf_smbus_refresh_bus(cam); + + /* Enable SBUS outputs */ + err += w9968cf_write_sb(cam, 0x0020); data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0); data[0] |= (address & 0x40) ? 0x4000 : 0x0; @@ -1589,7 +1592,7 @@ err += w9968cf_write_fsb(cam, data); /* Disable SBUS outputs */ - err += w9968cf_write_reg(cam, 0x0000, 0x01); + err += w9968cf_write_sb(cam, 0x0000); if (!err) DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X " @@ -1626,7 +1629,7 @@ err += w9968cf_smbus_read_byte(cam, value); err += w9968cf_smbus_write_ack(cam); err += w9968cf_smbus_stop(cam); - + /* Serial data disable */ err += w9968cf_write_sb(cam, 0x0000); @@ -1695,8 +1698,8 @@ int size, union i2c_smbus_data *data) { struct w9968cf_device* cam = adapter->data; - u8 i, j; - int rc = 0, err = 0; + u8 i; + int err = 0; switch (addr) { case OV6xx0_SID: @@ -1712,31 +1715,26 @@ addr <<= 1; if (read_write == I2C_SMBUS_WRITE) - rc = w9968cf_i2c_adap_write_byte(cam, addr, command); + err = w9968cf_i2c_adap_write_byte(cam, addr, command); else if (read_write == I2C_SMBUS_READ) - rc = w9968cf_i2c_adap_read_byte(cam,addr, &data->byte); + err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte); } else if (size == I2C_SMBUS_BYTE_DATA) { addr <<= 1; if (read_write == I2C_SMBUS_WRITE) - rc = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr, + err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr, command, data->byte); else if (read_write == I2C_SMBUS_READ) { for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) { - rc = w9968cf_i2c_adap_read_byte_data(cam, addr, + err = w9968cf_i2c_adap_read_byte_data(cam,addr, command, &data->byte); - if (rc < 0) { - /* Work around: this seems to wake up - the EEPROM from the stall state */ - for (j = 0; j <= 10; j++) { - err += w9968cf_write_sb(cam,0x0020); - err += w9968cf_write_sb(cam,0x0000); - if (err) - break; + if (err) { + if (w9968cf_smbus_refresh_bus(cam)) { + err = -EIO; + break; } - } - else + } else break; } @@ -1748,11 +1746,7 @@ return -EINVAL; } - /* This works around a bug in the I2C core */ - if (rc > 0) - rc = 0; - - return rc; + return err; } @@ -1768,41 +1762,22 @@ { struct w9968cf_device* cam = client->adapter->data; const char* clientname = client->name; - int id = client->driver->id; + int id = client->driver->id, err = 0; if (id == I2C_DRIVERID_OVCAMCHIP) { - int rc = 0; - cam->sensor_client = client; - - rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, - &cam->sensor_mono); - if (rc < 0) { - DBG(1, "CMOS sensor initialization failed (rc=%d)",rc); - cam->sensor_client = NULL; - return rc; - } - - if (w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, - &cam->sensor) < 0) - rc = -EIO; - else if (client->addr==OV7xx0_SID || client->addr==OV6xx0_SID) - w9968cf_sensor_configure(cam); - else - rc = -EINVAL; - - if (rc < 0) { + err = w9968cf_sensor_init(cam); + if (err) { cam->sensor_client = NULL; - cam->sensor = CC_UNKNOWN; - return rc; + return err; } - } else { - DBG(4, "Rejected client [%s] with [%s]", + } else { + DBG(4, "Rejected client [%s] with driver [%s]", clientname, client->driver->name) - return -1; + return -EINVAL; } - DBG(2, "I2C attach client [%s] with [%s]", + DBG(5, "I2C attach client [%s] with driver [%s]", clientname, client->driver->name) return 0; @@ -1818,7 +1793,7 @@ cam->sensor_client = NULL; } - DBG(2, "I2C detach [%s]", clientname) + DBG(5, "I2C detach client [%s]", clientname) return 0; } @@ -1846,7 +1821,7 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) { - int rc = 0; + int err = 0; static struct i2c_algorithm algo = { .name = "W996[87]CF algorithm", @@ -1869,15 +1844,15 @@ strcpy(cam->i2c_adapter.name, "w9968cf"); cam->i2c_adapter.data = cam; - DBG(6, "Registering I2C bus with kernel...") + DBG(6, "Registering I2C adapter with kernel...") - rc = i2c_add_adapter(&cam->i2c_adapter); - if (rc) - DBG(5, "Failed to register the I2C bus.") + err = i2c_add_adapter(&cam->i2c_adapter); + if (err) + DBG(1, "Failed to register the I2C adapter.") else - DBG(5, "I2C bus registered.") + DBG(5, "I2C adapter registered.") - return rc; + return err; } @@ -1917,7 +1892,7 @@ --------------------------------------------------------------------------*/ static int w9968cf_init_chip(struct w9968cf_device* cam) { - int err = 0, rc = 0; + int err = 0; err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */ err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */ @@ -1952,22 +1927,11 @@ err += w9968cf_set_window(cam, cam->window); if (err) - goto error; - - rc = w9968cf_sensor_change_settings(cam); - if (rc) - goto error; - - DBG(5, "Chip successfully initialized."); - - return 0; - -error: - DBG(1, "Chip initialization failed.") - if (err) - return err; + DBG(1, "Chip initialization failed.") else - return rc; + DBG(5, "Chip successfully initialized.") + + return err; } @@ -1979,7 +1943,7 @@ w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict) { u16 fmt, hw_depth, hw_palette, reg_v = 0x0000; - int err = 0, rc = 0; + int err = 0; /* Make sure we are using a valid depth */ pict.depth = w9968cf_valid_depth(pict.palette); @@ -2040,12 +2004,10 @@ else if (cam->filter_type == 2) reg_v |= 0x000c; - err = w9968cf_write_reg(cam, reg_v, 0x16); - if (err) + if ((err = w9968cf_write_reg(cam, reg_v, 0x16))) goto error; - rc = w9968cf_sensor_set_picture(cam, pict); - if (rc) + if ((err = w9968cf_sensor_update_picture(cam, pict))) goto error; /* If all went well, update the device data structure */ @@ -2064,10 +2026,7 @@ error: DBG(1, "Failed to change picture settings.") - if (err) - return err; - else - return rc; + return err; } @@ -2082,7 +2041,7 @@ u16 x, y, w, h, scx, scy, cw, ch, ax, ay; unsigned long fw, fh; struct ovcamchip_window s_win; - int err=0, rc=0; + int err = 0; /* Work around to avoid FP arithmetics */ #define __SC(x) ((x) << 10) @@ -2126,8 +2085,8 @@ ch = h; } - /* Setup the sensor window */ - s_win.format = SENSOR_FORMAT; + /* Setup the window of the sensor */ + s_win.format = VIDEO_PALETTE_UYVY; s_win.width = cam->maxwidth; s_win.height = cam->maxheight; s_win.quarter = 0; /* full progressive video */ @@ -2156,7 +2115,7 @@ s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR; } - /* We have to scale win.x and win.y offsets */ + /* We have to scale win.x and win.y offsets */ if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) || (cam->vpp_flag & VPP_UPSCALE) ) { ax = __SC(win.x)/fw; @@ -2187,7 +2146,7 @@ y = ay + s_win.y; /* Go ! */ - if ((rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win))) + if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win))) goto error; err += w9968cf_write_reg(cam, scx + x, 0x10); @@ -2232,10 +2191,7 @@ error: DBG(1, "Failed to change the capture area size.") - if (err) - return err; - else - return rc; + return err; } @@ -2450,173 +2406,192 @@ w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val) { struct ovcamchip_control ctl; - int rc; + int err; ctl.id = cid; ctl.value = val; - rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl); + err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl); - return rc; + return err; } + static int -w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int *val) +w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val) { struct ovcamchip_control ctl; - int rc; + int err; ctl.id = cid; - rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl); - if (rc >= 0) + err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl); + if (!err) *val = ctl.value; - return rc; + return err; } static inline int -w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void *arg) +w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg) { struct i2c_client* c = cam->sensor_client; + int rc = 0; - DBG(6, "Executing CMOS sensor command...") - - if (c && c->driver->command) - return c->driver->command(cam->sensor_client, cmd, arg); - else + if (c->driver->command) { + rc = c->driver->command(cam->sensor_client, cmd, arg); + /* The I2C driver returns -EPERM on non-supported controls */ + return (rc < 0 && rc != -EPERM) ? rc : 0; + } else return -ENODEV; } /*-------------------------------------------------------------------------- - Change some settings of the CMOS sensor. - Returns: 0 for success, a negative number otherwise. + Update some settings of the CMOS sensor. + Returns: 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ -static int w9968cf_sensor_change_settings(struct w9968cf_device* cam) +static int w9968cf_sensor_update_settings(struct w9968cf_device* cam) { - int rc; + int err = 0; /* Auto brightness */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, - cam->auto_brt); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, + cam->auto_brt); + if (err) + return err; /* Auto exposure */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, - cam->auto_exp); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, + cam->auto_exp); + if (err) + return err; /* Banding filter */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, - cam->bandfilt); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, + cam->bandfilt); + if (err) + return err; /* Light frequency */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ, - cam->lightfreq); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ, + cam->lightfreq); + if (err) + return err; /* Back light */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT, - cam->backlight); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT, + cam->backlight); + if (err) + return err; /* Mirror */ - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR, - cam->mirror); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR, + cam->mirror); + if (err) + return err; return 0; } /*-------------------------------------------------------------------------- - Get some current picture settings from the CMOS sensor. - Returns: 0 for success, a negative number otherwise. + Get some current picture settings from the CMOS sensor and update the + internal 'picture' structure of the camera. + Returns: 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ -static int -w9968cf_sensor_get_picture(struct w9968cf_device* cam, - struct video_picture* pict) +static int w9968cf_sensor_get_picture(struct w9968cf_device* cam) { - int rc, v; + int err, v; - /* Don't return error if a setting is unsupported, or rest of settings - will not be performed */ + err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v); + if (err) + return err; + cam->picture.contrast = v; + + err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v); + if (err) + return err; + cam->picture.brightness = v; - rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v); - if (SENSOR_FATAL_ERROR(rc)) - return rc; - pict->contrast = v; - - rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v); - if (SENSOR_FATAL_ERROR(rc)) - return rc; - pict->brightness = v; - - rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v); - if (SENSOR_FATAL_ERROR(rc)) - return rc; - pict->colour = v; - - rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v); - if (SENSOR_FATAL_ERROR(rc)) - return rc; - pict->hue = v; + err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v); + if (err) + return err; + cam->picture.colour = v; - pict->whiteness = W9968CF_WHITENESS; /* to do! */ + err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v); + if (err) + return err; + cam->picture.hue = v; DBG(5, "Got picture settings from the CMOS sensor.") PDBGG("Brightness, contrast, hue, colour, whiteness are " - "%d,%d,%d,%d,%d.", pict->brightness, pict->contrast, - pict->hue, pict->colour, pict->whiteness) + "%d,%d,%d,%d,%d.", cam->picture.brightness,cam->picture.contrast, + cam->picture.hue, cam->picture.colour, cam->picture.whiteness) return 0; } /*-------------------------------------------------------------------------- - Change picture settings of the CMOS sensor. - Returns: 0 for success, a negative number otherwise. + Update picture settings of the CMOS sensor. + Returns: 0 on success, a negative number otherwise. --------------------------------------------------------------------------*/ static int -w9968cf_sensor_set_picture(struct w9968cf_device* cam, - struct video_picture pict) +w9968cf_sensor_update_picture(struct w9968cf_device* cam, + struct video_picture pict) { - int rc; - - rc = w9968cf_sensor_set_control(cam,OVCAMCHIP_CID_CONT, pict.contrast); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + int err = 0; - if (!cam->auto_brt) { - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, - pict.brightness); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + if ((!cam->sensor_initialized) + || pict.contrast != cam->picture.contrast) { + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT, + pict.contrast); + if (err) + goto fail; + DBG(4, "Contrast changed from %d to %d.", + cam->picture.contrast, pict.contrast) + cam->picture.contrast = pict.contrast; } - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, pict.colour); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + if (((!cam->sensor_initialized) || + pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) { + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, + pict.brightness); + if (err) + goto fail; + DBG(4, "Brightness changed from %d to %d.", + cam->picture.brightness, pict.brightness) + cam->picture.brightness = pict.brightness; + } - rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, pict.hue); - if (SENSOR_FATAL_ERROR(rc)) - return rc; + if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) { + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, + pict.colour); + if (err) + goto fail; + DBG(4, "Colour changed from %d to %d.", + cam->picture.colour, pict.colour) + cam->picture.colour = pict.colour; + } - PDBGG("Brightness, contrast, hue, colour, whiteness are " - "%d,%d,%d,%d,%d.", pict.brightness, pict.contrast, - pict.hue, pict.colour, pict.whiteness) + if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) { + err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, + pict.hue); + if (err) + goto fail; + DBG(4, "Hue changed from %d to %d.", + cam->picture.hue, pict.hue) + cam->picture.hue = pict.hue; + } return 0; + +fail: + DBG(4, "Failed to change sensor picture setting.") + return err; } @@ -2626,12 +2601,22 @@ ****************************************************************************/ /*-------------------------------------------------------------------------- - This function is called when the CMOS sensor is detected. + This function is called when a supported CMOS sensor is detected. + Return 0 if the initialization succeeds, a negative number otherwise. --------------------------------------------------------------------------*/ -static void w9968cf_sensor_configure(struct w9968cf_device* cam) +static int w9968cf_sensor_init(struct w9968cf_device* cam) { - /* NOTE: Make sure width and height are a multiple of 16 */ + int err = 0; + + if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, + &cam->monochrome))) + goto error; + + if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, + &cam->sensor))) + goto error; + /* NOTE: Make sure width and height are a multiple of 16 */ switch (cam->sensor_client->addr) { case OV6xx0_SID: cam->maxwidth = 352; @@ -2645,6 +2630,10 @@ cam->minwidth = 64; cam->minheight = 48; break; + default: + DBG(1, "Not supported CMOS sensor detected for %s.", + symbolic(camlist, cam->id)) + return -EINVAL; } /* These values depend on the ones in the ovxxx0.c sources */ @@ -2663,7 +2652,24 @@ cam->hs_polarity = 0; } - DBG(5, "CMOS sensor %s configured.", symbolic(senlist, cam->sensor)) + if ((err = w9968cf_sensor_update_settings(cam))) + goto error; + + if ((err = w9968cf_sensor_update_picture(cam, cam->picture))) + goto error; + + cam->sensor_initialized = 1; + + DBG(2, "%s CMOS sensor initialized.", symbolic(senlist, cam->sensor)) + return 0; + +error: + cam->sensor_initialized = 0; + cam->sensor = CC_UNKNOWN; + DBG(1, "CMOS sensor initialization failed for %s (/dev/video%d). " + "Try to detach and attach this device again.", + symbolic(camlist, cam->id), cam->v4ldev->minor) + return err; } @@ -2678,7 +2684,7 @@ enum w9968cf_model_id mod_id, const unsigned short dev_nr) { -#if defined(CONFIG_VIDEO_PROC_FS) +#ifdef CONFIG_VIDEO_PROC_FS init_MUTEX(&cam->procfs_sem); #endif init_MUTEX(&cam->fileop_sem); @@ -2691,13 +2697,7 @@ cam->usbdev = udev; cam->id = mod_id; cam->sensor = CC_UNKNOWN; - - strcpy(cam->v4ldev.name, symbolic(camlist, mod_id)); - cam->v4ldev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev.hardware = VID_HARDWARE_W9968CF; - cam->v4ldev.fops = &w9968cf_fops; - cam->v4ldev.priv = (void*)cam; - cam->v4ldev.minor = video_nr[dev_nr]; + cam->sensor_initialized = 0; /* Calculate the alternate setting number (from 1 to 16) according to the 'packet_size' module parameter */ @@ -2709,66 +2709,66 @@ cam->max_buffers = (max_buffers[dev_nr] < 2 || max_buffers[dev_nr] > W9968CF_MAX_BUFFERS) - ? W9968CF_BUFFERS : max_buffers[dev_nr]; + ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr]; cam->double_buffer = (double_buffer[dev_nr] == 0 || double_buffer[dev_nr] == 1) - ? double_buffer[dev_nr] : W9968CF_DOUBLE_BUFFER; + ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER; cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1) - ? clamping[dev_nr] : W9968CF_CLAMPING; + ? (u8)clamping[dev_nr] : W9968CF_CLAMPING; cam->filter_type = (filter_type[dev_nr] == 0 || filter_type[dev_nr] == 1 || filter_type[dev_nr] == 2) - ? filter_type[dev_nr] : W9968CF_FILTER_TYPE; + ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE; cam->capture = 1; cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1) - ? largeview[dev_nr] : W9968CF_LARGEVIEW; + ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW; cam->decompression = (decompression[dev_nr] == 0 || decompression[dev_nr] == 1 || decompression[dev_nr] == 2) - ? decompression[dev_nr] : W9968CF_DECOMPRESSION; + ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION; cam->upscaling = (upscaling[dev_nr] == 0 || upscaling[dev_nr] == 1) - ? upscaling[dev_nr] : W9968CF_UPSCALING; + ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING; cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1) - ? autobright[dev_nr] : W9968CF_AUTOBRIGHT; + ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT; cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1) - ? autoexp[dev_nr] : W9968CF_AUTOEXP; + ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP; cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60) - ? lightfreq[dev_nr] : W9968CF_LIGHTFREQ; + ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ; cam->bandfilt = (bandingfilter[dev_nr] == 0 || bandingfilter[dev_nr] == 1) - ? bandingfilter[dev_nr] : W9968CF_BANDINGFILTER; + ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER; cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1) - ? backlight[dev_nr] : W9968CF_BACKLIGHT; + ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT; cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0) - ? clockdiv[dev_nr] : W9968CF_CLOCKDIV; + ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV; cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1) - ? mirror[dev_nr] : W9968CF_MIRROR; + ? (u8)mirror[dev_nr] : W9968CF_MIRROR; - cam->sensor_mono = (sensor_mono[dev_nr]==0 || sensor_mono[dev_nr]==1) - ? sensor_mono[dev_nr] : W9968CF_SENSOR_MONO; + cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1) + ? monochrome[dev_nr] : W9968CF_MONOCHROME; - cam->picture.brightness = brightness[dev_nr]; - cam->picture.hue = hue[dev_nr]; - cam->picture.colour = colour[dev_nr]; - cam->picture.contrast = contrast[dev_nr]; - cam->picture.whiteness = whiteness[dev_nr]; - if (w9968cf_valid_palette(force_palette[dev_nr])) { - cam->picture.palette = force_palette[dev_nr]; + cam->picture.brightness = (u16)brightness[dev_nr]; + cam->picture.hue = (u16)hue[dev_nr]; + cam->picture.colour = (u16)colour[dev_nr]; + cam->picture.contrast = (u16)contrast[dev_nr]; + cam->picture.whiteness = (u16)whiteness[dev_nr]; + if (w9968cf_valid_palette((u16)force_palette[dev_nr])) { + cam->picture.palette = (u16)force_palette[dev_nr]; cam->force_palette = 1; } else { cam->force_palette = 0; @@ -2781,7 +2781,7 @@ } cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1) - ? force_rgb[dev_nr] : W9968CF_FORCE_RGB; + ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB; cam->window.x = 0; cam->window.y = 0; @@ -2886,7 +2886,7 @@ else DBG(3, "- Clock divisor: %d", cam->clockdiv) - if (cam->sensor_mono) + if (cam->monochrome) DBG(3, "- CMOS sensor used as monochrome.") else DBG(3, "- CMOS sensor not used as monochrome.") @@ -2902,10 +2902,12 @@ { down(&w9968cf_devlist_sem); - DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev.minor) + DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor) +#ifdef CONFIG_VIDEO_PROC_FS w9968cf_proc_destroy_dev(cam); - video_unregister_device(&cam->v4ldev); +#endif + video_unregister_device(cam->v4ldev); list_del(&cam->v4llist); i2c_del_adapter(&cam->i2c_adapter); w9968cf_deallocate_memory(cam); @@ -2925,24 +2927,25 @@ static int w9968cf_open(struct inode* inode, struct file* filp) { - struct w9968cf_device* cam = - (struct w9968cf_device*)video_devdata(filp)->priv; + struct w9968cf_device* cam; int err; + cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); + down(&cam->dev_sem); if (cam->sensor == CC_UNKNOWN) { DBG(2, "No supported CMOS sensor has been detected by the " "'ovcamchip' module for the %s (/dev/video%d). Make " "sure it is loaded *before* the 'w9968cf' module.", - symbolic(camlist, cam->id),cam->v4ldev.minor) + symbolic(camlist, cam->id), cam->v4ldev->minor) up(&cam->dev_sem); return -ENODEV; } if (cam->users) { DBG(2, "%s (/dev/video%d) has been already occupied by '%s'.", - symbolic(camlist, cam->id),cam->v4ldev.minor, cam->command) + symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command) if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { up(&cam->dev_sem); return -EWOULDBLOCK; @@ -2958,7 +2961,7 @@ } DBG(5, "Opening the %s, /dev/video%d ...", - symbolic(camlist, cam->id), cam->v4ldev.minor) + symbolic(camlist, cam->id), cam->v4ldev->minor) cam->streaming = 0; cam->misconfigured = 0; @@ -2975,7 +2978,7 @@ if ((err = w9968cf_start_transfer(cam))) goto deallocate_memory; - filp->private_data = (void*)cam; + filp->private_data = cam; cam->users++; strcpy(cam->command, current->comm); @@ -2997,8 +3000,9 @@ static int w9968cf_release(struct inode* inode, struct file* filp) { - struct w9968cf_device* cam = - (struct w9968cf_device*)video_devdata(filp)->priv; + struct w9968cf_device* cam; + + cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); down(&cam->dev_sem); /* prevent disconnect() to be called */ @@ -3026,11 +3030,12 @@ static ssize_t w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos) { - struct w9968cf_device* cam = - (struct w9968cf_device*)video_devdata(filp)->priv; + struct w9968cf_device* cam; struct w9968cf_frame_t* fr; int err = 0; + cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); + if (filp->f_flags & O_NONBLOCK) return -EWOULDBLOCK; @@ -3094,9 +3099,8 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma) { - struct w9968cf_device* cam = - (struct w9968cf_device*)video_devdata(filp)->priv; - + struct w9968cf_device* cam = (struct w9968cf_device*) + video_get_drvdata(video_devdata(filp)); unsigned long vsize = vma->vm_end - vma->vm_start, psize = cam->nbuffers * w9968cf_get_max_bufsize(cam), start = vma->vm_start, @@ -3136,10 +3140,11 @@ w9968cf_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) { - struct w9968cf_device* cam = - (struct w9968cf_device*)video_devdata(filp)->priv; + struct w9968cf_device* cam; int err; + cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); + if (down_interruptible(&cam->fileop_sem)) return -ERESTARTSYS; @@ -3155,7 +3160,7 @@ return -EIO; } - err = w9968cf_do_ioctl(cam, cmd, (void*)arg); + err = w9968cf_v4l_ioctl(inode, filp, cmd, (void* )arg); up(&cam->fileop_sem); return err; @@ -3163,8 +3168,10 @@ static int -w9968cf_do_ioctl(struct w9968cf_device* cam, unsigned cmd, void* arg) +w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, + unsigned int cmd, void* arg) { + struct w9968cf_device* cam; const char* v4l1_ioctls[] = { "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF", @@ -3176,7 +3183,9 @@ #define V4L1_IOCTL(cmd) \ ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \ - v4l1_ioctls[_IOC_NR((cmd))] : "???") + v4l1_ioctls[_IOC_NR((cmd))] : "?") + + cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); switch (cmd) { @@ -3190,7 +3199,7 @@ .minheight = cam->minheight, }; sprintf(cap.name, "W996[87]CF USB Camera #%d", - cam->v4ldev.minor); + cam->v4ldev->minor); cap.maxwidth = (cam->upscaling && w9968cf_vppmod_present) ? W9968CF_MAX_WIDTH : cam->maxwidth; cap.maxheight = (cam->upscaling && w9968cf_vppmod_present) @@ -3241,15 +3250,10 @@ case VIDIOCGPICT: /* get image properties of the picture */ { - struct video_picture pict; - - if (w9968cf_sensor_get_picture(cam, &pict)) + if (w9968cf_sensor_get_picture(cam)) return -EIO; - pict.depth = cam->picture.depth; - pict.palette = cam->picture.palette; - - if (copy_to_user(arg, &pict, sizeof(pict))) + if (copy_to_user(arg, &cam->picture, sizeof(cam->picture))) return -EFAULT; DBG(5, "VIDIOCGPICT successfully called.") @@ -3278,13 +3282,6 @@ return -EINVAL; } - if (pict.depth != w9968cf_valid_depth(pict.palette)) { - DBG(4, "Depth %d bpp is not supported for %s palette. " - "VIDIOCSPICT failed.", - pict.depth, symbolic(v4l1_plist, pict.palette)) - return -EINVAL; - } - if (!cam->force_palette) { if (cam->decompression == 0) { if (w9968cf_need_decompression(pict.palette)) { @@ -3303,9 +3300,15 @@ } } - if (pict.palette != cam->picture.palette || - pict.depth != cam->picture.depth) - { + if (pict.depth != w9968cf_valid_depth(pict.palette)) { + DBG(4, "Requested depth %d bpp is not valid for %s " + "palette: ignored and changed to %d bpp.", + pict.depth, symbolic(v4l1_plist, pict.palette), + w9968cf_valid_depth(pict.palette)) + pict.depth = w9968cf_valid_depth(pict.palette); + } + + if (pict.palette != cam->picture.palette) { if(*cam->requested_frame || cam->frame_current->queued) { err = wait_event_interruptible @@ -3328,15 +3331,9 @@ if (w9968cf_start_transfer(cam)) goto ioctl_fail; - } else if ( ((pict.brightness != cam->picture.brightness) && - (!cam->auto_brt)) || - pict.hue != cam->picture.hue || - pict.colour != cam->picture.colour || - pict.contrast != cam->picture.contrast || - pict.whiteness != cam->picture.whiteness ) { - if (w9968cf_sensor_set_picture(cam, pict)) - return -EIO; - } + } else if (w9968cf_sensor_update_picture(cam, pict)) + return -EIO; + DBG(5, "VIDIOCSPICT successfully called.") return 0; @@ -3368,7 +3365,6 @@ win.y != cam->window.y || win.width != cam->window.width || win.height != cam->window.height) { - if(*cam->requested_frame || cam->frame_current->queued) { err = wait_event_interruptible @@ -3479,12 +3475,12 @@ } } - if (w9968cf_adjust_window_size(cam, (u16*)&mmap.width, - (u16*)&mmap.height)) { + if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, + (u16*)&mmap.height))) { DBG(4, "Resolution not supported (%dx%d). " "VIDIOCMCAPTURE failed.", mmap.width, mmap.height) - return -EINVAL; + return err; } fr = &cam->frame[mmap.frame]; @@ -3552,10 +3548,13 @@ case VIDIOCSYNC: /* wait until the capture of a frame is finished */ { - unsigned int f_num = *((unsigned int *) arg); + unsigned int f_num; struct w9968cf_frame_t* fr; int err = 0; + if (copy_from_user(&f_num, arg, sizeof(f_num))) + return -EFAULT; + if (f_num >= cam->nbuffers) { DBG(4, "Invalid frame number (%d). " "VIDIOCMCAPTURE failed.", f_num) @@ -3599,7 +3598,7 @@ case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/ { struct video_unit unit = { - .video = cam->v4ldev.minor, + .video = cam->v4ldev->minor, .vbi = VIDEO_NO_UNIT, .radio = VIDEO_NO_UNIT, .audio = VIDEO_NO_UNIT, @@ -3620,7 +3619,8 @@ { struct video_buffer* buffer = (struct video_buffer*)arg; - memset(buffer, 0, sizeof(struct video_buffer)); + if (clear_user(buffer, sizeof(struct video_buffer))) + return -EFAULT; DBG(5, "VIDIOCGFBUF successfully called.") return 0; @@ -3767,14 +3767,6 @@ return NULL; } - err = usb_set_configuration(udev, 1); - err += usb_set_interface(udev, 0, 0); - - if (err) { - DBG(1, "Device configuration failed.") - return NULL; - } - cam = (struct w9968cf_device*) kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL); @@ -3806,10 +3798,24 @@ } memset(cam->data_buffer, 0, 8); - /* Set some basic constants */ - w9968cf_configure_camera(cam, udev, mod_id, dev_nr); + /* Register the V4L device */ + cam->v4ldev = video_device_alloc(); + if (!cam->v4ldev) { + DBG(1, "Could not allocate memory for a V4L structure.") + err = -ENOMEM; + goto fail; + } + + strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); + cam->v4ldev->owner = THIS_MODULE; + cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; + cam->v4ldev->hardware = VID_HARDWARE_W9968CF; + cam->v4ldev->fops = &w9968cf_fops; + cam->v4ldev->minor = video_nr[dev_nr]; + cam->v4ldev->release = video_device_release; + video_set_drvdata(cam->v4ldev, cam); - err = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, + err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, video_nr[dev_nr]); if (err) { DBG(1, "V4L device registration failed.") @@ -3820,22 +3826,27 @@ goto fail; } - DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev.minor) + DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor) + + /* Set some basic constants */ + w9968cf_configure_camera(cam, udev, mod_id, dev_nr); /* Ok, add a new entry into the list of V4L registered devices */ down(&w9968cf_devlist_sem); list_add(&cam->v4llist, &w9968cf_dev_list); up(&w9968cf_devlist_sem); - dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0; w9968cf_turn_on_led(cam); w9968cf_i2c_init(cam); +#ifdef CONFIG_VIDEO_PROC_FS w9968cf_proc_create_dev(cam); +#endif up(&cam->dev_sem); + return (void*)cam; fail: /* Free unused memory */ @@ -3844,6 +3855,8 @@ kfree(cam->control_buffer); if (cam->data_buffer) kfree(cam->data_buffer); + if (cam->v4ldev) + video_device_release(cam->v4ldev); up(&cam->dev_sem); kfree(cam); } @@ -3851,7 +3864,8 @@ } -static void w9968cf_usb_disconnect(struct usb_device* udev, void* drv_context) +static void +w9968cf_usb_disconnect(struct usb_device* udev, void* drv_context) { struct w9968cf_device* cam = (struct w9968cf_device*)drv_context; @@ -3871,7 +3885,7 @@ DBG(2, "The device is open (/dev/video%d)! " "Process name: %s. Deregistration and memory " "deallocation are deferred on close.", - cam->v4ldev.minor, cam->command) + cam->v4ldev->minor, cam->command) cam->misconfigured = 1; @@ -3956,14 +3970,18 @@ init_MUTEX(&w9968cf_devlist_sem); +#ifdef CONFIG_VIDEO_PROC_FS w9968cf_proc_create(); +#endif w9968cf_vppmod_detect(); if ((err = usb_register(&w9968cf_usb_driver))) { if (w9968cf_vppmod_present) w9968cf_vppmod_release(); +#ifdef CONFIG_VIDEO_PROC_FS w9968cf_proc_destroy(); +#endif return err; } @@ -3976,7 +3994,9 @@ /* w9968cf_usb_disconnect() will be called */ usb_deregister(&w9968cf_usb_driver); +#ifdef CONFIG_VIDEO_PROC_FS w9968cf_proc_destroy(); +#endif if (w9968cf_vppmod_present) w9968cf_vppmod_release(); @@ -3987,3 +4007,5 @@ module_init(w9968cf_module_init); module_exit(w9968cf_module_exit); + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.24/drivers/usb/w9968cf.h linux-2.4.25/drivers/usb/w9968cf.h --- linux-2.4.24/drivers/usb/w9968cf.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/w9968cf.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /*************************************************************************** * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. * * * - * Copyright (C) 2002 2003 by Luca Risolia * + * Copyright (C) 2002 2003 by Luca Risolia * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -24,11 +24,14 @@ #include #include #include -#include +#ifdef CONFIG_VIDEO_PROC_FS +# include +#endif #include #include #include #include +#include #include #include @@ -106,7 +109,7 @@ #define W9968CF_LARGEVIEW 1 /* 0 disable, 1 enable */ #define W9968CF_UPSCALING 0 /* 0 disable, 1 enable */ -#define W9968CF_SENSOR_MONO 0 /* 0 not monochrome, 1 monochrome sensor */ +#define W9968CF_MONOCHROME 0 /* 0 not monochrome, 1 monochrome sensor */ #define W9968CF_BRIGHTNESS 31000 /* from 0 to 65535 */ #define W9968CF_HUE 32768 /* from 0 to 65535 */ #define W9968CF_COLOUR 32768 /* from 0 to 65535 */ @@ -130,9 +133,10 @@ #define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \ "Dual Mode Camera Chip" -#define W9968CF_MODULE_VERSION "v1.22" +#define W9968CF_MODULE_VERSION "v1.24-basic" #define W9968CF_MODULE_AUTHOR "(C) 2002 2003 Luca Risolia" -#define W9968CF_AUTHOR_EMAIL "" +#define W9968CF_AUTHOR_EMAIL "" +#define W9968CF_MODULE_LICENSE "GPL" static u8 w9968cf_vppmod_present; /* status flag: yes=1, no=0 */ @@ -172,6 +176,7 @@ }; struct w9968cf_frame_t { + #define W9968CF_HW_BUF_SIZE 640*480*2 /* buf.size of original frames */ void* buffer; u32 length; enum w9968cf_frame_status status; @@ -195,8 +200,8 @@ struct w9968cf_device { enum w9968cf_model_id id; /* private device identifier */ - struct video_device v4ldev; /* V4L structure */ - struct list_head v4llist; /* entry of the list of V4L cameras */ + struct video_device* v4ldev; /* -> V4L structure */ + struct list_head v4llist; /* entry of the list of V4L cameras */ struct usb_device* usbdev; /* -> main USB structure */ struct urb* urb[W9968CF_URBS]; /* -> USB request block structs */ @@ -208,9 +213,9 @@ struct w9968cf_frame_t frame_tmp; /* temporary frame */ struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */ struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS]; - void* vpp_buffer; /* -> helper buffer for post-processing routines */ + void* vpp_buffer; /*-> helper buf.for video post-processing routines */ - u8 max_buffers, /* number of requested buffers */ + u8 max_buffers, /* number of requested buffers */ force_palette, /* yes=1/no=0 */ force_rgb, /* read RGB instead of BGR, yes=1, no=0 */ double_buffer, /* hardware double buffering yes=1/no=0 */ @@ -221,15 +226,17 @@ decompression, /* 0=disabled, 1=forced, 2=allowed */ upscaling; /* software image scaling, 0=enabled, 1=disabled */ - struct video_picture picture; /* current window settings */ - struct video_window window; /* current picture settings */ + struct video_picture picture; /* current picture settings */ + struct video_window window; /* current window settings */ u16 hw_depth, /* depth (used by the chip) */ hw_palette, /* palette (used by the chip) */ hw_width, /* width (used by the chip) */ hw_height, /* height (used by the chip) */ hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */ - vs_polarity; /* 0=negative sync pulse, 1=positive sync pulse */ + vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */ + start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/ + start_cropy; /* pixels from VS incative edge to 1st cropped pixel*/ enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */ @@ -240,16 +247,15 @@ users, /* flag: number of users holding the device */ streaming; /* flag: yes=1, no=0 */ - int sensor; /* type of image CMOS sensor chip (CC_*) */ - - /* Determined by CMOS sensor type */ - u16 maxwidth, - maxheight, - minwidth, - minheight, - start_cropx, - start_cropy; + u8 sensor_initialized; /* flag: yes=1, no=0 */ + /* Determined by CMOS sensor type: */ + int sensor, /* type of image sensor chip (CC_*) */ + monochrome; /* CMOS sensor is (probably) monochrome */ + u16 maxwidth, /* maximum width supported by the CMOS sensor */ + maxheight, /* maximum height supported by the CMOS sensor */ + minwidth, /* minimum width supported by the CMOS sensor */ + minheight; /* minimum height supported by the CMOS sensor */ u8 auto_brt, /* auto brightness enabled flag */ auto_exp, /* auto exposure enabled flag */ backlight, /* backlight exposure algorithm flag */ @@ -257,21 +263,20 @@ lightfreq, /* power (lighting) frequency */ bandfilt; /* banding filter enabled flag */ s8 clockdiv; /* clock divisor */ - int sensor_mono; /* CMOS sensor is (probably) monochrome */ /* I2C interface to kernel */ struct i2c_adapter i2c_adapter; struct i2c_client* sensor_client; -#if defined(CONFIG_VIDEO_PROC_FS) +#ifdef CONFIG_VIDEO_PROC_FS /* /proc entries, relative to /proc/video/w9968cf/ */ - struct proc_dir_entry *proc_dev; /* readable per-device entry */ + struct proc_dir_entry *proc_dev; /* rw per-device entry */ #endif /* Locks */ struct semaphore dev_sem, /* for probe, disconnect,open and close */ fileop_sem; /* for read and ioctl */ -#if defined(CONFIG_VIDEO_PROC_FS) +#ifdef CONFIG_VIDEO_PROC_FS struct semaphore procfs_sem; /* for /proc read/write calls */ #endif spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */ @@ -280,14 +285,9 @@ wait_queue_head_t open, wait_queue; }; -#define W9968CF_HW_BUF_SIZE 640*480*2 /* buf. size for original video frames */ - -#define SENSOR_FORMAT VIDEO_PALETTE_UYVY -#define SENSOR_FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM) - /**************************************************************************** - * Macros and other constants * + * Macros for debugging * ****************************************************************************/ #undef DBG @@ -303,7 +303,7 @@ else if ((level) == 4) \ warn(fmt, ## args); \ else if ((level) >= 5) \ - info("[%s,%d] " fmt, \ + info("[%s:%d] " fmt, \ __PRETTY_FUNCTION__, __LINE__ , ## args); \ } \ } @@ -314,7 +314,7 @@ #undef PDBG #undef PDBGG -#define PDBG(fmt, args...) info("[%s, %d] "fmt, \ +#define PDBG(fmt, args...) info("[%s:%d] "fmt, \ __PRETTY_FUNCTION__, __LINE__ , ## args); #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */ diff -urN linux-2.4.24/drivers/usb/w9968cf_decoder.h linux-2.4.25/drivers/usb/w9968cf_decoder.h --- linux-2.4.24/drivers/usb/w9968cf_decoder.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/w9968cf_decoder.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,7 +1,7 @@ /*************************************************************************** * Video decoder for the W996[87]CF driver for Linux. * * * - * Copyright (C) 2003 by Luca Risolia * + * Copyright (C) 2003 by Luca Risolia * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * diff -urN linux-2.4.24/drivers/usb/w9968cf_externaldef.h linux-2.4.25/drivers/usb/w9968cf_externaldef.h --- linux-2.4.24/drivers/usb/w9968cf_externaldef.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/usb/w9968cf_externaldef.h 2004-02-18 05:36:31.000000000 -0800 @@ -1,8 +1,9 @@ /*************************************************************************** - * Various definitions for compatibility with external modules. * + * Various definitions for compatibility with OVCAMCHIP external module. * * This file is part of the W996[87]CF driver for Linux. * * * - * Copyright (C) 2002 2003 by Luca Risolia * + * The definitions have been taken from the OVCAMCHIP module written by * + * Mark McClelland. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -27,10 +28,8 @@ #include #include -/* The following values have been copied from the "ovcamchip" module. */ - #ifndef I2C_DRIVERID_OVCAMCHIP -# define I2C_DRIVERID_OVCAMCHIP 0xf00f +# define I2C_DRIVERID_OVCAMCHIP 0xf00f #endif /* Controls */ @@ -77,10 +76,10 @@ int width; int height; int format; - int quarter; /* Scale width and height down 2x */ + int quarter; /* Scale width and height down 2x */ /* This stuff will be removed eventually */ - int clockdiv; /* Clock divisor setting */ + int clockdiv; /* Clock divisor setting */ }; /* Commands. diff -urN linux-2.4.24/drivers/video/Config.in linux-2.4.25/drivers/video/Config.in --- linux-2.4.24/drivers/video/Config.in 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/video/Config.in 2004-02-18 05:36:31.000000000 -0800 @@ -224,6 +224,7 @@ tristate ' HD64461 Frame Buffer support' CONFIG_FB_HIT fi if [ "$CONFIG_DECSTATION" = "y" ]; then + dep_bool ' PMAG-AA TURBOchannel framebuffer support' CONFIG_FB_PMAG_AA $CONFIG_TC dep_bool ' PMAG-BA TURBOchannel framebuffer support' CONFIG_FB_PMAG_BA $CONFIG_TC dep_bool ' PMAGB-B TURBOchannel framebuffer support' CONFIG_FB_PMAGB_B $CONFIG_TC dep_bool ' Maxine (Personal DECstation) onboard framebuffer support' CONFIG_FB_MAXINE $CONFIG_TC @@ -231,6 +232,9 @@ if [ "$CONFIG_NINO" = "y" ]; then bool ' TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912 fi + if [ "$CONFIG_PCI" = "y" -o "$CONFIG_CPU_VR41XX" = "y" ]; then + tristate ' ITE IT8181E/F support' CONFIG_FB_IT8181 + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL fi @@ -303,8 +307,9 @@ "$CONFIG_FB_INTEL" = "y" -o \ "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ - "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \ - "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \ + "$CONFIG_FB_PMAG_AA" = "y" -o "$CONFIG_FB_PMAG_BA" = "y" -o \ + "$CONFIG_FB_PMAGB_B" = "y" -o "$CONFIG_FB_MAXINE" = "y" -o \ + "$CONFIG_FB_TX3912" = "y" -o \ "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \ "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \ "$CONFIG_FB_INTEL" = "y" ]; then @@ -325,9 +330,9 @@ "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \ "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \ - "$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \ - "$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ - "$CONFIG_FB_INTEL" = "m" -o \ + "$CONFIG_FB_PMAG_AA" = "m" -o "$CONFIG_FB_PMAG_BA" = "m" -o \ + "$CONFIG_FB_PMAGB_B" = "m" -o "$CONFIG_FB_MAXINE" = "m" -o \ + "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_INTEL" = "m" -o \ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \ "$CONFIG_FB_STI" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then diff -urN linux-2.4.24/drivers/video/Makefile linux-2.4.25/drivers/video/Makefile --- linux-2.4.24/drivers/video/Makefile 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/video/Makefile 2004-02-18 05:36:31.000000000 -0800 @@ -81,11 +81,13 @@ obj-$(CONFIG_FB_CGFOURTEEN) += cgfourteenfb.o sbusfb.o obj-$(CONFIG_FB_P9100) += p9100fb.o sbusfb.o obj-$(CONFIG_FB_LEO) += leofb.o sbusfb.o +obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o obj-$(CONFIG_FB_MAXINE) += maxinefb.o obj-$(CONFIG_FB_TX3912) += tx3912fb.o obj-$(CONFIG_FB_AU1100) += au1100fb.o fbgen.o +obj-$(CONFIG_FB_IT8181) += it8181fb.o fbgen.o subdir-$(CONFIG_STI_CONSOLE) += sti ifeq ($(CONFIG_STI_CONSOLE),y) diff -urN linux-2.4.24/drivers/video/aty/atyfb_base.c linux-2.4.25/drivers/video/aty/atyfb_base.c --- linux-2.4.24/drivers/video/aty/atyfb_base.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.25/drivers/video/aty/atyfb_base.c 2004-02-18 05:36:31.000000000 -0800 @@ -383,6 +383,7 @@ #if defined(CONFIG_FB_ATY_GX) || defined(CONFIG_FB_ATY_CT) static char ram_dram[] __initdata = "DRAM"; +static char ram_resv[] __initdata = "RESV"; #endif /* CONFIG_FB_ATY_GX || CONFIG_FB_ATY_CT */ #ifdef CONFIG_FB_ATY_GX @@ -395,7 +396,6 @@ static char ram_sgram[] __initdata = "SGRAM"; static char ram_wram[] __initdata = "WRAM"; static char ram_off[] __initdata = "OFF"; -static char ram_resv[] __initdata = "RESV"; #endif /* CONFIG_FB_ATY_CT */ #ifdef CONFIG_FB_ATY_GX @@ -488,8 +488,6 @@ static void aty_set_crtc(const struct fb_info_aty *info, const struct crtc *crtc) { - u32 v; - aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info); aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info); #ifdef CONFIG_FB_ATY_GENERIC_LCD @@ -523,6 +521,7 @@ registers. */ if (info->lcd_table != 0) { + u32 v; /* Enable/disable horizontal stretching */ v = aty_ld_lcd(HORZ_STRETCHING, info); v = v & ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_EN | AUTO_HORZ_RATIO | @@ -1985,7 +1984,6 @@ #if defined(CONFIG_PPC) int sense; #endif - u8 pll_ref_div; u32 monitors_enabled; info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0); @@ -2103,19 +2101,24 @@ info->ref_clk_per = 1000000000000ULL/14318180; xtal = "14.31818"; - if (M64_HAS(GTB_DSP) && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) { - int diff1, diff2; - diff1 = 510*14/pll_ref_div-pll; - diff2 = 510*29/pll_ref_div-pll; - if (diff1 < 0) - diff1 = -diff1; - if (diff2 < 0) - diff2 = -diff2; - if (diff2 < diff1) { - info->ref_clk_per = 1000000000000ULL/29498928; - xtal = "29.498928"; - } +#ifdef CONFIG_FB_ATY_CT + if (M64_HAS(INTEGRATED)) { + u8 pll_ref_div = aty_ld_pll(PLL_REF_DIV, info); + if (pll_ref_div) { + int diff1, diff2; + diff1 = 510*14/pll_ref_div-pll; + diff2 = 510*29/pll_ref_div-pll; + if (diff1 < 0) + diff1 = -diff1; + if (diff2 < 0) + diff2 = -diff2; + if (diff2 < diff1) { + info->ref_clk_per = 1000000000000ULL/29498928; + xtal = "29.498928"; + } + } } +#endif /* CONFIG_FB_ATY_CT */ i = aty_ld_le32(MEM_CNTL, info); gtb_memsize = M64_HAS(GTB_DSP); @@ -3001,9 +3004,11 @@ * Map the video memory (physical address given) to somewhere in the * kernel address space. */ - info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); + info->frame_buffer = (unsigned long)ioremap(phys_vmembase[m64_num], + phys_size[m64_num]); info->frame_buffer_phys = info->frame_buffer; /* Fake! */ - info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul; + info->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num], + 0x10000)+0xFC00ul; info->ati_regbase_phys = info->ati_regbase; /* Fake! */ aty_st_le32(CLOCK_CNTL, 0x12345678, info); diff -urN linux-2.4.24/drivers/video/aty/mach64_gx.c linux-2.4.25/drivers/video/aty/mach64_gx.c --- linux-2.4.24/drivers/video/aty/mach64_gx.c 2003-11-28 10:26:21.000000000 -0800 +++ linux-2.4.25/drivers/video/aty/mach64_gx.c 2004-02-18 05:36:31.000000000 -0800 @@ -124,7 +124,7 @@ } static int aty_var_to_pll_514(const struct fb_info_aty *info, u32 vclk_per, - u8 bpp, union aty_pll *pll) + u8 bpp, u32 xres, union aty_pll *pll) { /* * FIXME: use real calculations instead of using fixed values from the old @@ -325,7 +325,7 @@ */ static int aty_var_to_pll_18818(const struct fb_info_aty *info, u32 vclk_per, - u8 bpp, union aty_pll *pll) + u8 bpp, u32 xres, union aty_pll *pll) { u32 MHz100; /* in 0.01 MHz */ u32 program_bits; @@ -481,7 +481,7 @@ */ static int aty_var_to_pll_1703(const struct fb_info_aty *info, u32 vclk_per, - u8 bpp, union aty_pll *pll) + u8 bpp, u32 xres, union aty_pll *pll) { u32 mhz100; /* in 0.01 MHz */ u32 program_bits; @@ -595,7 +595,7 @@ */ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per, - u8 bpp, union aty_pll *pll) + u8 bpp, u32 xres, union aty_pll *pll) { u32 tempA, tempB, fOut, longMHz100, diff, preDiff; @@ -723,7 +723,7 @@ */ static int aty_var_to_pll_408(const struct fb_info_aty *info, u32 vclk_per, - u8 bpp, union aty_pll *pll) + u8 bpp, u32 xres, union aty_pll *pll) { u32 mhz100; /* in 0.01 MHz */ u32 program_bits; diff -urN linux-2.4.24/drivers/video/au1100fb.c linux-2.4.25/drivers/video/au1100fb.c --- linux-2.4.24/drivers/video/au1100fb.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/video/au1100fb.c 2004-02-18 05:36:31.000000000 -0800 @@ -61,7 +61,7 @@ * Sanity check. If this is a new Au1100 based board, search for * the PB1100 ifdefs to make sure you modify the code accordingly. */ -#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) +#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3) #else error Unknown Au1100 board #endif @@ -320,6 +320,12 @@ au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, PB1100_G_CONTROL); #endif +#ifdef CONFIG_MIPS_HYDROGEN3 + /* Turn controller & power supply on, GPIO213 */ + au_writel(0x20002000, 0xB1700008); + au_writel(0x00040000, 0xB1900108); + au_writel(0x01000100, 0xB1700008); +#endif au_sync(); break; @@ -479,6 +485,13 @@ au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, PB1100_G_CONTROL); #endif +#ifdef CONFIG_MIPS_HYDROGEN3 + /* Turn controller & power supply on, GPIO213 */ + au_writel(0x20002000, 0xB1700008); + au_writel(0x00040000, 0xB1900108); + au_writel(0x01000100, 0xB1700008); +#endif + p_lcd_reg->lcd_control |= LCD_CONTROL_GO; return 0; diff -urN linux-2.4.24/drivers/video/au1100fb.h linux-2.4.25/drivers/video/au1100fb.h --- linux-2.4.24/drivers/video/au1100fb.h 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/video/au1100fb.h 2004-02-18 05:36:31.000000000 -0800 @@ -532,6 +532,29 @@ /* mode_backlight */ 7 }, + { /* 8 */ + 320, /* xres */ + 240, /* yres */ + 16, /* bpp */ + + "Hydrogen_3_NEC_panel_320x240", + /* mode_control */ + LCD_CONTROL_BPP_16 | LCD_CONTROL_PC | LCD_CONTROL_PT | LCD_CONTROL_PO_00 | LCD_CONTROL_SBPPF_565, + /* mode_horztiming */ + LCD_HORZTIMING_HN2_N(8) | LCD_HORZTIMING_HN1_N(16) | LCD_HORZTIMING_HPW_N(24) | LCD_HORZTIMING_PPL_N(240), + /* mode_verttiming */ + LCD_VERTTIMING_VN2_N(5) | LCD_VERTTIMING_VN1_N(5) | LCD_VERTTIMING_VPW_N(2) | LCD_VERTTIMING_LPP_N(320), + /* mode_clkcontrol */ + LCD_CLKCONTROL_PCD_N(1), + /* mode_pwmdiv */ + 0, + /* mode_pwmhi */ + 0, + /* mode_toyclksrc */ + ((1<<7) | (0<<6) | (1<<5)), + /* mode_backlight */ + 0, + }, }; diff -urN linux-2.4.24/drivers/video/bt431.h linux-2.4.25/drivers/video/bt431.h --- linux-2.4.24/drivers/video/bt431.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/video/bt431.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,236 @@ +/* + * linux/drivers/video/bt431.h + * + * Copyright 2003 Thiemo Seufer + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ +#include +#include + +/* + * Bt431 cursor generator registers, 32-bit aligned. + * Two twin Bt431 are used on the DECstation's PMAG-AA. + */ +struct bt431_regs { + volatile u16 addr_lo; + u16 pad0; + volatile u16 addr_hi; + u16 pad1; + volatile u16 addr_cmap; + u16 pad2; + volatile u16 addr_reg; + u16 pad3; +}; + +static inline u16 bt431_set_value(u8 val) +{ + return ((val << 8) | (val & 0xff)) & 0xffff; +} + +static inline u8 bt431_get_value(u16 val) +{ + return val & 0xff; +} + +/* + * Additional registers addressed indirectly. + */ +#define BT431_REG_CMD 0x0000 +#define BT431_REG_CXLO 0x0001 +#define BT431_REG_CXHI 0x0002 +#define BT431_REG_CYLO 0x0003 +#define BT431_REG_CYHI 0x0004 +#define BT431_REG_WXLO 0x0005 +#define BT431_REG_WXHI 0x0006 +#define BT431_REG_WYLO 0x0007 +#define BT431_REG_WYHI 0x0008 +#define BT431_REG_WWLO 0x0009 +#define BT431_REG_WWHI 0x000a +#define BT431_REG_WHLO 0x000b +#define BT431_REG_WHHI 0x000c + +#define BT431_REG_CRAM_BASE 0x0000 +#define BT431_REG_CRAM_END 0x01ff + +/* + * Command register. + */ +#define BT431_CMD_CURS_ENABLE 0x40 +#define BT431_CMD_XHAIR_ENABLE 0x20 +#define BT431_CMD_OR_CURSORS 0x10 +#define BT431_CMD_AND_CURSORS 0x00 +#define BT431_CMD_1_1_MUX 0x00 +#define BT431_CMD_4_1_MUX 0x04 +#define BT431_CMD_5_1_MUX 0x08 +#define BT431_CMD_xxx_MUX 0x0c +#define BT431_CMD_THICK_1 0x00 +#define BT431_CMD_THICK_3 0x01 +#define BT431_CMD_THICK_5 0x02 +#define BT431_CMD_THICK_7 0x03 + +static inline void bt431_select_reg(struct bt431_regs *regs, int ir) +{ + /* + * The compiler splits the write in two bytes without these + * helper variables. + */ + volatile u16 *lo = &(regs->addr_lo); + volatile u16 *hi = &(regs->addr_hi); + + mb(); + *lo = bt431_set_value(ir & 0xff); + wmb(); + *hi = bt431_set_value((ir >> 8) & 0xff); +} + +/* Autoincrement read/write. */ +static inline u8 bt431_read_reg_inc(struct bt431_regs *regs) +{ + /* + * The compiler splits the write in two bytes without the + * helper variable. + */ + volatile u16 *r = &(regs->addr_reg); + + mb(); + return bt431_get_value(*r); +} + +static inline void bt431_write_reg_inc(struct bt431_regs *regs, u8 value) +{ + /* + * The compiler splits the write in two bytes without the + * helper variable. + */ + volatile u16 *r = &(regs->addr_reg); + + mb(); + *r = bt431_set_value(value); +} + +static inline u8 bt431_read_reg(struct bt431_regs *regs, int ir) +{ + bt431_select_reg(regs, ir); + return bt431_read_reg_inc(regs); +} + +static inline void bt431_write_reg(struct bt431_regs *regs, int ir, u8 value) +{ + bt431_select_reg(regs, ir); + bt431_write_reg_inc(regs, value); +} + +/* Autoincremented read/write for the cursor map. */ +static inline u16 bt431_read_cmap_inc(struct bt431_regs *regs) +{ + /* + * The compiler splits the write in two bytes without the + * helper variable. + */ + volatile u16 *r = &(regs->addr_cmap); + + mb(); + return *r; +} + +static inline void bt431_write_cmap_inc(struct bt431_regs *regs, u16 value) +{ + /* + * The compiler splits the write in two bytes without the + * helper variable. + */ + volatile u16 *r = &(regs->addr_cmap); + + mb(); + *r = value; +} + +static inline u16 bt431_read_cmap(struct bt431_regs *regs, int cr) +{ + bt431_select_reg(regs, cr); + return bt431_read_cmap_inc(regs); +} + +static inline void bt431_write_cmap(struct bt431_regs *regs, int cr, u16 value) +{ + bt431_select_reg(regs, cr); + bt431_write_cmap_inc(regs, value); +} + +static inline void bt431_enable_cursor(struct bt431_regs *regs) +{ + bt431_write_reg(regs, BT431_REG_CMD, + BT431_CMD_CURS_ENABLE | BT431_CMD_OR_CURSORS + | BT431_CMD_4_1_MUX | BT431_CMD_THICK_1); +} + +static inline void bt431_erase_cursor(struct bt431_regs *regs) +{ + bt431_write_reg(regs, BT431_REG_CMD, BT431_CMD_4_1_MUX); +} + +static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y) +{ + /* + * Magic from the MACH sources. + * + * Cx = x + D + H - P + * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 + * D = pixel skew between outdata and external data + * H = pixels between HSYNCH falling and active video + * + * Cy = y + V - 32 + * V = scanlines between HSYNCH falling, two or more + * clocks after VSYNCH falling, and active video + */ + x += 412 - 52; + y += 68 - 32; + + /* Use autoincrement. */ + bt431_select_reg(regs, BT431_REG_CXLO); + bt431_write_reg_inc(regs, x & 0xff); /* BT431_REG_CXLO */ + bt431_write_reg_inc(regs, (x >> 8) & 0x0f); /* BT431_REG_CXHI */ + bt431_write_reg_inc(regs, y & 0xff); /* BT431_REG_CYLO */ + bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */ +} + +static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc, + u16 width, u16 height) +{ + int i; + u16 fgp = fgc ? 0xffff : 0x0000; + u16 bgp = fgc ? 0x0000 : 0xffff; + + bt431_select_reg(regs, BT431_REG_CRAM_BASE); + for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) { + u16 value; + + if (height << 6 <= i << 3) + value = bgp; + else if (width <= i % 8 << 3) + value = bgp; + else if (((width >> 3) & 0xffff) > i % 8) + value = fgp; + else + value = fgp & ~(bgp << (width % 8 << 1)); + + bt431_write_cmap_inc(regs, value); + } +} + +static inline void bt431_init_cursor(struct bt431_regs *regs) +{ + /* no crosshair window */ + bt431_select_reg(regs, BT431_REG_WXLO); + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXLO */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXHI */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYLO */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYHI */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWLO */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWHI */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHLO */ + bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHHI */ +} diff -urN linux-2.4.24/drivers/video/bt455.h linux-2.4.25/drivers/video/bt455.h --- linux-2.4.24/drivers/video/bt455.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/video/bt455.h 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,95 @@ +/* + * linux/drivers/video/bt455.h + * + * Copyright 2003 Thiemo Seufer + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ +#include +#include + +/* + * Bt455 byte-wide registers, 32-bit aligned. + */ +struct bt455_regs { + volatile u8 addr_cmap; + u8 pad0[3]; + volatile u8 addr_cmap_data; + u8 pad1[3]; + volatile u8 addr_clr; + u8 pad2[3]; + volatile u8 addr_ovly; + u8 pad3[3]; +}; + +static inline void bt455_select_reg(struct bt455_regs *regs, int ir) +{ + mb(); + regs->addr_cmap = ir & 0x0f; +} + +/* + * Read/write to a Bt455 color map register. + */ +static inline void bt455_read_cmap_entry(struct bt455_regs *regs, int cr, + u8* red, u8* green, u8* blue) +{ + bt455_select_reg(regs, cr); + mb(); + *red = regs->addr_cmap_data & 0x0f; + rmb(); + *green = regs->addr_cmap_data & 0x0f; + rmb(); + *blue = regs->addr_cmap_data & 0x0f; +} + +static inline void bt455_write_cmap_entry(struct bt455_regs *regs, int cr, + u8 red, u8 green, u8 blue) +{ + bt455_select_reg(regs, cr); + wmb(); + regs->addr_cmap_data = red & 0x0f; + wmb(); + regs->addr_cmap_data = green & 0x0f; + wmb(); + regs->addr_cmap_data = blue & 0x0f; +} + +static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr, + u8 red, u8 green, u8 blue) +{ + bt455_select_reg(regs, cr); + wmb(); + regs->addr_ovly = red & 0x0f; + wmb(); + regs->addr_ovly = green & 0x0f; + wmb(); + regs->addr_ovly = blue & 0x0f; +} + +static inline void bt455_set_cursor(struct bt455_regs *regs) +{ + mb(); + regs->addr_ovly = 0x0f; + wmb(); + regs->addr_ovly = 0x0f; + wmb(); + regs->addr_ovly = 0x0f; +} + +static inline void bt455_erase_cursor(struct bt455_regs *regs) +{ + /* bt455_write_cmap_entry(regs, 8, 0x00, 0x00, 0x00); */ + /* bt455_write_cmap_entry(regs, 9, 0x00, 0x00, 0x00); */ + bt455_write_ovly_entry(regs, 8, 0x03, 0x03, 0x03); + bt455_write_ovly_entry(regs, 9, 0x07, 0x07, 0x07); + + wmb(); + regs->addr_ovly = 0x09; + wmb(); + regs->addr_ovly = 0x09; + wmb(); + regs->addr_ovly = 0x09; +} diff -urN linux-2.4.24/drivers/video/clgenfb.c linux-2.4.25/drivers/video/clgenfb.c --- linux-2.4.24/drivers/video/clgenfb.c 2003-06-13 07:51:37.000000000 -0700 +++ linux-2.4.25/drivers/video/clgenfb.c 2004-02-18 05:36:31.000000000 -0800 @@ -2547,7 +2547,7 @@ pdev = clgen_pci_dev_get (btype); if (!pdev) { - printk (KERN_ERR " Couldn't find PCI device\n"); + printk (KERN_INFO "clgenfb: couldn't find Cirrus Logic PCI device\n"); DPRINTK ("EXIT, returning 1\n"); return 1; } diff -urN linux-2.4.24/drivers/video/fbmem.c linux-2.4.25/drivers/video/fbmem.c --- linux-2.4.24/drivers/video/fbmem.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.25/drivers/video/fbmem.c 2004-02-18 05:36:31.000000000 -0800 @@ -124,9 +124,10 @@ extern int sisfb_setup(char*); extern int stifb_init(void); extern int stifb_setup(char*); +extern int pmagaafb_init(void); extern int pmagbafb_init(void); extern int pmagbbfb_init(void); -extern void maxinefb_init(void); +extern int maxinefb_init(void); extern int tx3912fb_init(void); extern int radeonfb_init(void); extern int radeonfb_setup(char*); @@ -142,6 +143,8 @@ extern int pvr2fb_setup(char*); extern int sstfb_init(void); extern int sstfb_setup(char*); +extern int it8181fb_init(void); +extern int it8181fb_setup(char*); static struct { const char *name; @@ -313,6 +316,9 @@ #ifdef CONFIG_FB_PVR2 { "pvr2", pvr2fb_init, pvr2fb_setup }, #endif +#ifdef CONFIG_FB_PMAG_AA + { "pmagaafb", pmagaafb_init, NULL }, +#endif #ifdef CONFIG_FB_PMAG_BA { "pmagbafb", pmagbafb_init, NULL }, #endif @@ -325,6 +331,9 @@ #ifdef CONFIG_FB_AU1100 { "au1100fb", au1100fb_init, au1100fb_setup }, #endif +#ifdef CONFIG_FB_IT8181 + { "it8181fb", it8181fb_init, it8181fb_setup }, +#endif /* diff -urN linux-2.4.24/drivers/video/hgafb.c linux-2.4.25/drivers/video/hgafb.c --- linux-2.4.24/drivers/video/hgafb.c 2001-11-12 09:46:25.000000000 -0800 +++ linux-2.4.25/drivers/video/hgafb.c 2004-02-18 05:36:31.000000000 -0800 @@ -704,7 +704,7 @@ int __init hgafb_init(void) { if (! hga_card_detect()) { - printk(KERN_ERR "hgafb: HGA card not detected.\n"); + printk(KERN_INFO "hgafb: HGA card not detected.\n"); return -EINVAL; } diff -urN linux-2.4.24/drivers/video/it8181fb.c linux-2.4.25/drivers/video/it8181fb.c --- linux-2.4.24/drivers/video/it8181fb.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.25/drivers/video/it8181fb.c 2004-02-18 05:36:31.000000000 -0800 @@ -0,0 +1,1350 @@ +/* IT8181 console frame buffer driver---it8181fb.c + * + * Copyright (C) 2001 Integrated Technology Express, Inc. + * Copyright (C) 2001 MontaVista Software Inc. + * Copyright (C) 2002,2003 Yoichi Yuasa + * + * Initial work by rich.liu@ite.com.tw + * + * Rewritten by MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Changes: + * Yoichi Yuasa + * - Added support of NEC VR4111 and VR4121. + * - rewrote it8181fb_set_par() + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include