## Automatically generated incremental diff ## From: linux-2.5.66-bk3 ## To: linux-2.5.66-bk4 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.5.66-bk3/Documentation/IPMI.txt linux-2.5.66-bk4/Documentation/IPMI.txt --- linux-2.5.66-bk3/Documentation/IPMI.txt Mon Mar 24 13:59:54 2003 +++ linux-2.5.66-bk4/Documentation/IPMI.txt Mon Mar 31 12:49:35 2003 @@ -5,6 +5,18 @@ +The Intelligent Platform Management Interface, or IPMI, is a +standard for controlling intelligent devices that monitor a system. +It provides for dynamic discovery of sensors in the system and the +ability to monitor the sensors and be informed when the sensor's +values change or go outside certain boundaries. It also has a +standardized database for field-replacable units (FRUs) and a watchdog +timer. + +To use this, you need an interface to an IPMI controller in your +system (called a Baseboard Management Controller, or BMC) and +management software that can use the IPMI system. + This document describes how to use the IPMI driver for Linux. If you are not familiar with IPMI itself, see the web site at http://www.intel.com/design/servers/ipmi/index.htm. IPMI is a big diff -urN linux-2.5.66-bk3/Makefile linux-2.5.66-bk4/Makefile --- linux-2.5.66-bk3/Makefile Mon Mar 31 12:49:33 2003 +++ linux-2.5.66-bk4/Makefile Mon Mar 31 12:49:35 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 66 -EXTRAVERSION = -bk3 +EXTRAVERSION = -bk4 # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -urN linux-2.5.66-bk3/arch/ppc/Kconfig linux-2.5.66-bk4/arch/ppc/Kconfig --- linux-2.5.66-bk3/arch/ppc/Kconfig Mon Mar 24 14:01:47 2003 +++ linux-2.5.66-bk4/arch/ppc/Kconfig Mon Mar 31 12:49:35 2003 @@ -666,6 +666,52 @@ here. Saying Y here will not hurt performance (on any machine) but will increase the size of the kernel. +config CPU_FREQ + bool "CPU Frequency scaling" + help + Clock scaling allows you to change the clock speed of CPUs on the + fly. This is a nice method to save battery power on notebooks, + because the lower the clock speed, the less power the CPU consumes. + + For more information, take a look at linux/Documentation/cpufreq or + at + + If in doubt, say N. + +config CPU_FREQ_PROC_INTF + bool "/proc/cpufreq interface (DEPRECATED)" + depends on CPU_FREQ && PROC_FS + help + This enables the /proc/cpufreq interface for controlling + CPUFreq. Please note that it is recommended to use the sysfs + interface instead (which is built automatically). + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +config CPU_FREQ_24_API + bool "/proc/sys/cpu/ interface (2.4. / OLD)" + depends on CPU_FREQ + help + This enables the /proc/sys/cpu/ sysctl interface for controlling + CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5 + uses a sysfs interface instead. Please note that some drivers do + not work well with the 2.4. /proc/sys/cpu sysctl interface, + so if in doubt, say N here. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + +config CPU_FREQ_PMAC + bool "Support for Apple PowerBooks" + depends on CPU_FREQ && ADB_PMU + help + This adds support for frequency switching on Apple PowerBooks, + this currently includes some models of iBook & Titanium + PowerBook. + endmenu menu "General setup" diff -urN linux-2.5.66-bk3/arch/ppc/kernel/Makefile linux-2.5.66-bk4/arch/ppc/kernel/Makefile --- linux-2.5.66-bk3/arch/ppc/kernel/Makefile Mon Mar 24 14:01:24 2003 +++ linux-2.5.66-bk4/arch/ppc/kernel/Makefile Mon Mar 31 12:49:35 2003 @@ -21,7 +21,7 @@ process.o signal.o ptrace.o align.o \ semaphore.o syscalls.o setup.o \ cputable.o ppc_htab.o -obj-$(CONFIG_6xx) += l2cr.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_PCI) += pci-dma.o diff -urN linux-2.5.66-bk3/arch/ppc/kernel/cpu_setup_6xx.S linux-2.5.66-bk4/arch/ppc/kernel/cpu_setup_6xx.S --- linux-2.5.66-bk3/arch/ppc/kernel/cpu_setup_6xx.S Wed Dec 31 16:00:00 1969 +++ linux-2.5.66-bk4/arch/ppc/kernel/cpu_setup_6xx.S Mon Mar 31 12:49:35 2003 @@ -0,0 +1,415 @@ +/* + * This file contains low level CPU setup functions. + * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +_GLOBAL(__setup_cpu_601) + blr +_GLOBAL(__setup_cpu_603) + b setup_common_caches +_GLOBAL(__setup_cpu_604) + mflr r4 + bl setup_common_caches + bl setup_604_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_750) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_750cx) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + bl setup_750cx + mtlr r4 + blr +_GLOBAL(__setup_cpu_750fx) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + bl setup_750fx + mtlr r4 + blr +_GLOBAL(__setup_cpu_7400) + mflr r4 + bl setup_7400_workarounds + bl setup_common_caches + bl setup_750_7400_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_7410) + mflr r4 + bl setup_7410_workarounds + bl setup_common_caches + bl setup_750_7400_hid0 + li r3,0 + mtspr SPRN_L2CR2,r3 + mtlr r4 + blr +_GLOBAL(__setup_cpu_7450) + mflr r4 + bl setup_common_caches + bl setup_745x_specifics + mtlr r4 + blr +_GLOBAL(__setup_cpu_7455) + mflr r4 + bl setup_common_caches + bl setup_745x_specifics + mtlr r4 + blr + +/* Enable caches for 603's, 604, 750 & 7400 */ +setup_common_caches: + mfspr r11,HID0 + andi. r0,r11,HID0_DCE +#ifdef CONFIG_DCACHE_DISABLE + ori r11,r11,HID0_ICE +#else + ori r11,r11,HID0_ICE|HID0_DCE +#endif + ori r8,r11,HID0_ICFI + bne 1f /* don't invalidate the D-cache */ + ori r8,r8,HID0_DCI /* unless it wasn't enabled */ +1: sync + mtspr HID0,r8 /* enable and invalidate caches */ + sync + mtspr HID0,r11 /* enable caches */ + sync + isync + blr + +/* 604, 604e, 604ev, ... + * Enable superscalar execution & branch history table + */ +setup_604_hid0: + mfspr r11,HID0 + ori r11,r11,HID0_SIED|HID0_BHTE + ori r8,r11,HID0_BTCD + sync + mtspr HID0,r8 /* flush branch target address cache */ + sync /* on 604e/604r */ + mtspr HID0,r11 + sync + isync + blr + +/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some + * erratas we work around here. + * Moto MPC710CE.pdf describes them, those are errata + * #3, #4 and #5 + * Note that we assume the firmware didn't choose to + * apply other workarounds (there are other ones documented + * in the .pdf). It appear that Apple firmware only works + * around #3 and with the same fix we use. We may want to + * check if the CPU is using 60x bus mode in which case + * the workaround for errata #4 is useless. Also, we may + * want to explicitely clear HID0_NOPDST as this is not + * needed once we have applied workaround #5 (though it's + * not set by Apple's firmware at least). + */ +setup_7400_workarounds: + mfpvr r3 + rlwinm r3,r3,0,20,31 + cmpwi 0,r3,0x0207 + ble 1f + blr +setup_7410_workarounds: + mfpvr r3 + rlwinm r3,r3,0,20,31 + cmpwi 0,r3,0x0100 + bnelr +1: + mfspr r11,SPRN_MSSSR0 + /* Errata #3: Set L1OPQ_SIZE to 0x10 */ + rlwinm r11,r11,0,9,6 + oris r11,r11,0x0100 + /* Errata #4: Set L2MQ_SIZE to 1 (check for MPX mode first ?) */ + oris r11,r11,0x0002 + /* Errata #5: Set DRLT_SIZE to 0x01 */ + rlwinm r11,r11,0,5,2 + oris r11,r11,0x0800 + sync + mtspr SPRN_MSSSR0,r11 + sync + isync + blr + +/* 740/750/7400/7410 + * Enable Store Gathering (SGE), Address Brodcast (ABE), + * Branch History Table (BHTE), Branch Target ICache (BTIC) + * Dynamic Power Management (DPM), Speculative (SPD) + * Clear Instruction cache throttling (ICTC) + */ +setup_750_7400_hid0: + mfspr r11,HID0 + ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC +BEGIN_FTR_SECTION + oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ +END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + li r3,HID0_SPD + andc r11,r11,r3 /* clear SPD: enable speculative */ + li r3,0 + mtspr ICTC,r3 /* Instruction Cache Throttling off */ + isync + mtspr HID0,r11 + sync + isync + blr + +/* 750cx specific + * Looks like we have to disable NAP feature for some PLL settings... + * (waiting for confirmation) + */ +setup_750cx: + mfspr r10, SPRN_HID1 + rlwinm r10,r10,4,28,31 + cmpi cr0,r10,7 + cmpi cr1,r10,9 + cmpi cr2,r10,11 + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + cror 4*cr0+eq,4*cr0+eq,4*cr2+eq + bnelr + lwz r6,CPU_SPEC_FEATURES(r5) + li r7,CPU_FTR_CAN_NAP + andc r6,r6,r7 + stw r6,CPU_SPEC_FEATURES(r5) + blr + +/* 750fx specific + */ +setup_750fx: + blr + +/* MPC 745x + * Enable Store Gathering (SGE), Branch Folding (FOLD) + * Branch History Table (BHTE), Branch Target ICache (BTIC) + * Dynamic Power Management (DPM), Speculative (SPD) + * Ensure our data cache instructions really operate. + * Timebase has to be running or we wouldn't have made it here, + * just ensure we don't disable it. + * Clear Instruction cache throttling (ICTC) + * Enable L2 HW prefetch + */ +setup_745x_specifics: + /* We check for the presence of an L3 cache setup by + * the firmware. If any, we disable NAP capability as + * it's known to be bogus on rev 2.1 and earlier + */ + mfspr r11,SPRN_L3CR + andis. r11,r11,L3CR_L3E@h + beq 1f + lwz r6,CPU_SPEC_FEATURES(r5) + andi. r0,r6,CPU_FTR_L3_DISABLE_NAP + beq 1f + li r7,CPU_FTR_CAN_NAP + andc r6,r6,r7 + stw r6,CPU_SPEC_FEATURES(r5) +1: + mfspr r11,HID0 + + /* All of the bits we have to set..... + */ + ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK +BEGIN_FTR_SECTION + oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ +END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + + /* All of the bits we have to clear.... + */ + li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI + andc r11,r11,r3 /* clear SPD: enable speculative */ + li r3,0 + + mtspr ICTC,r3 /* Instruction Cache Throttling off */ + isync + mtspr HID0,r11 + sync + isync + + /* Enable L2 HW prefetch + */ + mfspr r3,SPRN_MSSCR0 + ori r3,r3,3 + sync + mtspr SPRN_MSSCR0,r3 + sync + isync + blr + +/* Definitions for the table use to save CPU states */ +#define CS_HID0 0 +#define CS_HID1 4 +#define CS_MSSCR0 8 +#define CS_MSSSR0 12 +#define CS_ICTRL 16 +#define CS_LDSTCR 20 +#define CS_LDSTDB 24 +#define CS_SIZE 28 + + .data + .balign 4 +cpu_state_storage: + .space CS_SIZE + .text + +/* Called in normal context to backup CPU 0 state. This + * does not include cache settings. This function is also + * called for machine sleep. This does not include the MMU + * setup, BATs, etc... but rather the "special" registers + * like HID0, HID1, MSSCR0, etc... + */ +_GLOBAL(__save_cpu_setup) + /* Get storage ptr */ + lis r5,cpu_state_storage@h + ori r5,r5,cpu_state_storage@l + + /* Save HID0 (common to all CONFIG_6xx cpus) */ + mfspr r3,SPRN_HID0 + stw r3,CS_HID0(r5) + + /* Now deal with CPU type dependent registers */ + mfspr r3,PVR + srwi r3,r3,16 + cmpli cr0,r3,0x8000 /* 7450 */ + cmpli cr1,r3,0x000c /* 7400 */ + cmpli cr2,r3,0x800c /* 7410 */ + cmpli cr3,r3,0x8001 /* 7455 */ + cmpli cr4,r3,0x8002 /* 7457 */ + cmpli cr5,r3,0x7000 /* 750FX */ + /* cr1 is 7400 || 7410 */ + cror 4*cr1+eq,4*cr1+eq,4*cr2+eq + /* cr0 is 74xx */ + cror 4*cr0+eq,4*cr0+eq,4*cr3+eq + cror 4*cr0+eq,4*cr0+eq,4*cr4+eq + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + bne 1f + /* Backup 74xx specific regs */ + mfspr r4,SPRN_MSSCR0 + stw r4,CS_MSSCR0(r5) + mfspr r4,SPRN_MSSSR0 + stw r4,CS_MSSSR0(r5) + beq cr1,1f + /* Backup 745x specific registers */ + mfspr r4,SPRN_HID1 + stw r4,CS_HID1(r5) + mfspr r4,SPRN_ICTRL + stw r4,CS_ICTRL(r5) + mfspr r4,SPRN_LDSTCR + stw r4,CS_LDSTCR(r5) + mfspr r4,SPRN_LDSTDB + stw r4,CS_LDSTDB(r5) +1: + bne cr5,1f + /* Backup 750FX specific registers */ + mfspr r4,SPRN_HID1 + stw r4,CS_HID1(r5) +1: + blr + +/* Called with no MMU context (typically MSR:IR/DR off) to + * restore CPU state as backed up by the previous + * function. This does not include cache setting + */ +_GLOBAL(__restore_cpu_setup) + /* Get storage ptr */ + lis r5,(cpu_state_storage-KERNELBASE)@h + ori r5,r5,cpu_state_storage@l + + /* Restore HID0 */ + lwz r3,CS_HID0(r5) + sync + isync + mtspr SPRN_HID0,r3 + sync + isync + + /* Now deal with CPU type dependent registers */ + mfspr r3,PVR + srwi r3,r3,16 + cmpli cr0,r3,0x8000 /* 7450 */ + cmpli cr1,r3,0x000c /* 7400 */ + cmpli cr2,r3,0x800c /* 7410 */ + cmpli cr3,r3,0x8001 /* 7455 */ + cmpli cr4,r3,0x8002 /* 7457 */ + cmpli cr5,r3,0x7000 /* 750FX */ + /* cr1 is 7400 || 7410 */ + cror 4*cr1+eq,4*cr1+eq,4*cr2+eq + /* cr0 is 74xx */ + cror 4*cr0+eq,4*cr0+eq,4*cr3+eq + cror 4*cr0+eq,4*cr0+eq,4*cr4+eq + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + bne 2f + /* Restore 74xx specific regs */ + lwz r4,CS_MSSCR0(r5) + sync + mtspr SPRN_MSSCR0,r4 + sync + isync + lwz r4,CS_MSSSR0(r5) + sync + mtspr SPRN_MSSSR0,r4 + sync + isync + bne cr2,1f + /* Clear 7410 L2CR2 */ + li r4,0 + mtspr SPRN_L2CR2,r4 +1: beq cr1,2f + /* Restore 745x specific registers */ + lwz r4,CS_HID1(r5) + sync + mtspr SPRN_HID1,r4 + isync + sync + lwz r4,CS_ICTRL(r5) + sync + mtspr SPRN_ICTRL,r4 + isync + sync + lwz r4,CS_LDSTCR(r5) + sync + mtspr SPRN_LDSTCR,r4 + isync + sync + lwz r4,CS_LDSTDB(r5) + sync + mtspr SPRN_LDSTDB,r4 + isync + sync +2: bne cr5,1f + /* Restore 750FX specific registers + * that is restore PLL config & switch + * to PLL 0 + */ + lwz r4,CS_HID1(r5) + rlwinm r5,r4,0,16,14 + mtspr SPRN_HID1,r5 + /* Wait for PLL to stabilize */ + mftbl r5 +3: mftbl r6 + sub r6,r6,r5 + cmpli cr0,r6,10000 + ble 3b + /* Setup final PLL */ + mtspr SPRN_HID1,r4 +1: + blr + diff -urN linux-2.5.66-bk3/arch/ppc/kernel/head.S linux-2.5.66-bk4/arch/ppc/kernel/head.S --- linux-2.5.66-bk3/arch/ppc/kernel/head.S Mon Mar 24 14:00:45 2003 +++ linux-2.5.66-bk4/arch/ppc/kernel/head.S Mon Mar 31 12:49:35 2003 @@ -890,7 +890,7 @@ */ mfmsr r5 oris r5,r5,MSR_VEC@h - mtmsr r5 /* enable use of AltiVec now */ + MTMSRD(r5) /* enable use of AltiVec now */ isync /* * For SMP, we don't do lazy AltiVec switching because it just gets too @@ -962,7 +962,7 @@ mfmsr r5 oris r5,r5,MSR_VEC@h SYNC - mtmsr r5 /* enable use of AltiVec now */ + MTMSRD(r5) /* enable use of AltiVec now */ isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ @@ -999,7 +999,7 @@ ori r5,r5,MSR_FP SYNC_601 ISYNC_601 - mtmsr r5 /* enable use of fpu now */ + MTMSRD(r5) /* enable use of fpu now */ SYNC_601 isync cmpi 0,r3,0 @@ -1191,6 +1191,8 @@ MTMSRD(r0) isync #endif + /* Copy some CPU settings from CPU 0 */ + bl __restore_cpu_setup lis r3,-KERNELBASE@h mr r4,r24 @@ -1236,248 +1238,21 @@ #endif /* CONFIG_SMP */ /* - * Enable caches and 604-specific features if necessary. + * Those generic dummy functions are kept for CPUs not + * included in CONFIG_6xx */ -_GLOBAL(__setup_cpu_601) - blr -_GLOBAL(__setup_cpu_603) - b setup_common_caches -_GLOBAL(__setup_cpu_604) - mflr r4 - bl setup_common_caches - bl setup_604_hid0 - mtlr r4 - blr -_GLOBAL(__setup_cpu_750) - mflr r4 - bl setup_common_caches - bl setup_750_7400_hid0 - mtlr r4 - blr -_GLOBAL(__setup_cpu_750cx) - mflr r4 - bl setup_common_caches - bl setup_750_7400_hid0 - bl setup_750cx - mtlr r4 - blr -_GLOBAL(__setup_cpu_750fx) - mflr r4 - bl setup_common_caches - bl setup_750_7400_hid0 - bl setup_750fx - mtlr r4 - blr -_GLOBAL(__setup_cpu_7400) - mflr r4 - bl setup_7400_workarounds - bl setup_common_caches - bl setup_750_7400_hid0 - mtlr r4 - blr -_GLOBAL(__setup_cpu_7410) - mflr r4 - bl setup_7410_workarounds - bl setup_common_caches - bl setup_750_7400_hid0 - li r3,0 - mtspr SPRN_L2CR2,r3 - mtlr r4 - blr -_GLOBAL(__setup_cpu_7450) - mflr r4 - bl setup_common_caches - bl setup_745x_specifics - mtlr r4 - blr -_GLOBAL(__setup_cpu_7455) - mflr r4 - bl setup_common_caches - bl setup_745x_specifics - mtlr r4 - blr _GLOBAL(__setup_cpu_power3) blr _GLOBAL(__setup_cpu_generic) blr -/* Enable caches for 603's, 604, 750 & 7400 */ -setup_common_caches: - mfspr r11,HID0 - andi. r0,r11,HID0_DCE -#ifdef CONFIG_DCACHE_DISABLE - ori r11,r11,HID0_ICE -#else - ori r11,r11,HID0_ICE|HID0_DCE -#endif - ori r8,r11,HID0_ICFI - bne 1f /* don't invalidate the D-cache */ - ori r8,r8,HID0_DCI /* unless it wasn't enabled */ -1: sync - mtspr HID0,r8 /* enable and invalidate caches */ - sync - mtspr HID0,r11 /* enable caches */ - sync - isync - blr - -/* 604, 604e, 604ev, ... - * Enable superscalar execution & branch history table - */ -setup_604_hid0: - mfspr r11,HID0 - ori r11,r11,HID0_SIED|HID0_BHTE - ori r8,r11,HID0_BTCD - sync - mtspr HID0,r8 /* flush branch target address cache */ - sync /* on 604e/604r */ - mtspr HID0,r11 - sync - isync - blr - -/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some - * errata we work around here. - * Moto MPC710CE.pdf describes them, those are errata - * #3, #4 and #5 - * Note that we assume the firmware didn't choose to - * apply other workarounds (there are other ones documented - * in the .pdf). It appear that Apple firmware only works - * around #3 and with the same fix we use. We may want to - * check if the CPU is using 60x bus mode in which case - * the workaround for errata #4 is useless. Also, we may - * want to explicitely clear HID0_NOPDST as this is not - * needed once we have applied workaround #5 (though it's - * not set by Apple's firmware at least). - */ -setup_7400_workarounds: - mfpvr r3 - rlwinm r3,r3,0,20,31 - cmpwi 0,r3,0x0207 - ble 1f - blr -setup_7410_workarounds: - mfpvr r3 - rlwinm r3,r3,0,20,31 - cmpwi 0,r3,0x0100 - bnelr -1: - mfspr r11,SPRN_MSSSR0 - /* Errata #3: Set L1OPQ_SIZE to 0x10 */ - rlwinm r11,r11,0,9,6 - oris r11,r11,0x0100 - /* Errata #4: Set L2MQ_SIZE to 1 (check for MPX mode first ?) */ - oris r11,r11,0x0002 - /* Errata #5: Set DRLT_SIZE to 0x01 */ - rlwinm r11,r11,0,5,2 - oris r11,r11,0x0800 - sync - mtspr SPRN_MSSSR0,r11 - sync - isync - blr - -/* 740/750/7400/7410 - * Enable Store Gathering (SGE), Address Brodcast (ABE), - * Branch History Table (BHTE), Branch Target ICache (BTIC) - * Dynamic Power Management (DPM), Speculative (SPD) - * Clear Instruction cache throttling (ICTC) - */ -setup_750_7400_hid0: - mfspr r11,HID0 - ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC -BEGIN_FTR_SECTION - oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ -END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) - li r3,HID0_SPD - andc r11,r11,r3 /* clear SPD: enable speculative */ - li r3,0 - mtspr ICTC,r3 /* Instruction Cache Throttling off */ - isync - mtspr HID0,r11 - sync - isync - blr - -/* 750cx specific - * Looks like we have to disable NAP feature for some PLL settings... - * (waiting for confirmation) - */ -setup_750cx: - mfspr r10, SPRN_HID1 - rlwinm r10,r10,4,28,31 - cmpi cr0,r10,7 - cmpi cr1,r10,9 - cmpi cr2,r10,11 - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - cror 4*cr0+eq,4*cr0+eq,4*cr2+eq - bnelr - lwz r6,CPU_SPEC_FEATURES(r5) - li r7,CPU_FTR_CAN_NAP - andc r6,r6,r7 - stw r6,CPU_SPEC_FEATURES(r5) +#ifndef CONFIG_6xx +_GLOBAL(__save_cpu_setup) blr - -/* 750fx specific - */ -setup_750fx: +_GLOBAL(__restore_cpu_setup) blr +#endif /* CONFIG_6xx */ -/* MPC 745x - * Enable Store Gathering (SGE), Branch Folding (FOLD) - * Branch History Table (BHTE), Branch Target ICache (BTIC) - * Dynamic Power Management (DPM), Speculative (SPD) - * Ensure our data cache instructions really operate. - * Timebase has to be running or we wouldn't have made it here, - * just ensure we don't disable it. - * Clear Instruction cache throttling (ICTC) - * Enable L2 HW prefetch - */ -setup_745x_specifics: - /* We check for the presence of an L3 cache setup by - * the firmware. If any, we disable NAP capability as - * it's known to be bogus on rev 2.1 and earlier - */ - mfspr r11,SPRN_L3CR - andis. r11,r11,L3CR_L3E@h - beq 1f - lwz r6,CPU_SPEC_FEATURES(r5) - andi. r0,r6,CPU_FTR_L3_DISABLE_NAP - beq 1f - li r7,CPU_FTR_CAN_NAP - andc r6,r6,r7 - stw r6,CPU_SPEC_FEATURES(r5) -1: - mfspr r11,HID0 - - /* All of the bits we have to set..... - */ - ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK -BEGIN_FTR_SECTION - oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ -END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) - - /* All of the bits we have to clear.... - */ - li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI - andc r11,r11,r3 /* clear SPD: enable speculative */ - li r3,0 - - mtspr ICTC,r3 /* Instruction Cache Throttling off */ - isync - mtspr HID0,r11 - sync - isync - - /* Enable L2 HW prefetch - */ - mfspr r3,SPRN_MSSCR0 - ori r3,r3,3 - sync - mtspr SPRN_MSSCR0,r3 - sync - isync - blr /* * Load stuff into the MMU. Intended to be called with diff -urN linux-2.5.66-bk3/arch/ppc/kernel/misc.S linux-2.5.66-bk4/arch/ppc/kernel/misc.S --- linux-2.5.66-bk3/arch/ppc/kernel/misc.S Mon Mar 24 14:01:25 2003 +++ linux-2.5.66-bk4/arch/ppc/kernel/misc.S Mon Mar 31 12:49:35 2003 @@ -201,6 +201,60 @@ mr r4,r24 bctr +#ifdef CONFIG_CPU_FREQ_PMAC + +/* This gets called by via-pmu.c to switch the PLL selection + * on 750fx CPU. This function should really be moved to some + * other place (as most of the cpufreq code in via-pmu + */ +_GLOBAL(low_choose_750fx_pll) + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* If switching to PLL1, disable HID0:BTIC */ + cmpli cr0,r3,0 + beq 1f + mfspr r5,HID0 + rlwinm r5,r5,0,27,25 + sync + mtspr HID0,r5 + isync + sync + +1: + /* Calc new HID1 value */ + mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */ + rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */ + rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */ + or r4,r4,r5 + mtspr SPRN_HID1,r4 + + /* Store new HID1 image */ + rlwinm r6,r1,0,0,18 + lwz r6,TI_CPU(r6) + slwi r6,r6,2 + addis r6,r6,nap_save_hid1@ha + stw r4,nap_save_hid1@l(r6) + + /* If switching to PLL0, enable HID0:BTIC */ + cmpli cr0,r3,0 + bne 1f + mfspr r5,HID0 + ori r5,r5,HID0_BTIC + sync + mtspr HID0,r5 + isync + sync + +1: + /* Return */ + mtmsr r7 + blr + +#endif /* CONFIG_CPU_FREQ_PMAC */ + /* void local_save_flags_ptr(unsigned long *flags) */ _GLOBAL(local_save_flags_ptr) mfmsr r4 @@ -351,7 +405,16 @@ sync /* Flush to memory before changing mapping */ tlbia isync /* Flush shadow TLB */ -#else /* ! defined(CONFIG_40x) */ +#elif defined(CONFIG_440) + lis r3,0 + sync +1: + tlbwe r3,r3,PPC440_TLB_PAGEID + addi r3,r3,1 + cmpwi 0,r3,61 + ble 1b + isync +#else /* !(CONFIG_40x || CONFIG_440) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -392,7 +455,7 @@ * Flush MMU TLB for a particular address */ _GLOBAL(_tlbie) -#ifdef CONFIG_40x +#if defined(CONFIG_40x) tlbsx. r3, 0, r3 bne 10f sync @@ -402,7 +465,31 @@ tlbwe r3, r3, TLB_TAG isync 10: -#else /* ! CONFIG_40x */ +#elif defined(CONFIG_440) + mfspr r4,SPRN_MMUCR /* Get MMUCR */ + lis r5,PPC440_MMUCR_STS@h + ori r5,r5,PPC440_MMUCR_TID@l /* Create mask */ + andc r4,r4,r5 /* Clear out TID/STS bits */ + mfspr r5,SPRN_PID /* Get PID */ + or r4,r4,r5 /* Set TID bits */ + mfmsr r6 /* Get MSR */ + andi. r6,r6,MSR_IS@l /* TS=1? */ + beq 11f /* If not, leave STS=0 */ + oris r4,r4,PPC440_MMUCR_STS@h /* Set STS=1 */ +11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */ + + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, + * which means bit 22, is clear. Since 22 is + * the V bit in the TLB_PAGEID, loading this + * value will invalidate the TLB entry. + */ + tlbwe r3, r3, PPC440_TLB_PAGEID + isync +10: +#else /* !(CONFIG_40x || CONFIG_440) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -569,22 +656,18 @@ blr #ifdef CONFIG_NOT_COHERENT_CACHE -/* This is a bad one....It is used by 'consistent_sync' functions when - * there isn't any handle on the virtual address needed by the usual - * cache flush instructions. On the MPC8xx, we can use the cache line - * flush command, on others all we can do is read enough data to completely - * reload the cache, flushing old data out. - */ - -/* Cache organization. The 4xx has a 8K (128 line) cache, and the 8xx - * has 1, 2, 4, 8K variants. For now, cover worst case. When we can - * deteremine actual size, we will use that later. +/* + * 40x cores have 8K or 16K dcache and 32 byte line size. + * 440 has a 32K dcache and 32 byte line size. + * 8xx has 1, 2, 4, 8K variants. + * For now, cover the worst case of the 440. + * Must be called with external interrupts disabled. */ -#define CACHE_NWAYS 2 -#define CACHE_NLINES 128 +#define CACHE_NWAYS 64 +#define CACHE_NLINES 16 _GLOBAL(flush_dcache_all) - li r4, (CACHE_NWAYS * CACHE_NLINES) + li r4, (2 * CACHE_NWAYS * CACHE_NLINES) mtctr r4 lis r5, KERNELBASE@h 1: lwz r3, 0(r5) /* Load one word from every line */ diff -urN linux-2.5.66-bk3/arch/ppc/kernel/smp.c linux-2.5.66-bk4/arch/ppc/kernel/smp.c --- linux-2.5.66-bk3/arch/ppc/kernel/smp.c Mon Mar 24 14:01:43 2003 +++ linux-2.5.66-bk4/arch/ppc/kernel/smp.c Mon Mar 31 12:49:35 2003 @@ -68,6 +68,9 @@ static int __smp_call_function(void (*func) (void *info), void *info, int wait, int target); +/* Low level assembly function used to backup CPU 0 state */ +extern void __save_cpu_setup(void); + /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up @@ -349,6 +352,9 @@ num_cpus = smp_ops->probe(); cpu_possible_map = (1 << num_cpus)-1; + /* Backup CPU 0 state */ + __save_cpu_setup(); + if (smp_ops->space_timers) smp_ops->space_timers(num_cpus); } diff -urN linux-2.5.66-bk3/arch/ppc/platforms/Makefile linux-2.5.66-bk4/arch/ppc/platforms/Makefile --- linux-2.5.66-bk3/arch/ppc/platforms/Makefile Mon Mar 24 14:01:52 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/Makefile Mon Mar 31 12:49:35 2003 @@ -19,12 +19,14 @@ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o \ pmac_feature.o pmac_pci.o chrp_setup.o\ chrp_time.o chrp_pci.o prep_pci.o \ - prep_time.o prep_setup.o + prep_time.o prep_setup.o pmac_sleep.o ifeq ($(CONFIG_ALL_PPC),y) obj-$(CONFIG_NVRAM) += pmac_nvram.o endif obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o -obj-$(CONFIG_PMAC_PBOOK) += sleep.o +ifeq ($(CONFIG_ALL_PPC),y) +obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o +endif obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o obj-$(CONFIG_PREP_RESIDUAL) += residual.o obj-$(CONFIG_ADIR) += adir_setup.o adir_pic.o adir_pci.o diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_cpufreq.c linux-2.5.66-bk4/arch/ppc/platforms/pmac_cpufreq.c --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_cpufreq.c Wed Dec 31 16:00:00 1969 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_cpufreq.c Mon Mar 31 12:49:35 2003 @@ -0,0 +1,345 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG_FREQ + +extern void low_choose_750fx_pll(int pll); +extern void low_sleep_handler(void); +extern void openpic_sleep_save_intrs(void); +extern void openpic_sleep_restore_intrs(void); +extern void enable_kernel_altivec(void); +extern void enable_kernel_fp(void); + +static unsigned int low_freq; +static unsigned int hi_freq; +static unsigned int cur_freq; +static int cpufreq_uses_pmu; + +#define PMAC_CPU_LOW_SPEED 1 +#define PMAC_CPU_HIGH_SPEED 0 + +static inline void +wakeup_decrementer(void) +{ + set_dec(tb_ticks_per_jiffy); + /* No currently-supported powerbook has a 601, + * so use get_tbl, not native + */ + last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); +} + +#ifdef DEBUG_FREQ +static inline void +debug_calc_bogomips(void) +{ + /* This will cause a recalc of bogomips and display the + * result. We backup/restore the value to avoid affecting the + * core cpufreq framework's own calculation. + */ + extern void calibrate_delay(void); + + unsigned long save_lpj = loops_per_jiffy; + calibrate_delay(); + loops_per_jiffy = save_lpj; +} +#endif + +/* Switch CPU speed under 750FX CPU control + */ +static int __pmac +cpu_750fx_cpu_speed(int low_speed) +{ +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); +#endif + low_choose_750fx_pll(low_speed); +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); + debug_calc_bogomips(); +#endif + + return 0; +} + +/* Switch CPU speed under PMU control + */ +static int __pmac +pmu_set_cpu_speed(unsigned int low_speed) +{ + struct adb_request req; + unsigned long save_l2cr; + unsigned long save_l3cr; + +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); +#endif + /* Disable all interrupt sources on openpic */ + openpic_sleep_save_intrs(); + + /* Make sure the PMU is idle */ + pmu_suspend(); + + /* Make sure the decrementer won't interrupt us */ + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + /* Make sure any pending DEC interrupt occuring while we did + * the above didn't re-enable the DEC */ + mb(); + asm volatile("mtdec %0" : : "r" (0x7fffffff)); + + /* We can now disable MSR_EE */ + local_irq_disable(); + + /* Giveup the FPU & vec */ + enable_kernel_fp(); + +#ifdef CONFIG_ALTIVEC + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC) + enable_kernel_altivec(); +#endif /* CONFIG_ALTIVEC */ + + /* Save & disable L2 and L3 caches */ + save_l3cr = _get_L3CR(); /* (returns -1 if not available) */ + save_l2cr = _get_L2CR(); /* (returns -1 if not available) */ + if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0) + _set_L3CR(save_l3cr & 0x7fffffff); + if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) + _set_L2CR(save_l2cr & 0x7fffffff); + + /* Send the new speed command. My assumption is that this command + * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep + */ + pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed); + while (!req.complete) + pmu_poll(); + + pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1); + + low_sleep_handler(); + + pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0); + + /* Restore L2 cache */ + if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0) + _set_L2CR(save_l2cr); + /* Restore L3 cache */ + if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0) + _set_L3CR(save_l3cr); + + /* Restore userland MMU context */ + set_context(current->active_mm->context, current->active_mm->pgd); + +#ifdef DEBUG_FREQ + printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); +#endif + + /* Restore decrementer */ + wakeup_decrementer(); + + /* Restore interrupts */ + openpic_sleep_restore_intrs(); + + pmu_resume(); + + /* Let interrupts flow again ... */ + local_irq_enable(); + +#ifdef DEBUG_FREQ + debug_calc_bogomips(); +#endif + + return 0; +} + +static int __pmac +do_set_cpu_speed(int speed_mode) +{ + struct cpufreq_freqs freqs; + int rc; + + freqs.old = cur_freq; + freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; + freqs.cpu = CPUFREQ_ALL_CPUS; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + if (cpufreq_uses_pmu) + rc = pmu_set_cpu_speed(speed_mode); + else + rc = cpu_750fx_cpu_speed(speed_mode); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; + + return rc; +} + +static int __pmac +pmac_cpufreq_verify(struct cpufreq_policy *policy) +{ + if (!policy) + return -EINVAL; + + policy->cpu = 0; /* UP only */ + + cpufreq_verify_within_limits(policy, low_freq, hi_freq); + + if ((policy->min > low_freq) && + (policy->max < hi_freq)) + policy->max = hi_freq; + + return 0; +} + +static int __pmac +pmac_cpufreq_setpolicy(struct cpufreq_policy *policy) +{ + int rc; + + if (!policy) + return -EINVAL; + if (policy->min > low_freq) + rc = do_set_cpu_speed(PMAC_CPU_HIGH_SPEED); + else if (policy->max < hi_freq) + rc = do_set_cpu_speed(PMAC_CPU_LOW_SPEED); + else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) + rc = do_set_cpu_speed(PMAC_CPU_LOW_SPEED); + else + rc = do_set_cpu_speed(PMAC_CPU_HIGH_SPEED); + + return rc; +} + +unsigned int __pmac +pmac_get_one_cpufreq(int i) +{ + /* Supports only one CPU for now */ + return (i == 0) ? cur_freq : 0; +} + + +/* Currently, we support the following machines: + * + * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz) + * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz) + * - iBook2 500 (PMU based, 400Mhz & 500Mhz) + * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage) + */ +static int __init +pmac_cpufreq_setup(void) +{ + struct device_node *cpunode; + struct cpufreq_driver *driver; + u32 *value; + int has_freq_ctl = 0; + int rc; + + memset(&driver, 0, sizeof(driver)); + + /* Assume only one CPU */ + cpunode = find_type_devices("cpu"); + if (!cpunode) + goto out; + + /* Get current cpu clock freq */ + value = (u32 *)get_property(cpunode, "clock-frequency", NULL); + if (!value) + goto out; + cur_freq = (*value) / 1000; + + /* Check for tibook 800Mhz or 1Ghz */ + if (machine_is_compatible("PowerBook3,4") || machine_is_compatible("PowerBook3,5")) { + value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); + if (!value) + goto out; + low_freq = (*value) / 1000; + + value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); + if (!value) + goto out; + hi_freq = (*value) / 1000; + has_freq_ctl = 1; + cpufreq_uses_pmu = 1; + } + /* Else check for iBook2 500 */ + else if (machine_is_compatible("PowerBook4,1")) { + /* We only know about 500Mhz model */ + if (cur_freq < 450000 || cur_freq > 550000) + goto out; + hi_freq = cur_freq; + low_freq = 400000; + has_freq_ctl = 1; + cpufreq_uses_pmu = 1; + } + /* Else check for TiPb 500 */ + else if (machine_is_compatible("PowerBook3,2")) { + /* We only know about 500Mhz model */ + if (cur_freq < 450000 || cur_freq > 550000) + goto out; + hi_freq = cur_freq; + low_freq = 300000; + has_freq_ctl = 1; + cpufreq_uses_pmu = 1; + } + /* Else check for 750FX */ + else if (PVR_VER(mfspr(PVR)) == 0x7000) { + if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) + goto out; + hi_freq = cur_freq; + value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); + if (!value) + goto out; + low_freq = (*value) / 1000; + cpufreq_uses_pmu = 0; + has_freq_ctl = 1; + } +out: + if (!has_freq_ctl) + return -ENODEV; + + /* initialization of main "cpufreq" code*/ + driver = kmalloc(sizeof(struct cpufreq_driver) + + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); + if (!driver) + return -ENOMEM; + + driver->policy = (struct cpufreq_policy *) (driver + 1); + + driver->verify = &pmac_cpufreq_verify; + driver->setpolicy = &pmac_cpufreq_setpolicy; + driver->init = NULL; + driver->exit = NULL; + strncpy(driver->name, "powermac", CPUFREQ_NAME_LEN); + + driver->policy[0].cpu = 0; + driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL; + driver->policy[0].cpuinfo.min_freq = low_freq; + driver->policy[0].min = low_freq; + driver->policy[0].max = cur_freq; + driver->policy[0].cpuinfo.max_freq = cur_freq; + driver->policy[0].policy = (cur_freq == low_freq) ? + CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE; + + rc = cpufreq_register_driver(driver); + if (rc) + kfree(driver); + return rc; +} + +__initcall(pmac_cpufreq_setup); + diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_feature.c linux-2.5.66-bk4/arch/ppc/platforms/pmac_feature.c --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_feature.c Mon Mar 24 14:01:25 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_feature.c Mon Mar 31 12:49:35 2003 @@ -14,6 +14,8 @@ * - Replace mdelay with some schedule loop if possible * - Shorten some obfuscated delays on some routines (like modem * power) + * - Refcount some clocks (see darwin) + * - Split split split... * */ #include @@ -25,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -34,8 +38,10 @@ #include #include #include +#include #include #include +#include #undef DEBUG_FEATURE @@ -46,7 +52,8 @@ #endif /* Exported from arch/ppc/kernel/idle.c */ -extern unsigned long powersave_nap; +extern int powersave_nap; +extern int powersave_lowspeed; /* * We use a single global lock to protect accesses. Each driver has @@ -57,53 +64,13 @@ #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); + /* - * Helper functions regarding the various flavors of mac-io + * Instance of some macio stuffs */ - -#define MAX_MACIO_CHIPS 2 +struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata; -enum { - macio_unknown = 0, - macio_grand_central, - macio_ohare, - macio_ohareII, - macio_heathrow, - macio_gatwick, - macio_paddington, - macio_keylargo, - macio_pangea -}; - -static const char* macio_names[] __pmacdata = -{ - "Unknown", - "Grand Central", - "OHare", - "OHareII", - "Heathrow", - "Gatwick", - "Paddington", - "Keylargo", - "Pangea" -}; - -static struct macio_chip -{ - struct device_node* of_node; - int type; - int rev; - volatile u32* base; - unsigned long flags; -} macio_chips[MAX_MACIO_CHIPS] __pmacdata; - -#define MACIO_FLAG_SCCA_ON 0x00000001 -#define MACIO_FLAG_SCCB_ON 0x00000002 -#define MACIO_FLAG_SCC_LOCKED 0x00000004 -#define MACIO_FLAG_AIRPORT_ON 0x00000010 -#define MACIO_FLAG_FW_SUPPORTED 0x00000020 - -static struct macio_chip* __pmac +struct macio_chip* __pmac macio_find(struct device_node* child, int type) { while(child) { @@ -118,15 +85,21 @@ return NULL; } -#define MACIO_FCR32(macio, r) ((macio)->base + ((r) >> 2)) -#define MACIO_FCR8(macio, r) (((volatile u8*)((macio)->base)) + (r)) +static const char* macio_names[] __pmacdata = +{ + "Unknown", + "Grand Central", + "OHare", + "OHareII", + "Heathrow", + "Gatwick", + "Paddington", + "Keylargo", + "Pangea", + "Intrepid" +}; + -#define MACIO_IN32(r) (in_le32(MACIO_FCR32(macio,r))) -#define MACIO_OUT32(r,v) (out_le32(MACIO_FCR32(macio,r), (v))) -#define MACIO_BIS(r,v) (MACIO_OUT32((r), MACIO_IN32(r) | (v))) -#define MACIO_BIC(r,v) (MACIO_OUT32((r), MACIO_IN32(r) & ~(v))) -#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r))) -#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v))) /* * Uninorth reg. access. Note that Uni-N regs are big endian @@ -196,7 +169,7 @@ unsigned long chan_mask; unsigned long fcr; unsigned long flags; - int htw; + int htw, trans; unsigned long rmask; macio = macio_find(node, 0); @@ -211,6 +184,9 @@ htw = (macio->type == macio_heathrow || macio->type == macio_paddington || macio->type == macio_gatwick); + /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */ + trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && + pmac_mb.model_id != PMAC_TYPE_YIKES); if (value) { #ifdef CONFIG_ADB_PMU if ((param & 0xfff) == PMAC_SCC_IRDA) @@ -222,7 +198,13 @@ if (!(fcr & OH_SCC_ENABLE)) { fcr |= OH_SCC_ENABLE; if (htw) { - fcr &= ~HRW_SCC_TRANS_EN_N; + /* Side effect: this will also power up the + * modem, but it's too messy to figure out on which + * ports this controls the tranceiver and on which + * it controls the modem + */ + if (trans) + fcr &= ~HRW_SCC_TRANS_EN_N; MACIO_OUT32(OHARE_FCR, fcr); fcr |= (rmask = HRW_RESET_SCC); MACIO_OUT32(OHARE_FCR, fcr); @@ -258,7 +240,7 @@ MACIO_OUT32(OHARE_FCR, fcr); if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) { fcr &= ~OH_SCC_ENABLE; - if (htw) + if (htw && trans) fcr |= HRW_SCC_TRANS_EN_N; MACIO_OUT32(OHARE_FCR, fcr); } @@ -330,9 +312,9 @@ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) return -EPERM; - if (value) { + if (value == 1) { MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE); - } else { + } else if (value == 0) { MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); } @@ -522,7 +504,7 @@ return 0; } -static u32 save_fcr[5] __pmacdata; +static u32 save_fcr[6] __pmacdata; static u32 save_mbcr __pmacdata; static u32 save_gpio_levels[2] __pmacdata; static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata; @@ -586,6 +568,7 @@ /* This seems to be necessary as well or the fan * keeps coming up and battery drains fast */ MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE); + MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N); /* Make sure eth is down even if module or sleep * won't work properly */ MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET); @@ -750,7 +733,13 @@ struct macio_chip* macio; u8 gpio; unsigned long flags; - + + /* Hack for internal USB modem */ + if (node == NULL) { + if (macio_chips[0].type != macio_keylargo) + return -ENODEV; + node = macio_chips[0].of_node; + } macio = macio_find(node, 0); if (!macio) return -ENODEV; @@ -791,8 +780,96 @@ } static int __pmac +pangea_modem_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + /* Hack for internal USB modem */ + if (node == NULL) { + if (macio_chips[0].type != macio_pangea && + macio_chips[0].type != macio_intrepid) + return -ENODEV; + node = macio_chips[0].of_node; + } + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); + gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; + gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; + + if (!value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + mdelay(250); + } + LOCK(flags); + if (value) { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR2); + mdelay(250); + } else { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + UNLOCK(flags); + } + if (value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); + } + return 0; +} + +static int __pmac +core99_ata100_enable(struct device_node* node, int value) +{ + unsigned long flags; + struct pci_dev *pdev = NULL; + u8 pbus, pid; + + if (uninorth_rev < 0x24) + return -ENODEV; + + LOCK(flags); + if (value) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100); + (void)UN_IN(UNI_N_CLOCK_CNTL); + UNLOCK(flags); + udelay(20); + + if (value) { + if (pci_device_from_OF_node(node, &pbus, &pid) == 0) + pdev = pci_find_slot(pbus, pid); + if (pdev == NULL) + return 0; + pci_enable_device(pdev); + pci_set_master(pdev); + } + return 0; +} + +static int __pmac core99_ide_enable(struct device_node* node, int param, int value) { + /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2 + * based ata-100 + */ switch(param) { case 0: return simple_feature_tweak(node, macio_unknown, @@ -803,6 +880,8 @@ case 2: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_UIDE_ENABLE, value); + case 3: + return core99_ata100_enable(node, value); default: return -ENODEV; } @@ -850,7 +929,8 @@ struct macio_chip* macio; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; LOCK(flags); @@ -987,27 +1067,40 @@ static int __pmac core99_reset_cpu(struct device_node* node, int param, int value) { - const int reset_lines[] = { KL_GPIO_RESET_CPU0, - KL_GPIO_RESET_CPU1, - KL_GPIO_RESET_CPU2, - KL_GPIO_RESET_CPU3 }; - int reset_io; + unsigned int reset_io = 0; unsigned long flags; struct macio_chip* macio; + struct device_node* np; + const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0, + KL_GPIO_RESET_CPU1, + KL_GPIO_RESET_CPU2, + KL_GPIO_RESET_CPU3 }; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo) return -ENODEV; - if (param > 3 || param < 0) + + np = find_path_device("/cpus"); + if (np == NULL) return -ENODEV; - - reset_io = reset_lines[param]; + for (np = np->child; np != NULL; np = np->sibling) { + u32* num = (u32 *)get_property(np, "reg", NULL); + u32* rst = (u32 *)get_property(np, "soft-reset", NULL); + if (num == NULL || rst == NULL) + continue; + if (param == *num) { + reset_io = *rst; + break; + } + } + if (np == NULL || reset_io == 0) + reset_io = dflt_reset_lines[param]; LOCK(flags); MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(reset_io); udelay(1); - MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTOUT_DATA | KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(reset_io); UNLOCK(flags); @@ -1025,15 +1118,19 @@ u32 reg; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; - + + /* XXX Fix handling of 3rd USB controller in Intrepid, move the + * port connect stuff (KL4_*) to the sleep code eventually + */ prop = (char *)get_property(node, "AAPL,clock-id", NULL); if (!prop) return -ENODEV; - if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0) + if (strncmp(prop, "usb0u048", 8) == 0) number = 0; - else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0) + else if (strncmp(prop, "usb1u148", 8) == 0) number = 2; else return -ENODEV; @@ -1104,7 +1201,8 @@ struct macio_chip* macio; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; @@ -1133,7 +1231,8 @@ if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0) return -ENODEV; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; @@ -1172,23 +1271,24 @@ } static void __pmac -keylargo_shutdown(struct macio_chip* macio, int restart) +keylargo_shutdown(struct macio_chip* macio, int sleep_mode) { u32 temp; - mdelay(1); - MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); - (void)MACIO_IN32(KEYLARGO_FCR0); - mdelay(100); + if (sleep_mode) { + mdelay(1); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(1); + } MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | KL0_SCC_CELL_ENABLE | KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); - - (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); + MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); - (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE); MACIO_BIC(KEYLARGO_FCR1, KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | @@ -1199,27 +1299,33 @@ KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | KL1_UIDE_ENABLE); - (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); - udelay(10); MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); - udelay(10); + temp = MACIO_IN32(KEYLARGO_FCR3); - if (macio->rev >= 2) - temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL); - + if (macio->rev >= 2) { + temp |= KL3_SHUTDOWN_PLL2X; + if (sleep_mode) + temp |= KL3_SHUTDOWN_PLL_TOTAL; + } + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | - KL3_SHUTDOWN_PLLKW35 | KL3_SHUTDOWN_PLLKW12; + KL3_SHUTDOWN_PLLKW35; + if (sleep_mode) + temp |= KL3_SHUTDOWN_PLLKW12; temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE - | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE - | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); MACIO_OUT32(KEYLARGO_FCR3, temp); - (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } static void __pmac -pangea_shutdown(struct macio_chip* macio, int restart) +pangea_shutdown(struct macio_chip* macio, int sleep_mode) { u32 temp; @@ -1227,10 +1333,6 @@ KL0_SCC_CELL_ENABLE | KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); - (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); - MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); - (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); - MACIO_BIC(KEYLARGO_FCR1, KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | @@ -1238,18 +1340,54 @@ KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | KL1_UIDE_ENABLE); - (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); + if (pmac_mb.board_flags & PMAC_MB_MOBILE) + MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); - udelay(10); + temp = MACIO_IN32(KEYLARGO_FCR3); temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | KL3_SHUTDOWN_PLLKW35; - temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE - | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE - | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE); MACIO_OUT32(KEYLARGO_FCR3, temp); - (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); +} + +static void __pmac +intrepid_shutdown(struct macio_chip* macio, int sleep_mode) +{ + u32 temp; + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); + + MACIO_BIC(KEYLARGO_FCR1, + KL1_USB2_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE); + if (pmac_mb.board_flags & PMAC_MB_MOBILE) + MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N); + + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + + temp = MACIO_IN32(KEYLARGO_FCR3); + temp |= KL3_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 | + KL3_IT_SHUTDOWN_PLL3; + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | + KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE); + if (sleep_mode) + temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + + /* Flush posted writes & wait a bit */ + (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } static int __pmac @@ -1259,7 +1397,8 @@ int i; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; /* We power off the wireless slot in case it was not done @@ -1275,7 +1414,11 @@ } /* We make sure int. modem is off (in case driver lost it) */ - core99_modem_enable(macio->of_node, 0, 0); + if (macio->type == macio_keylargo) + core99_modem_enable(macio->of_node, 0, 0); + else + pangea_modem_enable(macio->of_node, 0, 0); + /* We make sure the sound is off as well */ core99_sound_chip_enable(macio->of_node, 0, 0); @@ -1292,12 +1435,15 @@ save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i); /* Save the FCRs */ - save_mbcr = MACIO_IN32(KEYLARGO_MBCR); + if (macio->type == macio_keylargo) + save_mbcr = MACIO_IN32(KEYLARGO_MBCR); save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0); save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1); save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2); save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3); save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4); + if (macio->type == macio_pangea || macio->type == macio_intrepid) + save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5); /* Save state & config of DBDMA channels */ dbdma_save(macio, save_dbdma); @@ -1306,9 +1452,11 @@ * Turn off as much as we can */ if (macio->type == macio_pangea) - pangea_shutdown(macio, 0); + pangea_shutdown(macio, 1); + else if (macio->type == macio_intrepid) + intrepid_shutdown(macio, 1); else if (macio->type == macio_keylargo) - keylargo_shutdown(macio, 0); + keylargo_shutdown(macio, 1); /* * Put the host bridge to sleep @@ -1338,7 +1486,8 @@ int i; macio = &macio_chips[0]; - if (macio->type != macio_keylargo && macio->type != macio_pangea) + if (macio->type != macio_keylargo && macio->type != macio_pangea && + macio->type != macio_intrepid) return -ENODEV; /* @@ -1352,9 +1501,11 @@ /* * Restore KeyLargo */ - - MACIO_OUT32(KEYLARGO_MBCR, save_mbcr); - (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + + if (macio->type == macio_keylargo) { + MACIO_OUT32(KEYLARGO_MBCR, save_mbcr); + (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + } MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]); (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]); @@ -1365,6 +1516,10 @@ (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]); (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10); + if (macio->type == macio_pangea || macio->type == macio_intrepid) { + MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]); + (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10); + } dbdma_restore(macio, save_dbdma); @@ -1390,6 +1545,21 @@ static int __pmac core99_sleep_state(struct device_node* node, int param, int value) { + /* Param == 1 means to enter the "fake sleep" mode that is + * used for CPU speed switch + */ + if (param == 1) { + if (value == 1) { + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2); + } else { + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); + udelay(10); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); + udelay(10); + } + return 0; + } if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) return -EPERM; if (value == 1) @@ -1400,55 +1570,6 @@ } static int __pmac -pangea_modem_enable(struct device_node* node, int param, int value) -{ - struct macio_chip* macio; - u8 gpio; - unsigned long flags; - - macio = macio_find(node, 0); - if (!macio) - return -ENODEV; - gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); - gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; - gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; - - if (!value) { - LOCK(flags); - MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); - UNLOCK(flags); - (void)MACIO_IN8(KL_GPIO_MODEM_RESET); - mdelay(250); - } - LOCK(flags); - if (value) { - MACIO_OUT8(KL_GPIO_MODEM_POWER, - KEYLARGO_GPIO_OUTPUT_ENABLE); - UNLOCK(flags); - (void)MACIO_IN32(KEYLARGO_FCR2); - mdelay(250); - } else { - MACIO_OUT8(KL_GPIO_MODEM_POWER, - KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - UNLOCK(flags); - } - if (value) { - LOCK(flags); - MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); - (void)MACIO_IN8(KL_GPIO_MODEM_RESET); - UNLOCK(flags); mdelay(250); LOCK(flags); - MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); - (void)MACIO_IN8(KL_GPIO_MODEM_RESET); - UNLOCK(flags); mdelay(250); LOCK(flags); - MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); - (void)MACIO_IN8(KL_GPIO_MODEM_RESET); - UNLOCK(flags); mdelay(250); - } - return 0; -} - - -static int __pmac generic_get_mb_info(struct device_node* node, int param, int value) { switch(param) { @@ -1561,6 +1682,26 @@ { 0, NULL } }; +/* RackMac + */ +static struct feature_table_entry rackmac_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, + { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, + { PMAC_FTR_IDE_RESET, core99_ide_reset }, + { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, + { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, + { PMAC_FTR_USB_ENABLE, core99_usb_enable }, + { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, + { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, + { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, +#ifdef CONFIG_SMP + { PMAC_FTR_RESET_CPU, core99_reset_cpu }, +#endif /* CONFIG_SMP */ + { PMAC_FTR_READ_GPIO, core99_read_gpio }, + { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { 0, NULL } +}; + /* Pangea features */ static struct feature_table_entry pangea_features[] __pmacdata = { @@ -1580,6 +1721,26 @@ { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, { 0, NULL } }; + +/* Intrepid features + */ +static struct feature_table_entry intrepid_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, + { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, + { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, + { PMAC_FTR_IDE_RESET, core99_ide_reset }, + { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, + { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, + { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, + { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, + { PMAC_FTR_USB_ENABLE, core99_usb_enable }, + { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, + { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, + { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, + { PMAC_FTR_READ_GPIO, core99_read_gpio }, + { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { 0, NULL } +}; static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { /* Warning: ordering is important as some models may claim @@ -1611,11 +1772,11 @@ }, { "AAPL,3400/2400", "PowerBook 3400", PMAC_TYPE_HOOPER, ohare_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE }, { "AAPL,3500", "PowerBook 3500", PMAC_TYPE_KANGA, ohare_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE }, { "AAPL,Gossamer", "PowerMac G3 (Gossamer)", PMAC_TYPE_GOSSAMER, heathrow_desktop_features, @@ -1627,11 +1788,11 @@ }, { "AAPL,PowerBook1998", "PowerBook Wallstreet", PMAC_TYPE_WALLSTREET, heathrow_laptop_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE }, - { "AAPL,PowerBook1,1", "PowerBook 101 (Lombard)", + { "PowerBook1,1", "PowerBook 101 (Lombard)", PMAC_TYPE_101_PBOOK, paddington_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE }, { "iMac,1", "iMac (first generation)", PMAC_TYPE_ORIG_IMAC, paddington_features, @@ -1641,13 +1802,21 @@ PMAC_TYPE_PANGEA_IMAC, pangea_features, PMAC_MB_CAN_SLEEP }, - { "PowerBook4,2", "iBook 2 with 14\" LCD", + { "PowerBook4,3", "iBook 2 rev. 2", PMAC_TYPE_IBOOK2, pangea_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE + }, + { "PowerBook4,2", "iBook 2", + PMAC_TYPE_IBOOK2, pangea_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE }, { "PowerBook4,1", "iBook 2", PMAC_TYPE_IBOOK2, pangea_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE + }, + { "PowerMac4,4", "eMac", + PMAC_TYPE_EMAC, core99_features, + PMAC_MB_CAN_SLEEP }, { "PowerMac4,2", "Flat panel iMac", PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features, @@ -1663,34 +1832,35 @@ }, { "PowerBook2,1", "iBook (first generation)", PMAC_TYPE_ORIG_IBOOK, core99_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE }, { "PowerMac3,1", "PowerMac G4 AGP Graphics", PMAC_TYPE_SAWTOOTH, core99_features, - 0 + PMAC_MB_OLD_CORE99 }, { "PowerMac3,2", "PowerMac G4 AGP Graphics", PMAC_TYPE_SAWTOOTH, core99_features, - 0 + PMAC_MB_OLD_CORE99 }, { "PowerMac3,3", "PowerMac G4 AGP Graphics", PMAC_TYPE_SAWTOOTH, core99_features, - 0 + PMAC_MB_OLD_CORE99 }, { "PowerMac2,1", "iMac FireWire", PMAC_TYPE_FW_IMAC, core99_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 }, { "PowerMac2,2", "iMac FireWire", PMAC_TYPE_FW_IMAC, core99_features, - PMAC_MB_CAN_SLEEP + PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 }, { "PowerBook2,2", "iBook FireWire", PMAC_TYPE_FW_IBOOK, core99_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE }, { "PowerMac5,1", "PowerMac G4 Cube", PMAC_TYPE_CUBE, core99_features, + PMAC_MB_OLD_CORE99 }, { "PowerMac3,4", "PowerMac G4 Silver", PMAC_TYPE_QUICKSILVER, core99_features, @@ -1702,19 +1872,31 @@ }, { "PowerBook3,1", "PowerBook Pismo", PMAC_TYPE_PISMO, core99_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE }, { "PowerBook3,2", "PowerBook Titanium", PMAC_TYPE_TITANIUM, core99_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE }, { "PowerBook3,3", "PowerBook Titanium II", PMAC_TYPE_TITANIUM2, core99_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE }, { "PowerBook3,4", "PowerBook Titanium III", PMAC_TYPE_TITANIUM3, core99_features, - PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE + }, + { "PowerBook3,5", "PowerBook Titanium IV", + PMAC_TYPE_TITANIUM4, core99_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE + }, + { "RackMac1,1", "XServe", + PMAC_TYPE_RACKMAC, rackmac_features, + 0, + }, + { "PowerMac3,6", "PowerMac G4 Windtunnel", + PMAC_TYPE_WINDTUNNEL, rackmac_features, + 0, }, }; @@ -1758,8 +1940,22 @@ { int i; struct macio_chip* macio = &macio_chips[0]; - - /* Lookup known motherboard type in device-tree */ + const char* model = NULL; + struct device_node *dt; + + /* Lookup known motherboard type in device-tree. First try an + * exact match on the "model" property, then try a "compatible" + * match is none is found. + */ + dt = find_devices("device-tree"); + if (dt != NULL) + model = (const char *) get_property(dt, "model", NULL); + for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { + if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { + pmac_mb = pmac_mb_defs[i]; + goto found; + } + } for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { if (machine_is_compatible(pmac_mb_defs[i].model_string)) { pmac_mb = pmac_mb_defs[i]; @@ -1797,6 +1993,11 @@ pmac_mb.model_name = "Unknown Pangea-based"; pmac_mb.features = pangea_features; break; + case macio_intrepid: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA; + pmac_mb.model_name = "Unknown Pangea-based"; + pmac_mb.features = intrepid_features; + break; default: return -ENODEV; } @@ -1815,6 +2016,7 @@ iounmap(mach_id_ptr); } +#ifdef CONFIG_6xx /* Set default value of powersave_nap on machines that support it. * It appears that uninorth rev 3 has a problem with it, we don't * enable it on those. In theory, the flush-on-lock property is @@ -1823,7 +2025,6 @@ */ while (uninorth_base && uninorth_rev > 3) { struct device_node* np = find_path_device("/cpus"); - u32 pvr = mfspr(PVR); if (!np || !np->child) { printk(KERN_WARNING "Can't find CPU(s) in device tree !\n"); break; @@ -1835,14 +2036,23 @@ /* Nap mode not supported if flush-on-lock property is present */ if (get_property(np, "flush-on-lock", NULL)) break; - /* Some 7450 may have problem with NAP mode too ... */ - if (((pvr >> 16) == 0x8000) && ((pvr & 0xffff) < 0x0201)) - break; powersave_nap = 1; printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); break; } + /* On CPUs that support it (750FX), lowspeed by default during + * NAP mode + */ + powersave_lowspeed = 1; +#endif /* CONFIG_6xx */ + + /* Check for "mobile" machine */ + if (model && (strncmp(model, "PowerBook", 9) == 0 + || strncmp(model, "iBook", 5) == 0)) + pmac_mb.board_flags |= PMAC_MB_MOBILE; + + printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); return 0; } @@ -1857,7 +2067,7 @@ /* Locate core99 Uni-N */ uninorth_node = find_devices("uni-n"); if (uninorth_node && uninorth_node->n_addrs > 0) { - uninorth_base = ioremap(uninorth_node->addrs[0].address, 0x1000); + uninorth_base = ioremap(uninorth_node->addrs[0].address, 0x4000); uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); } else uninorth_node = NULL; @@ -1867,15 +2077,23 @@ printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n", uninorth_rev); + printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); /* Set the arbitrer QAck delay according to what Apple does */ - if (uninorth_rev < 0x10) { + if (uninorth_rev < 0x11) { actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; UN_OUT(UNI_N_ARB_CTRL, actrl); } + + /* Some more magic as done by them in recent MacOS X on UniNorth + * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI + * memory timeout + */ + if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) + UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); } static void __init @@ -1917,11 +2135,14 @@ u32* did = (u32 *)get_property(node, "device-id", NULL); if (*did == 0x00000025) type = macio_pangea; + if (*did == 0x0000003e) + type = macio_intrepid; } macio_chips[i].of_node = node; macio_chips[i].type = type; macio_chips[i].base = base; macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; + macio_chips[i].name = macio_names[type]; revp = (u32 *)get_property(node, "revision-id", NULL); if (revp) macio_chips[i].rev = *revp; @@ -2011,7 +2232,8 @@ } if (macio_chips[0].type == macio_keylargo || - macio_chips[0].type == macio_pangea) { + macio_chips[0].type == macio_pangea || + macio_chips[0].type == macio_intrepid) { /* Enable GMAC for now for PCI probing. It will be disabled * later on after PCI probe */ @@ -2042,6 +2264,17 @@ np = np->next; } + /* Enable ATA-100 before PCI probe. */ + np = find_devices("ata-6"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "kauai-ata")) { + core99_ata100_enable(np, 1); + } + np = np->next; + } + /* Switch airport off */ np = find_devices("radio"); while(np) { @@ -2079,9 +2312,6 @@ initial_serial_shutdown(np); np = np->next; } - - /* Let hardware settle down */ - mdelay(10); } void __init diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_setup.c linux-2.5.66-bk4/arch/ppc/platforms/pmac_setup.c --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_setup.c Mon Mar 24 14:00:55 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_setup.c Mon Mar 31 12:49:35 2003 @@ -225,6 +225,20 @@ return 0; } +int __openfirmware +pmac_show_percpuinfo(struct seq_file *m, int i) +{ +#ifdef CONFIG_CPU_FREQ_PMAC + extern unsigned int pmac_get_one_cpufreq(int i); + unsigned int freq = pmac_get_one_cpufreq(i); + if (freq != 0) { + seq_printf(m, "clock\t\t: %dMHz\n", freq/1000); + return 0; + } +#endif /* CONFIG_CPU_FREQ_PMAC */ + return of_show_percpuinfo(m, i); +} + static volatile u32 *sysctrl_regs; void __init @@ -604,7 +618,7 @@ ppc_md.setup_arch = pmac_setup_arch; ppc_md.show_cpuinfo = pmac_show_cpuinfo; - ppc_md.show_percpuinfo = of_show_percpuinfo; + ppc_md.show_percpuinfo = pmac_show_percpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_sleep.S linux-2.5.66-bk4/arch/ppc/platforms/pmac_sleep.S --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_sleep.S Wed Dec 31 16:00:00 1969 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_sleep.S Mon Mar 31 12:49:35 2003 @@ -0,0 +1,375 @@ +/* + * This file contains sleep low-level functions for PowerBook G3. + * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * and Paul Mackerras (paulus@samba.org). + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAGIC 0x4c617273 /* 'Lars' */ + +/* + * Structure for storing CPU registers on the stack. + */ +#define SL_SP 0 +#define SL_PC 4 +#define SL_MSR 8 +#define SL_SDR1 0xc +#define SL_SPRG0 0x10 /* 4 sprg's */ +#define SL_DBAT0 0x20 +#define SL_IBAT0 0x28 +#define SL_DBAT1 0x30 +#define SL_IBAT1 0x38 +#define SL_DBAT2 0x40 +#define SL_IBAT2 0x48 +#define SL_DBAT3 0x50 +#define SL_IBAT3 0x58 +#define SL_TB 0x60 +#define SL_R2 0x68 +#define SL_CR 0x6c +#define SL_R12 0x70 /* r12 to r31 */ +#define SL_SIZE (SL_R12 + 80) + + .section .text + .align 5 + +#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC) + +/* This gets called by via-pmu.c late during the sleep process. + * The PMU was already send the sleep command and will shut us down + * soon. We need to save all that is needed and setup the wakeup + * vector that will be called by the ROM on wakeup + */ +_GLOBAL(low_sleep_handler) + mflr r0 + stw r0,4(r1) + stwu r1,-SL_SIZE(r1) + mfcr r0 + stw r0,SL_CR(r1) + stw r2,SL_R2(r1) + stmw r12,SL_R12(r1) + + /* Save MSR & SDR1 */ + mfmsr r4 + stw r4,SL_MSR(r1) + mfsdr1 r4 + stw r4,SL_SDR1(r1) + + /* Get a stable timebase and save it */ +1: mftbu r4 + stw r4,SL_TB(r1) + mftb r5 + stw r5,SL_TB+4(r1) + mftbu r3 + cmpw r3,r4 + bne 1b + + /* Save SPRGs */ + mfsprg r4,0 + stw r4,SL_SPRG0(r1) + mfsprg r4,1 + stw r4,SL_SPRG0+4(r1) + mfsprg r4,2 + stw r4,SL_SPRG0+8(r1) + mfsprg r4,3 + stw r4,SL_SPRG0+12(r1) + + /* Save BATs */ + mfdbatu r4,0 + stw r4,SL_DBAT0(r1) + mfdbatl r4,0 + stw r4,SL_DBAT0+4(r1) + mfdbatu r4,1 + stw r4,SL_DBAT1(r1) + mfdbatl r4,1 + stw r4,SL_DBAT1+4(r1) + mfdbatu r4,2 + stw r4,SL_DBAT2(r1) + mfdbatl r4,2 + stw r4,SL_DBAT2+4(r1) + mfdbatu r4,3 + stw r4,SL_DBAT3(r1) + mfdbatl r4,3 + stw r4,SL_DBAT3+4(r1) + mfibatu r4,0 + stw r4,SL_IBAT0(r1) + mfibatl r4,0 + stw r4,SL_IBAT0+4(r1) + mfibatu r4,1 + stw r4,SL_IBAT1(r1) + mfibatl r4,1 + stw r4,SL_IBAT1+4(r1) + mfibatu r4,2 + stw r4,SL_IBAT2(r1) + mfibatl r4,2 + stw r4,SL_IBAT2+4(r1) + mfibatu r4,3 + stw r4,SL_IBAT3(r1) + mfibatl r4,3 + stw r4,SL_IBAT3+4(r1) + + /* Backup various CPU config stuffs */ + bl __save_cpu_setup + + /* The ROM can wake us up via 2 different vectors: + * - On wallstreet & lombard, we must write a magic + * value 'Lars' at address 4 and a pointer to a + * memory location containing the PC to resume from + * at address 0. + * - On Core99, we must store the wakeup vector at + * address 0x80 and eventually it's parameters + * at address 0x84. I've have some trouble with those + * parameters however and I no longer use them. + */ + lis r5,grackle_wake_up@ha + addi r5,r5,grackle_wake_up@l + tophys(r5,r5) + stw r5,SL_PC(r1) + lis r4,KERNELBASE@h + tophys(r5,r1) + addi r5,r5,SL_PC + lis r6,MAGIC@ha + addi r6,r6,MAGIC@l + stw r5,0(r4) + stw r6,4(r4) + /* Setup stuffs at 0x80-0x84 for Core99 */ + lis r3,core99_wake_up@ha + addi r3,r3,core99_wake_up@l + tophys(r3,r3) + stw r3,0x80(r4) + stw r5,0x84(r4) + /* Store a pointer to our backup storage into + * a kernel global + */ + lis r3,sleep_storage@ha + addi r3,r3,sleep_storage@l + stw r5,0(r3) + +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + +/* + * Flush the L1 data cache by reading the first 128kB of RAM + * and then flushing the same area with the dcbf instruction. + * The L2 cache has already been disabled. + */ + li r4,0x1000 /* 128kB / 32B */ + mtctr r4 + lis r4,KERNELBASE@h +1: + lwz r0,0(r4) + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz 1b + sync + + li r4,0x1000 /* 128kB / 32B */ + mtctr r4 + lis r4,KERNELBASE@h +1: + dcbf r0,r4 + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz 1b + sync + +/* + * Set the HID0 and MSR for sleep. + */ + mfspr r2,HID0 + rlwinm r2,r2,0,10,7 /* clear doze, nap */ + oris r2,r2,HID0_SLEEP@h + sync + mtspr HID0,r2 + sync + +/* This loop puts us back to sleep in case we have a spurrious + * wakeup so that the host bridge properly stays asleep. The + * CPU will be turned off, either after a known time (about 1 + * second) on wallstreet & lombard, or as soon as the CPU enters + * SLEEP mode on core99 + */ + mfmsr r2 + oris r2,r2,MSR_POW@h +1: sync + mtmsr r2 + isync + b 1b + +/* + * Here is the resume code. + */ + + +/* + * Core99 machines resume here + * r4 has the physical address of SL_PC(sp) (unused) + */ +_GLOBAL(core99_wake_up) + /* Make sure HID0 no longer contains any sleep bit */ + mfspr r3,HID0 + rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */ + mtspr HID0,r3 + sync + isync + + /* Won't that cause problems on CPU that doesn't support it ? */ + lis r3, 0 + mtspr SPRN_MMCR0, r3 + + /* sanitize MSR */ + mfmsr r3 + ori r3,r3,MSR_EE|MSR_IP + xori r3,r3,MSR_EE|MSR_IP + sync + isync + mtmsr r3 + sync + isync + + /* Recover sleep storage */ + lis r3,sleep_storage@ha + addi r3,r3,sleep_storage@l + tophys(r3,r3) + lwz r1,0(r3) + + /* Pass thru to older resume code ... */ +/* + * Here is the resume code for older machines. + * r1 has the physical address of SL_PC(sp). + */ + +grackle_wake_up: + /* Enable and then Flash inval the instruction & data cache */ + mfspr r3,HID0 + ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI + sync + isync + mtspr HID0,r3 + xori r3,r3, HID0_ICFI|HID0_DCI + mtspr HID0,r3 + sync + + /* Restore the kernel's segment registers before + * we do any r1 memory access as we are not sure they + * are in a sane state above the first 256Mb region + */ + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + + subi r1,r1,SL_PC + + /* Restore various CPU config stuffs */ + bl __restore_cpu_setup + + /* Restore the BATs, and SDR1. Then we can turn on the MMU. */ + lwz r4,SL_SDR1(r1) + mtsdr1 r4 + lwz r4,SL_SPRG0(r1) + mtsprg 0,r4 + lwz r4,SL_SPRG0+4(r1) + mtsprg 1,r4 + lwz r4,SL_SPRG0+8(r1) + mtsprg 2,r4 + lwz r4,SL_SPRG0+12(r1) + mtsprg 3,r4 + + lwz r4,SL_DBAT0(r1) + mtdbatu 0,r4 + lwz r4,SL_DBAT0+4(r1) + mtdbatl 0,r4 + lwz r4,SL_DBAT1(r1) + mtdbatu 1,r4 + lwz r4,SL_DBAT1+4(r1) + mtdbatl 1,r4 + lwz r4,SL_DBAT2(r1) + mtdbatu 2,r4 + lwz r4,SL_DBAT2+4(r1) + mtdbatl 2,r4 + lwz r4,SL_DBAT3(r1) + mtdbatu 3,r4 + lwz r4,SL_DBAT3+4(r1) + mtdbatl 3,r4 + lwz r4,SL_IBAT0(r1) + mtibatu 0,r4 + lwz r4,SL_IBAT0+4(r1) + mtibatl 0,r4 + lwz r4,SL_IBAT1(r1) + mtibatu 1,r4 + lwz r4,SL_IBAT1+4(r1) + mtibatl 1,r4 + lwz r4,SL_IBAT2(r1) + mtibatu 2,r4 + lwz r4,SL_IBAT2+4(r1) + mtibatl 2,r4 + lwz r4,SL_IBAT3(r1) + mtibatu 3,r4 + lwz r4,SL_IBAT3+4(r1) + mtibatl 3,r4 + + /* Flush all TLBs */ + lis r4,0x1000 +1: addic. r4,r4,-0x1000 + tlbie r4 + blt 1b + sync + + /* restore the MSR and turn on the MMU */ + lwz r3,SL_MSR(r1) + bl turn_on_mmu + + /* get back the stack pointer */ + tovirt(r1,r1) + + /* Restore TB */ + li r3,0 + mttbl r3 + lwz r3,SL_TB(r1) + lwz r4,SL_TB+4(r1) + mttbu r3 + mttbl r4 + + /* Restore the callee-saved registers and return */ + lwz r0,SL_CR(r1) + mtcr r0 + lwz r2,SL_R2(r1) + lmw r12,SL_R12(r1) + addi r1,r1,SL_SIZE + lwz r0,4(r1) + mtlr r0 + blr + +turn_on_mmu: + mflr r4 + tovirt(r4,r4) + mtsrr0 r4 + mtsrr1 r3 + sync + isync + rfi + +#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */ + + + .data + .globl sleep_storage +sleep_storage: + .long 0 diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_smp.c linux-2.5.66-bk4/arch/ppc/platforms/pmac_smp.c --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_smp.c Mon Mar 24 14:00:39 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_smp.c Mon Mar 31 12:49:35 2003 @@ -106,14 +106,16 @@ volatile static long int core99_l3_cache; static void __init -core99_init_caches(void) +core99_init_caches(int cpu) { - int cpu = smp_processor_id(); - + /* Check cache presence on cpu 0, we assume all CPUs have + * same features here. We also assume that if we don't have + * L2CR, we don't have L3CR neither + */ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) return; - if (cpu == 0){ + if (cpu == 0) { core99_l2_cache = _get_L2CR(); printk("CPU0: L2CR is %lx\n", core99_l2_cache); } else { @@ -137,106 +139,6 @@ } } -/* Some CPU registers have to be saved from the first CPU and - * applied to others. Note that we override what is setup by - * the cputable intentionally. - */ - -#define reg_hid0 0 -#define reg_hid1 1 -#define reg_msscr0 2 -#define reg_msssr0 3 -#define reg_ictrl 4 -#define reg_ldstcr 5 -#define reg_ldstdb 6 -#define reg_count 7 - -static unsigned long cpu_regs[reg_count]; - -static void __pmac -cpu_setup_grab(void) -{ - unsigned int pvers = mfspr(SPRN_PVR)>>16; - - /* Read cache setting of CPU 0 */ - core99_init_caches(); - - /* 7400/7410/7450 */ - if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) { - cpu_regs[reg_hid0] = mfspr(SPRN_HID0); - cpu_regs[reg_msscr0] = mfspr(SPRN_MSSCR0); - cpu_regs[reg_msssr0] = mfspr(SPRN_MSSSR0); - } - /* 7450 only */ - if (pvers == 0x8000) { - cpu_regs[reg_hid1] = mfspr(SPRN_HID1); - cpu_regs[reg_ictrl] = mfspr(SPRN_ICTRL); - cpu_regs[reg_ldstcr] = mfspr(SPRN_LDSTCR); - cpu_regs[reg_ldstdb] = mfspr(SPRN_LDSTDB); - } - flush_dcache_range((unsigned long)cpu_regs, (unsigned long)&cpu_regs[reg_count]); -} - -static void __pmac -cpu_setup_apply(int cpu_nr) -{ - unsigned int pvers = mfspr(SPRN_PVR)>>16; - - /* Apply cache setting from CPU 0 */ - core99_init_caches(); - - /* 7400/7410/7450 */ - if (pvers == 0x8000 || pvers == 0x000c || pvers == 0x800c) { - unsigned long tmp; - __asm__ __volatile__ ( - "lwz %0,4*"stringify(reg_hid0)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_HID0)", %0\n" - "isync;sync\n" - "lwz %0, 4*"stringify(reg_msscr0)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_MSSCR0)", %0\n" - "isync;sync\n" -// "lwz %0, "stringify(reg_msssr0)"(%1)\n" -// "sync\n" -// "mtspr "stringify(SPRN_MSSSR0)", %0\n" -// "isync;sync\n" - : "=&r" (tmp) : "r" (cpu_regs)); - } - /* 7410 only */ - if (pvers == 0x800c) { - unsigned long tmp; - __asm__ __volatile__ ( - "li %0, 0\n" - "sync\n" - "mtspr "stringify(SPRN_L2CR2)", %0\n" - "isync;sync\n" - : "=&r" (tmp)); - } - /* 7450 only */ - if (pvers == 0x8000) { - unsigned long tmp; - __asm__ __volatile__ ( - "lwz %0, 4*"stringify(reg_hid1)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_HID1)", %0\n" - "isync;sync\n" - "lwz %0, 4*"stringify(reg_ictrl)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_ICTRL)", %0\n" - "isync;sync\n" - "lwz %0, 4*"stringify(reg_ldstcr)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_LDSTCR)", %0\n" - "isync;sync\n" - "lwz %0, 4*"stringify(reg_ldstdb)"(%1)\n" - "sync\n" - "mtspr "stringify(SPRN_LDSTDB)", %0\n" - "isync;sync\n" - : "=&r" (tmp) : "r" (cpu_regs)); - } -} - /* * Set and clear IPIs for powersurge. */ @@ -501,7 +403,7 @@ /* reset the entry point so if we get another intr we won't * try to startup again */ out_be32(psurge_start, 0x100); - if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0)) + if (request_irq(30, psurge_primary_intr, SA_INTERRUPT, "primary IPI", 0)) printk(KERN_ERR "Couldn't get primary IPI interrupt"); } @@ -526,8 +428,10 @@ openpic_request_IPIs(); for (i = 1; i < ncpus; ++i) smp_hw_index[i] = i; +#ifdef CONFIG_6xx powersave_nap = 0; - cpu_setup_grab(); +#endif + core99_init_caches(0); } return ncpus; @@ -593,7 +497,7 @@ { /* Setup some registers */ if (cpu_nr != 0) - cpu_setup_apply(cpu_nr); + core99_init_caches(cpu_nr); /* Setup openpic */ do_openpic_setup_cpu(); @@ -605,20 +509,20 @@ /* PowerSurge-style Macs */ struct smp_ops_t psurge_smp_ops __pmacdata = { - smp_psurge_message_pass, - smp_psurge_probe, - smp_psurge_kick_cpu, - smp_psurge_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, + .message_pass = smp_psurge_message_pass, + .probe = smp_psurge_probe, + .kick_cpu = smp_psurge_kick_cpu, + .setup_cpu = smp_psurge_setup_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, }; /* Core99 Macs (dual G4s) */ struct smp_ops_t core99_smp_ops __pmacdata = { - smp_openpic_message_pass, - smp_core99_probe, - smp_core99_kick_cpu, - smp_core99_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, + .message_pass = smp_openpic_message_pass, + .probe = smp_core99_probe, + .kick_cpu = smp_core99_kick_cpu, + .setup_cpu = smp_core99_setup_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, }; diff -urN linux-2.5.66-bk3/arch/ppc/platforms/pmac_time.c linux-2.5.66-bk4/arch/ppc/platforms/pmac_time.c --- linux-2.5.66-bk3/arch/ppc/platforms/pmac_time.c Mon Mar 24 14:00:14 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/pmac_time.c Mon Mar 31 12:49:35 2003 @@ -202,6 +202,8 @@ printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", tb_ticks_per_jiffy, dstart - dend); + iounmap((void*)via); + return 1; } diff -urN linux-2.5.66-bk3/arch/ppc/platforms/sleep.S linux-2.5.66-bk4/arch/ppc/platforms/sleep.S --- linux-2.5.66-bk3/arch/ppc/platforms/sleep.S Mon Mar 24 14:00:00 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/sleep.S Wed Dec 31 16:00:00 1969 @@ -1,444 +0,0 @@ -/* - * This file contains sleep low-level functions for PowerBook G3. - * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) - * and Paul Mackerras (paulus@samba.org). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include - -#define MAGIC 0x4c617273 /* 'Lars' */ - -/* - * Structure for storing CPU registers on the stack. - */ -#define SL_SP 0 -#define SL_PC 4 -#define SL_MSR 8 -#define SL_SDR1 0xc -#define SL_SPRG0 0x10 /* 4 sprg's */ -#define SL_DBAT0 0x20 -#define SL_IBAT0 0x28 -#define SL_DBAT1 0x30 -#define SL_IBAT1 0x38 -#define SL_DBAT2 0x40 -#define SL_IBAT2 0x48 -#define SL_DBAT3 0x50 -#define SL_IBAT3 0x58 -#define SL_TB 0x60 -#define SL_HID0 0x68 -#define SL_HID1 0x6c -#define SL_MSSCR0 0x70 -#define SL_MSSSR0 0x74 -#define SL_ICTRL 0x78 -#define SL_LDSTCR 0x7c -#define SL_LDSTDB 0x80 -#define SL_R2 0x84 -#define SL_CR 0x88 -#define SL_R12 0x8c /* r12 to r31 */ -#define SL_SIZE (SL_R12 + 80) - - .text - .align 5 - -/* This gets called by via-pmu.c late during the sleep process. - * The PMU was already send the sleep command and will shut us down - * soon. We need to save all that is needed and setup the wakeup - * vector that will be called by the ROM on wakeup - */ -_GLOBAL(low_sleep_handler) - mflr r0 - stw r0,4(r1) - stwu r1,-SL_SIZE(r1) - mfcr r0 - stw r0,SL_CR(r1) - stw r2,SL_R2(r1) - stmw r12,SL_R12(r1) - - /* Save MSR & SDR1 */ - mfmsr r4 - stw r4,SL_MSR(r1) - mfsdr1 r4 - stw r4,SL_SDR1(r1) - - /* Get a stable timebase and save it */ -1: mftbu r4 - stw r4,SL_TB(r1) - mftb r5 - stw r5,SL_TB+4(r1) - mftbu r3 - cmpw r3,r4 - bne 1b - - /* Save SPRGs */ - mfsprg r4,0 - stw r4,SL_SPRG0(r1) - mfsprg r4,1 - stw r4,SL_SPRG0+4(r1) - mfsprg r4,2 - stw r4,SL_SPRG0+8(r1) - mfsprg r4,3 - stw r4,SL_SPRG0+12(r1) - - /* Save BATs */ - mfdbatu r4,0 - stw r4,SL_DBAT0(r1) - mfdbatl r4,0 - stw r4,SL_DBAT0+4(r1) - mfdbatu r4,1 - stw r4,SL_DBAT1(r1) - mfdbatl r4,1 - stw r4,SL_DBAT1+4(r1) - mfdbatu r4,2 - stw r4,SL_DBAT2(r1) - mfdbatl r4,2 - stw r4,SL_DBAT2+4(r1) - mfdbatu r4,3 - stw r4,SL_DBAT3(r1) - mfdbatl r4,3 - stw r4,SL_DBAT3+4(r1) - mfibatu r4,0 - stw r4,SL_IBAT0(r1) - mfibatl r4,0 - stw r4,SL_IBAT0+4(r1) - mfibatu r4,1 - stw r4,SL_IBAT1(r1) - mfibatl r4,1 - stw r4,SL_IBAT1+4(r1) - mfibatu r4,2 - stw r4,SL_IBAT2(r1) - mfibatl r4,2 - stw r4,SL_IBAT2+4(r1) - mfibatu r4,3 - stw r4,SL_IBAT3(r1) - mfibatl r4,3 - stw r4,SL_IBAT3+4(r1) - - /* Save HID0 */ - mfspr r4,HID0 - stw r4,SL_HID0(r1) - - /* Save 7400/7410/7450 specific registers */ - mfspr r3,PVR - srwi r3,r3,16 - cmpli cr0,r3,0x8000 - cmpli cr1,r3,0x000c - cmpli cr2,r3,0x800c - cror 4*cr1+eq,4*cr1+eq,4*cr2+eq - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f - mfspr r4,SPRN_MSSCR0 - stw r4,SL_MSSCR0(r1) - mfspr r4,SPRN_MSSSR0 - stw r4,SL_MSSSR0(r1) - /* Save 7450 specific registers */ - beq cr1,1f - mfspr r4,HID1 - stw r4,SL_HID1(r1) - mfspr r4,SPRN_ICTRL - stw r4,SL_ICTRL(r1) - mfspr r4,SPRN_LDSTCR - stw r4,SL_LDSTCR(r1) - mfspr r4,SPRN_LDSTDB - stw r4,SL_LDSTDB(r1) -1: - /* The ROM can wake us up via 2 different vectors: - * - On wallstreet & lombard, we must write a magic - * value 'Lars' at address 4 and a pointer to a - * memory location containing the PC to resume from - * at address 0. - * - On Core99, we must store the wakeup vector at - * address 0x80 and eventually it's parameters - * at address 0x84. I've have some trouble with those - * parameters however and I no longer use them. - */ - lis r5,grackle_wake_up@ha - addi r5,r5,grackle_wake_up@l - tophys(r5,r5) - stw r5,SL_PC(r1) - lis r4,KERNELBASE@h - tophys(r5,r1) - addi r5,r5,SL_PC - lis r6,MAGIC@ha - addi r6,r6,MAGIC@l - stw r5,0(r4) - stw r6,4(r4) - /* Setup stuffs at 0x80-0x84 for Core99 */ - lis r3,core99_wake_up@ha - addi r3,r3,core99_wake_up@l - tophys(r3,r3) - stw r3,0x80(r4) - stw r5,0x84(r4) - /* Store a pointer to our backup storage into - * a kernel global - */ - lis r3,sleep_storage@ha - addi r3,r3,sleep_storage@l - stw r5,0(r3) - - -/* - * Flush the L1 data cache by reading the first 128kB of RAM - * and then flushing the same area with the dcbf instruction. - * The L2 cache has already been disabled. - */ - li r4,0x1000 /* 128kB / 32B */ - mtctr r4 - lis r4,KERNELBASE@h -1: - lwz r0,0(r4) - addi r4,r4,0x0020 /* Go to start of next cache line */ - bdnz 1b - sync - - li r4,0x1000 /* 128kB / 32B */ - mtctr r4 - lis r4,KERNELBASE@h -1: - dcbf r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ - bdnz 1b - sync - -/* - * Set the HID0 and MSR for sleep. - */ - mfspr r2,HID0 - rlwinm r2,r2,0,10,7 /* clear doze, nap */ - oris r2,r2,HID0_SLEEP@h - sync - mtspr HID0,r2 - sync - -/* This loop puts us back to sleep in case we have a spurrious - * wakeup so that the host bridge properly stays asleep. The - * CPU will be turned off, either after a known time (about 1 - * second) on wallstreet & lombard, or as soon as the CPU enters - * SLEEP mode on core99 - */ - mfmsr r2 - oris r2,r2,MSR_POW@h -1: sync - mtmsr r2 - isync - b 1b - -/* - * Here is the resume code. - */ - - -/* - * Core99 machines resume here - * r4 has the physical address of SL_PC(sp) (unused) - */ -_GLOBAL(core99_wake_up) - /* Make sure HID0 no longer contains any sleep bit */ - mfspr r3,HID0 - rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */ - mtspr HID0,r3 - sync - isync - - /* Won't that cause problems on CPU that doesn't support it ? */ - lis r3, 0 - mtspr SPRN_MMCR0, r3 - - /* sanitize MSR */ - mfmsr r3 - ori r3,r3,MSR_EE|MSR_IP - xori r3,r3,MSR_EE|MSR_IP - sync - isync - mtmsr r3 - sync - isync - - /* Recover sleep storage */ - lis r3,sleep_storage@ha - addi r3,r3,sleep_storage@l - tophys(r3,r3) - lwz r1,0(r3) - - /* Pass thru to older resume code ... */ -/* - * Here is the resume code for older machines. - * r1 has the physical address of SL_PC(sp). - */ - -grackle_wake_up: - /* Enable and then Flash inval the instruction & data cache */ - mfspr r3,HID0 - ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI - sync - isync - mtspr HID0,r3 - xori r3,r3, HID0_ICFI|HID0_DCI - mtspr HID0,r3 - sync - - /* Restore the kernel's segment registers before - * we do any r1 memory access as we are not sure they - * are in a sane state above the first 256Mb region - */ - li r0,16 /* load up segment register values */ - mtctr r0 /* for context 0 */ - lis r3,0x2000 /* Ku = 1, VSID = 0 */ - li r4,0 -3: mtsrin r3,r4 - addi r3,r3,0x111 /* increment VSID */ - addis r4,r4,0x1000 /* address of next segment */ - bdnz 3b - - /* Restore the remaining bits of the HID0 register. */ - subi r1,r1,SL_PC - lwz r3,SL_HID0(r1) - sync - isync - mtspr HID0,r3 - sync - isync - - /* Restore 7400/7410/7450 specific registers */ - mfspr r3,PVR - srwi r3,r3,16 - cmpli cr0,r3,0x8000 - cmpli cr1,r3,0x000c - cmpli cr2,r3,0x800c - cror 4*cr1+eq,4*cr1+eq,4*cr2+eq - cror 4*cr0+eq,4*cr0+eq,4*cr1+eq - bne 1f - lwz r4,SL_MSSCR0(r1) - sync - mtspr SPRN_MSSCR0,r4 - sync - isync - lwz r4,SL_MSSSR0(r1) - sync - mtspr SPRN_MSSSR0,r4 - sync - isync - bne cr2,1f - li r4,0 - mtspr SPRN_L2CR2,r4 - /* Restore 7450 specific registers */ - beq cr1,1f - lwz r4,SL_HID1(r1) - sync - mtspr HID1,r4 - isync - sync - lwz r4,SPRN_ICTRL(r1) - sync - mtspr SPRN_ICTRL,r4 - isync - sync - lwz r4,SPRN_LDSTCR(r1) - sync - mtspr SPRN_LDSTCR,r4 - isync - sync - lwz r4,SL_LDSTDB(r1) - sync - mtspr SPRN_LDSTDB,r4 - isync - sync -1: - /* Restore the BATs, and SDR1. Then we can turn on the MMU. */ - lwz r4,SL_SDR1(r1) - mtsdr1 r4 - lwz r4,SL_SPRG0(r1) - mtsprg 0,r4 - lwz r4,SL_SPRG0+4(r1) - mtsprg 1,r4 - lwz r4,SL_SPRG0+8(r1) - mtsprg 2,r4 - lwz r4,SL_SPRG0+12(r1) - mtsprg 3,r4 - - lwz r4,SL_DBAT0(r1) - mtdbatu 0,r4 - lwz r4,SL_DBAT0+4(r1) - mtdbatl 0,r4 - lwz r4,SL_DBAT1(r1) - mtdbatu 1,r4 - lwz r4,SL_DBAT1+4(r1) - mtdbatl 1,r4 - lwz r4,SL_DBAT2(r1) - mtdbatu 2,r4 - lwz r4,SL_DBAT2+4(r1) - mtdbatl 2,r4 - lwz r4,SL_DBAT3(r1) - mtdbatu 3,r4 - lwz r4,SL_DBAT3+4(r1) - mtdbatl 3,r4 - lwz r4,SL_IBAT0(r1) - mtibatu 0,r4 - lwz r4,SL_IBAT0+4(r1) - mtibatl 0,r4 - lwz r4,SL_IBAT1(r1) - mtibatu 1,r4 - lwz r4,SL_IBAT1+4(r1) - mtibatl 1,r4 - lwz r4,SL_IBAT2(r1) - mtibatu 2,r4 - lwz r4,SL_IBAT2+4(r1) - mtibatl 2,r4 - lwz r4,SL_IBAT3(r1) - mtibatu 3,r4 - lwz r4,SL_IBAT3+4(r1) - mtibatl 3,r4 - - /* Flush all TLBs */ - lis r4,0x1000 -1: addic. r4,r4,-0x1000 - tlbie r4 - blt 1b - sync - - /* restore the MSR and turn on the MMU */ - lwz r3,SL_MSR(r1) - bl turn_on_mmu - - /* get back the stack pointer */ - tovirt(r1,r1) - - /* Restore TB */ - li r3,0 - mttbl r3 - lwz r3,SL_TB(r1) - lwz r4,SL_TB+4(r1) - mttbu r3 - mttbl r4 - - /* Restore the callee-saved registers and return */ - lwz r0,SL_CR(r1) - mtcr r0 - lwz r2,SL_R2(r1) - lmw r12,SL_R12(r1) - addi r1,r1,SL_SIZE - lwz r0,4(r1) - mtlr r0 - blr - -turn_on_mmu: - mflr r4 - tovirt(r4,r4) - mtsrr0 r4 - mtsrr1 r3 - sync - isync - rfi - - .data - .globl sleep_storage -sleep_storage: - .long 0 diff -urN linux-2.5.66-bk3/arch/ppc/platforms/spruce_setup.c linux-2.5.66-bk4/arch/ppc/platforms/spruce_setup.c --- linux-2.5.66-bk3/arch/ppc/platforms/spruce_setup.c Mon Mar 24 14:00:01 2003 +++ linux-2.5.66-bk4/arch/ppc/platforms/spruce_setup.c Mon Mar 31 12:49:35 2003 @@ -133,8 +133,8 @@ #endif /* Identify the system */ - printk("System Identification: IBM Spruce\n"); - printk("IBM Spruce port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + printk(KERN_INFO "System Identification: IBM Spruce\n"); + printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); } static void diff -urN linux-2.5.66-bk3/arch/ppc/syslib/prom_init.c linux-2.5.66-bk4/arch/ppc/syslib/prom_init.c --- linux-2.5.66-bk3/arch/ppc/syslib/prom_init.c Mon Mar 24 14:01:47 2003 +++ linux-2.5.66-bk4/arch/ppc/syslib/prom_init.c Mon Mar 31 12:49:35 2003 @@ -275,7 +275,7 @@ { phandle node; ihandle ih; - int i; + int i, j; char type[16], *path; static unsigned char default_colors[] = { 0x00, 0x00, 0x00, @@ -335,26 +335,23 @@ break; } -try_again: - /* - * Open the first display and set its colormap. - */ - if (prom_num_displays > 0) { - path = prom_display_paths[0]; + for (j=0; j 0) - prom_disp_node = prom_display_nodes[0]; - else + if (--prom_num_displays > 0) { + prom_disp_node = prom_display_nodes[j]; + j--; + } else prom_disp_node = NULL; - goto try_again; + continue; } else { prom_print("... ok\n"); /* @@ -369,7 +366,7 @@ break; #ifdef CONFIG_LOGO_LINUX_CLUT224 - clut = logo_linux_clut224.clut; + clut = PTRRELOC(logo_linux_clut224.clut); for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3) if (prom_set_color(ih, i + 32, clut[0], diff -urN linux-2.5.66-bk3/drivers/char/ipmi/Kconfig linux-2.5.66-bk4/drivers/char/ipmi/Kconfig --- linux-2.5.66-bk3/drivers/char/ipmi/Kconfig Mon Mar 24 14:01:12 2003 +++ linux-2.5.66-bk4/drivers/char/ipmi/Kconfig Mon Mar 31 12:49:35 2003 @@ -7,8 +7,14 @@ tristate 'IPMI top-level message handler' help This enables the central IPMI message handler, required for IPMI - to work. Note that you must have this enabled to do any other IPMI - things. See IPMI.txt for more details. + to work. + + IPMI is a standard for managing sensors (temperature, + voltage, etc.) in a system. + + See Documentation/IPMI.txt for more details on the driver. + + If unsure, say N. config IPMI_PANIC_EVENT bool 'Generate a panic event to all BMCs on a panic' diff -urN linux-2.5.66-bk3/drivers/char/ipmi/ipmi_devintf.c linux-2.5.66-bk4/drivers/char/ipmi/ipmi_devintf.c --- linux-2.5.66-bk3/drivers/char/ipmi/ipmi_devintf.c Mon Mar 24 14:01:22 2003 +++ linux-2.5.66-bk4/drivers/char/ipmi/ipmi_devintf.c Mon Mar 31 12:49:35 2003 @@ -449,7 +449,7 @@ if (if_num > MAX_DEVICES) return; - snprinf(name, sizeof(name), "ipmidev/%d", if_num); + snprintf(name, sizeof(name), "ipmidev/%d", if_num); handles[if_num] = devfs_register(NULL, name, DEVFS_FL_NONE, ipmi_major, if_num, diff -urN linux-2.5.66-bk3/drivers/char/ipmi/ipmi_kcs_intf.c linux-2.5.66-bk4/drivers/char/ipmi/ipmi_kcs_intf.c --- linux-2.5.66-bk3/drivers/char/ipmi/ipmi_kcs_intf.c Mon Mar 24 13:59:46 2003 +++ linux-2.5.66-bk4/drivers/char/ipmi/ipmi_kcs_intf.c Mon Mar 31 12:49:35 2003 @@ -826,7 +826,7 @@ if (kcs_port && kcs_physaddr) return -EINVAL; - new_kcs = kmalloc(kcs_size(), GFP_KERNEL); + new_kcs = kmalloc(sizeof(*new_kcs), GFP_KERNEL); if (!new_kcs) { printk(KERN_ERR "ipmi_kcs: out of memory\n"); return -ENOMEM; diff -urN linux-2.5.66-bk3/drivers/char/ipmi/ipmi_kcs_sm.c linux-2.5.66-bk4/drivers/char/ipmi/ipmi_kcs_sm.c --- linux-2.5.66-bk3/drivers/char/ipmi/ipmi_kcs_sm.c Mon Mar 24 14:00:02 2003 +++ linux-2.5.66-bk4/drivers/char/ipmi/ipmi_kcs_sm.c Mon Mar 31 12:49:35 2003 @@ -468,7 +468,7 @@ break; case KCS_HOSED: - return KCS_SM_HOSED; + break; } if (kcs->state == KCS_HOSED) { diff -urN linux-2.5.66-bk3/drivers/ide/ide-disk.c linux-2.5.66-bk4/drivers/ide/ide-disk.c --- linux-2.5.66-bk3/drivers/ide/ide-disk.c Mon Mar 24 14:00:20 2003 +++ linux-2.5.66-bk4/drivers/ide/ide-disk.c Mon Mar 31 12:49:35 2003 @@ -1098,6 +1098,7 @@ * in above order (i.e., if value of higher priority is available, * reset will be ignored). */ +#define IDE_STROKE_LIMIT (32000*1024*2) static void init_idedisk_capacity (ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -1118,7 +1119,7 @@ drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect); drive->select.b.lba = 1; set_max_ext = idedisk_read_native_max_address_ext(drive); - if (set_max_ext > capacity_2) { + if (set_max_ext > capacity_2 && capacity_2 > IDE_STROKE_LIMIT) { #ifdef CONFIG_IDEDISK_STROKE set_max_ext = idedisk_read_native_max_address_ext(drive); set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext); @@ -1145,7 +1146,7 @@ drive->select.b.lba = 1; } - if (set_max > capacity) { + if (set_max > capacity && capacity > IDE_STROKE_LIMIT) { #ifdef CONFIG_IDEDISK_STROKE set_max = idedisk_read_native_max_address(drive); set_max = idedisk_set_max_address(drive, set_max); diff -urN linux-2.5.66-bk3/drivers/ide/ide-iops.c linux-2.5.66-bk4/drivers/ide/ide-iops.c --- linux-2.5.66-bk3/drivers/ide/ide-iops.c Mon Mar 24 14:00:15 2003 +++ linux-2.5.66-bk4/drivers/ide/ide-iops.c Mon Mar 31 12:49:35 2003 @@ -903,6 +903,14 @@ * Select the drive, and issue the SETFEATURES command */ disable_irq_nosync(hwif->irq); + + /* + * FIXME: we race against the running IRQ here if + * this is called from non IRQ context. If we use + * disable_irq() we hang on the error path. Work + * is needed. + */ + udelay(1); SELECT_DRIVE(drive); SELECT_MASK(drive, 0); diff -urN linux-2.5.66-bk3/drivers/ide/ide-taskfile.c linux-2.5.66-bk4/drivers/ide/ide-taskfile.c --- linux-2.5.66-bk3/drivers/ide/ide-taskfile.c Mon Mar 24 13:59:54 2003 +++ linux-2.5.66-bk4/drivers/ide/ide-taskfile.c Mon Mar 31 12:49:35 2003 @@ -1670,7 +1670,7 @@ #else - int err = 0; + int err = -EIO; u8 args[4], *argbuf = args; u8 xfer_rate = 0; int argsize = 0; diff -urN linux-2.5.66-bk3/drivers/ide/ide-timing.h linux-2.5.66-bk4/drivers/ide/ide-timing.h --- linux-2.5.66-bk3/drivers/ide/ide-timing.h Mon Mar 24 14:00:18 2003 +++ linux-2.5.66-bk4/drivers/ide/ide-timing.h Mon Mar 31 12:49:35 2003 @@ -245,14 +245,6 @@ } /* - * If the drive is an ATAPI device it may need slower address setup timing, - * so we stay on the safe side. - */ - - if (drive->media != ide_disk) - p.setup = 120; - -/* * Convert the timing to bus clock counts. */ diff -urN linux-2.5.66-bk3/drivers/md/linear.c linux-2.5.66-bk4/drivers/md/linear.c --- linux-2.5.66-bk3/drivers/md/linear.c Mon Mar 24 14:00:20 2003 +++ linux-2.5.66-bk4/drivers/md/linear.c Mon Mar 31 12:49:35 2003 @@ -37,7 +37,11 @@ linear_conf_t *conf = mddev_to_conf(mddev); sector_t block = sector >> 1; - hash = conf->hash_table + sector_div(block, conf->smallest->size); + /* + * sector_div(a,b) returns the remainer and sets a to a/b + */ + (void)sector_div(block, conf->smallest->size); + hash = conf->hash_table + block; if ((sector>>1) >= (hash->dev0->size + hash->dev0->offset)) return hash->dev1; @@ -75,8 +79,6 @@ unsigned int curr_offset; struct list_head *tmp; - MOD_INC_USE_COUNT; - conf = kmalloc (sizeof (*conf), GFP_KERNEL); if (!conf) goto out; @@ -163,7 +165,6 @@ out: if (conf) kfree(conf); - MOD_DEC_USE_COUNT; return 1; } @@ -174,8 +175,6 @@ kfree(conf->hash_table); kfree(conf); - MOD_DEC_USE_COUNT; - return 0; } @@ -189,7 +188,7 @@ block = bio->bi_sector >> 1; if (unlikely(!tmp_dev)) { - printk ("linear_make_request : hash->dev1==NULL for block %llu\n", + printk("linear_make_request: hash->dev1==NULL for block %llu\n", (unsigned long long)block); bio_io_error(bio, bio->bi_size); return 0; @@ -199,7 +198,7 @@ || block < tmp_dev->offset)) { char b[BDEVNAME_SIZE]; - printk ("linear_make_request: Block %llu out of bounds on " + printk("linear_make_request: Block %llu out of bounds on " "dev %s size %ld offset %ld\n", (unsigned long long)block, bdevname(tmp_dev->rdev->bdev, b), @@ -242,6 +241,7 @@ static mdk_personality_t linear_personality= { .name = "linear", + .owner = THIS_MODULE, .make_request = linear_make_request, .run = linear_run, .stop = linear_stop, diff -urN linux-2.5.66-bk3/drivers/md/md.c linux-2.5.66-bk4/drivers/md/md.c --- linux-2.5.66-bk3/drivers/md/md.c Mon Mar 24 14:00:14 2003 +++ linux-2.5.66-bk4/drivers/md/md.c Mon Mar 31 12:49:35 2003 @@ -64,6 +64,7 @@ #endif static mdk_personality_t *pers[MAX_PERSONALITY]; +static spinlock_t pers_lock = SPIN_LOCK_UNLOCKED; /* * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' @@ -302,22 +303,6 @@ return 0; } - -#define BAD_MAGIC KERN_ERR \ -"md: invalid raid superblock magic on %s\n" - -#define BAD_MINOR KERN_ERR \ -"md: %s: invalid raid minor (%x)\n" - -#define OUT_OF_MEM KERN_ALERT \ -"md: out of memory.\n" - -#define NO_SB KERN_ERR \ -"md: disabled device %s, could not read superblock.\n" - -#define BAD_CSUM KERN_WARNING \ -"md: invalid superblock checksum on %s\n" - static int alloc_disk_sb(mdk_rdev_t * rdev) { if (rdev->sb_page) @@ -325,7 +310,7 @@ rdev->sb_page = alloc_page(GFP_KERNEL); if (!rdev->sb_page) { - printk(OUT_OF_MEM); + printk(KERN_ALERT "md: out of memory.\n"); return -EINVAL; } @@ -397,7 +382,8 @@ return 0; fail: - printk(NO_SB,bdev_partition_name(rdev->bdev)); + printk(KERN_ERR "md: disabled device %s, could not read superblock.\n", + bdev_partition_name(rdev->bdev)); return -EINVAL; } @@ -526,27 +512,30 @@ sb = (mdp_super_t*)page_address(rdev->sb_page); if (sb->md_magic != MD_SB_MAGIC) { - printk(BAD_MAGIC, bdev_partition_name(rdev->bdev)); + printk(KERN_ERR "md: invalid raid superblock magic on %s\n", + bdev_partition_name(rdev->bdev)); goto abort; } if (sb->major_version != 0 || sb->minor_version != 90) { printk(KERN_WARNING "Bad version number %d.%d on %s\n", - sb->major_version, sb->minor_version, - bdev_partition_name(rdev->bdev)); + sb->major_version, sb->minor_version, + bdev_partition_name(rdev->bdev)); goto abort; } if (sb->md_minor >= MAX_MD_DEVS) { - printk(BAD_MINOR, bdev_partition_name(rdev->bdev), sb->md_minor); + printk(KERN_ERR "md: %s: invalid raid minor (%x)\n", + bdev_partition_name(rdev->bdev), sb->md_minor); goto abort; } if (sb->raid_disks <= 0) goto abort; if (calc_sb_csum(sb) != sb->sb_csum) { - printk(BAD_CSUM, bdev_partition_name(rdev->bdev)); + printk(KERN_WARNING "md: invalid superblock checksum on %s\n", + bdev_partition_name(rdev->bdev)); goto abort; } @@ -565,14 +554,15 @@ mdp_super_t *refsb = (mdp_super_t*)page_address(refdev->sb_page); if (!uuid_equal(refsb, sb)) { printk(KERN_WARNING "md: %s has different UUID to %s\n", - bdev_partition_name(rdev->bdev), - bdev_partition_name(refdev->bdev)); + bdev_partition_name(rdev->bdev), + bdev_partition_name(refdev->bdev)); goto abort; } if (!sb_equal(refsb, sb)) { - printk(KERN_WARNING "md: %s has same UUID but different superblock to %s\n", - bdev_partition_name(rdev->bdev), - bdev_partition_name(refdev->bdev)); + printk(KERN_WARNING "md: %s has same UUID" + " but different superblock to %s\n", + bdev_partition_name(rdev->bdev), + bdev_partition_name(refdev->bdev)); goto abort; } ev1 = md_event(sb); @@ -826,7 +816,8 @@ return -EINVAL; if (calc_sb_1_csum(sb) != sb->sb_csum) { - printk(BAD_CSUM, bdev_partition_name(rdev->bdev)); + printk("md: invalid superblock checksum on %s\n", + bdev_partition_name(rdev->bdev)); return -EINVAL; } rdev->preferred_minor = 0xffff; @@ -843,9 +834,10 @@ sb->level != refsb->level || sb->layout != refsb->layout || sb->chunksize != refsb->chunksize) { - printk(KERN_WARNING "md: %s has strangely different superblock to %s\n", - bdev_partition_name(rdev->bdev), - bdev_partition_name(refdev->bdev)); + printk(KERN_WARNING "md: %s has strangely different" + " superblock to %s\n", + bdev_partition_name(rdev->bdev), + bdev_partition_name(refdev->bdev)); return -EINVAL; } ev1 = le64_to_cpu(sb->events); @@ -1020,11 +1012,12 @@ } same_pdev = match_dev_unit(mddev, rdev); if (same_pdev) - printk( KERN_WARNING -"md%d: WARNING: %s appears to be on the same physical disk as %s. True\n" -" protection against single-disk failure might be compromised.\n", + printk(KERN_WARNING + "md%d: WARNING: %s appears to be on the same physical" + " disk as %s. True\n protection against single-disk" + " failure might be compromised.\n", mdidx(mddev), bdev_partition_name(rdev->bdev), - bdev_partition_name(same_pdev->bdev)); + bdev_partition_name(same_pdev->bdev)); /* Verify rdev->desc_nr is unique. * If it is -1, assign a free number, else @@ -1099,7 +1092,8 @@ static void export_rdev(mdk_rdev_t * rdev) { - printk(KERN_INFO "md: export_rdev(%s)\n",bdev_partition_name(rdev->bdev)); + printk(KERN_INFO "md: export_rdev(%s)\n", + bdev_partition_name(rdev->bdev)); if (rdev->mddev) MD_BUG(); free_disk_sb(rdev); @@ -1135,11 +1129,6 @@ mddev->major_version = 0; } -#undef BAD_CSUM -#undef BAD_MAGIC -#undef OUT_OF_MEM -#undef NO_SB - static void print_desc(mdp_disk_t *desc) { printk(" DISK\n", desc->number, @@ -1151,14 +1140,16 @@ { int i; - printk(KERN_INFO "md: SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n", + printk(KERN_INFO + "md: SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n", sb->major_version, sb->minor_version, sb->patch_version, sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3, sb->ctime); - printk(KERN_INFO "md: L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level, - sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor, - sb->layout, sb->chunk_size); - printk(KERN_INFO "md: UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n", + printk(KERN_INFO "md: L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", + sb->level, sb->size, sb->nr_disks, sb->raid_disks, + sb->md_minor, sb->layout, sb->chunk_size); + printk(KERN_INFO "md: UT:%08x ST:%d AD:%d WD:%d" + " FD:%d SD:%d CSUM:%08x E:%08lx\n", sb->utime, sb->state, sb->active_disks, sb->working_disks, sb->failed_disks, sb->spare_disks, sb->sb_csum, (unsigned long)sb->events_lo); @@ -1182,8 +1173,8 @@ static void print_rdev(mdk_rdev_t *rdev) { printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%d ", - bdev_partition_name(rdev->bdev), - (unsigned long long)rdev->size, rdev->faulty, rdev->in_sync, rdev->desc_nr); + bdev_partition_name(rdev->bdev), (unsigned long long)rdev->size, + rdev->faulty, rdev->in_sync, rdev->desc_nr); if (rdev->sb_loaded) { printk(KERN_INFO "md: rdev superblock:\n"); print_sb((mdp_super_t*)page_address(rdev->sb_page)); @@ -1227,13 +1218,15 @@ return 1; } - dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", bdev_partition_name(rdev->bdev), + dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", + bdev_partition_name(rdev->bdev), (unsigned long long)rdev->sb_offset); if (sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, WRITE)) return 0; - printk("md: write_disk_sb failed for device %s\n", bdev_partition_name(rdev->bdev)); + printk("md: write_disk_sb failed for device %s\n", + bdev_partition_name(rdev->bdev)); return 1; } @@ -1278,8 +1271,9 @@ if (!mddev->persistent) return; - dprintk(KERN_INFO "md: updating md%d RAID superblock on device (in sync %d)\n", - mdidx(mddev),mddev->in_sync); + dprintk(KERN_INFO + "md: updating md%d RAID superblock on device (in sync %d)\n", + mdidx(mddev),mddev->in_sync); err = 0; ITERATE_RDEV(mddev,rdev,tmp) { @@ -1298,10 +1292,12 @@ } if (err) { if (--count) { - printk(KERN_ERR "md: errors occurred during superblock update, repeating\n"); + printk(KERN_ERR "md: errors occurred during superblock" + " update, repeating\n"); goto repeat; } - printk(KERN_ERR "md: excessive errors occurred during superblock update, exiting\n"); + printk(KERN_ERR \ + "md: excessive errors occurred during superblock update, exiting\n"); } } @@ -1323,7 +1319,8 @@ rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL); if (!rdev) { - printk(KERN_ERR "md: could not alloc mem for %s!\n", partition_name(newdev)); + printk(KERN_ERR "md: could not alloc mem for %s!\n", + partition_name(newdev)); return ERR_PTR(-ENOMEM); } memset(rdev, 0, sizeof(*rdev)); @@ -1345,9 +1342,9 @@ size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; if (!size) { - printk(KERN_WARNING - "md: %s has zero or unknown size, marking faulty!\n", - bdev_partition_name(rdev->bdev)); + printk(KERN_WARNING + "md: %s has zero or unknown size, marking faulty!\n", + bdev_partition_name(rdev->bdev)); err = -EINVAL; goto abort_free; } @@ -1356,13 +1353,15 @@ err = super_types[super_format]. load_super(rdev, NULL, super_minor); if (err == -EINVAL) { - printk(KERN_WARNING "md: %s has invalid sb, not importing!\n", - bdev_partition_name(rdev->bdev)); + printk(KERN_WARNING + "md: %s has invalid sb, not importing!\n", + bdev_partition_name(rdev->bdev)); goto abort_free; } if (err < 0) { - printk(KERN_WARNING "md: could not read %s's sb, not importing!\n", - bdev_partition_name(rdev->bdev)); + printk(KERN_WARNING + "md: could not read %s's sb, not importing!\n", + bdev_partition_name(rdev->bdev)); goto abort_free; } } @@ -1384,20 +1383,6 @@ * Check a full RAID array for plausibility */ -#define INCONSISTENT KERN_ERR \ -"md: fatal superblock inconsistency in %s -- removing from array\n" - -#define OUT_OF_DATE KERN_ERR \ -"md: superblock update time inconsistency -- using the most recent one\n" - -#define OLD_VERSION KERN_ALERT \ -"md: md%d: unsupported raid array version %d.%d.%d\n" - -#define NOT_CLEAN_IGNORE KERN_ERR \ -"md: md%d: raid array is not clean -- starting background reconstruction\n" - -#define UNKNOWN_LEVEL KERN_ERR \ -"md: md%d: unsupported raid level %d\n" static int analyze_sbs(mddev_t * mddev) { @@ -1415,7 +1400,10 @@ case 0: break; default: - printk(INCONSISTENT, bdev_partition_name(rdev->bdev)); + printk( KERN_ERR \ + "md: fatal superblock inconsistency in %s" + " -- removing from array\n", + bdev_partition_name(rdev->bdev)); kick_rdev_from_array(rdev); } @@ -1428,8 +1416,9 @@ if (rdev != freshest) if (super_types[mddev->major_version]. validate_super(mddev, rdev)) { - printk(KERN_WARNING "md: kicking non-fresh %s from array!\n", - bdev_partition_name(rdev->bdev)); + printk(KERN_WARNING "md: kicking non-fresh %s" + " from array!\n", + bdev_partition_name(rdev->bdev)); kick_rdev_from_array(rdev); continue; } @@ -1446,26 +1435,24 @@ */ if (mddev->major_version != MD_MAJOR_VERSION || mddev->minor_version > MD_MINOR_VERSION) { - - printk(OLD_VERSION, mdidx(mddev), mddev->major_version, - mddev->minor_version, mddev->patch_version); + printk(KERN_ALERT + "md: md%d: unsupported raid array version %d.%d.%d\n", + mdidx(mddev), mddev->major_version, + mddev->minor_version, mddev->patch_version); goto abort; } if ((mddev->recovery_cp != MaxSector) && ((mddev->level == 1) || (mddev->level == 4) || (mddev->level == 5))) - printk(NOT_CLEAN_IGNORE, mdidx(mddev)); + printk(KERN_ERR "md: md%d: raid array is not clean" + " -- starting background reconstruction\n", + mdidx(mddev)); return 0; abort: return 1; } -#undef INCONSISTENT -#undef OUT_OF_DATE -#undef OLD_VERSION -#undef OLD_LEVEL - static int device_size_calculation(mddev_t * mddev) { int data_disks = 0; @@ -1484,9 +1471,11 @@ continue; if (rdev->size < mddev->chunk_size / 1024) { printk(KERN_WARNING - "md: Dev %s smaller than chunk_size: %lluk < %dk\n", + "md: Dev %s smaller than chunk_size:" + " %lluk < %dk\n", bdev_partition_name(rdev->bdev), - (unsigned long long)rdev->size, mddev->chunk_size / 1024); + (unsigned long long)rdev->size, + mddev->chunk_size / 1024); return -EINVAL; } } @@ -1517,7 +1506,8 @@ data_disks = mddev->raid_disks-1; break; default: - printk(UNKNOWN_LEVEL, mdidx(mddev), mddev->level); + printk(KERN_ERR "md: md%d: unsupported raid level %d\n", + mdidx(mddev), mddev->level); goto abort; } if (!md_size[mdidx(mddev)]) @@ -1539,7 +1529,7 @@ printk(KERN_INFO "md%d: %d data-disks, max readahead per data-disk: %ldk\n", - mdidx(mddev), data_disks, readahead/data_disks*(PAGE_SIZE/1024)); + mdidx(mddev), data_disks, readahead/data_disks*(PAGE_SIZE/1024)); return 0; abort: return 1; @@ -1589,14 +1579,6 @@ md_wakeup_thread(mddev->thread); } -#define TOO_BIG_CHUNKSIZE KERN_ERR \ -"too big chunk_size: %d > %d\n" - -#define TOO_SMALL_CHUNKSIZE KERN_ERR \ -"too small chunk_size: %d < %ld\n" - -#define BAD_CHUNKSIZE KERN_ERR \ -"no chunksize specified, see 'man raidtab'\n" static int do_md_run(mddev_t * mddev) { @@ -1639,11 +1621,13 @@ * we abort here to be on the safe side. We don't * want to continue the bad practice. */ - printk(BAD_CHUNKSIZE); + printk(KERN_ERR + "no chunksize specified, see 'man raidtab'\n"); return -EINVAL; } if (chunk_size > MAX_CHUNK_SIZE) { - printk(TOO_BIG_CHUNKSIZE, chunk_size, MAX_CHUNK_SIZE); + printk(KERN_ERR "too big chunk_size: %d > %d\n", + chunk_size, MAX_CHUNK_SIZE); return -EINVAL; } /* @@ -1654,7 +1638,8 @@ return -EINVAL; } if (chunk_size < PAGE_SIZE) { - printk(TOO_SMALL_CHUNKSIZE, chunk_size, PAGE_SIZE); + printk(KERN_ERR "too small chunk_size: %d < %ld\n", + chunk_size, PAGE_SIZE); return -EINVAL; } } @@ -1664,20 +1649,14 @@ return -EINVAL; } +#ifdef CONFIG_KMOD if (!pers[pnum]) { -#ifdef CONFIG_KMOD char module_name[80]; sprintf (module_name, "md-personality-%d", pnum); request_module (module_name); - if (!pers[pnum]) -#endif - { - printk(KERN_ERR "md: personality %d is not loaded!\n", - pnum); - return -EINVAL; - } } +#endif if (device_size_calculation(mddev)) return -EINVAL; @@ -1711,13 +1690,23 @@ disk = disks[mdidx(mddev)]; if (!disk) return -ENOMEM; + + spin_lock(&pers_lock); + if (!pers[pnum] || !try_module_get(pers[pnum]->owner)) { + spin_unlock(&pers_lock); + printk(KERN_ERR "md: personality %d is not loaded!\n", + pnum); + return -EINVAL; + } + mddev->pers = pers[pnum]; + spin_unlock(&pers_lock); blk_queue_make_request(&mddev->queue, mddev->pers->make_request); printk("%s: setting max_sectors to %d, segment boundary to %d\n", - disk->disk_name, - chunk_size >> 9, - (chunk_size>>1)-1); + disk->disk_name, + chunk_size >> 9, + (chunk_size>>1)-1); blk_queue_max_sectors(&mddev->queue, chunk_size >> 9); blk_queue_segment_boundary(&mddev->queue, (chunk_size>>1) - 1); mddev->queue.queuedata = mddev; @@ -1726,6 +1715,7 @@ if (err) { printk(KERN_ERR "md: pers->run() failed ...\n"); mddev->pers = NULL; + module_put(mddev->pers->owner); return -EINVAL; } atomic_set(&mddev->writes_pending,0); @@ -1741,9 +1731,6 @@ return (0); } -#undef TOO_BIG_CHUNKSIZE -#undef BAD_CHUNKSIZE - static int restart_array(mddev_t *mddev) { struct gendisk *disk = disks[mdidx(mddev)]; @@ -1765,8 +1752,8 @@ mddev->ro = 0; set_disk_ro(disk, 0); - printk(KERN_INFO - "md: md%d switched to read-write mode.\n", mdidx(mddev)); + printk(KERN_INFO "md: md%d switched to read-write mode.\n", + mdidx(mddev)); /* * Kick recovery or resync if necessary */ @@ -1783,18 +1770,13 @@ return err; } -#define STILL_MOUNTED KERN_WARNING \ -"md: md%d still mounted.\n" -#define STILL_IN_USE \ -"md: md%d still in use.\n" - static int do_md_stop(mddev_t * mddev, int ro) { int err = 0; struct gendisk *disk = disks[mdidx(mddev)]; if (atomic_read(&mddev->active)>2) { - printk(STILL_IN_USE, mdidx(mddev)); + printk("md: md%d still in use.\n",mdidx(mddev)); err = -EBUSY; goto out; } @@ -1824,6 +1806,7 @@ set_disk_ro(disk, 1); goto out; } + module_put(mddev->pers->owner); mddev->pers = NULL; if (mddev->ro) mddev->ro = 0; @@ -1850,7 +1833,8 @@ if (disk) set_capacity(disk, 0); } else - printk(KERN_INFO "md: md%d switched to read-only mode.\n", mdidx(mddev)); + printk(KERN_INFO "md: md%d switched to read-only mode.\n", + mdidx(mddev)); err = 0; out: return err; @@ -1905,11 +1889,13 @@ rdev0 = list_entry(pending_raid_disks.next, mdk_rdev_t, same_set); - printk(KERN_INFO "md: considering %s ...\n", bdev_partition_name(rdev0->bdev)); + printk(KERN_INFO "md: considering %s ...\n", + bdev_partition_name(rdev0->bdev)); INIT_LIST_HEAD(&candidates); ITERATE_RDEV_PENDING(rdev,tmp) if (super_90_load(rdev, rdev0, 0) >= 0) { - printk(KERN_INFO "md: adding %s ...\n", bdev_partition_name(rdev->bdev)); + printk(KERN_INFO "md: adding %s ...\n", + bdev_partition_name(rdev->bdev)); list_move(&rdev->same_set, &candidates); } /* @@ -1920,7 +1906,8 @@ mddev = mddev_find(rdev0->preferred_minor); if (!mddev) { - printk(KERN_ERR "md: cannot allocate memory for md drive.\n"); + printk(KERN_ERR + "md: cannot allocate memory for md drive.\n"); break; } if (mddev_lock(mddev)) @@ -1928,8 +1915,9 @@ mdidx(mddev)); else if (mddev->raid_disks || mddev->major_version || !list_empty(&mddev->disks)) { - printk(KERN_WARNING "md: md%d already running, cannot run %s\n", - mdidx(mddev), bdev_partition_name(rdev0->bdev)); + printk(KERN_WARNING + "md: md%d already running, cannot run %s\n", + mdidx(mddev), bdev_partition_name(rdev0->bdev)); mddev_unlock(mddev); } else { printk(KERN_INFO "md: created md%d\n", mdidx(mddev)); @@ -1956,33 +1944,6 @@ * if possible, the array gets run as well. */ -#define BAD_VERSION KERN_ERR \ -"md: %s has RAID superblock version 0.%d, autodetect needs v0.90 or higher\n" - -#define OUT_OF_MEM KERN_ALERT \ -"md: out of memory.\n" - -#define NO_DEVICE KERN_ERR \ -"md: disabled device %s\n" - -#define AUTOADD_FAILED KERN_ERR \ -"md: auto-adding devices to md%d FAILED (error %d).\n" - -#define AUTOADD_FAILED_USED KERN_ERR \ -"md: cannot auto-add device %s to md%d, already used.\n" - -#define AUTORUN_FAILED KERN_ERR \ -"md: auto-running md%d FAILED (error %d).\n" - -#define MDDEV_BUSY KERN_ERR \ -"md: cannot auto-add to md%d, already running.\n" - -#define AUTOADDING KERN_INFO \ -"md: auto-adding devices to md%d, based on %s's superblock.\n" - -#define AUTORUNNING KERN_INFO \ -"md: auto-running md%d.\n" - static int autostart_array(dev_t startdev) { int err = -EINVAL, i; @@ -1991,7 +1952,8 @@ start_rdev = md_import_device(startdev, 0, 0); if (IS_ERR(start_rdev)) { - printk(KERN_WARNING "md: could not import %s!\n", partition_name(startdev)); + printk(KERN_WARNING "md: could not import %s!\n", + partition_name(startdev)); return err; } @@ -2005,8 +1967,9 @@ } if (start_rdev->faulty) { - printk(KERN_WARNING "md: can not autostart based on faulty %s!\n", - bdev_partition_name(start_rdev->bdev)); + printk(KERN_WARNING + "md: can not autostart based on faulty %s!\n", + bdev_partition_name(start_rdev->bdev)); export_rdev(start_rdev); return err; } @@ -2025,8 +1988,9 @@ continue; rdev = md_import_device(dev, 0, 0); if (IS_ERR(rdev)) { - printk(KERN_WARNING "md: could not import %s, trying to run array nevertheless.\n", - partition_name(dev)); + printk(KERN_WARNING "md: could not import %s," + " trying to run array nevertheless.\n", + partition_name(dev)); continue; } list_add(&rdev->same_set, &pending_raid_disks); @@ -2040,15 +2004,6 @@ } -#undef BAD_VERSION -#undef OUT_OF_MEM -#undef NO_DEVICE -#undef AUTOADD_FAILED_USED -#undef AUTOADD_FAILED -#undef AUTORUN_FAILED -#undef AUTOADDING -#undef AUTORUNNING - static int get_version(void * arg) { @@ -2113,8 +2068,6 @@ return 0; } -#undef SET_FROM_SB - static int get_disk_info(mddev_t * mddev, void * arg) { @@ -2161,7 +2114,9 @@ /* expecting a device which has a superblock */ rdev = md_import_device(dev, mddev->major_version, mddev->minor_version); if (IS_ERR(rdev)) { - printk(KERN_WARNING "md: md_import_device returned %ld\n", PTR_ERR(rdev)); + printk(KERN_WARNING + "md: md_import_device returned %ld\n", + PTR_ERR(rdev)); return PTR_ERR(rdev); } if (!list_empty(&mddev->disks)) { @@ -2170,8 +2125,10 @@ int err = super_types[mddev->major_version] .load_super(rdev, rdev0, mddev->minor_version); if (err < 0) { - printk(KERN_WARNING "md: %s has different UUID to %s\n", - bdev_partition_name(rdev->bdev), bdev_partition_name(rdev0->bdev)); + printk(KERN_WARNING + "md: %s has different UUID to %s\n", + bdev_partition_name(rdev->bdev), + bdev_partition_name(rdev0->bdev)); export_rdev(rdev); return -EINVAL; } @@ -2190,14 +2147,17 @@ if (mddev->pers) { int err; if (!mddev->pers->hot_add_disk) { - printk(KERN_WARNING "md%d: personality does not support diskops!\n", + printk(KERN_WARNING + "md%d: personality does not support diskops!\n", mdidx(mddev)); return -EINVAL; } rdev = md_import_device(dev, mddev->major_version, mddev->minor_version); if (IS_ERR(rdev)) { - printk(KERN_WARNING "md: md_import_device returned %ld\n", PTR_ERR(rdev)); + printk(KERN_WARNING + "md: md_import_device returned %ld\n", + PTR_ERR(rdev)); return PTR_ERR(rdev); } rdev->in_sync = 0; /* just to be sure */ @@ -2223,7 +2183,9 @@ int err; rdev = md_import_device (dev, -1, 0); if (IS_ERR(rdev)) { - printk(KERN_WARNING "md: error, md_import_device() returned %ld\n", PTR_ERR(rdev)); + printk(KERN_WARNING + "md: error, md_import_device() returned %ld\n", + PTR_ERR(rdev)); return PTR_ERR(rdev); } rdev->desc_nr = info->number; @@ -2333,19 +2295,23 @@ partition_name(dev), mdidx(mddev)); if (mddev->major_version != 0) { - printk(KERN_WARNING "md%d: HOT_ADD may only be used with version-0 superblocks.\n", - mdidx(mddev)); + printk(KERN_WARNING "md%d: HOT_ADD may only be used with" + " version-0 superblocks.\n", + mdidx(mddev)); return -EINVAL; } if (!mddev->pers->hot_add_disk) { - printk(KERN_WARNING "md%d: personality does not support diskops!\n", - mdidx(mddev)); + printk(KERN_WARNING + "md%d: personality does not support diskops!\n", + mdidx(mddev)); return -EINVAL; } rdev = md_import_device (dev, -1, 0); if (IS_ERR(rdev)) { - printk(KERN_WARNING "md: error, md_import_device() returned %ld\n", PTR_ERR(rdev)); + printk(KERN_WARNING + "md: error, md_import_device() returned %ld\n", + PTR_ERR(rdev)); return -EINVAL; } @@ -2354,16 +2320,18 @@ rdev->size = size; if (size < mddev->size) { - printk(KERN_WARNING "md%d: disk size %llu blocks < array size %llu\n", - mdidx(mddev), (unsigned long long)size, - (unsigned long long)mddev->size); + printk(KERN_WARNING + "md%d: disk size %llu blocks < array size %llu\n", + mdidx(mddev), (unsigned long long)size, + (unsigned long long)mddev->size); err = -ENOSPC; goto abort_export; } if (rdev->faulty) { - printk(KERN_WARNING "md: can not hot-add faulty %s disk to md%d!\n", - bdev_partition_name(rdev->bdev), mdidx(mddev)); + printk(KERN_WARNING + "md: can not hot-add faulty %s disk to md%d!\n", + bdev_partition_name(rdev->bdev), mdidx(mddev)); err = -EINVAL; goto abort_export; } @@ -2378,7 +2346,7 @@ if (rdev->desc_nr == mddev->max_disks) { printk(KERN_WARNING "md%d: can not hot-add to full array!\n", - mdidx(mddev)); + mdidx(mddev)); err = -EBUSY; goto abort_unbind_export; } @@ -2426,8 +2394,9 @@ info->major_version >= sizeof(super_types)/sizeof(super_types[0]) || super_types[info->major_version].name == NULL) { /* maybe try to auto-load a module? */ - printk(KERN_INFO "md: superblock version %d not known\n", - info->major_version); + printk(KERN_INFO + "md: superblock version %d not known\n", + info->major_version); return -EINVAL; } mddev->major_version = info->major_version; @@ -2540,7 +2509,7 @@ err = autostart_array(arg); if (err) { printk(KERN_WARNING "md: autostart %s failed!\n", - partition_name(arg)); + partition_name(arg)); goto abort; } goto done; @@ -2548,8 +2517,9 @@ err = mddev_lock(mddev); if (err) { - printk(KERN_INFO "md: ioctl lock interrupted, reason %d, cmd %d\n", - err, cmd); + printk(KERN_INFO + "md: ioctl lock interrupted, reason %d, cmd %d\n", + err, cmd); goto abort; } @@ -2558,13 +2528,15 @@ case SET_ARRAY_INFO: if (!list_empty(&mddev->disks)) { - printk(KERN_WARNING "md: array md%d already has disks!\n", + printk(KERN_WARNING + "md: array md%d already has disks!\n", mdidx(mddev)); err = -EBUSY; goto abort_unlock; } if (mddev->raid_disks) { - printk(KERN_WARNING "md: array md%d already initialised!\n", + printk(KERN_WARNING + "md: array md%d already initialised!\n", mdidx(mddev)); err = -EBUSY; goto abort_unlock; @@ -2579,7 +2551,8 @@ } err = set_array_info(mddev, &info); if (err) { - printk(KERN_WARNING "md: couldn't set array info. %d\n", err); + printk(KERN_WARNING "md: couldn't set" + " array info. %d\n", err); goto abort_unlock; } } @@ -2701,9 +2674,10 @@ default: if (_IOC_TYPE(cmd) == MD_MAJOR) - printk(KERN_WARNING "md: %s(pid %d) used obsolete MD ioctl, " - "upgrade your software to use new ictls.\n", - current->comm, current->pid); + printk(KERN_WARNING "md: %s(pid %d) used" + " obsolete MD ioctl, upgrade your" + " software to use new ictls.\n", + current->comm, current->pid); err = -EINVAL; goto abort_unlock; } @@ -2879,7 +2853,8 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) { dprintk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", - MD_MAJOR,mdidx(mddev),MAJOR(rdev->bdev->bd_dev),MINOR(rdev->bdev->bd_dev), + MD_MAJOR,mdidx(mddev), + MAJOR(rdev->bdev->bd_dev), MINOR(rdev->bdev->bd_dev), __builtin_return_address(0),__builtin_return_address(1), __builtin_return_address(2),__builtin_return_address(3)); @@ -3038,10 +3013,12 @@ if (v == (void*)1) { seq_printf(seq, "Personalities : "); + spin_lock(&pers_lock); for (i = 0; i < MAX_PERSONALITY; i++) if (pers[i]) seq_printf(seq, "[%s] ", pers[i]->name); + spin_unlock(&pers_lock); seq_printf(seq, "\n"); return 0; } @@ -3125,13 +3102,16 @@ return -EINVAL; } + spin_lock(&pers_lock); if (pers[pnum]) { + spin_unlock(&pers_lock); MD_BUG(); return -EBUSY; } pers[pnum] = p; printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum); + spin_unlock(&pers_lock); return 0; } @@ -3143,7 +3123,9 @@ } printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name); + spin_lock(&pers_lock); pers[pnum] = NULL; + spin_unlock(&pers_lock); return 0; } @@ -3228,7 +3210,8 @@ void md_handle_safemode(mddev_t *mddev) { if (signal_pending(current)) { - printk(KERN_INFO "md: md%d in immediate safe mode\n",mdidx(mddev)); + printk(KERN_INFO "md: md%d in immediate safe mode\n", + mdidx(mddev)); mddev->safemode = 2; flush_signals(current); } @@ -3271,8 +3254,9 @@ continue; if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) { - printk(KERN_INFO "md: delaying resync of md%d until md%d " - "has finished resync (they share one or more physical units)\n", + printk(KERN_INFO "md: delaying resync of md%d" + " until md%d has finished resync (they" + " share one or more physical units)\n", mdidx(mddev), mdidx(mddev2)); if (mddev < mddev2) {/* arbitrarily yield */ mddev->curr_resync = 1; @@ -3295,7 +3279,8 @@ max_sectors = mddev->size << 1; printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev)); - printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n", sysctl_speed_limit_min); + printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:" + " %d KB/sec/disc.\n", sysctl_speed_limit_min); printk(KERN_INFO "md: using maximum available idle IO bandwith " "(but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max); @@ -3318,14 +3303,16 @@ */ window = 32*(PAGE_SIZE/512); printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n", - window/2,max_sectors/2); + window/2,max_sectors/2); atomic_set(&mddev->recovery_active, 0); init_waitqueue_head(&mddev->recovery_wait); last_check = 0; if (j) - printk(KERN_INFO "md: resuming recovery of md%d from checkpoint.\n", mdidx(mddev)); + printk(KERN_INFO + "md: resuming recovery of md%d from checkpoint.\n", + mdidx(mddev)); while (j < max_sectors) { int sectors; @@ -3367,7 +3354,8 @@ /* * got a signal, exit. */ - printk(KERN_INFO "md: md_do_sync() got signal ... exiting\n"); + printk(KERN_INFO + "md: md_do_sync() got signal ... exiting\n"); flush_signals(current); set_bit(MD_RECOVERY_INTR, &mddev->recovery); goto out; @@ -3408,7 +3396,9 @@ mddev->curr_resync > 2 && mddev->curr_resync > mddev->recovery_cp) { if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { - printk(KERN_INFO "md: checkpointing recovery of md%d.\n", mdidx(mddev)); + printk(KERN_INFO + "md: checkpointing recovery of md%d.\n", + mdidx(mddev)); mddev->recovery_cp = mddev->curr_resync; } else mddev->recovery_cp = MaxSector; @@ -3526,7 +3516,9 @@ mddev, "md%d_resync"); if (!mddev->sync_thread) { - printk(KERN_ERR "md%d: could not start resync thread...\n", mdidx(mddev)); + printk(KERN_ERR "md%d: could not start resync" + " thread...\n", + mdidx(mddev)); /* leave the spares where they are, it shouldn't hurt */ mddev->recovery = 0; } else { @@ -3590,7 +3582,8 @@ { int minor; - printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d, MD_SB_DISKS=%d\n", + printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d," + " MD_SB_DISKS=%d\n", MD_MAJOR_VERSION, MD_MINOR_VERSION, MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); diff -urN linux-2.5.66-bk3/drivers/md/multipath.c linux-2.5.66-bk4/drivers/md/multipath.c --- linux-2.5.66-bk3/drivers/md/multipath.c Mon Mar 24 14:00:21 2003 +++ linux-2.5.66-bk4/drivers/md/multipath.c Mon Mar 31 12:49:35 2003 @@ -78,7 +78,7 @@ } spin_unlock_irq(&conf->device_lock); - printk (KERN_ERR "multipath_map(): no more operational IO paths?\n"); + printk(KERN_ERR "multipath_map(): no more operational IO paths?\n"); return (-1); } @@ -130,7 +130,8 @@ */ md_error (mp_bh->mddev, rdev); printk(KERN_ERR "multipath: %s: rescheduling sector %llu\n", - bdev_partition_name(rdev->bdev), (unsigned long long)bio->bi_sector); + bdev_partition_name(rdev->bdev), + (unsigned long long)bio->bi_sector); multipath_reschedule_retry(mp_bh); } atomic_dec(&rdev->nr_pending); @@ -198,16 +199,6 @@ seq_printf (seq, "]"); } -#define LAST_DISK KERN_ALERT \ -"multipath: only one IO path left and IO error.\n" - -#define NO_SPARE_DISK KERN_ALERT \ -"multipath: no spare IO path left!\n" - -#define DISK_FAILED KERN_ALERT \ -"multipath: IO failure on %s, disabling IO path. \n" \ -" Operation continuing on %d IO paths.\n" - /* * Careful, this can execute in IRQ contexts as well! @@ -222,7 +213,8 @@ * first check if this is a queued request for a device * which has just failed. */ - printk (LAST_DISK); + printk(KERN_ALERT + "multipath: only one IO path left and IO error.\n"); /* leave it active... it's all we have */ } else { /* @@ -233,17 +225,15 @@ rdev->faulty = 1; mddev->sb_dirty = 1; conf->working_disks--; - printk (DISK_FAILED, bdev_partition_name (rdev->bdev), + printk(KERN_ALERT "multipath: IO failure on %s," + " disabling IO path. \n Operation continuing" + " on %d IO paths.\n", + bdev_partition_name (rdev->bdev), conf->working_disks); } } } -#undef LAST_DISK -#undef NO_SPARE_DISK -#undef DISK_FAILED - - static void print_multipath_conf (multipath_conf_t *conf) { int i; @@ -302,7 +292,7 @@ if (p->rdev) { if (p->rdev->in_sync || atomic_read(&p->rdev->nr_pending)) { - printk(KERN_ERR "hot-remove-disk, slot %d is identified but is still operational!\n", number); + printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); err = -EBUSY; goto abort; } @@ -318,11 +308,7 @@ return err; } -#define IO_ERROR KERN_ALERT \ -"multipath: %s: unrecoverable IO read error for block %llu\n" -#define REDIRECT_SECTOR KERN_ERR \ -"multipath: %s: redirecting sector %llu to another IO path\n" /* * This is a kernel thread which: @@ -354,59 +340,22 @@ rdev = NULL; if (multipath_map (mddev, &rdev)<0) { - printk(IO_ERROR, - bdev_partition_name(bio->bi_bdev), (unsigned long long)bio->bi_sector); + printk(KERN_ALERT "multipath: %s: unrecoverable IO read" + " error for block %llu\n", + bdev_partition_name(bio->bi_bdev), + (unsigned long long)bio->bi_sector); multipath_end_bh_io(mp_bh, 0); } else { - printk(REDIRECT_SECTOR, - bdev_partition_name(bio->bi_bdev), (unsigned long long)bio->bi_sector); + printk(KERN_ERR "multipath: %s: redirecting sector %llu" + " to another IO path\n", + bdev_partition_name(bio->bi_bdev), + (unsigned long long)bio->bi_sector); bio->bi_bdev = rdev->bdev; generic_make_request(bio); } } spin_unlock_irqrestore(&retry_list_lock, flags); } -#undef IO_ERROR -#undef REDIRECT_SECTOR - -#define INVALID_LEVEL KERN_WARNING \ -"multipath: md%d: raid level not set to multipath IO (%d)\n" - -#define NO_SB KERN_ERR \ -"multipath: disabled IO path %s (couldn't access raid superblock)\n" - -#define ERRORS KERN_ERR \ -"multipath: disabled IO path %s (errors detected)\n" - -#define NOT_IN_SYNC KERN_ERR \ -"multipath: making IO path %s a spare path (not in sync)\n" - -#define INCONSISTENT KERN_ERR \ -"multipath: disabled IO path %s (inconsistent descriptor)\n" - -#define ALREADY_RUNNING KERN_ERR \ -"multipath: disabled IO path %s (multipath %d already operational)\n" - -#define OPERATIONAL KERN_INFO \ -"multipath: device %s operational as IO path %d\n" - -#define MEM_ERROR KERN_ERR \ -"multipath: couldn't allocate memory for md%d\n" - -#define SPARE KERN_INFO \ -"multipath: spare IO path %s\n" - -#define NONE_OPERATIONAL KERN_ERR \ -"multipath: no operational IO paths for md%d\n" - -#define SB_DIFFERENCES KERN_ERR \ -"multipath: detected IO path differences!\n" - -#define ARRAY_IS_ACTIVE KERN_INFO \ -"multipath: array md%d active with %d out of %d IO paths\n" - -#define THREAD_ERROR KERN_ERR \ -"multipath: couldn't allocate thread for md%d\n" static int multipath_run (mddev_t *mddev) { @@ -416,10 +365,9 @@ mdk_rdev_t *rdev; struct list_head *tmp; - MOD_INC_USE_COUNT; - if (mddev->level != LEVEL_MULTIPATH) { - printk(INVALID_LEVEL, mdidx(mddev), mddev->level); + printk("multipath: md%d: raid level not set to multipath IO (%d)\n", + mdidx(mddev), mddev->level); goto out; } /* @@ -431,7 +379,9 @@ conf = kmalloc(sizeof(multipath_conf_t), GFP_KERNEL); mddev->private = conf; if (!conf) { - printk(MEM_ERROR, mdidx(mddev)); + printk(KERN_ERR + "multipath: couldn't allocate memory for md%d\n", + mdidx(mddev)); goto out; } memset(conf, 0, sizeof(*conf)); @@ -455,7 +405,8 @@ conf->device_lock = SPIN_LOCK_UNLOCKED; if (!conf->working_disks) { - printk(NONE_OPERATIONAL, mdidx(mddev)); + printk(KERN_ERR "multipath: no operational IO paths for md%d\n", + mdidx(mddev)); goto out_free_conf; } mddev->degraded = conf->raid_disks = conf->working_disks; @@ -464,7 +415,9 @@ mp_pool_alloc, mp_pool_free, NULL); if (conf->pool == NULL) { - printk(MEM_ERROR, mdidx(mddev)); + printk(KERN_ERR + "multipath: couldn't allocate memory for md%d\n", + mdidx(mddev)); goto out_free_conf; } @@ -473,13 +426,15 @@ mddev->thread = md_register_thread(multipathd, mddev, name); if (!mddev->thread) { - printk(THREAD_ERROR, mdidx(mddev)); + printk(KERN_ERR "multipath: couldn't allocate thread" + " for md%d\n", mdidx(mddev)); goto out_free_conf; } } - printk(ARRAY_IS_ACTIVE, mdidx(mddev), conf->working_disks, - mddev->raid_disks); + printk(KERN_INFO + "multipath: array md%d active with %d out of %d IO paths\n", + mdidx(mddev), conf->working_disks, mddev->raid_disks); /* * Ok, everything is just fine now */ @@ -491,21 +446,9 @@ kfree(conf); mddev->private = NULL; out: - MOD_DEC_USE_COUNT; return -EIO; } -#undef INVALID_LEVEL -#undef NO_SB -#undef ERRORS -#undef NOT_IN_SYNC -#undef INCONSISTENT -#undef ALREADY_RUNNING -#undef OPERATIONAL -#undef SPARE -#undef NONE_OPERATIONAL -#undef SB_DIFFERENCES -#undef ARRAY_IS_ACTIVE static int multipath_stop (mddev_t *mddev) { @@ -515,13 +458,13 @@ mempool_destroy(conf->pool); kfree(conf); mddev->private = NULL; - MOD_DEC_USE_COUNT; return 0; } static mdk_personality_t multipath_personality= { .name = "multipath", + .owner = THIS_MODULE, .make_request = multipath_make_request, .run = multipath_run, .stop = multipath_stop, diff -urN linux-2.5.66-bk3/drivers/md/raid0.c linux-2.5.66-bk4/drivers/md/raid0.c --- linux-2.5.66-bk3/drivers/md/raid0.c Mon Mar 24 14:00:44 2003 +++ linux-2.5.66-bk4/drivers/md/raid0.c Mon Mar 31 12:49:35 2003 @@ -43,12 +43,15 @@ conf->nr_strip_zones = 0; ITERATE_RDEV(mddev,rdev1,tmp1) { - printk("raid0: looking at %s\n", bdev_partition_name(rdev1->bdev)); + printk("raid0: looking at %s\n", + bdev_partition_name(rdev1->bdev)); c = 0; ITERATE_RDEV(mddev,rdev2,tmp2) { printk("raid0: comparing %s(%llu) with %s(%llu)\n", - bdev_partition_name(rdev1->bdev), (unsigned long long)rdev1->size, - bdev_partition_name(rdev2->bdev), (unsigned long long)rdev2->size); + bdev_partition_name(rdev1->bdev), + (unsigned long long)rdev1->size, + bdev_partition_name(rdev2->bdev), + (unsigned long long)rdev2->size); if (rdev2 == rdev1) { printk("raid0: END\n"); break; @@ -94,7 +97,8 @@ goto abort; } if (zone->dev[j]) { - printk("raid0: multiple devices for %d - aborting!\n", j); + printk("raid0: multiple devices for %d - aborting!\n", + j); goto abort; } zone->dev[j] = rdev1; @@ -103,8 +107,8 @@ cnt++; } if (cnt != mddev->raid_disks) { - printk("raid0: too few disks (%d of %d) - aborting!\n", cnt, - mddev->raid_disks); + printk("raid0: too few disks (%d of %d) - aborting!\n", + cnt, mddev->raid_disks); goto abort; } zone->nb_dev = cnt; @@ -136,7 +140,7 @@ if (!smallest || (rdev->size size)) { smallest = rdev; printk(" (%llu) is smallest!.\n", - (unsigned long long)rdev->size); + (unsigned long long)rdev->size); } } else printk(" nope.\n"); @@ -144,7 +148,8 @@ zone->nb_dev = c; zone->size = (smallest->size - current_offset) * c; - printk("raid0: zone->nb_dev: %d, size: %llu\n",zone->nb_dev, (unsigned long long)zone->size); + printk("raid0: zone->nb_dev: %d, size: %llu\n", + zone->nb_dev, (unsigned long long)zone->size); if (!conf->smallest || (zone->size < conf->smallest->size)) conf->smallest = zone; @@ -153,7 +158,8 @@ curr_zone_offset += zone->size; current_offset = smallest->size; - printk("raid0: current zone offset: %llu\n", (unsigned long long)current_offset); + printk("raid0: current zone offset: %llu\n", + (unsigned long long)current_offset); } printk("raid0: done.\n"); return 0; @@ -191,8 +197,6 @@ s64 size; raid0_conf_t *conf; - MOD_INC_USE_COUNT; - conf = vmalloc(sizeof (raid0_conf_t)); if (!conf) goto out; @@ -201,8 +205,10 @@ if (create_strip_zones (mddev)) goto out_free_conf; - printk("raid0 : md_size is %llu blocks.\n", (unsigned long long)md_size[mdidx(mddev)]); - printk("raid0 : conf->smallest->size is %llu blocks.\n", (unsigned long long)conf->smallest->size); + printk("raid0 : md_size is %llu blocks.\n", + (unsigned long long)md_size[mdidx(mddev)]); + printk("raid0 : conf->smallest->size is %llu blocks.\n", + (unsigned long long)conf->smallest->size); { #if __GNUC__ < 3 volatile @@ -267,7 +273,6 @@ vfree(conf); mddev->private = NULL; out: - MOD_DEC_USE_COUNT; return 1; } @@ -282,7 +287,6 @@ vfree (conf); mddev->private = NULL; - MOD_DEC_USE_COUNT; return 0; } @@ -357,16 +361,21 @@ return 1; bad_map: - printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %llu %d\n", chunk_size, (unsigned long long)bio->bi_sector, bio->bi_size >> 10); + printk("raid0_make_request bug: can't convert block across chunks" + " or bigger than %dk %llu %d\n", chunk_size, + (unsigned long long)bio->bi_sector, bio->bi_size >> 10); goto outerr; bad_hash: - printk("raid0_make_request bug: hash==NULL for block %llu\n", (unsigned long long)block); + printk("raid0_make_request bug: hash==NULL for block %llu\n", + (unsigned long long)block); goto outerr; bad_zone0: - printk ("raid0_make_request bug: hash->zone0==NULL for block %llu\n", (unsigned long long)block); + printk("raid0_make_request bug: hash->zone0==NULL for block %llu\n", + (unsigned long long)block); goto outerr; bad_zone1: - printk ("raid0_make_request bug: hash->zone1==NULL for block %llu\n", (unsigned long long)block); + printk("raid0_make_request bug: hash->zone1==NULL for block %llu\n", + (unsigned long long)block); outerr: bio_io_error(bio, bio->bi_size); return 0; @@ -411,6 +420,7 @@ static mdk_personality_t raid0_personality= { .name = "raid0", + .owner = THIS_MODULE, .make_request = raid0_make_request, .run = raid0_run, .stop = raid0_stop, diff -urN linux-2.5.66-bk3/drivers/md/raid1.c linux-2.5.66-bk4/drivers/md/raid1.c --- linux-2.5.66-bk3/drivers/md/raid1.c Mon Mar 24 14:00:44 2003 +++ linux-2.5.66-bk4/drivers/md/raid1.c Mon Mar 31 12:49:35 2003 @@ -217,7 +217,7 @@ } spin_unlock_irq(&conf->device_lock); - printk (KERN_ERR "raid1_map(): huh, no more operational devices?\n"); + printk(KERN_ERR "raid1_map(): huh, no more operational devices?\n"); return -1; } @@ -305,7 +305,7 @@ * oops, read error: */ printk(KERN_ERR "raid1: %s: rescheduling sector %llu\n", - bdev_partition_name(conf->mirrors[mirror].rdev->bdev), (unsigned long long)r1_bio->sector); + bdev_partition_name(conf->mirrors[mirror].rdev->bdev), (unsigned long long)r1_bio->sector); reschedule_retry(r1_bio); } } else { @@ -584,22 +584,6 @@ seq_printf(seq, "]"); } -#define LAST_DISK KERN_ALERT \ -"raid1: only one disk left and IO error.\n" - -#define NO_SPARE_DISK KERN_ALERT \ -"raid1: no spare disk left, degrading mirror level by one.\n" - -#define DISK_FAILED KERN_ALERT \ -"raid1: Disk failure on %s, disabling device. \n" \ -" Operation continuing on %d devices\n" - -#define START_SYNCING KERN_ALERT \ -"raid1: start syncing spare disk.\n" - -#define ALREADY_SYNCING KERN_INFO \ -"raid1: syncing already in progress.\n" - static void error(mddev_t *mddev, mdk_rdev_t *rdev) { @@ -629,7 +613,9 @@ rdev->in_sync = 0; rdev->faulty = 1; mddev->sb_dirty = 1; - printk(DISK_FAILED, bdev_partition_name(rdev->bdev), conf->working_disks); + printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" + " Operation continuing on %d devices\n", + bdev_partition_name(rdev->bdev), conf->working_disks); } static void print_conf(conf_t *conf) @@ -643,14 +629,14 @@ return; } printk(" --- wd:%d rd:%d\n", conf->working_disks, - conf->raid_disks); + conf->raid_disks); for (i = 0; i < conf->raid_disks; i++) { tmp = conf->mirrors + i; if (tmp->rdev) printk(" disk %d, wo:%d, o:%d, dev:%s\n", - i, !tmp->rdev->in_sync, !tmp->rdev->faulty, - bdev_partition_name(tmp->rdev->bdev)); + i, !tmp->rdev->in_sync, !tmp->rdev->faulty, + bdev_partition_name(tmp->rdev->bdev)); } } @@ -743,11 +729,6 @@ return err; } -#define IO_ERROR KERN_ALERT \ -"raid1: %s: unrecoverable I/O read error for block %llu\n" - -#define REDIRECT_SECTOR KERN_ERR \ -"raid1: %s: redirecting sector %llu to another mirror\n" static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) { @@ -823,7 +804,10 @@ * There is no point trying a read-for-reconstruct as * reconstruct is about to be aborted */ - printk(IO_ERROR, bdev_partition_name(bio->bi_bdev), (unsigned long long)r1_bio->sector); + printk(KERN_ALERT "raid1: %s: unrecoverable I/O read error" + " for block %llu\n", + bdev_partition_name(bio->bi_bdev), + (unsigned long long)r1_bio->sector); md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0); put_buf(r1_bio); return; @@ -874,7 +858,8 @@ * Nowhere to write this to... I guess we * must be done */ - printk(KERN_ALERT "raid1: sync aborting as there is nowhere to write sector %llu\n", + printk(KERN_ALERT "raid1: sync aborting as there is nowhere" + " to write sector %llu\n", (unsigned long long)r1_bio->sector); md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0); put_buf(r1_bio); @@ -928,12 +913,17 @@ case READ: case READA: if (map(mddev, &rdev) == -1) { - printk(IO_ERROR, bdev_partition_name(bio->bi_bdev), (unsigned long long)r1_bio->sector); + printk(KERN_ALERT "raid1: %s: unrecoverable I/O" + " read error for block %llu\n", + bdev_partition_name(bio->bi_bdev), + (unsigned long long)r1_bio->sector); raid_end_bio_io(r1_bio, 0); break; } - printk(REDIRECT_SECTOR, - bdev_partition_name(rdev->bdev), (unsigned long long)r1_bio->sector); + printk(KERN_ERR "raid1: %s: redirecting sector %llu to" + " another mirror\n", + bdev_partition_name(rdev->bdev), + (unsigned long long)r1_bio->sector); bio->bi_bdev = rdev->bdev; bio->bi_sector = r1_bio->sector + rdev->data_offset; bio->bi_rw = r1_bio->cmd; @@ -1063,45 +1053,6 @@ return nr_sectors; } -#define INVALID_LEVEL KERN_WARNING \ -"raid1: md%d: raid level not set to mirroring (%d)\n" - -#define NO_SB KERN_ERR \ -"raid1: disabled mirror %s (couldn't access raid superblock)\n" - -#define ERRORS KERN_ERR \ -"raid1: disabled mirror %s (errors detected)\n" - -#define NOT_IN_SYNC KERN_ERR \ -"raid1: disabled mirror %s (not in sync)\n" - -#define INCONSISTENT KERN_ERR \ -"raid1: disabled mirror %s (inconsistent descriptor)\n" - -#define ALREADY_RUNNING KERN_ERR \ -"raid1: disabled mirror %s (mirror %d already operational)\n" - -#define OPERATIONAL KERN_INFO \ -"raid1: device %s operational as mirror %d\n" - -#define MEM_ERROR KERN_ERR \ -"raid1: couldn't allocate memory for md%d\n" - -#define SPARE KERN_INFO \ -"raid1: spare disk %s\n" - -#define NONE_OPERATIONAL KERN_ERR \ -"raid1: no operational mirrors for md%d\n" - -#define ARRAY_IS_ACTIVE KERN_INFO \ -"raid1: raid set md%d active with %d out of %d mirrors\n" - -#define THREAD_ERROR KERN_ERR \ -"raid1: couldn't allocate thread for md%d\n" - -#define START_RESYNC KERN_WARNING \ -"raid1: raid set md%d not clean; reconstructing mirrors\n" - static int run(mddev_t *mddev) { conf_t *conf; @@ -1110,10 +1061,9 @@ mdk_rdev_t *rdev; struct list_head *tmp; - MOD_INC_USE_COUNT; - if (mddev->level != 1) { - printk(INVALID_LEVEL, mdidx(mddev), mddev->level); + printk("raid1: md%d: raid level not set to mirroring (%d)\n", + mdidx(mddev), mddev->level); goto out; } /* @@ -1124,7 +1074,8 @@ conf = kmalloc(sizeof(conf_t), GFP_KERNEL); mddev->private = conf; if (!conf) { - printk(MEM_ERROR, mdidx(mddev)); + printk(KERN_ERR "raid1: couldn't allocate memory for md%d\n", + mdidx(mddev)); goto out; } memset(conf, 0, sizeof(*conf)); @@ -1132,7 +1083,8 @@ conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc, r1bio_pool_free, NULL); if (!conf->r1bio_pool) { - printk(MEM_ERROR, mdidx(mddev)); + printk(KERN_ERR "raid1: couldn't allocate memory for md%d\n", + mdidx(mddev)); goto out; } @@ -1160,7 +1112,8 @@ init_waitqueue_head(&conf->wait_resume); if (!conf->working_disks) { - printk(NONE_OPERATIONAL, mdidx(mddev)); + printk(KERN_ERR "raid1: no operational mirrors for md%d\n", + mdidx(mddev)); goto out_free_conf; } @@ -1190,12 +1143,16 @@ { mddev->thread = md_register_thread(raid1d, mddev, "md%d_raid1"); if (!mddev->thread) { - printk(THREAD_ERROR, mdidx(mddev)); + printk(KERN_ERR + "raid1: couldn't allocate thread for md%d\n", + mdidx(mddev)); goto out_free_conf; } } - - printk(ARRAY_IS_ACTIVE, mdidx(mddev), mddev->raid_disks - mddev->degraded, mddev->raid_disks); + printk(KERN_INFO + "raid1: raid set md%d active with %d out of %d mirrors\n", + mdidx(mddev), mddev->raid_disks - mddev->degraded, + mddev->raid_disks); /* * Ok, everything is just fine now */ @@ -1207,7 +1164,6 @@ kfree(conf); mddev->private = NULL; out: - MOD_DEC_USE_COUNT; return -EIO; } @@ -1221,13 +1177,13 @@ mempool_destroy(conf->r1bio_pool); kfree(conf); mddev->private = NULL; - MOD_DEC_USE_COUNT; return 0; } static mdk_personality_t raid1_personality = { .name = "raid1", + .owner = THIS_MODULE, .make_request = make_request, .run = run, .stop = stop, diff -urN linux-2.5.66-bk3/drivers/md/raid5.c linux-2.5.66-bk4/drivers/md/raid5.c --- linux-2.5.66-bk3/drivers/md/raid5.c Mon Mar 24 14:00:09 2003 +++ linux-2.5.66-bk4/drivers/md/raid5.c Mon Mar 31 12:49:35 2003 @@ -182,7 +182,8 @@ BUG(); CHECK_DEVLOCK(); - PRINTK("init_stripe called, stripe %llu\n", (unsigned long long)sh->sector); + PRINTK("init_stripe called, stripe %llu\n", + (unsigned long long)sh->sector); remove_hash(sh); @@ -338,7 +339,9 @@ if (bi == &sh->dev[i].req) break; - PRINTK("end_read_request %llu/%d, count: %d, uptodate %d.\n", (unsigned long long)sh->sector, i, atomic_read(&sh->count), uptodate); + PRINTK("end_read_request %llu/%d, count: %d, uptodate %d.\n", + (unsigned long long)sh->sector, i, atomic_read(&sh->count), + uptodate); if (i == disks) { BUG(); return 0; @@ -409,7 +412,9 @@ if (bi == &sh->dev[i].req) break; - PRINTK("end_write_request %llu/%d, count %d, uptodate: %d.\n", (unsigned long long)sh->sector, i, atomic_read(&sh->count), uptodate); + PRINTK("end_write_request %llu/%d, count %d, uptodate: %d.\n", + (unsigned long long)sh->sector, i, atomic_read(&sh->count), + uptodate); if (i == disks) { BUG(); return 0; @@ -533,7 +538,8 @@ *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks; break; default: - printk ("raid5: unsupported algorithm %d\n", conf->algorithm); + printk("raid5: unsupported algorithm %d\n", + conf->algorithm); } /* @@ -573,7 +579,8 @@ i -= (sh->pd_idx + 1); break; default: - printk ("raid5: unsupported algorithm %d\n", conf->algorithm); + printk("raid5: unsupported algorithm %d\n", + conf->algorithm); } chunk_number = stripe * data_disks + i; @@ -655,7 +662,8 @@ int i, count, disks = conf->raid_disks; void *ptr[MAX_XOR_BLOCKS], *p; - PRINTK("compute_block, stripe %llu, idx %d\n", (unsigned long long)sh->sector, dd_idx); + PRINTK("compute_block, stripe %llu, idx %d\n", + (unsigned long long)sh->sector, dd_idx); ptr[0] = page_address(sh->dev[dd_idx].page); memset(ptr[0], 0, STRIPE_SIZE); @@ -667,7 +675,9 @@ if (test_bit(R5_UPTODATE, &sh->dev[i].flags)) ptr[count++] = p; else - printk("compute_block() %d, stripe %llu, %d not present\n", dd_idx, (unsigned long long)sh->sector, i); + printk("compute_block() %d, stripe %llu, %d" + " not present\n", dd_idx, + (unsigned long long)sh->sector, i); check_xor(); } @@ -683,7 +693,8 @@ void *ptr[MAX_XOR_BLOCKS]; struct bio *chosen; - PRINTK("compute_parity, stripe %llu, method %d\n", (unsigned long long)sh->sector, method); + PRINTK("compute_parity, stripe %llu, method %d\n", + (unsigned long long)sh->sector, method); count = 1; ptr[0] = page_address(sh->dev[pd_idx].page); @@ -768,7 +779,9 @@ struct bio **bip; raid5_conf_t *conf = sh->raid_conf; - PRINTK("adding bh b#%llu to stripe s#%llu\n", (unsigned long long)bi->bi_sector, (unsigned long long)sh->sector); + PRINTK("adding bh b#%llu to stripe s#%llu\n", + (unsigned long long)bi->bi_sector, + (unsigned long long)sh->sector); spin_lock(&sh->lock); @@ -789,7 +802,9 @@ spin_unlock_irq(&conf->device_lock); spin_unlock(&sh->lock); - PRINTK("added bi b#%llu to stripe s#%llu, disk %d.\n", (unsigned long long)bi->bi_sector, (unsigned long long)sh->sector, dd_idx); + PRINTK("added bi b#%llu to stripe s#%llu, disk %d.\n", + (unsigned long long)bi->bi_sector, + (unsigned long long)sh->sector, dd_idx); if (forwrite) { /* check if page is coverred */ @@ -838,7 +853,9 @@ int failed_num=0; struct r5dev *dev; - PRINTK("handling stripe %llu, cnt=%d, pd_idx=%d\n", (unsigned long long)sh->sector, atomic_read(&sh->count), sh->pd_idx); + PRINTK("handling stripe %llu, cnt=%d, pd_idx=%d\n", + (unsigned long long)sh->sector, atomic_read(&sh->count), + sh->pd_idx); spin_lock(&sh->lock); clear_bit(STRIPE_HANDLE, &sh->state); @@ -853,8 +870,8 @@ clear_bit(R5_Insync, &dev->flags); clear_bit(R5_Syncio, &dev->flags); - PRINTK("check %d: state 0x%lx read %p write %p written %p\n", i, - dev->flags, dev->toread, dev->towrite, dev->written); + PRINTK("check %d: state 0x%lx read %p write %p written %p\n", + i, dev->flags, dev->toread, dev->towrite, dev->written); /* maybe we can reply to a read */ if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread) { struct bio *rbi, *rbi2; @@ -895,8 +912,9 @@ } else set_bit(R5_Insync, &dev->flags); } - PRINTK("locked=%d uptodate=%d to_read=%d to_write=%d failed=%d failed_num=%d\n", - locked, uptodate, to_read, to_write, failed, failed_num); + PRINTK("locked=%d uptodate=%d to_read=%d" + " to_write=%d failed=%d failed_num=%d\n", + locked, uptodate, to_read, to_write, failed, failed_num); /* check if the array has lost two devices and, if so, some requests might * need to be failed */ @@ -1015,7 +1033,8 @@ } #endif locked++; - PRINTK("Reading block %d (sync=%d)\n", i, syncing); + PRINTK("Reading block %d (sync=%d)\n", + i, syncing); if (syncing) md_sync_acct(conf->disks[i].rdev, STRIPE_SECTORS); } @@ -1055,7 +1074,8 @@ else rcw += 2*disks; } } - PRINTK("for sector %llu, rmw=%d rcw=%d\n", (unsigned long long)sh->sector, rmw, rcw); + PRINTK("for sector %llu, rmw=%d rcw=%d\n", + (unsigned long long)sh->sector, rmw, rcw); set_bit(STRIPE_HANDLE, &sh->state); if (rmw < rcw && rmw > 0) /* prefer read-modify-write, but need to get some data */ @@ -1204,7 +1224,8 @@ md_sync_acct(rdev, STRIPE_SECTORS); bi->bi_bdev = rdev->bdev; - PRINTK("for %llu schedule op %ld on disc %d\n", (unsigned long long)sh->sector, bi->bi_rw, i); + PRINTK("for %llu schedule op %ld on disc %d\n", + (unsigned long long)sh->sector, bi->bi_rw, i); atomic_inc(&sh->count); bi->bi_sector = sh->sector + rdev->data_offset; bi->bi_flags = 1 << BIO_UPTODATE; @@ -1217,7 +1238,8 @@ bi->bi_next = NULL; generic_make_request(bi); } else { - PRINTK("skip op %ld on disc %d for sector %llu\n", bi->bi_rw, i, (unsigned long long)sh->sector); + PRINTK("skip op %ld on disc %d for sector %llu\n", + bi->bi_rw, i, (unsigned long long)sh->sector); clear_bit(R5_LOCKED, &sh->dev[i].flags); set_bit(STRIPE_HANDLE, &sh->state); } @@ -1285,8 +1307,9 @@ new_sector = raid5_compute_sector(logical_sector, raid_disks, data_disks, &dd_idx, &pd_idx, conf); - PRINTK("raid5: make_request, sector %Lu logical %Lu\n", - (unsigned long long)new_sector, (unsigned long long)logical_sector); + PRINTK("raid5: make_request, sector %Lu logical %Lu\n", + (unsigned long long)new_sector, + (unsigned long long)logical_sector); sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); if (sh) { @@ -1410,11 +1433,8 @@ struct disk_info *disk; struct list_head *tmp; - MOD_INC_USE_COUNT; - if (mddev->level != 5 && mddev->level != 4) { printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), mddev->level); - MOD_DEC_USE_COUNT; return -EIO; } @@ -1450,7 +1470,9 @@ disk->rdev = rdev; if (rdev->in_sync) { - printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", bdev_partition_name(rdev->bdev), raid_disk); + printk(KERN_INFO "raid5: device %s operational as raid" + " disk %d\n", bdev_partition_name(rdev->bdev), + raid_disk); conf->working_disks++; } } @@ -1467,48 +1489,62 @@ conf->max_nr_stripes = NR_STRIPES; if (!conf->chunk_size || conf->chunk_size % 4) { - printk(KERN_ERR "raid5: invalid chunk size %d for md%d\n", conf->chunk_size, mdidx(mddev)); + printk(KERN_ERR "raid5: invalid chunk size %d for md%d\n", + conf->chunk_size, mdidx(mddev)); goto abort; } if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) { - printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev)); + printk(KERN_ERR + "raid5: unsupported parity algorithm %d for md%d\n", + conf->algorithm, mdidx(mddev)); goto abort; } if (mddev->degraded > 1) { - printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks); + printk(KERN_ERR "raid5: not enough operational devices for md%d" + " (%d/%d failed)\n", + mdidx(mddev), conf->failed_disks, conf->raid_disks); goto abort; } if (mddev->degraded == 1 && mddev->recovery_cp != MaxSector) { - printk(KERN_ERR "raid5: cannot start dirty degraded array for md%d\n", mdidx(mddev)); + printk(KERN_ERR + "raid5: cannot start dirty degraded array for md%d\n", + mdidx(mddev)); goto abort; } { mddev->thread = md_register_thread(raid5d, mddev, "md%d_raid5"); if (!mddev->thread) { - printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev)); + printk(KERN_ERR + "raid5: couldn't allocate thread for md%d\n", + mdidx(mddev)); goto abort; } } - - memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + +memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; if (grow_stripes(conf, conf->max_nr_stripes)) { - printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory); + printk(KERN_ERR + "raid5: couldn't allocate %dkB for buffers\n", memory); shrink_stripes(conf); md_unregister_thread(mddev->thread); goto abort; } else - printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev)); + printk(KERN_INFO "raid5: allocated %dkB for md%d\n", + memory, mdidx(mddev)); if (mddev->degraded == 0) - printk("raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), - mddev->raid_disks-mddev->degraded, mddev->raid_disks, conf->algorithm); + printk("raid5: raid level %d set md%d active with %d out of %d" + " devices, algorithm %d\n", conf->level, mdidx(mddev), + mddev->raid_disks-mddev->degraded, mddev->raid_disks, + conf->algorithm); else - printk(KERN_ALERT "raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), - mddev->raid_disks - mddev->degraded, mddev->raid_disks, conf->algorithm); + printk(KERN_ALERT "raid5: raid level %d set md%d active with %d" + " out of %d devices, algorithm %d\n", conf->level, + mdidx(mddev), mddev->raid_disks - mddev->degraded, + mddev->raid_disks, conf->algorithm); print_raid5_conf(conf); @@ -1524,7 +1560,6 @@ } mddev->private = NULL; printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev)); - MOD_DEC_USE_COUNT; return -EIO; } @@ -1540,7 +1575,6 @@ free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); kfree(conf); mddev->private = NULL; - MOD_DEC_USE_COUNT; return 0; } @@ -1549,11 +1583,14 @@ { int i; - printk("sh %llu, pd_idx %d, state %ld.\n", (unsigned long long)sh->sector, sh->pd_idx, sh->state); - printk("sh %llu, count %d.\n", (unsigned long long)sh->sector, atomic_read(&sh->count)); + printk("sh %llu, pd_idx %d, state %ld.\n", + (unsigned long long)sh->sector, sh->pd_idx, sh->state); + printk("sh %llu, count %d.\n", + (unsigned long long)sh->sector, atomic_read(&sh->count)); printk("sh %llu, ", (unsigned long long)sh->sector); for (i = 0; i < sh->raid_conf->raid_disks; i++) { - printk("(cache%d: %p %ld) ", i, sh->dev[i].page, sh->dev[i].flags); + printk("(cache%d: %p %ld) ", + i, sh->dev[i].page, sh->dev[i].flags); } printk("\n"); } @@ -1693,6 +1730,7 @@ static mdk_personality_t raid5_personality= { .name = "raid5", + .owner = THIS_MODULE, .make_request = make_request, .run = run, .stop = stop, diff -urN linux-2.5.66-bk3/drivers/media/radio/radio-cadet.c linux-2.5.66-bk4/drivers/media/radio/radio-cadet.c --- linux-2.5.66-bk3/drivers/media/radio/radio-cadet.c Mon Mar 24 14:00:21 2003 +++ linux-2.5.66-bk4/drivers/media/radio/radio-cadet.c Mon Mar 31 12:49:35 2003 @@ -23,7 +23,9 @@ * 2002-01-17 Adam Belay * Updated to latest pnp code * -*/ + * 2003-01-31 Alan Cox + * Cleaned up locking, delay code, general odds and ends + */ #include /* Modules */ #include /* Initdata */ @@ -43,11 +45,11 @@ static int curtuner=0; static int tunestat=0; static int sigstrength=0; -static wait_queue_head_t tunerq,rdsq,readq; +static wait_queue_head_t readq; struct timer_list tunertimer,rdstimer,readtimer; static __u8 rdsin=0,rdsout=0,rdsstat=0; static unsigned char rdsbuf[RDS_BUFFER]; -static int cadet_lock=0; +static spinlock_t cadet_io_lock; static int cadet_probe(void); @@ -58,37 +60,19 @@ */ static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; -static void cadet_wake(unsigned long qnum) -{ - switch(qnum) { - case 0: /* cadet_setfreq */ - wake_up(&tunerq); - break; - case 1: /* cadet_getrds */ - wake_up(&rdsq); - break; - } -} - - - static int cadet_getrds(void) { int rdsstat=0; - cadet_lock++; + spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ - cadet_lock--; - init_timer(&rdstimer); - rdstimer.function=cadet_wake; - rdstimer.data=(unsigned long)1; - rdstimer.expires=jiffies+(HZ/10); - init_waitqueue_head(&rdsq); - add_timer(&rdstimer); - sleep_on(&rdsq); + spin_unlock(&cadet_io_lock); - cadet_lock++; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + + spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ if((inb(io+1)&0x80)!=0) { rdsstat|=VIDEO_TUNER_RDS_ON; @@ -96,32 +80,24 @@ if((inb(io+1)&0x10)!=0) { rdsstat|=VIDEO_TUNER_MBS_ON; } - cadet_lock--; + spin_unlock(&cadet_io_lock); return rdsstat; } - - - static int cadet_getstereo(void) { - if(curtuner!=0) { /* Only FM has stereo capability! */ + int ret = 0; + if(curtuner != 0) /* Only FM has stereo capability! */ return 0; - } - cadet_lock++; + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ - if((inb(io+1)&0x40)==0) { - cadet_lock--; - return 1; /* Stereo pilot detected */ - } - else { - cadet_lock--; - return 0; /* Mono */ - } + if( (inb(io+1) & 0x40) == 0) + ret = 1; + spin_unlock(&cadet_io_lock); + return ret; } - - static unsigned cadet_gettune(void) { int curvol,i; @@ -130,7 +106,9 @@ /* * Prepare for read */ - cadet_lock++; + + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ curvol=inb(io+1); /* Save current volume/mute setting */ outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ @@ -152,13 +130,11 @@ * Restore volume/mute setting */ outb(curvol,io+1); - cadet_lock--; + spin_unlock(&cadet_io_lock); return fifo; } - - static unsigned cadet_getfreq(void) { int i; @@ -191,14 +167,13 @@ return freq; } - - static void cadet_settune(unsigned fifo) { int i; unsigned test; - cadet_lock++; + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ /* * Write the shift register @@ -217,11 +192,9 @@ test=0x1c|((fifo>>23)&0x02); outb(test,io+1); } - cadet_lock--; + spin_unlock(&cadet_io_lock); } - - static void cadet_setfreq(unsigned freq) { unsigned fifo; @@ -253,92 +226,90 @@ /* * Save current volume/mute setting */ - cadet_lock++; + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ curvol=inb(io+1); + spin_unlock(&cadet_io_lock); /* * Tune the card */ for(j=3;j>-1;j--) { cadet_settune(fifo|(j<<16)); + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ outb(curvol,io+1); - cadet_lock--; - init_timer(&tunertimer); - tunertimer.function=cadet_wake; - tunertimer.data=(unsigned long)0; - tunertimer.expires=jiffies+(HZ/10); - init_waitqueue_head(&tunerq); - add_timer(&tunertimer); - sleep_on(&tunerq); + spin_unlock(&cadet_io_lock); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + cadet_gettune(); - if((tunestat&0x40)==0) { /* Tuned */ + if((tunestat & 0x40) == 0) { /* Tuned */ sigstrength=sigtable[curtuner][j]; return; } - cadet_lock++; } - cadet_lock--; sigstrength=0; } static int cadet_getvol(void) { - cadet_lock++; + int ret = 0; + + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ - if((inb(io+1)&0x20)!=0) { - cadet_lock--; - return 0xffff; - } - else { - cadet_lock--; - return 0; - } + if((inb(io + 1) & 0x20) != 0) + ret = 0xffff; + + spin_unlock(&cadet_io_lock); + return ret; } static void cadet_setvol(int vol) { - cadet_lock++; + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ - if(vol>0) { + if(vol>0) outb(0x20,io+1); - } - else { + else outb(0x00,io+1); - } - cadet_lock--; + spin_unlock(&cadet_io_lock); } - - void cadet_handler(unsigned long data) { /* * Service the RDS fifo */ - if(cadet_lock==0) { + + if(spin_trylock(&cadet_io_lock)) + { outb(0x3,io); /* Select RDS Decoder Control */ if((inb(io+1)&0x20)!=0) { printk(KERN_CRIT "cadet: RDS fifo overflow\n"); } outb(0x80,io); /* Select RDS fifo */ while((inb(io)&0x80)!=0) { - rdsbuf[rdsin++]=inb(io+1); - if(rdsin==rdsout) { - printk(KERN_CRIT "cadet: RDS buffer overflow\n"); - } + rdsbuf[rdsin]=inb(io+1); + if(rdsin==rdsout) + printk(KERN_WARNING "cadet: RDS buffer overflow\n"); + else + rdsin++; } + spin_unlock(&cadet_io_lock); } /* * Service pending read */ - if( rdsin!=rdsout) { + if( rdsin!=rdsout) wake_up_interruptible(&readq); - } /* * Clean up and exit @@ -359,10 +330,10 @@ unsigned char readbuf[RDS_BUFFER]; if(rdsstat==0) { - cadet_lock++; + spin_lock(&cadet_io_lock); rdsstat=1; outb(0x80,io); /* Select RDS fifo */ - cadet_lock--; + spin_unlock(&cadet_io_lock); init_timer(&readtimer); readtimer.function=cadet_handler; readtimer.data=(unsigned long)0; @@ -370,14 +341,13 @@ add_timer(&readtimer); } if(rdsin==rdsout) { - if (file->f_flags & O_NONBLOCK) { + if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; - } interruptible_sleep_on(&readq); } - while((i(n)) printk(KERN_DEBUG args) -static const char *version = -"ds.c 1.112 2001/10/13 00:08:28 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -188,35 +186,21 @@ void (*detach)(dev_link_t *)) { struct pcmcia_driver *driver; - socket_bind_t *b; - struct pcmcia_bus_socket *bus_sock; DEBUG(0, "ds: register_pccard_driver('%s')\n", (char *)dev_info); driver = get_pcmcia_driver(dev_info); - if (!driver) { - driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL); - if (!driver) return -ENOMEM; - memset(driver, 0, sizeof(struct pcmcia_driver)); - driver->drv.name = (char *)dev_info; - pcmcia_register_driver(driver); - } + if (driver) + return -EBUSY; + + driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL); + if (!driver) return -ENOMEM; + memset(driver, 0, sizeof(struct pcmcia_driver)); + driver->drv.name = (char *)dev_info; + pcmcia_register_driver(driver); driver->attach = attach; driver->detach = detach; - if (driver->use_count == 0) return 0; - - /* Instantiate any already-bound devices */ - down_read(&bus_socket_list_rwsem); - list_for_each_entry(bus_sock, &bus_socket_list, socket_list) { - for (b = bus_sock->bind; b; b = b->next) { - if (b->driver != driver) continue; - b->instance = driver->attach(); - if (b->instance == NULL) - printk(KERN_NOTICE "ds: unable to create instance " - "of '%s'!\n", driver->drv.name); - } - } - up_read(&bus_socket_list_rwsem); + return 0; } /* register_pccard_driver */ @@ -411,16 +395,11 @@ if (!s) return -EINVAL; - DEBUG(2, "bind_request(%d, '%s')\n", i, + DEBUG(2, "bind_request(%d, '%s')\n", s->socket_no, (char *)bind_info->dev_info); driver = get_pcmcia_driver(&bind_info->dev_info); - if (driver == NULL) { - driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL); - if (!driver) return -ENOMEM; - memset(driver, 0, sizeof(struct pcmcia_driver)); - driver->drv.name = bind_info->dev_info; - pcmcia_register_driver(driver); - } + if (!driver) + return -EINVAL; for (b = s->bind; b; b = b->next) if ((driver == b->driver) && @@ -543,7 +522,7 @@ { socket_bind_t **b, *c; - DEBUG(2, "unbind_request(%d, '%s')\n", i, + DEBUG(2, "unbind_request(%d, '%s')\n", s->socket_no, (char *)bind_info->dev_info); for (b = &s->bind; *b; b = &(*b)->next) if ((strcmp((char *)(*b)->driver->drv.name, diff -urN linux-2.5.66-bk3/drivers/scsi/3w-xxxx.c linux-2.5.66-bk4/drivers/scsi/3w-xxxx.c --- linux-2.5.66-bk3/drivers/scsi/3w-xxxx.c Mon Mar 24 14:01:43 2003 +++ linux-2.5.66-bk4/drivers/scsi/3w-xxxx.c Mon Mar 31 12:49:35 2003 @@ -677,7 +677,7 @@ dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n"); memset(tw_ioctl->data_buffer, 0, tw_ioctl->data_buffer_length); - spin_lock_irqsave(&tw_dev->host->host_lock, flags); + spin_lock_irqsave(tw_dev->host->host_lock, flags); if (tw_dev->aen_head == tw_dev->aen_tail) { tw_aen_code = TW_AEN_QUEUE_EMPTY; } else { @@ -688,7 +688,7 @@ tw_dev->aen_head = tw_dev->aen_head + 1; } } - spin_unlock_irqrestore(&tw_dev->tw_lock, flags); + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code)); break; case TW_CMD_PACKET_WITH_DATA: diff -urN linux-2.5.66-bk3/drivers/serial/Kconfig linux-2.5.66-bk4/drivers/serial/Kconfig --- linux-2.5.66-bk3/drivers/serial/Kconfig Mon Mar 24 14:01:25 2003 +++ linux-2.5.66-bk4/drivers/serial/Kconfig Mon Mar 31 12:49:35 2003 @@ -372,14 +372,25 @@ bool "Use NEC V850E on-chip UART for console" depends on V850E_NB85E_UART +config SERIAL98 + tristate "PC-9800 8251-based primary serial port support" + depends on X86_PC9800 + help + If you want to use standard primary serial ports on PC-9800, + say Y. Otherwise, say N. + +config SERIAL98_CONSOLE + bool "Support for console on PC-9800 standard serial port" + depends on SERIAL98=y + config SERIAL_CORE tristate - default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_NB85E_UART && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m) - default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_NB85E_UART + default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_NB85E_UART && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m) + default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_NB85E_UART || SERIAL98=y config SERIAL_CORE_CONSOLE bool - depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNCORE || V850E_NB85E_UART_CONSOLE + depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNCORE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE default y config SERIAL_68328 diff -urN linux-2.5.66-bk3/drivers/serial/Makefile linux-2.5.66-bk4/drivers/serial/Makefile --- linux-2.5.66-bk3/drivers/serial/Makefile Mon Mar 24 14:00:37 2003 +++ linux-2.5.66-bk4/drivers/serial/Makefile Mon Mar 31 12:49:35 2003 @@ -27,3 +27,4 @@ obj-$(CONFIG_SERIAL_68360) += 68360serial.o obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o obj-$(CONFIG_V850E_NB85E_UART) += nb85e_uart.o +obj-$(CONFIG_SERIAL98) += serial98.o diff -urN linux-2.5.66-bk3/fs/cramfs/inode.c linux-2.5.66-bk4/fs/cramfs/inode.c --- linux-2.5.66-bk3/fs/cramfs/inode.c Mon Mar 24 13:59:55 2003 +++ linux-2.5.66-bk4/fs/cramfs/inode.c Mon Mar 31 12:49:35 2003 @@ -43,6 +43,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) { struct inode * inode = new_inode(sb); + static struct timespec zerotime = { 0, 0 }; if (inode) { inode->i_mode = cramfs_inode->mode; @@ -51,7 +52,8 @@ inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_gid = cramfs_inode->gid; - inode->i_mtime = inode->i_atime = inode->i_ctime = 0; + /* Struct copy intentional */ + inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; inode->i_ino = CRAMINO(cramfs_inode); /* inode->i_nlink is left 1 - arguably wrong for directories, but it's the best we can do without reading the directory diff -urN linux-2.5.66-bk3/fs/exec.c linux-2.5.66-bk4/fs/exec.c --- linux-2.5.66-bk3/fs/exec.c Mon Mar 24 14:00:18 2003 +++ linux-2.5.66-bk4/fs/exec.c Mon Mar 31 12:49:35 2003 @@ -38,7 +38,6 @@ #include #include #include -#define __NO_VERSION__ #include #include #include diff -urN linux-2.5.66-bk3/fs/nfs/nfs4proc.c linux-2.5.66-bk4/fs/nfs/nfs4proc.c --- linux-2.5.66-bk3/fs/nfs/nfs4proc.c Mon Mar 24 14:01:14 2003 +++ linux-2.5.66-bk4/fs/nfs/nfs4proc.c Mon Mar 31 12:49:35 2003 @@ -1529,7 +1529,6 @@ renew_release(struct rpc_task *task) { kfree(task->tk_calldata); - task->tk_calldata = NULL; } int diff -urN linux-2.5.66-bk3/fs/nfs/read.c linux-2.5.66-bk4/fs/nfs/read.c --- linux-2.5.66-bk3/fs/nfs/read.c Mon Mar 24 13:59:46 2003 +++ linux-2.5.66-bk4/fs/nfs/read.c Mon Mar 31 12:49:35 2003 @@ -270,18 +270,10 @@ req->wb_pgbase + count, req->wb_bytes - count); - if (data->res.eof || - ((fattr->valid & NFS_ATTR_FATTR) && - ((req_offset(req) + count) >= fattr->size))) - SetPageUptodate(page); - else - if (count < req->wb_bytes) - SetPageError(page); count = 0; - } else { + } else count -= PAGE_CACHE_SIZE; - SetPageUptodate(page); - } + SetPageUptodate(page); } else SetPageError(page); unlock_page(page); diff -urN linux-2.5.66-bk3/fs/nfsd/export.c linux-2.5.66-bk4/fs/nfsd/export.c --- linux-2.5.66-bk3/fs/nfsd/export.c Mon Mar 24 14:00:48 2003 +++ linux-2.5.66-bk4/fs/nfsd/export.c Mon Mar 31 12:49:35 2003 @@ -496,13 +496,19 @@ { svc_export *exp; - read_lock(&dparent_lock); + dget(dentry); exp = exp_get_by_name(clp, mnt, dentry, reqp); + while (exp == NULL && dentry != dentry->d_parent) { - dentry = dentry->d_parent; + struct dentry *parent; + read_lock(&dparent_lock); + parent = dget(dentry->d_parent); + dput(dentry); + dentry = parent; + read_unlock(&dparent_lock); exp = exp_get_by_name(clp, mnt, dentry, reqp); } - read_unlock(&dparent_lock); + dput(dentry); return exp; } diff -urN linux-2.5.66-bk3/fs/nfsd/nfs4xdr.c linux-2.5.66-bk4/fs/nfsd/nfs4xdr.c --- linux-2.5.66-bk3/fs/nfsd/nfs4xdr.c Mon Mar 24 14:01:20 2003 +++ linux-2.5.66-bk4/fs/nfsd/nfs4xdr.c Mon Mar 31 12:49:35 2003 @@ -231,6 +231,7 @@ p += XDR_QUADLEN(nbytes); \ } while (0) +/* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */ #define READ_BUF(nbytes) do { \ if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \ p = argp->p; \ @@ -244,15 +245,15 @@ u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) { /* We want more bytes than seem to be available. - * Maybe we need a new page, may wehave just run out + * Maybe we need a new page, maybe we have just run out */ int avail = (char*)argp->end - (char*)argp->p; u32 *p; if (avail + argp->pagelen < nbytes) return NULL; - if (avail + PAGE_SIZE > nbytes) /* need more than a page !! */ + if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ return NULL; - /* ok, we can do it with the tail plus the next page */ + /* ok, we can do it with the current plus the next page */ if (nbytes <= sizeof(argp->tmp)) p = argp->tmp; else { @@ -851,16 +852,16 @@ v++; write->wr_vec[v].iov_base = page_address(argp->pagelist[0]); argp->pagelist++; - if (argp->pagelen >= PAGE_SIZE) { + if (len >= PAGE_SIZE) { write->wr_vec[v].iov_len = PAGE_SIZE; argp->pagelen -= PAGE_SIZE; } else { write->wr_vec[v].iov_len = argp->pagelen; - argp->pagelen = 0; + argp->pagelen -= len; } } argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len); - argp->p = (u32*) (write->wr_vec[v].iov_base + len); + argp->p = (u32*) (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); write->wr_vec[v].iov_len = len; write->wr_vlen = v+1; @@ -1690,7 +1691,8 @@ { u32 eof; int v, pn; - unsigned long maxcount, len; + unsigned long maxcount; + long len; ENCODE_HEAD; if (nfserr) @@ -1731,6 +1733,10 @@ resp->xbuf->page_len = maxcount; + /* read zero bytes -> don't set up tail */ + if(!maxcount) + return 0; + /* set up page for remaining responses */ svc_take_page(resp->rqstp); resp->xbuf->tail[0].iov_base = diff -urN linux-2.5.66-bk3/fs/quota.c linux-2.5.66-bk4/fs/quota.c --- linux-2.5.66-bk3/fs/quota.c Mon Mar 24 14:01:46 2003 +++ linux-2.5.66-bk4/fs/quota.c Mon Mar 31 12:49:35 2003 @@ -221,12 +221,17 @@ uint cmds, type; struct super_block *sb = NULL; struct block_device *bdev; + char *tmp; int ret = -ENODEV; cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; - bdev = lookup_bdev(special); + tmp = getname(special); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + bdev = lookup_bdev(tmp); + putname(tmp); if (IS_ERR(bdev)) return PTR_ERR(bdev); sb = get_super(bdev); diff -urN linux-2.5.66-bk3/include/asm-i386/ide.h linux-2.5.66-bk4/include/asm-i386/ide.h --- linux-2.5.66-bk3/include/asm-i386/ide.h Mon Mar 24 14:00:00 2003 +++ linux-2.5.66-bk4/include/asm-i386/ide.h Mon Mar 31 12:49:35 2003 @@ -26,6 +26,9 @@ static __inline__ int ide_default_irq(unsigned long base) { switch (base) { +#ifdef CONFIG_X86_PC9800 + case 0x640: return 9; +#endif case 0x1f0: return 14; case 0x170: return 15; case 0x1e8: return 11; @@ -40,12 +43,17 @@ static __inline__ unsigned long ide_default_io_base(int index) { switch (index) { +#ifdef CONFIG_X86_PC9800 + case 0: + case 1: return 0x640; +#else case 0: return 0x1f0; case 1: return 0x170; case 2: return 0x1e8; case 3: return 0x168; case 4: return 0x1e0; case 5: return 0x160; +#endif default: return 0; } @@ -56,13 +64,24 @@ { unsigned long reg = data_port; int i; +#ifdef CONFIG_X86_PC9800 + unsigned long increment = data_port == 0x640 ? 2 : 1; +#endif for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw->io_ports[i] = reg; +#ifdef CONFIG_X86_PC9800 + reg += increment; +#else reg += 1; +#endif } if (ctrl_port) { hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; +#ifdef CONFIG_X86_PC9800 + } else if (data_port == 0x640) { + hw->io_ports[IDE_CONTROL_OFFSET] = 0x74c; +#endif } else { hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; } diff -urN linux-2.5.66-bk3/include/asm-i386/uaccess.h linux-2.5.66-bk4/include/asm-i386/uaccess.h --- linux-2.5.66-bk3/include/asm-i386/uaccess.h Mon Mar 24 14:00:07 2003 +++ linux-2.5.66-bk4/include/asm-i386/uaccess.h Mon Mar 31 12:49:35 2003 @@ -510,9 +510,9 @@ * * Context: User context only. This function may sleep. * - * Get the size of a NULL-terminated string in user space. + * Get the size of a NUL-terminated string in user space. * - * Returns the size of the string INCLUDING the terminating NULL. + * Returns the size of the string INCLUDING the terminating NUL. * On exception, returns 0. * * If there is a limit on the length of a valid string, you may wish to diff -urN linux-2.5.66-bk3/include/asm-ppc/keylargo.h linux-2.5.66-bk4/include/asm-ppc/keylargo.h --- linux-2.5.66-bk3/include/asm-ppc/keylargo.h Mon Mar 24 14:00:49 2003 +++ linux-2.5.66-bk4/include/asm-ppc/keylargo.h Mon Mar 31 12:49:35 2003 @@ -10,12 +10,13 @@ #define KL_PANGEA_REV 0x100 /* offset from base for feature control registers */ -#define KEYLARGO_MBCR 0x34 /* Media bay control/status */ +#define KEYLARGO_MBCR 0x34 /* KL Only, Media bay control/status */ #define KEYLARGO_FCR0 0x38 #define KEYLARGO_FCR1 0x3c #define KEYLARGO_FCR2 0x40 #define KEYLARGO_FCR3 0x44 #define KEYLARGO_FCR4 0x48 +#define KEYLARGO_FCR5 0x4c /* Pangea only */ /* GPIO registers */ #define KEYLARGO_GPIO_LEVELS0 0x50 @@ -85,76 +86,111 @@ #define KL_MBCR_MB1_DEV_RESET 0x02000000 #define KL_MBCR_MB1_ENABLE 0x01000000 -#define KL0_SCC_B_INTF_ENABLE 0x00000001 +#define KL0_SCC_B_INTF_ENABLE 0x00000001 /* (KL Only) */ #define KL0_SCC_A_INTF_ENABLE 0x00000002 #define KL0_SCC_SLOWPCLK 0x00000004 #define KL0_SCC_RESET 0x00000008 #define KL0_SCCA_ENABLE 0x00000010 #define KL0_SCCB_ENABLE 0x00000020 #define KL0_SCC_CELL_ENABLE 0x00000040 -#define KL0_IRDA_HIGH_BAND 0x00000100 -#define KL0_IRDA_SOURCE2_SEL 0x00000200 -#define KL0_IRDA_SOURCE1_SEL 0x00000400 -#define KL0_IRDA_RESET 0x00000800 -#define KL0_IRDA_DEFAULT1 0x00001000 -#define KL0_IRDA_DEFAULT0 0x00002000 -#define KL0_IRDA_FAST_CONNECT 0x00004000 -#define KL0_IRDA_ENABLE 0x00008000 -#define KL0_IRDA_CLK32_ENABLE 0x00010000 -#define KL0_IRDA_CLK19_ENABLE 0x00020000 +#define KL0_IRDA_HIGH_BAND 0x00000100 /* (KL Only) */ +#define KL0_IRDA_SOURCE2_SEL 0x00000200 /* (KL Only) */ +#define KL0_IRDA_SOURCE1_SEL 0x00000400 /* (KL Only) */ +#define KL0_PG_USB0_PMI_ENABLE 0x00000400 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_RESET 0x00000800 /* (KL Only) */ +#define KL0_PG_USB0_REF_SUSPEND_SEL 0x00000800 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_DEFAULT1 0x00001000 /* (KL Only) */ +#define KL0_PG_USB0_REF_SUSPEND 0x00001000 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_DEFAULT0 0x00002000 /* (KL Only) */ +#define KL0_PG_USB0_PAD_SUSPEND 0x00002000 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_FAST_CONNECT 0x00004000 /* (KL Only) */ +#define KL0_PG_USB1_PMI_ENABLE 0x00004000 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_ENABLE 0x00008000 /* (KL Only) */ +#define KL0_PG_USB1_REF_SUSPEND_SEL 0x00008000 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_CLK32_ENABLE 0x00010000 /* (KL Only) */ +#define KL0_PG_USB1_REF_SUSPEND 0x00010000 /* (Pangea/Intrepid Only) */ +#define KL0_IRDA_CLK19_ENABLE 0x00020000 /* (KL Only) */ +#define KL0_PG_USB1_PAD_SUSPEND 0x00020000 /* (Pangea/Intrepid Only) */ #define KL0_USB0_PAD_SUSPEND0 0x00040000 #define KL0_USB0_PAD_SUSPEND1 0x00080000 #define KL0_USB0_CELL_ENABLE 0x00100000 #define KL0_USB1_PAD_SUSPEND0 0x00400000 #define KL0_USB1_PAD_SUSPEND1 0x00800000 #define KL0_USB1_CELL_ENABLE 0x01000000 -#define KL0_USB_REF_SUSPEND 0x10000000 +#define KL0_USB_REF_SUSPEND 0x10000000 /* (KL Only) */ #define KL0_SERIAL_ENABLE (KL0_SCC_B_INTF_ENABLE | \ KL0_SCC_SLOWPCLK | \ KL0_SCC_CELL_ENABLE | KL0_SCCA_ENABLE) -#define KL1_AUDIO_SEL_22MCLK 0x00000002 -#define KL1_AUDIO_CLK_ENABLE_BIT 0x00000008 -#define KL1_AUDIO_CLK_OUT_ENABLE 0x00000020 /* Burgundy only ? */ -#define KL1_AUDIO_CELL_ENABLE 0x00000040 -#define KL1_AUDIO_CHOOSE 0x00000080 /* Burgundy only ? */ +#define KL1_USB2_PMI_ENABLE 0x00000001 /* Intrepid only */ +#define KL1_AUDIO_SEL_22MCLK 0x00000002 /* KL/Pangea only */ +#define KL1_USB2_REF_SUSPEND_SEL 0x00000002 /* Intrepid only */ +#define KL1_USB2_REF_SUSPEND 0x00000004 /* Intrepid only */ +#define KL1_AUDIO_CLK_ENABLE_BIT 0x00000008 /* KL/Pangea only */ +#define KL1_USB2_PAD_SUSPEND_SEL 0x00000008 /* Intrepid only */ +#define KL1_USB2_PAD_SUSPEND0 0x00000010 /* Intrepid only */ +#define KL1_AUDIO_CLK_OUT_ENABLE 0x00000020 /* KL/Pangea only */ +#define KL1_USB2_PAD_SUSPEND1 0x00000020 /* Intrepid only */ +#define KL1_AUDIO_CELL_ENABLE 0x00000040 /* KL/Pangea only */ +#define KL1_USB2_CELL_ENABLE 0x00000040 /* Intrepid only */ +#define KL1_AUDIO_CHOOSE 0x00000080 /* KL/Pangea only */ +#define KL1_I2S0_CHOOSE 0x00000200 /* KL Only */ #define KL1_I2S0_CELL_ENABLE 0x00000400 #define KL1_I2S0_CLK_ENABLE_BIT 0x00001000 #define KL1_I2S0_ENABLE 0x00002000 #define KL1_I2S1_CELL_ENABLE 0x00020000 #define KL1_I2S1_CLK_ENABLE_BIT 0x00080000 #define KL1_I2S1_ENABLE 0x00100000 -#define KL1_EIDE0_ENABLE 0x00800000 -#define KL1_EIDE0_RESET_N 0x01000000 -#define KL1_EIDE1_ENABLE 0x04000000 -#define KL1_EIDE1_RESET_N 0x08000000 -#define KL1_UIDE_ENABLE 0x20000000 -#define KL1_UIDE_RESET_N 0x40000000 +#define KL1_EIDE0_ENABLE 0x00800000 /* KL/Intrepid Only */ +#define KL1_EIDE0_RESET_N 0x01000000 /* KL/Intrepid Only */ +#define KL1_EIDE1_ENABLE 0x04000000 /* KL Only */ +#define KL1_EIDE1_RESET_N 0x08000000 /* KL Only */ +#define KL1_UIDE_ENABLE 0x20000000 /* KL/Pangea Only */ +#define KL1_UIDE_RESET_N 0x40000000 /* KL/Pangea Only */ #define KL2_IOBUS_ENABLE 0x00000002 -#define KL2_SLEEP_STATE_BIT 0x00000100 +#define KL2_SLEEP_STATE_BIT 0x00000100 /* KL Only */ +#define KL2_PG_STOP_ALL_CLOCKS 0x00000100 /* Pangea Only */ #define KL2_MPIC_ENABLE 0x00020000 -#define KL2_ALT_DATA_OUT 0x02000000 +#define KL2_CARDSLOT_RESET 0x00040000 /* Pangea/Intrepid Only */ +#define KL2_ALT_DATA_OUT 0x02000000 /* KL Only ??? */ #define KL2_MEM_IS_BIG 0x04000000 #define KL2_CARDSEL_16 0x08000000 -#define KL3_SHUTDOWN_PLL_TOTAL 0x00000001 -#define KL3_SHUTDOWN_PLLKW6 0x00000002 -#define KL3_SHUTDOWN_PLLKW4 0x00000004 -#define KL3_SHUTDOWN_PLLKW35 0x00000008 -#define KL3_SHUTDOWN_PLLKW12 0x00000010 -#define KL3_PLL_RESET 0x00000020 -#define KL3_SHUTDOWN_PLL2X 0x00000080 -#define KL3_CLK66_ENABLE 0x00000100 +#define KL3_SHUTDOWN_PLL_TOTAL 0x00000001 /* KL/Pangea only */ +#define KL3_SHUTDOWN_PLLKW6 0x00000002 /* KL/Pangea only */ +#define KL3_IT_SHUTDOWN_PLL3 0x00000002 /* Intrepid only */ +#define KL3_SHUTDOWN_PLLKW4 0x00000004 /* KL/Pangea only */ +#define KL3_IT_SHUTDOWN_PLL2 0x00000004 /* Intrepid only */ +#define KL3_SHUTDOWN_PLLKW35 0x00000008 /* KL/Pangea only */ +#define KL3_IT_SHUTDOWN_PLL1 0x00000008 /* Intrepid only */ +#define KL3_SHUTDOWN_PLLKW12 0x00000010 /* KL Only */ +#define KL3_IT_ENABLE_PLL3_SHUTDOWN 0x00000010 /* Intrepid only */ +#define KL3_PLL_RESET 0x00000020 /* KL/Pangea only */ +#define KL3_IT_ENABLE_PLL2_SHUTDOWN 0x00000020 /* Intrepid only */ +#define KL3_IT_ENABLE_PLL1_SHUTDOWN 0x00000010 /* Intrepid only */ +#define KL3_SHUTDOWN_PLL2X 0x00000080 /* KL Only */ +#define KL3_CLK66_ENABLE 0x00000100 /* KL Only */ #define KL3_CLK49_ENABLE 0x00000200 #define KL3_CLK45_ENABLE 0x00000400 -#define KL3_CLK31_ENABLE 0x00000800 +#define KL3_CLK31_ENABLE 0x00000800 /* KL/Pangea only */ #define KL3_TIMER_CLK18_ENABLE 0x00001000 #define KL3_I2S1_CLK18_ENABLE 0x00002000 #define KL3_I2S0_CLK18_ENABLE 0x00004000 -#define KL3_VIA_CLK16_ENABLE 0x00008000 -#define KL3_STOPPING33_ENABLED 0x00080000 +#define KL3_VIA_CLK16_ENABLE 0x00008000 /* KL/Pangea only */ +#define KL3_IT_VIA_CLK32_ENABLE 0x00008000 /* Intrepid only */ +#define KL3_STOPPING33_ENABLED 0x00080000 /* KL Only */ +#define KL3_PG_PLL_ENABLE_TEST 0x00080000 /* Pangea Only */ + +/* Intrepid USB bus 2, port 0,1 */ +#define KL3_IT_PORT_WAKEUP_ENABLE(p) (0x00080000 << ((p)<<3)) +#define KL3_IT_PORT_RESUME_WAKE_EN(p) (0x00040000 << ((p)<<3)) +#define KL3_IT_PORT_CONNECT_WAKE_EN(p) (0x00020000 << ((p)<<3)) +#define KL3_IT_PORT_DISCONNECT_WAKE_EN(p) (0x00010000 << ((p)<<3)) +#define KL3_IT_PORT_RESUME_STAT(p) (0x00300000 << ((p)<<3)) +#define KL3_IT_PORT_CONNECT_STAT(p) (0x00200000 << ((p)<<3)) +#define KL3_IT_PORT_DISCONNECT_STAT(p) (0x00100000 << ((p)<<3)) /* Port 0,1 : bus 0, port 2,3 : bus 1 */ #define KL4_PORT_WAKEUP_ENABLE(p) (0x00000008 << ((p)<<3)) @@ -165,3 +201,10 @@ #define KL4_PORT_CONNECT_STAT(p) (0x00000020 << ((p)<<3)) #define KL4_PORT_DISCONNECT_STAT(p) (0x00000010 << ((p)<<3)) +/* Pangea and Intrepid only */ +#define KL5_VIA_USE_CLK31 0x000000001 /* Pangea Only */ +#define KL5_SCC_USE_CLK31 0x000000002 /* Pangea Only */ +#define KL5_PWM_CLK32_EN 0x000000004 +#define KL5_CLK3_68_EN 0x000000010 +#define KL5_CLK32_EN 0x000000020 + diff -urN linux-2.5.66-bk3/include/asm-ppc/macio_asic.h linux-2.5.66-bk4/include/asm-ppc/macio_asic.h --- linux-2.5.66-bk3/include/asm-ppc/macio_asic.h Wed Dec 31 16:00:00 1969 +++ linux-2.5.66-bk4/include/asm-ppc/macio_asic.h Mon Mar 31 12:49:35 2003 @@ -0,0 +1,80 @@ +#ifndef __MACIO_ASIC_H__ +#define __MACIO_ASIC_H__ + +#include + +extern struct bus_type macio_bus_type; + +/* MacIO device driver is defined later */ +struct macio_driver; +struct macio_chip; + +#define MACIO_DEV_COUNT_RESOURCE 8 +#define MACIO_DEV_COUNT_IRQS 8 + +/* + * the macio_bus structure is used to describe a "virtual" bus + * within a MacIO ASIC. It's typically provided by a macio_pci_asic + * PCI device, but could be provided differently as well (nubus + * machines using a fake OF tree). + */ +struct macio_bus +{ + struct macio_chip *chip; /* macio_chip (private use) */ + struct pci_dev *pdev; /* PCI device hosting this bus */ + struct list_head devices; /* list of devices on this bus */ +}; + +/* + * the macio_dev structure is used to describe a device + * within an Apple MacIO ASIC. + */ +struct macio_dev +{ + struct macio_bus *bus; /* virtual bus this device is on */ + + struct device_node *node; /* OF node */ + struct macio_driver *driver; /* which driver allocated this device */ + void *driver_data; /* placeholder for driver specific stuffs */ + struct resource resources[MACIO_DEV_COUNT_RESOURCE]; /* I/O */ + int irqs[MACIO_DEV_COUNT_IRQS]; + + struct device dev; /* Generic device interface */ +}; +#define to_macio_device(d) container_of(d, struct macio_dev, dev) + +/* + * Struct used for matching a device + */ +struct macio_match +{ + char *name; + char *type; + char *compatible; +}; +#define MACIO_ANY_MATCH ((char *)-1L) + +/* + * A driver for a mac-io chip based device + */ +struct macio_driver +{ + struct list_head node; + char *name; + struct macio_match *match_table; + + int (*probe)(struct macio_dev* dev, const struct macio_match *match); + int (*remove)(struct macio_dev* dev); + + int (*suspend)(struct macio_dev* dev, u32 state, u32 level); + int (*resume)(struct macio_dev* dev, u32 level); + int (*shutdown)(struct macio_dev* dev); + + struct device_driver driver; +}; +#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver) + +extern int macio_register_driver(struct macio_driver *); +extern void macio_unregister_driver(struct macio_driver *); + +#endif /* __MACIO_ASIC_H__ */ diff -urN linux-2.5.66-bk3/include/asm-ppc/pgtable.h linux-2.5.66-bk4/include/asm-ppc/pgtable.h --- linux-2.5.66-bk3/include/asm-ppc/pgtable.h Mon Mar 24 14:00:09 2003 +++ linux-2.5.66-bk4/include/asm-ppc/pgtable.h Mon Mar 31 12:49:35 2003 @@ -152,6 +152,7 @@ /* Definitions for 40x embedded chips. */ #define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ +#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */ #define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ #define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ #define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ @@ -172,6 +173,7 @@ #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ +#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */ #define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ #define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ @@ -210,6 +212,7 @@ /* Definitions for 60x, 740/750, etc. */ #define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ #define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */ +#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */ #define _PAGE_USER 0x004 /* usermode access allowed */ #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ @@ -378,6 +381,7 @@ static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } @@ -523,14 +527,19 @@ /* * Encode and decode a swap entry. * Note that the bits we use in a PTE for representing a swap entry - * must not include the _PAGE_PRESENT bit, or the _PAGE_HASHPTE bit - * (if used). -- paulus + * must not include the _PAGE_PRESENT bit, the _PAGE_FILE bit, or the + *_PAGE_HASHPTE bit (if used). -- paulus */ -#define __swp_type(entry) ((entry).val & 0x3f) -#define __swp_offset(entry) ((entry).val >> 6) -#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 6) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 2 }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 2 }) +#define __swp_type(entry) ((entry).val & 0x1f) +#define __swp_offset(entry) ((entry).val >> 5) +#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) + +/* Encode and decode a nonlinear file mapping entry */ +#define PTE_FILE_MAX_BITS 29 +#define pte_to_pgoff(pte) (pte_val(pte) >> 3) +#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE }) /* CONFIG_APUS */ /* For virtual address to physical address conversion */ diff -urN linux-2.5.66-bk3/include/asm-ppc/pmac_feature.h linux-2.5.66-bk4/include/asm-ppc/pmac_feature.h --- linux-2.5.66-bk3/include/asm-ppc/pmac_feature.h Mon Mar 24 13:59:53 2003 +++ linux-2.5.66-bk4/include/asm-ppc/pmac_feature.h Mon Mar 31 12:49:35 2003 @@ -31,10 +31,16 @@ #ifndef __PPC_ASM_PMAC_FEATURE_H #define __PPC_ASM_PMAC_FEATURE_H +#include + /* * Known Mac motherboard models * * Please, report any error here to benh@kernel.crashing.org, thanks ! + * + * Note that I don't fully maintain this list for Core99 & MacRISC2 + * and I'm considering removing all NewWorld entries from it and + * entirely rely on the model string. */ /* PowerSurge are the first generation of PCI Pmacs. This include @@ -85,10 +91,16 @@ #define PMAC_TYPE_QUICKSILVER 0x45 /* QuickSilver G4s */ #define PMAC_TYPE_PISMO 0x46 /* Pismo PowerBook */ #define PMAC_TYPE_TITANIUM 0x47 /* Titanium PowerBook */ -#define PMAC_TYPE_TITANIUM2 0x48 /* Titanium II PowerBook */ -#define PMAC_TYPE_TITANIUM3 0x49 /* Titanium III PowerBook (with L3) */ +#define PMAC_TYPE_TITANIUM2 0x48 /* Titanium II PowerBook (no L3, M6) */ +#define PMAC_TYPE_TITANIUM3 0x49 /* Titanium III PowerBook (with L3 & M7) */ +#define PMAC_TYPE_TITANIUM4 0x50 /* Titanium IV PowerBook (with L3 & M9) */ +#define PMAC_TYPE_EMAC 0x50 /* eMac */ #define PMAC_TYPE_UNKNOWN_CORE99 0x5f +/* MacRisc2 with UniNorth 2.0 */ +#define PMAC_TYPE_RACKMAC 0x80 /* XServe */ +#define PMAC_TYPE_WINDTUNNEL 0x81 + /* MacRISC2 machines based on the Pangea chipset */ #define PMAC_TYPE_PANGEA_IMAC 0x100 /* Flower Power iMac */ @@ -96,12 +108,18 @@ #define PMAC_TYPE_FLAT_PANEL_IMAC 0x102 /* Flat panel iMac */ #define PMAC_TYPE_UNKNOWN_PANGEA 0x10f +/* MacRISC2 machines based on the Intrepid chipset + */ +#define PMAC_TYPE_UNKNOWN_INTREPID 0x11f /* Generic */ + /* * Motherboard flags */ #define PMAC_MB_CAN_SLEEP 0x00000001 #define PMAC_MB_HAS_FW_POWER 0x00000002 +#define PMAC_MB_OLD_CORE99 0x00000004 +#define PMAC_MB_MOBILE 0x00000008 /* * Feature calls supported on pmac @@ -251,5 +269,60 @@ #define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x)) + +/* + * The part below is for use by macio_asic.c only, do not rely + * on the data structures or constants below in a normal driver + * + */ + +#define MAX_MACIO_CHIPS 2 + +enum { + macio_unknown = 0, + macio_grand_central, + macio_ohare, + macio_ohareII, + macio_heathrow, + macio_gatwick, + macio_paddington, + macio_keylargo, + macio_pangea, + macio_intrepid, +}; + +struct macio_chip +{ + struct device_node *of_node; + int type; + const char *name; + int rev; + volatile u32 *base; + unsigned long flags; + + /* For use by macio_asic PCI driver */ + struct macio_bus lbus; +}; + +extern struct macio_chip macio_chips[MAX_MACIO_CHIPS]; + +#define MACIO_FLAG_SCCA_ON 0x00000001 +#define MACIO_FLAG_SCCB_ON 0x00000002 +#define MACIO_FLAG_SCC_LOCKED 0x00000004 +#define MACIO_FLAG_AIRPORT_ON 0x00000010 +#define MACIO_FLAG_FW_SUPPORTED 0x00000020 + +extern struct macio_chip* macio_find(struct device_node* child, int type); + +#define MACIO_FCR32(macio, r) ((macio)->base + ((r) >> 2)) +#define MACIO_FCR8(macio, r) (((volatile u8*)((macio)->base)) + (r)) + +#define MACIO_IN32(r) (in_le32(MACIO_FCR32(macio,r))) +#define MACIO_OUT32(r,v) (out_le32(MACIO_FCR32(macio,r), (v))) +#define MACIO_BIS(r,v) (MACIO_OUT32((r), MACIO_IN32(r) | (v))) +#define MACIO_BIC(r,v) (MACIO_OUT32((r), MACIO_IN32(r) & ~(v))) +#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r))) +#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v))) + #endif /* __PPC_ASM_PMAC_FEATURE_H */ #endif /* __KERNEL__ */ diff -urN linux-2.5.66-bk3/include/asm-ppc/uninorth.h linux-2.5.66-bk4/include/asm-ppc/uninorth.h --- linux-2.5.66-bk3/include/asm-ppc/uninorth.h Mon Mar 24 14:01:23 2003 +++ linux-2.5.66-bk4/include/asm-ppc/uninorth.h Mon Mar 31 12:49:35 2003 @@ -28,6 +28,7 @@ #define UNI_N_CFG_GART_INVAL 0x00000001 #define UNI_N_CFG_GART_ENABLE 0x00000100 #define UNI_N_CFG_GART_2xRESET 0x00010000 +#define UNI_N_CFG_GART_DISSBADET 0x00020000 /* My understanding of UniNorth AGP as of UniNorth rev 1.0x, * revision 1.5 (x4 AGP) may need further changes. @@ -94,6 +95,7 @@ #define UNI_N_CLOCK_CNTL_PCI 0x00000001 /* PCI2 clock control */ #define UNI_N_CLOCK_CNTL_GMAC 0x00000002 /* GMAC clock control */ #define UNI_N_CLOCK_CNTL_FW 0x00000004 /* FireWire clock control */ +#define UNI_N_CLOCK_CNTL_ATA100 0x00000010 /* ATA-100 clock control (U2) */ /* Power Management control */ #define UNI_N_POWER_MGT 0x0030 diff -urN linux-2.5.66-bk3/include/asm-s390/bitops.h linux-2.5.66-bk4/include/asm-s390/bitops.h --- linux-2.5.66-bk3/include/asm-s390/bitops.h Mon Mar 24 13:59:54 2003 +++ linux-2.5.66-bk4/include/asm-s390/bitops.h Mon Mar 31 12:49:36 2003 @@ -51,7 +51,7 @@ #ifdef CONFIG_SMP /* - * SMP save set_bit routine based on compare and swap (CS) + * SMP safe set_bit routine based on compare and swap (CS) */ static inline void set_bit_cs(int nr, volatile unsigned long *ptr) { @@ -76,7 +76,7 @@ } /* - * SMP save clear_bit routine based on compare and swap (CS) + * SMP safe clear_bit routine based on compare and swap (CS) */ static inline void clear_bit_cs(int nr, volatile unsigned long *ptr) { @@ -101,7 +101,7 @@ } /* - * SMP save change_bit routine based on compare and swap (CS) + * SMP safe change_bit routine based on compare and swap (CS) */ static inline void change_bit_cs(int nr, volatile unsigned long *ptr) { @@ -126,7 +126,7 @@ } /* - * SMP save test_and_set_bit routine based on compare and swap (CS) + * SMP safe test_and_set_bit routine based on compare and swap (CS) */ static inline int test_and_set_bit_cs(int nr, volatile unsigned long *ptr) @@ -153,7 +153,7 @@ } /* - * SMP save test_and_clear_bit routine based on compare and swap (CS) + * SMP safe test_and_clear_bit routine based on compare and swap (CS) */ static inline int test_and_clear_bit_cs(int nr, volatile unsigned long *ptr) @@ -180,7 +180,7 @@ } /* - * SMP save test_and_change_bit routine based on compare and swap (CS) + * SMP safe test_and_change_bit routine based on compare and swap (CS) */ static inline int test_and_change_bit_cs(int nr, volatile unsigned long *ptr) diff -urN linux-2.5.66-bk3/include/linux/raid/md_k.h linux-2.5.66-bk4/include/linux/raid/md_k.h --- linux-2.5.66-bk3/include/linux/raid/md_k.h Mon Mar 24 13:59:55 2003 +++ linux-2.5.66-bk4/include/linux/raid/md_k.h Mon Mar 31 12:49:36 2003 @@ -254,6 +254,7 @@ struct mdk_personality_s { char *name; + struct module *owner; int (*make_request)(request_queue_t *q, struct bio *bio); int (*run)(mddev_t *mddev); int (*stop)(mddev_t *mddev); diff -urN linux-2.5.66-bk3/net/sunrpc/auth_gss/auth_gss.c linux-2.5.66-bk4/net/sunrpc/auth_gss/auth_gss.c --- linux-2.5.66-bk3/net/sunrpc/auth_gss/auth_gss.c Mon Mar 24 14:00:23 2003 +++ linux-2.5.66-bk4/net/sunrpc/auth_gss/auth_gss.c Mon Mar 31 12:49:36 2003 @@ -654,7 +654,6 @@ struct xdr_netobj bufin; struct xdr_netobj bufout; u32 flav,len; - int code = 0; dprintk("RPC: gss_validate\n"); @@ -675,8 +674,7 @@ bufout.data = (u8 *) p; bufout.len = len; - if ((code = gss_verify_mic(ctx->gc_gss_ctx, - &bufin, &bufout, &qop_state) < 0)) + if (gss_verify_mic(ctx->gc_gss_ctx, &bufin, &bufout, &qop_state) != 0) return NULL; task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2; dprintk("RPC: GSS gss_validate: gss_verify_mic succeeded.\n"); diff -urN linux-2.5.66-bk3/net/sunrpc/clnt.c linux-2.5.66-bk4/net/sunrpc/clnt.c --- linux-2.5.66-bk3/net/sunrpc/clnt.c Mon Mar 24 14:00:18 2003 +++ linux-2.5.66-bk4/net/sunrpc/clnt.c Mon Mar 31 12:49:36 2003 @@ -654,7 +654,8 @@ if (task->tk_status < 0) return; /* Encode here so that rpcsec_gss can use correct sequence number. */ - call_encode(task); + if (!task->tk_rqstp->rq_bytes_sent) + call_encode(task); if (task->tk_status < 0) return; xprt_transmit(task); diff -urN linux-2.5.66-bk3/net/sunrpc/rpc_pipe.c linux-2.5.66-bk4/net/sunrpc/rpc_pipe.c --- linux-2.5.66-bk3/net/sunrpc/rpc_pipe.c Mon Mar 24 14:00:14 2003 +++ linux-2.5.66-bk4/net/sunrpc/rpc_pipe.c Mon Mar 31 12:49:36 2003 @@ -422,8 +422,10 @@ } static int -rpc_lookup_path(char *path, struct nameidata *nd, int flags) +rpc_lookup_parent(char *path, struct nameidata *nd) { + if (path[0] == '\0') + return -ENOENT; if (rpc_get_mount()) { printk(KERN_WARNING "%s: %s failed to mount " "pseudofilesystem \n", __FILE__, __FUNCTION__); @@ -432,7 +434,7 @@ nd->mnt = mntget(rpc_mount); nd->dentry = dget(rpc_mount->mnt_root); nd->last_type = LAST_ROOT; - nd->flags = flags; + nd->flags = LOOKUP_PARENT; if (path_walk(path, nd)) { printk(KERN_WARNING "%s: %s failed to find path %s\n", @@ -594,7 +596,7 @@ struct inode *dir; int error; - if ((error = rpc_lookup_path(path, nd, LOOKUP_PARENT)) != 0) + if ((error = rpc_lookup_parent(path, nd)) != 0) return ERR_PTR(error); dir = nd->dentry->d_inode; down(&dir->i_sem); @@ -656,7 +658,7 @@ struct inode *dir; int error; - if ((error = rpc_lookup_path(path, &nd, LOOKUP_PARENT)) != 0) + if ((error = rpc_lookup_parent(path, &nd)) != 0) return error; dir = nd.dentry->d_inode; down(&dir->i_sem); @@ -716,7 +718,7 @@ struct inode *dir; int error; - if ((error = rpc_lookup_path(path, &nd, LOOKUP_PARENT)) != 0) + if ((error = rpc_lookup_parent(path, &nd)) != 0) return error; dir = nd.dentry->d_inode; down(&dir->i_sem); diff -urN linux-2.5.66-bk3/net/sunrpc/sched.c linux-2.5.66-bk4/net/sunrpc/sched.c --- linux-2.5.66-bk3/net/sunrpc/sched.c Mon Mar 24 14:00:44 2003 +++ linux-2.5.66-bk4/net/sunrpc/sched.c Mon Mar 31 12:49:36 2003 @@ -1115,11 +1115,12 @@ "-rpcwait -action- --exit--\n"); alltask_for_each(t, le, &all_tasks) printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n", - t->tk_pid, t->tk_msg.rpc_proc->p_proc, + t->tk_pid, + (t->tk_msg.rpc_proc->p_proc ? t->tk_msg.rpc_proc->p_proc : -1), t->tk_flags, t->tk_status, t->tk_client, t->tk_client->cl_prog, t->tk_rqstp, t->tk_timeout, - t->tk_rpcwait ? rpc_qname(t->tk_rpcwait) : " ", + rpc_qname(t->tk_rpcwait), t->tk_action, t->tk_exit); spin_unlock(&rpc_sched_lock); } diff -urN linux-2.5.66-bk3/net/sunrpc/xprt.c linux-2.5.66-bk4/net/sunrpc/xprt.c --- linux-2.5.66-bk3/net/sunrpc/xprt.c Mon Mar 24 14:00:55 2003 +++ linux-2.5.66-bk4/net/sunrpc/xprt.c Mon Mar 31 12:49:36 2003 @@ -175,10 +175,10 @@ if (xprt->snd_task) return; - if (!xprt->nocong && RPCXPRT_CONGESTED(xprt)) - return; task = rpc_wake_up_next(&xprt->resend); if (!task) { + if (!xprt->nocong && RPCXPRT_CONGESTED(xprt)) + return; task = rpc_wake_up_next(&xprt->sending); if (!task) return; @@ -1071,7 +1071,6 @@ } rpc_inc_timeo(&task->tk_client->cl_rtt); xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT); - __xprt_put_cong(xprt, req); } req->rq_nresend++; @@ -1211,10 +1210,7 @@ req->rq_bytes_sent = 0; } out_release: - spin_lock_bh(&xprt->sock_lock); - __xprt_release_write(xprt, task); - __xprt_put_cong(xprt, req); - spin_unlock_bh(&xprt->sock_lock); + xprt_release_write(xprt, task); return; out_receive: dprintk("RPC: %4d xmit complete\n", task->tk_pid);