summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 17:53:24 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 17:53:24 -0800
commitc9b9226830bdc88e57166ec7355bccda28eb95f5 (patch)
tree4b95963e7acd8d8b947d7c1baed9007eea243032
parent5e787ed514bb4b83cf5c74db1245547aecc4375a (diff)
v2.4.0.11 -> v2.4.0.12
- Get non-cpuid Cyrix probing right (it's not a NexGen) - Jens Axboe: cdrom tray status and queing cleanups - AGP GART: don't disable VIA, and allow i815 with external AGP - Coda: use iget4() in order to have big inode numbers without clashes. - Fix UDF writepage() page locking - NIIBE Yutaka: SuperH update - Martin Diehl and others: SiS pirq routing fixes - Andy Grover: ACPI update - Andrea Arkangeli: LVM update - Ingo Molnar: RAID cleanups - David Miller: sparc and networking updates - Make NFS really be able to handle large files
-rw-r--r--Documentation/Configure.help23
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile2
-rw-r--r--arch/i386/kernel/pci-irq.c113
-rw-r--r--arch/i386/kernel/setup.c6
-rw-r--r--arch/sh/boot/compressed/head.S2
-rw-r--r--arch/sh/kernel/entry.S738
-rw-r--r--arch/sh/kernel/fpu.c212
-rw-r--r--arch/sh/kernel/head.S44
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--arch/sh/kernel/irq_imask.c8
-rw-r--r--arch/sh/kernel/process.c32
-rw-r--r--arch/sh/kernel/setup.c4
-rw-r--r--arch/sh/kernel/sh_bios.c18
-rw-r--r--arch/sh/kernel/sh_ksyms.c5
-rw-r--r--arch/sh/kernel/signal.c4
-rw-r--r--arch/sh/kernel/traps.c445
-rw-r--r--arch/sh/lib/checksum.S157
-rw-r--r--arch/sh/lib/delay.c6
-rw-r--r--arch/sh/mm/cache.c16
-rw-r--r--arch/sparc/kernel/entry.S3
-rw-r--r--arch/sparc64/defconfig2
-rw-r--r--arch/sparc64/kernel/smp.c4
-rw-r--r--drivers/acpi/acpi_ksyms.c8
-rw-r--r--drivers/acpi/common/cmalloc.c2
-rw-r--r--drivers/acpi/common/cmxface.c16
-rw-r--r--drivers/acpi/cpu.c51
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c45
-rw-r--r--drivers/acpi/dispatcher/dswexec.c4
-rw-r--r--drivers/acpi/driver.c28
-rw-r--r--drivers/acpi/ec.c2
-rw-r--r--drivers/acpi/hardware/hwacpi.c50
-rw-r--r--drivers/acpi/hardware/hwcpu32.c709
-rw-r--r--drivers/acpi/hardware/hwgpe.c3
-rw-r--r--drivers/acpi/hardware/hwregs.c47
-rw-r--r--drivers/acpi/hardware/hwsleep.c189
-rw-r--r--drivers/acpi/hardware/hwtimer.c196
-rw-r--r--drivers/acpi/hardware/hwxface.c595
-rw-r--r--drivers/acpi/include/accommon.h2
-rw-r--r--drivers/acpi/include/acconfig.h4
-rw-r--r--drivers/acpi/include/achware.h96
-rw-r--r--drivers/acpi/include/acinterp.h70
-rw-r--r--drivers/acpi/include/aclocal.h24
-rw-r--r--drivers/acpi/include/acoutput.h3
-rw-r--r--drivers/acpi/include/acpiosxf.h4
-rw-r--r--drivers/acpi/include/acpixf.h4
-rw-r--r--drivers/acpi/include/actbl2.h4
-rw-r--r--drivers/acpi/include/actypes.h7
-rw-r--r--drivers/acpi/interpreter/amconvrt.c135
-rw-r--r--drivers/acpi/interpreter/amfield.c7
-rw-r--r--drivers/acpi/interpreter/amfldio.c22
-rw-r--r--drivers/acpi/interpreter/amresolv.c4
-rw-r--r--drivers/acpi/interpreter/amstore.c449
-rw-r--r--drivers/acpi/interpreter/amstoren.c488
-rw-r--r--drivers/acpi/interpreter/amstorob.c522
-rw-r--r--drivers/acpi/namespace/nssearch.c4
-rw-r--r--drivers/acpi/namespace/nsutils.c2
-rw-r--r--drivers/acpi/parser/psparse.c6
-rw-r--r--drivers/acpi/parser/psxface.c8
-rw-r--r--drivers/acpi/sys.c66
-rw-r--r--drivers/acpi/table.c21
-rw-r--r--drivers/acpi/tables/tbconvrt.c4
-rw-r--r--drivers/block/ll_rw_blk.c41
-rw-r--r--drivers/cdrom/cdrom.c4
-rw-r--r--drivers/char/agp/agpgart_be.c11
-rw-r--r--drivers/i2o/i2o_block.c5
-rw-r--r--drivers/ide/ide-cd.c37
-rw-r--r--drivers/isdn/hisax/config.c4
-rw-r--r--drivers/md/Config.in5
-rw-r--r--drivers/md/lvm-snap.c32
-rw-r--r--drivers/md/lvm-snap.h47
-rw-r--r--drivers/md/lvm.c632
-rw-r--r--drivers/md/md.c112
-rw-r--r--drivers/net/pcnet32.c2
-rw-r--r--drivers/net/pppoe.c3
-rw-r--r--drivers/sbus/sbus.c14
-rw-r--r--drivers/scsi/ibmmca.c9
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--drivers/sound/trix.c1
-rw-r--r--drivers/video/sbusfb.c6
-rw-r--r--fs/coda/cnode.c62
-rw-r--r--fs/exec.c2
-rw-r--r--fs/partitions/msdos.c6
-rw-r--r--fs/udf/file.c1
-rw-r--r--fs/udf/inode.c1
-rw-r--r--include/asm-sh/current.h2
-rw-r--r--include/asm-sh/pgtable.h6
-rw-r--r--include/asm-sh/sh_bios.h2
-rw-r--r--include/asm-sh/system.h65
-rw-r--r--include/linux/acpi.h13
-rw-r--r--include/linux/dn.h1
-rw-r--r--include/linux/lvm.h68
-rw-r--r--include/linux/nfs_xdr.h4
-rw-r--r--include/linux/raid/md_u.h1
-rw-r--r--include/linux/rtc.h2
-rw-r--r--include/net/dn.h1
-rw-r--r--kernel/ksyms.c1
-rw-r--r--mm/mmap.c4
-rw-r--r--net/decnet/af_decnet.c25
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c21
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c13
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c6
-rw-r--r--net/irda/af_irda.c3
103 files changed, 3289 insertions, 3741 deletions
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index bfe48e9ba811..297f2465fe48 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -1450,15 +1450,6 @@ CONFIG_BLK_DEV_LVM
want), say M here and read Documentation/modules.txt. The module
will be called lvm-mod.o.
-Logical Volume Manager /proc file system information
-CONFIG_LVM_PROC_FS
- If you say Y here, you are able to access overall Logical Volume
- Manager, Volume Group, Logical and Physical Volume information in
- /proc/lvm.
-
- To use this option, you have to check, that the "/proc file system
- support" (CONFIG_PROC_FS) is enabled too.
-
Multiple devices driver support
CONFIG_BLK_DEV_MD
This driver lets you combine several hard disk partitions into one
@@ -1565,20 +1556,6 @@ CONFIG_MD_RAID5
If unsure, say Y.
-RAID Boot support
-CONFIG_MD_BOOT
- To boot with an initial raid volume (any type) you can select
- autodetect, or answer Y here and appropriate options to the kernel
- at boot time.
- For lilo and loadlin options see the file Documentation/md.txt.
-
-RAID AutoDetect support
-CONFIG_AUTODETECT_RAID
- An alternative to "Raid Boot support" is autodetect support.
- With this selected, any partitons of type 0xFD will be considered for
- inclusion in a RAID array. Information in the RAID-superblock on
- the partition will determine how it is included.
-
Support for Acer PICA 1 chipset
CONFIG_ACER_PICA_61
This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
diff --git a/MAINTAINERS b/MAINTAINERS
index 492d15a40e50..e30666fb7ac2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,6 +196,12 @@ L: linux-kernel@vger.kernel.org
W: http://www.ocston.org/~tigran/patches/bfs
S: Maintained
+BLOCK LAYER
+P: Jens Axboe
+M: axboe@suse.de
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
BTTV VIDEO4LINUX DRIVER
P: Gerd Knorr
M: kraxel@goldbach.in-berlin.de
diff --git a/Makefile b/Makefile
index 5c35d263b899..95228549037e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 1
-EXTRAVERSION =-pre11
+EXTRAVERSION =-pre12
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c
index bd2bf22d39d0..8281e3f8272d 100644
--- a/arch/i386/kernel/pci-irq.c
+++ b/arch/i386/kernel/pci-irq.c
@@ -234,22 +234,107 @@ static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
return 1;
}
+/*
+ * PIRQ routing for SiS 85C503 router used in several SiS chipsets
+ * According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
+ * the related registers work as follows:
+ *
+ * general: one byte per re-routable IRQ,
+ * bit 7 IRQ mapping enabled (0) or disabled (1)
+ * bits [6:4] reserved
+ * bits [3:0] IRQ to map to
+ * allowed: 3-7, 9-12, 14-15
+ * reserved: 0, 1, 2, 8, 13
+ *
+ * individual registers in device config space:
+ *
+ * 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case
+ *
+ * 0x61: IDEIRQ: bits as in general case - but:
+ * bits [6:5] must be written 01
+ * bit 4 channel-select primary (0), secondary (1)
+ *
+ * 0x62: USBIRQ: bits as in general case - but:
+ * bit 4 OHCI function disabled (0), enabled (1)
+ *
+ * 0x6a: ACPI/SCI IRQ - bits as in general case
+ *
+ * 0x7e: Data Acq. Module IRQ - bits as in general case
+ *
+ * Apparently there are systems implementing PCI routing table using both
+ * link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
+ * like 0x62 as link values for USBIRQ e.g. So there is no simple
+ * "register = offset + pirq" relation.
+ * Currently we support PCI INTA..D and USBIRQ and try our best to handle
+ * both link mappings.
+ * IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
+ */
+
static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
- int reg = 0x41 + (pirq - 'A') ;
-
- pci_read_config_byte(router, reg, &x);
+ int reg = pirq;
+
+ switch(pirq) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ reg += 0x40;
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x62:
+ pci_read_config_byte(router, reg, &x);
+ if (reg != 0x62)
+ break;
+ if (!(x & 0x40))
+ return 0;
+ break;
+ case 0x61:
+ case 0x6a:
+ case 0x7e:
+ printk("SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
+ return 0;
+ default:
+ printk("SiS router pirq escape (%d)\n", pirq);
+ return 0;
+ }
return (x & 0x80) ? 0 : (x & 0x0f);
}
static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
u8 x;
- int reg = 0x41 + (pirq - 'A') ;
-
- pci_read_config_byte(router, reg, &x);
- x = (pirq & 0x20) ? 0 : (irq & 0x0f);
+ int reg = pirq;
+
+ switch(pirq) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ reg += 0x40;
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x62:
+ x = (irq&0x0f) ? (irq&0x0f) : 0x80;
+ if (reg != 0x62)
+ break;
+ /* always mark OHCI enabled, as nothing else knows about this */
+ x |= 0x40;
+ break;
+ case 0x61:
+ case 0x6a:
+ case 0x7e:
+ printk("advanced SiS pirq mapping not yet implemented\n");
+ return 0;
+ default:
+ printk("SiS router pirq escape (%d)\n", pirq);
+ return 0;
+ }
pci_write_config_byte(router, reg, x);
return 1;
@@ -462,18 +547,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
irq = pirq & 0xf;
DBG(" -> hardcoded IRQ %d\n", irq);
msg = "Hardcoded";
- if (dev->irq && dev->irq != irq) {
- printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n");
- return 0;
- }
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) {
DBG(" -> got IRQ %d\n", irq);
msg = "Found";
- /* We refuse to override the dev->irq information. Give a warning! */
- if (dev->irq && dev->irq != irq) {
- printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n");
- return 0;
- }
} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
DBG(" -> assigning IRQ %d", newirq);
if (r->set(pirq_router_dev, dev, pirq, newirq)) {
@@ -504,6 +580,11 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
if (!info)
continue;
if (info->irq[pin].link == pirq) {
+ /* We refuse to override the dev->irq information. Give a warning! */
+ if (dev2->irq && dev2->irq != irq) {
+ printk("IRQ routing conflict in pirq table for device %s\n", dev2->slot_name);
+ continue;
+ }
dev2->irq = irq;
pirq_penalty[irq]++;
if (dev != dev2)
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 0ea0d89e9b33..2c3f61f7fc36 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1401,9 +1401,6 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
wrmsr (0x1107, lo, hi);
set_bit(X86_FEATURE_CX8, &c->x86_capability);
- rdmsr (0x80000001, lo, hi);
- if (hi & (1<<31))
- set_bit(X86_FEATURE_3DNOW, &c->x86_capability);
get_model_name(c);
display_cacheinfo(c);
@@ -1874,7 +1871,8 @@ static int __init id_and_try_enable_cpuid(struct cpuinfo_x86 *c)
/* Detect Cyrix with disabled CPUID */
if ( c->x86 == 4 && test_cyrix_52div() ) {
strcpy(c->x86_vendor_id, "CyrixInstead");
- }
+ c->x86_vendor = X86_VENDOR_CYRIX;
+ } else
/* Detect NexGen with old hypercode */
if ( deep_magic_nexgen_probe() ) {
diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S
index 75d8b4ef9581..0edf490851c4 100644
--- a/arch/sh/boot/compressed/head.S
+++ b/arch/sh/boot/compressed/head.S
@@ -43,7 +43,7 @@ bss_start_addr:
end_addr:
.long _end
init_sr:
- .long 0x40000000 /* Privileged mode, Bank=0, Block=0, I3-I0=0 */
+ .long 0x400000F0 /* Privileged mode, Bank=0, Block=0, IMASK=0xF */
init_stack_addr:
.long stack_start
decompress_kernel_addr:
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 37d29a6c40ad..f2756f72c81d 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -36,23 +36,23 @@
* NOTE: This code uses a convention that instructions in the delay slot
* of a transfer-control instruction are indented by an extra space, thus:
*
- * jmp @$k0 ! control-transfer instruction
- * ldc $k1, $ssr ! delay slot
+ * jmp @k0 ! control-transfer instruction
+ * ldc k1, ssr ! delay slot
*
* Stack layout in 'ret_from_syscall':
* ptrace needs to have all regs on the stack.
* if the order here is changed, it needs to be
* updated in ptrace.c and ptrace.h
*
- * $r0
+ * r0
* ...
- * $r15 = stack pointer
- * $spc
- * $pr
- * $ssr
- * $gbr
- * $mach
- * $macl
+ * r15 = stack pointer
+ * spc
+ * pr
+ * ssr
+ * gbr
+ * mach
+ * macl
* syscall #
*
*/
@@ -88,16 +88,16 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register
#endif
/* Offsets to the stack */
-R0 = 0 /* Return value. New ABI also arg4 */
-R1 = 4 /* New ABI: arg5 */
-R2 = 8 /* New ABI: arg6 */
-R3 = 12 /* New ABI: syscall_nr */
-R4 = 16 /* New ABI: arg0 */
-R5 = 20 /* New ABI: arg1 */
-R6 = 24 /* New ABI: arg2 */
-R7 = 28 /* New ABI: arg3 */
-SP = (15*4)
-SR = (16*4+8)
+OFF_R0 = 0 /* Return value. New ABI also arg4 */
+OFF_R1 = 4 /* New ABI: arg5 */
+OFF_R2 = 8 /* New ABI: arg6 */
+OFF_R3 = 12 /* New ABI: syscall_nr */
+OFF_R4 = 16 /* New ABI: arg0 */
+OFF_R5 = 20 /* New ABI: arg1 */
+OFF_R6 = 24 /* New ABI: arg2 */
+OFF_R7 = 28 /* New ABI: arg3 */
+OFF_SP = (15*4)
+OFF_SR = (16*4+8)
SYSCALL_NR = (16*4+6*4)
@@ -140,117 +140,139 @@ SYSCALL_NR = (16*4+6*4)
!
#define STI() \
- mov.l __INV_IMASK, $r11; \
- stc $sr, $r10; \
- and $r11, $r10; \
- stc $k_g_imask, $r11; \
- or $r11, $r10; \
- ldc $r10, $sr
+ mov.l __INV_IMASK, r11; \
+ stc sr, r10; \
+ and r11, r10; \
+ stc k_g_imask, r11; \
+ or r11, r10; \
+ ldc r10, sr
.align 2
tlb_miss_load:
bra call_dpf
- mov #0, $r5
+ mov #0, r5
.align 2
tlb_miss_store:
bra call_dpf
- mov #1, $r5
+ mov #1, r5
.align 2
initial_page_write:
bra call_dpf
- mov #1, $r5
+ mov #1, r5
.align 2
tlb_protection_violation_load:
bra call_dpf
- mov #0, $r5
+ mov #0, r5
.align 2
tlb_protection_violation_store:
bra call_dpf
- mov #1, $r5
+ mov #1, r5
call_dpf:
- mov.l 1f, $r0
- mov $r5, $r8
- mov.l @$r0, $r6
- mov $r6, $r9
- mov.l 2f, $r0
- sts $pr, $r10
- jsr @$r0
- mov $r15, $r4
+ mov.l 1f, r0
+ mov r5, r8
+ mov.l @r0, r6
+ mov r6, r9
+ mov.l 2f, r0
+ sts pr, r10
+ jsr @r0
+ mov r15, r4
!
- tst #0xff, $r0
+ tst #0xff, r0
bf/s 0f
- lds $r10, $pr
+ lds r10, pr
rts
nop
0: STI()
- mov.l 3f, $r0
- mov $r9, $r6
- mov $r8, $r5
- jmp @$r0
- mov $r15, $r4
+ mov.l 3f, r0
+ mov r9, r6
+ mov r8, r5
+ jmp @r0
+ mov r15, r4
.align 2
1: .long MMU_TEA
2: .long SYMBOL_NAME(__do_page_fault)
3: .long SYMBOL_NAME(do_page_fault)
+ .align 2
+address_error_load:
+ bra call_dae
+ mov #0,r5 ! writeaccess = 0
+
+ .align 2
+address_error_store:
+ bra call_dae
+ mov #1,r5 ! writeaccess = 1
+
+call_dae:
+ mov.l 1f, r0
+ mov.l @r0, r6 ! address
+ mov.l 2f, r0
+ jmp @r0
+ mov r15, r4 ! regs
+
+ .align 2
+1: .long MMU_TEA
+2: .long SYMBOL_NAME(do_address_error)
+
#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
.align 2
/* Unwind the stack and jmp to the debug entry */
debug_kernel:
- mov.l @$r15+, $r0
- mov.l @$r15+, $r1
- mov.l @$r15+, $r2
- mov.l @$r15+, $r3
- mov.l @$r15+, $r4
- mov.l @$r15+, $r5
- mov.l @$r15+, $r6
- mov.l @$r15+, $r7
- stc $sr, $r8
- mov.l 1f, $r9 ! BL =1, RB=1, IMASK=0x0F
- or $r9, $r8
- ldc $r8, $sr ! here, change the register bank
- mov.l @$r15+, $r8
- mov.l @$r15+, $r9
- mov.l @$r15+, $r10
- mov.l @$r15+, $r11
- mov.l @$r15+, $r12
- mov.l @$r15+, $r13
- mov.l @$r15+, $r14
- mov.l @$r15+, $k0
- ldc.l @$r15+, $spc
- lds.l @$r15+, $pr
- mov.l @$r15+, $k1
- ldc.l @$r15+, $gbr
- lds.l @$r15+, $mach
- lds.l @$r15+, $macl
- mov $k0, $r15
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ mov.l @r15+, r7
+ stc sr, r8
+ mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F
+ or r9, r8
+ ldc r8, sr ! here, change the register bank
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ mov.l @r15+, r12
+ mov.l @r15+, r13
+ mov.l @r15+, r14
+ mov.l @r15+, k0
+ ldc.l @r15+, spc
+ lds.l @r15+, pr
+ mov.l @r15+, k1
+ ldc.l @r15+, gbr
+ lds.l @r15+, mach
+ lds.l @r15+, macl
+ mov k0, r15
!
- mov.l 2f, $k0
- jmp @$k0
- ldc $k1, $ssr
+ mov.l 2f, k0
+ mov.l @k0, k0
+ jmp @k0
+ ldc k1, ssr
.align 2
1: .long 0x300000f0
-2: .long CONFIG_GDB_STUB_VBR + 0x100
+2: .long SYMBOL_NAME(gdb_vbr_vector)
#endif
.align 2
debug_trap:
#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
- mov #SR, $r0
- mov.l @($r0,$r15), $r0 ! get status register
- shll $r0
- shll $r0 ! kernel space?
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
bt/s debug_kernel
#endif
- mov.l @$r15, $r0
- mov.l 1f, $r8
- jmp @$r8
+ mov.l @r15, r0
+ mov.l 1f, r8
+ jmp @r8
nop
.align 2
@@ -260,8 +282,8 @@ debug_trap:
error:
!
STI()
- mov.l 1f, $r0
- jmp @$r0
+ mov.l 1f, r0
+ jmp @r0
nop
.align 2
1: .long SYMBOL_NAME(do_exception_error)
@@ -272,7 +294,7 @@ error:
!
ENTRY(ret_from_fork)
bra SYMBOL_NAME(ret_from_syscall)
- add #4, $r15 ! pop down bogus r0 (see switch_to MACRO)
+ add #4, r15 ! pop down bogus r0 (see switch_to MACRO)
/*
* Old syscall interface:
@@ -305,90 +327,90 @@ ENTRY(ret_from_fork)
*/
system_call:
- mov.l __TRA, $r9
- mov.l @$r9, $r8
+ mov.l __TRA, r9
+ mov.l @r9, r8
!
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
- mov #0x20, $r9
- extu.b $r9, $r9
- shll2 $r9
- cmp/hs $r9, $r8
+ mov #0x20, r9
+ extu.b r9, r9
+ shll2 r9
+ cmp/hs r9, r8
bt debug_trap
!
- mov #SYSCALL_NR, $r14
- add $r15, $r14
+ mov #SYSCALL_NR, r14
+ add r15, r14
!
#ifdef COMPAT_OLD_SYSCALL_ABI
- mov #0x40, $r9
- cmp/hs $r9, $r8
+ mov #0x40, r9
+ cmp/hs r9, r8
bf/s old_abi_system_call
nop
#endif
! New Syscall ABI
- add #-0x40, $r8
- shlr2 $r8
- shll8 $r8
- shll8 $r8 ! $r8 = num_args<<16
- mov $r3, $r10
- or $r8, $r10 ! Encode syscall # and # of arguments
- mov.l $r10, @$r14 ! set syscall_nr
+ add #-0x40, r8
+ shlr2 r8
+ shll8 r8
+ shll8 r8 ! r8 = num_args<<16
+ mov r3, r10
+ or r8, r10 ! Encode syscall # and # of arguments
+ mov.l r10, @r14 ! set syscall_nr
STI()
!
- stc $k_current, $r11
- mov.l @(tsk_ptrace,$r11), $r10 ! Is current PTRACE_SYSCALL'd?
- mov #PT_TRACESYS, $r11
- tst $r11, $r10
+ stc k_current, r11
+ mov.l @(tsk_ptrace,r11), r10 ! Is current PTRACE_SYSCALL'd?
+ mov #PT_TRACESYS, r11
+ tst r11, r10
bt 5f
! Yes it is traced.
- mov.l __syscall_trace, $r11 ! Call syscall_trace() which notifies
- jsr @$r11 ! superior (will chomp $R[0-7])
+ mov.l __syscall_trace, r11 ! Call syscall_trace() which notifies
+ jsr @r11 ! superior (will chomp R[0-7])
nop
- ! Reload $R0-$R4 from kernel stack, where the
+ ! Reload R0-R4 from kernel stack, where the
! parent may have modified them using
- ! ptrace(POKEUSR). (Note that $R0-$R2 are
+ ! ptrace(POKEUSR). (Note that R0-R2 are
! used by the system call handler directly
! from the kernel stack anyway, so don't need
! to be reloaded here.) This allows the parent
! to rewrite system calls and args on the fly.
- mov.l @(R4,$r15), $r4 ! arg0
- mov.l @(R5,$r15), $r5
- mov.l @(R6,$r15), $r6
- mov.l @(R7,$r15), $r7 ! arg3
- mov.l @(R3,$r15), $r3 ! syscall_nr
+ mov.l @(OFF_R4,r15), r4 ! arg0
+ mov.l @(OFF_R5,r15), r5
+ mov.l @(OFF_R6,r15), r6
+ mov.l @(OFF_R7,r15), r7 ! arg3
+ mov.l @(OFF_R3,r15), r3 ! syscall_nr
! Arrange for syscall_trace() to be called
! again as the system call returns.
- mov.l __syscall_ret_trace, $r10
+ mov.l __syscall_ret_trace, r10
bra 6f
- lds $r10, $pr
+ lds r10, pr
! No it isn't traced.
! Arrange for normal system call return.
-5: mov.l __syscall_ret, $r10
- lds $r10, $pr
+5: mov.l __syscall_ret, r10
+ lds r10, pr
! Call the system call handler through the table.
! (both normal and ptrace'd)
! First check for bad syscall number
-6: mov $r3, $r9
- mov.l __n_sys, $r10
- cmp/hs $r10, $r9
+6: mov r3, r9
+ mov.l __n_sys, r10
+ cmp/hs r10, r9
bf 2f
! Bad syscall number
rts ! go to syscall_ret or syscall_ret_trace
- mov #-ENOSYS, $r0
+ mov #-ENOSYS, r0
! Good syscall number
-2: shll2 $r9 ! x4
- mov.l __sct, $r11
- add $r11, $r9
- mov.l @$r9, $r11
- jmp @$r11 ! jump to specific syscall handler
+2: shll2 r9 ! x4
+ mov.l __sct, r11
+ add r11, r9
+ mov.l @r9, r11
+ jmp @r11 ! jump to specific syscall handler
nop
! In case of trace
syscall_ret_trace:
- mov.l $r0, @(R0,$r15) ! save the return value
- mov.l __syscall_trace, $r1
- mova SYMBOL_NAME(ret_from_syscall), $r0
- jmp @$r1 ! Call syscall_trace() which notifies superior
- lds $r0, $pr ! Then return to ret_from_syscall()
+ mov.l r0, @(OFF_R0,r15) ! save the return value
+ mov.l __syscall_trace, r1
+ mova SYMBOL_NAME(ret_from_syscall), r0
+ jmp @r1 ! Call syscall_trace() which notifies superior
+ lds r0, pr ! Then return to ret_from_syscall()
@@ -396,41 +418,41 @@ syscall_ret_trace:
! Handle old ABI system call.
! Note that ptrace(SYSCALL) is not supported for the old ABI.
! At this point:
-! $r0, $r4-7 as per ABI
-! $r8 = value of TRA register (= num_args<<2)
-! $r14 = points to SYSCALL_NR in stack frame
+! r0, r4-7 as per ABI
+! r8 = value of TRA register (= num_args<<2)
+! r14 = points to SYSCALL_NR in stack frame
old_abi_system_call:
- mov $r0, $r9 ! Save system call number in $r9
+ mov r0, r9 ! Save system call number in r9
! ! arrange for return which pops stack
- mov.l __old_abi_syscall_ret, $r10
- lds $r10, $pr
+ mov.l __old_abi_syscall_ret, r10
+ lds r10, pr
! Build the stack frame if TRA > 0
- mov $r8, $r10
- cmp/pl $r10
+ mov r8, r10
+ cmp/pl r10
bf 0f
- mov.l @(SP,$r15), $r0 ! get original user stack
-7: add #-4, $r10
-4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
- mov.l $r1, @-$r15
- cmp/pl $r10
+ mov.l @(OFF_SP,r15), r0 ! get original user stack
+7: add #-4, r10
+4: mov.l @(r0,r10), r1 ! May cause address error exception..
+ mov.l r1, @-r15
+ cmp/pl r10
bt 7b
0:
- mov.l $r9, @$r14 ! set syscall_nr
+ mov.l r9, @r14 ! set syscall_nr
STI()
! Call the system call handler through the table.
! First check for bad syscall number
- mov.l __n_sys, $r10
- cmp/hs $r10, $r9
+ mov.l __n_sys, r10
+ cmp/hs r10, r9
bf 2f
! Bad syscall number
rts ! return to old_abi_syscall_ret
- mov #-ENOSYS, $r0
+ mov #-ENOSYS, r0
! Good syscall number
-2: shll2 $r9 ! x4
- mov.l __sct, $r11
- add $r11, $r9
- mov.l @$r9, $r11
- jmp @$r11 ! call specific syscall handler,
+2: shll2 r9 ! x4
+ mov.l __sct, r11
+ add r11, r9
+ mov.l @r9, r11
+ jmp @r11 ! call specific syscall handler,
nop
.align 2
@@ -440,16 +462,16 @@ __old_abi_syscall_ret:
! This code gets called on address error exception when copying
! syscall arguments from user stack to kernel stack. It is
! supposed to return -EINVAL through old_abi_syscall_ret, but it
- ! appears to have been broken for a long time in that the $r0
- ! return value will be saved into the kernel stack relative to $r15
- ! but the value of $r15 is not correct partway through the loop.
- ! So the user prog is returned its old $r0 value, not -EINVAL.
+ ! appears to have been broken for a long time in that the r0
+ ! return value will be saved into the kernel stack relative to r15
+ ! but the value of r15 is not correct partway through the loop.
+ ! So the user prog is returned its old r0 value, not -EINVAL.
! Greg Banks 28 Aug 2000.
.section .fixup,"ax"
fixup_syscall_argerr:
- ! First get $r15 back to
+ ! First get r15 back to
rts
- mov #-EINVAL, $r0
+ mov #-EINVAL, r0
.previous
.section __ex_table, "a"
@@ -473,18 +495,18 @@ __syscall_ret:
.align 2
reschedule:
- mova SYMBOL_NAME(ret_from_syscall), $r0
- mov.l 1f, $r1
- jmp @$r1
- lds $r0, $pr
+ mova SYMBOL_NAME(ret_from_syscall), r0
+ mov.l 1f, r1
+ jmp @r1
+ lds r0, pr
.align 2
1: .long SYMBOL_NAME(schedule)
ENTRY(ret_from_irq)
- mov #SR, $r0
- mov.l @($r0,$r15), $r0 ! get status register
- shll $r0
- shll $r0 ! kernel space?
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
bt restore_all ! Yes, it's from kernel, go back soon
!
STI()
@@ -492,10 +514,10 @@ ENTRY(ret_from_irq)
nop
ENTRY(ret_from_exception)
- mov #SR, $r0
- mov.l @($r0,$r15), $r0 ! get status register
- shll $r0
- shll $r0 ! kernel space?
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
bt restore_all ! Yes, it's from kernel, go back soon
!
STI()
@@ -508,38 +530,38 @@ __INV_IMASK:
.align 2
#ifdef COMPAT_OLD_SYSCALL_ABI
old_abi_syscall_ret:
- add $r8, $r15 ! pop off the arguments
+ add r8, r15 ! pop off the arguments
/* fall through */
#endif
syscall_ret:
- mov.l $r0, @(R0,$r15) ! save the return value
+ mov.l r0, @(OFF_R0,r15) ! save the return value
/* fall through */
ENTRY(ret_from_syscall)
- mov.l __irq_stat, $r0 ! softirq_active
- mov.l @$r0, $r1
- mov.l @(4,$r0), $r2 ! softirq_mask
- tst $r2, $r1
+ mov.l __irq_stat, r0 ! softirq_active
+ mov.l @r0, r1
+ mov.l @(4,r0), r2 ! softirq_mask
+ tst r2, r1
bt ret_with_reschedule
handle_softirq:
- mov.l __do_softirq, $r0
- jsr @$r0
+ mov.l __do_softirq, r0
+ jsr @r0
nop
ret_with_reschedule:
- stc $k_current, $r1
- mov.l @(need_resched,$r1), $r0
- tst #0xff, $r0
+ stc k_current, r1
+ mov.l @(need_resched,r1), r0
+ tst #0xff, r0
bf reschedule
- mov.l @(sigpending,$r1), $r0
- tst #0xff, $r0
+ mov.l @(sigpending,r1), r0
+ tst #0xff, r0
bt restore_all
signal_return:
- mov $r15, $r4
- mov #0, $r5
- mov.l __do_signal, $r1
- mova restore_all, $r0
- jmp @$r1
- lds $r0, $pr
+ mov r15, r4
+ mov #0, r5
+ mov.l __do_signal, r1
+ mova restore_all, r0
+ jmp @r1
+ lds r0, pr
.align 2
__do_signal:
.long SYMBOL_NAME(do_signal)
@@ -551,108 +573,108 @@ __do_softirq:
.align 2
restore_all:
#if defined(__SH4__)
- mov.l __fpu_prepare_fd, $r0
- jsr @$r0
- stc $sr, $r4
+ mov.l __fpu_prepare_fd, r0
+ jsr @r0
+ stc sr, r4
#endif
!
- mov.l @$r15+, $r0
- mov.l @$r15+, $r1
- mov.l @$r15+, $r2
- mov.l @$r15+, $r3
- mov.l @$r15+, $r4
- mov.l @$r15+, $r5
- mov.l @$r15+, $r6
- mov.l @$r15+, $r7
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ mov.l @r15+, r7
!
- stc $sr, $r8
- mov.l __blrb_flags, $r9 ! BL =1, RB=1
- or $r9, $r8
- ldc $r8, $sr ! here, change the register bank
+ stc sr, r8
+ mov.l __blrb_flags, r9 ! BL =1, RB=1
+ or r9, r8
+ ldc r8, sr ! here, change the register bank
!
- mov.l @$r15+, $r8
- mov.l @$r15+, $r9
- mov.l @$r15+, $r10
- mov.l @$r15+, $r11
- mov.l @$r15+, $r12
- mov.l @$r15+, $r13
- mov.l @$r15+, $r14
- mov.l @$r15+, $k4 ! original stack pointer
- ldc.l @$r15+, $spc
- lds.l @$r15+, $pr
- mov.l @$r15+, $k3 ! original SR
- ldc.l @$r15+, $gbr
- lds.l @$r15+, $mach
- lds.l @$r15+, $macl
- add #4, $r15 ! Skip syscall number
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ mov.l @r15+, r12
+ mov.l @r15+, r13
+ mov.l @r15+, r14
+ mov.l @r15+, k4 ! original stack pointer
+ ldc.l @r15+, spc
+ lds.l @r15+, pr
+ mov.l @r15+, k3 ! original SR
+ ldc.l @r15+, gbr
+ lds.l @r15+, mach
+ lds.l @r15+, macl
+ add #4, r15 ! Skip syscall number
!
! Calculate new SR value
- mov $k3, $k2 ! original SR value
- mov.l 1f, $k1
- stc $sr, $k0
- and $k1, $k0 ! Get current FD-bit
- mov.l 2f, $k1
- and $k1, $k2 ! Mask orignal SR value
- or $k0, $k2 ! Inherit current FD-bit
+ mov k3, k2 ! original SR value
+ mov.l 1f, k1
+ stc sr, k0
+ and k1, k0 ! Get current FD-bit
+ mov.l 2f, k1
+ and k1, k2 ! Mask orignal SR value
+ or k0, k2 ! Inherit current FD-bit
!
- mov $k3, $k0 ! Calculate IMASK-bits
- shlr2 $k0
- and #0x3c, $k0
- cmp/eq #0x3c, $k0
+ mov k3, k0 ! Calculate IMASK-bits
+ shlr2 k0
+ and #0x3c, k0
+ cmp/eq #0x3c, k0
bt/s 7f
- shll2 $k0
- mov $g_imask, $k0
+ shll2 k0
+ mov g_imask, k0
!
-7: or $k0, $k2 ! Set the IMASK-bits
- ldc $k2, $ssr
+7: or k0, k2 ! Set the IMASK-bits
+ ldc k2, ssr
!
#if defined(__SH4__)
- shll $k2
- shll $k2
+ shll k2
+ shll k2
bf 9f ! user mode
/* Kernel to kernel transition */
- mov.l 1f, $k1
- tst $k1, $k3
+ mov.l 1f, k1
+ tst k1, k3
bf 9f ! it hadn't FPU
! Kernel to kernel and FPU was used
! There's the case we don't get FPU now
- stc $sr, $k2
- tst $k1, $k2
+ stc sr, k2
+ tst k1, k2
bt 8f
! We need to grab FPU here
- xor $k1, $k2
- ldc $k2, $sr ! Grab FPU
- mov.l __init_task_flags, $k1
- mov.l @$k1, $k2
- mov.l __PF_USEDFPU, $k0
- or $k0, $k2
- mov.l $k2, @$k1 ! Set init_task.flags |= PF_USEDFPU
+ xor k1, k2
+ ldc k2, sr ! Grab FPU
+ mov.l __init_task_flags, k1
+ mov.l @k1, k2
+ mov.l __PF_USEDFPU, k0
+ or k0, k2
+ mov.l k2, @k1 ! Set init_task.flags |= PF_USEDFPU
!
! Restoring FPU...
!
-8: mov.l 3f, $k1
- lds $k1, $fpscr
- fmov.s @$r15+, $fr0
- fmov.s @$r15+, $fr1
- fmov.s @$r15+, $fr2
- fmov.s @$r15+, $fr3
- fmov.s @$r15+, $fr4
- fmov.s @$r15+, $fr5
- fmov.s @$r15+, $fr6
- fmov.s @$r15+, $fr7
- fmov.s @$r15+, $fr8
- fmov.s @$r15+, $fr9
- fmov.s @$r15+, $fr10
- fmov.s @$r15+, $fr11
- fmov.s @$r15+, $fr12
- fmov.s @$r15+, $fr13
- fmov.s @$r15+, $fr14
- fmov.s @$r15+, $fr15
- lds.l @$r15+, $fpscr
- lds.l @$r15+, $fpul
+8: mov.l 3f, k1
+ lds k1, fpscr
+ fmov.s @r15+, fr0
+ fmov.s @r15+, fr1
+ fmov.s @r15+, fr2
+ fmov.s @r15+, fr3
+ fmov.s @r15+, fr4
+ fmov.s @r15+, fr5
+ fmov.s @r15+, fr6
+ fmov.s @r15+, fr7
+ fmov.s @r15+, fr8
+ fmov.s @r15+, fr9
+ fmov.s @r15+, fr10
+ fmov.s @r15+, fr11
+ fmov.s @r15+, fr12
+ fmov.s @r15+, fr13
+ fmov.s @r15+, fr14
+ fmov.s @r15+, fr15
+ lds.l @r15+, fpscr
+ lds.l @r15+, fpul
9:
#endif
- mov $k4, $r15
+ mov k4, r15
rte
nop
@@ -680,10 +702,10 @@ ENTRY(vbr_base)
!
.balign 256,0,256
general_exception:
- mov.l 1f, $k2
- mov.l 2f, $k3
+ mov.l 1f, k2
+ mov.l 2f, k3
bra handle_exception
- mov.l @$k2, $k2
+ mov.l @k2, k2
.align 2
2: .long SYMBOL_NAME(ret_from_exception)
1: .long EXPEVT
@@ -691,17 +713,17 @@ general_exception:
!
.balign 1024,0,1024
tlb_miss:
- mov.l 1f, $k2
- mov.l 4f, $k3
+ mov.l 1f, k2
+ mov.l 4f, k3
bra handle_exception
- mov.l @$k2, $k2
+ mov.l @k2, k2
!
.balign 512,0,512
interrupt:
- mov.l 2f, $k2
- mov.l 3f, $k3
+ mov.l 2f, k2
+ mov.l 3f, k3
bra handle_exception
- mov.l @$k2, $k2
+ mov.l @k2, k2
.align 2
1: .long EXPEVT
@@ -715,102 +737,102 @@ handle_exception:
! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
! save all registers onto stack.
!
- stc $ssr, $k0 ! from kernel space?
- shll $k0 ! Check MD bit (bit30) by shifting it into the T bit
- shll $k0
+ stc ssr, k0 ! from kernel space?
+ shll k0 ! Check MD bit (bit30) by shifting it into the T bit
+ shll k0
#if defined(__SH4__)
bf/s 8f ! it's from user to kernel transition
- mov $r15, $k0 ! save original stack to k0
+ mov r15, k0 ! save original stack to k0
/* It's a kernel to kernel transition. */
/* Is the FPU disabled? */
- mov.l 2f, $k1
- stc $ssr, $k0
- tst $k1, $k0
- mov.l 4f, $k1
+ mov.l 2f, k1
+ stc ssr, k0
+ tst k1, k0
+ mov.l 4f, k1
bf/s 9f ! FPU is not enabled, no need to save it
- mov $r15, $k0 ! save original stack to k0
+ mov r15, k0 ! save original stack to k0
! FPU is enabled, save it
! /* XXX: Need to save another bank of FPU if all FPU feature is used */
! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */
- sts.l $fpul, @-$r15
- sts.l $fpscr, @-$r15
- mov.l 6f, $k1
- lds $k1, $fpscr
- mov.l 3f, $k1
- fmov.s $fr15, @-$r15
- fmov.s $fr14, @-$r15
- fmov.s $fr13, @-$r15
- fmov.s $fr12, @-$r15
- fmov.s $fr11, @-$r15
- fmov.s $fr10, @-$r15
- fmov.s $fr9, @-$r15
- fmov.s $fr8, @-$r15
- fmov.s $fr7, @-$r15
- fmov.s $fr6, @-$r15
- fmov.s $fr5, @-$r15
- fmov.s $fr4, @-$r15
- fmov.s $fr3, @-$r15
- fmov.s $fr2, @-$r15
- fmov.s $fr1, @-$r15
+ sts.l fpul, @-r15
+ sts.l fpscr, @-r15
+ mov.l 6f, k1
+ lds k1, fpscr
+ mov.l 3f, k1
+ fmov.s fr15, @-r15
+ fmov.s fr14, @-r15
+ fmov.s fr13, @-r15
+ fmov.s fr12, @-r15
+ fmov.s fr11, @-r15
+ fmov.s fr10, @-r15
+ fmov.s fr9, @-r15
+ fmov.s fr8, @-r15
+ fmov.s fr7, @-r15
+ fmov.s fr6, @-r15
+ fmov.s fr5, @-r15
+ fmov.s fr4, @-r15
+ fmov.s fr3, @-r15
+ fmov.s fr2, @-r15
+ fmov.s fr1, @-r15
bra 9f
- fmov.s $fr0, @-$r15
+ fmov.s fr0, @-r15
#else
- mov.l 3f, $k1
+ mov.l 3f, k1
bt/s 9f ! it's a kernel to kernel transition, and skip the FPU save.
- mov $r15, $k0 ! save original stack to k0 anyway
+ mov r15, k0 ! save original stack to k0 anyway
#endif
8: /* User space to kernel */
- mov #0x20, $k1
- shll8 $k1 ! $k1 <= 8192 == THREAD_SIZE
- add $current, $k1
- mov $k1, $r15 ! change to kernel stack
+ mov #0x20, k1
+ shll8 k1 ! k1 <= 8192 == THREAD_SIZE
+ add current, k1
+ mov k1, r15 ! change to kernel stack
!
- mov.l 4f, $k1 ! let kernel release FPU
+ mov.l 4f, k1 ! let kernel release FPU
9: ! Save the user registers on the stack.
! At this point, k1 should have been set to the new SR value
- mov #-1, $k4
- mov.l $k4, @-$r15 ! syscall_nr (default: -1)
+ mov #-1, k4
+ mov.l k4, @-r15 ! syscall_nr (default: -1)
!
- sts.l $macl, @-$r15
- sts.l $mach, @-$r15
- stc.l $gbr, @-$r15
- stc.l $ssr, @-$r15
- sts.l $pr, @-$r15
- stc.l $spc, @-$r15
+ sts.l macl, @-r15
+ sts.l mach, @-r15
+ stc.l gbr, @-r15
+ stc.l ssr, @-r15
+ sts.l pr, @-r15
+ stc.l spc, @-r15
!
- lds $k3, $pr ! Set the return address to pr
+ lds k3, pr ! Set the return address to pr
!
- mov.l $k0, @-$r15 ! save orignal stack
- mov.l $r14, @-$r15
- mov.l $r13, @-$r15
- mov.l $r12, @-$r15
- mov.l $r11, @-$r15
- mov.l $r10, @-$r15
- mov.l $r9, @-$r15
- mov.l $r8, @-$r15
+ mov.l k0, @-r15 ! save orignal stack
+ mov.l r14, @-r15
+ mov.l r13, @-r15
+ mov.l r12, @-r15
+ mov.l r11, @-r15
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
!
- stc $sr, $r8 ! Back to normal register bank, and
- or $k1, $r8 ! Block all interrupts, may release FPU
- mov.l 5f, $k1
- and $k1, $r8 ! ...
- ldc $r8, $sr ! ...changed here.
+ stc sr, r8 ! Back to normal register bank, and
+ or k1, r8 ! Block all interrupts, may release FPU
+ mov.l 5f, k1
+ and k1, r8 ! ...
+ ldc r8, sr ! ...changed here.
!
- mov.l $r7, @-$r15
- mov.l $r6, @-$r15
- mov.l $r5, @-$r15
- mov.l $r4, @-$r15
- mov.l $r3, @-$r15
- mov.l $r2, @-$r15
- mov.l $r1, @-$r15
- mov.l $r0, @-$r15
+ mov.l r7, @-r15
+ mov.l r6, @-r15
+ mov.l r5, @-r15
+ mov.l r4, @-r15
+ mov.l r3, @-r15
+ mov.l r2, @-r15
+ mov.l r1, @-r15
+ mov.l r0, @-r15
! Then, dispatch to the handler, according to the exception code.
- stc $k_ex_code, $r8
- shlr2 $r8
- shlr $r8
- mov.l 1f, $r9
- add $r8, $r9
- mov.l @$r9, $r9
- jmp @$r9
+ stc k_ex_code, r8
+ shlr2 r8
+ shlr r8
+ mov.l 1f, r9
+ add r8, r9
+ mov.l @r9, r9
+ jmp @r9
nop
.align 2
1: .long SYMBOL_NAME(exception_handling_table)
@@ -833,8 +855,8 @@ ENTRY(exception_handling_table)
.long initial_page_write
.long tlb_protection_violation_load
.long tlb_protection_violation_store
- .long error ! address_error_load (filled by trap_init)
- .long error ! address_error_store (filled by trap_init)
+ .long address_error_load
+ .long address_error_store
#if defined(__SH4__)
.long SYMBOL_NAME(do_fpu_error)
#else
diff --git a/arch/sh/kernel/fpu.c b/arch/sh/kernel/fpu.c
index cbeb60d31186..9036b20c015c 100644
--- a/arch/sh/kernel/fpu.c
+++ b/arch/sh/kernel/fpu.c
@@ -21,43 +21,43 @@
void
save_fpu(struct task_struct *tsk)
{
- asm volatile("sts.l $fpul, @-%0\n\t"
- "sts.l $fpscr, @-%0\n\t"
- "lds %1, $fpscr\n\t"
+ asm volatile("sts.l fpul, @-%0\n\t"
+ "sts.l fpscr, @-%0\n\t"
+ "lds %1, fpscr\n\t"
"frchg\n\t"
- "fmov.s $fr15, @-%0\n\t"
- "fmov.s $fr14, @-%0\n\t"
- "fmov.s $fr13, @-%0\n\t"
- "fmov.s $fr12, @-%0\n\t"
- "fmov.s $fr11, @-%0\n\t"
- "fmov.s $fr10, @-%0\n\t"
- "fmov.s $fr9, @-%0\n\t"
- "fmov.s $fr8, @-%0\n\t"
- "fmov.s $fr7, @-%0\n\t"
- "fmov.s $fr6, @-%0\n\t"
- "fmov.s $fr5, @-%0\n\t"
- "fmov.s $fr4, @-%0\n\t"
- "fmov.s $fr3, @-%0\n\t"
- "fmov.s $fr2, @-%0\n\t"
- "fmov.s $fr1, @-%0\n\t"
- "fmov.s $fr0, @-%0\n\t"
+ "fmov.s fr15, @-%0\n\t"
+ "fmov.s fr14, @-%0\n\t"
+ "fmov.s fr13, @-%0\n\t"
+ "fmov.s fr12, @-%0\n\t"
+ "fmov.s fr11, @-%0\n\t"
+ "fmov.s fr10, @-%0\n\t"
+ "fmov.s fr9, @-%0\n\t"
+ "fmov.s fr8, @-%0\n\t"
+ "fmov.s fr7, @-%0\n\t"
+ "fmov.s fr6, @-%0\n\t"
+ "fmov.s fr5, @-%0\n\t"
+ "fmov.s fr4, @-%0\n\t"
+ "fmov.s fr3, @-%0\n\t"
+ "fmov.s fr2, @-%0\n\t"
+ "fmov.s fr1, @-%0\n\t"
+ "fmov.s fr0, @-%0\n\t"
"frchg\n\t"
- "fmov.s $fr15, @-%0\n\t"
- "fmov.s $fr14, @-%0\n\t"
- "fmov.s $fr13, @-%0\n\t"
- "fmov.s $fr12, @-%0\n\t"
- "fmov.s $fr11, @-%0\n\t"
- "fmov.s $fr10, @-%0\n\t"
- "fmov.s $fr9, @-%0\n\t"
- "fmov.s $fr8, @-%0\n\t"
- "fmov.s $fr7, @-%0\n\t"
- "fmov.s $fr6, @-%0\n\t"
- "fmov.s $fr5, @-%0\n\t"
- "fmov.s $fr4, @-%0\n\t"
- "fmov.s $fr3, @-%0\n\t"
- "fmov.s $fr2, @-%0\n\t"
- "fmov.s $fr1, @-%0\n\t"
- "fmov.s $fr0, @-%0"
+ "fmov.s fr15, @-%0\n\t"
+ "fmov.s fr14, @-%0\n\t"
+ "fmov.s fr13, @-%0\n\t"
+ "fmov.s fr12, @-%0\n\t"
+ "fmov.s fr11, @-%0\n\t"
+ "fmov.s fr10, @-%0\n\t"
+ "fmov.s fr9, @-%0\n\t"
+ "fmov.s fr8, @-%0\n\t"
+ "fmov.s fr7, @-%0\n\t"
+ "fmov.s fr6, @-%0\n\t"
+ "fmov.s fr5, @-%0\n\t"
+ "fmov.s fr4, @-%0\n\t"
+ "fmov.s fr3, @-%0\n\t"
+ "fmov.s fr2, @-%0\n\t"
+ "fmov.s fr1, @-%0\n\t"
+ "fmov.s fr0, @-%0"
: /* no output */
: "r" ((char *)(&tsk->thread.fpu.hard.status)),
"r" (FPSCR_INIT)
@@ -70,43 +70,43 @@ save_fpu(struct task_struct *tsk)
static void
restore_fpu(struct task_struct *tsk)
{
- asm volatile("lds %1, $fpscr\n\t"
- "fmov.s @%0+, $fr0\n\t"
- "fmov.s @%0+, $fr1\n\t"
- "fmov.s @%0+, $fr2\n\t"
- "fmov.s @%0+, $fr3\n\t"
- "fmov.s @%0+, $fr4\n\t"
- "fmov.s @%0+, $fr5\n\t"
- "fmov.s @%0+, $fr6\n\t"
- "fmov.s @%0+, $fr7\n\t"
- "fmov.s @%0+, $fr8\n\t"
- "fmov.s @%0+, $fr9\n\t"
- "fmov.s @%0+, $fr10\n\t"
- "fmov.s @%0+, $fr11\n\t"
- "fmov.s @%0+, $fr12\n\t"
- "fmov.s @%0+, $fr13\n\t"
- "fmov.s @%0+, $fr14\n\t"
- "fmov.s @%0+, $fr15\n\t"
+ asm volatile("lds %1, fpscr\n\t"
+ "fmov.s @%0+, fr0\n\t"
+ "fmov.s @%0+, fr1\n\t"
+ "fmov.s @%0+, fr2\n\t"
+ "fmov.s @%0+, fr3\n\t"
+ "fmov.s @%0+, fr4\n\t"
+ "fmov.s @%0+, fr5\n\t"
+ "fmov.s @%0+, fr6\n\t"
+ "fmov.s @%0+, fr7\n\t"
+ "fmov.s @%0+, fr8\n\t"
+ "fmov.s @%0+, fr9\n\t"
+ "fmov.s @%0+, fr10\n\t"
+ "fmov.s @%0+, fr11\n\t"
+ "fmov.s @%0+, fr12\n\t"
+ "fmov.s @%0+, fr13\n\t"
+ "fmov.s @%0+, fr14\n\t"
+ "fmov.s @%0+, fr15\n\t"
"frchg\n\t"
- "fmov.s @%0+, $fr0\n\t"
- "fmov.s @%0+, $fr1\n\t"
- "fmov.s @%0+, $fr2\n\t"
- "fmov.s @%0+, $fr3\n\t"
- "fmov.s @%0+, $fr4\n\t"
- "fmov.s @%0+, $fr5\n\t"
- "fmov.s @%0+, $fr6\n\t"
- "fmov.s @%0+, $fr7\n\t"
- "fmov.s @%0+, $fr8\n\t"
- "fmov.s @%0+, $fr9\n\t"
- "fmov.s @%0+, $fr10\n\t"
- "fmov.s @%0+, $fr11\n\t"
- "fmov.s @%0+, $fr12\n\t"
- "fmov.s @%0+, $fr13\n\t"
- "fmov.s @%0+, $fr14\n\t"
- "fmov.s @%0+, $fr15\n\t"
+ "fmov.s @%0+, fr0\n\t"
+ "fmov.s @%0+, fr1\n\t"
+ "fmov.s @%0+, fr2\n\t"
+ "fmov.s @%0+, fr3\n\t"
+ "fmov.s @%0+, fr4\n\t"
+ "fmov.s @%0+, fr5\n\t"
+ "fmov.s @%0+, fr6\n\t"
+ "fmov.s @%0+, fr7\n\t"
+ "fmov.s @%0+, fr8\n\t"
+ "fmov.s @%0+, fr9\n\t"
+ "fmov.s @%0+, fr10\n\t"
+ "fmov.s @%0+, fr11\n\t"
+ "fmov.s @%0+, fr12\n\t"
+ "fmov.s @%0+, fr13\n\t"
+ "fmov.s @%0+, fr14\n\t"
+ "fmov.s @%0+, fr15\n\t"
"frchg\n\t"
- "lds.l @%0+, $fpscr\n\t"
- "lds.l @%0+, $fpul\n\t"
+ "lds.l @%0+, fpscr\n\t"
+ "lds.l @%0+, fpul\n\t"
: /* no output */
: "r" (&tsk->thread.fpu), "r" (FPSCR_INIT)
: "memory");
@@ -120,41 +120,41 @@ restore_fpu(struct task_struct *tsk)
void fpu_init(void)
{
- asm volatile("lds %0, $fpul\n\t"
- "lds %1, $fpscr\n\t"
- "fsts $fpul, $fr0\n\t"
- "fsts $fpul, $fr1\n\t"
- "fsts $fpul, $fr2\n\t"
- "fsts $fpul, $fr3\n\t"
- "fsts $fpul, $fr4\n\t"
- "fsts $fpul, $fr5\n\t"
- "fsts $fpul, $fr6\n\t"
- "fsts $fpul, $fr7\n\t"
- "fsts $fpul, $fr8\n\t"
- "fsts $fpul, $fr9\n\t"
- "fsts $fpul, $fr10\n\t"
- "fsts $fpul, $fr11\n\t"
- "fsts $fpul, $fr12\n\t"
- "fsts $fpul, $fr13\n\t"
- "fsts $fpul, $fr14\n\t"
- "fsts $fpul, $fr15\n\t"
+ asm volatile("lds %0, fpul\n\t"
+ "lds %1, fpscr\n\t"
+ "fsts fpul, fr0\n\t"
+ "fsts fpul, fr1\n\t"
+ "fsts fpul, fr2\n\t"
+ "fsts fpul, fr3\n\t"
+ "fsts fpul, fr4\n\t"
+ "fsts fpul, fr5\n\t"
+ "fsts fpul, fr6\n\t"
+ "fsts fpul, fr7\n\t"
+ "fsts fpul, fr8\n\t"
+ "fsts fpul, fr9\n\t"
+ "fsts fpul, fr10\n\t"
+ "fsts fpul, fr11\n\t"
+ "fsts fpul, fr12\n\t"
+ "fsts fpul, fr13\n\t"
+ "fsts fpul, fr14\n\t"
+ "fsts fpul, fr15\n\t"
"frchg\n\t"
- "fsts $fpul, $fr0\n\t"
- "fsts $fpul, $fr1\n\t"
- "fsts $fpul, $fr2\n\t"
- "fsts $fpul, $fr3\n\t"
- "fsts $fpul, $fr4\n\t"
- "fsts $fpul, $fr5\n\t"
- "fsts $fpul, $fr6\n\t"
- "fsts $fpul, $fr7\n\t"
- "fsts $fpul, $fr8\n\t"
- "fsts $fpul, $fr9\n\t"
- "fsts $fpul, $fr10\n\t"
- "fsts $fpul, $fr11\n\t"
- "fsts $fpul, $fr12\n\t"
- "fsts $fpul, $fr13\n\t"
- "fsts $fpul, $fr14\n\t"
- "fsts $fpul, $fr15\n\t"
+ "fsts fpul, fr0\n\t"
+ "fsts fpul, fr1\n\t"
+ "fsts fpul, fr2\n\t"
+ "fsts fpul, fr3\n\t"
+ "fsts fpul, fr4\n\t"
+ "fsts fpul, fr5\n\t"
+ "fsts fpul, fr6\n\t"
+ "fsts fpul, fr7\n\t"
+ "fsts fpul, fr8\n\t"
+ "fsts fpul, fr9\n\t"
+ "fsts fpul, fr10\n\t"
+ "fsts fpul, fr11\n\t"
+ "fsts fpul, fr12\n\t"
+ "fsts fpul, fr13\n\t"
+ "fsts fpul, fr14\n\t"
+ "fsts fpul, fr15\n\t"
"frchg"
: /* no output */
: "r" (0), "r" (FPSCR_INIT));
@@ -192,9 +192,9 @@ do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
*
* There's race condition in __cli:
*
- * (1) $SR --> register
+ * (1) SR --> register
* (2) Set IMASK of register
- * (3) $SR <-- register
+ * (3) SR <-- register
*
* Between (1) and (2), or (2) and (3) getting
* interrupt, and interrupt handler (or
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index f1ac6fd17b07..73c13dc7d917 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -37,40 +37,40 @@ ENTRY(empty_zero_page)
*/
ENTRY(_stext)
! Initialize Status Register
- mov.l 1f, $r0 ! MD=1, RB=0, BL=0, IMASK=0xF
- ldc $r0, $sr
+ mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF
+ ldc r0, sr
! Initialize global interrupt mask
- mov #0, $r0
- ldc $r0, $r6_bank
+ mov #0, r0
+ ldc r0, r6_bank
!
- mov.l 2f, $r0
- mov $r0, $r15 ! Set initial r15 (stack pointer)
- mov #0x20, $r1 !
- shll8 $r1 ! $r1 = 8192
- sub $r1, $r0 !
- ldc $r0, $r7_bank ! ... and init_task
+ mov.l 2f, r0
+ mov r0, r15 ! Set initial r15 (stack pointer)
+ mov #0x20, r1 !
+ shll8 r1 ! r1 = 8192
+ sub r1, r0 !
+ ldc r0, r7_bank ! ... and init_task
!
#if defined(__SH4__)
! Initialize fpu
- mov.l 7f, $r0
- jsr @$r0
+ mov.l 7f, r0
+ jsr @r0
nop
#endif
! Enable cache
- mov.l 6f, $r0
- jsr @$r0
+ mov.l 6f, r0
+ jsr @r0
nop
! Clear BSS area
- mov.l 3f, $r1
- add #4, $r1
- mov.l 4f, $r2
- mov #0, $r0
-9: cmp/hs $r2, $r1
+ mov.l 3f, r1
+ add #4, r1
+ mov.l 4f, r2
+ mov #0, r0
+9: cmp/hs r2, r1
bf/s 9b ! while (r1 < r2)
- mov.l $r0,@-$r2
+ mov.l r0,@-r2
! Start kernel
- mov.l 5f, $r0
- jmp @$r0
+ mov.l 5f, r0
+ jmp @r0
nop
.balign 4
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 6451c4c9effe..200148320965 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -235,7 +235,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
unsigned int status;
/* Get IRQ number */
- asm volatile("stc $r2_bank, %0\n\t"
+ asm volatile("stc r2_bank, %0\n\t"
"shlr2 %0\n\t"
"shlr2 %0\n\t"
"shlr %0\n\t"
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
index 27d91b372c8f..d0b3aea9fe10 100644
--- a/arch/sh/kernel/irq_imask.c
+++ b/arch/sh/kernel/irq_imask.c
@@ -59,16 +59,16 @@ void static inline set_interrupt_registers(int ip)
{
unsigned long __dummy;
- asm volatile("ldc %2, $r6_bank\n\t"
- "stc $sr, %0\n\t"
+ asm volatile("ldc %2, r6_bank\n\t"
+ "stc sr, %0\n\t"
"and #0xf0, %0\n\t"
"shlr2 %0\n\t"
"cmp/eq #0x3c, %0\n\t"
"bt/s 1f ! CLI-ed\n\t"
- " stc $sr, %0\n\t"
+ " stc sr, %0\n\t"
"and %1, %0\n\t"
"or %2, %0\n\t"
- "ldc %0, $sr\n"
+ "ldc %0, sr\n"
"1:"
: "=&z" (__dummy)
: "r" (~0xf0), "r" (ip << 4)
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index c7511093bef6..1ce22f0fd3f7 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -14,6 +14,8 @@
#define __KERNEL_SYSCALLS__
#include <stdarg.h>
+#include <linux/config.h>
+
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -31,6 +33,7 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -39,8 +42,9 @@
#include <asm/processor.h>
#include <asm/mmu_context.h>
#include <asm/elf.h>
-
-#include <linux/irq.h>
+#ifdef CONFIG_SH_STANDARD_BIOS
+#include <asm/sh_bios.h>
+#endif
static int hlt_counter=0;
@@ -79,11 +83,17 @@ void cpu_idle(void *unused)
}
void machine_restart(char * __unused)
-{ /* Need to set MMU_TTB?? */
+{
+#ifdef CONFIG_SH_STANDARD_BIOS
+ sh_bios_shutdown(1);
+#endif
}
void machine_halt(void)
{
+#ifdef CONFIG_SH_STANDARD_BIOS
+ sh_bios_shutdown(0);
+#endif
}
void machine_power_off(void)
@@ -93,7 +103,7 @@ void machine_power_off(void)
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("PC : %08lx SP : %08lx SR : %08lx TEA : %08lx\n",
+ printk("PC : %08lx SP : %08lx SR : %08lx TEA : %08x\n",
regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA));
printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n",
regs->regs[0],regs->regs[1],
@@ -144,12 +154,12 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
register unsigned long __sc9 __asm__ ("r9") = (long) fn;
__asm__("trapa #0x12\n\t" /* Linux/SH system call */
- "tst #0xff, $r0\n\t" /* child or parent? */
+ "tst #0xff, r0\n\t" /* child or parent? */
"bf 1f\n\t" /* parent - jump */
- "jsr @$r9\n\t" /* call fn */
- " mov $r8, $r4\n\t" /* push argument */
- "mov $r0, $r4\n\t" /* return value to arg of exit */
- "mov %1, $r3\n\t" /* exit */
+ "jsr @r9\n\t" /* call fn */
+ " mov r8, r4\n\t" /* push argument */
+ "mov r0, r4\n\t" /* return value to arg of exit */
+ "mov %1, r3\n\t" /* exit */
"trapa #0x11\n"
"1:"
: "=z" (__sc0)
@@ -285,7 +295,7 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
* Restore the kernel mode register
* k7 (r7_bank1)
*/
- asm volatile("ldc %0, $r7_bank"
+ asm volatile("ldc %0, r7_bank"
: /* no output */
:"r" (next));
}
@@ -376,7 +386,7 @@ unsigned long get_wchan(struct task_struct *p)
asmlinkage void print_syscall(int x)
{
unsigned long flags, sr;
- asm("stc $sr, %0": "=r" (sr));
+ asm("stc sr, %0": "=r" (sr));
save_and_cli(flags);
printk("%c: %c %c, %c: SYSCALL\n", (x&63)+32,
(current->flags&PF_USEDFPU)?'C':' ',
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 8dad245df35e..b6fb1e9a8c90 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -503,8 +503,8 @@ int get_cpuinfo(char *buffer)
"cache size\t: 8K-byte/16K-byte\n");
#endif
p += sprintf(p, "bogomips\t: %lu.%02lu\n\n",
- (loops_per_jiffy+2500)/(500000/HZ),
- ((loops_per_jiffy+2500)/(5000/HZ)) % 100);
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100);
p += sprintf(p, "Machine: %s\n", sh_mv.mv_name);
#define PRINT_CLOCK(name, value) \
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index 81a56b960ace..f72f71b988db 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,4 +1,4 @@
-/* $Id: sh_bios.c,v 1.3 2000/09/30 03:43:30 gniibe Exp $
+/* $Id: sh_bios.c,v 1.5 2001/01/08 08:42:32 gniibe Exp $
*
* linux/arch/sh/kernel/sh_bios.c
* C interface for trapping into the standard LinuxSH BIOS.
@@ -7,13 +7,12 @@
*
*/
-#include <linux/config.h>
#include <asm/sh_bios.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-
#define BIOS_CALL_CONSOLE_WRITE 0
-#define BIOS_CALL_READ_BLOCK 1 /* not implemented */
+#define BIOS_CALL_READ_BLOCK 1
+#define BIOS_CALL_ETH_NODE_ADDR 10
+#define BIOS_CALL_SHUTDOWN 11
#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
#define BIOS_CALL_GDB_GET_MODE_PTR 0xfe
#define BIOS_CALL_GDB_DETACH 0xff
@@ -66,5 +65,12 @@ void sh_bios_gdb_detach(void)
sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
}
-#endif
+void sh_bios_get_node_addr (unsigned char *node_addr)
+{
+ sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
+}
+void sh_bios_shutdown(unsigned int how)
+{
+ sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
+}
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 2b0298699bb4..2bdcd75ea8cb 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -64,10 +64,11 @@ EXPORT_SYMBOL(get_vm_area);
#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name)
/* These symbols are generated by the compiler itself */
+DECLARE_EXPORT(__udivsi3);
+DECLARE_EXPORT(__sdivsi3);
+
#ifdef __SH4__
-DECLARE_EXPORT(__udivsi3_i4);
-DECLARE_EXPORT(__sdivsi3_i4);
DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
DECLARE_EXPORT(__ashrdi3);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 1e3cb5277c04..9095c5c791fc 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -431,7 +431,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
current->comm, current->pid, frame, regs->pc, regs->pr);
#endif
- flush_icache_range(regs->pr, regs->pr+4);
+ flush_cache_sigtramp(regs->pr);
return;
give_sigsegv:
@@ -505,7 +505,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, current->pid, frame, regs->pc, regs->pr);
#endif
- flush_icache_range(regs->pr, regs->pr+4);
+ flush_cache_sigtramp(regs->pr);
return;
give_sigsegv:
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 4aeaf8efa0c7..a13d26dab8bf 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -2,7 +2,9 @@
*
* linux/arch/sh/traps.c
*
- * SuperH version: Copyright (C) 1999 Niibe Yutaka
+ * SuperH version: Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 2000 Philipp Rumpf
+ * Copyright (C) 2000 David Howells
*/
/*
@@ -35,7 +37,7 @@ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
{ \
unsigned long error_code; \
\
- asm volatile("stc $r2_bank, %0": "=r" (error_code)); \
+ asm volatile("stc r2_bank, %0": "=r" (error_code)); \
sti(); \
tsk->thread.error_code = error_code; \
tsk->thread.trap_no = trapnr; \
@@ -69,7 +71,16 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
die(str, regs, err);
}
-static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
+static int handle_unaligned_notify_count = 10;
+
+/*
+ * try and fix up kernelspace address errors
+ * - userspace errors just cause EFAULT to be returned, resulting in SEGV
+ * - kernel/userspace interfaces cause a jump to an appropriate handler
+ * - other kernel errors are bad
+ * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
+ */
+static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
{
if (!user_mode(regs))
{
@@ -77,14 +88,407 @@ static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
fixup = search_exception_table(regs->pc);
if (fixup) {
regs->pc = fixup;
- return;
+ return 0;
}
die(str, regs, err);
}
+ return -EFAULT;
+}
+
+/*
+ * handle an instruction that does an unaligned memory access by emulating the
+ * desired behaviour
+ * - note that PC _may not_ point to the faulting instruction
+ * (if that instruction is in a branch delay slot)
+ * - return 0 if emulation okay, -EFAULT on existential error
+ */
+static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
+{
+ int ret, index, count;
+ unsigned long *rm, *rn;
+ unsigned char *src, *dst;
+
+ index = (instruction>>8)&15; /* 0x0F00 */
+ rn = &regs->regs[index];
+
+ index = (instruction>>4)&15; /* 0x00F0 */
+ rm = &regs->regs[index];
+
+ count = 1<<(instruction&3);
+
+ ret = -EFAULT;
+ switch (instruction>>12) {
+ case 0: /* mov.[bwl] to/from memory via r0+rn */
+ if (instruction & 8) {
+ /* from memory */
+ src = (unsigned char*) *rm;
+ src += regs->regs[0];
+ dst = (unsigned char*) rn;
+ *(unsigned long*)dst = 0;
+
+#ifdef __LITTLE_ENDIAN__
+ if (copy_from_user(dst, src, count))
+ goto fetch_fault;
+
+ if ((count == 2) && dst[1] & 0x80) {
+ dst[2] = 0xff;
+ dst[3] = 0xff;
+ }
+#else
+ dst += 4-count;
+
+ if (__copy_user(dst, src, count))
+ goto fetch_fault;
+
+ if ((count == 2) && dst[2] & 0x80) {
+ dst[0] = 0xff;
+ dst[1] = 0xff;
+ }
+#endif
+ } else {
+ /* to memory */
+ src = (unsigned char*) rm;
+#if !defined(__LITTLE_ENDIAN__)
+ src += 4-count;
+#endif
+ dst = (unsigned char*) *rn;
+ dst += regs->regs[0];
+
+ if (copy_to_user(dst, src, count))
+ goto fetch_fault;
+ }
+ ret = 0;
+ break;
+
+ case 1: /* mov.l Rm,@(disp,Rn) */
+ src = (unsigned char*) rm;
+ dst = (unsigned char*) *rn;
+ dst += (instruction&0x000F)<<2;
+
+ if (copy_to_user(dst,src,4))
+ goto fetch_fault;
+ ret = 0;
+ break;
+
+ case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
+ if (instruction & 4)
+ *rn -= count;
+ src = (unsigned char*) rm;
+ dst = (unsigned char*) *rn;
+#if !defined(__LITTLE_ENDIAN__)
+ src += 4-count;
+#endif
+ if (copy_to_user(dst, src, count))
+ goto fetch_fault;
+ ret = 0;
+ break;
+
+ case 5: /* mov.l @(disp,Rm),Rn */
+ src = (unsigned char*) *rm;
+ src += (instruction&0x000F)<<2;
+ dst = (unsigned char*) rn;
+ *(unsigned long*)dst = 0;
+
+ if (copy_from_user(dst,src,4))
+ goto fetch_fault;
+ ret = 0;
+ break;
+
+ case 6: /* mov.[bwl] from memory, possibly with post-increment */
+ src = (unsigned char*) *rm;
+ if (instruction & 4)
+ *rm += count;
+ dst = (unsigned char*) rn;
+ *(unsigned long*)dst = 0;
+
+#ifdef __LITTLE_ENDIAN__
+ if (copy_from_user(dst, src, count))
+ goto fetch_fault;
+
+ if ((count == 2) && dst[1] & 0x80) {
+ dst[2] = 0xff;
+ dst[3] = 0xff;
+ }
+#else
+ dst += 4-count;
+
+ if (copy_from_user(dst, src, count))
+ goto fetch_fault;
+
+ if ((count == 2) && dst[2] & 0x80) {
+ dst[0] = 0xff;
+ dst[1] = 0xff;
+ }
+#endif
+ ret = 0;
+ break;
+
+ case 8:
+ switch ((instruction&0xFF00)>>8) {
+ case 0x81: /* mov.w R0,@(disp,Rn) */
+ src = (unsigned char*) &regs->regs[0];
+#if !defined(__LITTLE_ENDIAN__)
+ src += 2;
+#endif
+ dst = (unsigned char*) *rm; /* called Rn in the spec */
+ dst += (instruction&0x000F)<<1;
+
+ if (copy_to_user(dst, src, 2))
+ goto fetch_fault;
+ ret = 0;
+ break;
+
+ case 0x85: /* mov.w @(disp,Rm),R0 */
+ src = (unsigned char*) *rm;
+ src += (instruction&0x000F)<<1;
+ dst = (unsigned char*) &regs->regs[0];
+ *(unsigned long*)dst = 0;
+
+#if !defined(__LITTLE_ENDIAN__)
+ dst += 2;
+#endif
+
+ if (copy_from_user(dst, src, 2))
+ goto fetch_fault;
+
+#ifdef __LITTLE_ENDIAN__
+ if (dst[1] & 0x80) {
+ dst[2] = 0xff;
+ dst[3] = 0xff;
+ }
+#else
+ if (dst[2] & 0x80) {
+ dst[0] = 0xff;
+ dst[1] = 0xff;
+ }
+#endif
+ ret = 0;
+ break;
+ }
+ break;
+ }
+ return ret;
+
+ fetch_fault:
+ /* Argh. Address not only misaligned but also non-existent.
+ * Raise an EFAULT and see if it's trapped
+ */
+ return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
+}
+
+/*
+ * emulate the instruction in the delay slot
+ * - fetches the instruction from PC+2
+ */
+static inline int handle_unaligned_delayslot(struct pt_regs *regs)
+{
+ u16 instruction;
+
+ if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) {
+ /* the instruction-fetch faulted */
+ if (user_mode(regs))
+ return -EFAULT;
+
+ /* kernel */
+ die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0);
+ }
+
+ return handle_unaligned_ins(instruction,regs);
+}
+
+/*
+ * handle an instruction that does an unaligned memory access
+ * - have to be careful of branch delay-slot instructions that fault
+ * - if the branch would be taken PC points to the branch
+ * - if the branch would not be taken, PC points to delay-slot
+ * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
+ */
+static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
+{
+ u_int rm;
+ int ret, index;
+
+ index = (instruction>>8)&15; /* 0x0F00 */
+ rm = regs->regs[index];
+
+ /* shout about the first ten userspace fixups */
+ if (user_mode(regs) && handle_unaligned_notify_count>0) {
+ handle_unaligned_notify_count--;
+
+ printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+ current->comm,current->pid,(u16*)regs->pc,instruction);
+ }
+
+ ret = -EFAULT;
+ switch (instruction&0xF000) {
+ case 0x0000:
+ if (instruction==0x000B) {
+ /* rts */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc = regs->pr;
+ }
+ else if ((instruction&0x00FF)==0x0023) {
+ /* braf @Rm */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc += rm + 4;
+ }
+ else if ((instruction&0x00FF)==0x0003) {
+ /* bsrf @Rm */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0) {
+ regs->pr = regs->pc + 4;
+ regs->pc += rm + 4;
+ }
+ }
+ else {
+ /* mov.[bwl] to/from memory via r0+rn */
+ goto simple;
+ }
+ break;
+
+ case 0x1000: /* mov.l Rm,@(disp,Rn) */
+ goto simple;
+
+ case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */
+ goto simple;
+
+ case 0x4000:
+ if ((instruction&0x00FF)==0x002B) {
+ /* jmp @Rm */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc = rm;
+ }
+ else if ((instruction&0x00FF)==0x000B) {
+ /* jsr @Rm */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0) {
+ regs->pr = regs->pc + 4;
+ regs->pc = rm;
+ }
+ }
+ else {
+ /* mov.[bwl] to/from memory via r0+rn */
+ goto simple;
+ }
+ break;
+
+ case 0x5000: /* mov.l @(disp,Rm),Rn */
+ goto simple;
+
+ case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */
+ goto simple;
+
+ case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */
+ switch (instruction&0x0F00) {
+ case 0x0100: /* mov.w R0,@(disp,Rm) */
+ goto simple;
+ case 0x0500: /* mov.w @(disp,Rm),R0 */
+ goto simple;
+ case 0x0B00: /* bf lab - no delayslot*/
+ break;
+ case 0x0F00: /* bf/s lab */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc += (instruction&0x00FF)*2 + 4;
+ break;
+ case 0x0900: /* bt lab - no delayslot */
+ break;
+ case 0x0D00: /* bt/s lab */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc += (instruction&0x00FF)*2 + 4;
+ break;
+ }
+ break;
+
+ case 0xA000: /* bra label */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0)
+ regs->pc += (instruction&0x0FFF)*2 + 4;
+ break;
+
+ case 0xB000: /* bsr label */
+ ret = handle_unaligned_delayslot(regs);
+ if (ret==0) {
+ regs->pr = regs->pc + 4;
+ regs->pc += (instruction&0x0FFF)*2 + 4;
+ }
+ break;
+ }
+ return ret;
+
+ /* handle non-delay-slot instruction */
+ simple:
+ ret = handle_unaligned_ins(instruction,regs);
+ if (ret==0)
+ regs->pc += 2;
+ return ret;
+}
+
+/*
+ * Handle various address error exceptions
+ */
+asmlinkage void do_address_error(struct pt_regs *regs,
+ unsigned long writeaccess,
+ unsigned long address)
+{
+ unsigned long error_code;
+ mm_segment_t oldfs;
+ u16 instruction;
+ int tmp;
+
+ asm volatile("stc r2_bank,%0": "=r" (error_code));
+
+ oldfs = get_fs();
+
+ if (user_mode(regs)) {
+ sti();
+ current->thread.error_code = error_code;
+ current->thread.trap_no = (writeaccess) ? 8 : 7;
+
+ /* bad PC is not something we can fix */
+ if (regs->pc & 1)
+ goto uspace_segv;
+
+ set_fs(USER_DS);
+ if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
+ /* Argh. Fault on the instruction itself.
+ This should never happen non-SMP
+ */
+ set_fs(oldfs);
+ goto uspace_segv;
+ }
+
+ tmp = handle_unaligned_access(instruction, regs);
+ set_fs(oldfs);
+
+ if (tmp==0)
+ return; /* sorted */
+
+ uspace_segv:
+ printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm);
+ force_sig(SIGSEGV, current);
+ } else {
+ if (regs->pc & 1)
+ die("unaligned program counter", regs, error_code);
+
+ set_fs(KERNEL_DS);
+ if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
+ /* Argh. Fault on the instruction itself.
+ This should never happen non-SMP
+ */
+ set_fs(oldfs);
+ die("insn faulting in do_address_error", regs, 0);
+ }
+
+ handle_unaligned_access(instruction, regs);
+ set_fs(oldfs);
+ }
}
-DO_ERROR( 7, SIGSEGV, "address error (load)", address_error_load, current)
-DO_ERROR( 8, SIGSEGV, "address error (store)", address_error_store, current)
DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current)
DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current)
@@ -93,25 +497,42 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
struct pt_regs regs)
{
long ex;
- asm volatile("stc $r2_bank, %0" : "=r" (ex));
+ asm volatile("stc r2_bank, %0" : "=r" (ex));
die_if_kernel("exception", &regs, ex);
}
+#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+void *gdb_vbr_vector;
+#endif
+
void __init trap_init(void)
{
extern void *vbr_base;
extern void *exception_handling_table[14];
- exception_handling_table[7] = (void *)do_address_error_load;
- exception_handling_table[8] = (void *)do_address_error_store;
exception_handling_table[12] = (void *)do_reserved_inst;
exception_handling_table[13] = (void *)do_illegal_slot_inst;
+#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+ /*
+ * Read the old value of the VBR register to initialise
+ * the vector through which debug and BIOS traps are
+ * delegated by the Linux trap handler.
+ */
+ {
+ register unsigned long vbr;
+ asm volatile("stc vbr, %0" : "=r" (vbr));
+ gdb_vbr_vector = (void *)(vbr + 0x100);
+ printk("Setting GDB trap vector to 0x%08lx\n",
+ (unsigned long)gdb_vbr_vector);
+ }
+#endif
+
/* NOTE: The VBR value should be at P1
(or P2, virtural "fixed" address space).
It's definitely should not in physical address. */
- asm volatile("ldc %0, $vbr"
+ asm volatile("ldc %0, vbr"
: /* no output */
: "r" (&vbr_base)
: "memory");
@@ -123,8 +544,8 @@ void dump_stack(void)
unsigned long *end;
unsigned long *p;
- asm("mov $r15, %0" : "=r" (start));
- asm("stc $r7_bank, %0" : "=r" (end));
+ asm("mov r15, %0" : "=r" (start));
+ asm("stc r7_bank, %0" : "=r" (end));
end += 8192/4;
printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index c7e96a394fae..9d8e0f47627c 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -49,99 +49,99 @@ ENTRY(csum_partial)
* Fortunately, it is easy to convert 2-byte alignment to 4-byte
* alignment for the unrolled loop.
*/
- mov $r5, $r1
- mov $r4, $r0
- tst #2, $r0 ! Check alignment.
+ mov r5, r1
+ mov r4, r0
+ tst #2, r0 ! Check alignment.
bt 2f ! Jump if alignment is ok.
!
- add #-2, $r5 ! Alignment uses up two bytes.
- cmp/pz $r5 !
+ add #-2, r5 ! Alignment uses up two bytes.
+ cmp/pz r5 !
bt/s 1f ! Jump if we had at least two bytes.
clrt
bra 6f
- add #2, $r5 ! $r5 was < 2. Deal with it.
+ add #2, r5 ! r5 was < 2. Deal with it.
1:
- mov.w @$r4+, $r0
- extu.w $r0, $r0
- addc $r0, $r6
+ mov.w @r4+, r0
+ extu.w r0, r0
+ addc r0, r6
bf 2f
- add #1, $r6
+ add #1, r6
2:
- mov #-5, $r0
- shld $r0, $r5
- tst $r5, $r5
+ mov #-5, r0
+ shld r0, r5
+ tst r5, r5
bt/s 4f ! if it's =0, go to 4f
clrt
.align 2
3:
- mov.l @$r4+, $r0
- mov.l @$r4+, $r2
- mov.l @$r4+, $r3
- addc $r0, $r6
- mov.l @$r4+, $r0
- addc $r2, $r6
- mov.l @$r4+, $r2
- addc $r3, $r6
- mov.l @$r4+, $r3
- addc $r0, $r6
- mov.l @$r4+, $r0
- addc $r2, $r6
- mov.l @$r4+, $r2
- addc $r3, $r6
- addc $r0, $r6
- addc $r2, $r6
- movt $r0
- dt $r5
+ mov.l @r4+, r0
+ mov.l @r4+, r2
+ mov.l @r4+, r3
+ addc r0, r6
+ mov.l @r4+, r0
+ addc r2, r6
+ mov.l @r4+, r2
+ addc r3, r6
+ mov.l @r4+, r3
+ addc r0, r6
+ mov.l @r4+, r0
+ addc r2, r6
+ mov.l @r4+, r2
+ addc r3, r6
+ addc r0, r6
+ addc r2, r6
+ movt r0
+ dt r5
bf/s 3b
- cmp/eq #1, $r0
- ! here, we know $r5==0
- addc $r5, $r6 ! add carry to $r6
+ cmp/eq #1, r0
+ ! here, we know r5==0
+ addc r5, r6 ! add carry to r6
4:
- mov $r1, $r0
- and #0x1c, $r0
- tst $r0, $r0
+ mov r1, r0
+ and #0x1c, r0
+ tst r0, r0
bt/s 6f
- mov $r0, $r5
- shlr2 $r5
- mov #0, $r2
+ mov r0, r5
+ shlr2 r5
+ mov #0, r2
5:
- addc $r2, $r6
- mov.l @$r4+, $r2
- movt $r0
- dt $r5
+ addc r2, r6
+ mov.l @r4+, r2
+ movt r0
+ dt r5
bf/s 5b
- cmp/eq #1, $r0
- addc $r2, $r6
- addc $r5, $r6 ! $r5==0 here, so it means add carry-bit
+ cmp/eq #1, r0
+ addc r2, r6
+ addc r5, r6 ! r5==0 here, so it means add carry-bit
6:
- mov $r1, $r5
- mov #3, $r0
- and $r0, $r5
- tst $r5, $r5
+ mov r1, r5
+ mov #3, r0
+ and r0, r5
+ tst r5, r5
bt 9f ! if it's =0 go to 9f
- mov #2, $r1
- cmp/hs $r1, $r5
+ mov #2, r1
+ cmp/hs r1, r5
bf 7f
- mov.w @r4+, $r0
- extu.w $r0, $r0
- cmp/eq $r1, $r5
+ mov.w @r4+, r0
+ extu.w r0, r0
+ cmp/eq r1, r5
bt/s 8f
clrt
- shll16 $r0
- addc $r0, $r6
+ shll16 r0
+ addc r0, r6
7:
- mov.b @$r4+, $r0
- extu.b $r0, $r0
+ mov.b @r4+, r0
+ extu.b r0, r0
#ifndef __LITTLE_ENDIAN__
- shll8 $r0
+ shll8 r0
#endif
8:
- addc $r0, $r6
- mov #0, $r0
- addc $r0, $r6
+ addc r0, r6
+ mov #0, r0
+ addc r0, r6
9:
rts
- mov $r6, $r0
+ mov r6, r0
/*
unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
@@ -159,14 +159,14 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
* them all but there's no guarantee.
*/
-#define SRC(x,y) \
- 9999: x,y; \
+#define SRC(...) \
+ 9999: __VA_ARGS__ ; \
.section __ex_table, "a"; \
.long 9999b, 6001f ; \
.previous
-#define DST(x,y) \
- 9999: x,y; \
+#define DST(...) \
+ 9999: __VA_ARGS__ ; \
.section __ex_table, "a"; \
.long 9999b, 6002f ; \
.previous
@@ -202,7 +202,7 @@ ENTRY(csum_partial_copy_generic)
bt/s 1f
clrt
bra 4f
- add #2,r6 ! $r6 was < 2. Deal with it.
+ add #2,r6 ! r6 was < 2. Deal with it.
3: ! Handle different src and dest alinments.
! This is not common, so simple byte by byte copy will do.
@@ -211,7 +211,8 @@ ENTRY(csum_partial_copy_generic)
tst r6, r6
bt 4f
clrt
-SRC(5: mov.b @r4+,r0 )
+5:
+SRC( mov.b @r4+,r0 )
DST( mov.b r0,@r5 )
add #1, r5
SRC( mov.b @r4+,r1 )
@@ -244,7 +245,8 @@ DST( mov.b r1,@r5 )
! src and dest equally aligned, but to a two byte boundary.
! Handle first two bytes as a special case
.align 5
-SRC(1: mov.w @r4+,r0 )
+1:
+SRC( mov.w @r4+,r0 )
DST( mov.w r0,@r5 )
add #2,r5
extu.w r0,r0
@@ -258,7 +260,8 @@ DST( mov.w r0,@r5 )
tst r6,r6
bt/s 2f
clrt
-SRC(1: mov.l @r4+,r0 )
+1:
+SRC( mov.l @r4+,r0 )
SRC( mov.l @r4+,r1 )
addc r0,r7
DST( mov.l r0,@r5 )
@@ -276,7 +279,7 @@ DST( mov.l r0,@r5 )
DST( mov.l r1,@r5 )
add #4,r5
-SRC( mov.l @r4+,r0 )
+SRC( mov.l @r4+,r0 )
SRC( mov.l @r4+,r1 )
addc r0,r7
DST( mov.l r0,@r5 )
@@ -307,7 +310,8 @@ DST( mov.l r1,@r5 )
bf/s 4f
clrt
shlr2 r6
-SRC(3: mov.l @r4+,r0 )
+3:
+SRC( mov.l @r4+,r0 )
addc r0,r7
DST( mov.l r0,@r5 )
add #4,r5
@@ -334,7 +338,8 @@ DST( mov.w r0,@r5 )
clrt
shll16 r0
addc r0,r7
-SRC(5: mov.b @r4+,r0 )
+5:
+SRC( mov.b @r4+,r0 )
DST( mov.b r0,@r5 )
extu.b r0,r0
#ifndef __LITTLE_ENDIAN__
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
index 790fd180847c..e1fcc970f0e2 100644
--- a/arch/sh/lib/delay.c
+++ b/arch/sh/lib/delay.c
@@ -21,7 +21,11 @@ void __delay(unsigned long loops)
inline void __const_udelay(unsigned long xloops)
{
- xloops *= current_cpu_data.loops_per_jiffy;
+ __asm__("dmulu.l %0, %2\n\t"
+ "sts mach, %0"
+ : "=r" (xloops)
+ : "0" (xloops), "r" (current_cpu_data.loops_per_jiffy)
+ : "macl", "mach");
__delay(xloops * HZ);
}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index ab63535e4dcc..2ea37e723e25 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -244,6 +244,22 @@ void flush_icache_range(unsigned long start, unsigned long end)
}
/*
+ * Write back the D-cache and purge the I-cache for signal trampoline.
+ */
+void flush_cache_sigtramp(unsigned long addr)
+{
+ unsigned long v, index;
+
+ v = addr & ~(L1_CACHE_BYTES-1);
+ asm volatile("ocbwb %0"
+ : /* no output */
+ : "m" (__m(v)));
+
+ index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
+ ctrl_outl(0, index); /* Clear out Valid-bit */
+}
+
+/*
* Invalidate the I-cache of the page (don't need to write back D-cache).
*
* Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called.
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 70bbda891868..47fcf6226033 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.168 2001/01/01 01:46:15 davem Exp $
+/* $Id: entry.S,v 1.169 2001/01/25 21:47:20 davem Exp $
* arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -999,6 +999,7 @@ C_LABEL(invalid_segment_patch1):
ld [%l4 + 0x18], %l3
inc %l3 ! sun4c_kernel_ring.num_entries++
+ st %l3, [%l4 + 0x18]
b 4f
ld [%l6 + 0x08], %l5
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index c777356b3a63..d80f93cf6155 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -416,6 +416,8 @@ CONFIG_DRM_FFB=m
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=m
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 25f6ecff3306..76045d0d2b27 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -290,8 +290,8 @@ void __init smp_boot_cpus(void)
}
printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount + 1,
- (bogosum + 2500)/500000,
- ((bogosum + 2500)/5000)%100);
+ bogosum/(500000/HZ),
+ (bogosum/(5000/HZ))%100);
smp_activated = 1;
smp_num_cpus = cpucount + 1;
}
diff --git a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
index 13f4fe0e78fc..8e1774c9a99d 100644
--- a/drivers/acpi/acpi_ksyms.c
+++ b/drivers/acpi/acpi_ksyms.c
@@ -81,11 +81,3 @@ EXPORT_SYMBOL(acpi_set_current_resources);
EXPORT_SYMBOL(acpi_enable_event);
EXPORT_SYMBOL(acpi_disable_event);
EXPORT_SYMBOL(acpi_clear_event);
-
-EXPORT_SYMBOL(acpi_get_processor_throttling_info);
-EXPORT_SYMBOL(acpi_get_processor_throttling_state);
-EXPORT_SYMBOL(acpi_set_processor_throttling_state);
-
-EXPORT_SYMBOL(acpi_get_processor_cx_info);
-EXPORT_SYMBOL(acpi_set_processor_sleep_state);
-EXPORT_SYMBOL(acpi_processor_sleep);
diff --git a/drivers/acpi/common/cmalloc.c b/drivers/acpi/common/cmalloc.c
index 880376433130..d8514698fbec 100644
--- a/drivers/acpi/common/cmalloc.c
+++ b/drivers/acpi/common/cmalloc.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: cmalloc - local memory allocation routines
- * $Revision: 83 $
+ * $Revision: 84 $
*
*****************************************************************************/
diff --git a/drivers/acpi/common/cmxface.c b/drivers/acpi/common/cmxface.c
index c968fecfa5fa..ce87b50d273d 100644
--- a/drivers/acpi/common/cmxface.c
+++ b/drivers/acpi/common/cmxface.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: cmxface - External interfaces for "global" ACPI functions
- * $Revision: 58 $
+ * $Revision: 62 $
*
*****************************************************************************/
@@ -304,16 +304,22 @@ acpi_get_system_info (
out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
info_ptr = (ACPI_SYSTEM_INFO *) out_buffer->pointer;
- /* TBD [Future]: need a version number, or use the version string */
- info_ptr->acpi_ca_version = 0x1234;
+ info_ptr->acpi_ca_version = ACPI_CA_VERSION;
/* System flags (ACPI capabilities) */
info_ptr->flags = acpi_gbl_system_flags;
/* Timer resolution - 24 or 32 bits */
-
- info_ptr->timer_resolution = acpi_hw_pmt_resolution ();
+ if (!acpi_gbl_FADT) {
+ info_ptr->timer_resolution = 0;
+ }
+ else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+ info_ptr->timer_resolution = 24;
+ }
+ else {
+ info_ptr->timer_resolution = 32;
+ }
/* Clear the reserved fields */
diff --git a/drivers/acpi/cpu.c b/drivers/acpi/cpu.c
index 00ec59da5214..3e4adcee2b79 100644
--- a/drivers/acpi/cpu.c
+++ b/drivers/acpi/cpu.c
@@ -39,6 +39,9 @@ static int acpi_c3_tested = 0;
static int acpi_max_c_state = 1;
static int acpi_pm_tmr_len;
+#define MAX_C2_LATENCY 100
+#define MAX_C3_LATENCY 1000
+
/*
* Clear busmaster activity flag
*/
@@ -251,10 +254,7 @@ static ACPI_STATUS
acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
{
ACPI_OBJECT obj;
- ACPI_CX_STATE lat[4];
- ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
ACPI_BUFFER buf;
- int i, count;
buf.length = sizeof(obj);
buf.pointer = &obj;
@@ -273,41 +273,28 @@ acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
acpi_pblk = obj.processor.pblk_address;
- buf.length = sizeof(lat);
- buf.pointer = lat;
- if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
- return AE_OK;
+ if (acpi_fadt.plvl2_lat
+ && acpi_fadt.plvl2_lat <= MAX_C2_LATENCY) {
+ acpi_c2_exit_latency
+ = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat);
+ acpi_c2_enter_latency
+ = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
+ acpi_max_c_state = 2;
- if (lat[2].latency < MAX_CX_STATE_LATENCY) {
printk(KERN_INFO "ACPI: System firmware supports: C2");
- acpi_c2_exit_latency = lat[2].latency;
- acpi_max_c_state = 2;
- if (lat[3].latency < MAX_CX_STATE_LATENCY) {
- printk(" C3");
- acpi_c3_exit_latency = lat[3].latency;
+ if (acpi_fadt.plvl3_lat
+ && acpi_fadt.plvl3_lat <= MAX_C3_LATENCY) {
+ acpi_c3_exit_latency
+ = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat);
+ acpi_c3_enter_latency
+ = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5);
acpi_max_c_state = 3;
- }
- printk("\n");
- }
- memset(throttle, 0, sizeof(throttle));
- buf.length = sizeof(throttle);
- buf.pointer = throttle;
-
- if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
- return AE_OK;
-
- for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
- if (throttle[i].percent_of_clock)
- count++;
- }
-
- /* 0% throttled really doesn't count */
- count--;
+ printk(" C3");
+ }
- if (count > 0) {
- DEBUG_PRINT(ACPI_INFO, ("%d throttling states\n", count));
+ printk("\n");
}
return AE_OK;
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 24b7386b4c26..dfaa2a103216 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -1,7 +1,7 @@
/*******************************************************************************
*
* Module Name: dsmthdat - control method arguments and local variables
- * $Revision: 38 $
+ * $Revision: 39 $
*
******************************************************************************/
@@ -40,7 +40,7 @@
*
* FUNCTION: Acpi_ds_method_data_init
*
- * PARAMETERS: *Obj_desc
+ * PARAMETERS: Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -97,7 +97,7 @@ acpi_ds_method_data_init (
*
* FUNCTION: Acpi_ds_method_data_delete_all
*
- * PARAMETERS: None
+ * PARAMETERS: Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -153,7 +153,9 @@ acpi_ds_method_data_delete_all (
*
* FUNCTION: Acpi_ds_method_data_init_args
*
- * PARAMETERS: None
+ * PARAMETERS: *Params - Pointer to a parameter list for the method
+ * Max_param_count - The arg count for this method
+ * Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -214,6 +216,7 @@ acpi_ds_method_data_init_args (
* Index - Which local_var or argument to get
* Entry - Pointer to where a pointer to the stack
* entry is returned.
+ * Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -276,6 +279,7 @@ acpi_ds_method_data_get_entry (
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument to get
* Object - Object to be inserted into the stack entry
+ * Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -320,6 +324,7 @@ acpi_ds_method_data_set_entry (
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument whose type
* to get
+ * Walk_state - Current walk state object
*
* RETURN: Data type of selected Arg or Local
* Used only in Exec_monadic2()/Type_op.
@@ -366,6 +371,7 @@ acpi_ds_method_data_get_type (
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument whose type
* to get
+ * Walk_state - Current walk state object
*
* RETURN: Get the Node associated with a local or arg.
*
@@ -418,7 +424,8 @@ acpi_ds_method_data_get_nte (
*
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument to get
- * *Dest_desc - Descriptor into which selected Arg
+ * Walk_state - Current walk state object
+ * *Dest_desc - Ptr to Descriptor into which selected Arg
* or Local value should be copied
*
* RETURN: Status
@@ -474,10 +481,12 @@ acpi_ds_method_data_get_value (
switch (type)
{
case MTH_TYPE_ARG:
+
return (AE_AML_UNINITIALIZED_ARG);
break;
case MTH_TYPE_LOCAL:
+
return (AE_AML_UNINITIALIZED_LOCAL);
break;
}
@@ -502,6 +511,7 @@ acpi_ds_method_data_get_value (
*
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument to delete
+ * Walk_state - Current walk state object
*
* RETURN: Status
*
@@ -548,7 +558,6 @@ acpi_ds_method_data_delete_value (
* Decrement the reference count by one to balance the
* increment when the object was stored in the slot.
*/
-
acpi_cm_remove_reference (object);
}
@@ -563,18 +572,14 @@ acpi_ds_method_data_delete_value (
*
* PARAMETERS: Type - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
* Index - Which local_var or argument to set
- * *Src_desc - Value to be stored
- * *Dest_desc - Descriptor into which *Src_desc
- * can be copied, or NULL if one must
- * be allocated for the purpose. If
- * provided, this descriptor will be
- * used for the new value.
+ * Src_desc - Value to be stored
+ * Walk_state - Current walk state
*
* RETURN: Status
*
* DESCRIPTION: Store a value in an Arg or Local. The Src_desc is installed
* as the new value for the Arg or Local and the reference count
- * is incremented.
+ * for Src_desc is incremented.
*
******************************************************************************/
@@ -644,7 +649,6 @@ acpi_ds_method_data_set_value (
* Store this object into the Node
* (do the indirect store)
*/
-
status = acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) *entry, src_desc,
src_desc->common.type);
return (status);
@@ -652,10 +656,18 @@ acpi_ds_method_data_set_value (
/*
- * Otherwise, just delete the existing object
- * before storing the new one
+ * Perform "Implicit conversion" of the new object to the type of the
+ * existing object
*/
+ status = acpi_aml_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
+ if (ACPI_FAILURE (status)) {
+ goto cleanup;
+ }
+ /*
+ * Delete the existing object
+ * before storing the new one
+ */
acpi_ds_method_data_delete_value (type, index, walk_state);
}
@@ -666,7 +678,6 @@ acpi_ds_method_data_set_value (
* Install the new object in the stack entry
* (increments the object reference count by one)
*/
-
status = acpi_ds_method_data_set_entry (type, index, src_desc, walk_state);
if (ACPI_FAILURE (status)) {
goto cleanup;
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 6f0a8668c440..a2e1b73d3658 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -2,7 +2,7 @@
*
* Module Name: dswexec - Dispatcher method execution callbacks;
* dispatch to interpreter.
- * $Revision: 54 $
+ * $Revision: 55 $
*
*****************************************************************************/
@@ -330,6 +330,8 @@ acpi_ds_exec_end_op (
walk_state->num_operands = 0;
walk_state->return_desc = NULL;
+ walk_state->op_info = op_info;
+ walk_state->opcode = opcode;
/* Call debugger for single step support (DEBUG build only) */
diff --git a/drivers/acpi/driver.c b/drivers/acpi/driver.c
index 222598120b6c..241528fc6cb9 100644
--- a/drivers/acpi/driver.c
+++ b/drivers/acpi/driver.c
@@ -55,7 +55,7 @@ struct acpi_run_entry
static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
static volatile u32 acpi_event_status = 0;
-static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
+static volatile acpi_sstate_t acpi_event_state = ACPI_STATE_S0;
static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
static volatile int acpi_thread_pid = -1;
@@ -243,7 +243,7 @@ acpi_do_event(ctl_table * ctl,
/*
* Enter system sleep state
*/
-static int
+/*static int
acpi_do_sleep(ctl_table * ctl,
int write,
struct file *file,
@@ -257,13 +257,13 @@ acpi_do_sleep(ctl_table * ctl,
}
}
else {
- int status = acpi_enter_sx(ACPI_S1);
+ int status = acpi_enter_sx(ACPI_STATE_S1);
if (status)
return status;
}
file->f_pos += *len;
return 0;
-}
+}*/
/*
@@ -382,7 +382,8 @@ static struct ctl_table acpi_table[] =
&acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
0644, NULL, &acpi_do_ulong},
- {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
+/* until it actually works */
+/* {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},*/
{ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
@@ -415,7 +416,9 @@ static struct ctl_table acpi_dir_table[] =
static int
acpi_thread(void *context)
{
- ACPI_PHYSICAL_ADDRESS rsdp_phys;
+ ACPI_PHYSICAL_ADDRESS rsdp_phys;
+ ACPI_BUFFER buffer;
+ ACPI_SYSTEM_INFO sys_info;
/*
* initialize
@@ -437,8 +440,6 @@ acpi_thread(void *context)
rsdp_phys = efi.acpi;
#endif
- printk(KERN_ERR "ACPI: System description tables found\n");
-
if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys)))
return -ENODEV;
@@ -448,6 +449,17 @@ acpi_thread(void *context)
return -ENODEV;
}
+ buffer.length = sizeof(sys_info);
+ buffer.pointer = &sys_info;
+
+ if (!ACPI_SUCCESS (acpi_get_system_info(&buffer))) {
+ printk(KERN_ERR "ACPI: Could not get system info\n");
+ acpi_terminate();
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "ACPI: Core Subsystem version [%x]\n", sys_info.acpi_ca_version);
+
if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) {
printk(KERN_ERR "ACPI: Subsystem enable failed\n");
acpi_terminate();
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8bedfac6c59b..5e42683c6ac2 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -400,8 +400,6 @@ ec_region_setup (
{
FUNCTION_TRACE("acpi_ec_region_setup");
- printk("acpi_ec_region_setup\n");
-
if (function == ACPI_REGION_DEACTIVATE)
{
if (*region_context)
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index 28e25368541c..304d3dec6d3b 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -1,7 +1,8 @@
+
/******************************************************************************
*
- * Module Name: hwacpi - ACPI hardware functions - mode and timer
- * $Revision: 35 $
+ * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
+ * $Revision: 36 $
*
*****************************************************************************/
@@ -304,48 +305,3 @@ acpi_hw_get_mode_capabilities (void)
}
-/******************************************************************************
- *
- * FUNCTION: Acpi_hw_pmt_ticks
- *
- * PARAMETERS: none
- *
- * RETURN: Current value of the ACPI PMT (timer)
- *
- * DESCRIPTION: Obtains current value of ACPI PMT
- *
- ******************************************************************************/
-
-u32
-acpi_hw_pmt_ticks (void)
-{
- u32 ticks;
-
- ticks = acpi_os_in32 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address));
-
- return (ticks);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: Acpi_hw_pmt_resolution
- *
- * PARAMETERS: none
- *
- * RETURN: Number of bits of resolution in the PMT (either 24 or 32)
- *
- * DESCRIPTION: Obtains resolution of the ACPI PMT (either 24bit or 32bit)
- *
- ******************************************************************************/
-
-u32
-acpi_hw_pmt_resolution (void)
-{
- if (0 == acpi_gbl_FADT->tmr_val_ext) {
- return (24);
- }
-
- return (32);
-}
-
diff --git a/drivers/acpi/hardware/hwcpu32.c b/drivers/acpi/hardware/hwcpu32.c
deleted file mode 100644
index 380db25e3c62..000000000000
--- a/drivers/acpi/hardware/hwcpu32.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/******************************************************************************
- *
- * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states)
- * $Revision: 42 $
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000, 2001 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "acpi.h"
-#include "acnamesp.h"
-#include "achware.h"
-
-#define _COMPONENT HARDWARE
- MODULE_NAME ("Hwcpu32")
-
-
-#define BIT_4 0x10 /* TBD: [investigate] is this correct? */
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_enter_c1
- *
- * PARAMETERS: Pblk_address - Address of the processor control block
- * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep
- *
- * RETURN: Function status.
- *
- * DESCRIPTION: Set C1 state on IA32 processor (halt)
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_enter_c1(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks)
-{
- u32 timer = 0;
-
-
- if (!pm_timer_ticks) {
- /*
- * Enter C1:
- * ---------
- */
- enable();
- halt();
- *pm_timer_ticks = ACPI_UINT32_MAX;
- }
- else {
- timer = acpi_hw_pmt_ticks ();
-
- /*
- * Enter C1:
- * ---------
- */
- enable ();
- halt ();
-
- /*
- * Compute Time in C1:
- * -------------------
- */
- timer = acpi_hw_pmt_ticks () - timer;
-
- *pm_timer_ticks = timer;
- }
-
- return (AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_enter_c2
- *
- * PARAMETERS: Pblk_address - Address of the processor control block
- * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep
- *
- * RETURN: <none>
- *
- * DESCRIPTION: Set C2 state on IA32 processor
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_enter_c2(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks)
-{
- u32 timer = 0;
-
-
- if (!pblk_address || !pm_timer_ticks) {
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Disable interrupts before all C2/C3 transitions.
- */
- disable ();
-
- timer = acpi_hw_pmt_ticks ();
-
- /*
- * Enter C2:
- * ---------
- * Read from the P_LVL2 (P_BLK+4) register to invoke a C2 transition.
- */
- acpi_os_in8 ((ACPI_IO_ADDRESS) (pblk_address + 4));
-
- /*
- * Perform Dummy Op:
- * -----------------
- * We have to do something useless after reading LVL2 because chipsets
- * cannot guarantee that STPCLK# gets asserted in time to freeze execution.
- */
- acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
-
- /*
- * Compute Time in C2:
- * -------------------
- */
- timer = acpi_hw_pmt_ticks () - timer;
-
- *pm_timer_ticks = timer;
-
- /*
- * Re-enable interrupts after coming out of C2/C3.
- */
- enable ();
-
- return (AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_enter_c3
- *
- * PARAMETERS: Pblk_address - Address of the processor control block
- * Pm_timer_ticks - Number of PM timer ticks elapsed while asleep
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Set C3 state on IA32 processor (UP only, cache coherency via
- * disabling bus mastering)
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_enter_c3(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks)
-{
- u32 timer = 0;
- u32 bus_master_status = 0;
-
-
- if (!pblk_address || !pm_timer_ticks) {
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Check the BM_STS bit, if it is set, do not enter C3
- * but clear the bit (with a write) and exit, telling
- * the calling module that we spent zero time in C3.
- * If bus mastering continues, this action should
- * eventually cause a demotion to C2
- */
- if (1 == (bus_master_status =
- acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS)))
- {
- /*
- * Clear the BM_STS bit by setting it.
- */
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1);
- *pm_timer_ticks = 0;
- return (AE_OK);
- }
-
- /*
- * Disable interrupts before all C2/C3 transitions.
- */
- disable();
-
- /*
- * Disable Bus Mastering:
- * ----------------------
- * Set the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits.
- */
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1);
-
- /*
- * Get the timer base before entering C state
- */
- timer = acpi_hw_pmt_ticks ();
-
- /*
- * Enter C3:
- * ---------
- * Read from the P_LVL3 (P_BLK+5) register to invoke a C3 transition.
- */
- acpi_os_in8 ((ACPI_IO_ADDRESS)(pblk_address + 5));
-
- /*
- * Perform Dummy Op:
- * -----------------
- * We have to do something useless after reading LVL3 because chipsets
- * cannot guarantee that STPCLK# gets asserted in time to freeze execution.
- */
- acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
- /*
- * Immediately compute the time in the C state
- */
- timer = acpi_hw_pmt_ticks() - timer;
-
- /*
- * Re-Enable Bus Mastering:
- * ------------------------
- * Clear the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits.
- */
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0);
-
- /* TBD: [Unhandled]: Support 24-bit timers (this algorithm assumes 32-bit) */
-
- *pm_timer_ticks = timer;
-
- /*
- * Re-enable interrupts after coming out of C2/C3.
- */
- enable();
-
- return (AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_enter_cx
- *
- * PARAMETERS: Processor_handle - handle of the processor
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Invoke the currently active processor Cx handler to put this
- * processor to sleep.
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_enter_cx (
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks)
-{
-
- if (!acpi_hw_cx_handlers[acpi_hw_active_cx_state]) {
- return (AE_SUPPORT);
- }
-
- return (acpi_hw_cx_handlers[acpi_hw_active_cx_state] (pblk_address, pm_timer_ticks));
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_set_cx
- *
- * PARAMETERS: State - value (1-3) of the Cx state to 'make active'
- *
- * RETURN: Function status.
- *
- * DESCRIPTION: Sets the state to use during calls to Acpi_hw_enter_cx().
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_set_cx (
- u32 cx_state)
-{
- /*
- * Supported State?
- * ----------------
- */
- if ((cx_state < 1) || (cx_state > 3)) {
- return (AE_BAD_PARAMETER);
- }
-
- if (!acpi_hw_cx_handlers[cx_state]) {
- return (AE_SUPPORT);
- }
-
- /*
- * New Cx State?
- * -------------
- * We only care when moving from one state to another...
- */
- if (acpi_hw_active_cx_state == cx_state) {
- return (AE_OK);
- }
-
- /*
- * Prepare to Use New State:
- * -------------------------
- * If the new Cx_state is C3, the BM_RLD bit must be set to allow
- * the generation of a bus master requets to cause the processor
- * in the C3 state to transition to the C0 state.
- */
- switch (cx_state)
- {
- case 3:
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1);
- break;
- }
-
- /*
- * Clean up from Old State:
- * ------------------------
- * If the old Cx_state was C3, the BM_RLD bit is reset. When the
- * bit is reset, the generation of a bus master request does not
- * effect any processor in the C3 state.
- */
- switch (acpi_hw_active_cx_state)
- {
- case 3:
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
- break;
- }
-
- /*
- * Enable:
- * -------
- */
- acpi_hw_active_cx_state = cx_state;
-
- return (AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_get_cx_info
- *
- * PARAMETERS: Cx_states - Information (latencies) on all Cx states
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: This function is called both to initialize Cx handling
- * and retrieve the current Cx information (latency values).
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_get_cx_info (
- u32 cx_states[])
-{
- u8 SMP_system = FALSE;
-
-
- if (!cx_states) {
- return(AE_BAD_PARAMETER);
- }
-
- /*
- * TBD: [Unhandled] need to init SMP_system using info from the MAPIC
- * table.
- */
-
- /*
- * Set Defaults:
- * -------------
- * C0 and C1 support is implied (but what about that PROC_C1 register
- * in the FADT?!?!). Set C2/C3 to max. latency (not supported until
- * proven otherwise).
- */
- cx_states[0] = 0;
- cx_states[1] = 0;
- cx_states[2] = MAX_CX_STATE_LATENCY;
- cx_states[3] = MAX_CX_STATE_LATENCY;
-
- /*
- * C2 Supported?
- * -------------
- * We're only supporting C2 when the latency is <= 100 microseconds,
- * and on SMP systems when P_LVL2_UP (which indicates C2 only on UP)
- * is not set.
- */
- if (acpi_gbl_FADT->plvl2_lat <= 100) {
- if (!SMP_system) {
- acpi_hw_cx_handlers[2] = acpi_hw_enter_c2;
- cx_states[2] = acpi_gbl_FADT->plvl2_lat;
- }
-
- else if (!acpi_gbl_FADT->plvl2_up) {
- acpi_hw_cx_handlers[2] = acpi_hw_enter_c2;
- cx_states[2] = acpi_gbl_FADT->plvl2_lat;
- }
- }
-
- /*
- * C3 Supported?
- * -------------
- * We're only supporting C3 on UP systems when the latency is
- * <= 1000 microseconds and that include the ability to disable
- * Bus Mastering while in C3 (ARB_DIS) but allows Bus Mastering
- * requests to wake the system from C3 (BM_RLD). Note his method
- * of maintaining cache coherency (disabling of bus mastering)
- * cannot be used on SMP systems, and flushing caches (e.g. WBINVD)
- * is simply too costly (at this time).
- */
- if (acpi_gbl_FADT->plvl3_lat <= 1000) {
- if (!SMP_system && (acpi_gbl_FADT->Xpm2_cnt_blk.address &&
- acpi_gbl_FADT->pm2_cnt_len))
- {
- acpi_hw_cx_handlers[3] = acpi_hw_enter_c3;
- cx_states[3] = acpi_gbl_FADT->plvl3_lat;
- }
- }
-
- return(AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_get_cx_handler
- *
- * PARAMETERS: State - the Cx state
- * Handler - pointer to location for the returned handler
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: This function is called to get an installed Cx state handler.
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_get_cx_handler (
- u32 cx_state,
- ACPI_C_STATE_HANDLER *handler)
-{
-
- if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) {
- return(AE_BAD_PARAMETER);
- }
-
- *handler = acpi_hw_cx_handlers[cx_state];
-
- return(AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_hw_set_cx_handler
- *
- * PARAMETERS: Cx_state - the Cx state
- * Handler - new Cx state handler
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: This function is called to install a new Cx state handler.
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_hw_set_cx_handler (
- u32 cx_state,
- ACPI_C_STATE_HANDLER handler)
-{
-
- if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) {
- return(AE_BAD_PARAMETER);
- }
-
- acpi_hw_cx_handlers[cx_state] = handler;
-
- return(AE_OK);
-}
-
-
-/**************************************************************************
- *
- * FUNCTION: Acpi_hw_local_pow
- *
- * PARAMETERS: x,y operands
- *
- * RETURN: result
- *
- * DESCRIPTION: Compute x ^ y
- *
- *************************************************************************/
-
-NATIVE_UINT
-acpi_hw_local_pow (
- NATIVE_UINT x,
- NATIVE_UINT y)
-{
- NATIVE_UINT i;
- NATIVE_UINT result = 1;
-
-
- for (i = 0; i < y; i++) {
- result = result * x;
- }
-
- return (result);
-}
-
-
-/**************************************************************************
- *
- * FUNCTION: Acpi_hw_enable_throttling
- *
- * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control)
- * register
- *
- * RETURN: none
- *
- * DESCRIPTION: Enable throttling by setting the THT_EN bit.
- *
- *************************************************************************/
-
-void
-acpi_hw_enable_throttling (
- ACPI_IO_ADDRESS pblk_address)
-{
- u32 pblk_value;
-
-
- pblk_value = acpi_os_in32 (pblk_address);
- pblk_value = pblk_value | BIT_4;
- acpi_os_out32 (pblk_address, pblk_value);
-
- return;
-}
-
-
-/**************************************************************************
- *
- * FUNCTION: Acpi_hw_disable_throttling
- *
- * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control)
- * register
- *
- * RETURN: none
- *
- * DESCRIPTION:Disable throttling by clearing the THT_EN bit
- *
- *************************************************************************/
-
-void
-acpi_hw_disable_throttling (
- ACPI_IO_ADDRESS pblk_address)
-{
- u32 pblk_value;
-
-
- pblk_value = acpi_os_in32 (pblk_address);
- pblk_value = pblk_value & (~(u32)BIT_4);
- acpi_os_out32 (pblk_address, pblk_value);
-
- return;
-}
-
-
-/**************************************************************************
- *
- * FUNCTION: Acpi_hw_get_duty_cycle
- *
- * PARAMETERS: Duty_offset Pcnt register duty cycle field offset
- * Pblk_address Pcnt register address in chipset
- * Num_throttle_states # of CPU throttle states this system
- * supports
- *
- * RETURN: none
- *
- * DESCRIPTION: Get the duty cycle from the chipset
- *
- *************************************************************************/
-
-u32
-acpi_hw_get_duty_cycle (
- u8 duty_offset,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states)
-{
- NATIVE_UINT index;
- u32 duty32_value;
- u32 pcnt_mask_off_duty_field;
-
-
- /*
- * Use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)]
- * and then shift it into the right position
- */
- pcnt_mask_off_duty_field = num_throttle_states - 1;
-
- /*
- * Read in the current value from the port
- */
- duty32_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address);
-
- /*
- * Shift the the value to LSB
- */
- for (index = 0; index < (NATIVE_UINT) duty_offset; index++) {
- duty32_value = duty32_value >> 1;
- }
-
- /*
- * Get the duty field only
- */
- duty32_value = duty32_value & pcnt_mask_off_duty_field;
-
- return ((u32) duty32_value);
-}
-
-
-/**************************************************************************
- *
- * FUNCTION: Acpi_hw_program_duty_cycle
- *
- * PARAMETERS: Duty_offset Pcnt register duty cycle field offset
- * Duty_cycle duty cycle to program into chipset
- * Pblk_address Pcnt register address in chipset
- * Num_throttle_states # of CPU throttle states this system
- * supports
- *
- * RETURN: none
- *
- * DESCRIPTION: Program chipset with specified duty cycle by bit-shifting the
- * duty cycle bits to the appropriate offset, reading the duty
- * cycle register, OR-ing in the duty cycle, and writing it to
- * the Pcnt register.
- *
- *************************************************************************/
-
-void
-acpi_hw_program_duty_cycle (
- u8 duty_offset,
- u32 duty_cycle,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states)
-{
- NATIVE_UINT index;
- u32 duty32_value;
- u32 pcnt_mask_off_duty_field;
- u32 port_value;
-
-
- /*
- * valid Duty_cycle passed
- */
- duty32_value = duty_cycle;
-
- /*
- * use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)]
- * and then shift it into the right position
- */
- pcnt_mask_off_duty_field = num_throttle_states - 1;
-
- /*
- * Shift the mask
- */
- for (index = 0; index < (NATIVE_UINT) duty_offset; index++) {
- pcnt_mask_off_duty_field = pcnt_mask_off_duty_field << 1;
- duty32_value = duty32_value << 1;
- }
-
- /*
- * Read in the current value from the port
- */
- port_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address);
-
- /*
- * Mask off the duty field so we don't OR in junk!
- */
- port_value = port_value & (~pcnt_mask_off_duty_field);
-
- /*
- * OR in the bits we want to write out to the port
- */
- port_value = (port_value | duty32_value) & (~(u32)BIT_4);
-
- /*
- * write it to the port
- */
- acpi_os_out32 ((ACPI_IO_ADDRESS) pblk_address, port_value);
-
- return;
-}
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index b2a621e47523..b7b777df6337 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -1,7 +1,8 @@
+
/******************************************************************************
*
* Module Name: hwgpe - Low level GPE enable/disable/clear functions
- * $Revision: 27 $
+ * $Revision: 28 $
*
*****************************************************************************/
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index cbb98ec78364..fc96c51fbe8a 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -3,7 +3,7 @@
*
* Module Name: hwregs - Read/write access functions for the various ACPI
* control and status registers.
- * $Revision: 87 $
+ * $Revision: 88 $
*
******************************************************************************/
@@ -37,7 +37,7 @@
/* This matches the #defines in actypes.h. */
NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
- "\\_S4_","\\_S4_b","\\_S5_"};
+ "\\_S4_","\\_S5_","\\_S4_b"};
/*******************************************************************************
@@ -53,7 +53,7 @@ NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","
*
******************************************************************************/
-static u32
+u32
acpi_hw_get_bit_shift (
u32 mask)
{
@@ -581,13 +581,8 @@ acpi_hw_register_read (
case PM1_CONTROL: /* 16-bit access */
- if (register_id != SLP_TYPE_B) {
- value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
- }
-
- if (register_id != SLP_TYPE_A) {
- value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
- }
+ value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
+ value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
break;
@@ -696,30 +691,20 @@ acpi_hw_register_write (
case PM1_CONTROL: /* 16-bit access */
- /*
- * If SLP_TYP_A or SLP_TYP_B, only write to one reg block.
- * Otherwise, write to both.
- */
- if (register_id == SLP_TYPE_A) {
- acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
- }
- else if (register_id == SLP_TYPE_B) {
- acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
- }
- else {
- /* disable/re-enable interrupts if sleeping */
- if (register_id == SLP_EN) {
- disable();
- }
+ acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
+ acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
+ break;
- acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
- acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
- if (register_id == SLP_EN) {
- enable();
- }
- }
+ case PM1_a_CONTROL: /* 16-bit access */
+
+ acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
+ break;
+
+
+ case PM1_b_CONTROL: /* 16-bit access */
+ acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
break;
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
new file mode 100644
index 000000000000..892c721c6a0d
--- /dev/null
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -0,0 +1,189 @@
+
+/******************************************************************************
+ *
+ * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
+ * $Revision: 5 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "acpi.h"
+#include "acnamesp.h"
+#include "achware.h"
+
+#define _COMPONENT HARDWARE
+ MODULE_NAME ("hwsleep")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_set_firmware_waking_vector
+ *
+ * PARAMETERS: Physical_address - Physical address of ACPI real mode
+ * entry point.
+ *
+ * RETURN: AE_OK or AE_ERROR
+ *
+ * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_set_firmware_waking_vector (
+ ACPI_PHYSICAL_ADDRESS physical_address)
+{
+
+
+ /* Make sure that we have an FACS */
+
+ if (!acpi_gbl_FACS) {
+ return (AE_NO_ACPI_TABLES);
+ }
+
+ /* Set the vector */
+
+ if (acpi_gbl_FACS->vector_width == 32) {
+ * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address;
+ }
+ else {
+ *acpi_gbl_FACS->firmware_waking_vector = physical_address;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_get_firmware_waking_vector
+ *
+ * PARAMETERS: *Physical_address - Output buffer where contents of
+ * the Firmware_waking_vector field of
+ * the FACS will be stored.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_firmware_waking_vector (
+ ACPI_PHYSICAL_ADDRESS *physical_address)
+{
+
+
+ if (!physical_address) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Make sure that we have an FACS */
+
+ if (!acpi_gbl_FACS) {
+ return (AE_NO_ACPI_TABLES);
+ }
+
+ /* Get the vector */
+
+ if (acpi_gbl_FACS->vector_width == 32) {
+ *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector;
+ }
+ else {
+ *physical_address = *acpi_gbl_FACS->firmware_waking_vector;
+ }
+
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_enter_sleep_state
+ *
+ * PARAMETERS: Sleep_state - Which sleep state to enter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_enter_sleep_state (
+ u8 sleep_state)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT_LIST arg_list;
+ ACPI_OBJECT arg;
+ u8 type_a;
+ u8 type_b;
+ u16 PM1_acontrol;
+ u16 PM1_bcontrol;
+
+ /*
+ * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
+ */
+
+ status = acpi_hw_obtain_sleep_type_register_data(sleep_state, &type_a, &type_b);
+
+ if (!ACPI_SUCCESS(status)) {
+ return status;
+ }
+
+ /* run the _PTS and _GTS methods */
+ MEMSET(&arg_list, 0, sizeof(arg_list));
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+
+ MEMSET(&arg, 0, sizeof(arg));
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = sleep_state;
+
+ acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
+ acpi_evaluate_object(NULL, "\\_GTS", &arg_list, NULL);
+
+ /* clear wake status */
+ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1);
+
+ PM1_acontrol = (u16) acpi_hw_register_read(ACPI_MTX_LOCK, PM1_CONTROL);
+
+ /* mask off SLP_EN and SLP_TYP fields */
+ PM1_acontrol &= 0xC3FF;
+
+ /* mask in SLP_EN */
+ PM1_acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));
+
+ PM1_bcontrol = PM1_acontrol;
+
+ /* mask in SLP_TYP */
+ PM1_acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));
+ PM1_bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));
+
+ /* the old version was disabling interrupts. let's try it without
+ * and see how that works
+ */
+ /*disable();*/
+
+ acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol);
+ acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol);
+
+ /*enable();*/
+
+ return (AE_OK);
+}
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
new file mode 100644
index 000000000000..b7f529ccf67c
--- /dev/null
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -0,0 +1,196 @@
+
+/******************************************************************************
+ *
+ * Name: hwtimer.c - ACPI Power Management Timer Interface
+ * $Revision: 4 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "acpi.h"
+#include "achware.h"
+
+#define _COMPONENT HARDWARE
+ MODULE_NAME ("hwtimer")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_get_timer_resolution
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: Number of bits of resolution in the PM Timer (24 or 32).
+ *
+ * DESCRIPTION: Obtains resolution of the ACPI PM Timer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_timer_resolution (
+ u32 *resolution)
+{
+ if (!resolution) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ if (0 == acpi_gbl_FADT->tmr_val_ext) {
+ *resolution = 24;
+ }
+ else {
+ *resolution = 32;
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_get_timer
+ *
+ * PARAMETERS: none
+ *
+ * RETURN: Current value of the ACPI PM Timer (in ticks).
+ *
+ * DESCRIPTION: Obtains current value of ACPI PM Timer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_timer (
+ u32 *ticks)
+{
+ if (!ticks) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ *ticks = acpi_os_in32 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address));
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_get_timer_duration
+ *
+ * PARAMETERS: Start_ticks
+ * End_ticks
+ * Time_elapsed
+ *
+ * RETURN: Time_elapsed
+ *
+ * DESCRIPTION: Computes the time elapsed (in microseconds) between two
+ * PM Timer time stamps, taking into account the possibility of
+ * rollovers, the timer resolution, and timer frequency.
+ *
+ * The PM Timer's clock ticks at roughly 3.6 times per
+ * _microsecond_, and its clock continues through Cx state
+ * transitions (unlike many CPU timestamp counters) -- making it
+ * a versatile and accurate timer.
+ *
+ * Note that this function accomodates only a single timer
+ * rollover. Thus for 24-bit timers, this function should only
+ * be used for calculating durations less than ~4.6 seconds
+ * (~20 hours for 32-bit timers).
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_get_timer_duration (
+ u32 start_ticks,
+ u32 end_ticks,
+ u32 *time_elapsed)
+{
+ u32 delta_ticks = 0;
+ u32 seconds = 0;
+ u32 milliseconds = 0;
+ u32 microseconds = 0;
+ u32 remainder = 0;
+
+ if (!time_elapsed) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Compute Tick Delta:
+ * -------------------
+ * Handle timer rollovers on 24- versus 32-bit timers.
+ */
+ if (start_ticks < end_ticks) {
+ delta_ticks = end_ticks - start_ticks;
+ }
+ else if (start_ticks > end_ticks) {
+ /* 24-bit Timer */
+ if (0 == acpi_gbl_FADT->tmr_val_ext) {
+ delta_ticks = (0x00FFFFFF - start_ticks) + end_ticks;
+ }
+ /* 32-bit Timer */
+ else {
+ delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
+ }
+ }
+
+ /*
+ * Compute Duration:
+ * -----------------
+ * Since certain compilers (gcc/Linux, argh!) don't support 64-bit
+ * divides in kernel-space we have to do some trickery to preserve
+ * accuracy while using 32-bit math.
+ *
+ * TODO: Change to use 64-bit math when supported.
+ *
+ * The process is as follows:
+ * 1. Compute the number of seconds by dividing Delta Ticks by
+ * the timer frequency.
+ * 2. Compute the number of milliseconds in the remainder from step #1
+ * by multiplying by 1000 and then dividing by the timer frequency.
+ * 3. Compute the number of microseconds in the remainder from step #2
+ * by multiplying by 1000 and then dividing by the timer frequency.
+ * 4. Add the results from steps 1, 2, and 3 to get the total duration.
+ *
+ * Example: The time elapsed for Delta_ticks = 0xFFFFFFFF should be
+ * 1199864031 microseconds. This is computed as follows:
+ * Step #1: Seconds = 1199; Remainder = 3092840
+ * Step #2: Milliseconds = 864; Remainder = 113120
+ * Step #3: Microseconds = 31; Remainder = <don't care!>
+ */
+
+ /* Step #1 */
+ seconds = delta_ticks / PM_TIMER_FREQUENCY;
+ remainder = delta_ticks % PM_TIMER_FREQUENCY;
+
+ /* Step #2 */
+ milliseconds = (remainder * 1000) / PM_TIMER_FREQUENCY;
+ remainder = (remainder * 1000) % PM_TIMER_FREQUENCY;
+
+ /* Step #3 */
+ microseconds = (remainder * 1000) / PM_TIMER_FREQUENCY;
+
+ /* Step #4 */
+ *time_elapsed = seconds * 1000000;
+ *time_elapsed += milliseconds * 1000;
+ *time_elapsed += microseconds;
+
+ return (AE_OK);
+}
+
+
diff --git a/drivers/acpi/hardware/hwxface.c b/drivers/acpi/hardware/hwxface.c
deleted file mode 100644
index 35194cae38c6..000000000000
--- a/drivers/acpi/hardware/hwxface.c
+++ /dev/null
@@ -1,595 +0,0 @@
-
-/******************************************************************************
- *
- * Name: hwxface.c - Hardware access external interfaces
- * $Revision: 38 $
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000, 2001 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "acpi.h"
-#include "acnamesp.h"
-#include "achware.h"
-
-#define _COMPONENT HARDWARE
- MODULE_NAME ("hwxface")
-
-
-/******************************************************************************
- *
- * Hardware globals
- *
- ******************************************************************************/
-
-
-ACPI_C_STATE_HANDLER acpi_hw_cx_handlers[MAX_CX_STATES] =
- {NULL, acpi_hw_enter_c1, NULL, NULL};
-
-u32 acpi_hw_active_cx_state = 1;
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_get_processor_throttling_info
- *
- * PARAMETERS: Processor_handle - handle for the cpu to get info about
- * User_buffer - caller supplied buffer
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Get throttling capabilities for the processor, this routine
- * builds the data directly into the callers buffer
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_get_processor_throttling_info (
- ACPI_HANDLE processor_handle,
- ACPI_BUFFER *user_buffer)
-{
- NATIVE_UINT percent_step;
- NATIVE_UINT next_percent;
- NATIVE_UINT num_throttle_states;
- NATIVE_UINT buffer_space_needed;
- NATIVE_UINT i;
- u8 duty_width;
- ACPI_NAMESPACE_NODE *cpu_node;
- ACPI_OPERAND_OBJECT *cpu_obj;
- ACPI_CPU_THROTTLING_STATE *state_ptr;
-
-
- /*
- * Have to at least have a buffer to return info in
- */
- if (!user_buffer) {
- return(AE_BAD_PARAMETER);
- }
-
- /*
- * Convert and validate the device handle
- */
-
- cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_node) {
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Check for an existing internal object
- */
-
- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
- if (!cpu_obj) {
- return (AE_NOT_FOUND);
- }
-
- /*
- * (Duty Width on IA-64 is zero)
- */
- duty_width = acpi_gbl_FADT->duty_width;
-
- /*
- * P0 must always have a P_BLK all others may be null
- * in either case, we can't throttle a processor that has no P_BLK
- *
- * Also if no Duty width, one state and it is 100%
- *
- */
- if (!cpu_obj->processor.length || !duty_width ||
- (ACPI_UINT16_MAX < cpu_obj->processor.address))
- {
- /*
- * Acpi_even though we can't throttle, we still have one state (100%)
- */
- num_throttle_states = 1;
- }
-
- else {
- num_throttle_states = (int) acpi_hw_local_pow (2,duty_width);
- }
-
- buffer_space_needed = num_throttle_states * sizeof (ACPI_CPU_THROTTLING_STATE);
-
- if ((user_buffer->length < buffer_space_needed) || !user_buffer->pointer) {
- user_buffer->length = buffer_space_needed;
- return (AE_BUFFER_OVERFLOW);
- }
-
- user_buffer->length = buffer_space_needed;
- state_ptr = (ACPI_CPU_THROTTLING_STATE *) user_buffer->pointer;
- percent_step = 1000 / num_throttle_states;
-
- /*
- * Build each entry in the buffer. Note that we're using the value
- * 1000 and dividing each state by 10 to better avoid round-off
- * accumulation. Also note that the throttling STATES are ordered
- * sequentially from 100% (state 0) on down (e.g. 87.5% = state 1),
- * which is exactly opposite from duty cycle values (12.5% = state 1).
- */
- for (i = 0, next_percent = 1000; i < num_throttle_states; i++) {
- state_ptr[i].state_number = i;
- state_ptr[i].percent_of_clock = next_percent / 10;
- next_percent -= percent_step;
- }
-
- return(AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_get_processor_throttling_state
- *
- * PARAMETERS: Processor_handle - handle for the cpu to throttle
- * Throttle_state - throttling state to enter
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Get current hardware throttling state
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_get_processor_throttling_state (
- ACPI_HANDLE processor_handle,
- u32 *throttle_state)
-{
- ACPI_NAMESPACE_NODE *cpu_node;
- ACPI_OPERAND_OBJECT *cpu_obj;
- u32 num_throttle_states;
- u32 duty_cycle;
- u8 duty_offset;
- u8 duty_width;
-
-
- /* Convert and validate the device handle */
-
- cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_node || !throttle_state) {
- return (AE_BAD_PARAMETER);
- }
-
- /* Check for an existing internal object */
-
- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
- if (!cpu_obj) {
- return (AE_NOT_FOUND);
- }
-
- /*
- * No Duty fields in IA64 tables
- */
- duty_offset = acpi_gbl_FADT->duty_offset;
- duty_width = acpi_gbl_FADT->duty_width;
-
- /*
- * Must have a valid P_BLK P0 must have a P_BLK all others may be null
- * in either case, we can't thottle a processor that has no P_BLK
- * that means we are in the only supported state (0 - 100%)
- *
- * also, if Duty_width is zero there are no additional states
- */
- if (!cpu_obj->processor.length || !duty_width ||
- (ACPI_UINT16_MAX < cpu_obj->processor.address))
- {
- *throttle_state = 0;
- return(AE_OK);
- }
-
- num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width);
-
- /*
- * Get the current duty cycle value.
- */
- duty_cycle = acpi_hw_get_duty_cycle (duty_offset,
- cpu_obj->processor.address,
- num_throttle_states);
-
- /*
- * Convert duty cycle to throttling state (invert).
- */
- if (duty_cycle == 0) {
- *throttle_state = 0;
- }
-
- else {
- *throttle_state = num_throttle_states - duty_cycle;
- }
-
- return(AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_set_processor_throttling_state
- *
- * PARAMETERS: Processor_handle - handle for the cpu to throttle
- * Throttle_state - throttling state to enter
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Set hardware into requested throttling state, the handle
- * passed in must have a valid P_BLK
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_set_processor_throttling_state (
- ACPI_HANDLE processor_handle,
- u32 throttle_state)
-{
- ACPI_NAMESPACE_NODE *cpu_node;
- ACPI_OPERAND_OBJECT *cpu_obj;
- u32 num_throttle_states = 0;
- u8 duty_offset;
- u8 duty_width;
- u32 duty_cycle = 0;
-
-
- /* Convert and validate the device handle */
-
- cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_node) {
- return (AE_BAD_PARAMETER);
- }
-
- /* Check for an existing internal object */
-
- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
- if (!cpu_obj) {
- return (AE_NOT_FOUND);
- }
-
- /*
- * No Duty fields in IA64 tables
- */
- duty_offset = acpi_gbl_FADT->duty_offset;
- duty_width = acpi_gbl_FADT->duty_width;
-
- /*
- * Must have a valid P_BLK P0 must have a P_BLK all others may be null
- * in either case, we can't thottle a processor that has no P_BLK
- * that means we are in the only supported state (0 - 100%)
- *
- * also, if Duty_width is zero there are no additional states
- */
- if (!cpu_obj->processor.length || !duty_width ||
- (ACPI_UINT16_MAX < cpu_obj->processor.address))
- {
- /*
- * If caller wants to set the state to the only state we handle
- * we're done.
- */
- if (throttle_state == 0) {
- return (AE_OK);
- }
-
- /*
- * Can't set this state
- */
- return (AE_SUPPORT);
- }
-
- num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width);
-
- /*
- * Convert throttling state to duty cycle (invert).
- */
- if (throttle_state > 0) {
- duty_cycle = num_throttle_states - throttle_state;
- }
-
- /*
- * Turn off throttling (don't muck with the h/w while throttling).
- */
- acpi_hw_disable_throttling (cpu_obj->processor.address);
-
- /*
- * Program the throttling state.
- */
- acpi_hw_program_duty_cycle (duty_offset, duty_cycle,
- cpu_obj->processor.address, num_throttle_states);
-
- /*
- * Only enable throttling for non-zero states (0 - 100%)
- */
- if (throttle_state) {
- acpi_hw_enable_throttling (cpu_obj->processor.address);
- }
-
- return(AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_get_processor_cx_info
- *
- * PARAMETERS: Processor_handle - handle for the cpu return info about
- * User_buffer - caller supplied buffer
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Get Cx state latencies, this routine
- * builds the data directly into the callers buffer
- *
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_get_processor_cx_info (
- ACPI_HANDLE processor_handle,
- ACPI_BUFFER *user_buffer)
-{
- ACPI_STATUS status = AE_OK;
- u32 cx_state_latencies[4] = {0, 0, 0, 0};
- NATIVE_UINT buffer_space_needed = 0;
- ACPI_CX_STATE *state_ptr = NULL;
- NATIVE_UINT i = 0;
-
-
- /*
- * Have to at least have a buffer to return info in
- */
- if (!user_buffer) {
- return (AE_BAD_PARAMETER);
- }
-
- status = acpi_hw_get_cx_info (cx_state_latencies);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- buffer_space_needed = 4 * sizeof (ACPI_CX_STATE);
-
- if ((user_buffer->length < buffer_space_needed) || !user_buffer->pointer) {
- user_buffer->length = buffer_space_needed;
- return (AE_BUFFER_OVERFLOW);
- }
-
- user_buffer->length = buffer_space_needed;
-
- state_ptr = (ACPI_CX_STATE *) user_buffer->pointer;
-
- for (i = 0; i < 4; i++) {
- state_ptr[i].state_number = i;
- state_ptr[i].latency = cx_state_latencies[i];
- }
-
- return (AE_OK);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_set_processor_sleep_state
- *
- * PARAMETERS: Processor_handle - handle for the cpu return info about
- * Cx_state - the Cx sleeping state (C1-C3) to make
- * 'active'
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Sets which Cx state will be used during calls to
- * Acpi_processor_sleep ()
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_set_processor_sleep_state (
- ACPI_HANDLE processor_handle,
- u32 cx_state)
-{
- ACPI_STATUS status;
-
-
- status = acpi_hw_set_cx (cx_state);
-
- return (status);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_processor_sleep
- *
- * PARAMETERS: Processor_handle - handle for the cpu to put to sleep (Cx)
- * Time_sleeping - time (in microseconds) elapsed while
- * sleeping
- *
- * RETURN: Status of function
- *
- * DESCRIPTION: Puts the processor into the currently active sleep state (Cx)
- *
- ****************************************************************************/
-
-ACPI_STATUS
-acpi_processor_sleep (
- ACPI_HANDLE processor_handle,
- u32 *pm_timer_ticks)
-{
- ACPI_NAMESPACE_NODE *cpu_node = NULL;
- ACPI_OPERAND_OBJECT *cpu_obj = NULL;
- ACPI_IO_ADDRESS address = 0;
-
-
- /*
- * Convert Processor_handle to Pblk_addres...
- */
-
- /* Convert and validate the device handle */
-
- cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_node) {
- return (AE_BAD_PARAMETER);
- }
-
- /* Check for an existing internal object */
-
- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
- if (!cpu_obj) {
- return (AE_NOT_FOUND);
- }
-
- /* Get the processor register block (P_BLK) address */
-
- address = cpu_obj->processor.address;
- if (!cpu_obj->processor.length) {
- /* Ensure a NULL addresss (note that P_BLK isn't required for C1) */
-
- address = 0;
- }
-
- /*
- * Enter the currently active Cx sleep state.
- */
- return (acpi_hw_enter_cx (address, pm_timer_ticks));
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: Acpi_get_timer
- *
- * PARAMETERS: none
- *
- * RETURN: Current value of the ACPI PMT (timer)
- *
- * DESCRIPTION: Obtains current value of ACPI PMT
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_get_timer (
- u32 *out_ticks)
-{
-
- if (!out_ticks) {
- return (AE_BAD_PARAMETER);
- }
-
- *out_ticks = acpi_hw_pmt_ticks ();
-
- return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: Acpi_set_firmware_waking_vector
- *
- * PARAMETERS: Physical_address - Physical address of ACPI real mode
- * entry point.
- *
- * RETURN: AE_OK or AE_ERROR
- *
- * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_set_firmware_waking_vector (
- ACPI_PHYSICAL_ADDRESS physical_address)
-{
-
-
- /* Make sure that we have an FACS */
-
- if (!acpi_gbl_FACS) {
- return (AE_NO_ACPI_TABLES);
- }
-
- /* Set the vector */
-
- if (acpi_gbl_FACS->vector_width == 32) {
- * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address;
- }
- else {
- *acpi_gbl_FACS->firmware_waking_vector = physical_address;
- }
-
- return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: Acpi_get_firmware_waking_vector
- *
- * PARAMETERS: *Physical_address - Output buffer where contents of
- * the Firmware_waking_vector field of
- * the FACS will be stored.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Access function for d_firmware_waking_vector field in FACS
- *
- ******************************************************************************/
-
-ACPI_STATUS
-acpi_get_firmware_waking_vector (
- ACPI_PHYSICAL_ADDRESS *physical_address)
-{
-
-
- if (!physical_address) {
- return (AE_BAD_PARAMETER);
- }
-
- /* Make sure that we have an FACS */
-
- if (!acpi_gbl_FACS) {
- return (AE_NO_ACPI_TABLES);
- }
-
- /* Get the vector */
-
- if (acpi_gbl_FACS->vector_width == 32) {
- *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector;
- }
- else {
- *physical_address = *acpi_gbl_FACS->firmware_waking_vector;
- }
-
- return (AE_OK);
-}
-
-
diff --git a/drivers/acpi/include/accommon.h b/drivers/acpi/include/accommon.h
index b657b6d9eee6..61d54a220dcc 100644
--- a/drivers/acpi/include/accommon.h
+++ b/drivers/acpi/include/accommon.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: accommon.h -- prototypes for the common (subsystem-wide) procedures
- * $Revision: 86 $
+ * $Revision: 87 $
*
*****************************************************************************/
diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h
index d5ab95dfb600..ea9be649d745 100644
--- a/drivers/acpi/include/acconfig.h
+++ b/drivers/acpi/include/acconfig.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acconfig.h - Global configuration constants
- * $Revision: 51 $
+ * $Revision: 53 $
*
*****************************************************************************/
@@ -53,7 +53,7 @@
/* Version string */
-#define ACPI_CA_VERSION __DATE__
+#define ACPI_CA_VERSION 0x20010125
/* Maximum objects in the various object caches */
diff --git a/drivers/acpi/include/achware.h b/drivers/acpi/include/achware.h
index 24b767cc939d..efb97bd2fdb8 100644
--- a/drivers/acpi/include/achware.h
+++ b/drivers/acpi/include/achware.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: achware.h -- hardware specific interfaces
- * $Revision: 50 $
+ * $Revision: 53 $
*
*****************************************************************************/
@@ -27,6 +27,10 @@
#define __ACHWARE_H__
+/* PM Timer ticks per second (HZ) */
+#define PM_TIMER_FREQUENCY 3579545
+
+
/* Prototypes */
@@ -92,6 +96,10 @@ void
acpi_hw_clear_acpi_status (
void);
+u32
+acpi_hw_get_bit_shift (
+ u32 mask);
+
/* GPE support */
@@ -121,89 +129,21 @@ acpi_hw_obtain_sleep_type_register_data (
u8 *slp_typ_b);
-/* Cx State Prototypes */
-
-ACPI_STATUS
-acpi_hw_enter_c1(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_c2(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_c3(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_cx (
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_set_cx (
- u32 cx_state);
-
-ACPI_STATUS
-acpi_hw_get_cx_info (
- u32 cx_states[]);
+/* ACPI Timer prototypes */
ACPI_STATUS
-acpi_hw_get_cx_handler (
- u32 cx_state,
- ACPI_C_STATE_HANDLER *handler);
+acpi_get_timer_resolution (
+ u32 *resolution);
ACPI_STATUS
-acpi_hw_set_cx_handler (
- u32 cx_state,
- ACPI_C_STATE_HANDLER handler);
-
-
-/* Throttling Prototypes */
-
-void
-acpi_hw_enable_throttling (
- ACPI_IO_ADDRESS pblk_address);
-
-void
-acpi_hw_disable_throttling (
- ACPI_IO_ADDRESS pblk_address);
-
-u32
-acpi_hw_get_duty_cycle (
- u8 duty_offset,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states);
-
-void
-acpi_hw_program_duty_cycle (
- u8 duty_offset,
- u32 duty_cycle,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states);
-
-NATIVE_UINT
-acpi_hw_local_pow (
- NATIVE_UINT x,
- NATIVE_UINT y);
-
-
-/* ACPI Timer prototypes */
-
-u32
-acpi_hw_pmt_ticks (
- void);
-
-u32
-acpi_hw_pmt_resolution (
- void);
+acpi_get_timer (
+ u32 *ticks);
ACPI_STATUS
-acpi_get_timer (
- u32 *out_ticks);
+acpi_get_timer_duration (
+ u32 start_ticks,
+ u32 end_ticks,
+ u32 *time_elapsed);
#endif /* __ACHWARE_H__ */
diff --git a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h
index ffeb5682f96e..6eb571e5fae0 100644
--- a/drivers/acpi/include/acinterp.h
+++ b/drivers/acpi/include/acinterp.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acinterp.h - Interpreter subcomponent prototypes and defines
- * $Revision: 89 $
+ * $Revision: 91 $
*
*****************************************************************************/
@@ -88,6 +88,12 @@ acpi_aml_convert_to_string (
ACPI_OPERAND_OBJECT **obj_desc,
ACPI_WALK_STATE *walk_state);
+ACPI_STATUS
+acpi_aml_convert_to_target_type (
+ OBJECT_TYPE_INTERNAL destination_type,
+ ACPI_OPERAND_OBJECT **obj_desc,
+ ACPI_WALK_STATE *walk_state);
+
/*
* amfield - ACPI AML (p-code) execution - field manipulation
@@ -438,17 +444,75 @@ acpi_aml_exec_store (
ACPI_WALK_STATE *walk_state);
ACPI_STATUS
-acpi_aml_store_object_to_object (
+acpi_aml_store_object_to_index (
ACPI_OPERAND_OBJECT *val_desc,
ACPI_OPERAND_OBJECT *dest_desc,
ACPI_WALK_STATE *walk_state);
ACPI_STATUS
acpi_aml_store_object_to_node (
- ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *source_desc,
ACPI_NAMESPACE_NODE *node,
ACPI_WALK_STATE *walk_state);
+ACPI_STATUS
+acpi_aml_store_object_to_object (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,
+ ACPI_WALK_STATE *walk_state);
+
+
+/*
+ *
+ */
+
+ACPI_STATUS
+acpi_aml_resolve_object (
+ ACPI_OPERAND_OBJECT **source_desc_ptr,
+ OBJECT_TYPE_INTERNAL target_type,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_aml_store_object (
+ ACPI_OPERAND_OBJECT *source_desc,
+ OBJECT_TYPE_INTERNAL target_type,
+ ACPI_OPERAND_OBJECT **target_desc_ptr,
+ ACPI_WALK_STATE *walk_state);
+
+
+/*
+ * amcopy - object copy
+ */
+
+ACPI_STATUS
+acpi_aml_copy_buffer_to_buffer (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc);
+
+ACPI_STATUS
+acpi_aml_copy_string_to_string (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc);
+
+ACPI_STATUS
+acpi_aml_copy_integer_to_index_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc);
+
+ACPI_STATUS
+acpi_aml_copy_integer_to_bank_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc);
+
+ACPI_STATUS
+acpi_aml_copy_data_to_named_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_NAMESPACE_NODE *node);
+
+ACPI_STATUS
+acpi_aml_copy_integer_to_field_unit (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc);
/*
* amutils - interpreter/scanner utilities
diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h
index 99da2a422741..2d931387ed90 100644
--- a/drivers/acpi/include/aclocal.h
+++ b/drivers/acpi/include/aclocal.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: aclocal.h - Internal data types used across the ACPI subsystem
- * $Revision: 97 $
+ * $Revision: 100 $
*
*****************************************************************************/
@@ -74,7 +74,7 @@ typedef u32 ACPI_MUTEX_HANDLE;
#define NUM_MTX MAX_MTX+1
-#ifdef ACPI_DEBUG
+#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER)
#ifdef DEFINE_ACPI_GLOBALS
/* Names for the mutexes used in the subsystem */
@@ -593,6 +593,7 @@ typedef struct acpi_walk_state
ACPI_GENERIC_STATE *scope_info; /* Stack of nested scopes */
ACPI_PARSE_STATE *parser_state; /* Current state of parser */
u8 *aml_last_while;
+ ACPI_OPCODE_INFO *op_info; /* Info on current opcode */
ACPI_PARSE_DOWNWARDS descending_callback;
ACPI_PARSE_UPWARDS ascending_callback;
@@ -607,6 +608,7 @@ typedef struct acpi_walk_state
u32 parse_flags;
u8 walk_type;
u8 return_used;
+ u16 opcode; /* Current AML opcode */
u32 prev_arg_types;
/* Debug support */
@@ -730,14 +732,16 @@ typedef struct acpi_get_devices_info
#define PM1_STS 0x0100
#define PM1_EN 0x0200
#define PM1_CONTROL 0x0300
-#define PM2_CONTROL 0x0400
-#define PM_TIMER 0x0500
-#define PROCESSOR_BLOCK 0x0600
-#define GPE0_STS_BLOCK 0x0700
-#define GPE0_EN_BLOCK 0x0800
-#define GPE1_STS_BLOCK 0x0900
-#define GPE1_EN_BLOCK 0x0A00
-#define SMI_CMD_BLOCK 0x0B00
+#define PM1_a_CONTROL 0x0400
+#define PM1_b_CONTROL 0x0500
+#define PM2_CONTROL 0x0600
+#define PM_TIMER 0x0700
+#define PROCESSOR_BLOCK 0x0800
+#define GPE0_STS_BLOCK 0x0900
+#define GPE0_EN_BLOCK 0x0A00
+#define GPE1_STS_BLOCK 0x0B00
+#define GPE1_EN_BLOCK 0x0C00
+#define SMI_CMD_BLOCK 0x0D00
/*
* Address space bitmasks for mmio or io spaces
diff --git a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h
index 8e79f788cc96..5c20943cba89 100644
--- a/drivers/acpi/include/acoutput.h
+++ b/drivers/acpi/include/acoutput.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acoutput.h -- debug output
- * $Revision: 68 $
+ * $Revision: 69 $
*
*****************************************************************************/
@@ -58,6 +58,7 @@
#define BATTERY 0x00040000
#define DEBUGGER 0x00100000
+#define COMPILER 0x00200000
#define ALL_COMPONENTS 0x001FFFFF
#define COMPONENT_DEFAULT (ALL_COMPONENTS)
diff --git a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h
index c2b3ed79edcf..ee289f33e9b9 100644
--- a/drivers/acpi/include/acpiosxf.h
+++ b/drivers/acpi/include/acpiosxf.h
@@ -121,6 +121,10 @@ acpi_os_unmap_memory (
void *logical_address,
u32 length);
+ACPI_STATUS
+acpi_os_get_physical_address (
+ void *logical_address,
+ ACPI_PHYSICAL_ADDRESS *physical_address);
/*
* Interrupt handlers
diff --git a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h
index 76c7fe26b800..8d293818f908 100644
--- a/drivers/acpi/include/acpixf.h
+++ b/drivers/acpi/include/acpixf.h
@@ -285,6 +285,10 @@ acpi_get_firmware_waking_vector (
ACPI_PHYSICAL_ADDRESS *physical_address);
ACPI_STATUS
+acpi_enter_sleep_state (
+ u8 sleep_state);
+
+ACPI_STATUS
acpi_get_processor_throttling_info (
ACPI_HANDLE processor_handle,
ACPI_BUFFER *user_buffer);
diff --git a/drivers/acpi/include/actbl2.h b/drivers/acpi/include/actbl2.h
index d36555b3f759..0a05efa1caf2 100644
--- a/drivers/acpi/include/actbl2.h
+++ b/drivers/acpi/include/actbl2.h
@@ -142,8 +142,8 @@ typedef struct
u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */
u16 flush_size; /* number of flush strides that need to be read */
u16 flush_stride; /* Processor's memory cache line width, in bytes */
- u8 duty_offset; /* Processor’s duty cycle index in processor's P_CNT reg*/
- u8 duty_width; /* Processor’s duty cycle value bit width in P_CNT register.*/
+ u8 duty_offset; /* Processor_’s duty cycle index in processor's P_CNT reg*/
+ u8 duty_width; /* Processor_’s duty cycle value bit width in P_CNT register.*/
u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */
u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */
u8 century; /* index to century in RTC CMOS RAM */
diff --git a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h
index 06cc0f33124a..826fc89018ad 100644
--- a/drivers/acpi/include/actypes.h
+++ b/drivers/acpi/include/actypes.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: actypes.h - Common data types for the entire ACPI subsystem
- * $Revision: 162 $
+ * $Revision: 163 $
*
*****************************************************************************/
@@ -249,8 +249,9 @@ typedef UINT64 ACPI_INTEGER;
#define ACPI_STATE_S2 (u8) 2
#define ACPI_STATE_S3 (u8) 3
#define ACPI_STATE_S4 (u8) 4
-#define ACPI_STATE_S4_bIOS (u8) 5
-#define ACPI_STATE_S5 (u8) 6
+#define ACPI_STATE_S5 (u8) 5
+/* let's pretend S4_bIOS didn't exist for now. ASG */
+#define ACPI_STATE_S4_bIOS (u8) 6
#define ACPI_S_STATES_MAX ACPI_STATE_S5
diff --git a/drivers/acpi/interpreter/amconvrt.c b/drivers/acpi/interpreter/amconvrt.c
index 3519553e8615..4c895c7eded0 100644
--- a/drivers/acpi/interpreter/amconvrt.c
+++ b/drivers/acpi/interpreter/amconvrt.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: amconvrt - Object conversion routines
- * $Revision: 2 $
+ * $Revision: 3 $
*
*****************************************************************************/
@@ -39,6 +39,121 @@
/*******************************************************************************
*
+ * FUNCTION: Acpi_aml_convert_to_target_type
+ *
+ * PARAMETERS: *Obj_desc - Object to be converted.
+ * Walk_state - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_convert_to_target_type (
+ OBJECT_TYPE_INTERNAL destination_type,
+ ACPI_OPERAND_OBJECT **obj_desc,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_STATUS status = AE_OK;
+
+
+ /*
+ * If required by the target,
+ * perform implicit conversion on the source before we store it.
+ */
+
+ switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args))
+ {
+ case ARGI_SIMPLE_TARGET:
+ case ARGI_FIXED_TARGET:
+ case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
+
+ switch (destination_type)
+ {
+ case INTERNAL_TYPE_DEF_FIELD:
+ /*
+ * Named field can always handle conversions
+ */
+ break;
+
+ default:
+ /* No conversion allowed for these types */
+
+ if (destination_type != (*obj_desc)->common.type) {
+ status = AE_TYPE;
+ }
+ }
+ break;
+
+
+ case ARGI_TARGETREF:
+
+ switch (destination_type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_FIELD_UNIT:
+ case INTERNAL_TYPE_BANK_FIELD:
+ case INTERNAL_TYPE_INDEX_FIELD:
+ /*
+ * These types require an Integer operand. We can convert
+ * a Buffer or a String to an Integer if necessary.
+ */
+ status = acpi_aml_convert_to_integer (obj_desc, walk_state);
+ break;
+
+
+ case ACPI_TYPE_STRING:
+
+ /*
+ * The operand must be a String. We can convert an
+ * Integer or Buffer if necessary
+ */
+ status = acpi_aml_convert_to_string (obj_desc, walk_state);
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ /*
+ * The operand must be a String. We can convert an
+ * Integer or Buffer if necessary
+ */
+ status = acpi_aml_convert_to_buffer (obj_desc, walk_state);
+ break;
+ }
+ break;
+
+
+ case ARGI_REFERENCE:
+ /*
+ * Create_xxxx_field cases - we are storing the field object into the name
+ */
+ break;
+
+
+ default:
+ status = AE_AML_INTERNAL;
+ }
+
+
+ /*
+ * Source-to-Target conversion semantics:
+ *
+ * If conversion to the target type cannot be performed, then simply
+ * overwrite the target with the new object and type.
+ */
+ if (status == AE_TYPE) {
+ status = AE_OK;
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: Acpi_aml_convert_to_integer
*
* PARAMETERS: *Obj_desc - Object to be converted. Must be an
@@ -159,7 +274,11 @@ acpi_aml_convert_to_integer (
/* Save the Result, delete original descriptor, store new descriptor */
ret_desc->integer.value = result;
- acpi_cm_remove_reference (*obj_desc);
+
+ if (walk_state->opcode != AML_STORE_OP) {
+ acpi_cm_remove_reference (*obj_desc);
+ }
+
*obj_desc = ret_desc;
return (AE_OK);
@@ -234,7 +353,9 @@ acpi_aml_convert_to_buffer (
/* Return the new buffer descriptor */
- acpi_cm_remove_reference (*obj_desc);
+ if (walk_state->opcode != AML_STORE_OP) {
+ acpi_cm_remove_reference (*obj_desc);
+ }
*obj_desc = ret_desc;
break;
@@ -330,7 +451,9 @@ acpi_aml_convert_to_string (
/* Return the new buffer descriptor */
- acpi_cm_remove_reference (*obj_desc);
+ if (walk_state->opcode != AML_STORE_OP) {
+ acpi_cm_remove_reference (*obj_desc);
+ }
*obj_desc = ret_desc;
return (AE_OK);
@@ -380,7 +503,9 @@ acpi_aml_convert_to_string (
/* Return the new buffer descriptor */
- acpi_cm_remove_reference (*obj_desc);
+ if (walk_state->opcode != AML_STORE_OP) {
+ acpi_cm_remove_reference (*obj_desc);
+ }
*obj_desc = ret_desc;
break;
diff --git a/drivers/acpi/interpreter/amfield.c b/drivers/acpi/interpreter/amfield.c
index b722d8107204..3ed442c95f7d 100644
--- a/drivers/acpi/interpreter/amfield.c
+++ b/drivers/acpi/interpreter/amfield.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: amfield - ACPI AML (p-code) execution - field manipulation
- * $Revision: 76 $
+ * $Revision: 77 $
*
*****************************************************************************/
@@ -174,7 +174,8 @@ acpi_aml_access_named_field (
u32 byte_field_length;
- /* Basic data checking */
+ /* Parameter validation */
+
if ((!named_field) || (ACPI_READ == mode && !buffer)) {
return (AE_AML_INTERNAL);
}
@@ -227,7 +228,7 @@ acpi_aml_access_named_field (
/* TBD: should these round down to a power of 2? */
- if (DIV_8(bit_granularity) > byte_field_length) {
+ if (DIV_8 (bit_granularity) > byte_field_length) {
bit_granularity = MUL_8(byte_field_length);
}
diff --git a/drivers/acpi/interpreter/amfldio.c b/drivers/acpi/interpreter/amfldio.c
index 535be8c45fb6..d16cd3d9b51d 100644
--- a/drivers/acpi/interpreter/amfldio.c
+++ b/drivers/acpi/interpreter/amfldio.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: amfldio - Aml Field I/O
- * $Revision: 35 $
+ * $Revision: 37 $
*
*****************************************************************************/
@@ -405,8 +405,6 @@ acpi_aml_write_field_data_with_update_rule (
merged_value = field_value;
- /* Check if update rule needs to be applied (not if mask is all ones) */
-
/* Decode the update rule */
@@ -415,13 +413,17 @@ acpi_aml_write_field_data_with_update_rule (
case UPDATE_PRESERVE:
- /*
- * Read the current contents of the byte/word/dword containing
- * the field, and merge with the new field value.
- */
- status = acpi_aml_read_field_data (obj_desc, this_field_byte_offset,
- bit_granularity, &current_value);
- merged_value |= (current_value & ~mask);
+ /* Check if update rule needs to be applied (not if mask is all ones) */
+
+ if (((1 << bit_granularity) -1) & ~mask) {
+ /*
+ * Read the current contents of the byte/word/dword containing
+ * the field, and merge with the new field value.
+ */
+ status = acpi_aml_read_field_data (obj_desc, this_field_byte_offset,
+ bit_granularity, &current_value);
+ merged_value |= (current_value & ~mask);
+ }
break;
diff --git a/drivers/acpi/interpreter/amresolv.c b/drivers/acpi/interpreter/amresolv.c
index c63424e10003..c08a4731cb01 100644
--- a/drivers/acpi/interpreter/amresolv.c
+++ b/drivers/acpi/interpreter/amresolv.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: amresolv - AML Interpreter object resolution
- * $Revision: 80 $
+ * $Revision: 81 $
*
*****************************************************************************/
@@ -150,7 +150,7 @@ acpi_aml_get_field_unit_value (
*
* RETURN: Status
*
- * DESCRIPTION: Convert Reference entries on Obj_stack to Rvalues
+ * DESCRIPTION: Convert Reference objects to values
*
******************************************************************************/
diff --git a/drivers/acpi/interpreter/amstore.c b/drivers/acpi/interpreter/amstore.c
index 9c780e9ac570..9f350bb29d24 100644
--- a/drivers/acpi/interpreter/amstore.c
+++ b/drivers/acpi/interpreter/amstore.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: amstore - AML Interpreter object store support
- * $Revision: 119 $
+ * $Revision: 121 $
*
*****************************************************************************/
@@ -64,12 +64,7 @@ acpi_aml_exec_store (
ACPI_WALK_STATE *walk_state)
{
ACPI_STATUS status = AE_OK;
- ACPI_OPERAND_OBJECT *delete_dest_desc = NULL;
- ACPI_OPERAND_OBJECT *tmp_desc;
- ACPI_NAMESPACE_NODE *node = NULL;
- u8 value = 0;
- u32 length;
- u32 i;
+ ACPI_OPERAND_OBJECT *ref_desc = dest_desc;
/* Validate parameters */
@@ -78,27 +73,23 @@ acpi_aml_exec_store (
return (AE_AML_NO_OPERAND);
}
- /* Examine the datatype of the Dest_desc */
+ /* Dest_desc can be either a namespace node or an ACPI object */
if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) {
- /* Dest is an ACPI_HANDLE, create a new object */
-
- node = (ACPI_NAMESPACE_NODE *) dest_desc;
- dest_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
- if (!dest_desc) {
- /* Allocation failure */
-
- return (AE_NO_MEMORY);
- }
+ /*
+ * Dest is a namespace node,
+ * Storing an object into a Name "container"
+ */
+ status = acpi_aml_store_object_to_node (val_desc,
+ (ACPI_NAMESPACE_NODE *) dest_desc, walk_state);
- /* Build a new Reference wrapper around the handle */
+ /* All done, that's it */
- dest_desc->reference.op_code = AML_NAME_OP;
- dest_desc->reference.object = node;
+ return (status);
}
- /* Destination object must be of type Reference */
+ /* Destination object must be an object of type Reference */
if (dest_desc->common.type != INTERNAL_TYPE_REFERENCE) {
/* Destination is not an Reference */
@@ -106,36 +97,130 @@ acpi_aml_exec_store (
return (AE_AML_OPERAND_TYPE);
}
- /* Examine the Reference opcode */
- switch (dest_desc->reference.op_code)
+ /*
+ * Examine the Reference opcode. These cases are handled:
+ *
+ * 1) Store to Name (Change the object associated with a name)
+ * 2) Store to an indexed area of a Buffer or Package
+ * 3) Store to a Method Local or Arg
+ * 4) Store to the debug object
+ * 5) Store to a constant -- a noop
+ */
+
+ switch (ref_desc->reference.op_code)
{
case AML_NAME_OP:
- /*
- * Storing into a Name
- */
- delete_dest_desc = dest_desc;
- status = acpi_aml_store_object_to_node (val_desc, dest_desc->reference.object,
- walk_state);
+ /* Storing an object into a Name "container" */
- break; /* Case Name_op */
+ status = acpi_aml_store_object_to_node (val_desc, ref_desc->reference.object,
+ walk_state);
+ break;
case AML_INDEX_OP:
- delete_dest_desc = dest_desc;
+ /* Storing to an Index (pointer into a packager or buffer) */
+
+ status = acpi_aml_store_object_to_index (val_desc, ref_desc, walk_state);
+ break;
+
+
+ case AML_LOCAL_OP:
+
+ status = acpi_ds_method_data_set_value (MTH_TYPE_LOCAL,
+ (ref_desc->reference.offset), val_desc, walk_state);
+ break;
+
+
+ case AML_ARG_OP:
+
+ status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
+ (ref_desc->reference.offset), val_desc, walk_state);
+ break;
+
+
+ case AML_DEBUG_OP:
/*
- * Valid source value and destination reference pointer.
+ * Storing to the Debug object causes the value stored to be
+ * displayed and otherwise has no effect -- see ACPI Specification
*
- * ACPI Specification 1.0B section 15.2.3.4.2.13:
- * Destination should point to either a buffer or a package
+ * TBD: print known object types "prettier".
*/
+ break;
+
+
+ case AML_ZERO_OP:
+ case AML_ONE_OP:
+ case AML_ONES_OP:
+
/*
- * Actually, storing to a package is not so simple. The source must be
+ * Storing to a constant is a no-op -- see ACPI Specification
+ * Delete the reference descriptor, however
+ */
+ break;
+
+
+ default:
+
+ /* TBD: [Restructure] use object dump routine !! */
+
+ status = AE_AML_INTERNAL;
+ break;
+
+ } /* switch (Ref_desc->Reference.Op_code) */
+
+
+ /* Always delete the reference descriptor object */
+
+ if (ref_desc) {
+ acpi_cm_remove_reference (ref_desc);
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_store_object_to_index
+ *
+ * PARAMETERS: *Val_desc - Value to be stored
+ * *Node - Named object to recieve the value
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_store_object_to_index (
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_STATUS status = AE_OK;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ u32 length;
+ u32 i;
+ u8 value = 0;
+
+
+ /*
+ * Destination must be a reference pointer, and
+ * must point to either a buffer or a package
+ */
+
+ switch (dest_desc->reference.target_type)
+ {
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * Storing to a package element is not simple. The source must be
* evaluated and converted to the type of the destination and then the
* source is copied into the destination - we can't just point to the
* source object.
@@ -145,8 +230,8 @@ acpi_aml_exec_store (
* The object at *(Dest_desc->Reference.Where) is the
* element within the package that is to be modified.
*/
- tmp_desc = *(dest_desc->reference.where);
- if (tmp_desc) {
+ obj_desc = *(dest_desc->reference.where);
+ if (obj_desc) {
/*
* If the Destination element is a package, we will delete
* that object and construct a new one.
@@ -155,41 +240,39 @@ acpi_aml_exec_store (
* to be packages?
* && (Val_desc->Common.Type == ACPI_TYPE_PACKAGE)
*/
- if (tmp_desc->common.type == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/*
* Take away the reference for being part of a package and
* delete
*/
- acpi_cm_remove_reference (tmp_desc);
- acpi_cm_remove_reference (tmp_desc);
+ acpi_cm_remove_reference (obj_desc);
+ acpi_cm_remove_reference (obj_desc);
- tmp_desc = NULL;
+ obj_desc = NULL;
}
}
- if (!tmp_desc) {
+ if (!obj_desc) {
/*
- * If the Tmp_desc is NULL, that means an uninitialized package
- * has been used as a destination, therefore, we must create
- * the destination element to match the type of the source
- * element NOTE: Val_desc can be of any type.
+ * If the Obj_desc is NULL, it means that an uninitialized package
+ * element has been used as a destination (this is OK), therefore,
+ * we must create the destination element to match the type of the
+ * source element NOTE: Val_desc can be of any type.
*/
- tmp_desc = acpi_cm_create_internal_object (val_desc->common.type);
- if (!tmp_desc) {
- status = AE_NO_MEMORY;
- goto cleanup;
+ obj_desc = acpi_cm_create_internal_object (val_desc->common.type);
+ if (!obj_desc) {
+ return (AE_NO_MEMORY);
}
/*
* If the source is a package, copy the source to the new dest
*/
- if (ACPI_TYPE_PACKAGE == tmp_desc->common.type) {
+ if (ACPI_TYPE_PACKAGE == obj_desc->common.type) {
status = acpi_aml_build_copy_internal_package_object (
- val_desc, tmp_desc, walk_state);
+ val_desc, obj_desc, walk_state);
if (ACPI_FAILURE (status)) {
- acpi_cm_remove_reference (tmp_desc);
- tmp_desc = NULL;
- goto cleanup;
+ acpi_cm_remove_reference (obj_desc);
+ return (status);
}
}
@@ -199,38 +282,31 @@ acpi_aml_exec_store (
* part of the parent package
*/
- *(dest_desc->reference.where) = tmp_desc;
- acpi_cm_add_reference (tmp_desc);
+ *(dest_desc->reference.where) = obj_desc;
+ acpi_cm_add_reference (obj_desc);
}
- if (ACPI_TYPE_PACKAGE != tmp_desc->common.type) {
+ if (ACPI_TYPE_PACKAGE != obj_desc->common.type) {
/*
* The destination element is not a package, so we need to
* convert the contents of the source (Val_desc) and copy into
- * the destination (Tmp_desc)
+ * the destination (Obj_desc)
*/
- status = acpi_aml_store_object_to_object (val_desc, tmp_desc,
+ status = acpi_aml_store_object_to_object (val_desc, obj_desc,
walk_state);
if (ACPI_FAILURE (status)) {
/*
* An error occurrered when copying the internal object
* so delete the reference.
*/
- status = AE_AML_OPERAND_TYPE;
+ return (AE_AML_OPERAND_TYPE);
}
}
-
- break;
}
+ break;
- /*
- * Check that the destination is a Buffer Field type
- */
- if (dest_desc->reference.target_type != ACPI_TYPE_BUFFER_FIELD) {
- status = AE_AML_OPERAND_TYPE;
- break;
- }
+ case ACPI_TYPE_BUFFER_FIELD:
/*
* Storing into a buffer at a location defined by an Index.
*
@@ -239,13 +315,11 @@ acpi_aml_exec_store (
*/
/*
- * Set the Tmp_desc to the destination object and type check.
+ * Set the Obj_desc to the destination object and type check.
*/
- tmp_desc = dest_desc->reference.object;
-
- if (tmp_desc->common.type != ACPI_TYPE_BUFFER) {
- status = AE_AML_OPERAND_TYPE;
- break;
+ obj_desc = dest_desc->reference.object;
+ if (obj_desc->common.type != ACPI_TYPE_BUFFER) {
+ return (AE_AML_OPERAND_TYPE);
}
/*
@@ -256,15 +330,15 @@ acpi_aml_exec_store (
switch (val_desc->common.type)
{
/*
- * If the type is Integer, the Length is 4.
+ * If the type is Integer, assign bytewise
* This loop to assign each of the elements is somewhat
- * backward because of the Big Endian-ness of IA-64
+ * backward because of the Big Endian-ness of IA-64
*/
case ACPI_TYPE_INTEGER:
- length = 4;
+ length = sizeof (ACPI_INTEGER);
for (i = length; i != 0; i--) {
value = (u8)(val_desc->integer.value >> (MUL_8 (i - 1)));
- tmp_desc->buffer.pointer[dest_desc->reference.offset] = value;
+ obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
}
break;
@@ -276,7 +350,7 @@ acpi_aml_exec_store (
length = val_desc->buffer.length;
for (i = 0; i < length; i++) {
value = *(val_desc->buffer.pointer + i);
- tmp_desc->buffer.pointer[dest_desc->reference.offset] = value;
+ obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
}
break;
@@ -288,7 +362,7 @@ acpi_aml_exec_store (
length = val_desc->string.length;
for (i = 0; i < length; i++) {
value = *(val_desc->string.pointer + i);
- tmp_desc->buffer.pointer[dest_desc->reference.offset] = value;
+ obj_desc->buffer.pointer[dest_desc->reference.offset] = value;
}
break;
@@ -299,80 +373,207 @@ acpi_aml_exec_store (
status = AE_AML_OPERAND_TYPE;
break;
}
+ break;
- /*
- * If we had an error, break out of this case statement.
- */
- if (ACPI_FAILURE (status)) {
- break;
- }
-
- /*
- * Set the return pointer
- */
- dest_desc = tmp_desc;
+ default:
+ status = AE_AML_OPERAND_TYPE;
break;
+ }
- case AML_ZERO_OP:
- case AML_ONE_OP:
- case AML_ONES_OP:
- /*
- * Storing to a constant is a no-op -- see ACPI Specification
- * Delete the result descriptor.
- */
+ return (status);
+}
- delete_dest_desc = dest_desc;
- break;
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_store_object_to_node
+ *
+ * PARAMETERS: *Source_desc - Value to be stored
+ * *Node - Named object to recieve the value
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ * The Assignment of an object to a named object is handled here
+ * The val passed in will replace the current value (if any)
+ * with the input value.
+ *
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation.
+ *
+ * NOTE: the global lock is acquired early. This will result
+ * in the global lock being held a bit longer. Also, if the
+ * function fails during set up we may get the lock when we
+ * don't really need it. I don't think we care.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_store_object_to_node (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_STATUS status = AE_OK;
+ ACPI_OPERAND_OBJECT *target_desc;
+ OBJECT_TYPE_INTERNAL target_type = ACPI_TYPE_ANY;
- case AML_LOCAL_OP:
+ /*
+ * Assuming the parameters were already validated
+ */
+ ACPI_ASSERT((node) && (source_desc));
- status = acpi_ds_method_data_set_value (MTH_TYPE_LOCAL,
- (dest_desc->reference.offset), val_desc, walk_state);
- delete_dest_desc = dest_desc;
- break;
+ /*
+ * Get current type of the node, and object attached to Node
+ */
+ target_type = acpi_ns_get_type (node);
+ target_desc = acpi_ns_get_attached_object (node);
- case AML_ARG_OP:
- status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
- (dest_desc->reference.offset), val_desc, walk_state);
- delete_dest_desc = dest_desc;
+ /*
+ * Resolve the source object to an actual value
+ * (If it is a reference object)
+ */
+ status = acpi_aml_resolve_object (&source_desc, target_type, walk_state);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+
+ /*
+ * Do the actual store operation
+ */
+ switch (target_type)
+ {
+ case INTERNAL_TYPE_DEF_FIELD:
+
+ /* Raw data copy for target types Integer/String/Buffer */
+
+ status = acpi_aml_copy_data_to_named_field (source_desc, node);
break;
- case AML_DEBUG_OP:
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ case INTERNAL_TYPE_BANK_FIELD:
+ case INTERNAL_TYPE_INDEX_FIELD:
+ case ACPI_TYPE_FIELD_UNIT:
/*
- * Storing to the Debug object causes the value stored to be
- * displayed and otherwise has no effect -- see ACPI Specification
+ * These target types are all of type Integer/String/Buffer, and
+ * therefore support implicit conversion before the store.
+ *
+ * Copy and/or convert the source object to a new target object
*/
+ status = acpi_aml_store_object (source_desc, target_type, &target_desc, walk_state);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
- delete_dest_desc = dest_desc;
+ /*
+ * Store the new Target_desc as the new value of the Name, and set
+ * the Name's type to that of the value being stored in it.
+ * Source_desc reference count is incremented by Attach_object.
+ */
+ status = acpi_ns_attach_object (node, target_desc, target_type);
break;
default:
- /* TBD: [Restructure] use object dump routine !! */
+ /* No conversions for all other types. Just attach the source object */
- delete_dest_desc = dest_desc;
- status = AE_AML_INTERNAL;
+ status = acpi_ns_attach_object (node, source_desc, source_desc->common.type);
- } /* switch(Dest_desc->Reference.Op_code) */
+ break;
+ }
-cleanup:
+ return (status);
+}
- /* Cleanup and exit*/
- if (delete_dest_desc) {
- acpi_cm_remove_reference (delete_dest_desc);
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_store_object_to_object
+ *
+ * PARAMETERS: *Source_desc - Value to be stored
+ * *Dest_desc - Object to receive the value
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store an object to another object.
+ *
+ * The Assignment of an object to another (not named) object
+ * is handled here.
+ * The val passed in will replace the current value (if any)
+ * with the input value.
+ *
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation.
+ *
+ * This module allows destination types of Number, String,
+ * and Buffer.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_store_object_to_object (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_STATUS status = AE_OK;
+ OBJECT_TYPE_INTERNAL destination_type = dest_desc->common.type;
+
+
+ /*
+ * Assuming the parameters are valid!
+ */
+ ACPI_ASSERT((dest_desc) && (source_desc));
+
+
+ /*
+ * From this interface, we only support Integers/Strings/Buffers
+ */
+ switch (destination_type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ break;
+
+ default:
+ return (AE_NOT_IMPLEMENTED);
}
+
+ /*
+ * Resolve the source object to an actual value
+ * (If it is a reference object)
+ */
+ status = acpi_aml_resolve_object (&source_desc, destination_type, walk_state);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+
+ /*
+ * Copy and/or convert the source object to the destination object
+ */
+ status = acpi_aml_store_object (source_desc, destination_type, &dest_desc, walk_state);
+
+
return (status);
}
-
diff --git a/drivers/acpi/interpreter/amstoren.c b/drivers/acpi/interpreter/amstoren.c
index 6e3d0c7e0282..eb62ed2f1b1a 100644
--- a/drivers/acpi/interpreter/amstoren.c
+++ b/drivers/acpi/interpreter/amstoren.c
@@ -2,8 +2,8 @@
/******************************************************************************
*
* Module Name: amstoren - AML Interpreter object store support,
- * Store to Node (namespace object)
- * $Revision: 26 $
+ * Store to Node (namespace object)
+ * $Revision: 28 $
*
*****************************************************************************/
@@ -41,127 +41,72 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_aml_store_object_to_node
+ * FUNCTION: Acpi_aml_resolve_object
*
- * PARAMETERS: *Val_desc - Value to be stored
- * *Node - Named object to recieve the value
+ * PARAMETERS: Source_desc_ptr - Pointer to the source object
+ * Target_type - Current type of the target
+ * Walk_state - Current walk state
*
- * RETURN: Status
- *
- * DESCRIPTION: Store the object to the named object.
- *
- * The Assignment of an object to a named object is handled here
- * The val passed in will replace the current value (if any)
- * with the input value.
+ * RETURN: Status, resolved object in Source_desc_ptr.
*
- * When storing into an object the data is converted to the
- * target object type then stored in the object. This means
- * that the target object type (for an initialized target) will
- * not be changed by a store operation.
- *
- * NOTE: the global lock is acquired early. This will result
- * in the global lock being held a bit longer. Also, if the
- * function fails during set up we may get the lock when we
- * don't really need it. I don't think we care.
+ * DESCRIPTION: Resolve an object. If the object is a reference, dereference
+ * it and return the actual object in the Source_desc_ptr.
*
******************************************************************************/
ACPI_STATUS
-acpi_aml_store_object_to_node (
- ACPI_OPERAND_OBJECT *val_desc,
- ACPI_NAMESPACE_NODE *node,
+acpi_aml_resolve_object (
+ ACPI_OPERAND_OBJECT **source_desc_ptr,
+ OBJECT_TYPE_INTERNAL target_type,
ACPI_WALK_STATE *walk_state)
{
+ ACPI_OPERAND_OBJECT *source_desc = *source_desc_ptr;
ACPI_STATUS status = AE_OK;
- u8 *buffer = NULL;
- u32 length = 0;
- u32 mask;
- u32 new_value;
- u8 locked = FALSE;
- u8 *location=NULL;
- ACPI_OPERAND_OBJECT *dest_desc;
- OBJECT_TYPE_INTERNAL destination_type = ACPI_TYPE_ANY;
/*
- * Assuming the parameters are valid!!!
+ * Ensure we have a Source that can be stored in the target
*/
- ACPI_ASSERT((node) && (val_desc));
+ switch (target_type)
+ {
- destination_type = acpi_ns_get_type (node);
+ /* This case handles the "interchangeable" types Integer, String, and Buffer. */
/*
- * First ensure we have a value that can be stored in the target
+ * These cases all require only Integers or values that
+ * can be converted to Integers (Strings or Buffers)
*/
- switch (destination_type)
- {
- /* Type of Name's existing value */
-
- case INTERNAL_TYPE_ALIAS:
-
- /*
- * Aliases are resolved by Acpi_aml_prep_operands
- */
-
- status = AE_AML_INTERNAL;
- break;
-
-
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_FIELD_UNIT:
case INTERNAL_TYPE_BANK_FIELD:
case INTERNAL_TYPE_INDEX_FIELD:
- case ACPI_TYPE_FIELD_UNIT:
- case ACPI_TYPE_INTEGER:
-
- /*
- * These cases all require only number values or values that
- * can be converted to numbers.
- *
- * If value is not a Number, try to resolve it to one.
- */
-
- if (val_desc->common.type != ACPI_TYPE_INTEGER) {
- /*
- * Initially not a number, convert
- */
- status = acpi_aml_resolve_to_value (&val_desc, walk_state);
- if (ACPI_SUCCESS (status) &&
- (val_desc->common.type != ACPI_TYPE_INTEGER))
- {
- /*
- * Conversion successful but still not a number
- */
- status = AE_AML_OPERAND_TYPE;
- }
- }
-
- break;
+ /*
+ * Stores into a Field/Region or into a Buffer/String
+ * are all essentially the same.
+ */
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
case INTERNAL_TYPE_DEF_FIELD:
/*
- * Storing into a Field in a region or into a buffer or into
- * a string all is essentially the same.
- *
- * If value is not a valid type, try to resolve it to one.
+ * If Source_desc is not a valid type, try to resolve it to one.
*/
-
- if ((val_desc->common.type != ACPI_TYPE_INTEGER) &&
- (val_desc->common.type != ACPI_TYPE_BUFFER) &&
- (val_desc->common.type != ACPI_TYPE_STRING))
+ if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+ (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (source_desc->common.type != ACPI_TYPE_STRING))
{
/*
- * Initially not a valid type, convert
+ * Initially not a valid type, convert
*/
- status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+ status = acpi_aml_resolve_to_value (source_desc_ptr, walk_state);
if (ACPI_SUCCESS (status) &&
- (val_desc->common.type != ACPI_TYPE_INTEGER) &&
- (val_desc->common.type != ACPI_TYPE_BUFFER) &&
- (val_desc->common.type != ACPI_TYPE_STRING))
+ (source_desc->common.type != ACPI_TYPE_INTEGER) &&
+ (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (source_desc->common.type != ACPI_TYPE_STRING))
{
/*
- * Conversion successful but still not a valid type
+ * Conversion successful but still not a valid type
*/
status = AE_AML_OPERAND_TYPE;
}
@@ -169,347 +114,133 @@ acpi_aml_store_object_to_node (
break;
- case ACPI_TYPE_PACKAGE:
+ case INTERNAL_TYPE_ALIAS:
/*
- * TBD: [Unhandled] Not real sure what to do here
+ * Aliases are resolved by Acpi_aml_prep_operands
*/
- status = AE_NOT_IMPLEMENTED;
+ status = AE_AML_INTERNAL;
break;
+ case ACPI_TYPE_PACKAGE:
default:
/*
- * All other types than Alias and the various Fields come here.
- * Store Val_desc as the new value of the Name, and set
- * the Name's type to that of the value being stored in it.
- * Val_desc reference count is incremented by Attach_object.
+ * All other types than Alias and the various Fields come here,
+ * including the untyped case - ACPI_TYPE_ANY.
*/
-
- status = acpi_ns_attach_object (node, val_desc, val_desc->common.type);
-
- goto clean_up_and_bail_out;
break;
}
- /* Exit now if failure above */
+ return (status);
+}
+
- if (ACPI_FAILURE (status)) {
- goto clean_up_and_bail_out;
- }
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_store_object
+ *
+ * PARAMETERS: Source_desc - Object to store
+ * Target_type - Current type of the target
+ * Target_desc_ptr - Pointer to the target
+ * Walk_state - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: "Store" an object to another object. This may include
+ * converting the source type to the target type (implicit
+ * conversion), and a copy of the value of the source to
+ * the target.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_store_object (
+ ACPI_OPERAND_OBJECT *source_desc,
+ OBJECT_TYPE_INTERNAL target_type,
+ ACPI_OPERAND_OBJECT **target_desc_ptr,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_OPERAND_OBJECT *target_desc = *target_desc_ptr;
+ ACPI_STATUS status;
- /*
- * Get descriptor for object attached to Node
- */
- dest_desc = acpi_ns_get_attached_object (node);
- if (!dest_desc) {
- /*
- * There is no existing object attached to this Node
- */
- status = AE_AML_INTERNAL;
- goto clean_up_and_bail_out;
- }
/*
- * Make sure the destination Object is the same as the Node
+ * Perform the "implicit conversion" of the source to the current type
+ * of the target - As per the ACPI specification.
+ *
+ * If no conversion performed, Source_desc is left alone, otherwise it
+ * is updated with a new object.
*/
- if (dest_desc->common.type != (u8) destination_type) {
- status = AE_AML_INTERNAL;
- goto clean_up_and_bail_out;
+ status = acpi_aml_convert_to_target_type (target_type, &source_desc, walk_state);
+ if (ACPI_FAILURE (status)) {
+ return (status);
}
+
/*
- * Acpi_everything is ready to execute now, We have
- * a value we can handle, just perform the update
+ * We now have two objects of identical types, and we can perform a
+ * copy of the *value* of the source object.
*/
-
- switch (destination_type)
+ switch (target_type)
{
- /* Type of Name's existing value */
-
- case INTERNAL_TYPE_BANK_FIELD:
-
- /*
- * Get the global lock if needed
- */
- locked = acpi_aml_acquire_global_lock (dest_desc->bank_field.lock_rule);
+ case ACPI_TYPE_ANY:
+ case INTERNAL_TYPE_DEF_ANY:
/*
- * Set Bank value to select proper Bank
- * Perform the update (Set Bank Select)
+ * The target namespace node is uninitialized (has no target object),
+ * and will take on the type of the source object
*/
- status = acpi_aml_access_named_field (ACPI_WRITE,
- dest_desc->bank_field.bank_select,
- &dest_desc->bank_field.value,
- sizeof (dest_desc->bank_field.value));
- if (ACPI_SUCCESS (status)) {
- /* Set bank select successful, set data value */
-
- status = acpi_aml_access_named_field (ACPI_WRITE,
- dest_desc->bank_field.bank_select,
- &val_desc->bank_field.value,
- sizeof (val_desc->bank_field.value));
- }
-
+ *target_desc_ptr = source_desc;
break;
- case INTERNAL_TYPE_DEF_FIELD:
-
- /*
- * Get the global lock if needed
- */
- locked = acpi_aml_acquire_global_lock (val_desc->field.lock_rule);
-
- /*
- * Perform the update
- */
-
- switch (val_desc->common.type)
- {
- case ACPI_TYPE_INTEGER:
- buffer = (u8 *) &val_desc->integer.value;
- length = sizeof (val_desc->integer.value);
- break;
-
- case ACPI_TYPE_BUFFER:
- buffer = (u8 *) val_desc->buffer.pointer;
- length = val_desc->buffer.length;
- break;
-
- case ACPI_TYPE_STRING:
- buffer = (u8 *) val_desc->string.pointer;
- length = val_desc->string.length;
- break;
- }
-
- status = acpi_aml_access_named_field (ACPI_WRITE,
- node, buffer, length);
-
- break; /* Global Lock released below */
-
-
- case ACPI_TYPE_STRING:
-
- /*
- * Perform the update
- */
-
- switch (val_desc->common.type)
- {
- case ACPI_TYPE_INTEGER:
- buffer = (u8 *) &val_desc->integer.value;
- length = sizeof (val_desc->integer.value);
- break;
-
- case ACPI_TYPE_BUFFER:
- buffer = (u8 *) val_desc->buffer.pointer;
- length = val_desc->buffer.length;
- break;
-
- case ACPI_TYPE_STRING:
- buffer = (u8 *) val_desc->string.pointer;
- length = val_desc->string.length;
- break;
- }
+ case ACPI_TYPE_INTEGER:
- /*
- * Setting a string value replaces the old string
- */
+ target_desc->integer.value = source_desc->integer.value;
- if (length < dest_desc->string.length) {
- /*
- * Zero fill, not willing to do pointer arithmetic for
- * archetecture independance. Just clear the whole thing
- */
- MEMSET(dest_desc->string.pointer, 0, dest_desc->string.length);
- MEMCPY(dest_desc->string.pointer, buffer, length);
- }
- else {
- /*
- * Free the current buffer, then allocate a buffer
- * large enough to hold the value
- */
- if ( dest_desc->string.pointer &&
- !acpi_tb_system_table_pointer (dest_desc->string.pointer))
- {
- /*
- * Only free if not a pointer into the DSDT
- */
+ /* Truncate value if we are executing from a 32-bit ACPI table */
- acpi_cm_free(dest_desc->string.pointer);
- }
+ acpi_aml_truncate_for32bit_table (target_desc, walk_state);
+ break;
- dest_desc->string.pointer = acpi_cm_allocate (length + 1);
- dest_desc->string.length = length;
- if (!dest_desc->string.pointer) {
- status = AE_NO_MEMORY;
- goto clean_up_and_bail_out;
- }
+ case ACPI_TYPE_FIELD_UNIT:
- MEMCPY(dest_desc->string.pointer, buffer, length);
- }
+ status = acpi_aml_copy_integer_to_field_unit (source_desc, target_desc);
break;
- case ACPI_TYPE_BUFFER:
-
- /*
- * Perform the update to the buffer
- */
-
- switch (val_desc->common.type)
- {
- case ACPI_TYPE_INTEGER:
- buffer = (u8 *) &val_desc->integer.value;
- length = sizeof (val_desc->integer.value);
- break;
-
- case ACPI_TYPE_BUFFER:
- buffer = (u8 *) val_desc->buffer.pointer;
- length = val_desc->buffer.length;
- break;
-
- case ACPI_TYPE_STRING:
- buffer = (u8 *) val_desc->string.pointer;
- length = val_desc->string.length;
- break;
- }
+ case INTERNAL_TYPE_BANK_FIELD:
- /*
- * Buffer is a static allocation,
- * only place what will fit in the buffer.
- */
- if (length <= dest_desc->buffer.length) {
- /*
- * Zero fill first, not willing to do pointer arithmetic for
- * archetecture independence. Just clear the whole thing
- */
- MEMSET(dest_desc->buffer.pointer, 0, dest_desc->buffer.length);
- MEMCPY(dest_desc->buffer.pointer, buffer, length);
- }
- else {
- /*
- * truncate, copy only what will fit
- */
- MEMCPY(dest_desc->buffer.pointer, buffer, dest_desc->buffer.length);
- }
+ status = acpi_aml_copy_integer_to_bank_field (source_desc, target_desc);
break;
case INTERNAL_TYPE_INDEX_FIELD:
- /*
- * Get the global lock if needed
- */
- locked = acpi_aml_acquire_global_lock (dest_desc->index_field.lock_rule);
-
- /*
- * Set Index value to select proper Data register
- * perform the update (Set index)
- */
-
- status = acpi_aml_access_named_field (ACPI_WRITE,
- dest_desc->index_field.index,
- &dest_desc->index_field.value,
- sizeof (dest_desc->index_field.value));
-
- if (ACPI_SUCCESS (status)) {
- /* set index successful, next set Data value */
-
- status = acpi_aml_access_named_field (ACPI_WRITE,
- dest_desc->index_field.data,
- &val_desc->integer.value,
- sizeof (val_desc->integer.value));
- }
+ status = acpi_aml_copy_integer_to_index_field (source_desc, target_desc);
break;
- case ACPI_TYPE_FIELD_UNIT:
-
-
- /*
- * If the Field Buffer and Index have not been previously evaluated,
- * evaluate them and save the results.
- */
- if (!(dest_desc->common.flags & AOPOBJ_DATA_VALID)) {
- status = acpi_ds_get_field_unit_arguments (dest_desc);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
- }
-
- if ((!dest_desc->field_unit.container ||
- ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type))
- {
- status = AE_AML_INTERNAL;
- goto clean_up_and_bail_out;
- }
-
- /*
- * Get the global lock if needed
- */
- locked = acpi_aml_acquire_global_lock (dest_desc->field_unit.lock_rule);
-
- /*
- * TBD: [Unhandled] REMOVE this limitation
- * Make sure the operation is within the limits of our implementation
- * this is not a Spec limitation!!
- */
- if (dest_desc->field_unit.length + dest_desc->field_unit.bit_offset > 32) {
- status = AE_NOT_IMPLEMENTED;
- goto clean_up_and_bail_out;
- }
-
- /* Field location is (base of buffer) + (byte offset) */
-
- location = dest_desc->field_unit.container->buffer.pointer
- + dest_desc->field_unit.offset;
-
- /*
- * Construct Mask with 1 bits where the field is,
- * 0 bits elsewhere
- */
- mask = ((u32) 1 << dest_desc->field_unit.length) - ((u32)1
- << dest_desc->field_unit.bit_offset);
-
- /* Zero out the field in the buffer */
-
- MOVE_UNALIGNED32_TO_32 (&new_value, location);
- new_value &= ~mask;
-
- /*
- * Shift and mask the new value into position,
- * and or it into the buffer.
- */
- new_value |= (val_desc->integer.value << dest_desc->field_unit.bit_offset) &
- mask;
-
- /* Store back the value */
-
- MOVE_UNALIGNED32_TO_32 (location, &new_value);
+ case ACPI_TYPE_STRING:
+ status = acpi_aml_copy_string_to_string (source_desc, target_desc);
break;
- case ACPI_TYPE_INTEGER:
-
-
- dest_desc->integer.value = val_desc->integer.value;
-
- /* Truncate value if we are executing from a 32-bit ACPI table */
+ case ACPI_TYPE_BUFFER:
- acpi_aml_truncate_for32bit_table (dest_desc, walk_state);
+ status = acpi_aml_copy_buffer_to_buffer (source_desc, target_desc);
break;
case ACPI_TYPE_PACKAGE:
/*
- * TBD: [Unhandled] Not real sure what to do here
+ * TBD: [Unhandled] Not real sure what to do here
*/
status = AE_NOT_IMPLEMENTED;
break;
@@ -518,24 +249,13 @@ acpi_aml_store_object_to_node (
default:
/*
- * All other types than Alias and the various Fields come here.
- * Store Val_desc as the new value of the Name, and set
- * the Name's type to that of the value being stored in it.
- * Val_desc reference count is incremented by Attach_object.
+ * All other types come here.
*/
-
status = AE_NOT_IMPLEMENTED;
break;
}
-clean_up_and_bail_out:
-
- /*
- * Release global lock if we acquired it earlier
- */
- acpi_aml_release_global_lock (locked);
-
return (status);
}
diff --git a/drivers/acpi/interpreter/amstorob.c b/drivers/acpi/interpreter/amstorob.c
index f4f26d07f10e..8118f08bd5e7 100644
--- a/drivers/acpi/interpreter/amstorob.c
+++ b/drivers/acpi/interpreter/amstorob.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: amstorob - AML Interpreter object store support, store to object
- * $Revision: 20 $
+ * $Revision: 22 $
*
*****************************************************************************/
@@ -40,281 +40,383 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_aml_store_object_to_object
+ * FUNCTION: Acpi_aml_copy_buffer_to_buffer
*
- * PARAMETERS: *Val_desc - Value to be stored
- * *Dest_desc - Object to receive the value
+ * PARAMETERS: Source_desc - Source object to copy
+ * Target_desc - Destination object of the copy
*
* RETURN: Status
*
- * DESCRIPTION: Store an object to another object.
+ * DESCRIPTION: Copy a buffer object to another buffer object.
*
- * The Assignment of an object to another (not named) object
- * is handled here.
- * The val passed in will replace the current value (if any)
- * with the input value.
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_copy_buffer_to_buffer (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc)
+{
+ u32 length;
+ u8 *buffer;
+
+ /*
+ * We know that Source_desc is a buffer by now
+ */
+ buffer = (u8 *) source_desc->buffer.pointer;
+ length = source_desc->buffer.length;
+
+ /*
+ * Buffer is a static allocation,
+ * only place what will fit in the buffer.
+ */
+ if (length <= target_desc->buffer.length) {
+ /* Clear existing buffer and copy in the new one */
+
+ MEMSET(target_desc->buffer.pointer, 0, target_desc->buffer.length);
+ MEMCPY(target_desc->buffer.pointer, buffer, length);
+ }
+
+ else {
+ /*
+ * Truncate the source, copy only what will fit
+ */
+ MEMCPY(target_desc->buffer.pointer, buffer, target_desc->buffer.length);
+
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
*
- * When storing into an object the data is converted to the
- * target object type then stored in the object. This means
- * that the target object type (for an initialized target) will
- * not be changed by a store operation.
+ * FUNCTION: Acpi_aml_copy_string_to_string
+ *
+ * PARAMETERS: Source_desc - Source object to copy
+ * Target_desc - Destination object of the copy
+ *
+ * RETURN: Status
*
- * This module allows destination types of Number, String,
- * and Buffer.
+ * DESCRIPTION: Copy a String object to another String object
*
******************************************************************************/
ACPI_STATUS
-acpi_aml_store_object_to_object (
- ACPI_OPERAND_OBJECT *val_desc,
- ACPI_OPERAND_OBJECT *dest_desc,
- ACPI_WALK_STATE *walk_state)
+acpi_aml_copy_string_to_string (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc)
{
- ACPI_STATUS status = AE_OK;
- u8 *buffer = NULL;
- u32 length = 0;
- OBJECT_TYPE_INTERNAL destination_type = dest_desc->common.type;
+ u32 length;
+ u8 *buffer;
/*
- * Assuming the parameters are valid!!!
+ * We know that Source_desc is a string by now.
*/
- ACPI_ASSERT((dest_desc) && (val_desc));
+ buffer = (u8 *) source_desc->string.pointer;
+ length = source_desc->string.length;
/*
- * First ensure we have a value that can be stored in the target
+ * Setting a string value replaces the old string
*/
- switch (destination_type)
- {
- /* Type of Name's existing value */
+ if (length < target_desc->string.length) {
+ /* Clear old string and copy in the new one */
- case ACPI_TYPE_INTEGER:
+ MEMSET(target_desc->string.pointer, 0, target_desc->string.length);
+ MEMCPY(target_desc->string.pointer, buffer, length);
+ }
+ else {
/*
- * These cases all require only number values or values that
- * can be converted to numbers.
- *
- * If value is not a Number, try to resolve it to one.
+ * Free the current buffer, then allocate a buffer
+ * large enough to hold the value
*/
-
- if (val_desc->common.type != ACPI_TYPE_INTEGER) {
+ if (target_desc->string.pointer &&
+ !acpi_tb_system_table_pointer (target_desc->string.pointer))
+ {
/*
- * Initially not a number, convert
+ * Only free if not a pointer into the DSDT
*/
- status = acpi_aml_resolve_to_value (&val_desc, walk_state);
- if (ACPI_SUCCESS (status) &&
- (val_desc->common.type != ACPI_TYPE_INTEGER))
- {
- /*
- * Conversion successful but still not a number
- */
- status = AE_AML_OPERAND_TYPE;
- }
+ acpi_cm_free(target_desc->string.pointer);
}
- break;
+ target_desc->string.pointer = acpi_cm_allocate (length + 1);
+ target_desc->string.length = length;
- case ACPI_TYPE_STRING:
- case ACPI_TYPE_BUFFER:
+ if (!target_desc->string.pointer) {
+ return (AE_NO_MEMORY);
+ }
- /*
- * Storing into a Field in a region or into a buffer or into
- * a string all is essentially the same.
- *
- * If value is not a valid type, try to resolve it to one.
- */
+ MEMCPY(target_desc->string.pointer, buffer, length);
+ }
- if ((val_desc->common.type != ACPI_TYPE_INTEGER) &&
- (val_desc->common.type != ACPI_TYPE_BUFFER) &&
- (val_desc->common.type != ACPI_TYPE_STRING))
- {
- /*
- * Initially not a valid type, convert
- */
- status = acpi_aml_resolve_to_value (&val_desc, walk_state);
- if (ACPI_SUCCESS (status) &&
- (val_desc->common.type != ACPI_TYPE_INTEGER) &&
- (val_desc->common.type != ACPI_TYPE_BUFFER) &&
- (val_desc->common.type != ACPI_TYPE_STRING))
- {
- /*
- * Conversion successful but still not a valid type
- */
- status = AE_AML_OPERAND_TYPE;
- }
- }
- break;
+ return (AE_OK);
+}
- default:
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_copy_integer_to_index_field
+ *
+ * PARAMETERS: Source_desc - Source object to copy
+ * Target_desc - Destination object of the copy
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write an Integer to an Index Field
+ *
+ ******************************************************************************/
- /*
- * TBD: [Unhandled] What other combinations must be implemented?
- */
- status = AE_NOT_IMPLEMENTED;
- break;
- }
+ACPI_STATUS
+acpi_aml_copy_integer_to_index_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc)
+{
+ ACPI_STATUS status;
+ u8 locked;
+
+
+ /*
+ * Get the global lock if needed
+ */
+ locked = acpi_aml_acquire_global_lock (target_desc->index_field.lock_rule);
- /* Exit now if failure above */
+ /*
+ * Set Index value to select proper Data register
+ * perform the update (Set index)
+ */
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ target_desc->index_field.index,
+ &target_desc->index_field.value,
+ sizeof (target_desc->index_field.value));
+ if (ACPI_SUCCESS (status)) {
+ /* Set_index was successful, next set Data value */
+
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ target_desc->index_field.data,
+ &source_desc->integer.value,
+ sizeof (source_desc->integer.value));
- if (ACPI_FAILURE (status)) {
- goto clean_up_and_bail_out;
}
+
+
/*
- * Acpi_everything is ready to execute now, We have
- * a value we can handle, just perform the update
+ * Release global lock if we acquired it earlier
*/
+ acpi_aml_release_global_lock (locked);
- switch (destination_type)
- {
+ return (status);
+}
- case ACPI_TYPE_STRING:
- /*
- * Perform the update
- */
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_copy_integer_to_bank_field
+ *
+ * PARAMETERS: Source_desc - Source object to copy
+ * Target_desc - Destination object of the copy
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write an Integer to a Bank Field
+ *
+ ******************************************************************************/
- switch (val_desc->common.type)
- {
- case ACPI_TYPE_INTEGER:
- buffer = (u8 *) &val_desc->integer.value;
- length = sizeof (val_desc->integer.value);
- break;
-
- case ACPI_TYPE_BUFFER:
- buffer = (u8 *) val_desc->buffer.pointer;
- length = val_desc->buffer.length;
- break;
-
- case ACPI_TYPE_STRING:
- buffer = (u8 *) val_desc->string.pointer;
- length = val_desc->string.length;
- break;
- }
+ACPI_STATUS
+acpi_aml_copy_integer_to_bank_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc)
+{
+ ACPI_STATUS status;
+ u8 locked;
- /*
- * Setting a string value replaces the old string
- */
- if (length < dest_desc->string.length) {
- /*
- * Zero fill, not willing to do pointer arithmetic for
- * architecture independence. Just clear the whole thing
- */
- MEMSET(dest_desc->string.pointer, 0, dest_desc->string.length);
- MEMCPY(dest_desc->string.pointer, buffer, length);
- }
- else {
- /*
- * Free the current buffer, then allocate a buffer
- * large enough to hold the value
- */
- if ( dest_desc->string.pointer &&
- !acpi_tb_system_table_pointer (dest_desc->string.pointer))
- {
- /*
- * Only free if not a pointer into the DSDT
- */
+ /*
+ * Get the global lock if needed
+ */
+ locked = acpi_aml_acquire_global_lock (target_desc->index_field.lock_rule);
- acpi_cm_free(dest_desc->string.pointer);
- }
- dest_desc->string.pointer = acpi_cm_allocate (length + 1);
- dest_desc->string.length = length;
+ /*
+ * Set Bank value to select proper Bank
+ * Perform the update (Set Bank Select)
+ */
+
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ target_desc->bank_field.bank_select,
+ &target_desc->bank_field.value,
+ sizeof (target_desc->bank_field.value));
+ if (ACPI_SUCCESS (status)) {
+ /* Set bank select successful, set data value */
+
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ target_desc->bank_field.bank_select,
+ &source_desc->bank_field.value,
+ sizeof (source_desc->bank_field.value));
+ }
- if (!dest_desc->string.pointer) {
- status = AE_NO_MEMORY;
- goto clean_up_and_bail_out;
- }
- MEMCPY(dest_desc->string.pointer, buffer, length);
- }
- break;
+ /*
+ * Release global lock if we acquired it earlier
+ */
+ acpi_aml_release_global_lock (locked);
- case ACPI_TYPE_BUFFER:
+ return (status);
+}
- /*
- * Perform the update to the buffer
- */
- switch (val_desc->common.type)
- {
- case ACPI_TYPE_INTEGER:
- buffer = (u8 *) &val_desc->integer.value;
- length = sizeof (val_desc->integer.value);
- break;
-
- case ACPI_TYPE_BUFFER:
- buffer = (u8 *) val_desc->buffer.pointer;
- length = val_desc->buffer.length;
- break;
-
- case ACPI_TYPE_STRING:
- buffer = (u8 *) val_desc->string.pointer;
- length = val_desc->string.length;
- break;
- }
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_copy_data_to_named_field
+ *
+ * PARAMETERS: Source_desc - Source object to copy
+ * Node - Destination Namespace node
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Copy raw data to a Named Field. No implicit conversion
+ * is performed on the source object
+ *
+ ******************************************************************************/
- /*
- * If the buffer is uninitialized,
- * memory needs to be allocated for the copy.
- */
- if(0 == dest_desc->buffer.length) {
- dest_desc->buffer.pointer = acpi_cm_callocate(length);
- dest_desc->buffer.length = length;
-
- if (!dest_desc->buffer.pointer) {
- status = AE_NO_MEMORY;
- goto clean_up_and_bail_out;
- }
- }
+ACPI_STATUS
+acpi_aml_copy_data_to_named_field (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_NAMESPACE_NODE *node)
+{
+ ACPI_STATUS status;
+ u8 locked;
+ u32 length;
+ u8 *buffer;
- /*
- * Buffer is a static allocation,
- * only place what will fit in the buffer.
- */
- if (length <= dest_desc->buffer.length) {
- /*
- * Zero fill first, not willing to do pointer arithmetic for
- * architecture independence. Just clear the whole thing
- */
- MEMSET(dest_desc->buffer.pointer, 0, dest_desc->buffer.length);
- MEMCPY(dest_desc->buffer.pointer, buffer, length);
- }
- else {
- /*
- * truncate, copy only what will fit
- */
- MEMCPY(dest_desc->buffer.pointer, buffer, dest_desc->buffer.length);
- }
- break;
+ /*
+ * Named fields (Create_xxx_field) - We don't perform any conversions on the
+ * source operand, just use the raw data
+ */
+ switch (source_desc->common.type)
+ {
case ACPI_TYPE_INTEGER:
+ buffer = (u8 *) &source_desc->integer.value;
+ length = sizeof (source_desc->integer.value);
+ break;
- dest_desc->integer.value = val_desc->integer.value;
-
- /* Truncate value if we are executing from a 32-bit ACPI table */
+ case ACPI_TYPE_BUFFER:
+ buffer = (u8 *) source_desc->buffer.pointer;
+ length = source_desc->buffer.length;
+ break;
- acpi_aml_truncate_for32bit_table (dest_desc, walk_state);
+ case ACPI_TYPE_STRING:
+ buffer = (u8 *) source_desc->string.pointer;
+ length = source_desc->string.length;
break;
default:
+ return (AE_TYPE);
+ }
- /*
- * All other types than Alias and the various Fields come here.
- * Store Val_desc as the new value of the Name, and set
- * the Name's type to that of the value being stored in it.
- * Val_desc reference count is incremented by Attach_object.
- */
+ /*
+ * Get the global lock if needed before the update
+ * TBD: not needed!
+ */
+ locked = acpi_aml_acquire_global_lock (source_desc->field.lock_rule);
- status = AE_NOT_IMPLEMENTED;
- break;
- }
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ node, buffer, length);
-clean_up_and_bail_out:
+ acpi_aml_release_global_lock (locked);
return (status);
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_aml_copy_integer_to_field_unit
+ *
+ * PARAMETERS: Source_desc - Source object to copy
+ * Target_desc - Destination object of the copy
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write an Integer to a Field Unit.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_copy_integer_to_field_unit (
+ ACPI_OPERAND_OBJECT *source_desc,
+ ACPI_OPERAND_OBJECT *target_desc)
+{
+ ACPI_STATUS status = AE_OK;
+ u8 *location = NULL;
+ u32 mask;
+ u32 new_value;
+ u8 locked = FALSE;
+
+
+ /*
+ * If the Field Buffer and Index have not been previously evaluated,
+ * evaluate them and save the results.
+ */
+ if (!(target_desc->common.flags & AOPOBJ_DATA_VALID)) {
+ status = acpi_ds_get_field_unit_arguments (target_desc);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ }
+
+ if ((!target_desc->field_unit.container ||
+ ACPI_TYPE_BUFFER != target_desc->field_unit.container->common.type))
+ {
+ return (AE_AML_INTERNAL);
+ }
+
+ /*
+ * Get the global lock if needed
+ */
+ locked = acpi_aml_acquire_global_lock (target_desc->field_unit.lock_rule);
+
+ /*
+ * TBD: [Unhandled] REMOVE this limitation
+ * Make sure the operation is within the limits of our implementation
+ * this is not a Spec limitation!!
+ */
+ if (target_desc->field_unit.length + target_desc->field_unit.bit_offset > 32) {
+ return (AE_NOT_IMPLEMENTED);
+ }
+
+ /* Field location is (base of buffer) + (byte offset) */
+
+ location = target_desc->field_unit.container->buffer.pointer
+ + target_desc->field_unit.offset;
+
+ /*
+ * Construct Mask with 1 bits where the field is,
+ * 0 bits elsewhere
+ */
+ mask = ((u32) 1 << target_desc->field_unit.length) - ((u32)1
+ << target_desc->field_unit.bit_offset);
+
+ /* Zero out the field in the buffer */
+
+ MOVE_UNALIGNED32_TO_32 (&new_value, location);
+ new_value &= ~mask;
+
+ /*
+ * Shift and mask the new value into position,
+ * and or it into the buffer.
+ */
+ new_value |= (source_desc->integer.value << target_desc->field_unit.bit_offset) &
+ mask;
+
+ /* Store back the value */
+
+ MOVE_UNALIGNED32_TO_32 (location, &new_value);
+
+ return (AE_OK);
+}
+
+
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 6a9336c7141b..7a29e75426a6 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -1,7 +1,7 @@
/*******************************************************************************
*
* Module Name: nssearch - Namespace search
- * $Revision: 63 $
+ * $Revision: 64 $
*
******************************************************************************/
@@ -70,8 +70,6 @@ acpi_ns_search_node (
ACPI_NAMESPACE_NODE *next_node;
-
-
/*
* Search for name in this table, which is to say that we must search
* for the name among the children of this object
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index f795fbba65ab..11457b33f369 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -2,7 +2,7 @@
*
* Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
* parents and siblings and Scope manipulation
- * $Revision: 76 $
+ * $Revision: 77 $
*
*****************************************************************************/
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index dc6fcaee8964..7373013da9ea 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psparse - Parser top level AML parse routines
- * $Revision: 73 $
+ * $Revision: 74 $
*
*****************************************************************************/
@@ -537,7 +537,9 @@ acpi_ps_parse_loop (
*/
status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE);
- if (ACPI_FAILURE (status)) {
+ if (ACPI_FAILURE (status) &&
+ ((status & AE_CODE_MASK) != AE_CODE_CONTROL))
+ {
return (status);
}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 296ddb1047a1..328c755d9867 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psxface - Parser external interfaces
- * $Revision: 39 $
+ * $Revision: 40 $
*
*****************************************************************************/
@@ -121,6 +121,12 @@ acpi_psx_execute (
return (AE_NO_MEMORY);
}
+
+ /* Init new op with the method name and pointer back to the NS node */
+
+ acpi_ps_set_name (op, method_node->name);
+ op->node = method_node;
+
/*
* The walk of the parse tree is where we actually execute the method
*/
diff --git a/drivers/acpi/sys.c b/drivers/acpi/sys.c
index 09781f97732d..2011174a1ec6 100644
--- a/drivers/acpi/sys.c
+++ b/drivers/acpi/sys.c
@@ -27,18 +27,13 @@
#define _COMPONENT OS_DEPENDENT
MODULE_NAME ("sys")
-#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
-#define ACPI_SLP_TYPA(value) ((value) >> 8)
-#define ACPI_SLP_TYPB(value) ((value) & 0xff)
-
struct acpi_enter_sx_ctx
{
wait_queue_head_t wait;
unsigned int state;
};
-volatile acpi_sstate_t acpi_sleep_state = ACPI_S0;
-static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,};
+volatile acpi_sstate_t acpi_sleep_state = ACPI_STATE_S0;
/*
* Enter system sleep state
@@ -50,44 +45,20 @@ acpi_enter_sx_async(void *context)
ACPI_OBJECT_LIST arg_list;
ACPI_OBJECT arg;
- /*
- * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
- */
-
- // run the _PTS method
- memset(&arg_list, 0, sizeof(arg_list));
- arg_list.count = 1;
- arg_list.pointer = &arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = ACPI_TYPE_INTEGER;
- arg.integer.value = ctx->state;
+ acpi_enter_sleep_state(ctx->state);
- acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
-
- // clear wake status by writing a 1
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1);
-
- acpi_sleep_state = ctx->state;
-
- // set ACPI_SLP_TYPA/b and ACPI_SLP_EN
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_A,
- ACPI_SLP_TYPA(acpi_slptyp[ctx->state]));
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_B,
- ACPI_SLP_TYPB(acpi_slptyp[ctx->state]));
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_EN, 1);
-
- if (ctx->state != ACPI_S1) {
- /* we should have just shut off - what are we doing here? */
- printk(KERN_ERR "ACPI: S%d failed\n", ctx->state);
+ /* either we are in S1, or the transition failed, as the other states resume
+ from the waking vector */
+ if (ctx->state != ACPI_STATE_S1) {
+ printk(KERN_ERR "Could not enter S%d\n", ctx->state);
goto out;
}
- // wait until S1 is entered
+ /* wait until S1 is entered */
while (!(acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, WAK_STS)))
safe_halt();
- // run the _WAK method
+ /* run the _WAK method */
memset(&arg_list, 0, sizeof(arg_list));
arg_list.count = 1;
arg_list.pointer = &arg;
@@ -99,7 +70,7 @@ acpi_enter_sx_async(void *context)
acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
out:
- acpi_sleep_state = ACPI_S0;
+ acpi_sleep_state = ACPI_STATE_S0;
if (waitqueue_active(&ctx->wait))
wake_up_interruptible(&ctx->wait);
@@ -112,13 +83,9 @@ static void
acpi_power_off(void)
{
struct acpi_enter_sx_ctx ctx;
-
- if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0)
- || acpi_slptyp[ACPI_S5] == ACPI_INVALID)
- return;
init_waitqueue_head(&ctx.wait);
- ctx.state = ACPI_S5;
+ ctx.state = ACPI_STATE_S5;
acpi_enter_sx_async(&ctx);
}
@@ -132,10 +99,6 @@ acpi_enter_sx(acpi_sstate_t state)
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
- if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0)
- || acpi_slptyp[state] == ACPI_INVALID)
- return -EINVAL;
-
init_waitqueue_head(&ctx.wait);
ctx.state = state;
@@ -166,19 +129,14 @@ acpi_sys_init(void)
printk(KERN_INFO "ACPI: System firmware supports:");
- for (sx = ACPI_S0; sx <= ACPI_S5; sx++) {
- int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1);
+ for (sx = ACPI_STATE_S0; sx <= ACPI_STATE_S5; sx++) {
if (ACPI_SUCCESS(
- acpi_hw_obtain_sleep_type_register_data(ca_sx,
+ acpi_hw_obtain_sleep_type_register_data(sx,
&type_a,
&type_b))) {
- acpi_slptyp[sx] = ACPI_SLP_TYP(type_a, type_b);
printk(" S%d", sx);
}
- else {
- acpi_slptyp[sx] = ACPI_INVALID;
- }
}
printk("\n");
diff --git a/drivers/acpi/table.c b/drivers/acpi/table.c
index 8379b4204d44..de0f99a275a9 100644
--- a/drivers/acpi/table.c
+++ b/drivers/acpi/table.c
@@ -47,21 +47,6 @@ acpi_fetch_fadt(void)
return -ENODEV;
}
- if (acpi_fadt.plvl2_lat
- && acpi_fadt.plvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
- acpi_c2_exit_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat);
- acpi_c2_enter_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
- }
- if (acpi_fadt.plvl3_lat
- && acpi_fadt.plvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
- acpi_c3_exit_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat);
- acpi_c3_enter_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5);
- }
-
return 0;
}
@@ -71,11 +56,7 @@ acpi_fetch_fadt(void)
int
acpi_find_and_load_tables(u64 rsdp)
{
- if (ACPI_SUCCESS(acpi_load_tables(rsdp)))
- {
- printk(KERN_INFO "ACPI: System description tables loaded\n");
- }
- else {
+ if (!ACPI_SUCCESS(acpi_load_tables(rsdp))) {
printk(KERN_INFO "ACPI: System description table load failed\n");
acpi_terminate();
return -1;
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index 9984bcadb754..76d7fff15c47 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -312,11 +312,11 @@ acpi_tb_convert_table_fadt (void)
/* No 0.71 equivalence. Leave pre-zeroed. */
/* FADT2->Flush_stride = 0; */
- /* Processor’s duty cycle index in processor's P_CNT reg*/
+ /* Processor's duty cycle index in processor's P_CNT reg*/
/* No 0.71 equivalence. Leave pre-zeroed. */
/* FADT2->Duty_offset = 0; */
- /* Processor’s duty cycle value bit width in P_CNT register.*/
+ /* Processor's duty cycle value bit width in P_CNT register.*/
/* No 0.71 equivalence. Leave pre-zeroed. */
/* FADT2->Duty_width = 0; */
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 7b7a6f2066b6..836a89f1e3ed 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -39,8 +39,6 @@
extern int mac_floppy_init(void);
#endif
-extern int lvm_init(void);
-
/*
* For the allocated request tables
*/
@@ -1120,12 +1118,25 @@ sorry:
extern int stram_device_init (void);
#endif
-/*
- * First step of what used to be end_request
+
+/**
+ * end_that_request_first - end I/O on one buffer.
+ * @req: the request being processed
+ * @uptodate: 0 for I/O error
+ * @name: the name printed for an I/O error
*
- * 0 means continue with end_that_request_last,
- * 1 means we are done
- */
+ * Description:
+ * Ends I/O on the first buffer attached to @req, and sets it up
+ * for the next buffer_head (if any) in the cluster.
+ *
+ * Return:
+ * 0 - we are done with this request, call end_that_request_last()
+ * 1 - still buffers pending for this request
+ *
+ * Caveat:
+ * Drivers implementing their own end_request handling must call
+ * blk_finished_io() appropriately.
+ **/
int end_that_request_first (struct request *req, int uptodate, char *name)
{
@@ -1198,17 +1209,10 @@ int __init blk_dev_init(void)
* use half of RAM
*/
high_queued_sectors = (total_ram * 2) / 3;
- low_queued_sectors = high_queued_sectors - MB(128);
- if (low_queued_sectors < 0)
- low_queued_sectors = total_ram / 2;
-
- /*
- * for big RAM machines (>= 384MB), use more for I/O
- */
- if (total_ram >= MB(384)) {
- high_queued_sectors = (total_ram * 4) / 5;
+ low_queued_sectors = high_queued_sectors / 3;
+ if (high_queued_sectors - low_queued_sectors > MB(128))
low_queued_sectors = high_queued_sectors - MB(128);
- }
+
/*
* make it sectors (512b)
@@ -1337,9 +1341,6 @@ int __init blk_dev_init(void)
#ifdef CONFIG_SUN_JSFLASH
jsfd_init();
#endif
-#ifdef CONFIG_BLK_DEV_LVM
- lvm_init();
-#endif
return 0;
};
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 1e555da55a80..cafe72afd32c 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -295,11 +295,11 @@ MODULE_PARM(check_media_type, "i");
/* These are used to simplify getting data in from and back to user land */
#define IOCTL_IN(arg, type, in) \
- if (copy_from_user(&in, (type *) arg, sizeof in)) \
+ if (copy_from_user(&(in), (type *) (arg), sizeof (in))) \
return -EFAULT;
#define IOCTL_OUT(arg, type, out) \
- if (copy_to_user((type *) arg, &out, sizeof out)) \
+ if (copy_to_user((type *) (arg), &(out), sizeof (out))) \
return -EFAULT;
/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index 942142832282..ccd53dacce7b 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -1384,9 +1384,11 @@ static void via_cleanup(void)
aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge.previous_size);
- pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE, 0);
pci_write_config_byte(agp_bridge.dev, VIA_APSIZE,
previous_size->size_value);
+ /* Do not disable by writing 0 to VIA_ATTBASE, it screws things up
+ * during reinitialization.
+ */
}
static void via_tlbflush(agp_memory * mem)
@@ -2373,9 +2375,10 @@ static int __init agp_find_supported_device(void)
if (i810_dev == NULL) {
printk(KERN_ERR PFX "agpgart: Detected an "
"Intel i815, but could not find the"
- " secondary device.\n");
- agp_bridge.type = NOT_SUPPORTED;
- return -ENODEV;
+ " secondary device.\n"
+ "Assuming user has added an external AGP"
+ " card\n");
+ break;
}
printk(KERN_INFO PFX "agpgart: Detected an Intel i815 "
"Chipset.\n");
diff --git a/drivers/i2o/i2o_block.c b/drivers/i2o/i2o_block.c
index c79d113a79e4..857b32a7efd9 100644
--- a/drivers/i2o/i2o_block.c
+++ b/drivers/i2o/i2o_block.c
@@ -420,17 +420,12 @@ static int i2ob_merge_requests(request_queue_t *q,
{
int max_segments = i2ob_dev[MINOR(req->rq_dev)].max_segments;
int total_segments = req->nr_segments + next->nr_segments;
- int same_segment;
if (__max_segments < max_segments)
max_segments = __max_segments;
- same_segment = 0;
if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
- {
total_segments--;
- same_segment = 1;
- }
if (total_segments > max_segments)
return 0;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3a6a9e8d94f9..433951e955a7 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -288,6 +288,9 @@
* 4.59 Aug 11, 2000 - Fix changer problem in cdrom_read_toc, we weren't
* correctly sensing a disc change.
* - Rearranged some code
+ * - Use extended sense on drives that support it for
+ * correctly reporting tray status -- from
+ * Michael D Johnson <johnsom@orst.edu>
*
*************************************************************************/
@@ -759,16 +762,13 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
* changed 5 parameters to 3 for dvd-ram
* struct packet_command *pc; now packet_command_t *pc;
*/
-#undef CLASSIC_PACKET_STRUCT
static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
struct packet_command *pc,
ide_handler_t *handler)
{
-#ifdef CLASSIC_PACKET_STRUCT
unsigned char *cmd_buf = pc->c;
int cmd_len = sizeof(pc->c);
unsigned int timeout = pc->timeout;
-#endif
ide_startstop_t startstop;
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
@@ -786,22 +786,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
}
/* Arm the interrupt handler. */
-#ifdef CLASSIC_PACKET_STRUCT
- /* Arm the interrupt handler. */
ide_set_handler (drive, handler, timeout, cdrom_timer_expiry);
/* Send the command to the device. */
atapi_output_bytes (drive, cmd_buf, cmd_len);
-#else /* !CLASSIC_PACKET_STRUCT */
- /* Arm the interrupt handler. */
-// ide_set_handler (drive, handler, (unsigned int) pc->timeout, cdrom_timer_expiry);
- ide_set_handler (drive, handler, pc->timeout, cdrom_timer_expiry);
-
- /* Send the command to the device. */
-// atapi_output_bytes (drive, (void *)pc->c, (unsigned int) sizeof(pc->c));
- atapi_output_bytes (drive, pc->c, sizeof(pc->c));
-#endif /* CLASSIC_PACKET_STRUCT */
-
return ide_started;
}
@@ -1884,9 +1872,6 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
If it is, just return. */
(void) cdrom_check_status(drive, sense);
- if (CDROM_STATE_FLAGS(drive)->toc_valid)
- return 0;
-
/* First read just the header, so we know how long the TOC is. */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
sizeof(struct atapi_toc_header), sense);
@@ -2324,11 +2309,17 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
sense.ascq == 0x04)
return CDS_DISC_OK;
+
+ /*
+ * If not using Mt Fuji extended media tray reports,
+ * just return TRAY_OPEN since ATAPI doesn't provide
+ * any other way to detect this...
+ */
if (sense.sense_key == NOT_READY) {
- /* ATAPI doesn't have anything that can help
- us decide whether the drive is really
- emtpy or the tray is just open. irk. */
- return CDS_TRAY_OPEN;
+ if (sense.asc == 0x3a && (!sense.ascq||sense.ascq == 1))
+ return CDS_NO_DISC;
+ else
+ return CDS_TRAY_OPEN;
}
return CDS_DRIVE_NOT_READY;
@@ -2597,7 +2588,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_ram)
printk (" DVD%s%s",
(CDROM_CONFIG_FLAGS (drive)->dvd_r)? "-R" : "",
- (CDROM_CONFIG_FLAGS (drive)->dvd_ram)? "AM" : "");
+ (CDROM_CONFIG_FLAGS (drive)->dvd_ram)? "-RAM" : "");
if (CDROM_CONFIG_FLAGS (drive)->cd_r|CDROM_CONFIG_FLAGS (drive)->cd_rw)
printk (" CD%s%s",
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 0b60e89b3d90..6d0366cf268d 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1708,8 +1708,8 @@ int __devinit hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *
}
static struct pci_device_id hisax_pci_tbl[] __initdata = {
-#ifdef CONFIG_HISAX_FRTIZPCI
- {PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_FRITZ, PCI_ANY_ID, PCI_ANY_ID},
+#ifdef CONFIG_HISAX_FRITZPCI
+ {PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID},
#endif
#ifdef CONFIG_HISAX_DIEHLDIVA
{PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, PCI_ANY_ID, PCI_ANY_ID},
diff --git a/drivers/md/Config.in b/drivers/md/Config.in
index 565055a68faa..30438c77fd3c 100644
--- a/drivers/md/Config.in
+++ b/drivers/md/Config.in
@@ -11,12 +11,7 @@ dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
- bool ' Boot support' CONFIG_MD_BOOT
- bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-fi
dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD
-dep_mbool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS $CONFIG_BLK_DEV_LVM
endmenu
diff --git a/drivers/md/lvm-snap.c b/drivers/md/lvm-snap.c
index 980694ee32df..e28ffdbe9449 100644
--- a/drivers/md/lvm-snap.c
+++ b/drivers/md/lvm-snap.c
@@ -21,6 +21,14 @@
*
*/
+/*
+ * Changelog
+ *
+ * 05/07/2000 - implemented persistent snapshot support
+ * 23/11/2000 - used cpu_to_le64 rather than my own macro
+ *
+ */
+
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/blkdev.h>
@@ -30,7 +38,9 @@
#include <linux/lvm.h>
-static char *lvm_snap_version __attribute__ ((unused)) = "LVM 0.9 snapshot code (13/11/2000)\n";
+#include "lvm-snap.h"
+
+static char *lvm_snap_version __attribute__ ((unused)) = "LVM 0.9.1_beta2 snapshot code (18/01/2001)\n";
extern const char *const lvm_name;
extern int lvm_blocksizes[];
@@ -214,10 +224,10 @@ void lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap)
memset(lv_COW_table, 0, blksize_snap);
for ( ; is < lv_snap->lv_remap_ptr; is++, id++) {
/* store new COW_table entry */
- lv_COW_table[id].pv_org_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_org));
- lv_COW_table[id].pv_org_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[is].rsector_org);
- lv_COW_table[id].pv_snap_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_new));
- lv_COW_table[id].pv_snap_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[is].rsector_new);
+ lv_COW_table[id].pv_org_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_org));
+ lv_COW_table[id].pv_org_rsector = cpu_to_le64(lv_snap->lv_block_exception[is].rsector_org);
+ lv_COW_table[id].pv_snap_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[is].rdev_new));
+ lv_COW_table[id].pv_snap_rsector = cpu_to_le64(lv_snap->lv_block_exception[is].rsector_new);
}
}
@@ -227,8 +237,7 @@ void lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap)
*
*/
-int lvm_write_COW_table_block(vg_t * vg,
- lv_t * lv_snap)
+int lvm_write_COW_table_block(vg_t * vg, lv_t * lv_snap)
{
int blksize_snap;
int end_of_table;
@@ -268,10 +277,10 @@ int lvm_write_COW_table_block(vg_t * vg,
blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10);
/* store new COW_table entry */
- lv_COW_table[idx_COW_table].pv_org_number = LVM_TO_DISK64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[idx].rdev_org));
- lv_COW_table[idx_COW_table].pv_org_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[idx].rsector_org);
- lv_COW_table[idx_COW_table].pv_snap_number = LVM_TO_DISK64(lvm_pv_get_number(vg, snap_phys_dev));
- lv_COW_table[idx_COW_table].pv_snap_rsector = LVM_TO_DISK64(lv_snap->lv_block_exception[idx].rsector_new);
+ lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(lvm_pv_get_number(vg, lv_snap->lv_block_exception[idx].rdev_org));
+ lv_COW_table[idx_COW_table].pv_org_rsector = cpu_to_le64(lv_snap->lv_block_exception[idx].rsector_org);
+ lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(lvm_pv_get_number(vg, snap_phys_dev));
+ lv_COW_table[idx_COW_table].pv_snap_rsector = cpu_to_le64(lv_snap->lv_block_exception[idx].rsector_new);
length_tmp = iobuf->length;
iobuf->length = blksize_snap;
@@ -568,6 +577,7 @@ void lvm_snapshot_release(lv_t * lv)
}
if (lv->lv_iobuf)
{
+ kiobuf_wait_for_io(lv->lv_iobuf);
unmap_kiobuf(lv->lv_iobuf);
free_kiovec(1, &lv->lv_iobuf);
lv->lv_iobuf = NULL;
diff --git a/drivers/md/lvm-snap.h b/drivers/md/lvm-snap.h
new file mode 100644
index 000000000000..23538a1b7467
--- /dev/null
+++ b/drivers/md/lvm-snap.h
@@ -0,0 +1,47 @@
+/*
+ * kernel/lvm-snap.h
+ *
+ * Copyright (C) 2001 Sistina Software
+ *
+ *
+ * LVM driver is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * LVM driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/*
+ * Changelog
+ *
+ * 05/01/2001:Joe Thornber - Factored this file out of lvm.c
+ *
+ */
+
+#ifndef LVM_SNAP_H
+#define LVM_SNAP_H
+
+/* external snapshot calls */
+extern inline int lvm_get_blksize(kdev_t);
+extern int lvm_snapshot_alloc(lv_t *);
+extern void lvm_snapshot_fill_COW_page(vg_t *, lv_t *);
+extern int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, lv_t *);
+extern int lvm_snapshot_remap_block(kdev_t *, ulong *, ulong, lv_t *);
+extern void lvm_snapshot_release(lv_t *);
+extern int lvm_write_COW_table_block(vg_t *, lv_t *);
+extern inline void lvm_hash_link(lv_block_exception_t *,
+ kdev_t, ulong, lv_t *);
+extern int lvm_snapshot_alloc_hash_table(lv_t *);
+extern void lvm_drop_snapshot(lv_t *, const char *);
+
+#endif
diff --git a/drivers/md/lvm.c b/drivers/md/lvm.c
index ea276c57c95e..a4ca05e9086d 100644
--- a/drivers/md/lvm.c
+++ b/drivers/md/lvm.c
@@ -7,22 +7,23 @@
* April-May,July-August,November 1998
* January-March,May,July,September,October 1999
* January,February,July,September-November 2000
+ * January 2001
*
*
* LVM driver is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
- *
+ *
* LVM driver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Boston, MA 02111-1307, USA.
*
*/
@@ -138,13 +139,21 @@
* 01/11/2000 - added memory information on hash tables to
* lvm_proc_get_global_info()
* 02/11/2000 - implemented /proc/lvm/ hierarchy
- * 07/12/2000 - make sure lvm_make_request_fn returns correct value - 0 or 1 - NeilBrown
+ * 22/11/2000 - changed lvm_do_create_proc_entry_of_pv () to work
+ * with devfs
+ * 26/11/2000 - corrected #ifdef locations for PROC_FS
+ * 28/11/2000 - fixed lvm_do_vg_extend() NULL pointer BUG
+ * - fixed lvm_do_create_proc_entry_of_pv() buffer tampering BUG
+ * 08/01/2001 - Removed conditional compiles related to PROC_FS,
+ * procfs is always supported now. (JT)
+ * 12/01/2001 - avoided flushing logical volume in case of shrinking
+ * because of unecessary overhead in case of heavy updates
*
*/
-static char *lvm_version = "LVM version 0.9 by Heinz Mauelshagen (13/11/2000)\n";
-static char *lvm_short_version = "version 0.9 (13/11/2000)";
+static char *lvm_version = "LVM version 0.9.1_beta2 by Heinz Mauelshagen (18/01/2001)\n";
+static char *lvm_short_version = "version 0.9.1_beta2 (18/01/2001)";
#define MAJOR_NR LVM_BLK_MAJOR
#define DEVICE_OFF(device)
@@ -190,6 +199,8 @@ static char *lvm_short_version = "version 0.9 (13/11/2000)";
#include <linux/errno.h>
#include <linux/lvm.h>
+#include "lvm-snap.h"
+
#define LVM_CORRECT_READ_AHEAD( a) \
if ( a < LVM_MIN_READ_AHEAD || \
a > LVM_MAX_READ_AHEAD) a = LVM_MAX_READ_AHEAD;
@@ -198,19 +209,28 @@ static char *lvm_short_version = "version 0.9 (13/11/2000)";
# define WRITEA WRITE
#endif
-/*
- * External function prototypes
- */
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
+/* debug macros */
+#ifdef DEBUG_IOCTL
+#define P_IOCTL(fmt, args...) printk(KERN_DEBUG "lvm ioctl: " fmt, ## args)
#else
-extern int lvm_init(void);
+#define P_IOCTL(fmt, args...)
#endif
-static void lvm_dummy_device_request(request_queue_t *);
-#define DEVICE_REQUEST lvm_dummy_device_request
+#ifdef DEBUG_MAP
+#define P_MAP(fmt, args...) printk(KERN_DEBUG "lvm map: " fmt, ## args)
+#else
+#define P_MAP(fmt, args...)
+#endif
+
+#ifdef DEBUG_KFREE
+#define P_KFREE(fmt, args...) printk(KERN_DEBUG "lvm kfree: " fmt, ## args)
+#else
+#define P_KFREE(fmt, args...)
+#endif
+/*
+ * External function prototypes
+ */
static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*);
static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
@@ -224,42 +244,29 @@ static int lvm_user_bmap(struct inode *, struct lv_bmap *);
static int lvm_chr_ioctl(struct inode *, struct file *, uint, ulong);
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
int lvm_proc_read_vg_info(char *, char **, off_t, int, int *, void *);
int lvm_proc_read_lv_info(char *, char **, off_t, int, int *, void *);
int lvm_proc_read_pv_info(char *, char **, off_t, int, int *, void *);
static int lvm_proc_get_global_info(char *, char **, off_t, int, int *, void *);
+
+void lvm_do_create_devfs_entry_of_vg ( vg_t *);
+
void lvm_do_create_proc_entry_of_vg ( vg_t *);
-inline void lvm_do_remove_proc_entry_of_vg ( vg_t *);
-inline void lvm_do_create_proc_entry_of_lv ( vg_t *, lv_t *);
-inline void lvm_do_remove_proc_entry_of_lv ( vg_t *, lv_t *);
-inline void lvm_do_create_proc_entry_of_pv ( vg_t *, pv_t *);
-inline void lvm_do_remove_proc_entry_of_pv ( vg_t *, pv_t *);
-#endif
+void lvm_do_remove_proc_entry_of_vg ( vg_t *);
+void lvm_do_create_proc_entry_of_lv ( vg_t *, lv_t *);
+void lvm_do_remove_proc_entry_of_lv ( vg_t *, lv_t *);
+void lvm_do_create_proc_entry_of_pv ( vg_t *, pv_t *);
+void lvm_do_remove_proc_entry_of_pv ( vg_t *, pv_t *);
-#ifdef LVM_HD_NAME
-void lvm_hd_name(char *, int);
-#endif
/* End external function prototypes */
/*
* Internal function prototypes
*/
+static void lvm_cleanup(void);
static void lvm_init_vars(void);
-/* external snapshot calls */
-extern inline int lvm_get_blksize(kdev_t);
-extern int lvm_snapshot_alloc(lv_t *);
-extern void lvm_snapshot_fill_COW_page(vg_t *, lv_t *);
-extern int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, lv_t *);
-extern int lvm_snapshot_remap_block(kdev_t *, ulong *, ulong, lv_t *);
-extern void lvm_snapshot_release(lv_t *);
-extern int lvm_write_COW_table_block(vg_t *, lv_t *);
-extern inline void lvm_hash_link(lv_block_exception_t *, kdev_t, ulong, lv_t *);
-extern int lvm_snapshot_alloc_hash_table(lv_t *);
-extern void lvm_drop_snapshot(lv_t *, char *);
-
#ifdef LVM_HD_NAME
extern void (*lvm_hd_name_ptr) (char *, int);
#endif
@@ -288,9 +295,9 @@ static int lvm_do_vg_reduce(vg_t *, void *);
static int lvm_do_vg_rename(vg_t *, void *);
static int lvm_do_vg_remove(int);
static void lvm_geninit(struct gendisk *);
-#ifdef LVM_GET_INODE
-static struct inode *lvm_get_inode(int);
-void lvm_clear_inode(struct inode *);
+static char *lvm_show_uuid ( char *);
+#ifdef LVM_HD_NAME
+void lvm_hd_name(char *, int);
#endif
/* END Internal function prototypes */
@@ -298,12 +305,10 @@ void lvm_clear_inode(struct inode *);
/* volume group descriptor area pointers */
static vg_t *vg[ABS_MAX_VG];
-#ifdef CONFIG_DEVFS_FS
static devfs_handle_t lvm_devfs_handle;
static devfs_handle_t vg_devfs_handle[MAX_VG];
static devfs_handle_t ch_devfs_handle[MAX_VG];
static devfs_handle_t lv_devfs_handle[MAX_LV];
-#endif
static pv_t *pvp = NULL;
static lv_t *lvp = NULL;
@@ -340,18 +345,15 @@ static int loadtime = 0;
static uint vg_count = 0;
static long lvm_chr_open_count = 0;
static ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION;
-static DECLARE_WAIT_QUEUE_HEAD(lvm_snapshot_wait);
static DECLARE_WAIT_QUEUE_HEAD(lvm_wait);
static DECLARE_WAIT_QUEUE_HEAD(lvm_map_wait);
static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t lvm_snapshot_lock = SPIN_LOCK_UNLOCKED;
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
static struct proc_dir_entry *lvm_proc_dir = NULL;
static struct proc_dir_entry *lvm_proc_vg_subdir = NULL;
struct proc_dir_entry *pde = NULL;
-#endif
static struct file_operations lvm_chr_fops =
{
@@ -360,7 +362,7 @@ static struct file_operations lvm_chr_fops =
ioctl: lvm_chr_ioctl,
};
-#define BLOCK_DEVICE_OPERATIONS
+
/* block device operations structure needed for 2.3.38? and above */
static struct block_device_operations lvm_blk_dops =
{
@@ -391,22 +393,10 @@ static struct gendisk lvm_gendisk =
NULL, /* pointer to next gendisk struct (internal) */
};
-
-#ifdef MODULE
-/*
- * Module initialization...
- */
-int init_module(void)
-#else
/*
* Driver initialization...
*/
-#ifdef __initfunc
-__initfunc(int lvm_init(void))
-#else
-int __init lvm_init(void)
-#endif
-#endif /* #ifdef MODULE */
+int lvm_init(void)
{
struct gendisk *gendisk_ptr = NULL;
@@ -414,11 +404,7 @@ int __init lvm_init(void)
printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
return -EIO;
}
-#ifdef BLOCK_DEVICE_OPERATIONS
if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0)
-#else
- if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_fops) < 0)
-#endif
{
printk("%s -- register_blkdev failed\n", lvm_name);
if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
@@ -426,21 +412,17 @@ int __init lvm_init(void)
return -EIO;
}
-#ifdef CONFIG_DEVFS_FS
lvm_devfs_handle = devfs_register(
0 , "lvm", 0, 0, LVM_CHAR_MAJOR,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
&lvm_chr_fops, NULL);
-#endif
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_proc_dir = create_proc_entry (LVM_DIR, S_IFDIR, &proc_root);
if (lvm_proc_dir != NULL) {
lvm_proc_vg_subdir = create_proc_entry (LVM_VG_SUBDIR, S_IFDIR, lvm_proc_dir);
pde = create_proc_entry(LVM_GLOBAL, S_IFREG, lvm_proc_dir);
if ( pde != NULL) pde->read_proc = &lvm_proc_get_global_info;
}
-#endif
lvm_init_vars();
lvm_geninit(&lvm_gendisk);
@@ -464,9 +446,9 @@ int __init lvm_init(void)
lvm_hd_name_ptr = lvm_hd_name;
#endif
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn);
+
/* optional read root VGDA */
/*
if ( *rootvg != 0) vg_read_with_pv_and_lv ( rootvg, &vg);
@@ -483,20 +465,17 @@ int __init lvm_init(void)
lvm_version, lvm_name);
return 0;
-} /* init_module() / lvm_init() */
+} /* lvm_init() */
-#ifdef MODULE
/*
- * Module cleanup...
+ * cleanup...
*/
-void cleanup_module(void)
+static void lvm_cleanup(void)
{
struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
-#ifdef CONFIG_DEVFS_FS
devfs_unregister (lvm_devfs_handle);
-#endif
if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
@@ -504,7 +483,7 @@ void cleanup_module(void)
if (unregister_blkdev(MAJOR_NR, lvm_name) < 0) {
printk(KERN_ERR "%s -- unregister_blkdev failed\n", lvm_name);
}
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
gendisk_ptr = gendisk_ptr_prev = gendisk_head;
while (gendisk_ptr != NULL) {
@@ -521,11 +500,9 @@ void cleanup_module(void)
blksize_size[MAJOR_NR] = NULL;
hardsect_size[MAJOR_NR] = NULL;
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
remove_proc_entry(LVM_GLOBAL, lvm_proc_dir);
remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir);
remove_proc_entry(LVM_DIR, &proc_root);
-#endif
#ifdef LVM_HD_NAME
/* reference from linux/drivers/block/genhd.c */
@@ -535,18 +512,13 @@ void cleanup_module(void)
printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name);
return;
-} /* void cleanup_module() */
-#endif /* #ifdef MODULE */
+} /* lvm_cleanup() */
/*
* support function to initialize lvm variables
*/
-#ifdef __initfunc
-__initfunc(void lvm_init_vars(void))
-#else
void __init lvm_init_vars(void)
-#endif
{
int v;
@@ -626,13 +598,9 @@ static int lvm_chr_ioctl(struct inode *inode, struct file *file,
/* otherwise cc will complain about unused variables */
(void) lvm_lock;
-
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_chr_ioctl: command: 0x%X MINOR: %d "
- "VG#: %d mode: 0x%X\n",
- lvm_name, command, minor, VG_CHR(minor), file->f_mode);
-#endif
+ P_IOCTL("%s -- lvm_chr_ioctl: command: 0x%X MINOR: %d "
+ "VG#: %d mode: 0x%X\n",
+ lvm_name, command, minor, VG_CHR(minor), file->f_mode);
#ifdef LVM_TOTAL_RESET
if (lvm_reset_spindown > 0) return -EACCES;
@@ -890,14 +858,12 @@ static int lvm_blk_open(struct inode *inode, struct file *file)
if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM;
/* Check inactive LV and open for read/write */
- if (file->f_mode & O_RDWR) {
- if (!(lv_ptr->lv_status & LV_ACTIVE)) return -EPERM;
- if (!(lv_ptr->lv_access & LV_WRITE)) return -EACCES;
- }
+ if (!(lv_ptr->lv_status & LV_ACTIVE))
+ return -EPERM;
+ if (!(lv_ptr->lv_access & LV_WRITE) &&
+ (file->f_mode & FMODE_WRITE))
+ return -EACCES;
-#ifndef BLOCK_DEVICE_OPERATIONS
- file->f_op = &lvm_blk_fops;
-#endif
/* be sure to increment VG counter */
if (lv_ptr->lv_open == 0) vg_ptr->lv_open++;
@@ -930,24 +896,18 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
void *arg = (void *) a;
struct hd_geometry *hd = (struct hd_geometry *) a;
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl MINOR: %d command: 0x%X arg: %X "
- "VG#: %dl LV#: %d\n",
- lvm_name, minor, command, (ulong) arg,
- VG_BLK(minor), LV_BLK(minor));
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl MINOR: %d command: 0x%X arg: %X "
+ "VG#: %dl LV#: %d\n",
+ lvm_name, minor, command, (ulong) arg,
+ VG_BLK(minor), LV_BLK(minor));
switch (command) {
case BLKGETSIZE:
/* return device size */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
- lvm_name, lv_ptr->lv_size);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
+ lvm_name, lv_ptr->lv_size);
if (put_user(lv_ptr->lv_size, (long *)arg))
- return -EFAULT;
+ return -EFAULT;
break;
@@ -955,10 +915,8 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
/* flush buffer cache */
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);
+
fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
break;
@@ -968,11 +926,9 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
/* set read ahead for block device */
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
- lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
+ lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);
+
if ((long) arg < LVM_MIN_READ_AHEAD ||
(long) arg > LVM_MAX_READ_AHEAD)
return -EINVAL;
@@ -982,10 +938,7 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
case BLKRAGET:
/* get current read ahead setting */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);
if (put_user(lv_ptr->lv_read_ahead, (long *)arg))
return -EFAULT;
break;
@@ -993,10 +946,7 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
case HDIO_GETGEO:
/* get disk geometry */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
if (hd == NULL)
return -EINVAL;
{
@@ -1016,11 +966,8 @@ static int lvm_blk_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
}
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- cylinders: %d\n",
- lvm_name, lv_ptr->lv_size / heads / sectors);
-#endif
+ P_IOCTL("%s -- lvm_blk_ioctl -- cylinders: %d\n",
+ lvm_name, lv_ptr->lv_size / heads / sectors);
break;
@@ -1127,22 +1074,22 @@ static int lvm_user_bmap(struct inode *inode, struct lv_bmap *user_result)
struct buffer_head bh;
unsigned long block;
int err;
-
+
if (get_user(block, &user_result->lv_block))
- return -EFAULT;
-
+ return -EFAULT;
+
memset(&bh,0,sizeof bh);
bh.b_rsector = block;
bh.b_dev = bh.b_rdev = inode->i_dev;
bh.b_size = lvm_get_blksize(bh.b_dev);
if ((err=lvm_map(&bh, READ)) < 0) {
- printk("lvm map failed: %d\n", err);
- return -EINVAL;
+ printk("lvm map failed: %d\n", err);
+ return -EINVAL;
}
-
- return put_user( kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
+
+ return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
put_user(bh.b_rsector, &user_result->lv_block) ? -EFAULT : 0;
-}
+}
/*
@@ -1168,7 +1115,7 @@ int lvm_vg_info(vg_t *vg_ptr, char *buf) {
vg_ptr->pe_total,
vg_ptr->pe_allocated * vg_ptr->pe_size >> 1,
vg_ptr->pe_allocated,
- (vg_ptr->pe_total - vg_ptr->pe_allocated) *
+ (vg_ptr->pe_total - vg_ptr->pe_allocated) *
vg_ptr->pe_size >> 1,
vg_ptr->pe_total - vg_ptr->pe_allocated);
return sz;
@@ -1263,7 +1210,6 @@ int lvm_pv_info(pv_t *pv_ptr, char *buf) {
}
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
/*
* Support functions /proc-Filesystem
*/
@@ -1325,10 +1271,7 @@ static int lvm_proc_get_global_info(char *page, char **start, off_t pos, int cou
lv_block_exception_t_bytes *= sizeof(lv_block_exception_t);
if (buf != NULL) {
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG
- "%s -- vfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- vfree %d\n", lvm_name, __LINE__);
lock_kernel();
vfree(buf);
unlock_kernel();
@@ -1452,7 +1395,6 @@ static int lvm_proc_get_global_info(char *page, char **start, off_t pos, int cou
else
return count;
} /* lvm_proc_get_global_info() */
-#endif /* #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS */
/*
@@ -1478,7 +1420,7 @@ int lvm_proc_read_vg_info(char *page, char **start, off_t off,
sz += sprintf ( page+sz, "PE size: %u\n", vg->pe_size / 2);
sz += sprintf ( page+sz, "PE total: %u\n", vg->pe_total);
sz += sprintf ( page+sz, "PE allocated: %u\n", vg->pe_allocated);
- sz += sprintf ( page+sz, "uuid: %s\n", vg->vg_uuid);
+ sz += sprintf ( page+sz, "uuid: %s\n", lvm_show_uuid(vg->vg_uuid));
return sz;
}
@@ -1525,7 +1467,7 @@ int lvm_proc_read_pv_info(char *page, char **start, off_t off,
sz += sprintf ( page+sz, "PE allocated: %u\n", pv->pe_allocated);
sz += sprintf ( page+sz, "device: %02u:%02u\n",
MAJOR(pv->pv_dev), MINOR(pv->pv_dev));
- sz += sprintf ( page+sz, "uuid: %s\n", pv->pv_uuid);
+ sz += sprintf ( page+sz, "uuid: %s\n", lvm_show_uuid(pv->pv_uuid));
return sz;
@@ -1565,15 +1507,13 @@ static int lvm_map(struct buffer_head *bh, int rw)
lvm_name, lv->lv_name);
return -1;
}
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
- "size:%lu\n",
- lvm_name, minor,
- MAJOR(rdev_tmp),
- MINOR(rdev_tmp),
- rsector_tmp, size);
-#endif
+
+ P_MAP("%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
+ "size:%lu\n",
+ lvm_name, minor,
+ MAJOR(rdev_tmp),
+ MINOR(rdev_tmp),
+ rsector_tmp, size);
if (rsector_tmp + size > lv->lv_size) {
printk(KERN_ALERT
@@ -1595,15 +1535,13 @@ lvm_second_remap:
(rsector_tmp % vg_this->pe_size);
rdev_tmp = lv->lv_current_pe[index].dev;
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n",
+ P_MAP("lv_current_pe[%ld].pe: %ld rdev: %02d:%02d "
+ "rsector:%ld\n",
index,
lv->lv_current_pe[index].pe,
MAJOR(rdev_tmp),
MINOR(rdev_tmp),
rsector_tmp);
-#endif
/* striped mapping */
} else {
@@ -1624,9 +1562,7 @@ lvm_second_remap:
rdev_tmp = lv->lv_current_pe[index].dev;
}
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
+ P_MAP("lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
"stripe_length: %ld stripe_index: %ld\n",
index,
lv->lv_current_pe[index].pe,
@@ -1635,7 +1571,6 @@ lvm_second_remap:
rsector_tmp,
stripe_length,
stripe_index);
-#endif
/* handle physical extents on the move */
if (pe_lock_req.lock == LOCK_PE) {
@@ -1659,6 +1594,8 @@ lvm_second_remap:
if (lv->lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG)) {
/* original logical volume */
if (lv->lv_access & LV_SNAPSHOT_ORG) {
+ /* Serializes the access to the lv_snapshot_next list */
+ down(&lv->lv_snapshot_sem);
if (rw == WRITE || rw == WRITEA)
{
lv_t *lv_ptr;
@@ -1669,7 +1606,8 @@ lvm_second_remap:
lv_ptr = lv_ptr->lv_snapshot_next) {
/* Check for inactive snapshot */
if (!(lv_ptr->lv_status & LV_ACTIVE)) continue;
- down(&lv->lv_snapshot_org->lv_snapshot_sem);
+ /* Serializes the COW with the accesses to the snapshot device */
+ down(&lv_ptr->lv_snapshot_sem);
/* do we still have exception storage for this snapshot free? */
if (lv_ptr->lv_block_exception != NULL) {
rdev_sav = rdev_tmp;
@@ -1690,9 +1628,10 @@ lvm_second_remap:
rdev_tmp = rdev_sav;
rsector_tmp = rsector_sav;
}
- up(&lv->lv_snapshot_org->lv_snapshot_sem);
+ up(&lv_ptr->lv_snapshot_sem);
}
}
+ up(&lv->lv_snapshot_sem);
} else {
/* remap snapshot logical volume */
down(&lv->lv_snapshot_sem);
@@ -1733,31 +1672,12 @@ void lvm_hd_name(char *buf, int minor)
/*
- * this one never should be called...
- */
-static void lvm_dummy_device_request(request_queue_t * t)
-{
- printk(KERN_EMERG
- "%s -- oops, got lvm request for %02d:%02d [sector: %lu]\n",
- lvm_name,
- MAJOR(CURRENT->rq_dev),
- MINOR(CURRENT->rq_dev),
- CURRENT->sector);
- return;
-}
-
-
-/*
* make request function
*/
static int lvm_make_request_fn(request_queue_t *q,
int rw,
- struct buffer_head *bh)
-{
- if (lvm_map(bh, rw)<0)
- return 0; /* failure, buffer_IO_error has been called, don't recurse */
- else
- return 1; /* all ok, mapping done, call lower level driver */
+ struct buffer_head *bh) {
+ return (lvm_map(bh, rw) < 0) ? 0 : 1;
}
@@ -1774,10 +1694,8 @@ static int lvm_do_lock_lvm(void)
lock_try_again:
spin_lock(&lvm_lock);
if (lock != 0 && lock != current->pid) {
-#ifdef DEBUG_IOCTL
- printk(KERN_INFO "lvm_do_lock_lvm: %s is locked by pid %d ...\n",
- lvm_name, lock);
-#endif
+ P_IOCTL("lvm_do_lock_lvm: %s is locked by pid %d ...\n",
+ lvm_name, lock);
spin_unlock(&lvm_lock);
interruptible_sleep_on(&lvm_wait);
if (current->sigpending != 0)
@@ -1966,6 +1884,8 @@ int lvm_do_vg_create(int minor, void *arg)
}
}
+ lvm_do_create_devfs_entry_of_vg ( vg_ptr);
+
/* Second path to correct snapshot logical volumes which are not
in place during first path above */
for (l = 0; l < ls; l++) {
@@ -1980,18 +1900,7 @@ int lvm_do_vg_create(int minor, void *arg)
}
}
-#ifdef CONFIG_DEVFS_FS
- vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, NULL);
- ch_devfs_handle[vg_ptr->vg_number] = devfs_register(
- vg_devfs_handle[vg_ptr->vg_number] , "group",
- DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
- &lvm_chr_fops, NULL);
-#endif
-
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_create_proc_entry_of_vg ( vg_ptr);
-#endif
vfree(snap_lv_ptr);
@@ -2021,25 +1930,15 @@ static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg)
for (p = 0; p < vg_ptr->pv_max; p++) {
if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) {
ret = lvm_do_pv_create(arg, vg_ptr, p);
- lvm_do_create_proc_entry_of_pv ( vg_ptr, pv_ptr);
if ( ret != 0) return ret;
-
- /* We don't need the PE list
- in kernel space like LVs pe_t list */
- pv_ptr->pe = NULL;
- vg_ptr->pv_cur++;
- vg_ptr->pv_act++;
- vg_ptr->pe_total +=
- pv_ptr->pe_total;
-#ifdef LVM_GET_INODE
- /* insert a dummy inode for fs_may_mount */
- pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
-#endif
+ pv_ptr = vg_ptr->pv[p];
+ vg_ptr->pe_total += pv_ptr->pe_total;
+ lvm_do_create_proc_entry_of_pv(vg_ptr, pv_ptr);
return 0;
}
}
}
-return -EPERM;
+ return -EPERM;
} /* lvm_do_vg_extend() */
@@ -2060,10 +1959,6 @@ static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg) {
strcmp(pv_ptr->pv_name,
pv_name) == 0) {
if (pv_ptr->lv_cur > 0) return -EPERM;
- vg_ptr->pe_total -=
- pv_ptr->pe_total;
- vg_ptr->pv_cur--;
- vg_ptr->pv_act--;
lvm_do_pv_remove(vg_ptr, p);
/* Make PV pointer array contiguous */
for (; p < vg_ptr->pv_max - 1; p++)
@@ -2091,9 +1986,7 @@ static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg)
if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0)
return -EFAULT;
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_remove_proc_entry_of_vg ( vg_ptr);
-#endif
strncpy ( vg_ptr->vg_name, vg_name, sizeof ( vg_name)-1);
for ( l = 0; l < vg_ptr->lv_max; l++)
@@ -2115,9 +2008,7 @@ static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg)
strncpy(pv_ptr->vg_name, vg_name, NAME_LEN);
}
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_create_proc_entry_of_vg ( vg_ptr);
-#endif
return 0;
} /* lvm_do_vg_rename */
@@ -2166,27 +2057,17 @@ static int lvm_do_vg_remove(int minor)
/* free PVs */
for (i = 0; i < vg_ptr->pv_max; i++) {
if ((pv_ptr = vg_ptr->pv[i]) != NULL) {
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG
- "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);
lvm_do_pv_remove(vg_ptr, i);
}
}
-#ifdef CONFIG_DEVFS_FS
devfs_unregister (ch_devfs_handle[vg_ptr->vg_number]);
devfs_unregister (vg_devfs_handle[vg_ptr->vg_number]);
-#endif
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_remove_proc_entry_of_vg ( vg_ptr);
-#endif
-
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);
kfree(vg_ptr);
vg[VG_CHR(minor)] = NULL;
@@ -2222,11 +2103,6 @@ static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) {
vg_ptr->pv_act++;
vg_ptr->pv_cur++;
-#ifdef LVM_GET_INODE
- /* insert a dummy inode for fs_may_mount */
- pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
-#endif
-
return 0;
} /* lvm_do_pv_create() */
@@ -2237,11 +2113,8 @@ static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) {
static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) {
pv_t *pv_ptr = vg_ptr->pv[p];
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_remove_proc_entry_of_pv ( vg_ptr, pv_ptr);
-#endif
- vg_ptr->pe_total -=
- pv_ptr->pe_total;
+ vg_ptr->pe_total -= pv_ptr->pe_total;
vg_ptr->pv_cur--;
vg_ptr->pv_act--;
#ifdef LVM_GET_INODE
@@ -2320,11 +2193,9 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
"%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
"at line %d\n",
lvm_name, size, __LINE__);
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);
kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;
+ vg_ptr->lv[l] = NULL;
return -ENOMEM;
}
if (copy_from_user(lv_ptr->lv_current_pe, pep, size)) {
@@ -2354,9 +2225,8 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
"%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
"of %d byte at line %d\n",
lvm_name, size, __LINE__);
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- kfree %d\n", lvm_name,
+ __LINE__);
kfree(lv_ptr);
vg_ptr->lv[l] = NULL;
return -ENOMEM;
@@ -2364,7 +2234,7 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) {
vfree(lv_ptr->lv_block_exception);
kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;
+ vg_ptr->lv[l] = NULL;
return -EFAULT;
}
/* point to the original logical volume */
@@ -2372,33 +2242,32 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
lv_ptr->lv_snapshot_minor = 0;
lv_ptr->lv_snapshot_org = lv_ptr;
- lv_ptr->lv_snapshot_prev = NULL;
- /* walk thrugh the snapshot list */
- while (lv_ptr->lv_snapshot_next != NULL)
- lv_ptr = lv_ptr->lv_snapshot_next;
- /* now lv_ptr points to the last existing snapshot in the chain */
- vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr;
/* our new one now back points to the previous last in the chain
which can be the original logical volume */
lv_ptr = vg_ptr->lv[l];
/* now lv_ptr points to our new last snapshot logical volume */
- lv_ptr->lv_snapshot_org = lv_ptr->lv_snapshot_prev->lv_snapshot_org;
- lv_ptr->lv_snapshot_next = NULL;
lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe;
+ lv_ptr->lv_allocated_snapshot_le = lv_ptr->lv_allocated_le;
lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le;
lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le;
lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size;
lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes;
lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize;
+
+ /* Update the VG PE(s) used by snapshot reserve space. */
+ vg_ptr->pe_allocated += lv_ptr->lv_allocated_snapshot_le;
+
if ((ret = lvm_snapshot_alloc(lv_ptr)) != 0)
{
vfree(lv_ptr->lv_block_exception);
kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;
+ vg_ptr->lv[l] = NULL;
return ret;
}
for ( e = 0; e < lv_ptr->lv_remap_ptr; e++)
- lvm_hash_link (lv_ptr->lv_block_exception + e, lv_ptr->lv_block_exception[e].rdev_org, lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
+ lvm_hash_link (lv_ptr->lv_block_exception + e,
+ lv_ptr->lv_block_exception[e].rdev_org,
+ lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
/* need to fill the COW exception table data
into the page for disk i/o */
lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr);
@@ -2426,9 +2295,8 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
vg_ptr->lv_cur++;
lv_ptr->lv_status = lv_status_save;
-#ifdef CONFIG_DEVFS_FS
{
- char *lv_tmp, *lv_buf = NULL;
+ char *lv_tmp, *lv_buf = lv->lv_name;
strtok(lv->lv_name, "/"); /* /dev */
while((lv_tmp = strtok(NULL, "/")) != NULL)
@@ -2440,24 +2308,29 @@ static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
&lvm_blk_dops, NULL);
}
-#endif
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr);
-#endif
/* optionally add our new snapshot LV */
if (lv_ptr->lv_access & LV_SNAPSHOT) {
+ lv_t *org = lv_ptr->lv_snapshot_org, *last;
+
/* sync the original logical volume */
- fsync_dev(lv_ptr->lv_snapshot_org->lv_dev);
+ fsync_dev(org->lv_dev);
#ifdef LVM_VFS_ENHANCEMENT
/* VFS function call to sync and lock the filesystem */
- fsync_dev_lockfs(lv_ptr->lv_snapshot_org->lv_dev);
+ fsync_dev_lockfs(org->lv_dev);
#endif
- lv_ptr->lv_snapshot_org->lv_access |= LV_SNAPSHOT_ORG;
- lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG;
- /* put ourselve into the chain */
- lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr;
+
+ down(&org->lv_snapshot_sem);
+ org->lv_access |= LV_SNAPSHOT_ORG;
+ lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */
+
+ /* Link in the list of snapshot volumes */
+ for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next);
+ lv_ptr->lv_snapshot_prev = last;
+ last->lv_snapshot_next = lv_ptr;
+ up(&org->lv_snapshot_sem);
}
/* activate the logical volume */
@@ -2513,6 +2386,31 @@ static int lvm_do_lv_remove(int minor, char *lv_name, int l)
lv_ptr->lv_snapshot_next != NULL)
return -EPERM;
+ if (lv_ptr->lv_access & LV_SNAPSHOT) {
+ /*
+ * Atomically make the the snapshot invisible
+ * to the original lv before playing with it.
+ */
+ lv_t * org = lv_ptr->lv_snapshot_org;
+ down(&org->lv_snapshot_sem);
+
+ /* remove this snapshot logical volume from the chain */
+ lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next;
+ if (lv_ptr->lv_snapshot_next != NULL) {
+ lv_ptr->lv_snapshot_next->lv_snapshot_prev =
+ lv_ptr->lv_snapshot_prev;
+ }
+ up(&org->lv_snapshot_sem);
+
+ /* no more snapshots? */
+ if (!org->lv_snapshot_next)
+ org->lv_access &= ~LV_SNAPSHOT_ORG;
+ lvm_snapshot_release(lv_ptr);
+
+ /* Update the VG PE(s) used by snapshot reserve space. */
+ vg_ptr->pe_allocated -= lv_ptr->lv_allocated_snapshot_le;
+ }
+
lv_ptr->lv_status |= LV_SPINDOWN;
/* sync the buffers */
@@ -2532,7 +2430,8 @@ static int lvm_do_lv_remove(int minor, char *lv_name, int l)
vg_lv_map[MINOR(lv_ptr->lv_dev)].vg_number = ABS_MAX_VG;
vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1;
- /* correct the PE count in PVs if this is no snapshot logical volume */
+ /* correct the PE count in PVs if this is not a snapshot
+ logical volume */
if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
/* only if this is no snapshot logical volume because
we share the lv_current_pe[] structs with the
@@ -2546,31 +2445,13 @@ static int lvm_do_lv_remove(int minor, char *lv_name, int l)
}
}
vfree(lv_ptr->lv_current_pe);
- /* LV_SNAPSHOT */
- } else {
- /* remove this snapshot logical volume from the chain */
- lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next;
- if (lv_ptr->lv_snapshot_next != NULL) {
- lv_ptr->lv_snapshot_next->lv_snapshot_prev =
- lv_ptr->lv_snapshot_prev;
- }
- /* no more snapshots? */
- if (lv_ptr->lv_snapshot_org->lv_snapshot_next == NULL)
- lv_ptr->lv_snapshot_org->lv_access &= ~LV_SNAPSHOT_ORG;
- lvm_snapshot_release(lv_ptr);
}
-#ifdef CONFIG_DEVFS_FS
devfs_unregister(lv_devfs_handle[lv_ptr->lv_number]);
-#endif
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_remove_proc_entry_of_lv ( vg_ptr, lv_ptr);
-#endif
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
+ P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);
kfree(lv_ptr);
vg_ptr->lv[l] = NULL;
vg_ptr->lv_cur--;
@@ -2638,21 +2519,24 @@ static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *lv)
}
memcpy(lvbe,
lv_ptr->lv_block_exception,
- (lv->lv_remap_end > lv_ptr->lv_remap_end ? lv_ptr->lv_remap_ptr : lv->lv_remap_end) * sizeof(lv_block_exception_t));
+ (lv->lv_remap_end > lv_ptr->lv_remap_end ?
+ lv_ptr->lv_remap_ptr : lv->lv_remap_end) * sizeof(lv_block_exception_t));
lv_ptr->lv_block_exception = lvbe;
lv_ptr->lv_remap_end = lv->lv_remap_end;
if (lvm_snapshot_alloc_hash_table(lv_ptr) != 0)
{
- lvm_drop_snapshot(lv_ptr, "hash_alloc");
+ lvm_drop_snapshot(lv_ptr, "no memory for hash table");
up(&lv_ptr->lv_snapshot_org->lv_snapshot_sem);
vfree(lvbe_old);
vfree(lvs_hash_table_old);
- return 1;
+ return -ENOMEM;
}
for (e = 0; e < lv_ptr->lv_remap_ptr; e++)
- lvm_hash_link (lv_ptr->lv_block_exception + e, lv_ptr->lv_block_exception[e].rdev_org, lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
+ lvm_hash_link (lv_ptr->lv_block_exception + e,
+ lv_ptr->lv_block_exception[e].rdev_org,
+ lv_ptr->lv_block_exception[e].rsector_org, lv_ptr);
up(&lv_ptr->lv_snapshot_org->lv_snapshot_sem);
@@ -2677,15 +2561,6 @@ static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *lv)
return -EFAULT;
}
-#ifdef DEBUG
- printk(KERN_DEBUG
- "%s -- fsync_dev and "
- "invalidate_buffers for %s [%s] in %s\n",
- lvm_name, lv_ptr->lv_name,
- kdevname(lv_ptr->lv_dev),
- vg_ptr->vg_name);
-#endif
-
/* reduce allocation counters on PV(s) */
for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
vg_ptr->pe_allocated--;
@@ -2714,9 +2589,6 @@ static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *lv)
/* save # of old allocated logical extents */
old_allocated_le = lv_ptr->lv_allocated_le;
- /* in case of shrinking -> let's flush */
- if ( end > lv->lv_current_le) fsync_dev(lv_ptr->lv_dev);
-
/* copy preloaded LV */
memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));
@@ -2914,15 +2786,11 @@ static int lvm_do_lv_rename(vg_t *vg_ptr, lv_req_t *lv_req, lv_t *lv)
if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue;
if (lv_ptr->lv_dev == lv->lv_dev)
{
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_remove_proc_entry_of_lv ( vg_ptr, lv_ptr);
-#endif
strncpy(lv_ptr->lv_name,
lv_req->lv_name,
NAME_LEN);
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr);
-#endif
break;
}
}
@@ -3004,9 +2872,22 @@ static int lvm_do_pv_status(vg_t *vg_ptr, void *arg)
/*
+ * create a devfs entry for a volume group
+ */
+void lvm_do_create_devfs_entry_of_vg ( vg_t *vg_ptr) {
+ vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, NULL);
+ ch_devfs_handle[vg_ptr->vg_number] = devfs_register(
+ vg_devfs_handle[vg_ptr->vg_number] , "group",
+ DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+ &lvm_chr_fops, NULL);
+}
+
+
+/*
* create a /proc entry for a logical volume
*/
-inline void lvm_do_create_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
+void lvm_do_create_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
char *basename;
if ( vg_ptr->lv_subdir_pde != NULL) {
@@ -3026,7 +2907,7 @@ inline void lvm_do_create_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
/*
* remove a /proc entry for a logical volume
*/
-inline void lvm_do_remove_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
+void lvm_do_remove_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
char *basename;
if ( vg_ptr->lv_subdir_pde != NULL) {
@@ -3041,13 +2922,17 @@ inline void lvm_do_remove_proc_entry_of_lv ( vg_t *vg_ptr, lv_t *lv_ptr) {
/*
* create a /proc entry for a physical volume
*/
-inline void lvm_do_create_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
+void lvm_do_create_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
+ int offset = 0;
char *basename;
-
- basename = strrchr(pv_ptr->pv_name, '/');
- if (basename == NULL) basename = pv_ptr->pv_name;
- else basename++;
- pde = create_proc_entry(basename, S_IFREG, vg_ptr->pv_subdir_pde);
+ char buffer[NAME_LEN];
+
+ basename = pv_ptr->pv_name;
+ if (strncmp(basename, "/dev/", 5) == 0) offset = 5;
+ strncpy(buffer, basename + offset, sizeof(buffer));
+ basename = buffer;
+ while ( ( basename = strchr ( basename, '/')) != NULL) *basename = '_';
+ pde = create_proc_entry(buffer, S_IFREG, vg_ptr->pv_subdir_pde);
if ( pde != NULL) {
pde->read_proc = lvm_proc_read_pv_info;
pde->data = pv_ptr;
@@ -3058,7 +2943,7 @@ inline void lvm_do_create_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
/*
* remove a /proc entry for a physical volume
*/
-inline void lvm_do_remove_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
+void lvm_do_remove_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
char *basename;
basename = strrchr(pv_ptr->pv_name, '/');
@@ -3074,7 +2959,6 @@ inline void lvm_do_remove_proc_entry_of_pv ( vg_t *vg_ptr, pv_t *pv_ptr) {
/*
* create a /proc entry for a volume group
*/
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
void lvm_do_create_proc_entry_of_vg ( vg_t *vg_ptr) {
int l, p;
pv_t *pv_ptr;
@@ -3090,24 +2974,25 @@ void lvm_do_create_proc_entry_of_vg ( vg_t *vg_ptr) {
pde->read_proc = lvm_proc_read_vg_info;
pde->data = vg_ptr;
}
- vg_ptr->lv_subdir_pde =
- create_proc_entry(LVM_LV_SUBDIR, S_IFDIR,
- vg_ptr->vg_dir_pde);
- vg_ptr->pv_subdir_pde =
- create_proc_entry(LVM_PV_SUBDIR, S_IFDIR,
- vg_ptr->vg_dir_pde);
- }
-
- if ( vg_ptr->pv_subdir_pde != NULL) {
- for ( l = 0; l < vg_ptr->lv_max; l++) {
- if ( ( lv_ptr = vg_ptr->lv[l]) == NULL) continue;
- lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr);
- }
- for ( p = 0; p < vg_ptr->pv_max; p++) {
- if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) continue;
- lvm_do_create_proc_entry_of_pv ( vg_ptr, pv_ptr);
- }
- }
+ pde = create_proc_entry(LVM_LV_SUBDIR, S_IFDIR,
+ vg_ptr->vg_dir_pde);
+ if ( pde != NULL) {
+ vg_ptr->lv_subdir_pde = pde;
+ for ( l = 0; l < vg_ptr->lv_max; l++) {
+ if ( ( lv_ptr = vg_ptr->lv[l]) == NULL) continue;
+ lvm_do_create_proc_entry_of_lv ( vg_ptr, lv_ptr);
+ }
+ }
+ pde = create_proc_entry(LVM_PV_SUBDIR, S_IFDIR,
+ vg_ptr->vg_dir_pde);
+ if ( pde != NULL) {
+ vg_ptr->pv_subdir_pde = pde;
+ for ( p = 0; p < vg_ptr->pv_max; p++) {
+ if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) continue;
+ lvm_do_create_proc_entry_of_pv ( vg_ptr, pv_ptr);
+ }
+ }
+ }
}
/*
@@ -3133,18 +3018,12 @@ void lvm_do_remove_proc_entry_of_vg ( vg_t *vg_ptr) {
remove_proc_entry(vg_ptr->vg_name, lvm_proc_vg_subdir);
}
}
-#endif
/*
* support function initialize gendisk variables
*/
-#ifdef __initfunc
-__initfunc(void lvm_geninit(struct gendisk *lvm_gdisk))
-#else
-void __init
- lvm_geninit(struct gendisk *lvm_gdisk)
-#endif
+void __init lvm_geninit(struct gendisk *lvm_gdisk)
{
int i = 0;
@@ -3166,39 +3045,30 @@ void __init
} /* lvm_gen_init() */
-#ifdef LVM_GET_INODE
/*
- * support function to get an empty inode
- *
- * Gets an empty inode to be inserted into the inode hash,
- * so that a physical volume can't be mounted.
- * This is analog to drivers/block/md.c
- *
- * Is this the real thing?
- *
+ * return a pointer to a '-' padded uuid
*/
-struct inode *lvm_get_inode(int dev)
-{
- struct inode *inode_this = NULL;
+static char *lvm_show_uuid ( char *uuidstr) {
+ int i, j;
+ static char uuid[NAME_LEN] = { 0, };
- /* Lock the device by inserting a dummy inode. */
- inode_this = get_empty_inode();
- inode_this->i_dev = dev;
- insert_inode_hash(inode_this);
- return inode_this;
-}
+ memset ( uuid, 0, NAME_LEN);
+ i = 6;
+ memcpy ( uuid, uuidstr, i);
+ uuidstr += i;
-/*
- * support function to clear an inode
- *
- */
-void lvm_clear_inode(struct inode *inode)
-{
-#ifdef I_FREEING
- inode->i_state |= I_FREEING;
-#endif
- clear_inode(inode);
- return;
+ for ( j = 0; j < 6; j++) {
+ uuid[i++] = '-';
+ memcpy ( &uuid[i], uuidstr, 4);
+ uuidstr += 4;
+ i += 4;
+ }
+
+ memcpy ( &uuid[i], uuidstr, 2 );
+
+ return uuid;
}
-#endif /* #ifdef LVM_GET_INODE */
+
+module_init(lvm_init);
+module_exit(lvm_cleanup);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8542bc2b067f..5d4bab6c9d8b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2033,68 +2033,65 @@ abort:
struct {
int set;
int noautodetect;
+} raid_setup_args md__initdata;
-} raid_setup_args md__initdata = { 0, 0 };
-
-void md_setup_drive(void) md__init;
+void md_setup_drive (void) md__init;
/*
* Searches all registered partitions for autorun RAID arrays
* at boot time.
*/
-#ifdef CONFIG_AUTODETECT_RAID
-static int detected_devices[128] md__initdata = { 0, };
-static int dev_cnt=0;
+static int detected_devices[128] md__initdata;
+static int dev_cnt;
+
void md_autodetect_dev(kdev_t dev)
{
if (dev_cnt >= 0 && dev_cnt < 127)
detected_devices[dev_cnt++] = dev;
}
-#endif
-int md__init md_run_setup(void)
+
+static void autostart_arrays (void)
{
-#ifdef CONFIG_AUTODETECT_RAID
mdk_rdev_t *rdev;
int i;
- if (raid_setup_args.noautodetect)
- printk(KERN_INFO "skipping autodetection of RAID arrays\n");
- else {
-
- printk(KERN_INFO "autodetecting RAID arrays\n");
+ printk(KERN_INFO "autodetecting RAID arrays\n");
- for (i=0; i<dev_cnt; i++) {
- kdev_t dev = detected_devices[i];
+ for (i=0; i<dev_cnt; i++) {
+ kdev_t dev = detected_devices[i];
- if (md_import_device(dev,1)) {
- printk(KERN_ALERT "could not import %s!\n",
- partition_name(dev));
- continue;
- }
- /*
- * Sanity checks:
- */
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- continue;
- }
- if (rdev->faulty) {
- MD_BUG();
- continue;
- }
- md_list_add(&rdev->pending, &pending_raid_disks);
+ if (md_import_device(dev,1)) {
+ printk(KERN_ALERT "could not import %s!\n",
+ partition_name(dev));
+ continue;
}
-
- autorun_devices(-1);
+ /*
+ * Sanity checks:
+ */
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ continue;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ continue;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
}
+ autorun_devices(-1);
+}
+
+int md__init md_run_setup(void)
+{
+ if (raid_setup_args.noautodetect)
+ printk(KERN_INFO "skipping autodetection of RAID arrays\n");
+ else
+ autostart_arrays();
dev_cnt = -1; /* make sure further calls to md_autodetect_dev are ignored */
-#endif
-#ifdef CONFIG_MD_BOOT
md_setup_drive();
-#endif
return 0;
}
@@ -2558,6 +2555,11 @@ static int md_ioctl (struct inode *inode, struct file *file,
md_print_devices();
goto done_unlock;
+ case RAID_AUTORUN:
+ err = 0;
+ autostart_arrays();
+ goto done;
+
case BLKGETSIZE: /* Return device size */
if (!arg) {
err = -EINVAL;
@@ -3639,14 +3641,12 @@ int md__init md_init (void)
return (0);
}
-#ifdef CONFIG_MD_BOOT
-#define MAX_MD_BOOT_DEVS 8
-struct {
- unsigned long set;
- int pers[MAX_MD_BOOT_DEVS];
- int chunk[MAX_MD_BOOT_DEVS];
- kdev_t devices[MAX_MD_BOOT_DEVS][MD_SB_DISKS];
-} md_setup_args md__initdata = { 0, };
+static struct {
+ char device_set [MAX_MD_DEVS];
+ int pers[MAX_MD_DEVS];
+ int chunk[MAX_MD_DEVS];
+ kdev_t devices[MAX_MD_DEVS][MD_SB_DISKS];
+} md_setup_args md__initdata;
/*
* Parse the command-line parameters given our kernel, but do not
@@ -3676,10 +3676,10 @@ static int md__init md_setup(char *str)
printk("md: Too few arguments supplied to md=.\n");
return 0;
}
- if (minor >= MAX_MD_BOOT_DEVS) {
+ if (minor >= MAX_MD_DEVS) {
printk ("md: Minor device number too high.\n");
return 0;
- } else if (md_setup_args.set & (1 << minor)) {
+ } else if (md_setup_args.device_set[minor]) {
printk ("md: Warning - md=%d,... has been specified twice;\n"
" will discard the first definition.\n", minor);
}
@@ -3737,7 +3737,7 @@ static int md__init md_setup(char *str)
printk ("md: Will configure md%d (%s) from %s, below.\n",
minor, pername, devnames);
md_setup_args.devices[minor][i] = (kdev_t) 0;
- md_setup_args.set |= (1 << minor);
+ md_setup_args.device_set[minor] = 1;
return 1;
}
@@ -3747,10 +3747,11 @@ void md__init md_setup_drive(void)
kdev_t dev;
mddev_t*mddev;
- for (minor = 0; minor < MAX_MD_BOOT_DEVS; minor++) {
+ for (minor = 0; minor < MAX_MD_DEVS; minor++) {
mdu_disk_info_t dinfo;
- int err=0;
- if (!(md_setup_args.set & (1 << minor)))
+
+ int err = 0;
+ if (!md_setup_args.device_set[minor])
continue;
printk("md: Loading md%d.\n", minor);
if (mddev_map[minor].mddev) {
@@ -3776,7 +3777,7 @@ void md__init md_setup_drive(void)
ainfo.layout = 0;
ainfo.chunk_size = md_setup_args.chunk[minor];
err = set_array_info(mddev, &ainfo);
- for (i=0; !err && (dev = md_setup_args.devices[minor][i]); i++) {
+ for (i = 0; !err && (dev = md_setup_args.devices[minor][i]); i++) {
dinfo.number = i;
dinfo.raid_disk = i;
dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
@@ -3807,7 +3808,6 @@ void md__init md_setup_drive(void)
}
__setup("md=", md_setup);
-#endif
#ifdef MODULE
int init_module (void)
@@ -3859,9 +3859,7 @@ void cleanup_module (void)
#endif
__initcall(md_init);
-#if defined(CONFIG_AUTODETECT_RAID) || defined(CONFIG_MD_BOOT)
__initcall(md_run_setup);
-#endif
MD_EXPORT_SYMBOL(md_size);
MD_EXPORT_SYMBOL(register_md_personality);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 70004107f45c..495c85d75633 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -685,6 +685,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
if (a == NULL) {
printk(KERN_ERR "pcnet32: No access methods\n");
+ pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
return -ENODEV;
}
lp->a = *a;
@@ -731,6 +732,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
printk(", probed IRQ %d.\n", dev->irq);
else {
printk(", failed to detect IRQ line.\n");
+ pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
return -ENODEV;
}
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 1cdec0a45faf..7fffdf4f73a3 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -413,13 +413,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source);
if (!po)
- goto abort_put;
+ goto abort;
sk = po->sk;
pppox_unbind_sock(sk);
- abort_put:
sock_put(sk);
abort:
kfree_skb(skb);
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 942a6c59bbca..032776c7037f 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.91 2000/11/08 05:04:06 davem Exp $
+/* $Id: sbus.c,v 1.92 2001/01/25 17:15:59 davem Exp $
* sbus.c: SBus support routines.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -238,10 +238,14 @@ static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
break;
}
if (rngnum == num_ranges) {
- prom_printf("sbus_apply_ranges: Cannot find matching "
- "range nregs[%d] nranges[%d].\n",
- num_regs, num_ranges);
- prom_halt();
+ /* We used to flag this as an error. Actually
+ * some devices do not report the regs as we expect.
+ * For example, see SUNW,pln device. In that case
+ * the reg property is in a format internal to that
+ * node, ie. it is not in the SBUS register space
+ * per se. -DaveM
+ */
+ return;
}
regs[regnum].which_io = ranges[rngnum].ot_parent_space;
regs[regnum].phys_addr += ranges[rngnum].ot_parent_base;
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index f966bf5a78ff..0e5ee69354f4 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -16,6 +16,7 @@
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
#error "This driver works only with kernel 2.4.0 or higher!"
#endif
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ctype.h>
@@ -38,7 +39,7 @@
#include <linux/config.h>
/* current version of this driver-source: */
-#define IBMMCA_SCSI_DRIVER_VERSION "4.0a"
+#define IBMMCA_SCSI_DRIVER_VERSION "4.0b"
#define IBMLOCK spin_lock_irqsave(&io_request_lock, flags);
#define IBMUNLOCK spin_unlock_irqrestore(&io_request_lock, flags);
@@ -443,7 +444,6 @@ static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
(that is kernel version 2.1.x) */
#if defined(MODULE)
static char *boot_options = NULL;
-#include <linux/module.h>
MODULE_PARM(boot_options, "s");
MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
@@ -2563,9 +2563,6 @@ static int option_setup(char *str)
__setup("ibmmcascsi=", option_setup);
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = IBMMCA;
+static Scsi_Host_Template driver_template = IBMMCA;
#include "scsi_module.c"
-#endif
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 365ea61a5f46..7a2cde23b87a 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -678,7 +678,7 @@ void get_capabilities(int i)
CDC_DVD | CDC_DVD_RAM |
CDC_SELECT_DISC | CDC_SELECT_SPEED);
scsi_free(buffer, 512);
- printk("sr%i: scsi-1 drive\n");
+ printk("sr%i: scsi-1 drive\n", i);
return;
}
n = buffer[3] + 4;
diff --git a/drivers/sound/trix.c b/drivers/sound/trix.c
index 73c9dcf54c65..03b4b1999cf3 100644
--- a/drivers/sound/trix.c
+++ b/drivers/sound/trix.c
@@ -17,7 +17,6 @@
* Arnaldo C. de Melo Got rid of attach_uart401
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
index f9fa0d213c7d..4d5b66386d13 100644
--- a/drivers/video/sbusfb.c
+++ b/drivers/video/sbusfb.c
@@ -678,7 +678,7 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
int end, count, index;
struct fbcmap *cmap;
- if (!fb->loadcmap)
+ if (!fb->loadcmap || !fb->color_map)
return -EINVAL;
i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
if (i) return i;
@@ -1110,6 +1110,8 @@ sizechange:
}
if (!p) {
+ if (fb->color_map)
+ kfree(fb->color_map);
kfree(fb);
return;
}
@@ -1147,6 +1149,8 @@ sizechange:
sbusfb_set_var(var, -1, &fb->info);
if (register_framebuffer(&fb->info) < 0) {
+ if (fb->color_map)
+ kfree(fb->color_map);
kfree(fb);
return;
}
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index c8dc3dd8fccb..12de14e7b0c5 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -14,17 +14,21 @@
extern int coda_debug;
extern int coda_print_entry;
+static ViceFid NullFID = { 0, 0, 0 };
+
inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
{
- if (fid1->Vnode != fid2->Vnode)
- return 0;
- if (fid1->Volume != fid2->Volume)
- return 0;
- if (fid1->Unique != fid2->Unique)
- return 0;
+ if (fid1->Vnode != fid2->Vnode) return 0;
+ if (fid1->Volume != fid2->Volume) return 0;
+ if (fid1->Unique != fid2->Unique) return 0;
return 1;
}
+static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
+{
+ return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
+}
+
static struct inode_operations coda_symlink_inode_operations = {
readlink: page_readlink,
follow_link: page_follow_link,
@@ -62,7 +66,8 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
struct coda_inode_info *cii;
ino_t ino = attr->va_fileid;
- inode = iget(sb, ino);
+ inode = iget4(sb, ino, coda_inocmp, fid);
+
if ( !inode ) {
CDEBUG(D_CNODE, "coda_iget: no inode\n");
return ERR_PTR(-ENOMEM);
@@ -70,25 +75,16 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
/* check if the inode is already initialized */
cii = ITOC(inode);
- if (cii->c_fid.Volume != 0 || cii->c_fid.Vnode != 0 || cii->c_fid.Unique != 0) {
- /* see if it is the right one (might have an inode collision) */
- if ( !coda_fideq(fid, &cii->c_fid) ) {
- printk("coda_iget: initialized inode old %s new %s!\n",
- coda_f2s(&cii->c_fid), coda_f2s2(fid));
- iput(inode);
- return ERR_PTR(-ENOENT);
- }
- /* we will still replace the attributes, type might have changed */
- goto out;
+ if (coda_fideq(&cii->c_fid, &NullFID)) {
+ /* new, empty inode found... initializing */
+ cii->c_fid = *fid;
+ cii->c_vnode = inode;
}
- /* new, empty inode found... initializing */
-
- /* Initialize the Coda inode info structure */
- cii->c_fid = *fid;
- cii->c_vnode = inode;
+ /* we shouldnt see inode collisions anymore */
+ if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
-out:
+ /* always replace the attributes, type might have changed */
coda_fill_inode(inode, attr);
return inode;
}
@@ -107,7 +103,6 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
ENTRY;
/* We get inode numbers from Venus -- see venus source */
-
error = venus_getattr(sb, fid, &attr);
if ( error ) {
CDEBUG(D_CNODE,
@@ -183,7 +178,7 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
if ( coda_fideq(&cii->c_fid, fid) ) {
inode = cii->c_vnode;
CDEBUG(D_INODE, "volume root, found %ld\n", inode->i_ino);
- iget(sb, inode->i_ino);
+ iget4(sb, inode->i_ino, coda_inocmp, fid);
return inode;
}
}
@@ -192,7 +187,7 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
/* fid is not weird: ino should be computable */
nr = coda_f2i(fid);
- inode = iget(sb, nr);
+ inode = iget4(sb, nr, coda_inocmp, fid);
if ( !inode ) {
printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
sb, (long)nr);
@@ -202,18 +197,11 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
/* check if this inode is linked to a cnode */
cii = ITOC(inode);
- /* make sure this is the one we want */
- if ( coda_fideq(fid, &cii->c_fid) ) {
- CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
- return inode;
- }
-
-#if 0
- printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr, coda_f2s(fid));
-#endif
- iput(inode);
- return NULL;
+ /* we shouldn't have inode collisions anymore */
+ if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
+ CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
+ return inode;
}
/* the CONTROL inode is made without asking attributes from Venus */
diff --git a/fs/exec.c b/fs/exec.c
index 667e5dad9058..28cb7db4c06d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -388,10 +388,8 @@ static int exec_mmap(void)
old_mm = current->mm;
if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
- flush_cache_mm(old_mm);
mm_release();
exit_mmap(old_mm);
- flush_tlb_mm(old_mm);
return 0;
}
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 69f6f0ce9234..0d72631c89b6 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -36,7 +36,7 @@
#include "check.h"
#include "msdos.h"
-#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+#if CONFIG_BLK_DEV_MD
extern void md_autodetect_dev(kdev_t dev);
#endif
@@ -136,7 +136,7 @@ static void extended_partition(struct gendisk *hd, kdev_t dev)
add_gd_partition(hd, current_minor,
this_sector+START_SECT(p)*sector_size,
NR_SECTS(p)*sector_size);
-#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+#if CONFIG_BLK_DEV_MD
if (SYS_IND(p) == LINUX_RAID_PARTITION) {
md_autodetect_dev(MKDEV(hd->major,current_minor));
}
@@ -448,7 +448,7 @@ check_table:
continue;
add_gd_partition(hd, minor, first_sector+START_SECT(p)*sector_size,
NR_SECTS(p)*sector_size);
-#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+#if CONFIG_BLK_DEV_MD
if (SYS_IND(p) == LINUX_RAID_PARTITION) {
md_autodetect_dev(MKDEV(hd->major,minor));
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 9ab57d370ec8..02aa4f025047 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -86,6 +86,7 @@ static int udf_adinicb_writepage(struct page *page)
brelse(bh);
SetPageUptodate(page);
kunmap(page);
+ UnlockPage(page);
return 0;
}
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 3783b43fdd85..8c818666ca84 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -203,7 +203,6 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
udf_release_data(bh);
inode->i_data.a_ops->writepage(page);
- UnlockPage(page);
page_cache_release(page);
mark_inode_dirty(inode);
diff --git a/include/asm-sh/current.h b/include/asm-sh/current.h
index 355a2cd14588..c690c233b356 100644
--- a/include/asm-sh/current.h
+++ b/include/asm-sh/current.h
@@ -12,7 +12,7 @@ static __inline__ struct task_struct * get_current(void)
{
struct task_struct *current;
- __asm__("stc $r7_bank, %0"
+ __asm__("stc r7_bank, %0"
:"=r" (current));
return current;
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index b1a6f9461771..a448c6f00f38 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -39,6 +39,7 @@ extern void paging_init(void);
#define flush_dcache_page(page) do { } while (0)
#define flush_icache_range(start, end) do { } while (0)
#define flush_icache_page(vma,pg) do { } while (0)
+#define flush_cache_sigtramp(vaddr) do { } while (0)
#elif defined(__SH4__)
/*
* Caches are broken on SH-4, so we need them.
@@ -52,6 +53,7 @@ extern void flush_page_to_ram(struct page *page);
extern void flush_dcache_page(struct page *pg);
extern void flush_icache_range(unsigned long start, unsigned long end);
extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
+extern void flush_cache_sigtramp(unsigned long addr);
#endif
/*
@@ -125,11 +127,7 @@ extern unsigned long empty_zero_page[1024];
/* Hardware flags: SZ=1 (4k-byte) */
#define _PAGE_FLAGS_HARD 0x00000010
-#if defined(__sh3__)
-#define _PAGE_SHARED _PAGE_HW_SHARED
-#elif defined(__SH4__)
#define _PAGE_SHARED _PAGE_U0_SHARED
-#endif
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
diff --git a/include/asm-sh/sh_bios.h b/include/asm-sh/sh_bios.h
index cdb73bdea28c..0ca261956e3d 100644
--- a/include/asm-sh/sh_bios.h
+++ b/include/asm-sh/sh_bios.h
@@ -13,5 +13,7 @@ extern void sh_bios_char_out(char ch);
extern int sh_bios_in_gdb_mode(void);
extern void sh_bios_gdb_detach(void);
+extern void sh_bios_get_node_addr(unsigned char *node_addr);
+extern void sh_bios_shutdown(unsigned int how);
#endif /* __ASM_SH_BIOS_H */
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 86786c730665..a8f720582de4 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -6,6 +6,7 @@
*/
#include <linux/config.h>
+#include <linux/kernel.h>
/*
* switch_to() should switch tasks to task nr n, first
@@ -28,37 +29,37 @@ typedef struct {
register unsigned long *__ts6 __asm__ ("r6") = &next->thread.sp; \
register unsigned long __ts7 __asm__ ("r7") = next->thread.pc; \
__asm__ __volatile__ (".balign 4\n\t" \
- "stc.l $gbr, @-$r15\n\t" \
- "sts.l $pr, @-$r15\n\t" \
- "mov.l $r8, @-$r15\n\t" \
- "mov.l $r9, @-$r15\n\t" \
- "mov.l $r10, @-$r15\n\t" \
- "mov.l $r11, @-$r15\n\t" \
- "mov.l $r12, @-$r15\n\t" \
- "mov.l $r13, @-$r15\n\t" \
- "mov.l $r14, @-$r15\n\t" \
- "mov.l $r15, @$r1 ! save SP\n\t" \
- "mov.l @$r6, $r15 ! change to new stack\n\t" \
- "mov.l %0, @-$r15 ! push R0 onto new stack\n\t" \
+ "stc.l gbr, @-r15\n\t" \
+ "sts.l pr, @-r15\n\t" \
+ "mov.l r8, @-r15\n\t" \
+ "mov.l r9, @-r15\n\t" \
+ "mov.l r10, @-r15\n\t" \
+ "mov.l r11, @-r15\n\t" \
+ "mov.l r12, @-r15\n\t" \
+ "mov.l r13, @-r15\n\t" \
+ "mov.l r14, @-r15\n\t" \
+ "mov.l r15, @r1 ! save SP\n\t" \
+ "mov.l @r6, r15 ! change to new stack\n\t" \
+ "mov.l %0, @-r15 ! push R0 onto new stack\n\t" \
"mova 1f, %0\n\t" \
- "mov.l %0, @$r2 ! save PC\n\t" \
+ "mov.l %0, @r2 ! save PC\n\t" \
"mov.l 2f, %0\n\t" \
"jmp @%0 ! call __switch_to\n\t" \
- " lds $r7, $pr ! with return to new PC\n\t" \
+ " lds r7, pr ! with return to new PC\n\t" \
".balign 4\n" \
"2:\n\t" \
".long " "__switch_to\n" \
"1:\n\t" \
- "mov.l @$r15+, %0 ! pop R0 from new stack\n\t" \
- "mov.l @$r15+, $r14\n\t" \
- "mov.l @$r15+, $r13\n\t" \
- "mov.l @$r15+, $r12\n\t" \
- "mov.l @$r15+, $r11\n\t" \
- "mov.l @$r15+, $r10\n\t" \
- "mov.l @$r15+, $r9\n\t" \
- "mov.l @$r15+, $r8\n\t" \
- "lds.l @$r15+, $pr\n\t" \
- "ldc.l @$r15+, $gbr\n\t" \
+ "mov.l @r15+, %0 ! pop R0 from new stack\n\t" \
+ "mov.l @r15+, r14\n\t" \
+ "mov.l @r15+, r13\n\t" \
+ "mov.l @r15+, r12\n\t" \
+ "mov.l @r15+, r11\n\t" \
+ "mov.l @r15+, r10\n\t" \
+ "mov.l @r15+, r9\n\t" \
+ "mov.l @r15+, r8\n\t" \
+ "lds.l @r15+, pr\n\t" \
+ "ldc.l @r15+, gbr\n\t" \
:"=&z" (__last) \
:"0" (prev), \
"r" (__ts1), "r" (__ts2), \
@@ -107,11 +108,11 @@ static __inline__ void __sti(void)
{
unsigned long __dummy0, __dummy1;
- __asm__ __volatile__("stc $sr, %0\n\t"
+ __asm__ __volatile__("stc sr, %0\n\t"
"and %1, %0\n\t"
- "stc $r6_bank, %1\n\t"
+ "stc r6_bank, %1\n\t"
"or %1, %0\n\t"
- "ldc %0, $sr"
+ "ldc %0, sr"
: "=&r" (__dummy0), "=r" (__dummy1)
: "1" (~0x000000f0)
: "memory");
@@ -120,9 +121,9 @@ static __inline__ void __sti(void)
static __inline__ void __cli(void)
{
unsigned long __dummy;
- __asm__ __volatile__("stc $sr, %0\n\t"
+ __asm__ __volatile__("stc sr, %0\n\t"
"or #0xf0, %0\n\t"
- "ldc %0, $sr"
+ "ldc %0, sr"
: "=&z" (__dummy)
: /* no inputs */
: "memory");
@@ -131,7 +132,7 @@ static __inline__ void __cli(void)
#define __save_flags(x) \
x = (__extension__ ({ unsigned long __sr; \
__asm__ __volatile__( \
- "stc $sr, %0" \
+ "stc sr, %0" \
: "=&r" (__sr) \
: /* no inputs */ \
: "memory"); \
@@ -140,10 +141,10 @@ x = (__extension__ ({ unsigned long __sr; \
#define __save_and_cli(x) \
x = (__extension__ ({ unsigned long __dummy,__sr; \
__asm__ __volatile__( \
- "stc $sr, %1\n\t" \
+ "stc sr, %1\n\t" \
"mov %1, %0\n\t" \
"or #0xf0, %0\n\t" \
- "ldc %0, $sr" \
+ "ldc %0, sr" \
: "=&z" (__dummy), "=&r" (__sr) \
: /* no inputs */ \
: "memory"); (__sr & 0x000000f0); }))
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 38b7a6a982a5..4fce3f847249 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -28,19 +28,6 @@
#include <linux/wait.h>
#endif /* __KERNEL__ */
-/*
- * System sleep states
- */
-enum
-{
- ACPI_S0, /* working */
- ACPI_S1, /* sleep */
- ACPI_S2, /* sleep */
- ACPI_S3, /* sleep */
- ACPI_S4, /* non-volatile sleep */
- ACPI_S5, /* soft-off */
-};
-
typedef int acpi_sstate_t;
/*
diff --git a/include/linux/dn.h b/include/linux/dn.h
index d98b0c3c7903..782cae49e64c 100644
--- a/include/linux/dn.h
+++ b/include/linux/dn.h
@@ -143,6 +143,5 @@ struct dn_addr {
#define SIOCGNETADDR _IOR(DECNET_IOCTL_BASE, 0xe1, struct dn_naddr)
#define OSIOCSNETADDR _IOW(DECNET_IOCTL_BASE, 0xe0, int)
#define OSIOCGNETADDR _IOR(DECNET_IOCTL_BASE, 0xe1, int)
-/* #define SIOCATEOR _IOR(DECNET_IOCTL_BASE, 0x01, int) */
#endif /* _LINUX_DN_H */
diff --git a/include/linux/lvm.h b/include/linux/lvm.h
index 7b4ff94f9e53..07dac6c3677b 100644
--- a/include/linux/lvm.h
+++ b/include/linux/lvm.h
@@ -9,6 +9,7 @@
* May-July 1998
* January-March,July,September,October,Dezember 1999
* January,February,July,November 2000
+ * January 2001
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,6 +58,8 @@
* 26/06/2000 - implemented snapshot persistency and resizing support
* 02/11/2000 - added hash table size member to lv structure
* 12/11/2000 - removed unneeded timestamp definitions
+ * 24/12/2000 - removed LVM_TO_{CORE,DISK}*, use cpu_{from, to}_le*
+ * instead - Christoph Hellwig
*
*/
@@ -64,11 +67,9 @@
#ifndef _LVM_H_INCLUDE
#define _LVM_H_INCLUDE
-#define _LVM_KERNEL_H_VERSION "LVM 0.9 (13/11/2000)"
+#define _LVM_KERNEL_H_VERSION "LVM 0.9.1_beta2 (18/01/2001)"
-#include <linux/config.h>
#include <linux/version.h>
-#include <endian.h>
/*
* preprocessor definitions
@@ -77,8 +78,7 @@
#define LVM_TOTAL_RESET
#ifdef __KERNEL__
-#define LVM_GET_INODE
-#undef LVM_HD_NAME /* display nice names in /proc/partitions */
+#undef LVM_HD_NAME /* display nice names in /proc/partitions */
/* lots of debugging output (see driver source)
#define DEBUG_LVM_GET_INFO
@@ -109,6 +109,7 @@
#ifdef __KERNEL__
#include <linux/spinlock.h>
+
#include <asm/semaphore.h>
#endif /* #ifdef __KERNEL__ */
@@ -216,15 +217,13 @@
*
* 1K volume group structure ~200 byte
*
- * 5K time stamp structure ~
- *
* 6K namelist of physical volumes 128 byte each
*
- * 6k + n * 128byte n logical volume structures ~300 byte each
+ * 6k + n * ~300byte n logical volume structures ~300 byte each
*
- * + m * 328byte m physical extent alloc. structs 4 byte each
+ * + m * 4byte m physical extent alloc. structs 4 byte each
*
- * End of disk - first physical extent typical 4 megabyte
+ * End of disk - first physical extent typically 4 megabyte
* PE total *
* PE size
*
@@ -292,7 +291,7 @@
#define LVM_MAX_PE_SIZE ( 16L * 1024L * 1024L / SECTOR_SIZE * 1024) /* 16GB in sectors */
#define LVM_DEFAULT_PE_SIZE ( 4096L * 1024 / SECTOR_SIZE) /* 4 MB in sectors */
#define LVM_DEFAULT_STRIPE_SIZE 16L /* 16 KB */
-#define LVM_MIN_STRIPE_SIZE ( PAGE_SIZE>>9) /* PAGESIZE in sectors */
+#define LVM_MIN_STRIPE_SIZE ( PAGE_SIZE/SECTOR_SIZE) /* PAGESIZE in sectors */
#define LVM_MAX_STRIPE_SIZE ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */
#define LVM_MAX_STRIPES 128 /* max # of stripes */
#define LVM_MAX_SIZE ( 1024LU * 1024 / SECTOR_SIZE * 1024 * 1024) /* 1TB[sectors] */
@@ -326,51 +325,6 @@
COW_table_entries_per_PE - COW_table_chunks_per_PE;})
-/* to disk and to core data conversion macros */
-#if __BYTE_ORDER == __BIG_ENDIAN
-
-#define LVM_TO_CORE16(x) ( \
- ((uint16_t)((((uint16_t)(x) & 0x00FFU) << 8) | \
- (((uint16_t)(x) & 0xFF00U) >> 8))))
-
-#define LVM_TO_DISK16(x) LVM_TO_CORE16(x)
-
-#define LVM_TO_CORE32(x) ( \
- ((uint32_t)((((uint32_t)(x) & 0x000000FFU) << 24) | \
- (((uint32_t)(x) & 0x0000FF00U) << 8))) \
- (((uint32_t)(x) & 0x00FF0000U) >> 8))) \
- (((uint32_t)(x) & 0xFF000000U) >> 24))))
-
-#define LVM_TO_DISK32(x) LVM_TO_CORE32(x)
-
-#define LVM_TO_CORE64(x) \
- ((uint64_t)((((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \
- (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \
- (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \
- (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \
- (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \
- (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \
- (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \
- (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56)))
-
-#define LVM_TO_DISK64(x) LVM_TO_CORE64(x)
-
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-
-#define LVM_TO_CORE16(x) x
-#define LVM_TO_DISK16(x) x
-#define LVM_TO_CORE32(x) x
-#define LVM_TO_DISK32(x) x
-#define LVM_TO_CORE64(x) x
-#define LVM_TO_DISK64(x) x
-
-#else
-
-#error "__BYTE_ORDER must be defined as __LITTLE_ENDIAN or __BIG_ENDIAN"
-
-#endif /* #if __BYTE_ORDER == __BIG_ENDIAN */
-
-
/*
* ioctls
*/
@@ -687,6 +641,8 @@ typedef struct lv_v4 {
wait_queue_head_t lv_snapshot_wait;
int lv_snapshot_use_rate;
void *vg;
+
+ uint lv_allocated_snapshot_le;
#else
char dummy[200];
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 1ee4dd6167e1..4c77c2081721 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -74,7 +74,7 @@ struct nfs_readargs {
struct nfs_readres {
struct nfs_fattr * fattr;
- unsigned int count;
+ __u32 count;
int eof;
};
@@ -84,7 +84,7 @@ struct nfs_readres {
#define NFS_WRITE_MAXIOV 8
struct nfs_writeargs {
struct nfs_fh * fh;
- __u32 offset;
+ __u64 offset;
__u32 count;
enum nfs3_stable_how stable;
unsigned int nriov;
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index c96b0e404386..22a1543808c9 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -22,6 +22,7 @@
#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t)
#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13)
+#define RAID_AUTORUN _IO (MD_MAJOR, 0x14)
/* configuration */
#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20)
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index fba9111dacef..df958b66ada6 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -8,7 +8,7 @@
* Copyright (C) 1999 Hewlett-Packard Co.
* Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
*/
-#ifndef _LINUX_RTC_H
+#ifndef _LINUX_RTC_H_
#define _LINUX_RTC_H_
/*
diff --git a/include/net/dn.h b/include/net/dn.h
index c4c598f2f15c..88a0bab3e072 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -58,7 +58,6 @@ struct dn_scp /* Session Control Port */
unsigned short segsize_rem;
unsigned short segsize_loc;
- unsigned char at_eor;
unsigned char nonagle;
unsigned char multi_ireq;
unsigned char accept_mode;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 3efa00b11469..f362615000f5 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -395,6 +395,7 @@ EXPORT_SYMBOL(unmap_kiobuf);
EXPORT_SYMBOL(lock_kiovec);
EXPORT_SYMBOL(unlock_kiovec);
EXPORT_SYMBOL(brw_kiovec);
+EXPORT_SYMBOL(kiobuf_wait_for_io);
/* dma handling */
EXPORT_SYMBOL(request_dma);
diff --git a/mm/mmap.c b/mm/mmap.c
index e5b3a989ed20..e1faba3c7ea4 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -883,6 +883,8 @@ void exit_mmap(struct mm_struct * mm)
mm->rss = 0;
mm->total_vm = 0;
mm->locked_vm = 0;
+
+ flush_cache_mm(mm);
while (mpnt) {
struct vm_area_struct * next = mpnt->vm_next;
unsigned long start = mpnt->vm_start;
@@ -895,13 +897,13 @@ void exit_mmap(struct mm_struct * mm)
}
mm->map_count--;
remove_shared_vm_struct(mpnt);
- flush_cache_range(mm, start, end);
zap_page_range(mm, start, size);
if (mpnt->vm_file)
fput(mpnt->vm_file);
kmem_cache_free(vm_area_cachep, mpnt);
mpnt = next;
}
+ flush_tlb_mm(mm);
/* This is just debugging */
if (mm->map_count)
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index da59ab6ef3d9..b930878c2eef 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -439,7 +439,6 @@ struct sock *dn_alloc_sock(struct socket *sock, int gfp)
scp->info_loc = 0x03; /* NSP version 4.1 */
scp->segsize_rem = 230; /* Default: Updated by remote segsize */
scp->segsize_loc = 1450; /* Best guess for ethernet */
- scp->at_eor = 1;
scp->nonagle = 0;
scp->multi_ireq = 1;
scp->accept_mode = ACC_IMMED;
@@ -1121,18 +1120,6 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
release_sock(sk);
return val;
-#ifdef SIOCATEOR
- case SIOCATEOR:
- lock_sock(sk);
- val = scp->at_eor;
- if (scp->state != DN_RUN)
- val = -ENOTCONN;
- if (sock->type != SOCK_SEQPACKET)
- val = -EINVAL;
- release_sock(sk);
- return val;
-#endif /* SIOCATEOR */
-
#ifdef CONFIG_DECNET_ROUTER
case SIOCADDRT:
case SIOCDELRT:
@@ -1768,14 +1755,10 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
rv = copied;
- if (!(flags & (MSG_PEEK|MSG_OOB)))
- scp->at_eor = 0;
- if (eor && (sk->type == SOCK_SEQPACKET)) {
+ if (eor && (sk->type == SOCK_SEQPACKET))
msg->msg_flags |= MSG_EOR;
- if (!(flags & (MSG_PEEK|MSG_OOB)))
- scp->at_eor = 1;
- }
+
out:
if (rv == 0)
rv = (flags & MSG_PEEK) ? -sk->err : sock_error(sk);
@@ -2042,12 +2025,12 @@ static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
{
int i;
- switch (dn->sdn_objnamel) {
+ switch (dn_ntohs(dn->sdn_objnamel)) {
case 0:
sprintf(buf, "%d", dn->sdn_objnum);
break;
default:
- for (i = 0; i < dn->sdn_objnamel; i++) {
+ for (i = 0; i < dn_ntohs(dn->sdn_objnamel); i++) {
buf[i] = dn->sdn_objname[i];
if (IS_NOT_PRINTABLE(buf[i]))
buf[i] = '.';
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9ba62dc8480a..cc19e1f0b5ee 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -438,8 +438,27 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
conntrack));
ret = 1;
goto clear_fulls;
+ } else if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
+ /* Try implicit source NAT; protocol
+ may be able to play with ports to
+ make it unique. */
+ struct ip_nat_range r
+ = { IP_NAT_RANGE_MAP_IPS,
+ tuple->src.ip, tuple->src.ip,
+ { 0 }, { 0 } };
+ DEBUGP("Trying implicit mapping\n");
+ if (proto->unique_tuple(tuple, &r,
+ IP_NAT_MANIP_SRC,
+ conntrack)) {
+ /* Must be unique. */
+ IP_NF_ASSERT(!ip_nat_used_tuple
+ (tuple, conntrack));
+ ret = 1;
+ goto clear_fulls;
+ }
}
- DEBUGP("Protocol can't get unique tuple.\n");
+ DEBUGP("Protocol can't get unique tuple %u.\n",
+ hooknum);
}
/* Eliminate that from range, and try again. */
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 99164a7a0201..3d7afadb0996 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -68,6 +68,7 @@ masquerade_target(struct sk_buff **pskb,
struct ip_nat_multi_range newrange;
u_int32_t newsrc;
struct rtable *rt;
+ struct rt_key key;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -82,10 +83,14 @@ masquerade_target(struct sk_buff **pskb,
mr = targinfo;
- if (ip_route_output(&rt, (*pskb)->nh.iph->daddr,
- 0,
- RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN,
- out->ifindex) != 0) {
+ key.dst = (*pskb)->nh.iph->daddr;
+ key.src = 0; /* Unknown: that's what we're trying to establish */
+ key.tos = RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN;
+ key.oif = out->ifindex;
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ key.fwmark = (*pskb)->nfmark;
+#endif
+ if (ip_route_output_key(&rt, &key) != 0) {
/* Shouldn't happen */
printk("MASQUERADE: No route: Rusty's brain broke!\n");
return NF_DROP;
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index c52ada64e606..60d4698fb74e 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -53,7 +53,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } },
/* LOCAL_OUT */
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
@@ -61,7 +61,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } }
},
/* ERROR */
@@ -70,7 +70,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_error),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_error_target), IPT_ERROR_TARGET } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
{ } },
"ERROR"
}
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index e5504ee96e9d..250b22ae9a96 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2409,6 +2409,7 @@ int __init irda_proto_init(void)
#endif
return 0;
}
+module_init(irda_proto_init);
/*
* Function irda_proto_cleanup (void)
@@ -2429,11 +2430,9 @@ void irda_proto_cleanup(void)
return;
}
-module_init(irda_proto_init);
module_exit(irda_proto_cleanup);
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
MODULE_PARM(irda_debug, "1l");
#endif /* MODULE */
-