diff --git a/[refs] b/[refs] index 039759922e55..e344949224b6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cc14cf46da215a9df1c0a4388763a68769ef9e53 +refs/heads/master: 0c7b525c344bc29a760c37053f8d5c80292ee1be diff --git a/trunk/Documentation/dvb/README.dvb-usb b/trunk/Documentation/dvb/README.dvb-usb index ac0797ea646c..c7ed01b9f8f4 100644 --- a/trunk/Documentation/dvb/README.dvb-usb +++ b/trunk/Documentation/dvb/README.dvb-usb @@ -13,17 +13,14 @@ different way: With the help of a dvb-usb-framework. The framework provides generic functions (mostly kernel API calls), such as: - Transport Stream URB handling in conjunction with dvb-demux-feed-control - (bulk and isoc are supported) + (bulk and isoc (TODO) are supported) - registering the device for the DVB-API - registering an I2C-adapter if applicable - remote-control/input-device handling - firmware requesting and loading (currently just for the Cypress USB - controllers) + controller) - other functions/methods which can be shared by several drivers (such as functions for bulk-control-commands) -- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses - depending on length of a register and the number of values that can be - multi-written and multi-read. The source code of the particular DVB USB devices does just the communication with the device via the bus. The connection between the DVB-API-functionality @@ -39,18 +36,93 @@ the dvb-usb-lib. TODO: dynamic enabling and disabling of the pid-filter in regard to number of feeds requested. -Supported devices +Supported devices USB1.1 ======================== -See the LinuxTV DVB Wiki at www.linuxtv.org for a complete list of -cards/drivers/firmwares: +Produced and reselled by Twinhan: +--------------------------------- +- TwinhanDTV USB-Ter DVB-T Device (VP7041) + http://www.twinhan.com/product_terrestrial_3.asp -http://www.linuxtv.org/wiki/index.php/DVB_USB +- TwinhanDTV Magic Box (VP7041e) + http://www.twinhan.com/product_terrestrial_4.asp + +- HAMA DVB-T USB device + http://www.hama.de/portal/articleId*110620/action*2598 + +- CTS Portable (Chinese Television System) (2) + http://www.2cts.tv/ctsportable/ + +- Unknown USB DVB-T device with vendor ID Hyper-Paltek + + +Produced and reselled by KWorld: +-------------------------------- +- KWorld V-Stream XPERT DTV DVB-T USB + http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html + +- JetWay DTV DVB-T USB + http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm + +- ADSTech Instant TV DVB-T USB + http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333 + + +Others: +------- +- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) + http://82.161.246.249/products-tvbox.html + +- Compro Videomate DVB-U2000 - DVB-T USB (2) + http://www.comprousa.com/products/vmu2000.htm + +- Grandtec USB DVB-T + http://www.grand.com.tw/ + +- AVerMedia AverTV DVBT USB + http://www.avermedia.com/ + +- DiBcom USB DVB-T reference device (non-public) + + +Supported devices USB2.0-only +============================= +- Twinhan MagicBox II + http://www.twinhan.com/product_terrestrial_7.asp + +- TwinhanDTV Alpha + http://www.twinhan.com/product_terrestrial_8.asp + +- DigitalNow TinyUSB 2 DVB-t Receiver + http://www.digitalnow.com.au/DigitalNow%20tinyUSB2%20Specifications.html + +- Hanftek UMT-010 + http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529 + + +Supported devices USB2.0 and USB1.1 +============================= +- Typhoon/Yakumo/HAMA/Yuan DVB-T mobile USB2.0 + http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T + http://www.yuan.com.tw/en/products/vdo_ub300.html + http://www.hama.de/portal/articleId*114663/action*2563 + http://www.anubisline.com/english/articlec.asp?id=50502&catid=002 + +- Artec T1 USB TVBOX (FX2) (2) + +- Hauppauge WinTV NOVA-T USB2 + http://www.hauppauge.com/ + +- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B) + +- DiBcom USB2.0 DVB-T reference device (non-public) + +- AVerMedia AverTV A800 DVB-T USB2.0 + +1) It is working almost - work-in-progress. +2) No test reports received yet. 0. History & News: - 2005-06-30 - added support for WideView WT-220U (Thanks to Steve Chang) - 2005-05-30 - added basic isochronous support to the dvb-usb-framework - added support for Conexant Hybrid reference design and Nebula DigiTV USB 2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework 2005-04-02 - re-enabled and improved remote control code. 2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb. @@ -65,7 +137,7 @@ http://www.linuxtv.org/wiki/index.php/DVB_USB 2005-01-31 - distorted streaming is gone for USB1.1 devices 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb - first almost working version for HanfTek UMT-010 - - found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010 + - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 2005-01-10 - refactoring completed, now everything is very delightful - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. @@ -115,13 +187,25 @@ http://www.linuxtv.org/wiki/index.php/DVB_USB 1. How to use? 1.1. Firmware -Most of the USB drivers need to download a firmware to the device before start -working. +Most of the USB drivers need to download a firmware to start working. + +for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw +for USB2.0 HanfTek: dvb-usb-umt-010-02.fw +for USB2.0 DiBcom: dvb-usb-dibusb-6.0.0.8.fw +for USB2.0 AVerMedia AverTV DVB-T USB2: dvb-usb-avertv-a800-01.fw +for USB2.0 TwinhanDTV Alpha/MagicBox II: dvb-usb-vp7045-01.fw + +The files can be found on http://www.linuxtv.org/download/firmware/ . -Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware -you need for your device: +We do not have the permission (yet) to publish the following firmware-files. +You'll need to extract them from the windows drivers. -http://www.linuxtv.org/wiki/index.php/DVB_USB +You should be able to use "get_dvb_firmware dvb-usb" to get the firmware: + +for USB1.1 (AN2235) (a few Artec T1 devices): dvb-usb-dibusb-an2235-01.fw +for USB2.0 Hauppauge: dvb-usb-nova-t-usb2-01.fw +for USB2.0 ADSTech/Kworld USB2.0: dvb-usb-adstech-usb2-01.fw +for USB2.0 Yakumo/Typhoon/Hama: dvb-usb-dtt200u-01.fw 1.2. Compiling @@ -205,9 +289,6 @@ Patches, comments and suggestions are very very welcome. Gunnar Wittich and Joachim von Caron for their trust for providing root-shells on their machines to implement support for new devices. - Allan Third and Michael Hutchinson for their help to write the Nebula - digitv-driver. - Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei Jung from AVerMedia who kindly provided a special firmware to get the device up and running in Linux. @@ -215,12 +296,7 @@ Patches, comments and suggestions are very very welcome. Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by writing the vp7045-driver. - Steve Chang from WideView for providing information for new devices and - firmware files. - - Michael Paxton for submitting remote control keymaps. - - Some guys on the linux-dvb mailing list for encouraging me. + Some guys on the linux-dvb mailing list for encouraging me Peter Schildmann >peter.schildmann-nospam-at-web.de< for his user-level firmware loader, which saves a lot of time @@ -229,4 +305,4 @@ Patches, comments and suggestions are very very welcome. Ulf Hermenau for helping me out with traditional chinese. André Smoktun and Christian Frömmel for supporting me with - hardware and listening to my problems very patiently. + hardware and listening to my problems very patient. diff --git a/trunk/Documentation/dvb/bt8xx.txt b/trunk/Documentation/dvb/bt8xx.txt index e6b8d05bc08d..3a3260794758 100644 --- a/trunk/Documentation/dvb/bt8xx.txt +++ b/trunk/Documentation/dvb/bt8xx.txt @@ -1,55 +1,66 @@ -How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working -========================================================================================= +How to get the Nebula, PCTV and Twinhan DST cards working +========================================================= -1) General information -====================== +This class of cards has a bt878a as the PCI interface, and +require the bttv driver. -This class of cards has a bt878a chip as the PCI interface. -The different card drivers require the bttv driver to provide the means -to access the i2c bus and the gpio pins of the bt8xx chipset. +Please pay close attention to the warning about the bttv module +options below for the DST card. -2) Compilation rules for Kernel >= 2.6.12 -========================================= +1) General informations +======================= -Enable the following options: +These drivers require the bttv driver to provide the means to access +the i2c bus and the gpio pins of the bt8xx chipset. +Because of this, you need to enable "Device drivers" => "Multimedia devices" - => "Video For Linux" => "BT848 Video For Linux" + => "Video For Linux" => "BT848 Video For Linux" + +Furthermore you need to enable "Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" - => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards" + => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards" -3) Loading Modules, described by two approaches -=============================================== +2) Loading Modules +================== In general you need to load the bttv driver, which will handle the gpio and -i2c communication for us, plus the common dvb-bt8xx device driver, -which is called the backend. -The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110), -TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend. -For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt. +i2c communication for us, plus the common dvb-bt8xx device driver. +The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and +TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. -3a) The manual approach ------------------------ +3a) Nebula / Pinnacle PCTV +-------------------------- -Loading modules: -modprobe bttv -modprobe dvb-bt8xx + $ modprobe bttv (normally bttv is being loaded automatically by kmod) + $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading) -Unloading modules: -modprobe -r dvb-bt8xx -modprobe -r bttv -3b) The automatic approach +3b) TwinHan and Clones -------------------------- -If not already done by installation, place a line either in -/etc/modules.conf or in /etc/modprobe.conf containing this text: -alias char-major-81 bttv + $ modprobe bttv i2c_hw=1 card=0x71 + $ modprobe dvb-bt8xx + $ modprobe dst + +The value 0x71 will override the PCI type detection for dvb-bt8xx, +which is necessary for TwinHan cards. + +If you're having an older card (blue color circuit) and card=0x71 locks +your machine, try using 0x68, too. If that does not work, ask on the +mailing list. + +The DST module takes a couple of useful parameters: -Then place a line in /etc/modules containing this text: -dvb-bt8xx +a. verbose takes values 0 to 5. These values control the verbosity level. +b. debug takes values 0 and 1. You can either disable or enable debugging. +c. dst_addons takes values 0 and 0x20: +- A value of 0 means it is a FTA card. +- A value of 0x20 means it has a Conditional Access slot. -Reboot your system and have fun! +The autodetected values are determined by the "response string" +of the card, which you can see in your logs: +e.g.: dst_get_device_id: Recognize [DSTMCI] -- Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 12dde43fe657..1d227ee3792a 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -119,19 +119,3 @@ Why: Match the other drivers' name for the same function, duplicate names will be available until removal of old names. Who: Grant Coady ---------------------------- - -What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) -When: November 2005 -Files: drivers/pcmcia/: pcmcia_ioctl.c -Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a - normal hotpluggable bus, and with it using the default kernel - infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA - control ioctl needed by cardmgr and cardctl from pcmcia-cs is - unnecessary, and makes further cleanups and integration of the - PCMCIA subsystem into the Linux kernel device driver model more - difficult. The features provided by cardmgr and cardctl are either - handled by the kernel itself now or are available in the new - pcmciautils package available at - http://kernel.org/pub/linux/utils/kernel/pcmcia/ -Who: Dominik Brodowski diff --git a/trunk/Documentation/infiniband/user_verbs.txt b/trunk/Documentation/infiniband/user_verbs.txt deleted file mode 100644 index f847501e50b5..000000000000 --- a/trunk/Documentation/infiniband/user_verbs.txt +++ /dev/null @@ -1,69 +0,0 @@ -USERSPACE VERBS ACCESS - - The ib_uverbs module, built by enabling CONFIG_INFINIBAND_USER_VERBS, - enables direct userspace access to IB hardware via "verbs," as - described in chapter 11 of the InfiniBand Architecture Specification. - - To use the verbs, the libibverbs library, available from - , is required. libibverbs contains a - device-independent API for using the ib_uverbs interface. - libibverbs also requires appropriate device-dependent kernel and - userspace driver for your InfiniBand hardware. For example, to use - a Mellanox HCA, you will need the ib_mthca kernel module and the - libmthca userspace driver be installed. - -User-kernel communication - - Userspace communicates with the kernel for slow path, resource - management operations via the /dev/infiniband/uverbsN character - devices. Fast path operations are typically performed by writing - directly to hardware registers mmap()ed into userspace, with no - system call or context switch into the kernel. - - Commands are sent to the kernel via write()s on these device files. - The ABI is defined in drivers/infiniband/include/ib_user_verbs.h. - The structs for commands that require a response from the kernel - contain a 64-bit field used to pass a pointer to an output buffer. - Status is returned to userspace as the return value of the write() - system call. - -Resource management - - Since creation and destruction of all IB resources is done by - commands passed through a file descriptor, the kernel can keep track - of which resources are attached to a given userspace context. The - ib_uverbs module maintains idr tables that are used to translate - between kernel pointers and opaque userspace handles, so that kernel - pointers are never exposed to userspace and userspace cannot trick - the kernel into following a bogus pointer. - - This also allows the kernel to clean up when a process exits and - prevent one process from touching another process's resources. - -Memory pinning - - Direct userspace I/O requires that memory regions that are potential - I/O targets be kept resident at the same physical address. The - ib_uverbs module manages pinning and unpinning memory regions via - get_user_pages() and put_page() calls. It also accounts for the - amount of memory pinned in the process's locked_vm, and checks that - unprivileged processes do not exceed their RLIMIT_MEMLOCK limit. - - Pages that are pinned multiple times are counted each time they are - pinned, so the value of locked_vm may be an overestimate of the - number of pages pinned by a process. - -/dev files - - To create the appropriate character device files automatically with - udev, a rule like - - KERNEL="uverbs*", NAME="infiniband/%k" - - can be used. This will create device nodes named - - /dev/infiniband/uverbs0 - - and so on. Since the InfiniBand userspace verbs should be safe for - use by non-privileged processes, it may be useful to add an - appropriate MODE or GROUP to the udev rule. diff --git a/trunk/Documentation/power/video.txt b/trunk/Documentation/power/video.txt index 7a4a5036d123..881a37e3eeb0 100644 --- a/trunk/Documentation/power/video.txt +++ b/trunk/Documentation/power/video.txt @@ -117,7 +117,6 @@ IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4) Medion MD4220 ??? (*) Samsung P35 vbetool needed (6) Sharp PC-AR10 (ATI rage) none (1) -Sony Vaio PCG-C1VRX/K s3_bios (2) Sony Vaio PCG-F403 ??? (*) Sony Vaio PCG-N505SN ??? (*) Sony Vaio vgn-s260 X or boot-radeon can init it (5) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 37fb1e2ec687..302b31960008 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -370,10 +370,6 @@ W: http://www.thekelleys.org.uk/atmel W: http://atmelwlandriver.sourceforge.net/ S: Maintained -AUDIT SUBSYSTEM -L: linux-audit@redhat.com (subscribers-only) -S: Maintained - AX.25 NETWORK LAYER P: Ralf Baechle M: ralf@linux-mips.org @@ -1807,9 +1803,8 @@ M: greg@kroah.com S: Maintained PCMCIA SUBSYSTEM -P: Linux PCMCIA Team L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia -S: Maintained +S: Unmaintained PCNET32 NETWORK DRIVER P: Thomas Bogendörfer diff --git a/trunk/Makefile b/trunk/Makefile index 9cf07e7b9f88..278d50992c71 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -792,9 +792,6 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) $(Q)$(MAKE) $(build)=$(@D) $@ %.o: %.c scripts FORCE $(Q)$(MAKE) $(build)=$(@D) $@ -%.ko: scripts FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o) - $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost %/: scripts prepare FORCE $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) %.lst: %.c scripts FORCE @@ -1036,7 +1033,6 @@ help: @echo ' modules_install - Install all modules' @echo ' dir/ - Build all files in dir and below' @echo ' dir/file.[ois] - Build specified target only' - @echo ' dir/file.ko - Build module including final link' @echo ' rpm - Build a kernel as an RPM package' @echo ' tags/TAGS - Generate tags file for editors' @echo ' cscope - Generate cscope index' @@ -1153,7 +1149,7 @@ endif # KBUILD_EXTMOD #(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. #Adding $(srctree) adds about 20M on i386 to the size of the output file! -ifeq ($(src),$(obj)) +ifeq ($(KBUILD_OUTPUT),) __srctree = else __srctree = $(srctree)/ diff --git a/trunk/arch/frv/defconfig b/trunk/arch/frv/defconfig deleted file mode 100644 index b6e4ca5efb59..000000000000 --- a/trunk/arch/frv/defconfig +++ /dev/null @@ -1,627 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.11.8 -# Fri May 13 17:16:03 2005 -# -CONFIG_FRV=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_GENERIC_CALIBRATE_DELAY is not set -# CONFIG_GENERIC_HARDIRQS is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -# CONFIG_KOBJECT_UEVENT is not set -# CONFIG_IKCONFIG is not set -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Fujitsu FR-V system setup -# -CONFIG_MMU=y -CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_FRV_DEFL_CACHE_WBACK is not set -# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set -CONFIG_FRV_DEFL_CACHE_WTHRU=y -# CONFIG_FRV_DEFL_CACHE_DISABLED is not set - -# -# CPU core support -# -CONFIG_CPU_FR451=y -CONFIG_CPU_FR451_COMPILE=y -CONFIG_FRV_L1_CACHE_SHIFT=5 -CONFIG_MB93091_VDK=y -# CONFIG_MB93093_PDK is not set -CONFIG_MB93090_MB00=y -# CONFIG_MB93091_NO_MB is not set -# CONFIG_GPREL_DATA_8 is not set -CONFIG_GPREL_DATA_4=y -# CONFIG_GPREL_DATA_NONE is not set -CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -# CONFIG_PCI_NAMES is not set -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCMCIA is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Executable formats -# -# CONFIG_BINFMT_ELF is not set -CONFIG_BINFMT_ELF_FDPIC=y -# CONFIG_BINFMT_MISC is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set -# CONFIG_FORK_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_KGDBOE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -CONFIG_NE2K_PCI=y -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISER4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_EARLY_PRINTK is not set -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_GDBSTUB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 4553ffd94b1f..2203a9d20212 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -435,11 +435,6 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) if (c == &boot_cpu_data) sysenter_setup(); enable_sep_cpu(); - - if (c == &boot_cpu_data) - mtrr_bp_init(); - else - mtrr_ap_init(); } #ifdef CONFIG_X86_HT diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index a2c33c1a46c5..96a75d045835 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -25,7 +25,7 @@ extern int trap_init_f00f_bug(void); /* * Alignment at which movsl is preferred for bulk memory copies. */ -struct movsl_mask movsl_mask __read_mostly; +struct movsl_mask movsl_mask; #endif void __devinit early_intel_workaround(struct cpuinfo_x86 *c) diff --git a/trunk/arch/i386/kernel/cpu/mtrr/generic.c b/trunk/arch/i386/kernel/cpu/mtrr/generic.c index 169ac8e0db68..64d91f73a0a4 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/generic.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/generic.c @@ -67,6 +67,13 @@ void __init get_mtrr_state(void) mtrr_state.enabled = (lo & 0xc00) >> 10; } +/* Free resources associated with a struct mtrr_state */ +void __init finalize_mtrr_state(void) +{ + kfree(mtrr_state.var_ranges); + mtrr_state.var_ranges = NULL; +} + /* Some BIOS's are fucked and don't set all MTRRs the same! */ void __init mtrr_state_warn(void) { @@ -327,9 +334,6 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, */ { unsigned long flags; - struct mtrr_var_range *vr; - - vr = &mtrr_state.var_ranges[reg]; local_irq_save(flags); prepare_set(); @@ -338,15 +342,11 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, /* The invalid bit is kept in the mask, so we simply clear the relevant mask register to disable a range. */ mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); - memset(vr, 0, sizeof(struct mtrr_var_range)); } else { - vr->base_lo = base << PAGE_SHIFT | type; - vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT); - vr->mask_lo = -size << PAGE_SHIFT | 0x800; - vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT); - - mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi); - mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi); + mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type, + (base & size_and_mask) >> (32 - PAGE_SHIFT)); + mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800, + (-size & size_and_mask) >> (32 - PAGE_SHIFT)); } post_set(); diff --git a/trunk/arch/i386/kernel/cpu/mtrr/main.c b/trunk/arch/i386/kernel/cpu/mtrr/main.c index 764cac64e211..d66b09e0c820 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/main.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/main.c @@ -332,8 +332,6 @@ int mtrr_add_page(unsigned long base, unsigned long size, error = -EINVAL; - /* No CPU hotplug when we change MTRR entries */ - lock_cpu_hotplug(); /* Search for existing MTRR */ down(&main_lock); for (i = 0; i < num_var_ranges; ++i) { @@ -374,7 +372,6 @@ int mtrr_add_page(unsigned long base, unsigned long size, error = i; out: up(&main_lock); - unlock_cpu_hotplug(); return error; } @@ -464,8 +461,6 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) return -ENXIO; max = num_var_ranges; - /* No CPU hotplug when we change MTRR entries */ - lock_cpu_hotplug(); down(&main_lock); if (reg < 0) { /* Search for existing MTRR */ @@ -506,7 +501,6 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) error = reg; out: up(&main_lock); - unlock_cpu_hotplug(); return error; } /** @@ -550,9 +544,21 @@ static void __init init_ifs(void) centaur_init_mtrr(); } -/* The suspend/resume methods are only for CPU without MTRR. CPU using generic - * MTRR driver doesn't require this - */ +static void __init init_other_cpus(void) +{ + if (use_intel()) + get_mtrr_state(); + + /* bring up the other processors */ + set_mtrr(~0U,0,0,0); + + if (use_intel()) { + finalize_mtrr_state(); + mtrr_state_warn(); + } +} + + struct mtrr_value { mtrr_type ltype; unsigned long lbase; @@ -605,13 +611,13 @@ static struct sysdev_driver mtrr_sysdev_driver = { /** - * mtrr_bp_init - initialize mtrrs on the boot CPU + * mtrr_init - initialize mtrrs on the boot CPU * * This needs to be called early; before any of the other CPUs are * initialized (i.e. before smp_init()). * */ -void __init mtrr_bp_init(void) +static int __init mtrr_init(void) { init_ifs(); @@ -668,48 +674,12 @@ void __init mtrr_bp_init(void) if (mtrr_if) { set_num_var_ranges(); init_table(); - if (use_intel()) - get_mtrr_state(); - } -} - -void mtrr_ap_init(void) -{ - unsigned long flags; + init_other_cpus(); - if (!mtrr_if || !use_intel()) - return; - /* - * Ideally we should hold main_lock here to avoid mtrr entries changed, - * but this routine will be called in cpu boot time, holding the lock - * breaks it. This routine is called in two cases: 1.very earily time - * of software resume, when there absolutely isn't mtrr entry changes; - * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to - * prevent mtrr entry changes - */ - local_irq_save(flags); - - mtrr_if->set_all(); - - local_irq_restore(flags); -} - -static int __init mtrr_init_finialize(void) -{ - if (!mtrr_if) - return 0; - if (use_intel()) - mtrr_state_warn(); - else { - /* The CPUs haven't MTRR and seemes not support SMP. They have - * specific drivers, we use a tricky method to support - * suspend/resume for them. - * TBD: is there any system with such CPU which supports - * suspend/resume? if no, we should remove the code. - */ - sysdev_driver_register(&cpu_sysdev_class, - &mtrr_sysdev_driver); + return sysdev_driver_register(&cpu_sysdev_class, + &mtrr_sysdev_driver); } - return 0; + return -ENXIO; } -subsys_initcall(mtrr_init_finialize); + +subsys_initcall(mtrr_init); diff --git a/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h b/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h index 99c9f2682041..de1351245599 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h +++ b/trunk/arch/i386/kernel/cpu/mtrr/mtrr.h @@ -91,6 +91,7 @@ extern struct mtrr_ops * mtrr_if; extern unsigned int num_var_ranges; +void finalize_mtrr_state(void); void mtrr_state_warn(void); char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 8ac8e9fd5614..d66bf489a2e9 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -68,21 +68,21 @@ EXPORT_SYMBOL(smp_num_siblings); #endif /* Package ID of each logical CPU */ -int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; +int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(phys_proc_id); /* Core ID of each logical CPU */ -int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; +int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; EXPORT_SYMBOL(cpu_core_id); -cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; +cpumask_t cpu_sibling_map[NR_CPUS]; EXPORT_SYMBOL(cpu_sibling_map); -cpumask_t cpu_core_map[NR_CPUS] __read_mostly; +cpumask_t cpu_core_map[NR_CPUS]; EXPORT_SYMBOL(cpu_core_map); /* bitmap of online cpus */ -cpumask_t cpu_online_map __read_mostly; +cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); cpumask_t cpu_callin_map; @@ -100,7 +100,7 @@ static int __devinitdata tsc_sync_disabled; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_data); -u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = +u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = 0xff }; EXPORT_SYMBOL(x86_cpu_to_apicid); @@ -550,10 +550,10 @@ extern struct { #ifdef CONFIG_NUMA /* which logical CPUs are on which nodes */ -cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = +cpumask_t node_2_cpu_mask[MAX_NUMNODES] = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; /* which node each logical CPU is on */ -int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; +int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_2_node); /* set up a mapping between cpu and node. */ @@ -581,7 +581,7 @@ static inline void unmap_cpu_to_node(int cpu) #endif /* CONFIG_NUMA */ -u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; +u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; static void map_cpu_to_logical_apicid(void) { diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 0ee9dee8af06..2854c357377f 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -91,7 +91,7 @@ EXPORT_SYMBOL(rtc_lock); DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); -struct timer_opts *cur_timer __read_mostly = &timer_none; +struct timer_opts *cur_timer = &timer_none; /* * This is a special lock that is owned by the CPU and holds the index diff --git a/trunk/arch/i386/kernel/timers/timer_hpet.c b/trunk/arch/i386/kernel/timers/timer_hpet.c index ef8dac5dd33b..d766e0963ac1 100644 --- a/trunk/arch/i386/kernel/timers/timer_hpet.c +++ b/trunk/arch/i386/kernel/timers/timer_hpet.c @@ -18,7 +18,7 @@ #include "mach_timer.h" #include -static unsigned long __read_mostly hpet_usec_quotient; /* convert hpet clks to usec */ +static unsigned long hpet_usec_quotient; /* convert hpet clks to usec */ static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */ static unsigned long hpet_last; /* hpet counter value at last tick*/ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ @@ -180,7 +180,7 @@ static int __init init_hpet(char* override) /************************************************************/ /* tsc timer_opts struct */ -static struct timer_opts timer_hpet __read_mostly = { +static struct timer_opts timer_hpet = { .name = "hpet", .mark_offset = mark_offset_hpet, .get_offset = get_offset_hpet, diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index 761972f8cb6c..7e01a528a83a 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -57,9 +57,6 @@ SECTIONS *(.data.cacheline_aligned) } - /* rarely changed data like cpu maps */ - . = ALIGN(32); - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } _edata = .; /* End of data section */ . = ALIGN(THREAD_SIZE); /* init_task */ diff --git a/trunk/arch/i386/mm/ioremap.c b/trunk/arch/i386/mm/ioremap.c index f379b8d67558..6b25afc933b6 100644 --- a/trunk/arch/i386/mm/ioremap.c +++ b/trunk/arch/i386/mm/ioremap.c @@ -228,8 +228,7 @@ EXPORT_SYMBOL(ioremap_nocache); void iounmap(volatile void __iomem *addr) { struct vm_struct *p; - - if ((void __force *)addr <= high_memory) + if ((void __force *) addr <= high_memory) return; /* @@ -242,10 +241,9 @@ void iounmap(volatile void __iomem *addr) return; write_lock(&vmlist_lock); - p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); + p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); if (!p) { printk(KERN_WARNING "iounmap: bad address %p\n", addr); - dump_stack(); goto out_unlock; } diff --git a/trunk/arch/i386/power/cpu.c b/trunk/arch/i386/power/cpu.c index c547c1af6fa1..0e6b45b61251 100644 --- a/trunk/arch/i386/power/cpu.c +++ b/trunk/arch/i386/power/cpu.c @@ -137,7 +137,6 @@ void __restore_processor_state(struct saved_context *ctxt) fix_processor_context(); do_fpu_end(); - mtrr_ap_init(); } void restore_processor_state(void) diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index e1fb68ddec26..b2e2f6509eb0 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o -obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 542256e98e60..cda06f88c66e 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -640,10 +640,8 @@ acpi_boot_init (void) if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; } -# endif -#endif -#ifdef CONFIG_ACPI_NUMA build_cpu_to_node_map(); +# endif #endif /* Make boot-up look pretty */ printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); diff --git a/trunk/arch/ia64/kernel/numa.c b/trunk/arch/ia64/kernel/numa.c deleted file mode 100644 index a68ce6678092..000000000000 --- a/trunk/arch/ia64/kernel/numa.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ia64 kernel NUMA specific stuff - * - * Copyright (C) 2002 Erich Focht - * Copyright (C) 2004 Silicon Graphics, Inc. - * Jesse Barnes - */ -#include -#include -#include -#include -#include - -u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL(cpu_to_node_map); - -cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; - -/** - * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays - * - * Build cpu to node mapping and initialize the per node cpu masks using - * info from the node_cpuid array handed to us by ACPI. - */ -void __init build_cpu_to_node_map(void) -{ - int cpu, i, node; - - for(node=0; node < MAX_NUMNODES; node++) - cpus_clear(node_to_cpu_mask[node]); - - for(cpu = 0; cpu < NR_CPUS; ++cpu) { - node = -1; - for (i = 0; i < NR_CPUS; ++i) - if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) { - node = node_cpuid[i].nid; - break; - } - cpu_to_node_map[cpu] = (node >= 0) ? node : 0; - if (node >= 0) - cpu_set(cpu, node_to_cpu_mask[node]); - } -} diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index b8a0a7d257a9..edd9f07860b2 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -143,7 +143,6 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); psr->mfh = 0; /* drop signal handler's fph contents... */ - preempt_disable(); if (psr->dfh) ia64_drop_fpu(current); else { @@ -151,7 +150,6 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) __ia64_load_fpu(current->thread.fph); ia64_set_local_fpu_owner(current); } - preempt_enable(); } return err; } diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 7d72c0d872b3..623b0a546709 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -525,6 +525,47 @@ smp_build_cpu_map (void) } } +#ifdef CONFIG_NUMA + +/* on which node is each logical CPU (one cacheline even for 64 CPUs) */ +u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_to_node_map); +/* which logical CPUs are on which nodes */ +cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; + +/* + * Build cpu to node mapping and initialize the per node cpu masks. + */ +void __init +build_cpu_to_node_map (void) +{ + int cpu, i, node; + + for(node=0; node= 0) ? node : 0; + if (node >= 0) + cpu_set(cpu, node_to_cpu_mask[node]); + } +} + +#endif /* CONFIG_NUMA */ + /* * Cycle through the APs sending Wakeup IPIs to boot each. */ diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index 4440c8343fa4..e7e520d90f03 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -90,16 +90,14 @@ die (const char *str, struct pt_regs *regs, long err) .lock_owner_depth = 0 }; static int die_counter; - int cpu = get_cpu(); - if (die.lock_owner != cpu) { + if (die.lock_owner != smp_processor_id()) { console_verbose(); spin_lock_irq(&die.lock); - die.lock_owner = cpu; + die.lock_owner = smp_processor_id(); die.lock_owner_depth = 0; bust_spinlocks(1); } - put_cpu(); if (++die.lock_owner_depth < 3) { printk("%s[%d]: %s %ld [%d]\n", diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index b5c90e548195..f3fd528ead3b 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -44,7 +44,150 @@ struct early_node_data { }; static struct early_node_data mem_data[MAX_NUMNODES] __initdata; -static nodemask_t memory_less_mask __initdata; + +/** + * reassign_cpu_only_nodes - called from find_memory to move CPU-only nodes to a memory node + * + * This function will move nodes with only CPUs (no memory) + * to a node with memory which is at the minimum numa_slit distance. + * Any reassigments will result in the compression of the nodes + * and renumbering the nid values where appropriate. + * The static declarations below are to avoid large stack size which + * makes the code not re-entrant. + */ +static void __init reassign_cpu_only_nodes(void) +{ + struct node_memblk_s *p; + int i, j, k, nnode, nid, cpu, cpunid, pxm; + u8 cslit, slit; + static DECLARE_BITMAP(nodes_with_mem, MAX_NUMNODES) __initdata; + static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata; + static int node_flip[MAX_NUMNODES] __initdata; + static int old_nid_map[NR_CPUS] __initdata; + + for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++) + if (!test_bit(p->nid, (void *) nodes_with_mem)) { + set_bit(p->nid, (void *) nodes_with_mem); + nnode++; + } + + /* + * All nids with memory. + */ + if (nnode == num_online_nodes()) + return; + + /* + * Change nids and attempt to migrate CPU-only nodes + * to the best numa_slit (closest neighbor) possible. + * For reassigned CPU nodes a nid can't be arrived at + * until after this loop because the target nid's new + * identity might not have been established yet. So + * new nid values are fabricated above num_online_nodes() and + * mapped back later to their true value. + */ + /* MCD - This code is a bit complicated, but may be unnecessary now. + * We can now handle much more interesting node-numbering. + * The old requirement that 0 <= nid <= numnodes <= MAX_NUMNODES + * and that there be no holes in the numbering 0..numnodes + * has become simply 0 <= nid <= MAX_NUMNODES. + */ + nid = 0; + for_each_online_node(i) { + if (test_bit(i, (void *) nodes_with_mem)) { + /* + * Save original nid value for numa_slit + * fixup and node_cpuid reassignments. + */ + node_flip[nid] = i; + + if (i == nid) { + nid++; + continue; + } + + for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++) + if (p->nid == i) + p->nid = nid; + + cpunid = nid; + nid++; + } else + cpunid = MAX_NUMNODES; + + for (cpu = 0; cpu < NR_CPUS; cpu++) + if (node_cpuid[cpu].nid == i) { + /* + * For nodes not being reassigned just + * fix the cpu's nid and reverse pxm map + */ + if (cpunid < MAX_NUMNODES) { + pxm = nid_to_pxm_map[i]; + pxm_to_nid_map[pxm] = + node_cpuid[cpu].nid = cpunid; + continue; + } + + /* + * For nodes being reassigned, find best node by + * numa_slit information and then make a temporary + * nid value based on current nid and num_online_nodes(). + */ + slit = 0xff; + k = 2*num_online_nodes(); + for_each_online_node(j) { + if (i == j) + continue; + else if (test_bit(j, (void *) nodes_with_mem)) { + cslit = numa_slit[i * num_online_nodes() + j]; + if (cslit < slit) { + k = num_online_nodes() + j; + slit = cslit; + } + } + } + + /* save old nid map so we can update the pxm */ + old_nid_map[cpu] = node_cpuid[cpu].nid; + node_cpuid[cpu].nid = k; + } + } + + /* + * Fixup temporary nid values for CPU-only nodes. + */ + for (cpu = 0; cpu < NR_CPUS; cpu++) + if (node_cpuid[cpu].nid == (2*num_online_nodes())) { + pxm = nid_to_pxm_map[old_nid_map[cpu]]; + pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = nnode - 1; + } else { + for (i = 0; i < nnode; i++) { + if (node_flip[i] != (node_cpuid[cpu].nid - num_online_nodes())) + continue; + + pxm = nid_to_pxm_map[old_nid_map[cpu]]; + pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = i; + break; + } + } + + /* + * Fix numa_slit by compressing from larger + * nid array to reduced nid array. + */ + for (i = 0; i < nnode; i++) + for (j = 0; j < nnode; j++) + numa_slit_fix[i * nnode + j] = + numa_slit[node_flip[i] * num_online_nodes() + node_flip[j]]; + + memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit)); + + nodes_clear(node_online_map); + for (i = 0; i < nnode; i++) + node_set_online(i); + + return; +} /* * To prevent cache aliasing effects, align per-node structures so that they @@ -90,101 +233,44 @@ static int __init build_node_maps(unsigned long start, unsigned long len, } /** - * early_nr_cpus_node - return number of cpus on a given node + * early_nr_phys_cpus_node - return number of physical cpus on a given node * @node: node to check * - * Count the number of cpus on @node. We can't use nr_cpus_node() yet because + * Count the number of physical cpus on @node. These are cpus that actually + * exist. We can't use nr_cpus_node() yet because * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been - * called yet. Note that node 0 will also count all non-existent cpus. + * called yet. */ -static int __init early_nr_cpus_node(int node) +static int early_nr_phys_cpus_node(int node) { int cpu, n = 0; for (cpu = 0; cpu < NR_CPUS; cpu++) if (node == node_cpuid[cpu].nid) - n++; + if ((cpu == 0) || node_cpuid[cpu].phys_id) + n++; return n; } -/** - * compute_pernodesize - compute size of pernode data - * @node: the node id. - */ -static unsigned long __init compute_pernodesize(int node) -{ - unsigned long pernodesize = 0, cpus; - - cpus = early_nr_cpus_node(node); - pernodesize += PERCPU_PAGE_SIZE * cpus; - pernodesize += node * L1_CACHE_BYTES; - pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t)); - pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - pernodesize = PAGE_ALIGN(pernodesize); - return pernodesize; -} /** - * per_cpu_node_setup - setup per-cpu areas on each node - * @cpu_data: per-cpu area on this node - * @node: node to setup + * early_nr_cpus_node - return number of cpus on a given node + * @node: node to check * - * Copy the static per-cpu data into the region we just set aside and then - * setup __per_cpu_offset for each CPU on this node. Return a pointer to - * the end of the area. - */ -static void *per_cpu_node_setup(void *cpu_data, int node) -{ -#ifdef CONFIG_SMP - int cpu; - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - if (node == node_cpuid[cpu].nid) { - memcpy(__va(cpu_data), __phys_per_cpu_start, - __per_cpu_end - __per_cpu_start); - __per_cpu_offset[cpu] = (char*)__va(cpu_data) - - __per_cpu_start; - cpu_data += PERCPU_PAGE_SIZE; - } - } -#endif - return cpu_data; -} - -/** - * fill_pernode - initialize pernode data. - * @node: the node id. - * @pernode: physical address of pernode data - * @pernodesize: size of the pernode data + * Count the number of cpus on @node. We can't use nr_cpus_node() yet because + * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been + * called yet. Note that node 0 will also count all non-existent cpus. */ -static void __init fill_pernode(int node, unsigned long pernode, - unsigned long pernodesize) +static int early_nr_cpus_node(int node) { - void *cpu_data; - int cpus = early_nr_cpus_node(node); - struct bootmem_data *bdp = &mem_data[node].bootmem_data; - - mem_data[node].pernode_addr = pernode; - mem_data[node].pernode_size = pernodesize; - memset(__va(pernode), 0, pernodesize); - - cpu_data = (void *)pernode; - pernode += PERCPU_PAGE_SIZE * cpus; - pernode += node * L1_CACHE_BYTES; - - mem_data[node].pgdat = __va(pernode); - pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); - - mem_data[node].node_data = __va(pernode); - pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - - mem_data[node].pgdat->bdata = bdp; - pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + int cpu, n = 0; - cpu_data = per_cpu_node_setup(cpu_data, node); + for (cpu = 0; cpu < NR_CPUS; cpu++) + if (node == node_cpuid[cpu].nid) + n++; - return; + return n; } /** @@ -218,8 +304,9 @@ static void __init fill_pernode(int node, unsigned long pernode, static int __init find_pernode_space(unsigned long start, unsigned long len, int node) { - unsigned long epfn; + unsigned long epfn, cpu, cpus, phys_cpus; unsigned long pernodesize = 0, pernode, pages, mapsize; + void *cpu_data; struct bootmem_data *bdp = &mem_data[node].bootmem_data; epfn = (start + len) >> PAGE_SHIFT; @@ -242,12 +329,49 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, * Calculate total size needed, incl. what's necessary * for good alignment and alias prevention. */ - pernodesize = compute_pernodesize(node); + cpus = early_nr_cpus_node(node); + phys_cpus = early_nr_phys_cpus_node(node); + pernodesize += PERCPU_PAGE_SIZE * cpus; + pernodesize += node * L1_CACHE_BYTES; + pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t)); + pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + pernodesize = PAGE_ALIGN(pernodesize); pernode = NODEDATA_ALIGN(start, node); /* Is this range big enough for what we want to store here? */ - if (start + len > (pernode + pernodesize + mapsize)) - fill_pernode(node, pernode, pernodesize); + if (start + len > (pernode + pernodesize + mapsize)) { + mem_data[node].pernode_addr = pernode; + mem_data[node].pernode_size = pernodesize; + memset(__va(pernode), 0, pernodesize); + + cpu_data = (void *)pernode; + pernode += PERCPU_PAGE_SIZE * cpus; + pernode += node * L1_CACHE_BYTES; + + mem_data[node].pgdat = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + mem_data[node].node_data = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + + mem_data[node].pgdat->bdata = bdp; + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + /* + * Copy the static per-cpu data into the region we + * just set aside and then setup __per_cpu_offset + * for each CPU on this node. + */ + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (node == node_cpuid[cpu].nid) { + memcpy(__va(cpu_data), __phys_per_cpu_start, + __per_cpu_end - __per_cpu_start); + __per_cpu_offset[cpu] = (char*)__va(cpu_data) - + __per_cpu_start; + cpu_data += PERCPU_PAGE_SIZE; + } + } + } return 0; } @@ -287,9 +411,6 @@ static void __init reserve_pernode_space(void) for_each_online_node(node) { pg_data_t *pdp = mem_data[node].pgdat; - if (node_isset(node, memory_less_mask)) - continue; - bdp = pdp->bdata; /* First the bootmem_map itself */ @@ -315,8 +436,8 @@ static void __init reserve_pernode_space(void) */ static void __init initialize_pernode_data(void) { - pg_data_t *pgdat_list[MAX_NUMNODES]; int cpu, node; + pg_data_t *pgdat_list[MAX_NUMNODES]; for_each_online_node(node) pgdat_list[node] = mem_data[node].pgdat; @@ -326,99 +447,12 @@ static void __init initialize_pernode_data(void) memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, sizeof(pgdat_list)); } -#ifdef CONFIG_SMP + /* Set the node_data pointer for each per-cpu struct */ for (cpu = 0; cpu < NR_CPUS; cpu++) { node = node_cpuid[cpu].nid; per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data; } -#else - { - struct cpuinfo_ia64 *cpu0_cpu_info; - cpu = 0; - node = node_cpuid[cpu].nid; - cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start + - ((char *)&per_cpu__cpu_info - __per_cpu_start)); - cpu0_cpu_info->node_data = mem_data[node].node_data; - } -#endif /* CONFIG_SMP */ -} - -/** - * memory_less_node_alloc - * attempt to allocate memory on the best NUMA slit - * node but fall back to any other node when __alloc_bootmem_node fails - * for best. - * @nid: node id - * @pernodesize: size of this node's pernode data - * @align: alignment to use for this node's pernode data - */ -static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, - unsigned long align) -{ - void *ptr = NULL; - u8 best = 0xff; - int bestnode = -1, node; - - for_each_online_node(node) { - if (node_isset(node, memory_less_mask)) - continue; - else if (node_distance(nid, node) < best) { - best = node_distance(nid, node); - bestnode = node; - } - } - - ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, - pernodesize, align, __pa(MAX_DMA_ADDRESS)); - - if (!ptr) - panic("NO memory for memory less node\n"); - return ptr; -} - -/** - * pgdat_insert - insert the pgdat into global pgdat_list - * @pgdat: the pgdat for a node. - */ -static void __init pgdat_insert(pg_data_t *pgdat) -{ - pg_data_t *prev = NULL, *next; - - for_each_pgdat(next) - if (pgdat->node_id < next->node_id) - break; - else - prev = next; - - if (prev) { - prev->pgdat_next = pgdat; - pgdat->pgdat_next = next; - } else { - pgdat->pgdat_next = pgdat_list; - pgdat_list = pgdat; - } - - return; -} - -/** - * memory_less_nodes - allocate and initialize CPU only nodes pernode - * information. - */ -static void __init memory_less_nodes(void) -{ - unsigned long pernodesize; - void *pernode; - int node; - - for_each_node_mask(node, memory_less_mask) { - pernodesize = compute_pernodesize(node); - pernode = memory_less_node_alloc(node, pernodesize, - (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024)); - fill_pernode(node, __pa(pernode), pernodesize); - } - - return; } /** @@ -438,19 +472,16 @@ void __init find_memory(void) node_set_online(0); } - nodes_or(memory_less_mask, memory_less_mask, node_online_map); min_low_pfn = -1; max_low_pfn = 0; + if (num_online_nodes() > 1) + reassign_cpu_only_nodes(); + /* These actually end up getting called by call_pernode_memory() */ efi_memmap_walk(filter_rsvd_memory, build_node_maps); efi_memmap_walk(filter_rsvd_memory, find_pernode_space); - for_each_online_node(node) - if (mem_data[node].bootmem_data.node_low_pfn) { - node_clear(node, memory_less_mask); - mem_data[node].min_pfn = ~0UL; - } /* * Initialize the boot memory maps in reverse order since that's * what the bootmem allocator expects @@ -461,14 +492,17 @@ void __init find_memory(void) if (!node_online(node)) continue; - else if (node_isset(node, memory_less_mask)) - continue; bdp = &mem_data[node].bootmem_data; pernode = mem_data[node].pernode_addr; pernodesize = mem_data[node].pernode_size; map = pernode + pernodesize; + /* Sanity check... */ + if (!pernode) + panic("pernode space for node %d " + "could not be allocated!", node); + init_bootmem_node(mem_data[node].pgdat, map>>PAGE_SHIFT, bdp->node_boot_start>>PAGE_SHIFT, @@ -478,7 +512,6 @@ void __init find_memory(void) efi_memmap_walk(filter_rsvd_memory, free_node_bootmem); reserve_pernode_space(); - memory_less_nodes(); initialize_pernode_data(); max_pfn = max_low_pfn; @@ -486,7 +519,6 @@ void __init find_memory(void) find_initrd(); } -#ifdef CONFIG_SMP /** * per_cpu_init - setup per-cpu variables * @@ -497,15 +529,15 @@ void *per_cpu_init(void) { int cpu; - if (smp_processor_id() != 0) - return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; - - for (cpu = 0; cpu < NR_CPUS; cpu++) - per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; + if (smp_processor_id() == 0) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { + per_cpu(local_per_cpu_offset, cpu) = + __per_cpu_offset[cpu]; + } + } return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; } -#endif /* CONFIG_SMP */ /** * show_mem - give short summary of memory stats @@ -648,12 +680,11 @@ void __init paging_init(void) max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - efi_memmap_walk(filter_rsvd_memory, count_node_pages); + /* so min() will work in count_node_pages */ + for_each_online_node(node) + mem_data[node].min_pfn = ~0UL; - vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page)); - vmem_map = (struct page *) vmalloc_end; - efi_memmap_walk(create_mem_map_page_table, NULL); - printk("Virtual mem_map starts at 0x%p\n", vmem_map); + efi_memmap_walk(filter_rsvd_memory, count_node_pages); for_each_online_node(node) { memset(zones_size, 0, sizeof(zones_size)); @@ -688,6 +719,15 @@ void __init paging_init(void) mem_data[node].num_dma_physpages); } + if (node == 0) { + vmalloc_end -= + PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmem_map = (struct page *) vmalloc_end; + + efi_memmap_walk(create_mem_map_page_table, NULL); + printk("Virtual mem_map starts at 0x%p\n", vmem_map); + } + pfn_offset = mem_data[node].min_pfn; NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; @@ -695,11 +735,5 @@ void __init paging_init(void) pfn_offset, zholes_size); } - /* - * Make memory less nodes become a member of the known nodes. - */ - for_each_node_mask(node, memory_less_mask) - pgdat_insert(mem_data[node].pgdat); - zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 65f9958db9f0..4eb2f52b87a1 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -597,8 +597,7 @@ mem_init (void) kclist_add(&kcore_kernel, _stext, _end - _stext); for_each_pgdat(pgdat) - if (pgdat->bdata->node_bootmem_map) - totalram_pages += free_all_bootmem_node(pgdat); + totalram_pages += free_all_bootmem_node(pgdat); reserved_pages = 0; efi_memmap_walk(count_reserved_pages, &reserved_pages); diff --git a/trunk/include/asm-ia64/sn/pcibr_provider.h b/trunk/arch/ia64/sn/include/pci/pcibr_provider.h similarity index 95% rename from trunk/include/asm-ia64/sn/pcibr_provider.h rename to trunk/arch/ia64/sn/include/pci/pcibr_provider.h index f9b8d2164007..1cd291d8badd 100644 --- a/trunk/include/asm-ia64/sn/pcibr_provider.h +++ b/trunk/arch/ia64/sn/include/pci/pcibr_provider.h @@ -8,9 +8,6 @@ #ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H #define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H -#include -#include - /* Workarounds */ #define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */ @@ -23,7 +20,7 @@ #define IS_PIC_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC) -/* +/* * The different PCI Bridge types supported on the SGI Altix platforms */ #define PCIBR_BRIDGETYPE_UNKNOWN -1 @@ -103,16 +100,15 @@ struct pcibus_info { struct ate_resource pbi_int_ate_resource; uint64_t pbi_int_ate_size; - + uint64_t pbi_dir_xbase; char pbi_hub_xid; uint64_t pbi_devreg[8]; + spinlock_t pbi_lock; uint32_t pbi_valid_devices; uint32_t pbi_enabled_devices; - - spinlock_t pbi_lock; }; /* @@ -152,8 +148,4 @@ extern void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info); extern int pcibr_ate_alloc(struct pcibus_info *, int); extern void pcibr_ate_free(struct pcibus_info *, int); extern void ate_write(struct pcibus_info *, int, int, uint64_t); -extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device, - void *resp); -extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device, - int action, void *resp); #endif diff --git a/trunk/include/asm-ia64/sn/pic.h b/trunk/arch/ia64/sn/include/pci/pic.h similarity index 98% rename from trunk/include/asm-ia64/sn/pic.h rename to trunk/arch/ia64/sn/include/pci/pic.h index 0de82e6b0893..fd18acecb1e6 100644 --- a/trunk/include/asm-ia64/sn/pic.h +++ b/trunk/arch/ia64/sn/include/pci/pic.h @@ -15,7 +15,7 @@ * PIC handles PCI/X busses. PCI/X requires that the 'bridge' (i.e. PIC) * be designated as 'device 0'. That is a departure from earlier SGI * PCI bridges. Because of that we use config space 1 to access the - * config space of the first actual PCI device on the bus. + * config space of the first actual PCI device on the bus. * Here's what the PIC manual says: * * The current PCI-X bus specification now defines that the parent @@ -29,14 +29,14 @@ * correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc. * PCI-X requires we start a 1, not 0 and currently the PX brick * does associate our: - * + * * device 0 with configuration space window 1, - * device 1 with configuration space window 2, + * device 1 with configuration space window 2, * device 2 with configuration space window 3, * device 3 with configuration space window 4. * - * The net effect is that all config space access are off-by-one with - * relation to other per-slot accesses on the PIC. + * The net effect is that all config space access are off-by-one with + * relation to other per-slot accesses on the PIC. * Here is a table that shows some of that: * * Internal Slot# @@ -65,7 +65,7 @@ *****************************************************************************/ /* NOTE: PIC WAR. PV#854697. PIC does not allow writes just to [31:0] - * of a 64-bit register. When writing PIC registers, always write the + * of a 64-bit register. When writing PIC registers, always write the * entire 64 bits. */ @@ -164,7 +164,7 @@ struct pic { uint64_t clear_all; /* 0x000{438,,,5F8} */ } p_buf_count[8]; - + /* 0x000600-0x0009FF -- PCI/X registers */ uint64_t p_pcix_bus_err_addr; /* 0x000600 */ uint64_t p_pcix_bus_err_attr; /* 0x000608 */ diff --git a/trunk/include/asm-ia64/sn/tiocp.h b/trunk/arch/ia64/sn/include/pci/tiocp.h similarity index 99% rename from trunk/include/asm-ia64/sn/tiocp.h rename to trunk/arch/ia64/sn/include/pci/tiocp.h index 5f2489c9d2dd..f07c83b2bf6e 100644 --- a/trunk/include/asm-ia64/sn/tiocp.h +++ b/trunk/arch/ia64/sn/include/pci/tiocp.h @@ -111,7 +111,7 @@ struct tiocp{ uint64_t clear_all; /* 0x000{438,,,5F8} */ } cp_buf_count[8]; - + /* 0x000600-0x0009FF -- PCI/X registers */ uint64_t cp_pcix_bus_err_addr; /* 0x000600 */ uint64_t cp_pcix_bus_err_attr; /* 0x000608 */ diff --git a/trunk/arch/ia64/sn/include/xtalk/hubdev.h b/trunk/arch/ia64/sn/include/xtalk/hubdev.h index 580a1c0403a7..868e7ecae84b 100644 --- a/trunk/arch/ia64/sn/include/xtalk/hubdev.h +++ b/trunk/arch/ia64/sn/include/xtalk/hubdev.h @@ -8,8 +8,6 @@ #ifndef _ASM_IA64_SN_XTALK_HUBDEV_H #define _ASM_IA64_SN_XTALK_HUBDEV_H -#include "xtalk/xwidgetdev.h" - #define HUB_WIDGET_ID_MAX 0xf #define DEV_PER_WIDGET (2*2*8) #define IIO_ITTE_WIDGET_BITS 4 /* size of widget field */ diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index a67f39e448cb..783eb4323847 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -9,28 +9,21 @@ #include #include #include +#include #include -#include -#include -#include #include #include +#include "pci/pcibr_provider.h" +#include "xtalk/xwidgetdev.h" +#include +#include "xtalk/hubdev.h" +#include #include -#include #include -#include "xtalk/hubdev.h" -#include "xtalk/xwidgetdev.h" +char master_baseio_wid; nasid_t master_nasid = INVALID_NASID; /* Partition Master */ -static struct list_head sn_sysdata_list; - -/* sysdata list struct */ -struct sysdata_el { - struct list_head entry; - void *sysdata; -}; - struct slab_info { struct hubdev_info hubdev; }; @@ -144,6 +137,23 @@ sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, return ret_stuff.v0; } +/* + * sn_alloc_pci_sysdata() - This routine allocates a pci controller + * which is expected as the pci_dev and pci_bus sysdata by the Linux + * PCI infrastructure. + */ +static inline struct pci_controller *sn_alloc_pci_sysdata(void) +{ + struct pci_controller *pci_sysdata; + + pci_sysdata = kmalloc(sizeof(*pci_sysdata), GFP_KERNEL); + if (!pci_sysdata) + BUG(); + + memset(pci_sysdata, 0, sizeof(*pci_sysdata)); + return pci_sysdata; +} + /* * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for * each node in the system. @@ -211,34 +221,22 @@ static void sn_fixup_ionodes(void) } -void sn_pci_unfixup_slot(struct pci_dev *dev) -{ - struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; - - sn_irq_unfixup(dev); - pci_dev_put(host_pci_dev); - pci_dev_put(dev); -} - /* * sn_pci_fixup_slot() - This routine sets up a slot's resources * consistent with the Linux PCI abstraction layer. Resources acquired * from our PCI provider include PIO maps to BAR space and interrupt * objects. */ -void sn_pci_fixup_slot(struct pci_dev *dev) +static void sn_pci_fixup_slot(struct pci_dev *dev) { int idx; int segment = 0; + uint64_t size; + struct sn_irq_info *sn_irq_info; + struct pci_dev *host_pci_dev; int status = 0; struct pcibus_bussoft *bs; - struct pci_bus *host_pci_bus; - struct pci_dev *host_pci_dev; - struct sn_irq_info *sn_irq_info; - unsigned long size; - unsigned int bus_no, devfn; - pci_dev_get(dev); /* for the sysdata pointer */ dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL); if (SN_PCIDEV_INFO(dev) <= 0) BUG(); /* Cannot afford to run out of memory */ @@ -255,7 +253,7 @@ void sn_pci_fixup_slot(struct pci_dev *dev) (u64) __pa(SN_PCIDEV_INFO(dev)), (u64) __pa(sn_irq_info)); if (status) - BUG(); /* Cannot get platform pci device information */ + BUG(); /* Cannot get platform pci device information information */ /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { @@ -277,21 +275,15 @@ void sn_pci_fixup_slot(struct pci_dev *dev) dev->resource[idx].parent = &iomem_resource; } - /* - * Using the PROMs values for the PCI host bus, get the Linux - * PCI host_pci_dev struct and set up host bus linkages - */ - - bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32; - devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; - host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no); - host_pci_dev = pci_get_slot(host_pci_bus, devfn); - - SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; + /* set up host bus linkages */ + bs = SN_PCIBUS_BUSSOFT(dev->bus); + host_pci_dev = + pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32, + SN_PCIDEV_INFO(dev)-> + pdi_slot_host_handle & 0xffffffff); SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info = - SN_PCIDEV_INFO(host_pci_dev); + SN_PCIDEV_INFO(host_pci_dev); SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev; - bs = SN_PCIBUS_BUSSOFT(dev->bus); SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs; if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { @@ -305,9 +297,6 @@ void sn_pci_fixup_slot(struct pci_dev *dev) SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info; dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq; sn_irq_fixup(dev, sn_irq_info); - } else { - SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL; - kfree(sn_irq_info); } } @@ -315,57 +304,55 @@ void sn_pci_fixup_slot(struct pci_dev *dev) * sn_pci_controller_fixup() - This routine sets up a bus's resources * consistent with the Linux PCI abstraction layer. */ -void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) +static void sn_pci_controller_fixup(int segment, int busnum) { int status = 0; int nasid, cnode; + struct pci_bus *bus; struct pci_controller *controller; struct pcibus_bussoft *prom_bussoft_ptr; struct hubdev_info *hubdev_info; void *provider_soft; struct sn_pcibus_provider *provider; - status = sal_get_pcibus_info((u64) segment, (u64) busnum, - (u64) ia64_tpa(&prom_bussoft_ptr)); - if (status > 0) - return; /*bus # does not exist */ - prom_bussoft_ptr = __va(prom_bussoft_ptr); + status = + sal_get_pcibus_info((u64) segment, (u64) busnum, + (u64) ia64_tpa(&prom_bussoft_ptr)); + if (status > 0) { + return; /* bus # does not exist */ + } - controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); - if (!controller) - BUG(); + prom_bussoft_ptr = __va(prom_bussoft_ptr); + controller = sn_alloc_pci_sysdata(); + /* controller non-zero is BUG'd in sn_alloc_pci_sysdata */ + bus = pci_scan_bus(busnum, &pci_root_ops, controller); if (bus == NULL) { - bus = pci_scan_bus(busnum, &pci_root_ops, controller); - if (bus == NULL) - return; /* error, or bus already scanned */ - bus->sysdata = NULL; + return; /* error, or bus already scanned */ } - if (bus->sysdata) - goto error_return; /* sysdata already alloc'd */ - /* * Per-provider fixup. Copies the contents from prom to local * area and links SN_PCIBUS_BUSSOFT(). */ - if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) + if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) { return; /* unsupported asic type */ - - if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) - goto error_return; /* no further fixup necessary */ + } provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; - if (provider == NULL) + if (provider == NULL) { return; /* no provider registerd for this asic */ + } provider_soft = NULL; - if (provider->bus_fixup) + if (provider->bus_fixup) { provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr); + } - if (provider_soft == NULL) + if (provider_soft == NULL) { return; /* fixup failed or not applicable */ + } /* * Generic bus fixup goes here. Don't reference prom_bussoft_ptr @@ -374,47 +361,12 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) bus->sysdata = controller; PCI_CONTROLLER(bus)->platform_data = provider_soft; + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); cnode = nasid_to_cnodeid(nasid); hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); - - return; - -error_return: - - kfree(controller); - return; -} - -void sn_bus_store_sysdata(struct pci_dev *dev) -{ - struct sysdata_el *element; - - element = kcalloc(1, sizeof(struct sysdata_el), GFP_KERNEL); - if (!element) { - dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); - return; - } - element->sysdata = dev->sysdata; - list_add(&element->entry, &sn_sysdata_list); -} - -void sn_bus_free_sysdata(void) -{ - struct sysdata_el *element; - struct list_head *list; - -sn_sysdata_free_start: - list_for_each(list, &sn_sysdata_list) { - element = list_entry(list, struct sysdata_el, entry); - list_del(&element->entry); - kfree(element->sysdata); - kfree(element); - goto sn_sysdata_free_start; - } - return; } /* @@ -451,17 +403,20 @@ static int __init sn_pci_init(void) */ ia64_max_iommu_merge_mask = ~PAGE_MASK; sn_fixup_ionodes(); - sn_irq_lh_init(); - INIT_LIST_HEAD(&sn_sysdata_list); + sn_irq = kmalloc(sizeof(struct sn_irq_info *) * NR_IRQS, GFP_KERNEL); + if (sn_irq <= 0) + BUG(); /* Canno afford to run out of memory. */ + memset(sn_irq, 0, sizeof(struct sn_irq_info *) * NR_IRQS); + sn_init_cpei_timer(); #ifdef CONFIG_PROC_FS register_sn_procfs(); #endif - /* busses are not known yet ... */ - for (i = 0; i < PCI_BUSES_TO_SCAN; i++) - sn_pci_controller_fixup(0, i, NULL); + for (i = 0; i < PCI_BUSES_TO_SCAN; i++) { + sn_pci_controller_fixup(0, i); + } /* * Generic Linux PCI Layer has created the pci_bus and pci_dev @@ -470,8 +425,9 @@ static int __init sn_pci_init(void) */ while ((pci_dev = - pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) + pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { sn_pci_fixup_slot(pci_dev); + } sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ @@ -513,8 +469,3 @@ cnodeid_get_geoid(cnodeid_t cnode) } subsys_initcall(sn_pci_init); -EXPORT_SYMBOL(sn_pci_fixup_slot); -EXPORT_SYMBOL(sn_pci_unfixup_slot); -EXPORT_SYMBOL(sn_pci_controller_fixup); -EXPORT_SYMBOL(sn_bus_store_sysdata); -EXPORT_SYMBOL(sn_bus_free_sysdata); diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 84d276a14ecb..0f4e8138658f 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -9,13 +9,13 @@ */ #include -#include +#include #include #include -#include -#include +#include "xtalk/xwidgetdev.h" #include #include +#include "pci/pcibr_provider.h" #include #include @@ -25,8 +25,7 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); extern int sn_force_interrupt_flag; extern int sn_ioif_inited; -static struct list_head **sn_irq_lh; -static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ +struct sn_irq_info **sn_irq; static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget, u64 sn_irq_info, @@ -102,7 +101,7 @@ static void sn_end_irq(unsigned int irq) nasid = get_nasid(); event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR (nasid, SH_EVENT_OCCURRED)); - /* If the UART bit is set here, we may have received an + /* If the UART bit is set here, we may have received an * interrupt from the UART that the driver missed. To * make sure, we IPI ourselves to force us to look again. */ @@ -116,84 +115,82 @@ static void sn_end_irq(unsigned int irq) force_interrupt(irq); } -static void sn_irq_info_free(struct rcu_head *head); - static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) { - struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; + struct sn_irq_info *sn_irq_info = sn_irq[irq]; + struct sn_irq_info *tmp_sn_irq_info; int cpuid, cpuphys; + nasid_t t_nasid; /* nasid to target */ + int t_slice; /* slice to target */ + + /* allocate a temp sn_irq_info struct to get new target info */ + tmp_sn_irq_info = kmalloc(sizeof(*tmp_sn_irq_info), GFP_KERNEL); + if (!tmp_sn_irq_info) + return; cpuid = first_cpu(mask); cpuphys = cpu_physical_id(cpuid); + t_nasid = cpuid_to_nasid(cpuid); + t_slice = cpuid_to_slice(cpuid); - list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, - sn_irq_lh[irq], list) { - uint64_t bridge; - int local_widget, status; - nasid_t local_nasid; - struct sn_irq_info *new_irq_info; - - new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); - if (new_irq_info == NULL) - break; - memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); - - bridge = (uint64_t) new_irq_info->irq_bridge; - if (!bridge) { - kfree(new_irq_info); - break; /* irq is not a device interrupt */ - } + while (sn_irq_info) { + int status; + int local_widget; + uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; + nasid_t local_nasid = NASID_GET(bridge); - local_nasid = NASID_GET(bridge); + if (!bridge) + break; /* irq is not a device interrupt */ if (local_nasid & 1) local_widget = TIO_SWIN_WIDGETNUM(bridge); else local_widget = SWIN_WIDGETNUM(bridge); - /* Free the old PROM new_irq_info structure */ - sn_intr_free(local_nasid, local_widget, new_irq_info); - /* Update kernels new_irq_info with new target info */ - unregister_intr_pda(new_irq_info); + /* Free the old PROM sn_irq_info structure */ + sn_intr_free(local_nasid, local_widget, sn_irq_info); - /* allocate a new PROM new_irq_info struct */ + /* allocate a new PROM sn_irq_info struct */ status = sn_intr_alloc(local_nasid, local_widget, - __pa(new_irq_info), irq, - cpuid_to_nasid(cpuid), - cpuid_to_slice(cpuid)); - - /* SAL call failed */ - if (status) { - kfree(new_irq_info); - break; - } - - new_irq_info->irq_cpuid = cpuid; - register_intr_pda(new_irq_info); - - if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type)) - pcibr_change_devices_irq(new_irq_info); + __pa(tmp_sn_irq_info), irq, t_nasid, + t_slice); + + if (status == 0) { + /* Update kernels sn_irq_info with new target info */ + unregister_intr_pda(sn_irq_info); + sn_irq_info->irq_cpuid = cpuid; + sn_irq_info->irq_nasid = t_nasid; + sn_irq_info->irq_slice = t_slice; + sn_irq_info->irq_xtalkaddr = + tmp_sn_irq_info->irq_xtalkaddr; + sn_irq_info->irq_cookie = tmp_sn_irq_info->irq_cookie; + register_intr_pda(sn_irq_info); + + if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type)) { + pcibr_change_devices_irq(sn_irq_info); + } - spin_lock(&sn_irq_info_lock); - list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); - spin_unlock(&sn_irq_info_lock); - call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + sn_irq_info = sn_irq_info->irq_next; #ifdef CONFIG_SMP - set_irq_affinity_info((irq & 0xff), cpuphys, 0); + set_irq_affinity_info((irq & 0xff), cpuphys, 0); #endif + } else { + break; /* snp_affinity failed the intr_alloc */ + } } + kfree(tmp_sn_irq_info); } struct hw_interrupt_type irq_type_sn = { - .typename = "SN hub", - .startup = sn_startup_irq, - .shutdown = sn_shutdown_irq, - .enable = sn_enable_irq, - .disable = sn_disable_irq, - .ack = sn_ack_irq, - .end = sn_end_irq, - .set_affinity = sn_set_affinity_irq + "SN hub", + sn_startup_irq, + sn_shutdown_irq, + sn_enable_irq, + sn_disable_irq, + sn_ack_irq, + sn_end_irq, + sn_set_affinity_irq }; unsigned int sn_local_vector_to_irq(u8 vector) @@ -234,18 +231,19 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) struct sn_irq_info *tmp_irq_info; int i, foundmatch; - rcu_read_lock(); if (pdacpu(cpu)->sn_last_irq == irq) { foundmatch = 0; - for (i = pdacpu(cpu)->sn_last_irq - 1; - i && !foundmatch; i--) { - list_for_each_entry_rcu(tmp_irq_info, - sn_irq_lh[i], - list) { + for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--) { + tmp_irq_info = sn_irq[i]; + while (tmp_irq_info) { if (tmp_irq_info->irq_cpuid == cpu) { - foundmatch = 1; + foundmatch++; break; } + tmp_irq_info = tmp_irq_info->irq_next; + } + if (foundmatch) { + break; } } pdacpu(cpu)->sn_last_irq = i; @@ -253,27 +251,60 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) if (pdacpu(cpu)->sn_first_irq == irq) { foundmatch = 0; - for (i = pdacpu(cpu)->sn_first_irq + 1; - i < NR_IRQS && !foundmatch; i++) { - list_for_each_entry_rcu(tmp_irq_info, - sn_irq_lh[i], - list) { + for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++) { + tmp_irq_info = sn_irq[i]; + while (tmp_irq_info) { if (tmp_irq_info->irq_cpuid == cpu) { - foundmatch = 1; + foundmatch++; break; } + tmp_irq_info = tmp_irq_info->irq_next; + } + if (foundmatch) { + break; } } pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i); } - rcu_read_unlock(); } -static void sn_irq_info_free(struct rcu_head *head) +struct sn_irq_info *sn_irq_alloc(nasid_t local_nasid, int local_widget, int irq, + nasid_t nasid, int slice) { struct sn_irq_info *sn_irq_info; + int status; + + sn_irq_info = kmalloc(sizeof(*sn_irq_info), GFP_KERNEL); + if (sn_irq_info == NULL) + return NULL; + + memset(sn_irq_info, 0x0, sizeof(*sn_irq_info)); + + status = + sn_intr_alloc(local_nasid, local_widget, __pa(sn_irq_info), irq, + nasid, slice); + + if (status) { + kfree(sn_irq_info); + return NULL; + } else { + return sn_irq_info; + } +} + +void sn_irq_free(struct sn_irq_info *sn_irq_info) +{ + uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge; + nasid_t local_nasid = NASID_GET(bridge); + int local_widget; + + if (local_nasid & 1) /* tio check */ + local_widget = TIO_SWIN_WIDGETNUM(bridge); + else + local_widget = SWIN_WIDGETNUM(bridge); + + sn_intr_free(local_nasid, local_widget, sn_irq_info); - sn_irq_info = container_of(head, struct sn_irq_info, rcu); kfree(sn_irq_info); } @@ -283,54 +314,30 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) int slice = sn_irq_info->irq_slice; int cpu = nasid_slice_to_cpuid(nasid, slice); - pci_dev_get(pci_dev); sn_irq_info->irq_cpuid = cpu; sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev); /* link it into the sn_irq[irq] list */ - spin_lock(&sn_irq_info_lock); - list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); - spin_unlock(&sn_irq_info_lock); + sn_irq_info->irq_next = sn_irq[sn_irq_info->irq_irq]; + sn_irq[sn_irq_info->irq_irq] = sn_irq_info; (void)register_intr_pda(sn_irq_info); } -void sn_irq_unfixup(struct pci_dev *pci_dev) -{ - struct sn_irq_info *sn_irq_info; - - /* Only cleanup IRQ stuff if this device has a host bus context */ - if (!SN_PCIDEV_BUSSOFT(pci_dev)) - return; - - sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info; - if (!sn_irq_info || !sn_irq_info->irq_irq) { - kfree(sn_irq_info); - return; - } - - unregister_intr_pda(sn_irq_info); - spin_lock(&sn_irq_info_lock); - list_del_rcu(&sn_irq_info->list); - spin_unlock(&sn_irq_info_lock); - call_rcu(&sn_irq_info->rcu, sn_irq_info_free); - pci_dev_put(pci_dev); -} - static void force_interrupt(int irq) { struct sn_irq_info *sn_irq_info; if (!sn_ioif_inited) return; - - rcu_read_lock(); - list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) { + sn_irq_info = sn_irq[irq]; + while (sn_irq_info) { if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && - (sn_irq_info->irq_bridge != NULL)) + (sn_irq_info->irq_bridge != NULL)) { pcibr_force_interrupt(sn_irq_info); + } + sn_irq_info = sn_irq_info->irq_next; } - rcu_read_unlock(); } /* @@ -395,41 +402,19 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) void sn_lb_int_war_check(void) { - struct sn_irq_info *sn_irq_info; int i; if (!sn_ioif_inited || pda->sn_first_irq == 0) return; - - rcu_read_lock(); for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { - list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { - /* - * Only call for PCI bridges that are fully - * initialized. - */ + struct sn_irq_info *sn_irq_info = sn_irq[i]; + while (sn_irq_info) { + /* Only call for PCI bridges that are fully initialized. */ if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) && - (sn_irq_info->irq_bridge != NULL)) + (sn_irq_info->irq_bridge != NULL)) { sn_check_intr(i, sn_irq_info); + } + sn_irq_info = sn_irq_info->irq_next; } } - rcu_read_unlock(); -} - -void sn_irq_lh_init(void) -{ - int i; - - sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL); - if (!sn_irq_lh) - panic("SN PCI INIT: Failed to allocate memory for PCI init\n"); - - for (i = 0; i < NR_IRQS; i++) { - sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL); - if (!sn_irq_lh[i]) - panic("SN PCI INIT: Failed IRQ memory allocation\n"); - - INIT_LIST_HEAD(sn_irq_lh[i]); - } - } diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 7c7fe441d623..22e10d282c7f 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -270,7 +270,7 @@ void __init sn_setup(char **cmdline_p) { long status, ticks_per_sec, drift; int pxm; - u32 version = sn_sal_rev(); + int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); extern void sn_cpu_init(void); ia64_sn_plat_set_error_handling_features(); @@ -308,21 +308,22 @@ void __init sn_setup(char **cmdline_p) * support here so we don't have to listen to failed keyboard probe * messages. */ - if (version <= 0x0209 && acpi_kbd_controller_present) { + if ((major < 2 || (major == 2 && minor <= 9)) && + acpi_kbd_controller_present) { printk(KERN_INFO "Disabling legacy keyboard support as prom " "is too old and doesn't provide FADT\n"); acpi_kbd_controller_present = 0; } - printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); + printk("SGI SAL version %x.%02x\n", major, minor); /* * Confirm the SAL we're running on is recent enough... */ - if (version < SN_SAL_MIN_VERSION) { + if ((major < SN_SAL_MIN_MAJOR) || (major == SN_SAL_MIN_MAJOR && + minor < SN_SAL_MIN_MINOR)) { printk(KERN_ERR "This kernel needs SGI SAL version >= " - "%x.%02x\n", SN_SAL_MIN_VERSION >> 8, - SN_SAL_MIN_VERSION & 0x00FF); + "%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR); panic("PROM version too old\n"); } diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c index c1cbcd1a1398..8716f4d5314b 100644 --- a/trunk/arch/ia64/sn/kernel/tiocx.c +++ b/trunk/arch/ia64/sn/kernel/tiocx.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -482,9 +481,6 @@ static int __init tiocx_init(void) cnodeid_t cnodeid; int found_tiocx_device = 0; - if (!ia64_platform_is("sn2")) - return -ENODEV; - bus_register(&tiocx_bus_type); for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index a2f7a88aefbb..5da9bdbde7cb 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -11,10 +11,9 @@ #include #include -#include +#include #include #include -#include #define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) #define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index d1647b863e61..0e47bce85f2d 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include "pci/pcibr_provider.h" int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index b058dc2a0b9d..64af2b2c1787 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -8,17 +8,18 @@ #include #include -#include +#include #include -#include +#include "xtalk/xwidgetdev.h" +#include "xtalk/hubdev.h" #include #include -#include -#include -#include +#include "pci/tiocp.h" +#include "pci/pic.h" +#include "pci/pcibr_provider.h" +#include "pci/tiocp.h" #include "tio.h" -#include "xtalk/xwidgetdev.h" -#include "xtalk/hubdev.h" +#include extern int sn_ioif_inited; diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 9813da56d311..3893999d23d8 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -6,51 +6,18 @@ * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. */ -#include #include +#include #include -#include -#include -#include -#include -#include #include #include "xtalk/xwidgetdev.h" +#include #include "xtalk/hubdev.h" +#include +#include +#include "pci/pcibr_provider.h" +#include -int -sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) -{ - struct ia64_sal_retval ret_stuff; - uint64_t busnum; - - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - busnum = soft->pbi_buscommon.bs_persist_busnum; - SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum, - (u64) device, (u64) resp, 0, 0, 0, 0); - - return (int)ret_stuff.v0; -} - -int -sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action, - void *resp) -{ - struct ia64_sal_retval ret_stuff; - uint64_t busnum; - - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - busnum = soft->pbi_buscommon.bs_persist_busnum; - SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, - (u64) busnum, (u64) device, (u64) action, - (u64) resp, 0, 0, 0); - - return (int)ret_stuff.v0; -} static int sal_pcibr_error_interrupt(struct pcibus_info *soft) { @@ -221,6 +188,3 @@ pcibr_init_provider(void) return 0; } - -EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable); -EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable); diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 21426d02fbe6..865c11c3b50a 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_reg.c @@ -6,13 +6,13 @@ * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. */ -#include #include -#include +#include #include #include -#include -#include +#include "pci/tiocp.h" +#include "pci/pic.h" +#include "pci/pcibr_provider.h" union br_ptr { struct tiocp tio; diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index 51cc4e63092c..05aa8c2fe9bb 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -589,7 +589,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) /* sanity check prom rev */ - if (sn_sal_rev() < 0x0406) { + if (sn_sal_rev_major() < 4 || + (sn_sal_rev_major() == 4 && sn_sal_rev_minor() < 6)) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " "for tioca support\n", __FUNCTION__); diff --git a/trunk/arch/m32r/kernel/setup_m32700ut.c b/trunk/arch/m32r/kernel/setup_m32700ut.c index a146b24a556b..b014e2c1e524 100644 --- a/trunk/arch/m32r/kernel/setup_m32700ut.c +++ b/trunk/arch/m32r/kernel/setup_m32700ut.c @@ -3,8 +3,8 @@ * * Setup routines for Renesas M32700UT Board * - * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Takeo Takahashi + * Copyright (c) 2002 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Takeo Takahashi * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -435,7 +435,7 @@ void __init init_IRQ(void) icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; enable_m32700ut_irq(M32R_IRQ_INT2); -#if defined(CONFIG_VIDEO_M32R_AR) +//#if defined(CONFIG_VIDEO_M32R_AR) /* * INT3# is used for AR */ @@ -445,11 +445,9 @@ void __init init_IRQ(void) irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; disable_m32700ut_irq(M32R_IRQ_INT3); -#endif /* CONFIG_VIDEO_M32R_AR */ +//#endif /* CONFIG_VIDEO_M32R_AR */ } -#if defined(CONFIG_SMC91X) - #define LAN_IOSTART 0x300 #define LAN_IOEND 0x320 static struct resource smc91x_resources[] = { @@ -471,55 +469,10 @@ static struct platform_device smc91x_device = { .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; -#endif - -#if defined(CONFIG_FB_S1D13XXX) - -#include