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_PREFET